blob: aa3e1331dac37d3118a1c55e5fc72f8a9cf7f4b3 [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"
sewardj2019a972011-03-07 16:04:07 +000037#include "libvex.h" /* needed for bb_to_IR.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 */
43#include "host_s390_disasm.h"
44#include "host_s390_defs.h" /* S390_ROUND_xyzzy */
45
sewardj2019a972011-03-07 16:04:07 +000046
47/*------------------------------------------------------------*/
florianb4df7682011-07-05 02:09:01 +000048/*--- Forward declarations ---*/
49/*------------------------------------------------------------*/
50static UInt s390_decode_and_irgen(UChar *, UInt, DisResult *);
florianb0bf6602012-05-05 00:01:16 +000051static void s390_irgen_xonc(IROp, IRTemp, IRTemp, IRTemp);
florian79e839e2012-05-05 02:20:30 +000052static void s390_irgen_CLC_EX(IRTemp, IRTemp, IRTemp);
florianb4df7682011-07-05 02:09:01 +000053
54
55/*------------------------------------------------------------*/
sewardj2019a972011-03-07 16:04:07 +000056/*--- Globals ---*/
57/*------------------------------------------------------------*/
58
59/* The IRSB* into which we're generating code. */
60static IRSB *irsb;
61
62/* The guest address for the instruction currently being
63 translated. */
64static Addr64 guest_IA_curr_instr;
65
66/* The guest address for the instruction following the current instruction. */
67static Addr64 guest_IA_next_instr;
68
69/* Result of disassembly step. */
70static DisResult *dis_res;
71
floriana64c2432011-07-16 02:11:50 +000072/* Resteer function and callback data */
73static Bool (*resteer_fn)(void *, Addr64);
74static void *resteer_data;
75
sewardj2019a972011-03-07 16:04:07 +000076/* The last seen execute target instruction */
77ULong last_execute_target;
78
79/* The possible outcomes of a decoding operation */
80typedef enum {
81 S390_DECODE_OK,
82 S390_DECODE_UNKNOWN_INSN,
83 S390_DECODE_UNIMPLEMENTED_INSN,
84 S390_DECODE_UNKNOWN_SPECIAL_INSN,
85 S390_DECODE_ERROR
86} s390_decode_t;
87
florian428dfdd2012-03-27 03:09:49 +000088
sewardj2019a972011-03-07 16:04:07 +000089/*------------------------------------------------------------*/
90/*--- Helpers for constructing IR. ---*/
91/*------------------------------------------------------------*/
92
93/* Sign extend a value with the given number of bits. This is a
94 macro because it allows us to overload the type of the value.
95 Note that VALUE must have a signed type! */
96#undef sign_extend
97#define sign_extend(value,num_bits) \
98(((value) << (sizeof(__typeof__(value)) * 8 - (num_bits))) >> \
99 (sizeof(__typeof__(value)) * 8 - (num_bits)))
100
101
102/* Add a statement to the current irsb. */
103static __inline__ void
104stmt(IRStmt *st)
105{
106 addStmtToIRSB(irsb, st);
107}
108
109/* Allocate a new temporary of the given type. */
110static __inline__ IRTemp
111newTemp(IRType type)
112{
113 vassert(isPlausibleIRType(type));
114
115 return newIRTemp(irsb->tyenv, type);
116}
117
118/* Create an expression node for a temporary */
119static __inline__ IRExpr *
120mkexpr(IRTemp tmp)
121{
122 return IRExpr_RdTmp(tmp);
123}
124
florian8844a632012-04-13 04:04:06 +0000125/* Generate an expression node for an address. */
126static __inline__ IRExpr *
127mkaddr_expr(Addr64 addr)
128{
129 return IRExpr_Const(IRConst_U64(addr));
130}
131
sewardj2019a972011-03-07 16:04:07 +0000132/* Add a statement that assigns to a temporary */
133static __inline__ void
134assign(IRTemp dst, IRExpr *expr)
135{
136 stmt(IRStmt_WrTmp(dst, expr));
137}
138
florian8844a632012-04-13 04:04:06 +0000139/* Write an address into the guest_IA */
140static __inline__ void
141put_IA(IRExpr *address)
142{
143 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_IA), address));
144}
145
sewardj2019a972011-03-07 16:04:07 +0000146/* Create a temporary of the given type and assign the expression to it */
147static __inline__ IRTemp
148mktemp(IRType type, IRExpr *expr)
149{
150 IRTemp temp = newTemp(type);
151
152 assign(temp, expr);
153
154 return temp;
155}
156
157/* Create a unary expression */
158static __inline__ IRExpr *
159unop(IROp kind, IRExpr *op)
160{
161 return IRExpr_Unop(kind, op);
162}
163
164/* Create a binary expression */
165static __inline__ IRExpr *
166binop(IROp kind, IRExpr *op1, IRExpr *op2)
167{
168 return IRExpr_Binop(kind, op1, op2);
169}
170
171/* Create a ternary expression */
172static __inline__ IRExpr *
173triop(IROp kind, IRExpr *op1, IRExpr *op2, IRExpr *op3)
174{
175 return IRExpr_Triop(kind, op1, op2, op3);
176}
177
178/* Create a quaternary expression */
179static __inline__ IRExpr *
180qop(IROp kind, IRExpr *op1, IRExpr *op2, IRExpr *op3, IRExpr *op4)
181{
182 return IRExpr_Qop(kind, op1, op2, op3, op4);
183}
184
185/* Create an expression node for an 8-bit integer constant */
186static __inline__ IRExpr *
187mkU8(UInt value)
188{
189 vassert(value < 256);
190
191 return IRExpr_Const(IRConst_U8((UChar)value));
192}
193
194/* Create an expression node for a 16-bit integer constant */
195static __inline__ IRExpr *
196mkU16(UInt value)
197{
198 vassert(value < 65536);
199
200 return IRExpr_Const(IRConst_U16((UShort)value));
201}
202
203/* Create an expression node for a 32-bit integer constant */
204static __inline__ IRExpr *
205mkU32(UInt value)
206{
207 return IRExpr_Const(IRConst_U32(value));
208}
209
210/* Create an expression node for a 64-bit integer constant */
211static __inline__ IRExpr *
212mkU64(ULong value)
213{
214 return IRExpr_Const(IRConst_U64(value));
215}
216
217/* Create an expression node for a 32-bit floating point constant
218 whose value is given by a bit pattern. */
219static __inline__ IRExpr *
220mkF32i(UInt value)
221{
222 return IRExpr_Const(IRConst_F32i(value));
223}
224
225/* Create an expression node for a 32-bit floating point constant
226 whose value is given by a bit pattern. */
227static __inline__ IRExpr *
228mkF64i(ULong value)
229{
230 return IRExpr_Const(IRConst_F64i(value));
231}
232
233/* Little helper function for my sanity. ITE = if-then-else */
234static IRExpr *
235mkite(IRExpr *condition, IRExpr *iftrue, IRExpr *iffalse)
236{
237 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
238
239 return IRExpr_Mux0X(unop(Iop_1Uto8, condition), iffalse, iftrue);
240}
241
242/* Add a statement that stores DATA at ADDR. This is a big-endian machine. */
243static void __inline__
244store(IRExpr *addr, IRExpr *data)
245{
246 stmt(IRStmt_Store(Iend_BE, addr, data));
247}
248
249/* Create an expression that loads a TYPE sized value from ADDR.
250 This is a big-endian machine. */
251static __inline__ IRExpr *
252load(IRType type, IRExpr *addr)
253{
254 return IRExpr_Load(Iend_BE, type, addr);
255}
256
257/* Function call */
258static void
259call_function(IRExpr *callee_address)
260{
florian8844a632012-04-13 04:04:06 +0000261 put_IA(callee_address);
sewardj2019a972011-03-07 16:04:07 +0000262
florian8844a632012-04-13 04:04:06 +0000263 dis_res->whatNext = Dis_StopHere;
264 dis_res->jk_StopHere = Ijk_Call;
sewardj2019a972011-03-07 16:04:07 +0000265}
266
floriana64c2432011-07-16 02:11:50 +0000267/* Function call with known target. */
268static void
269call_function_and_chase(Addr64 callee_address)
270{
271 if (resteer_fn(resteer_data, callee_address)) {
272 dis_res->whatNext = Dis_ResteerU;
273 dis_res->continueAt = callee_address;
274 } else {
florian8844a632012-04-13 04:04:06 +0000275 put_IA(mkaddr_expr(callee_address));
276
floriana64c2432011-07-16 02:11:50 +0000277 dis_res->whatNext = Dis_StopHere;
florian8844a632012-04-13 04:04:06 +0000278 dis_res->jk_StopHere = Ijk_Call;
floriana64c2432011-07-16 02:11:50 +0000279 }
280}
281
sewardj2019a972011-03-07 16:04:07 +0000282/* Function return sequence */
283static void
284return_from_function(IRExpr *return_address)
285{
florian8844a632012-04-13 04:04:06 +0000286 put_IA(return_address);
sewardj2019a972011-03-07 16:04:07 +0000287
florian8844a632012-04-13 04:04:06 +0000288 dis_res->whatNext = Dis_StopHere;
289 dis_res->jk_StopHere = Ijk_Ret;
sewardj2019a972011-03-07 16:04:07 +0000290}
291
292/* A conditional branch whose target is not known at instrumentation time.
293
294 if (condition) goto computed_target;
295
296 Needs to be represented as:
297
298 if (! condition) goto next_instruction;
299 goto computed_target;
sewardj2019a972011-03-07 16:04:07 +0000300*/
301static void
florianf321da72012-07-21 20:32:57 +0000302if_condition_goto_computed(IRExpr *condition, IRExpr *target)
sewardj2019a972011-03-07 16:04:07 +0000303{
304 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
305
florianf321da72012-07-21 20:32:57 +0000306 condition = unop(Iop_Not1, condition);
307
florian8844a632012-04-13 04:04:06 +0000308 stmt(IRStmt_Exit(condition, Ijk_Boring, IRConst_U64(guest_IA_next_instr),
309 S390X_GUEST_OFFSET(guest_IA)));
sewardj2019a972011-03-07 16:04:07 +0000310
florian8844a632012-04-13 04:04:06 +0000311 put_IA(target);
sewardj2019a972011-03-07 16:04:07 +0000312
florian8844a632012-04-13 04:04:06 +0000313 dis_res->whatNext = Dis_StopHere;
314 dis_res->jk_StopHere = Ijk_Boring;
sewardj2019a972011-03-07 16:04:07 +0000315}
316
317/* A conditional branch whose target is known at instrumentation time. */
318static void
319if_condition_goto(IRExpr *condition, Addr64 target)
320{
321 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
322
florian8844a632012-04-13 04:04:06 +0000323 stmt(IRStmt_Exit(condition, Ijk_Boring, IRConst_U64(target),
324 S390X_GUEST_OFFSET(guest_IA)));
325
florian7346c7a2012-04-13 21:14:24 +0000326 put_IA(mkaddr_expr(guest_IA_next_instr));
florian8844a632012-04-13 04:04:06 +0000327
328 dis_res->whatNext = Dis_StopHere;
329 dis_res->jk_StopHere = Ijk_Boring;
sewardj2019a972011-03-07 16:04:07 +0000330}
331
332/* An unconditional branch. Target may or may not be known at instrumentation
333 time. */
334static void
335always_goto(IRExpr *target)
336{
florian8844a632012-04-13 04:04:06 +0000337 put_IA(target);
sewardj2019a972011-03-07 16:04:07 +0000338
florian8844a632012-04-13 04:04:06 +0000339 dis_res->whatNext = Dis_StopHere;
340 dis_res->jk_StopHere = Ijk_Boring;
sewardj2019a972011-03-07 16:04:07 +0000341}
342
florian8844a632012-04-13 04:04:06 +0000343
floriana64c2432011-07-16 02:11:50 +0000344/* An unconditional branch to a known target. */
345static void
346always_goto_and_chase(Addr64 target)
347{
348 if (resteer_fn(resteer_data, target)) {
florian8844a632012-04-13 04:04:06 +0000349 /* Follow into the target */
floriana64c2432011-07-16 02:11:50 +0000350 dis_res->whatNext = Dis_ResteerU;
351 dis_res->continueAt = target;
352 } else {
florian8844a632012-04-13 04:04:06 +0000353 put_IA(mkaddr_expr(target));
354
355 dis_res->whatNext = Dis_StopHere;
356 dis_res->jk_StopHere = Ijk_Boring;
floriana64c2432011-07-16 02:11:50 +0000357 }
358}
359
sewardj2019a972011-03-07 16:04:07 +0000360/* A system call */
361static void
362system_call(IRExpr *sysno)
363{
364 /* Store the system call number in the pseudo register. */
florian428dfdd2012-03-27 03:09:49 +0000365 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_SYSNO), sysno));
sewardj2019a972011-03-07 16:04:07 +0000366
sewardj69007022011-04-28 20:13:45 +0000367 /* Store the current IA into guest_IP_AT_SYSCALL. libvex_ir.h says so. */
florian428dfdd2012-03-27 03:09:49 +0000368 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_IP_AT_SYSCALL),
369 mkU64(guest_IA_curr_instr)));
sewardj2019a972011-03-07 16:04:07 +0000370
florian8844a632012-04-13 04:04:06 +0000371 put_IA(mkaddr_expr(guest_IA_next_instr));
372
sewardj2019a972011-03-07 16:04:07 +0000373 /* It's important that all ArchRegs carry their up-to-date value
374 at this point. So we declare an end-of-block here, which
375 forces any TempRegs caching ArchRegs to be flushed. */
florian8844a632012-04-13 04:04:06 +0000376 dis_res->whatNext = Dis_StopHere;
377 dis_res->jk_StopHere = Ijk_Sys_syscall;
sewardj2019a972011-03-07 16:04:07 +0000378}
379
florian6820ba52012-07-26 02:01:50 +0000380/* A side exit that branches back to the current insn if CONDITION is
381 true. Does not set DisResult. */
382static void
383iterate_if(IRExpr *condition)
384{
385 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
386
387 stmt(IRStmt_Exit(condition, Ijk_Boring, IRConst_U64(guest_IA_curr_instr),
388 S390X_GUEST_OFFSET(guest_IA)));
389}
390
391/* A side exit that branches back to the current insn.
392 Does not set DisResult. */
393static __inline__ void
394iterate(void)
395{
396 iterate_if(IRExpr_Const(IRConst_U1(True)));
397}
398
399/* A side exit that branches back to the insn immediately following the
400 current insn if CONDITION is true. Does not set DisResult. */
401static void
402next_insn_if(IRExpr *condition)
403{
404 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
405
406 stmt(IRStmt_Exit(condition, Ijk_Boring, IRConst_U64(guest_IA_next_instr),
407 S390X_GUEST_OFFSET(guest_IA)));
408}
409
410/* Convenience function to restart the current insn */
411static void
412restart_if(IRExpr *condition)
413{
414 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
415
416 stmt(IRStmt_Exit(condition, Ijk_TInval, IRConst_U64(guest_IA_curr_instr),
417 S390X_GUEST_OFFSET(guest_IA)));
418}
419
420/* Convenience function to yield to thread scheduler */
421static void
422yield_if(IRExpr *condition)
423{
424 stmt(IRStmt_Exit(condition, Ijk_Yield, IRConst_U64(guest_IA_next_instr),
425 S390X_GUEST_OFFSET(guest_IA)));
426}
427
florian847684d2012-09-05 04:19:09 +0000428/* Encode the s390 rounding mode as it appears in the m3 field of certain
429 instructions to VEX's IRRoundingMode. Rounding modes that cannot be
430 represented in VEX are converted to Irrm_NEAREST. The rationale is, that
431 Irrm_NEAREST refers to IEEE 754's roundTiesToEven which the standard
432 considers the default rounding mode (4.3.3). */
floriandb4fcaa2012-09-05 19:54:08 +0000433static IRTemp
434encode_bfp_rounding_mode(UChar mode)
sewardj2019a972011-03-07 16:04:07 +0000435{
floriandb4fcaa2012-09-05 19:54:08 +0000436 IRExpr *rm;
437
sewardj2019a972011-03-07 16:04:07 +0000438 switch (mode) {
florian847684d2012-09-05 04:19:09 +0000439 case S390_ROUND_PER_FPC: /* not supported */
440 case S390_ROUND_NEAREST_AWAY: /* not supported */
441 case S390_ROUND_PREPARE_SHORT: /* not supported */
floriandb4fcaa2012-09-05 19:54:08 +0000442 case S390_ROUND_NEAREST_EVEN: rm = mkU32(Irrm_NEAREST); break;
443 case S390_ROUND_ZERO: rm = mkU32(Irrm_ZERO); break;
444 case S390_ROUND_POSINF: rm = mkU32(Irrm_PosINF); break;
445 case S390_ROUND_NEGINF: rm = mkU32(Irrm_NegINF); break;
446 default:
447 vpanic("encode_bfp_rounding_mode");
sewardj2019a972011-03-07 16:04:07 +0000448 }
floriandb4fcaa2012-09-05 19:54:08 +0000449
450 return mktemp(Ity_I32, rm);
sewardj2019a972011-03-07 16:04:07 +0000451}
452
453static __inline__ IRExpr *get_fpr_dw0(UInt);
454static __inline__ void put_fpr_dw0(UInt, IRExpr *);
455
456/* Read a floating point register pair and combine their contents into a
457 128-bit value */
458static IRExpr *
459get_fpr_pair(UInt archreg)
460{
461 IRExpr *high = get_fpr_dw0(archreg);
462 IRExpr *low = get_fpr_dw0(archreg + 2);
463
464 return binop(Iop_F64HLtoF128, high, low);
465}
466
467/* Write a 128-bit floating point value into a register pair. */
468static void
469put_fpr_pair(UInt archreg, IRExpr *expr)
470{
471 IRExpr *high = unop(Iop_F128HItoF64, expr);
472 IRExpr *low = unop(Iop_F128LOtoF64, expr);
473
474 put_fpr_dw0(archreg, high);
475 put_fpr_dw0(archreg + 2, low);
476}
477
floriane75dafa2012-09-01 17:54:09 +0000478/* Terminate the current IRSB with an emulation failure. */
479static void
480emulation_failure(VexEmNote fail_kind)
481{
482 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_EMNOTE), mkU32(fail_kind)));
floriane75dafa2012-09-01 17:54:09 +0000483 dis_res->whatNext = Dis_StopHere;
484 dis_res->jk_StopHere = Ijk_EmFail;
485}
sewardj2019a972011-03-07 16:04:07 +0000486
florian4b8efad2012-09-02 18:07:08 +0000487/* Terminate the current IRSB with an emulation warning. */
488static void
489emulation_warning(VexEmNote warn_kind)
490{
491 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_EMNOTE), mkU32(warn_kind)));
492 dis_res->whatNext = Dis_StopHere;
493 dis_res->jk_StopHere = Ijk_EmWarn;
494}
495
sewardj2019a972011-03-07 16:04:07 +0000496/*------------------------------------------------------------*/
florianf3410f92012-08-03 18:41:58 +0000497/*--- IR Debugging aids. ---*/
498/*------------------------------------------------------------*/
499#if 0
500
501static ULong
502s390_do_print(HChar *text, ULong value)
503{
504 vex_printf("%s %llu\n", text, value);
505 return 0;
506}
507
508static void
509s390_print(HChar *text, IRExpr *value)
510{
511 IRDirty *d;
512
513 d = unsafeIRDirty_0_N(0 /* regparms */, "s390_do_print", &s390_do_print,
514 mkIRExprVec_2(mkU64((ULong)text), value));
515 stmt(IRStmt_Dirty(d));
516}
517#endif
518
519
520/*------------------------------------------------------------*/
sewardj2019a972011-03-07 16:04:07 +0000521/*--- Build the flags thunk. ---*/
522/*------------------------------------------------------------*/
523
524/* Completely fill the flags thunk. We're always filling all fields.
525 Apparently, that is better for redundant PUT elimination. */
526static void
527s390_cc_thunk_fill(IRExpr *op, IRExpr *dep1, IRExpr *dep2, IRExpr *ndep)
528{
529 UInt op_off, dep1_off, dep2_off, ndep_off;
530
florian428dfdd2012-03-27 03:09:49 +0000531 op_off = S390X_GUEST_OFFSET(guest_CC_OP);
532 dep1_off = S390X_GUEST_OFFSET(guest_CC_DEP1);
533 dep2_off = S390X_GUEST_OFFSET(guest_CC_DEP2);
534 ndep_off = S390X_GUEST_OFFSET(guest_CC_NDEP);
sewardj2019a972011-03-07 16:04:07 +0000535
536 stmt(IRStmt_Put(op_off, op));
537 stmt(IRStmt_Put(dep1_off, dep1));
538 stmt(IRStmt_Put(dep2_off, dep2));
539 stmt(IRStmt_Put(ndep_off, ndep));
540}
541
542
543/* Create an expression for V and widen the result to 64 bit. */
544static IRExpr *
545s390_cc_widen(IRTemp v, Bool sign_extend)
546{
547 IRExpr *expr;
548
549 expr = mkexpr(v);
550
551 switch (typeOfIRTemp(irsb->tyenv, v)) {
552 case Ity_I64:
553 break;
554 case Ity_I32:
555 expr = unop(sign_extend ? Iop_32Sto64 : Iop_32Uto64, expr);
556 break;
557 case Ity_I16:
558 expr = unop(sign_extend ? Iop_16Sto64 : Iop_16Uto64, expr);
559 break;
560 case Ity_I8:
561 expr = unop(sign_extend ? Iop_8Sto64 : Iop_8Uto64, expr);
562 break;
563 default:
564 vpanic("s390_cc_widen");
565 }
566
567 return expr;
568}
569
570static void
571s390_cc_thunk_put1(UInt opc, IRTemp d1, Bool sign_extend)
572{
573 IRExpr *op, *dep1, *dep2, *ndep;
574
575 op = mkU64(opc);
576 dep1 = s390_cc_widen(d1, sign_extend);
577 dep2 = mkU64(0);
578 ndep = mkU64(0);
579
580 s390_cc_thunk_fill(op, dep1, dep2, ndep);
581}
582
583
584static void
585s390_cc_thunk_put2(UInt opc, IRTemp d1, IRTemp d2, Bool sign_extend)
586{
587 IRExpr *op, *dep1, *dep2, *ndep;
588
589 op = mkU64(opc);
590 dep1 = s390_cc_widen(d1, sign_extend);
591 dep2 = s390_cc_widen(d2, sign_extend);
592 ndep = mkU64(0);
593
594 s390_cc_thunk_fill(op, dep1, dep2, ndep);
595}
596
597
598/* memcheck believes that the NDEP field in the flags thunk is always
599 defined. But for some flag computations (e.g. add with carry) that is
600 just not true. We therefore need to convey to memcheck that the value
601 of the ndep field does matter and therefore we make the DEP2 field
602 depend on it:
603
604 DEP2 = original_DEP2 ^ NDEP
605
606 In s390_calculate_cc we exploit that (a^b)^b == a
607 I.e. we xor the DEP2 value with the NDEP value to recover the
608 original_DEP2 value. */
609static void
610s390_cc_thunk_put3(UInt opc, IRTemp d1, IRTemp d2, IRTemp nd, Bool sign_extend)
611{
612 IRExpr *op, *dep1, *dep2, *ndep, *dep2x;
613
614 op = mkU64(opc);
615 dep1 = s390_cc_widen(d1, sign_extend);
616 dep2 = s390_cc_widen(d2, sign_extend);
617 ndep = s390_cc_widen(nd, sign_extend);
618
619 dep2x = binop(Iop_Xor64, dep2, ndep);
620
621 s390_cc_thunk_fill(op, dep1, dep2x, ndep);
622}
623
624
625/* Write one floating point value into the flags thunk */
626static void
627s390_cc_thunk_put1f(UInt opc, IRTemp d1)
628{
629 IRExpr *op, *dep1, *dep2, *ndep;
630
631 op = mkU64(opc);
632 dep1 = mkexpr(d1);
633 dep2 = mkU64(0);
634 ndep = mkU64(0);
635
636 s390_cc_thunk_fill(op, dep1, dep2, ndep);
637}
638
639
640/* Write a floating point value and an integer into the flags thunk. The
641 integer value is zero-extended first. */
642static void
643s390_cc_thunk_putFZ(UInt opc, IRTemp d1, IRTemp d2)
644{
645 IRExpr *op, *dep1, *dep2, *ndep;
646
647 op = mkU64(opc);
648 dep1 = mkexpr(d1);
649 dep2 = s390_cc_widen(d2, False);
650 ndep = mkU64(0);
651
652 s390_cc_thunk_fill(op, dep1, dep2, ndep);
653}
654
655
656/* Write a 128-bit floating point value into the flags thunk. This is
657 done by splitting the value into two 64-bits values. */
658static void
659s390_cc_thunk_put1f128(UInt opc, IRTemp d1)
660{
661 IRExpr *op, *hi, *lo, *ndep;
662
663 op = mkU64(opc);
664 hi = unop(Iop_F128HItoF64, mkexpr(d1));
665 lo = unop(Iop_F128LOtoF64, mkexpr(d1));
666 ndep = mkU64(0);
667
668 s390_cc_thunk_fill(op, hi, lo, ndep);
669}
670
671
672/* Write a 128-bit floating point value and an integer into the flags thunk.
673 The integer value is zero-extended first. */
674static void
675s390_cc_thunk_put1f128Z(UInt opc, IRTemp d1, IRTemp nd)
676{
677 IRExpr *op, *hi, *lo, *lox, *ndep;
678
679 op = mkU64(opc);
680 hi = unop(Iop_F128HItoF64, mkexpr(d1));
681 lo = unop(Iop_ReinterpF64asI64, unop(Iop_F128LOtoF64, mkexpr(d1)));
682 ndep = s390_cc_widen(nd, False);
683
684 lox = binop(Iop_Xor64, lo, ndep); /* convey dependency */
685
686 s390_cc_thunk_fill(op, hi, lox, ndep);
687}
688
689
690static void
691s390_cc_set(UInt val)
692{
693 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
694 mkU64(val), mkU64(0), mkU64(0));
695}
696
697/* Build IR to calculate the condition code from flags thunk.
698 Returns an expression of type Ity_I32 */
699static IRExpr *
700s390_call_calculate_cc(void)
701{
702 IRExpr **args, *call, *op, *dep1, *dep2, *ndep;
703
florian428dfdd2012-03-27 03:09:49 +0000704 op = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_OP), Ity_I64);
705 dep1 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP1), Ity_I64);
706 dep2 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP2), Ity_I64);
707 ndep = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_NDEP), Ity_I64);
sewardj2019a972011-03-07 16:04:07 +0000708
709 args = mkIRExprVec_4(op, dep1, dep2, ndep);
710 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
711 "s390_calculate_cc", &s390_calculate_cc, args);
712
713 /* Exclude OP and NDEP from definedness checking. We're only
714 interested in DEP1 and DEP2. */
715 call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<3);
716
717 return call;
718}
719
720/* Build IR to calculate the internal condition code for a "compare and branch"
721 insn. Returns an expression of type Ity_I32 */
722static IRExpr *
florianff9613f2012-05-12 15:26:44 +0000723s390_call_calculate_icc(UInt m, UInt opc, IRTemp op1, IRTemp op2)
sewardj2019a972011-03-07 16:04:07 +0000724{
florianff9613f2012-05-12 15:26:44 +0000725 IRExpr **args, *call, *op, *dep1, *dep2, *mask;
sewardj2019a972011-03-07 16:04:07 +0000726
florianff9613f2012-05-12 15:26:44 +0000727 switch (opc) {
728 case S390_CC_OP_SIGNED_COMPARE:
729 dep1 = s390_cc_widen(op1, True);
730 dep2 = s390_cc_widen(op2, True);
731 break;
732
733 case S390_CC_OP_UNSIGNED_COMPARE:
734 dep1 = s390_cc_widen(op1, False);
735 dep2 = s390_cc_widen(op2, False);
736 break;
737
738 default:
739 vpanic("s390_call_calculate_icc");
740 }
741
742 mask = mkU64(m);
sewardj2019a972011-03-07 16:04:07 +0000743 op = mkU64(opc);
sewardj2019a972011-03-07 16:04:07 +0000744
florianff9613f2012-05-12 15:26:44 +0000745 args = mkIRExprVec_5(mask, op, dep1, dep2, mkU64(0) /* unused */);
sewardj2019a972011-03-07 16:04:07 +0000746 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
florianff9613f2012-05-12 15:26:44 +0000747 "s390_calculate_cond", &s390_calculate_cond, args);
sewardj2019a972011-03-07 16:04:07 +0000748
florianff9613f2012-05-12 15:26:44 +0000749 /* Exclude the requested condition, OP and NDEP from definedness
750 checking. We're only interested in DEP1 and DEP2. */
751 call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<1) | (1<<4);
sewardj2019a972011-03-07 16:04:07 +0000752
753 return call;
754}
755
756/* Build IR to calculate the condition code from flags thunk.
757 Returns an expression of type Ity_I32 */
758static IRExpr *
759s390_call_calculate_cond(UInt m)
760{
761 IRExpr **args, *call, *op, *dep1, *dep2, *ndep, *mask;
762
763 mask = mkU64(m);
florian428dfdd2012-03-27 03:09:49 +0000764 op = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_OP), Ity_I64);
765 dep1 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP1), Ity_I64);
766 dep2 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP2), Ity_I64);
767 ndep = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_NDEP), Ity_I64);
sewardj2019a972011-03-07 16:04:07 +0000768
769 args = mkIRExprVec_5(mask, op, dep1, dep2, ndep);
770 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
771 "s390_calculate_cond", &s390_calculate_cond, args);
772
773 /* Exclude the requested condition, OP and NDEP from definedness
774 checking. We're only interested in DEP1 and DEP2. */
775 call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<1) | (1<<4);
776
777 return call;
778}
779
780#define s390_cc_thunk_putZ(op,dep1) s390_cc_thunk_put1(op,dep1,False)
781#define s390_cc_thunk_putS(op,dep1) s390_cc_thunk_put1(op,dep1,True)
782#define s390_cc_thunk_putF(op,dep1) s390_cc_thunk_put1f(op,dep1)
783#define s390_cc_thunk_putZZ(op,dep1,dep2) s390_cc_thunk_put2(op,dep1,dep2,False)
784#define s390_cc_thunk_putSS(op,dep1,dep2) s390_cc_thunk_put2(op,dep1,dep2,True)
785#define s390_cc_thunk_putFF(op,dep1,dep2) s390_cc_thunk_put2f(op,dep1,dep2)
786#define s390_cc_thunk_putZZZ(op,dep1,dep2,ndep) \
787 s390_cc_thunk_put3(op,dep1,dep2,ndep,False)
788#define s390_cc_thunk_putSSS(op,dep1,dep2,ndep) \
789 s390_cc_thunk_put3(op,dep1,dep2,ndep,True)
sewardj2019a972011-03-07 16:04:07 +0000790
791
sewardj2019a972011-03-07 16:04:07 +0000792
793
794/*------------------------------------------------------------*/
795/*--- Guest register access ---*/
796/*------------------------------------------------------------*/
797
798
799/*------------------------------------------------------------*/
800/*--- ar registers ---*/
801/*------------------------------------------------------------*/
802
803/* Return the guest state offset of a ar register. */
804static UInt
805ar_offset(UInt archreg)
806{
807 static const UInt offset[16] = {
floriane88b3c92011-07-05 02:48:39 +0000808 S390X_GUEST_OFFSET(guest_a0),
809 S390X_GUEST_OFFSET(guest_a1),
810 S390X_GUEST_OFFSET(guest_a2),
811 S390X_GUEST_OFFSET(guest_a3),
812 S390X_GUEST_OFFSET(guest_a4),
813 S390X_GUEST_OFFSET(guest_a5),
814 S390X_GUEST_OFFSET(guest_a6),
815 S390X_GUEST_OFFSET(guest_a7),
816 S390X_GUEST_OFFSET(guest_a8),
817 S390X_GUEST_OFFSET(guest_a9),
818 S390X_GUEST_OFFSET(guest_a10),
819 S390X_GUEST_OFFSET(guest_a11),
820 S390X_GUEST_OFFSET(guest_a12),
821 S390X_GUEST_OFFSET(guest_a13),
822 S390X_GUEST_OFFSET(guest_a14),
823 S390X_GUEST_OFFSET(guest_a15),
sewardj2019a972011-03-07 16:04:07 +0000824 };
825
826 vassert(archreg < 16);
827
828 return offset[archreg];
829}
830
831
832/* Return the guest state offset of word #0 of a ar register. */
833static __inline__ UInt
834ar_w0_offset(UInt archreg)
835{
836 return ar_offset(archreg) + 0;
837}
838
839/* Write word #0 of a ar to the guest state. */
840static __inline__ void
841put_ar_w0(UInt archreg, IRExpr *expr)
842{
843 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
844
845 stmt(IRStmt_Put(ar_w0_offset(archreg), expr));
846}
847
848/* Read word #0 of a ar register. */
849static __inline__ IRExpr *
850get_ar_w0(UInt archreg)
851{
852 return IRExpr_Get(ar_w0_offset(archreg), Ity_I32);
853}
854
855
856/*------------------------------------------------------------*/
857/*--- fpr registers ---*/
858/*------------------------------------------------------------*/
859
860/* Return the guest state offset of a fpr register. */
861static UInt
862fpr_offset(UInt archreg)
863{
864 static const UInt offset[16] = {
floriane88b3c92011-07-05 02:48:39 +0000865 S390X_GUEST_OFFSET(guest_f0),
866 S390X_GUEST_OFFSET(guest_f1),
867 S390X_GUEST_OFFSET(guest_f2),
868 S390X_GUEST_OFFSET(guest_f3),
869 S390X_GUEST_OFFSET(guest_f4),
870 S390X_GUEST_OFFSET(guest_f5),
871 S390X_GUEST_OFFSET(guest_f6),
872 S390X_GUEST_OFFSET(guest_f7),
873 S390X_GUEST_OFFSET(guest_f8),
874 S390X_GUEST_OFFSET(guest_f9),
875 S390X_GUEST_OFFSET(guest_f10),
876 S390X_GUEST_OFFSET(guest_f11),
877 S390X_GUEST_OFFSET(guest_f12),
878 S390X_GUEST_OFFSET(guest_f13),
879 S390X_GUEST_OFFSET(guest_f14),
880 S390X_GUEST_OFFSET(guest_f15),
sewardj2019a972011-03-07 16:04:07 +0000881 };
882
883 vassert(archreg < 16);
884
885 return offset[archreg];
886}
887
888
889/* Return the guest state offset of word #0 of a fpr register. */
890static __inline__ UInt
891fpr_w0_offset(UInt archreg)
892{
893 return fpr_offset(archreg) + 0;
894}
895
896/* Write word #0 of a fpr to the guest state. */
897static __inline__ void
898put_fpr_w0(UInt archreg, IRExpr *expr)
899{
900 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_F32);
901
902 stmt(IRStmt_Put(fpr_w0_offset(archreg), expr));
903}
904
905/* Read word #0 of a fpr register. */
906static __inline__ IRExpr *
907get_fpr_w0(UInt archreg)
908{
909 return IRExpr_Get(fpr_w0_offset(archreg), Ity_F32);
910}
911
912/* Return the guest state offset of double word #0 of a fpr register. */
913static __inline__ UInt
914fpr_dw0_offset(UInt archreg)
915{
916 return fpr_offset(archreg) + 0;
917}
918
919/* Write double word #0 of a fpr to the guest state. */
920static __inline__ void
921put_fpr_dw0(UInt archreg, IRExpr *expr)
922{
923 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_F64);
924
925 stmt(IRStmt_Put(fpr_dw0_offset(archreg), expr));
926}
927
928/* Read double word #0 of a fpr register. */
929static __inline__ IRExpr *
930get_fpr_dw0(UInt archreg)
931{
932 return IRExpr_Get(fpr_dw0_offset(archreg), Ity_F64);
933}
934
935
936/*------------------------------------------------------------*/
937/*--- gpr registers ---*/
938/*------------------------------------------------------------*/
939
940/* Return the guest state offset of a gpr register. */
941static UInt
942gpr_offset(UInt archreg)
943{
944 static const UInt offset[16] = {
floriane88b3c92011-07-05 02:48:39 +0000945 S390X_GUEST_OFFSET(guest_r0),
946 S390X_GUEST_OFFSET(guest_r1),
947 S390X_GUEST_OFFSET(guest_r2),
948 S390X_GUEST_OFFSET(guest_r3),
949 S390X_GUEST_OFFSET(guest_r4),
950 S390X_GUEST_OFFSET(guest_r5),
951 S390X_GUEST_OFFSET(guest_r6),
952 S390X_GUEST_OFFSET(guest_r7),
953 S390X_GUEST_OFFSET(guest_r8),
954 S390X_GUEST_OFFSET(guest_r9),
955 S390X_GUEST_OFFSET(guest_r10),
956 S390X_GUEST_OFFSET(guest_r11),
957 S390X_GUEST_OFFSET(guest_r12),
958 S390X_GUEST_OFFSET(guest_r13),
959 S390X_GUEST_OFFSET(guest_r14),
960 S390X_GUEST_OFFSET(guest_r15),
sewardj2019a972011-03-07 16:04:07 +0000961 };
962
963 vassert(archreg < 16);
964
965 return offset[archreg];
966}
967
968
969/* Return the guest state offset of word #0 of a gpr register. */
970static __inline__ UInt
971gpr_w0_offset(UInt archreg)
972{
973 return gpr_offset(archreg) + 0;
974}
975
976/* Write word #0 of a gpr to the guest state. */
977static __inline__ void
978put_gpr_w0(UInt archreg, IRExpr *expr)
979{
980 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
981
982 stmt(IRStmt_Put(gpr_w0_offset(archreg), expr));
983}
984
985/* Read word #0 of a gpr register. */
986static __inline__ IRExpr *
987get_gpr_w0(UInt archreg)
988{
989 return IRExpr_Get(gpr_w0_offset(archreg), Ity_I32);
990}
991
992/* Return the guest state offset of double word #0 of a gpr register. */
993static __inline__ UInt
994gpr_dw0_offset(UInt archreg)
995{
996 return gpr_offset(archreg) + 0;
997}
998
999/* Write double word #0 of a gpr to the guest state. */
1000static __inline__ void
1001put_gpr_dw0(UInt archreg, IRExpr *expr)
1002{
1003 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I64);
1004
1005 stmt(IRStmt_Put(gpr_dw0_offset(archreg), expr));
1006}
1007
1008/* Read double word #0 of a gpr register. */
1009static __inline__ IRExpr *
1010get_gpr_dw0(UInt archreg)
1011{
1012 return IRExpr_Get(gpr_dw0_offset(archreg), Ity_I64);
1013}
1014
1015/* Return the guest state offset of half word #1 of a gpr register. */
1016static __inline__ UInt
1017gpr_hw1_offset(UInt archreg)
1018{
1019 return gpr_offset(archreg) + 2;
1020}
1021
1022/* Write half word #1 of a gpr to the guest state. */
1023static __inline__ void
1024put_gpr_hw1(UInt archreg, IRExpr *expr)
1025{
1026 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1027
1028 stmt(IRStmt_Put(gpr_hw1_offset(archreg), expr));
1029}
1030
1031/* Read half word #1 of a gpr register. */
1032static __inline__ IRExpr *
1033get_gpr_hw1(UInt archreg)
1034{
1035 return IRExpr_Get(gpr_hw1_offset(archreg), Ity_I16);
1036}
1037
1038/* Return the guest state offset of byte #6 of a gpr register. */
1039static __inline__ UInt
1040gpr_b6_offset(UInt archreg)
1041{
1042 return gpr_offset(archreg) + 6;
1043}
1044
1045/* Write byte #6 of a gpr to the guest state. */
1046static __inline__ void
1047put_gpr_b6(UInt archreg, IRExpr *expr)
1048{
1049 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1050
1051 stmt(IRStmt_Put(gpr_b6_offset(archreg), expr));
1052}
1053
1054/* Read byte #6 of a gpr register. */
1055static __inline__ IRExpr *
1056get_gpr_b6(UInt archreg)
1057{
1058 return IRExpr_Get(gpr_b6_offset(archreg), Ity_I8);
1059}
1060
1061/* Return the guest state offset of byte #3 of a gpr register. */
1062static __inline__ UInt
1063gpr_b3_offset(UInt archreg)
1064{
1065 return gpr_offset(archreg) + 3;
1066}
1067
1068/* Write byte #3 of a gpr to the guest state. */
1069static __inline__ void
1070put_gpr_b3(UInt archreg, IRExpr *expr)
1071{
1072 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1073
1074 stmt(IRStmt_Put(gpr_b3_offset(archreg), expr));
1075}
1076
1077/* Read byte #3 of a gpr register. */
1078static __inline__ IRExpr *
1079get_gpr_b3(UInt archreg)
1080{
1081 return IRExpr_Get(gpr_b3_offset(archreg), Ity_I8);
1082}
1083
1084/* Return the guest state offset of byte #0 of a gpr register. */
1085static __inline__ UInt
1086gpr_b0_offset(UInt archreg)
1087{
1088 return gpr_offset(archreg) + 0;
1089}
1090
1091/* Write byte #0 of a gpr to the guest state. */
1092static __inline__ void
1093put_gpr_b0(UInt archreg, IRExpr *expr)
1094{
1095 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1096
1097 stmt(IRStmt_Put(gpr_b0_offset(archreg), expr));
1098}
1099
1100/* Read byte #0 of a gpr register. */
1101static __inline__ IRExpr *
1102get_gpr_b0(UInt archreg)
1103{
1104 return IRExpr_Get(gpr_b0_offset(archreg), Ity_I8);
1105}
1106
1107/* Return the guest state offset of word #1 of a gpr register. */
1108static __inline__ UInt
1109gpr_w1_offset(UInt archreg)
1110{
1111 return gpr_offset(archreg) + 4;
1112}
1113
1114/* Write word #1 of a gpr to the guest state. */
1115static __inline__ void
1116put_gpr_w1(UInt archreg, IRExpr *expr)
1117{
1118 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1119
1120 stmt(IRStmt_Put(gpr_w1_offset(archreg), expr));
1121}
1122
1123/* Read word #1 of a gpr register. */
1124static __inline__ IRExpr *
1125get_gpr_w1(UInt archreg)
1126{
1127 return IRExpr_Get(gpr_w1_offset(archreg), Ity_I32);
1128}
1129
1130/* Return the guest state offset of half word #3 of a gpr register. */
1131static __inline__ UInt
1132gpr_hw3_offset(UInt archreg)
1133{
1134 return gpr_offset(archreg) + 6;
1135}
1136
1137/* Write half word #3 of a gpr to the guest state. */
1138static __inline__ void
1139put_gpr_hw3(UInt archreg, IRExpr *expr)
1140{
1141 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1142
1143 stmt(IRStmt_Put(gpr_hw3_offset(archreg), expr));
1144}
1145
1146/* Read half word #3 of a gpr register. */
1147static __inline__ IRExpr *
1148get_gpr_hw3(UInt archreg)
1149{
1150 return IRExpr_Get(gpr_hw3_offset(archreg), Ity_I16);
1151}
1152
1153/* Return the guest state offset of byte #7 of a gpr register. */
1154static __inline__ UInt
1155gpr_b7_offset(UInt archreg)
1156{
1157 return gpr_offset(archreg) + 7;
1158}
1159
1160/* Write byte #7 of a gpr to the guest state. */
1161static __inline__ void
1162put_gpr_b7(UInt archreg, IRExpr *expr)
1163{
1164 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1165
1166 stmt(IRStmt_Put(gpr_b7_offset(archreg), expr));
1167}
1168
1169/* Read byte #7 of a gpr register. */
1170static __inline__ IRExpr *
1171get_gpr_b7(UInt archreg)
1172{
1173 return IRExpr_Get(gpr_b7_offset(archreg), Ity_I8);
1174}
1175
1176/* Return the guest state offset of half word #0 of a gpr register. */
1177static __inline__ UInt
1178gpr_hw0_offset(UInt archreg)
1179{
1180 return gpr_offset(archreg) + 0;
1181}
1182
1183/* Write half word #0 of a gpr to the guest state. */
1184static __inline__ void
1185put_gpr_hw0(UInt archreg, IRExpr *expr)
1186{
1187 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1188
1189 stmt(IRStmt_Put(gpr_hw0_offset(archreg), expr));
1190}
1191
1192/* Read half word #0 of a gpr register. */
1193static __inline__ IRExpr *
1194get_gpr_hw0(UInt archreg)
1195{
1196 return IRExpr_Get(gpr_hw0_offset(archreg), Ity_I16);
1197}
1198
1199/* Return the guest state offset of byte #4 of a gpr register. */
1200static __inline__ UInt
1201gpr_b4_offset(UInt archreg)
1202{
1203 return gpr_offset(archreg) + 4;
1204}
1205
1206/* Write byte #4 of a gpr to the guest state. */
1207static __inline__ void
1208put_gpr_b4(UInt archreg, IRExpr *expr)
1209{
1210 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1211
1212 stmt(IRStmt_Put(gpr_b4_offset(archreg), expr));
1213}
1214
1215/* Read byte #4 of a gpr register. */
1216static __inline__ IRExpr *
1217get_gpr_b4(UInt archreg)
1218{
1219 return IRExpr_Get(gpr_b4_offset(archreg), Ity_I8);
1220}
1221
1222/* Return the guest state offset of byte #1 of a gpr register. */
1223static __inline__ UInt
1224gpr_b1_offset(UInt archreg)
1225{
1226 return gpr_offset(archreg) + 1;
1227}
1228
1229/* Write byte #1 of a gpr to the guest state. */
1230static __inline__ void
1231put_gpr_b1(UInt archreg, IRExpr *expr)
1232{
1233 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1234
1235 stmt(IRStmt_Put(gpr_b1_offset(archreg), expr));
1236}
1237
1238/* Read byte #1 of a gpr register. */
1239static __inline__ IRExpr *
1240get_gpr_b1(UInt archreg)
1241{
1242 return IRExpr_Get(gpr_b1_offset(archreg), Ity_I8);
1243}
1244
1245/* Return the guest state offset of half word #2 of a gpr register. */
1246static __inline__ UInt
1247gpr_hw2_offset(UInt archreg)
1248{
1249 return gpr_offset(archreg) + 4;
1250}
1251
1252/* Write half word #2 of a gpr to the guest state. */
1253static __inline__ void
1254put_gpr_hw2(UInt archreg, IRExpr *expr)
1255{
1256 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1257
1258 stmt(IRStmt_Put(gpr_hw2_offset(archreg), expr));
1259}
1260
1261/* Read half word #2 of a gpr register. */
1262static __inline__ IRExpr *
1263get_gpr_hw2(UInt archreg)
1264{
1265 return IRExpr_Get(gpr_hw2_offset(archreg), Ity_I16);
1266}
1267
1268/* Return the guest state offset of byte #5 of a gpr register. */
1269static __inline__ UInt
1270gpr_b5_offset(UInt archreg)
1271{
1272 return gpr_offset(archreg) + 5;
1273}
1274
1275/* Write byte #5 of a gpr to the guest state. */
1276static __inline__ void
1277put_gpr_b5(UInt archreg, IRExpr *expr)
1278{
1279 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1280
1281 stmt(IRStmt_Put(gpr_b5_offset(archreg), expr));
1282}
1283
1284/* Read byte #5 of a gpr register. */
1285static __inline__ IRExpr *
1286get_gpr_b5(UInt archreg)
1287{
1288 return IRExpr_Get(gpr_b5_offset(archreg), Ity_I8);
1289}
1290
1291/* Return the guest state offset of byte #2 of a gpr register. */
1292static __inline__ UInt
1293gpr_b2_offset(UInt archreg)
1294{
1295 return gpr_offset(archreg) + 2;
1296}
1297
1298/* Write byte #2 of a gpr to the guest state. */
1299static __inline__ void
1300put_gpr_b2(UInt archreg, IRExpr *expr)
1301{
1302 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1303
1304 stmt(IRStmt_Put(gpr_b2_offset(archreg), expr));
1305}
1306
1307/* Read byte #2 of a gpr register. */
1308static __inline__ IRExpr *
1309get_gpr_b2(UInt archreg)
1310{
1311 return IRExpr_Get(gpr_b2_offset(archreg), Ity_I8);
1312}
1313
1314/* Return the guest state offset of the counter register. */
1315static UInt
1316counter_offset(void)
1317{
floriane88b3c92011-07-05 02:48:39 +00001318 return S390X_GUEST_OFFSET(guest_counter);
sewardj2019a972011-03-07 16:04:07 +00001319}
1320
1321/* Return the guest state offset of double word #0 of the counter register. */
1322static __inline__ UInt
1323counter_dw0_offset(void)
1324{
1325 return counter_offset() + 0;
1326}
1327
1328/* Write double word #0 of the counter to the guest state. */
1329static __inline__ void
1330put_counter_dw0(IRExpr *expr)
1331{
1332 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I64);
1333
1334 stmt(IRStmt_Put(counter_dw0_offset(), expr));
1335}
1336
1337/* Read double word #0 of the counter register. */
1338static __inline__ IRExpr *
1339get_counter_dw0(void)
1340{
1341 return IRExpr_Get(counter_dw0_offset(), Ity_I64);
1342}
1343
1344/* Return the guest state offset of word #0 of the counter register. */
1345static __inline__ UInt
1346counter_w0_offset(void)
1347{
1348 return counter_offset() + 0;
1349}
1350
1351/* Return the guest state offset of word #1 of the counter register. */
1352static __inline__ UInt
1353counter_w1_offset(void)
1354{
1355 return counter_offset() + 4;
1356}
1357
1358/* Write word #0 of the counter to the guest state. */
1359static __inline__ void
1360put_counter_w0(IRExpr *expr)
1361{
1362 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1363
1364 stmt(IRStmt_Put(counter_w0_offset(), expr));
1365}
1366
1367/* Read word #0 of the counter register. */
1368static __inline__ IRExpr *
1369get_counter_w0(void)
1370{
1371 return IRExpr_Get(counter_w0_offset(), Ity_I32);
1372}
1373
1374/* Write word #1 of the counter to the guest state. */
1375static __inline__ void
1376put_counter_w1(IRExpr *expr)
1377{
1378 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1379
1380 stmt(IRStmt_Put(counter_w1_offset(), expr));
1381}
1382
1383/* Read word #1 of the counter register. */
1384static __inline__ IRExpr *
1385get_counter_w1(void)
1386{
1387 return IRExpr_Get(counter_w1_offset(), Ity_I32);
1388}
1389
1390/* Return the guest state offset of the fpc register. */
1391static UInt
1392fpc_offset(void)
1393{
floriane88b3c92011-07-05 02:48:39 +00001394 return S390X_GUEST_OFFSET(guest_fpc);
sewardj2019a972011-03-07 16:04:07 +00001395}
1396
1397/* Return the guest state offset of word #0 of the fpc register. */
1398static __inline__ UInt
1399fpc_w0_offset(void)
1400{
1401 return fpc_offset() + 0;
1402}
1403
1404/* Write word #0 of the fpc to the guest state. */
1405static __inline__ void
1406put_fpc_w0(IRExpr *expr)
1407{
1408 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1409
1410 stmt(IRStmt_Put(fpc_w0_offset(), expr));
1411}
1412
1413/* Read word #0 of the fpc register. */
1414static __inline__ IRExpr *
1415get_fpc_w0(void)
1416{
1417 return IRExpr_Get(fpc_w0_offset(), Ity_I32);
1418}
1419
1420
1421/*------------------------------------------------------------*/
1422/*--- Build IR for formats ---*/
1423/*------------------------------------------------------------*/
1424static void
1425s390_format_I(HChar *(*irgen)(UChar i),
1426 UChar i)
1427{
1428 HChar *mnm = irgen(i);
1429
sewardj7ee97522011-05-09 21:45:04 +00001430 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001431 s390_disasm(ENC2(MNM, UINT), mnm, i);
1432}
1433
1434static void
1435s390_format_RI(HChar *(*irgen)(UChar r1, UShort i2),
1436 UChar r1, UShort i2)
1437{
1438 irgen(r1, i2);
1439}
1440
1441static void
1442s390_format_RI_RU(HChar *(*irgen)(UChar r1, UShort i2),
1443 UChar r1, UShort i2)
1444{
1445 HChar *mnm = irgen(r1, i2);
1446
sewardj7ee97522011-05-09 21:45:04 +00001447 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001448 s390_disasm(ENC3(MNM, GPR, UINT), mnm, r1, i2);
1449}
1450
1451static void
1452s390_format_RI_RI(HChar *(*irgen)(UChar r1, UShort i2),
1453 UChar r1, UShort i2)
1454{
1455 HChar *mnm = irgen(r1, i2);
1456
sewardj7ee97522011-05-09 21:45:04 +00001457 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001458 s390_disasm(ENC3(MNM, GPR, INT), mnm, r1, (Int)(Short)i2);
1459}
1460
1461static void
1462s390_format_RI_RP(HChar *(*irgen)(UChar r1, UShort i2),
1463 UChar r1, UShort i2)
1464{
1465 HChar *mnm = irgen(r1, i2);
1466
sewardj7ee97522011-05-09 21:45:04 +00001467 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001468 s390_disasm(ENC3(MNM, GPR, PCREL), mnm, r1, (Int)(Short)i2);
1469}
1470
1471static void
1472s390_format_RIE_RRP(HChar *(*irgen)(UChar r1, UChar r3, UShort i2),
1473 UChar r1, UChar r3, UShort i2)
1474{
1475 HChar *mnm = irgen(r1, r3, i2);
1476
sewardj7ee97522011-05-09 21:45:04 +00001477 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001478 s390_disasm(ENC4(MNM, GPR, GPR, PCREL), mnm, r1, r3, (Int)(Short)i2);
1479}
1480
1481static void
1482s390_format_RIE_RRI0(HChar *(*irgen)(UChar r1, UChar r3, UShort i2),
1483 UChar r1, UChar r3, UShort i2)
1484{
1485 HChar *mnm = irgen(r1, r3, i2);
1486
sewardj7ee97522011-05-09 21:45:04 +00001487 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001488 s390_disasm(ENC4(MNM, GPR, GPR, INT), mnm, r1, r3, (Int)(Short)i2);
1489}
1490
1491static void
1492s390_format_RIE_RRUUU(HChar *(*irgen)(UChar r1, UChar r2, UChar i3, UChar i4,
1493 UChar i5),
1494 UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
1495{
1496 HChar *mnm = irgen(r1, r2, i3, i4, i5);
1497
sewardj7ee97522011-05-09 21:45:04 +00001498 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001499 s390_disasm(ENC6(MNM, GPR, GPR, UINT, UINT, UINT), mnm, r1, r2, i3, i4,
1500 i5);
1501}
1502
1503static void
1504s390_format_RIE_RRPU(HChar *(*irgen)(UChar r1, UChar r2, UShort i4, UChar m3),
1505 UChar r1, UChar r2, UShort i4, UChar m3)
1506{
1507 HChar *mnm = irgen(r1, r2, i4, m3);
1508
sewardj7ee97522011-05-09 21:45:04 +00001509 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001510 s390_disasm(ENC5(XMNM, GPR, GPR, CABM, PCREL), S390_XMNM_CAB, mnm, m3, r1,
1511 r2, m3, (Int)(Short)i4);
1512}
1513
1514static void
1515s390_format_RIE_RUPU(HChar *(*irgen)(UChar r1, UChar m3, UShort i4, UChar i2),
1516 UChar r1, UChar m3, UShort i4, UChar i2)
1517{
1518 HChar *mnm = irgen(r1, m3, i4, i2);
1519
sewardj7ee97522011-05-09 21:45:04 +00001520 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001521 s390_disasm(ENC5(XMNM, GPR, UINT, CABM, PCREL), S390_XMNM_CAB, mnm, m3,
1522 r1, i2, m3, (Int)(Short)i4);
1523}
1524
1525static void
1526s390_format_RIE_RUPI(HChar *(*irgen)(UChar r1, UChar m3, UShort i4, UChar i2),
1527 UChar r1, UChar m3, UShort i4, UChar i2)
1528{
1529 HChar *mnm = irgen(r1, m3, i4, i2);
1530
sewardj7ee97522011-05-09 21:45:04 +00001531 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001532 s390_disasm(ENC5(XMNM, GPR, INT, CABM, PCREL), S390_XMNM_CAB, mnm, m3, r1,
1533 (Int)(Char)i2, m3, (Int)(Short)i4);
1534}
1535
1536static void
1537s390_format_RIL(HChar *(*irgen)(UChar r1, UInt i2),
1538 UChar r1, UInt i2)
1539{
1540 irgen(r1, i2);
1541}
1542
1543static void
1544s390_format_RIL_RU(HChar *(*irgen)(UChar r1, UInt i2),
1545 UChar r1, UInt i2)
1546{
1547 HChar *mnm = irgen(r1, i2);
1548
sewardj7ee97522011-05-09 21:45:04 +00001549 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001550 s390_disasm(ENC3(MNM, GPR, UINT), mnm, r1, i2);
1551}
1552
1553static void
1554s390_format_RIL_RI(HChar *(*irgen)(UChar r1, UInt i2),
1555 UChar r1, UInt i2)
1556{
1557 HChar *mnm = irgen(r1, i2);
1558
sewardj7ee97522011-05-09 21:45:04 +00001559 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001560 s390_disasm(ENC3(MNM, GPR, INT), mnm, r1, i2);
1561}
1562
1563static void
1564s390_format_RIL_RP(HChar *(*irgen)(UChar r1, UInt i2),
1565 UChar r1, UInt i2)
1566{
1567 HChar *mnm = irgen(r1, i2);
1568
sewardj7ee97522011-05-09 21:45:04 +00001569 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001570 s390_disasm(ENC3(MNM, GPR, PCREL), mnm, r1, i2);
1571}
1572
1573static void
1574s390_format_RIL_UP(HChar *(*irgen)(void),
1575 UChar r1, UInt i2)
1576{
1577 HChar *mnm = irgen();
1578
sewardj7ee97522011-05-09 21:45:04 +00001579 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001580 s390_disasm(ENC3(MNM, UINT, PCREL), mnm, r1, i2);
1581}
1582
1583static void
1584s390_format_RIS_RURDI(HChar *(*irgen)(UChar r1, UChar m3, UChar i2,
1585 IRTemp op4addr),
1586 UChar r1, UChar m3, UChar b4, UShort d4, UChar i2)
1587{
1588 HChar *mnm;
1589 IRTemp op4addr = newTemp(Ity_I64);
1590
1591 assign(op4addr, binop(Iop_Add64, mkU64(d4), b4 != 0 ? get_gpr_dw0(b4) :
1592 mkU64(0)));
1593
1594 mnm = irgen(r1, m3, i2, op4addr);
1595
sewardj7ee97522011-05-09 21:45:04 +00001596 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001597 s390_disasm(ENC5(XMNM, GPR, INT, CABM, UDXB), S390_XMNM_CAB, mnm, m3, r1,
1598 (Int)(Char)i2, m3, d4, 0, b4);
1599}
1600
1601static void
1602s390_format_RIS_RURDU(HChar *(*irgen)(UChar r1, UChar m3, UChar i2,
1603 IRTemp op4addr),
1604 UChar r1, UChar m3, UChar b4, UShort d4, UChar i2)
1605{
1606 HChar *mnm;
1607 IRTemp op4addr = newTemp(Ity_I64);
1608
1609 assign(op4addr, binop(Iop_Add64, mkU64(d4), b4 != 0 ? get_gpr_dw0(b4) :
1610 mkU64(0)));
1611
1612 mnm = irgen(r1, m3, i2, op4addr);
1613
sewardj7ee97522011-05-09 21:45:04 +00001614 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001615 s390_disasm(ENC5(XMNM, GPR, UINT, CABM, UDXB), S390_XMNM_CAB, mnm, m3, r1,
1616 i2, m3, d4, 0, b4);
1617}
1618
1619static void
1620s390_format_RR(HChar *(*irgen)(UChar r1, UChar r2),
1621 UChar r1, UChar r2)
1622{
1623 irgen(r1, r2);
1624}
1625
1626static void
1627s390_format_RR_RR(HChar *(*irgen)(UChar r1, UChar r2),
1628 UChar r1, UChar r2)
1629{
1630 HChar *mnm = irgen(r1, r2);
1631
sewardj7ee97522011-05-09 21:45:04 +00001632 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001633 s390_disasm(ENC3(MNM, GPR, GPR), mnm, r1, r2);
1634}
1635
1636static void
1637s390_format_RR_FF(HChar *(*irgen)(UChar r1, UChar r2),
1638 UChar r1, UChar r2)
1639{
1640 HChar *mnm = irgen(r1, r2);
1641
sewardj7ee97522011-05-09 21:45:04 +00001642 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001643 s390_disasm(ENC3(MNM, FPR, FPR), mnm, r1, r2);
1644}
1645
1646static void
1647s390_format_RRE(HChar *(*irgen)(UChar r1, UChar r2),
1648 UChar r1, UChar r2)
1649{
1650 irgen(r1, r2);
1651}
1652
1653static void
1654s390_format_RRE_RR(HChar *(*irgen)(UChar r1, UChar r2),
1655 UChar r1, UChar r2)
1656{
1657 HChar *mnm = irgen(r1, r2);
1658
sewardj7ee97522011-05-09 21:45:04 +00001659 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001660 s390_disasm(ENC3(MNM, GPR, GPR), mnm, r1, r2);
1661}
1662
1663static void
1664s390_format_RRE_FF(HChar *(*irgen)(UChar r1, UChar r2),
1665 UChar r1, UChar r2)
1666{
1667 HChar *mnm = irgen(r1, r2);
1668
sewardj7ee97522011-05-09 21:45:04 +00001669 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001670 s390_disasm(ENC3(MNM, FPR, FPR), mnm, r1, r2);
1671}
1672
1673static void
1674s390_format_RRE_RF(HChar *(*irgen)(UChar, UChar),
1675 UChar r1, UChar r2)
1676{
1677 HChar *mnm = irgen(r1, r2);
1678
sewardj7ee97522011-05-09 21:45:04 +00001679 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001680 s390_disasm(ENC3(MNM, GPR, FPR), mnm, r1, r2);
1681}
1682
1683static void
1684s390_format_RRE_FR(HChar *(*irgen)(UChar r1, UChar r2),
1685 UChar r1, UChar r2)
1686{
1687 HChar *mnm = irgen(r1, r2);
1688
sewardj7ee97522011-05-09 21:45:04 +00001689 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001690 s390_disasm(ENC3(MNM, FPR, GPR), mnm, r1, r2);
1691}
1692
1693static void
1694s390_format_RRE_R0(HChar *(*irgen)(UChar r1),
1695 UChar r1)
1696{
1697 HChar *mnm = irgen(r1);
1698
sewardj7ee97522011-05-09 21:45:04 +00001699 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001700 s390_disasm(ENC2(MNM, GPR), mnm, r1);
1701}
1702
1703static void
1704s390_format_RRE_F0(HChar *(*irgen)(UChar r1),
1705 UChar r1)
1706{
1707 HChar *mnm = irgen(r1);
1708
sewardj7ee97522011-05-09 21:45:04 +00001709 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001710 s390_disasm(ENC2(MNM, FPR), mnm, r1);
1711}
1712
1713static void
florian9af37692012-01-15 21:01:16 +00001714s390_format_RRF_M0RERE(HChar *(*irgen)(UChar m3, UChar r1, UChar r2),
1715 UChar m3, UChar r1, UChar r2)
1716{
florianfed3ea32012-07-19 14:54:03 +00001717 HChar *mnm = irgen(m3, r1, r2);
florian9af37692012-01-15 21:01:16 +00001718
1719 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
florianfed3ea32012-07-19 14:54:03 +00001720 s390_disasm(ENC4(MNM, GPR, GPR, UINT), mnm, r1, r2, m3);
florian9af37692012-01-15 21:01:16 +00001721}
1722
1723static void
sewardj2019a972011-03-07 16:04:07 +00001724s390_format_RRF_F0FF(HChar *(*irgen)(UChar, UChar, UChar),
1725 UChar r1, UChar r3, UChar r2)
1726{
1727 HChar *mnm = irgen(r1, r3, r2);
1728
sewardj7ee97522011-05-09 21:45:04 +00001729 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001730 s390_disasm(ENC4(MNM, FPR, FPR, FPR), mnm, r1, r3, r2);
1731}
1732
1733static void
florian4b8efad2012-09-02 18:07:08 +00001734s390_format_RRF_UUFF(HChar *(*irgen)(UChar m3, UChar m4, UChar r1, UChar r2),
1735 UChar m3, UChar m4, UChar r1, UChar r2)
1736{
1737 HChar *mnm = irgen(m3, m4, r1, r2);
1738
1739 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
1740 s390_disasm(ENC5(MNM, FPR, UINT, FPR, UINT), mnm, r1, m3, r2, m4);
1741}
1742
1743static void
florian1c8f7ff2012-09-01 00:12:11 +00001744s390_format_RRF_UUFR(HChar *(*irgen)(UChar m3, UChar m4, UChar r1, UChar r2),
1745 UChar m3, UChar m4, UChar r1, UChar r2)
1746{
1747 HChar *mnm = irgen(m3, m4, r1, r2);
1748
1749 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
1750 s390_disasm(ENC5(MNM, FPR, UINT, GPR, UINT), mnm, r1, m3, r2, m4);
1751}
1752
1753static void
1754s390_format_RRF_UURF(HChar *(*irgen)(UChar m3, UChar m4, UChar r1, UChar r2),
1755 UChar m3, UChar m4, UChar r1, UChar r2)
1756{
1757 HChar *mnm = irgen(m3, m4, r1, r2);
1758
1759 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
1760 s390_disasm(ENC5(MNM, GPR, UINT, FPR, UINT), mnm, r1, m3, r2, m4);
1761}
1762
1763
1764static void
sewardjd7bde722011-04-05 13:19:33 +00001765s390_format_RRF_U0RR(HChar *(*irgen)(UChar m3, UChar r1, UChar r2),
1766 UChar m3, UChar r1, UChar r2, Int xmnm_kind)
1767{
1768 irgen(m3, r1, r2);
1769
sewardj7ee97522011-05-09 21:45:04 +00001770 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardjd7bde722011-04-05 13:19:33 +00001771 s390_disasm(ENC3(XMNM, GPR, GPR), xmnm_kind, m3, r1, r2);
1772}
1773
1774static void
sewardj2019a972011-03-07 16:04:07 +00001775s390_format_RRF_F0FF2(HChar *(*irgen)(UChar, UChar, UChar),
1776 UChar r3, UChar r1, UChar r2)
1777{
1778 HChar *mnm = irgen(r3, r1, r2);
1779
sewardj7ee97522011-05-09 21:45:04 +00001780 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001781 s390_disasm(ENC4(MNM, FPR, FPR, FPR), mnm, r1, r3, r2);
1782}
1783
1784static void
1785s390_format_RRF_R0RR2(HChar *(*irgen)(UChar r3, UChar r1, UChar r2),
1786 UChar r3, UChar r1, UChar r2)
1787{
1788 HChar *mnm = irgen(r3, r1, r2);
1789
sewardj7ee97522011-05-09 21:45:04 +00001790 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001791 s390_disasm(ENC4(MNM, GPR, GPR, GPR), mnm, r1, r2, r3);
1792}
1793
1794static void
1795s390_format_RRS(HChar *(*irgen)(UChar r1, UChar r2, UChar m3, IRTemp op4addr),
1796 UChar r1, UChar r2, UChar b4, UShort d4, UChar m3)
1797{
1798 HChar *mnm;
1799 IRTemp op4addr = newTemp(Ity_I64);
1800
1801 assign(op4addr, binop(Iop_Add64, mkU64(d4), b4 != 0 ? get_gpr_dw0(b4) :
1802 mkU64(0)));
1803
1804 mnm = irgen(r1, r2, m3, op4addr);
1805
sewardj7ee97522011-05-09 21:45:04 +00001806 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001807 s390_disasm(ENC5(XMNM, GPR, GPR, CABM, UDXB), S390_XMNM_CAB, mnm, m3, r1,
1808 r2, m3, d4, 0, b4);
1809}
1810
1811static void
1812s390_format_RS_R0RD(HChar *(*irgen)(UChar r1, IRTemp op2addr),
1813 UChar r1, UChar b2, UShort d2)
1814{
1815 HChar *mnm;
1816 IRTemp op2addr = newTemp(Ity_I64);
1817
1818 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
1819 mkU64(0)));
1820
1821 mnm = irgen(r1, op2addr);
1822
sewardj7ee97522011-05-09 21:45:04 +00001823 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001824 s390_disasm(ENC3(MNM, GPR, UDXB), mnm, r1, d2, 0, b2);
1825}
1826
1827static void
1828s390_format_RS_RRRD(HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
1829 UChar r1, UChar r3, UChar b2, UShort d2)
1830{
1831 HChar *mnm;
1832 IRTemp op2addr = newTemp(Ity_I64);
1833
1834 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
1835 mkU64(0)));
1836
1837 mnm = irgen(r1, r3, op2addr);
1838
sewardj7ee97522011-05-09 21:45:04 +00001839 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001840 s390_disasm(ENC4(MNM, GPR, GPR, UDXB), mnm, r1, r3, d2, 0, b2);
1841}
1842
1843static void
1844s390_format_RS_RURD(HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
1845 UChar r1, UChar r3, UChar b2, UShort d2)
1846{
1847 HChar *mnm;
1848 IRTemp op2addr = newTemp(Ity_I64);
1849
1850 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
1851 mkU64(0)));
1852
1853 mnm = irgen(r1, r3, op2addr);
1854
sewardj7ee97522011-05-09 21:45:04 +00001855 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001856 s390_disasm(ENC4(MNM, GPR, UINT, UDXB), mnm, r1, r3, d2, 0, b2);
1857}
1858
1859static void
1860s390_format_RS_AARD(HChar *(*irgen)(UChar, UChar, IRTemp),
1861 UChar r1, UChar r3, UChar b2, UShort d2)
1862{
1863 HChar *mnm;
1864 IRTemp op2addr = newTemp(Ity_I64);
1865
1866 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
1867 mkU64(0)));
1868
1869 mnm = irgen(r1, r3, op2addr);
1870
sewardj7ee97522011-05-09 21:45:04 +00001871 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001872 s390_disasm(ENC4(MNM, AR, AR, UDXB), mnm, r1, r3, d2, 0, b2);
1873}
1874
1875static void
1876s390_format_RSI_RRP(HChar *(*irgen)(UChar r1, UChar r3, UShort i2),
1877 UChar r1, UChar r3, UShort i2)
1878{
1879 HChar *mnm = irgen(r1, r3, i2);
1880
sewardj7ee97522011-05-09 21:45:04 +00001881 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001882 s390_disasm(ENC4(MNM, GPR, GPR, PCREL), mnm, r1, r3, (Int)(Short)i2);
1883}
1884
1885static void
1886s390_format_RSY_RRRD(HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
1887 UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2)
1888{
1889 HChar *mnm;
1890 IRTemp op2addr = newTemp(Ity_I64);
1891 IRTemp d2 = newTemp(Ity_I64);
1892
1893 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
1894 assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
1895 mkU64(0)));
1896
1897 mnm = irgen(r1, r3, op2addr);
1898
sewardj7ee97522011-05-09 21:45:04 +00001899 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001900 s390_disasm(ENC4(MNM, GPR, GPR, SDXB), mnm, r1, r3, dh2, dl2, 0, b2);
1901}
1902
1903static void
1904s390_format_RSY_AARD(HChar *(*irgen)(UChar, UChar, IRTemp),
1905 UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2)
1906{
1907 HChar *mnm;
1908 IRTemp op2addr = newTemp(Ity_I64);
1909 IRTemp d2 = newTemp(Ity_I64);
1910
1911 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
1912 assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
1913 mkU64(0)));
1914
1915 mnm = irgen(r1, r3, op2addr);
1916
sewardj7ee97522011-05-09 21:45:04 +00001917 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001918 s390_disasm(ENC4(MNM, AR, AR, SDXB), mnm, r1, r3, dh2, dl2, 0, b2);
1919}
1920
1921static void
1922s390_format_RSY_RURD(HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
1923 UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2)
1924{
1925 HChar *mnm;
1926 IRTemp op2addr = newTemp(Ity_I64);
1927 IRTemp d2 = newTemp(Ity_I64);
1928
1929 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
1930 assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
1931 mkU64(0)));
1932
1933 mnm = irgen(r1, r3, op2addr);
1934
sewardj7ee97522011-05-09 21:45:04 +00001935 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001936 s390_disasm(ENC4(MNM, GPR, UINT, SDXB), mnm, r1, r3, dh2, dl2, 0, b2);
1937}
1938
1939static void
sewardjd7bde722011-04-05 13:19:33 +00001940s390_format_RSY_RDRM(HChar *(*irgen)(UChar r1, IRTemp op2addr),
1941 UChar r1, UChar m3, UChar b2, UShort dl2, UChar dh2,
1942 Int xmnm_kind)
1943{
1944 IRTemp op2addr = newTemp(Ity_I64);
1945 IRTemp d2 = newTemp(Ity_I64);
1946
florian6820ba52012-07-26 02:01:50 +00001947 next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0)));
1948
sewardjd7bde722011-04-05 13:19:33 +00001949 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
1950 assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
1951 mkU64(0)));
1952
1953 irgen(r1, op2addr);
florian6820ba52012-07-26 02:01:50 +00001954
1955 vassert(dis_res->whatNext == Dis_Continue);
sewardjd7bde722011-04-05 13:19:33 +00001956
sewardj7ee97522011-05-09 21:45:04 +00001957 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardjd7bde722011-04-05 13:19:33 +00001958 s390_disasm(ENC3(XMNM, GPR, SDXB), xmnm_kind, m3, r1, dh2, dl2, 0, b2);
1959}
1960
1961static void
sewardj2019a972011-03-07 16:04:07 +00001962s390_format_RX(HChar *(*irgen)(UChar r1, UChar x2, UChar b2, UShort d2,
1963 IRTemp op2addr),
1964 UChar r1, UChar x2, UChar b2, UShort d2)
1965{
1966 IRTemp op2addr = newTemp(Ity_I64);
1967
1968 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
1969 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
1970 mkU64(0)));
1971
1972 irgen(r1, x2, b2, d2, op2addr);
1973}
1974
1975static void
1976s390_format_RX_RRRD(HChar *(*irgen)(UChar r1, IRTemp op2addr),
1977 UChar r1, UChar x2, UChar b2, UShort d2)
1978{
1979 HChar *mnm;
1980 IRTemp op2addr = newTemp(Ity_I64);
1981
1982 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
1983 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
1984 mkU64(0)));
1985
1986 mnm = irgen(r1, op2addr);
1987
sewardj7ee97522011-05-09 21:45:04 +00001988 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001989 s390_disasm(ENC3(MNM, GPR, UDXB), mnm, r1, d2, x2, b2);
1990}
1991
1992static void
1993s390_format_RX_FRRD(HChar *(*irgen)(UChar r1, IRTemp op2addr),
1994 UChar r1, UChar x2, UChar b2, UShort d2)
1995{
1996 HChar *mnm;
1997 IRTemp op2addr = newTemp(Ity_I64);
1998
1999 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
2000 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2001 mkU64(0)));
2002
2003 mnm = irgen(r1, op2addr);
2004
sewardj7ee97522011-05-09 21:45:04 +00002005 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002006 s390_disasm(ENC3(MNM, FPR, UDXB), mnm, r1, d2, x2, b2);
2007}
2008
2009static void
2010s390_format_RXE_FRRD(HChar *(*irgen)(UChar r1, IRTemp op2addr),
2011 UChar r1, UChar x2, UChar b2, UShort d2)
2012{
2013 HChar *mnm;
2014 IRTemp op2addr = newTemp(Ity_I64);
2015
2016 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
2017 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2018 mkU64(0)));
2019
2020 mnm = irgen(r1, op2addr);
2021
sewardj7ee97522011-05-09 21:45:04 +00002022 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002023 s390_disasm(ENC3(MNM, FPR, UDXB), mnm, r1, d2, x2, b2);
2024}
2025
2026static void
2027s390_format_RXF_FRRDF(HChar *(*irgen)(UChar, IRTemp, UChar),
2028 UChar r3, UChar x2, UChar b2, UShort d2, UChar r1)
2029{
2030 HChar *mnm;
2031 IRTemp op2addr = newTemp(Ity_I64);
2032
2033 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
2034 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2035 mkU64(0)));
2036
2037 mnm = irgen(r3, op2addr, r1);
2038
sewardj7ee97522011-05-09 21:45:04 +00002039 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002040 s390_disasm(ENC4(MNM, FPR, FPR, UDXB), mnm, r1, r3, d2, x2, b2);
2041}
2042
2043static void
2044s390_format_RXY_RRRD(HChar *(*irgen)(UChar r1, IRTemp op2addr),
2045 UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
2046{
2047 HChar *mnm;
2048 IRTemp op2addr = newTemp(Ity_I64);
2049 IRTemp d2 = newTemp(Ity_I64);
2050
2051 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2052 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkexpr(d2),
2053 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2054 mkU64(0)));
2055
2056 mnm = irgen(r1, op2addr);
2057
sewardj7ee97522011-05-09 21:45:04 +00002058 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002059 s390_disasm(ENC3(MNM, GPR, SDXB), mnm, r1, dh2, dl2, x2, b2);
2060}
2061
2062static void
2063s390_format_RXY_FRRD(HChar *(*irgen)(UChar r1, IRTemp op2addr),
2064 UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
2065{
2066 HChar *mnm;
2067 IRTemp op2addr = newTemp(Ity_I64);
2068 IRTemp d2 = newTemp(Ity_I64);
2069
2070 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2071 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkexpr(d2),
2072 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2073 mkU64(0)));
2074
2075 mnm = irgen(r1, op2addr);
2076
sewardj7ee97522011-05-09 21:45:04 +00002077 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002078 s390_disasm(ENC3(MNM, FPR, SDXB), mnm, r1, dh2, dl2, x2, b2);
2079}
2080
2081static void
2082s390_format_RXY_URRD(HChar *(*irgen)(void),
2083 UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
2084{
2085 HChar *mnm;
2086 IRTemp op2addr = newTemp(Ity_I64);
2087 IRTemp d2 = newTemp(Ity_I64);
2088
2089 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2090 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkexpr(d2),
2091 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2092 mkU64(0)));
2093
2094 mnm = irgen();
2095
sewardj7ee97522011-05-09 21:45:04 +00002096 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002097 s390_disasm(ENC3(MNM, UINT, SDXB), mnm, r1, dh2, dl2, x2, b2);
2098}
2099
2100static void
2101s390_format_S_RD(HChar *(*irgen)(IRTemp op2addr),
2102 UChar b2, UShort d2)
2103{
2104 HChar *mnm;
2105 IRTemp op2addr = newTemp(Ity_I64);
2106
2107 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2108 mkU64(0)));
2109
2110 mnm = irgen(op2addr);
2111
sewardj7ee97522011-05-09 21:45:04 +00002112 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002113 s390_disasm(ENC2(MNM, UDXB), mnm, d2, 0, b2);
2114}
2115
2116static void
2117s390_format_SI_URD(HChar *(*irgen)(UChar i2, IRTemp op1addr),
2118 UChar i2, UChar b1, UShort d1)
2119{
2120 HChar *mnm;
2121 IRTemp op1addr = newTemp(Ity_I64);
2122
2123 assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
2124 mkU64(0)));
2125
2126 mnm = irgen(i2, op1addr);
2127
sewardj7ee97522011-05-09 21:45:04 +00002128 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002129 s390_disasm(ENC3(MNM, UDXB, UINT), mnm, d1, 0, b1, i2);
2130}
2131
2132static void
2133s390_format_SIY_URD(HChar *(*irgen)(UChar i2, IRTemp op1addr),
2134 UChar i2, UChar b1, UShort dl1, UChar dh1)
2135{
2136 HChar *mnm;
2137 IRTemp op1addr = newTemp(Ity_I64);
2138 IRTemp d1 = newTemp(Ity_I64);
2139
2140 assign(d1, mkU64(((ULong)(Long)(Char)dh1 << 12) | ((ULong)dl1)));
2141 assign(op1addr, binop(Iop_Add64, mkexpr(d1), b1 != 0 ? get_gpr_dw0(b1) :
2142 mkU64(0)));
2143
2144 mnm = irgen(i2, op1addr);
2145
sewardj7ee97522011-05-09 21:45:04 +00002146 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002147 s390_disasm(ENC3(MNM, SDXB, UINT), mnm, dh1, dl1, 0, b1, i2);
2148}
2149
2150static void
2151s390_format_SIY_IRD(HChar *(*irgen)(UChar i2, IRTemp op1addr),
2152 UChar i2, UChar b1, UShort dl1, UChar dh1)
2153{
2154 HChar *mnm;
2155 IRTemp op1addr = newTemp(Ity_I64);
2156 IRTemp d1 = newTemp(Ity_I64);
2157
2158 assign(d1, mkU64(((ULong)(Long)(Char)dh1 << 12) | ((ULong)dl1)));
2159 assign(op1addr, binop(Iop_Add64, mkexpr(d1), b1 != 0 ? get_gpr_dw0(b1) :
2160 mkU64(0)));
2161
2162 mnm = irgen(i2, op1addr);
2163
sewardj7ee97522011-05-09 21:45:04 +00002164 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002165 s390_disasm(ENC3(MNM, SDXB, INT), mnm, dh1, dl1, 0, b1, (Int)(Char)i2);
2166}
2167
2168static void
2169s390_format_SS_L0RDRD(HChar *(*irgen)(UChar, IRTemp, IRTemp),
2170 UChar l, UChar b1, UShort d1, UChar b2, UShort d2)
2171{
2172 HChar *mnm;
2173 IRTemp op1addr = newTemp(Ity_I64);
2174 IRTemp op2addr = newTemp(Ity_I64);
2175
2176 assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
2177 mkU64(0)));
2178 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2179 mkU64(0)));
2180
2181 mnm = irgen(l, op1addr, op2addr);
2182
sewardj7ee97522011-05-09 21:45:04 +00002183 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002184 s390_disasm(ENC3(MNM, UDLB, UDXB), mnm, d1, l, b1, d2, 0, b2);
2185}
2186
2187static void
2188s390_format_SIL_RDI(HChar *(*irgen)(UShort i2, IRTemp op1addr),
2189 UChar b1, UShort d1, UShort i2)
2190{
2191 HChar *mnm;
2192 IRTemp op1addr = newTemp(Ity_I64);
2193
2194 assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
2195 mkU64(0)));
2196
2197 mnm = irgen(i2, op1addr);
2198
sewardj7ee97522011-05-09 21:45:04 +00002199 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002200 s390_disasm(ENC3(MNM, UDXB, INT), mnm, d1, 0, b1, (Int)(Short)i2);
2201}
2202
2203static void
2204s390_format_SIL_RDU(HChar *(*irgen)(UShort i2, IRTemp op1addr),
2205 UChar b1, UShort d1, UShort i2)
2206{
2207 HChar *mnm;
2208 IRTemp op1addr = newTemp(Ity_I64);
2209
2210 assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
2211 mkU64(0)));
2212
2213 mnm = irgen(i2, op1addr);
2214
sewardj7ee97522011-05-09 21:45:04 +00002215 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002216 s390_disasm(ENC3(MNM, UDXB, UINT), mnm, d1, 0, b1, i2);
2217}
2218
2219
2220
2221/*------------------------------------------------------------*/
2222/*--- Build IR for opcodes ---*/
2223/*------------------------------------------------------------*/
2224
2225static HChar *
2226s390_irgen_AR(UChar r1, UChar r2)
2227{
2228 IRTemp op1 = newTemp(Ity_I32);
2229 IRTemp op2 = newTemp(Ity_I32);
2230 IRTemp result = newTemp(Ity_I32);
2231
2232 assign(op1, get_gpr_w1(r1));
2233 assign(op2, get_gpr_w1(r2));
2234 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2235 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2236 put_gpr_w1(r1, mkexpr(result));
2237
2238 return "ar";
2239}
2240
2241static HChar *
2242s390_irgen_AGR(UChar r1, UChar r2)
2243{
2244 IRTemp op1 = newTemp(Ity_I64);
2245 IRTemp op2 = newTemp(Ity_I64);
2246 IRTemp result = newTemp(Ity_I64);
2247
2248 assign(op1, get_gpr_dw0(r1));
2249 assign(op2, get_gpr_dw0(r2));
2250 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2251 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
2252 put_gpr_dw0(r1, mkexpr(result));
2253
2254 return "agr";
2255}
2256
2257static HChar *
2258s390_irgen_AGFR(UChar r1, UChar r2)
2259{
2260 IRTemp op1 = newTemp(Ity_I64);
2261 IRTemp op2 = newTemp(Ity_I64);
2262 IRTemp result = newTemp(Ity_I64);
2263
2264 assign(op1, get_gpr_dw0(r1));
2265 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
2266 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2267 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
2268 put_gpr_dw0(r1, mkexpr(result));
2269
2270 return "agfr";
2271}
2272
2273static HChar *
2274s390_irgen_ARK(UChar r3, UChar r1, UChar r2)
2275{
2276 IRTemp op2 = newTemp(Ity_I32);
2277 IRTemp op3 = newTemp(Ity_I32);
2278 IRTemp result = newTemp(Ity_I32);
2279
2280 assign(op2, get_gpr_w1(r2));
2281 assign(op3, get_gpr_w1(r3));
2282 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2283 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
2284 put_gpr_w1(r1, mkexpr(result));
2285
2286 return "ark";
2287}
2288
2289static HChar *
2290s390_irgen_AGRK(UChar r3, UChar r1, UChar r2)
2291{
2292 IRTemp op2 = newTemp(Ity_I64);
2293 IRTemp op3 = newTemp(Ity_I64);
2294 IRTemp result = newTemp(Ity_I64);
2295
2296 assign(op2, get_gpr_dw0(r2));
2297 assign(op3, get_gpr_dw0(r3));
2298 assign(result, binop(Iop_Add64, mkexpr(op2), mkexpr(op3)));
2299 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op2, op3);
2300 put_gpr_dw0(r1, mkexpr(result));
2301
2302 return "agrk";
2303}
2304
2305static HChar *
2306s390_irgen_A(UChar r1, IRTemp op2addr)
2307{
2308 IRTemp op1 = newTemp(Ity_I32);
2309 IRTemp op2 = newTemp(Ity_I32);
2310 IRTemp result = newTemp(Ity_I32);
2311
2312 assign(op1, get_gpr_w1(r1));
2313 assign(op2, load(Ity_I32, mkexpr(op2addr)));
2314 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2315 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2316 put_gpr_w1(r1, mkexpr(result));
2317
2318 return "a";
2319}
2320
2321static HChar *
2322s390_irgen_AY(UChar r1, IRTemp op2addr)
2323{
2324 IRTemp op1 = newTemp(Ity_I32);
2325 IRTemp op2 = newTemp(Ity_I32);
2326 IRTemp result = newTemp(Ity_I32);
2327
2328 assign(op1, get_gpr_w1(r1));
2329 assign(op2, load(Ity_I32, mkexpr(op2addr)));
2330 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2331 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2332 put_gpr_w1(r1, mkexpr(result));
2333
2334 return "ay";
2335}
2336
2337static HChar *
2338s390_irgen_AG(UChar r1, IRTemp op2addr)
2339{
2340 IRTemp op1 = newTemp(Ity_I64);
2341 IRTemp op2 = newTemp(Ity_I64);
2342 IRTemp result = newTemp(Ity_I64);
2343
2344 assign(op1, get_gpr_dw0(r1));
2345 assign(op2, load(Ity_I64, mkexpr(op2addr)));
2346 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2347 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
2348 put_gpr_dw0(r1, mkexpr(result));
2349
2350 return "ag";
2351}
2352
2353static HChar *
2354s390_irgen_AGF(UChar r1, IRTemp op2addr)
2355{
2356 IRTemp op1 = newTemp(Ity_I64);
2357 IRTemp op2 = newTemp(Ity_I64);
2358 IRTemp result = newTemp(Ity_I64);
2359
2360 assign(op1, get_gpr_dw0(r1));
2361 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
2362 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2363 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
2364 put_gpr_dw0(r1, mkexpr(result));
2365
2366 return "agf";
2367}
2368
2369static HChar *
2370s390_irgen_AFI(UChar r1, UInt i2)
2371{
2372 IRTemp op1 = newTemp(Ity_I32);
2373 Int op2;
2374 IRTemp result = newTemp(Ity_I32);
2375
2376 assign(op1, get_gpr_w1(r1));
2377 op2 = (Int)i2;
2378 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
2379 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
2380 mkU32((UInt)op2)));
2381 put_gpr_w1(r1, mkexpr(result));
2382
2383 return "afi";
2384}
2385
2386static HChar *
2387s390_irgen_AGFI(UChar r1, UInt i2)
2388{
2389 IRTemp op1 = newTemp(Ity_I64);
2390 Long op2;
2391 IRTemp result = newTemp(Ity_I64);
2392
2393 assign(op1, get_gpr_dw0(r1));
2394 op2 = (Long)(Int)i2;
2395 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64((ULong)op2)));
2396 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, mktemp(Ity_I64,
2397 mkU64((ULong)op2)));
2398 put_gpr_dw0(r1, mkexpr(result));
2399
2400 return "agfi";
2401}
2402
2403static HChar *
2404s390_irgen_AHIK(UChar r1, UChar r3, UShort i2)
2405{
2406 Int op2;
2407 IRTemp op3 = newTemp(Ity_I32);
2408 IRTemp result = newTemp(Ity_I32);
2409
2410 op2 = (Int)(Short)i2;
2411 assign(op3, get_gpr_w1(r3));
2412 assign(result, binop(Iop_Add32, mkU32((UInt)op2), mkexpr(op3)));
2413 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, mktemp(Ity_I32, mkU32((UInt)
2414 op2)), op3);
2415 put_gpr_w1(r1, mkexpr(result));
2416
2417 return "ahik";
2418}
2419
2420static HChar *
2421s390_irgen_AGHIK(UChar r1, UChar r3, UShort i2)
2422{
2423 Long op2;
2424 IRTemp op3 = newTemp(Ity_I64);
2425 IRTemp result = newTemp(Ity_I64);
2426
2427 op2 = (Long)(Short)i2;
2428 assign(op3, get_gpr_dw0(r3));
2429 assign(result, binop(Iop_Add64, mkU64((ULong)op2), mkexpr(op3)));
2430 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, mktemp(Ity_I64, mkU64((ULong)
2431 op2)), op3);
2432 put_gpr_dw0(r1, mkexpr(result));
2433
2434 return "aghik";
2435}
2436
2437static HChar *
2438s390_irgen_ASI(UChar i2, IRTemp op1addr)
2439{
2440 IRTemp op1 = newTemp(Ity_I32);
2441 Int op2;
2442 IRTemp result = newTemp(Ity_I32);
2443
2444 assign(op1, load(Ity_I32, mkexpr(op1addr)));
2445 op2 = (Int)(Char)i2;
2446 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
2447 store(mkexpr(op1addr), mkexpr(result));
2448 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
2449 mkU32((UInt)op2)));
2450
2451 return "asi";
2452}
2453
2454static HChar *
2455s390_irgen_AGSI(UChar i2, IRTemp op1addr)
2456{
2457 IRTemp op1 = newTemp(Ity_I64);
2458 Long op2;
2459 IRTemp result = newTemp(Ity_I64);
2460
2461 assign(op1, load(Ity_I64, mkexpr(op1addr)));
2462 op2 = (Long)(Char)i2;
2463 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64((ULong)op2)));
2464 store(mkexpr(op1addr), mkexpr(result));
2465 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, mktemp(Ity_I64,
2466 mkU64((ULong)op2)));
2467
2468 return "agsi";
2469}
2470
2471static HChar *
2472s390_irgen_AH(UChar r1, IRTemp op2addr)
2473{
2474 IRTemp op1 = newTemp(Ity_I32);
2475 IRTemp op2 = newTemp(Ity_I32);
2476 IRTemp result = newTemp(Ity_I32);
2477
2478 assign(op1, get_gpr_w1(r1));
2479 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
2480 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2481 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2482 put_gpr_w1(r1, mkexpr(result));
2483
2484 return "ah";
2485}
2486
2487static HChar *
2488s390_irgen_AHY(UChar r1, IRTemp op2addr)
2489{
2490 IRTemp op1 = newTemp(Ity_I32);
2491 IRTemp op2 = newTemp(Ity_I32);
2492 IRTemp result = newTemp(Ity_I32);
2493
2494 assign(op1, get_gpr_w1(r1));
2495 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
2496 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2497 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2498 put_gpr_w1(r1, mkexpr(result));
2499
2500 return "ahy";
2501}
2502
2503static HChar *
2504s390_irgen_AHI(UChar r1, UShort i2)
2505{
2506 IRTemp op1 = newTemp(Ity_I32);
2507 Int op2;
2508 IRTemp result = newTemp(Ity_I32);
2509
2510 assign(op1, get_gpr_w1(r1));
2511 op2 = (Int)(Short)i2;
2512 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
2513 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
2514 mkU32((UInt)op2)));
2515 put_gpr_w1(r1, mkexpr(result));
2516
2517 return "ahi";
2518}
2519
2520static HChar *
2521s390_irgen_AGHI(UChar r1, UShort i2)
2522{
2523 IRTemp op1 = newTemp(Ity_I64);
2524 Long op2;
2525 IRTemp result = newTemp(Ity_I64);
2526
2527 assign(op1, get_gpr_dw0(r1));
2528 op2 = (Long)(Short)i2;
2529 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64((ULong)op2)));
2530 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, mktemp(Ity_I64,
2531 mkU64((ULong)op2)));
2532 put_gpr_dw0(r1, mkexpr(result));
2533
2534 return "aghi";
2535}
2536
2537static HChar *
2538s390_irgen_AHHHR(UChar r3, UChar r1, UChar r2)
2539{
2540 IRTemp op2 = newTemp(Ity_I32);
2541 IRTemp op3 = newTemp(Ity_I32);
2542 IRTemp result = newTemp(Ity_I32);
2543
2544 assign(op2, get_gpr_w0(r2));
2545 assign(op3, get_gpr_w0(r3));
2546 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2547 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
2548 put_gpr_w0(r1, mkexpr(result));
2549
2550 return "ahhhr";
2551}
2552
2553static HChar *
2554s390_irgen_AHHLR(UChar r3, UChar r1, UChar r2)
2555{
2556 IRTemp op2 = newTemp(Ity_I32);
2557 IRTemp op3 = newTemp(Ity_I32);
2558 IRTemp result = newTemp(Ity_I32);
2559
2560 assign(op2, get_gpr_w0(r2));
2561 assign(op3, get_gpr_w1(r3));
2562 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2563 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
2564 put_gpr_w0(r1, mkexpr(result));
2565
2566 return "ahhlr";
2567}
2568
2569static HChar *
2570s390_irgen_AIH(UChar r1, UInt i2)
2571{
2572 IRTemp op1 = newTemp(Ity_I32);
2573 Int op2;
2574 IRTemp result = newTemp(Ity_I32);
2575
2576 assign(op1, get_gpr_w0(r1));
2577 op2 = (Int)i2;
2578 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
2579 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
2580 mkU32((UInt)op2)));
2581 put_gpr_w0(r1, mkexpr(result));
2582
2583 return "aih";
2584}
2585
2586static HChar *
2587s390_irgen_ALR(UChar r1, UChar r2)
2588{
2589 IRTemp op1 = newTemp(Ity_I32);
2590 IRTemp op2 = newTemp(Ity_I32);
2591 IRTemp result = newTemp(Ity_I32);
2592
2593 assign(op1, get_gpr_w1(r1));
2594 assign(op2, get_gpr_w1(r2));
2595 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2596 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, op2);
2597 put_gpr_w1(r1, mkexpr(result));
2598
2599 return "alr";
2600}
2601
2602static HChar *
2603s390_irgen_ALGR(UChar r1, UChar r2)
2604{
2605 IRTemp op1 = newTemp(Ity_I64);
2606 IRTemp op2 = newTemp(Ity_I64);
2607 IRTemp result = newTemp(Ity_I64);
2608
2609 assign(op1, get_gpr_dw0(r1));
2610 assign(op2, get_gpr_dw0(r2));
2611 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2612 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
2613 put_gpr_dw0(r1, mkexpr(result));
2614
2615 return "algr";
2616}
2617
2618static HChar *
2619s390_irgen_ALGFR(UChar r1, UChar r2)
2620{
2621 IRTemp op1 = newTemp(Ity_I64);
2622 IRTemp op2 = newTemp(Ity_I64);
2623 IRTemp result = newTemp(Ity_I64);
2624
2625 assign(op1, get_gpr_dw0(r1));
2626 assign(op2, unop(Iop_32Uto64, get_gpr_w1(r2)));
2627 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2628 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
2629 put_gpr_dw0(r1, mkexpr(result));
2630
2631 return "algfr";
2632}
2633
2634static HChar *
2635s390_irgen_ALRK(UChar r3, UChar r1, UChar r2)
2636{
2637 IRTemp op2 = newTemp(Ity_I32);
2638 IRTemp op3 = newTemp(Ity_I32);
2639 IRTemp result = newTemp(Ity_I32);
2640
2641 assign(op2, get_gpr_w1(r2));
2642 assign(op3, get_gpr_w1(r3));
2643 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2644 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
2645 put_gpr_w1(r1, mkexpr(result));
2646
2647 return "alrk";
2648}
2649
2650static HChar *
2651s390_irgen_ALGRK(UChar r3, UChar r1, UChar r2)
2652{
2653 IRTemp op2 = newTemp(Ity_I64);
2654 IRTemp op3 = newTemp(Ity_I64);
2655 IRTemp result = newTemp(Ity_I64);
2656
2657 assign(op2, get_gpr_dw0(r2));
2658 assign(op3, get_gpr_dw0(r3));
2659 assign(result, binop(Iop_Add64, mkexpr(op2), mkexpr(op3)));
2660 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op2, op3);
2661 put_gpr_dw0(r1, mkexpr(result));
2662
2663 return "algrk";
2664}
2665
2666static HChar *
2667s390_irgen_AL(UChar r1, IRTemp op2addr)
2668{
2669 IRTemp op1 = newTemp(Ity_I32);
2670 IRTemp op2 = newTemp(Ity_I32);
2671 IRTemp result = newTemp(Ity_I32);
2672
2673 assign(op1, get_gpr_w1(r1));
2674 assign(op2, load(Ity_I32, mkexpr(op2addr)));
2675 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2676 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, op2);
2677 put_gpr_w1(r1, mkexpr(result));
2678
2679 return "al";
2680}
2681
2682static HChar *
2683s390_irgen_ALY(UChar r1, IRTemp op2addr)
2684{
2685 IRTemp op1 = newTemp(Ity_I32);
2686 IRTemp op2 = newTemp(Ity_I32);
2687 IRTemp result = newTemp(Ity_I32);
2688
2689 assign(op1, get_gpr_w1(r1));
2690 assign(op2, load(Ity_I32, mkexpr(op2addr)));
2691 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2692 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, op2);
2693 put_gpr_w1(r1, mkexpr(result));
2694
2695 return "aly";
2696}
2697
2698static HChar *
2699s390_irgen_ALG(UChar r1, IRTemp op2addr)
2700{
2701 IRTemp op1 = newTemp(Ity_I64);
2702 IRTemp op2 = newTemp(Ity_I64);
2703 IRTemp result = newTemp(Ity_I64);
2704
2705 assign(op1, get_gpr_dw0(r1));
2706 assign(op2, load(Ity_I64, mkexpr(op2addr)));
2707 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2708 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
2709 put_gpr_dw0(r1, mkexpr(result));
2710
2711 return "alg";
2712}
2713
2714static HChar *
2715s390_irgen_ALGF(UChar r1, IRTemp op2addr)
2716{
2717 IRTemp op1 = newTemp(Ity_I64);
2718 IRTemp op2 = newTemp(Ity_I64);
2719 IRTemp result = newTemp(Ity_I64);
2720
2721 assign(op1, get_gpr_dw0(r1));
2722 assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
2723 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2724 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
2725 put_gpr_dw0(r1, mkexpr(result));
2726
2727 return "algf";
2728}
2729
2730static HChar *
2731s390_irgen_ALFI(UChar r1, UInt i2)
2732{
2733 IRTemp op1 = newTemp(Ity_I32);
2734 UInt op2;
2735 IRTemp result = newTemp(Ity_I32);
2736
2737 assign(op1, get_gpr_w1(r1));
2738 op2 = i2;
2739 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
2740 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, mktemp(Ity_I32,
2741 mkU32(op2)));
2742 put_gpr_w1(r1, mkexpr(result));
2743
2744 return "alfi";
2745}
2746
2747static HChar *
2748s390_irgen_ALGFI(UChar r1, UInt i2)
2749{
2750 IRTemp op1 = newTemp(Ity_I64);
2751 ULong op2;
2752 IRTemp result = newTemp(Ity_I64);
2753
2754 assign(op1, get_gpr_dw0(r1));
2755 op2 = (ULong)i2;
2756 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64(op2)));
2757 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, mktemp(Ity_I64,
2758 mkU64(op2)));
2759 put_gpr_dw0(r1, mkexpr(result));
2760
2761 return "algfi";
2762}
2763
2764static HChar *
2765s390_irgen_ALHHHR(UChar r3, UChar r1, UChar r2)
2766{
2767 IRTemp op2 = newTemp(Ity_I32);
2768 IRTemp op3 = newTemp(Ity_I32);
2769 IRTemp result = newTemp(Ity_I32);
2770
2771 assign(op2, get_gpr_w0(r2));
2772 assign(op3, get_gpr_w0(r3));
2773 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2774 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
2775 put_gpr_w0(r1, mkexpr(result));
2776
2777 return "alhhhr";
2778}
2779
2780static HChar *
2781s390_irgen_ALHHLR(UChar r3, UChar r1, UChar r2)
2782{
2783 IRTemp op2 = newTemp(Ity_I32);
2784 IRTemp op3 = newTemp(Ity_I32);
2785 IRTemp result = newTemp(Ity_I32);
2786
2787 assign(op2, get_gpr_w0(r2));
2788 assign(op3, get_gpr_w1(r3));
2789 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2790 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
2791 put_gpr_w0(r1, mkexpr(result));
2792
2793 return "alhhlr";
2794}
2795
2796static HChar *
2797s390_irgen_ALCR(UChar r1, UChar r2)
2798{
2799 IRTemp op1 = newTemp(Ity_I32);
2800 IRTemp op2 = newTemp(Ity_I32);
2801 IRTemp result = newTemp(Ity_I32);
2802 IRTemp carry_in = newTemp(Ity_I32);
2803
2804 assign(op1, get_gpr_w1(r1));
2805 assign(op2, get_gpr_w1(r2));
2806 assign(carry_in, binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)));
2807 assign(result, binop(Iop_Add32, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)),
2808 mkexpr(carry_in)));
2809 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_32, op1, op2, carry_in);
2810 put_gpr_w1(r1, mkexpr(result));
2811
2812 return "alcr";
2813}
2814
2815static HChar *
2816s390_irgen_ALCGR(UChar r1, UChar r2)
2817{
2818 IRTemp op1 = newTemp(Ity_I64);
2819 IRTemp op2 = newTemp(Ity_I64);
2820 IRTemp result = newTemp(Ity_I64);
2821 IRTemp carry_in = newTemp(Ity_I64);
2822
2823 assign(op1, get_gpr_dw0(r1));
2824 assign(op2, get_gpr_dw0(r2));
2825 assign(carry_in, unop(Iop_32Uto64, binop(Iop_Shr32, s390_call_calculate_cc(),
2826 mkU8(1))));
2827 assign(result, binop(Iop_Add64, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)),
2828 mkexpr(carry_in)));
2829 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_64, op1, op2, carry_in);
2830 put_gpr_dw0(r1, mkexpr(result));
2831
2832 return "alcgr";
2833}
2834
2835static HChar *
2836s390_irgen_ALC(UChar r1, IRTemp op2addr)
2837{
2838 IRTemp op1 = newTemp(Ity_I32);
2839 IRTemp op2 = newTemp(Ity_I32);
2840 IRTemp result = newTemp(Ity_I32);
2841 IRTemp carry_in = newTemp(Ity_I32);
2842
2843 assign(op1, get_gpr_w1(r1));
2844 assign(op2, load(Ity_I32, mkexpr(op2addr)));
2845 assign(carry_in, binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)));
2846 assign(result, binop(Iop_Add32, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)),
2847 mkexpr(carry_in)));
2848 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_32, op1, op2, carry_in);
2849 put_gpr_w1(r1, mkexpr(result));
2850
2851 return "alc";
2852}
2853
2854static HChar *
2855s390_irgen_ALCG(UChar r1, IRTemp op2addr)
2856{
2857 IRTemp op1 = newTemp(Ity_I64);
2858 IRTemp op2 = newTemp(Ity_I64);
2859 IRTemp result = newTemp(Ity_I64);
2860 IRTemp carry_in = newTemp(Ity_I64);
2861
2862 assign(op1, get_gpr_dw0(r1));
2863 assign(op2, load(Ity_I64, mkexpr(op2addr)));
2864 assign(carry_in, unop(Iop_32Uto64, binop(Iop_Shr32, s390_call_calculate_cc(),
2865 mkU8(1))));
2866 assign(result, binop(Iop_Add64, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)),
2867 mkexpr(carry_in)));
2868 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_64, op1, op2, carry_in);
2869 put_gpr_dw0(r1, mkexpr(result));
2870
2871 return "alcg";
2872}
2873
2874static HChar *
2875s390_irgen_ALSI(UChar i2, IRTemp op1addr)
2876{
2877 IRTemp op1 = newTemp(Ity_I32);
2878 UInt op2;
2879 IRTemp result = newTemp(Ity_I32);
2880
2881 assign(op1, load(Ity_I32, mkexpr(op1addr)));
2882 op2 = (UInt)(Int)(Char)i2;
2883 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
2884 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, mktemp(Ity_I32,
2885 mkU32(op2)));
2886 store(mkexpr(op1addr), mkexpr(result));
2887
2888 return "alsi";
2889}
2890
2891static HChar *
2892s390_irgen_ALGSI(UChar i2, IRTemp op1addr)
2893{
2894 IRTemp op1 = newTemp(Ity_I64);
2895 ULong op2;
2896 IRTemp result = newTemp(Ity_I64);
2897
2898 assign(op1, load(Ity_I64, mkexpr(op1addr)));
2899 op2 = (ULong)(Long)(Char)i2;
2900 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64(op2)));
2901 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, mktemp(Ity_I64,
2902 mkU64(op2)));
2903 store(mkexpr(op1addr), mkexpr(result));
2904
2905 return "algsi";
2906}
2907
2908static HChar *
2909s390_irgen_ALHSIK(UChar r1, UChar r3, UShort i2)
2910{
2911 UInt op2;
2912 IRTemp op3 = newTemp(Ity_I32);
2913 IRTemp result = newTemp(Ity_I32);
2914
2915 op2 = (UInt)(Int)(Short)i2;
2916 assign(op3, get_gpr_w1(r3));
2917 assign(result, binop(Iop_Add32, mkU32(op2), mkexpr(op3)));
2918 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, mktemp(Ity_I32, mkU32(op2)),
2919 op3);
2920 put_gpr_w1(r1, mkexpr(result));
2921
2922 return "alhsik";
2923}
2924
2925static HChar *
2926s390_irgen_ALGHSIK(UChar r1, UChar r3, UShort i2)
2927{
2928 ULong op2;
2929 IRTemp op3 = newTemp(Ity_I64);
2930 IRTemp result = newTemp(Ity_I64);
2931
2932 op2 = (ULong)(Long)(Short)i2;
2933 assign(op3, get_gpr_dw0(r3));
2934 assign(result, binop(Iop_Add64, mkU64(op2), mkexpr(op3)));
2935 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, mktemp(Ity_I64, mkU64(op2)),
2936 op3);
2937 put_gpr_dw0(r1, mkexpr(result));
2938
2939 return "alghsik";
2940}
2941
2942static HChar *
2943s390_irgen_ALSIH(UChar r1, UInt i2)
2944{
2945 IRTemp op1 = newTemp(Ity_I32);
2946 UInt op2;
2947 IRTemp result = newTemp(Ity_I32);
2948
2949 assign(op1, get_gpr_w0(r1));
2950 op2 = i2;
2951 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
2952 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, mktemp(Ity_I32,
2953 mkU32(op2)));
2954 put_gpr_w0(r1, mkexpr(result));
2955
2956 return "alsih";
2957}
2958
2959static HChar *
2960s390_irgen_ALSIHN(UChar r1, UInt i2)
2961{
2962 IRTemp op1 = newTemp(Ity_I32);
2963 UInt op2;
2964 IRTemp result = newTemp(Ity_I32);
2965
2966 assign(op1, get_gpr_w0(r1));
2967 op2 = i2;
2968 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
2969 put_gpr_w0(r1, mkexpr(result));
2970
2971 return "alsihn";
2972}
2973
2974static HChar *
2975s390_irgen_NR(UChar r1, UChar r2)
2976{
2977 IRTemp op1 = newTemp(Ity_I32);
2978 IRTemp op2 = newTemp(Ity_I32);
2979 IRTemp result = newTemp(Ity_I32);
2980
2981 assign(op1, get_gpr_w1(r1));
2982 assign(op2, get_gpr_w1(r2));
2983 assign(result, binop(Iop_And32, mkexpr(op1), mkexpr(op2)));
2984 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
2985 put_gpr_w1(r1, mkexpr(result));
2986
2987 return "nr";
2988}
2989
2990static HChar *
2991s390_irgen_NGR(UChar r1, UChar r2)
2992{
2993 IRTemp op1 = newTemp(Ity_I64);
2994 IRTemp op2 = newTemp(Ity_I64);
2995 IRTemp result = newTemp(Ity_I64);
2996
2997 assign(op1, get_gpr_dw0(r1));
2998 assign(op2, get_gpr_dw0(r2));
2999 assign(result, binop(Iop_And64, mkexpr(op1), mkexpr(op2)));
3000 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3001 put_gpr_dw0(r1, mkexpr(result));
3002
3003 return "ngr";
3004}
3005
3006static HChar *
3007s390_irgen_NRK(UChar r3, UChar r1, UChar r2)
3008{
3009 IRTemp op2 = newTemp(Ity_I32);
3010 IRTemp op3 = newTemp(Ity_I32);
3011 IRTemp result = newTemp(Ity_I32);
3012
3013 assign(op2, get_gpr_w1(r2));
3014 assign(op3, get_gpr_w1(r3));
3015 assign(result, binop(Iop_And32, mkexpr(op2), mkexpr(op3)));
3016 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3017 put_gpr_w1(r1, mkexpr(result));
3018
3019 return "nrk";
3020}
3021
3022static HChar *
3023s390_irgen_NGRK(UChar r3, UChar r1, UChar r2)
3024{
3025 IRTemp op2 = newTemp(Ity_I64);
3026 IRTemp op3 = newTemp(Ity_I64);
3027 IRTemp result = newTemp(Ity_I64);
3028
3029 assign(op2, get_gpr_dw0(r2));
3030 assign(op3, get_gpr_dw0(r3));
3031 assign(result, binop(Iop_And64, mkexpr(op2), mkexpr(op3)));
3032 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3033 put_gpr_dw0(r1, mkexpr(result));
3034
3035 return "ngrk";
3036}
3037
3038static HChar *
3039s390_irgen_N(UChar r1, IRTemp op2addr)
3040{
3041 IRTemp op1 = newTemp(Ity_I32);
3042 IRTemp op2 = newTemp(Ity_I32);
3043 IRTemp result = newTemp(Ity_I32);
3044
3045 assign(op1, get_gpr_w1(r1));
3046 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3047 assign(result, binop(Iop_And32, mkexpr(op1), mkexpr(op2)));
3048 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3049 put_gpr_w1(r1, mkexpr(result));
3050
3051 return "n";
3052}
3053
3054static HChar *
3055s390_irgen_NY(UChar r1, IRTemp op2addr)
3056{
3057 IRTemp op1 = newTemp(Ity_I32);
3058 IRTemp op2 = newTemp(Ity_I32);
3059 IRTemp result = newTemp(Ity_I32);
3060
3061 assign(op1, get_gpr_w1(r1));
3062 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3063 assign(result, binop(Iop_And32, mkexpr(op1), mkexpr(op2)));
3064 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3065 put_gpr_w1(r1, mkexpr(result));
3066
3067 return "ny";
3068}
3069
3070static HChar *
3071s390_irgen_NG(UChar r1, IRTemp op2addr)
3072{
3073 IRTemp op1 = newTemp(Ity_I64);
3074 IRTemp op2 = newTemp(Ity_I64);
3075 IRTemp result = newTemp(Ity_I64);
3076
3077 assign(op1, get_gpr_dw0(r1));
3078 assign(op2, load(Ity_I64, mkexpr(op2addr)));
3079 assign(result, binop(Iop_And64, mkexpr(op1), mkexpr(op2)));
3080 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3081 put_gpr_dw0(r1, mkexpr(result));
3082
3083 return "ng";
3084}
3085
3086static HChar *
3087s390_irgen_NI(UChar i2, IRTemp op1addr)
3088{
3089 IRTemp op1 = newTemp(Ity_I8);
3090 UChar op2;
3091 IRTemp result = newTemp(Ity_I8);
3092
3093 assign(op1, load(Ity_I8, mkexpr(op1addr)));
3094 op2 = i2;
3095 assign(result, binop(Iop_And8, mkexpr(op1), mkU8(op2)));
3096 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3097 store(mkexpr(op1addr), mkexpr(result));
3098
3099 return "ni";
3100}
3101
3102static HChar *
3103s390_irgen_NIY(UChar i2, IRTemp op1addr)
3104{
3105 IRTemp op1 = newTemp(Ity_I8);
3106 UChar op2;
3107 IRTemp result = newTemp(Ity_I8);
3108
3109 assign(op1, load(Ity_I8, mkexpr(op1addr)));
3110 op2 = i2;
3111 assign(result, binop(Iop_And8, mkexpr(op1), mkU8(op2)));
3112 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3113 store(mkexpr(op1addr), mkexpr(result));
3114
3115 return "niy";
3116}
3117
3118static HChar *
3119s390_irgen_NIHF(UChar r1, UInt i2)
3120{
3121 IRTemp op1 = newTemp(Ity_I32);
3122 UInt op2;
3123 IRTemp result = newTemp(Ity_I32);
3124
3125 assign(op1, get_gpr_w0(r1));
3126 op2 = i2;
3127 assign(result, binop(Iop_And32, mkexpr(op1), mkU32(op2)));
3128 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3129 put_gpr_w0(r1, mkexpr(result));
3130
3131 return "nihf";
3132}
3133
3134static HChar *
3135s390_irgen_NIHH(UChar r1, UShort i2)
3136{
3137 IRTemp op1 = newTemp(Ity_I16);
3138 UShort op2;
3139 IRTemp result = newTemp(Ity_I16);
3140
3141 assign(op1, get_gpr_hw0(r1));
3142 op2 = i2;
3143 assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
3144 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3145 put_gpr_hw0(r1, mkexpr(result));
3146
3147 return "nihh";
3148}
3149
3150static HChar *
3151s390_irgen_NIHL(UChar r1, UShort i2)
3152{
3153 IRTemp op1 = newTemp(Ity_I16);
3154 UShort op2;
3155 IRTemp result = newTemp(Ity_I16);
3156
3157 assign(op1, get_gpr_hw1(r1));
3158 op2 = i2;
3159 assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
3160 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3161 put_gpr_hw1(r1, mkexpr(result));
3162
3163 return "nihl";
3164}
3165
3166static HChar *
3167s390_irgen_NILF(UChar r1, UInt i2)
3168{
3169 IRTemp op1 = newTemp(Ity_I32);
3170 UInt op2;
3171 IRTemp result = newTemp(Ity_I32);
3172
3173 assign(op1, get_gpr_w1(r1));
3174 op2 = i2;
3175 assign(result, binop(Iop_And32, mkexpr(op1), mkU32(op2)));
3176 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3177 put_gpr_w1(r1, mkexpr(result));
3178
3179 return "nilf";
3180}
3181
3182static HChar *
3183s390_irgen_NILH(UChar r1, UShort i2)
3184{
3185 IRTemp op1 = newTemp(Ity_I16);
3186 UShort op2;
3187 IRTemp result = newTemp(Ity_I16);
3188
3189 assign(op1, get_gpr_hw2(r1));
3190 op2 = i2;
3191 assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
3192 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3193 put_gpr_hw2(r1, mkexpr(result));
3194
3195 return "nilh";
3196}
3197
3198static HChar *
3199s390_irgen_NILL(UChar r1, UShort i2)
3200{
3201 IRTemp op1 = newTemp(Ity_I16);
3202 UShort op2;
3203 IRTemp result = newTemp(Ity_I16);
3204
3205 assign(op1, get_gpr_hw3(r1));
3206 op2 = i2;
3207 assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
3208 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3209 put_gpr_hw3(r1, mkexpr(result));
3210
3211 return "nill";
3212}
3213
3214static HChar *
3215s390_irgen_BASR(UChar r1, UChar r2)
3216{
3217 IRTemp target = newTemp(Ity_I64);
3218
3219 if (r2 == 0) {
3220 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 2ULL));
3221 } else {
3222 if (r1 != r2) {
3223 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 2ULL));
3224 call_function(get_gpr_dw0(r2));
3225 } else {
3226 assign(target, get_gpr_dw0(r2));
3227 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 2ULL));
3228 call_function(mkexpr(target));
3229 }
3230 }
3231
3232 return "basr";
3233}
3234
3235static HChar *
3236s390_irgen_BAS(UChar r1, IRTemp op2addr)
3237{
3238 IRTemp target = newTemp(Ity_I64);
3239
3240 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 4ULL));
3241 assign(target, mkexpr(op2addr));
3242 call_function(mkexpr(target));
3243
3244 return "bas";
3245}
3246
3247static HChar *
3248s390_irgen_BCR(UChar r1, UChar r2)
3249{
3250 IRTemp cond = newTemp(Ity_I32);
3251
sewardja52e37e2011-04-28 18:48:06 +00003252 if (r2 == 0 && (r1 >= 14)) { /* serialization */
3253 stmt(IRStmt_MBE(Imbe_Fence));
3254 }
3255
sewardj2019a972011-03-07 16:04:07 +00003256 if ((r2 == 0) || (r1 == 0)) {
3257 } else {
3258 if (r1 == 15) {
3259 return_from_function(get_gpr_dw0(r2));
3260 } else {
3261 assign(cond, s390_call_calculate_cond(r1));
florianf321da72012-07-21 20:32:57 +00003262 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3263 get_gpr_dw0(r2));
sewardj2019a972011-03-07 16:04:07 +00003264 }
3265 }
sewardj7ee97522011-05-09 21:45:04 +00003266 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00003267 s390_disasm(ENC2(XMNM, GPR), S390_XMNM_BCR, r1, r2);
3268
3269 return "bcr";
3270}
3271
3272static HChar *
3273s390_irgen_BC(UChar r1, UChar x2, UChar b2, UShort d2, IRTemp op2addr)
3274{
3275 IRTemp cond = newTemp(Ity_I32);
3276
3277 if (r1 == 0) {
3278 } else {
3279 if (r1 == 15) {
3280 always_goto(mkexpr(op2addr));
3281 } else {
3282 assign(cond, s390_call_calculate_cond(r1));
florianf321da72012-07-21 20:32:57 +00003283 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3284 mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003285 }
3286 }
sewardj7ee97522011-05-09 21:45:04 +00003287 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00003288 s390_disasm(ENC2(XMNM, UDXB), S390_XMNM_BC, r1, d2, x2, b2);
3289
3290 return "bc";
3291}
3292
3293static HChar *
3294s390_irgen_BCTR(UChar r1, UChar r2)
3295{
3296 put_gpr_w1(r1, binop(Iop_Sub32, get_gpr_w1(r1), mkU32(1)));
3297 if (r2 != 0) {
florianf321da72012-07-21 20:32:57 +00003298 if_condition_goto_computed(binop(Iop_CmpNE32, get_gpr_w1(r1), mkU32(0)),
3299 get_gpr_dw0(r2));
sewardj2019a972011-03-07 16:04:07 +00003300 }
3301
3302 return "bctr";
3303}
3304
3305static HChar *
3306s390_irgen_BCTGR(UChar r1, UChar r2)
3307{
3308 put_gpr_dw0(r1, binop(Iop_Sub64, get_gpr_dw0(r1), mkU64(1)));
3309 if (r2 != 0) {
florianf321da72012-07-21 20:32:57 +00003310 if_condition_goto_computed(binop(Iop_CmpNE64, get_gpr_dw0(r1), mkU64(0)),
3311 get_gpr_dw0(r2));
sewardj2019a972011-03-07 16:04:07 +00003312 }
3313
3314 return "bctgr";
3315}
3316
3317static HChar *
3318s390_irgen_BCT(UChar r1, IRTemp op2addr)
3319{
3320 put_gpr_w1(r1, binop(Iop_Sub32, get_gpr_w1(r1), mkU32(1)));
florianf321da72012-07-21 20:32:57 +00003321 if_condition_goto_computed(binop(Iop_CmpNE32, get_gpr_w1(r1), mkU32(0)),
3322 mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003323
3324 return "bct";
3325}
3326
3327static HChar *
3328s390_irgen_BCTG(UChar r1, IRTemp op2addr)
3329{
3330 put_gpr_dw0(r1, binop(Iop_Sub64, get_gpr_dw0(r1), mkU64(1)));
florianf321da72012-07-21 20:32:57 +00003331 if_condition_goto_computed(binop(Iop_CmpNE64, get_gpr_dw0(r1), mkU64(0)),
3332 mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003333
3334 return "bctg";
3335}
3336
3337static HChar *
3338s390_irgen_BXH(UChar r1, UChar r3, IRTemp op2addr)
3339{
3340 IRTemp value = newTemp(Ity_I32);
3341
3342 assign(value, get_gpr_w1(r3 | 1));
3343 put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
florianf321da72012-07-21 20:32:57 +00003344 if_condition_goto_computed(binop(Iop_CmpLT32S, mkexpr(value),
3345 get_gpr_w1(r1)), mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003346
3347 return "bxh";
3348}
3349
3350static HChar *
3351s390_irgen_BXHG(UChar r1, UChar r3, IRTemp op2addr)
3352{
3353 IRTemp value = newTemp(Ity_I64);
3354
3355 assign(value, get_gpr_dw0(r3 | 1));
3356 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
florianf321da72012-07-21 20:32:57 +00003357 if_condition_goto_computed(binop(Iop_CmpLT64S, mkexpr(value),
3358 get_gpr_dw0(r1)), mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003359
3360 return "bxhg";
3361}
3362
3363static HChar *
3364s390_irgen_BXLE(UChar r1, UChar r3, IRTemp op2addr)
3365{
3366 IRTemp value = newTemp(Ity_I32);
3367
3368 assign(value, get_gpr_w1(r3 | 1));
3369 put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
florianf321da72012-07-21 20:32:57 +00003370 if_condition_goto_computed(binop(Iop_CmpLE32S, get_gpr_w1(r1),
3371 mkexpr(value)), mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003372
3373 return "bxle";
3374}
3375
3376static HChar *
3377s390_irgen_BXLEG(UChar r1, UChar r3, IRTemp op2addr)
3378{
3379 IRTemp value = newTemp(Ity_I64);
3380
3381 assign(value, get_gpr_dw0(r3 | 1));
3382 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
florianf321da72012-07-21 20:32:57 +00003383 if_condition_goto_computed(binop(Iop_CmpLE64S, get_gpr_dw0(r1),
3384 mkexpr(value)), mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003385
3386 return "bxleg";
3387}
3388
3389static HChar *
3390s390_irgen_BRAS(UChar r1, UShort i2)
3391{
3392 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 4ULL));
floriana64c2432011-07-16 02:11:50 +00003393 call_function_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
sewardj2019a972011-03-07 16:04:07 +00003394
3395 return "bras";
3396}
3397
3398static HChar *
3399s390_irgen_BRASL(UChar r1, UInt i2)
3400{
3401 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 6ULL));
floriana64c2432011-07-16 02:11:50 +00003402 call_function_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1));
sewardj2019a972011-03-07 16:04:07 +00003403
3404 return "brasl";
3405}
3406
3407static HChar *
3408s390_irgen_BRC(UChar r1, UShort i2)
3409{
3410 IRTemp cond = newTemp(Ity_I32);
3411
3412 if (r1 == 0) {
3413 } else {
3414 if (r1 == 15) {
floriana64c2432011-07-16 02:11:50 +00003415 always_goto_and_chase(
3416 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
sewardj2019a972011-03-07 16:04:07 +00003417 } else {
3418 assign(cond, s390_call_calculate_cond(r1));
3419 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3420 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3421
3422 }
3423 }
sewardj7ee97522011-05-09 21:45:04 +00003424 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00003425 s390_disasm(ENC2(XMNM, PCREL), S390_XMNM_BRC, r1, (Int)(Short)i2);
3426
3427 return "brc";
3428}
3429
3430static HChar *
3431s390_irgen_BRCL(UChar r1, UInt i2)
3432{
3433 IRTemp cond = newTemp(Ity_I32);
3434
3435 if (r1 == 0) {
3436 } else {
3437 if (r1 == 15) {
floriana64c2432011-07-16 02:11:50 +00003438 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1));
sewardj2019a972011-03-07 16:04:07 +00003439 } else {
3440 assign(cond, s390_call_calculate_cond(r1));
3441 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3442 guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1));
3443 }
3444 }
sewardj7ee97522011-05-09 21:45:04 +00003445 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00003446 s390_disasm(ENC2(XMNM, PCREL), S390_XMNM_BRCL, r1, i2);
3447
3448 return "brcl";
3449}
3450
3451static HChar *
3452s390_irgen_BRCT(UChar r1, UShort i2)
3453{
3454 put_gpr_w1(r1, binop(Iop_Sub32, get_gpr_w1(r1), mkU32(1)));
3455 if_condition_goto(binop(Iop_CmpNE32, get_gpr_w1(r1), mkU32(0)),
3456 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3457
3458 return "brct";
3459}
3460
3461static HChar *
3462s390_irgen_BRCTG(UChar r1, UShort i2)
3463{
3464 put_gpr_dw0(r1, binop(Iop_Sub64, get_gpr_dw0(r1), mkU64(1)));
3465 if_condition_goto(binop(Iop_CmpNE64, get_gpr_dw0(r1), mkU64(0)),
3466 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3467
3468 return "brctg";
3469}
3470
3471static HChar *
3472s390_irgen_BRXH(UChar r1, UChar r3, UShort i2)
3473{
3474 IRTemp value = newTemp(Ity_I32);
3475
3476 assign(value, get_gpr_w1(r3 | 1));
3477 put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
3478 if_condition_goto(binop(Iop_CmpLT32S, mkexpr(value), get_gpr_w1(r1)),
3479 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3480
3481 return "brxh";
3482}
3483
3484static HChar *
3485s390_irgen_BRXHG(UChar r1, UChar r3, UShort i2)
3486{
3487 IRTemp value = newTemp(Ity_I64);
3488
3489 assign(value, get_gpr_dw0(r3 | 1));
3490 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
3491 if_condition_goto(binop(Iop_CmpLT64S, mkexpr(value), get_gpr_dw0(r1)),
3492 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3493
3494 return "brxhg";
3495}
3496
3497static HChar *
3498s390_irgen_BRXLE(UChar r1, UChar r3, UShort i2)
3499{
3500 IRTemp value = newTemp(Ity_I32);
3501
3502 assign(value, get_gpr_w1(r3 | 1));
3503 put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
3504 if_condition_goto(binop(Iop_CmpLE32S, get_gpr_w1(r1), mkexpr(value)),
3505 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3506
3507 return "brxle";
3508}
3509
3510static HChar *
3511s390_irgen_BRXLG(UChar r1, UChar r3, UShort i2)
3512{
3513 IRTemp value = newTemp(Ity_I64);
3514
3515 assign(value, get_gpr_dw0(r3 | 1));
3516 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
3517 if_condition_goto(binop(Iop_CmpLE64S, get_gpr_dw0(r1), mkexpr(value)),
3518 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3519
3520 return "brxlg";
3521}
3522
3523static HChar *
3524s390_irgen_CR(UChar r1, UChar r2)
3525{
3526 IRTemp op1 = newTemp(Ity_I32);
3527 IRTemp op2 = newTemp(Ity_I32);
3528
3529 assign(op1, get_gpr_w1(r1));
3530 assign(op2, get_gpr_w1(r2));
3531 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3532
3533 return "cr";
3534}
3535
3536static HChar *
3537s390_irgen_CGR(UChar r1, UChar r2)
3538{
3539 IRTemp op1 = newTemp(Ity_I64);
3540 IRTemp op2 = newTemp(Ity_I64);
3541
3542 assign(op1, get_gpr_dw0(r1));
3543 assign(op2, get_gpr_dw0(r2));
3544 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3545
3546 return "cgr";
3547}
3548
3549static HChar *
3550s390_irgen_CGFR(UChar r1, UChar r2)
3551{
3552 IRTemp op1 = newTemp(Ity_I64);
3553 IRTemp op2 = newTemp(Ity_I64);
3554
3555 assign(op1, get_gpr_dw0(r1));
3556 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
3557 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3558
3559 return "cgfr";
3560}
3561
3562static HChar *
3563s390_irgen_C(UChar r1, IRTemp op2addr)
3564{
3565 IRTemp op1 = newTemp(Ity_I32);
3566 IRTemp op2 = newTemp(Ity_I32);
3567
3568 assign(op1, get_gpr_w1(r1));
3569 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3570 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3571
3572 return "c";
3573}
3574
3575static HChar *
3576s390_irgen_CY(UChar r1, IRTemp op2addr)
3577{
3578 IRTemp op1 = newTemp(Ity_I32);
3579 IRTemp op2 = newTemp(Ity_I32);
3580
3581 assign(op1, get_gpr_w1(r1));
3582 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3583 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3584
3585 return "cy";
3586}
3587
3588static HChar *
3589s390_irgen_CG(UChar r1, IRTemp op2addr)
3590{
3591 IRTemp op1 = newTemp(Ity_I64);
3592 IRTemp op2 = newTemp(Ity_I64);
3593
3594 assign(op1, get_gpr_dw0(r1));
3595 assign(op2, load(Ity_I64, mkexpr(op2addr)));
3596 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3597
3598 return "cg";
3599}
3600
3601static HChar *
3602s390_irgen_CGF(UChar r1, IRTemp op2addr)
3603{
3604 IRTemp op1 = newTemp(Ity_I64);
3605 IRTemp op2 = newTemp(Ity_I64);
3606
3607 assign(op1, get_gpr_dw0(r1));
3608 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
3609 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3610
3611 return "cgf";
3612}
3613
3614static HChar *
3615s390_irgen_CFI(UChar r1, UInt i2)
3616{
3617 IRTemp op1 = newTemp(Ity_I32);
3618 Int op2;
3619
3620 assign(op1, get_gpr_w1(r1));
3621 op2 = (Int)i2;
3622 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
3623 mkU32((UInt)op2)));
3624
3625 return "cfi";
3626}
3627
3628static HChar *
3629s390_irgen_CGFI(UChar r1, UInt i2)
3630{
3631 IRTemp op1 = newTemp(Ity_I64);
3632 Long op2;
3633
3634 assign(op1, get_gpr_dw0(r1));
3635 op2 = (Long)(Int)i2;
3636 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I64,
3637 mkU64((ULong)op2)));
3638
3639 return "cgfi";
3640}
3641
3642static HChar *
3643s390_irgen_CRL(UChar r1, UInt i2)
3644{
3645 IRTemp op1 = newTemp(Ity_I32);
3646 IRTemp op2 = newTemp(Ity_I32);
3647
3648 assign(op1, get_gpr_w1(r1));
3649 assign(op2, load(Ity_I32, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
3650 i2 << 1))));
3651 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3652
3653 return "crl";
3654}
3655
3656static HChar *
3657s390_irgen_CGRL(UChar r1, UInt i2)
3658{
3659 IRTemp op1 = newTemp(Ity_I64);
3660 IRTemp op2 = newTemp(Ity_I64);
3661
3662 assign(op1, get_gpr_dw0(r1));
3663 assign(op2, load(Ity_I64, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
3664 i2 << 1))));
3665 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3666
3667 return "cgrl";
3668}
3669
3670static HChar *
3671s390_irgen_CGFRL(UChar r1, UInt i2)
3672{
3673 IRTemp op1 = newTemp(Ity_I64);
3674 IRTemp op2 = newTemp(Ity_I64);
3675
3676 assign(op1, get_gpr_dw0(r1));
3677 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
3678 ((ULong)(Long)(Int)i2 << 1)))));
3679 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3680
3681 return "cgfrl";
3682}
3683
3684static HChar *
3685s390_irgen_CRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
3686{
3687 IRTemp op1 = newTemp(Ity_I32);
3688 IRTemp op2 = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00003689 IRTemp cond = newTemp(Ity_I32);
3690
3691 if (m3 == 0) {
3692 } else {
3693 if (m3 == 14) {
3694 always_goto(mkexpr(op4addr));
3695 } else {
3696 assign(op1, get_gpr_w1(r1));
3697 assign(op2, get_gpr_w1(r2));
florianff9613f2012-05-12 15:26:44 +00003698 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
3699 op1, op2));
florianf321da72012-07-21 20:32:57 +00003700 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond),
3701 mkU32(0)), mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00003702 }
3703 }
3704
3705 return "crb";
3706}
3707
3708static HChar *
3709s390_irgen_CGRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
3710{
3711 IRTemp op1 = newTemp(Ity_I64);
3712 IRTemp op2 = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00003713 IRTemp cond = newTemp(Ity_I32);
3714
3715 if (m3 == 0) {
3716 } else {
3717 if (m3 == 14) {
3718 always_goto(mkexpr(op4addr));
3719 } else {
3720 assign(op1, get_gpr_dw0(r1));
3721 assign(op2, get_gpr_dw0(r2));
florianff9613f2012-05-12 15:26:44 +00003722 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
3723 op1, op2));
florianf321da72012-07-21 20:32:57 +00003724 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond),
3725 mkU32(0)), mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00003726 }
3727 }
3728
3729 return "cgrb";
3730}
3731
3732static HChar *
3733s390_irgen_CRJ(UChar r1, UChar r2, UShort i4, UChar m3)
3734{
3735 IRTemp op1 = newTemp(Ity_I32);
3736 IRTemp op2 = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00003737 IRTemp cond = newTemp(Ity_I32);
3738
3739 if (m3 == 0) {
3740 } else {
3741 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00003742 always_goto_and_chase(
3743 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00003744 } else {
3745 assign(op1, get_gpr_w1(r1));
3746 assign(op2, get_gpr_w1(r2));
florianff9613f2012-05-12 15:26:44 +00003747 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
3748 op1, op2));
sewardj2019a972011-03-07 16:04:07 +00003749 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3750 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
3751
3752 }
3753 }
3754
3755 return "crj";
3756}
3757
3758static HChar *
3759s390_irgen_CGRJ(UChar r1, UChar r2, UShort i4, UChar m3)
3760{
3761 IRTemp op1 = newTemp(Ity_I64);
3762 IRTemp op2 = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00003763 IRTemp cond = newTemp(Ity_I32);
3764
3765 if (m3 == 0) {
3766 } else {
3767 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00003768 always_goto_and_chase(
3769 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00003770 } else {
3771 assign(op1, get_gpr_dw0(r1));
3772 assign(op2, get_gpr_dw0(r2));
florianff9613f2012-05-12 15:26:44 +00003773 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
3774 op1, op2));
sewardj2019a972011-03-07 16:04:07 +00003775 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3776 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
3777
3778 }
3779 }
3780
3781 return "cgrj";
3782}
3783
3784static HChar *
3785s390_irgen_CIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
3786{
3787 IRTemp op1 = newTemp(Ity_I32);
3788 Int op2;
sewardj2019a972011-03-07 16:04:07 +00003789 IRTemp cond = newTemp(Ity_I32);
3790
3791 if (m3 == 0) {
3792 } else {
3793 if (m3 == 14) {
3794 always_goto(mkexpr(op4addr));
3795 } else {
3796 assign(op1, get_gpr_w1(r1));
3797 op2 = (Int)(Char)i2;
florianff9613f2012-05-12 15:26:44 +00003798 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
3799 mktemp(Ity_I32, mkU32((UInt)op2))));
florianf321da72012-07-21 20:32:57 +00003800 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3801 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00003802 }
3803 }
3804
3805 return "cib";
3806}
3807
3808static HChar *
3809s390_irgen_CGIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
3810{
3811 IRTemp op1 = newTemp(Ity_I64);
3812 Long op2;
sewardj2019a972011-03-07 16:04:07 +00003813 IRTemp cond = newTemp(Ity_I32);
3814
3815 if (m3 == 0) {
3816 } else {
3817 if (m3 == 14) {
3818 always_goto(mkexpr(op4addr));
3819 } else {
3820 assign(op1, get_gpr_dw0(r1));
3821 op2 = (Long)(Char)i2;
florianff9613f2012-05-12 15:26:44 +00003822 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
3823 mktemp(Ity_I64, mkU64((ULong)op2))));
florianf321da72012-07-21 20:32:57 +00003824 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3825 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00003826 }
3827 }
3828
3829 return "cgib";
3830}
3831
3832static HChar *
3833s390_irgen_CIJ(UChar r1, UChar m3, UShort i4, UChar i2)
3834{
3835 IRTemp op1 = newTemp(Ity_I32);
3836 Int op2;
sewardj2019a972011-03-07 16:04:07 +00003837 IRTemp cond = newTemp(Ity_I32);
3838
3839 if (m3 == 0) {
3840 } else {
3841 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00003842 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00003843 } else {
3844 assign(op1, get_gpr_w1(r1));
3845 op2 = (Int)(Char)i2;
florianff9613f2012-05-12 15:26:44 +00003846 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
3847 mktemp(Ity_I32, mkU32((UInt)op2))));
sewardj2019a972011-03-07 16:04:07 +00003848 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3849 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
3850
3851 }
3852 }
3853
3854 return "cij";
3855}
3856
3857static HChar *
3858s390_irgen_CGIJ(UChar r1, UChar m3, UShort i4, UChar i2)
3859{
3860 IRTemp op1 = newTemp(Ity_I64);
3861 Long op2;
sewardj2019a972011-03-07 16:04:07 +00003862 IRTemp cond = newTemp(Ity_I32);
3863
3864 if (m3 == 0) {
3865 } else {
3866 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00003867 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00003868 } else {
3869 assign(op1, get_gpr_dw0(r1));
3870 op2 = (Long)(Char)i2;
florianff9613f2012-05-12 15:26:44 +00003871 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
3872 mktemp(Ity_I64, mkU64((ULong)op2))));
sewardj2019a972011-03-07 16:04:07 +00003873 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3874 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
3875
3876 }
3877 }
3878
3879 return "cgij";
3880}
3881
3882static HChar *
3883s390_irgen_CH(UChar r1, IRTemp op2addr)
3884{
3885 IRTemp op1 = newTemp(Ity_I32);
3886 IRTemp op2 = newTemp(Ity_I32);
3887
3888 assign(op1, get_gpr_w1(r1));
3889 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
3890 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3891
3892 return "ch";
3893}
3894
3895static HChar *
3896s390_irgen_CHY(UChar r1, IRTemp op2addr)
3897{
3898 IRTemp op1 = newTemp(Ity_I32);
3899 IRTemp op2 = newTemp(Ity_I32);
3900
3901 assign(op1, get_gpr_w1(r1));
3902 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
3903 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3904
3905 return "chy";
3906}
3907
3908static HChar *
3909s390_irgen_CGH(UChar r1, IRTemp op2addr)
3910{
3911 IRTemp op1 = newTemp(Ity_I64);
3912 IRTemp op2 = newTemp(Ity_I64);
3913
3914 assign(op1, get_gpr_dw0(r1));
3915 assign(op2, unop(Iop_16Sto64, load(Ity_I16, mkexpr(op2addr))));
3916 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3917
3918 return "cgh";
3919}
3920
3921static HChar *
3922s390_irgen_CHI(UChar r1, UShort i2)
3923{
3924 IRTemp op1 = newTemp(Ity_I32);
3925 Int op2;
3926
3927 assign(op1, get_gpr_w1(r1));
3928 op2 = (Int)(Short)i2;
3929 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
3930 mkU32((UInt)op2)));
3931
3932 return "chi";
3933}
3934
3935static HChar *
3936s390_irgen_CGHI(UChar r1, UShort i2)
3937{
3938 IRTemp op1 = newTemp(Ity_I64);
3939 Long op2;
3940
3941 assign(op1, get_gpr_dw0(r1));
3942 op2 = (Long)(Short)i2;
3943 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I64,
3944 mkU64((ULong)op2)));
3945
3946 return "cghi";
3947}
3948
3949static HChar *
3950s390_irgen_CHHSI(UShort i2, IRTemp op1addr)
3951{
3952 IRTemp op1 = newTemp(Ity_I16);
3953 Short op2;
3954
3955 assign(op1, load(Ity_I16, mkexpr(op1addr)));
3956 op2 = (Short)i2;
3957 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I16,
3958 mkU16((UShort)op2)));
3959
3960 return "chhsi";
3961}
3962
3963static HChar *
3964s390_irgen_CHSI(UShort i2, IRTemp op1addr)
3965{
3966 IRTemp op1 = newTemp(Ity_I32);
3967 Int op2;
3968
3969 assign(op1, load(Ity_I32, mkexpr(op1addr)));
3970 op2 = (Int)(Short)i2;
3971 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
3972 mkU32((UInt)op2)));
3973
3974 return "chsi";
3975}
3976
3977static HChar *
3978s390_irgen_CGHSI(UShort i2, IRTemp op1addr)
3979{
3980 IRTemp op1 = newTemp(Ity_I64);
3981 Long op2;
3982
3983 assign(op1, load(Ity_I64, mkexpr(op1addr)));
3984 op2 = (Long)(Short)i2;
3985 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I64,
3986 mkU64((ULong)op2)));
3987
3988 return "cghsi";
3989}
3990
3991static HChar *
3992s390_irgen_CHRL(UChar r1, UInt i2)
3993{
3994 IRTemp op1 = newTemp(Ity_I32);
3995 IRTemp op2 = newTemp(Ity_I32);
3996
3997 assign(op1, get_gpr_w1(r1));
3998 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
3999 ((ULong)(Long)(Int)i2 << 1)))));
4000 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4001
4002 return "chrl";
4003}
4004
4005static HChar *
4006s390_irgen_CGHRL(UChar r1, UInt i2)
4007{
4008 IRTemp op1 = newTemp(Ity_I64);
4009 IRTemp op2 = newTemp(Ity_I64);
4010
4011 assign(op1, get_gpr_dw0(r1));
4012 assign(op2, unop(Iop_16Sto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
4013 ((ULong)(Long)(Int)i2 << 1)))));
4014 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4015
4016 return "cghrl";
4017}
4018
4019static HChar *
4020s390_irgen_CHHR(UChar r1, UChar r2)
4021{
4022 IRTemp op1 = newTemp(Ity_I32);
4023 IRTemp op2 = newTemp(Ity_I32);
4024
4025 assign(op1, get_gpr_w0(r1));
4026 assign(op2, get_gpr_w0(r2));
4027 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4028
4029 return "chhr";
4030}
4031
4032static HChar *
4033s390_irgen_CHLR(UChar r1, UChar r2)
4034{
4035 IRTemp op1 = newTemp(Ity_I32);
4036 IRTemp op2 = newTemp(Ity_I32);
4037
4038 assign(op1, get_gpr_w0(r1));
4039 assign(op2, get_gpr_w1(r2));
4040 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4041
4042 return "chlr";
4043}
4044
4045static HChar *
4046s390_irgen_CHF(UChar r1, IRTemp op2addr)
4047{
4048 IRTemp op1 = newTemp(Ity_I32);
4049 IRTemp op2 = newTemp(Ity_I32);
4050
4051 assign(op1, get_gpr_w0(r1));
4052 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4053 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4054
4055 return "chf";
4056}
4057
4058static HChar *
4059s390_irgen_CIH(UChar r1, UInt i2)
4060{
4061 IRTemp op1 = newTemp(Ity_I32);
4062 Int op2;
4063
4064 assign(op1, get_gpr_w0(r1));
4065 op2 = (Int)i2;
4066 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
4067 mkU32((UInt)op2)));
4068
4069 return "cih";
4070}
4071
4072static HChar *
4073s390_irgen_CLR(UChar r1, UChar r2)
4074{
4075 IRTemp op1 = newTemp(Ity_I32);
4076 IRTemp op2 = newTemp(Ity_I32);
4077
4078 assign(op1, get_gpr_w1(r1));
4079 assign(op2, get_gpr_w1(r2));
4080 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4081
4082 return "clr";
4083}
4084
4085static HChar *
4086s390_irgen_CLGR(UChar r1, UChar r2)
4087{
4088 IRTemp op1 = newTemp(Ity_I64);
4089 IRTemp op2 = newTemp(Ity_I64);
4090
4091 assign(op1, get_gpr_dw0(r1));
4092 assign(op2, get_gpr_dw0(r2));
4093 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4094
4095 return "clgr";
4096}
4097
4098static HChar *
4099s390_irgen_CLGFR(UChar r1, UChar r2)
4100{
4101 IRTemp op1 = newTemp(Ity_I64);
4102 IRTemp op2 = newTemp(Ity_I64);
4103
4104 assign(op1, get_gpr_dw0(r1));
4105 assign(op2, unop(Iop_32Uto64, get_gpr_w1(r2)));
4106 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4107
4108 return "clgfr";
4109}
4110
4111static HChar *
4112s390_irgen_CL(UChar r1, IRTemp op2addr)
4113{
4114 IRTemp op1 = newTemp(Ity_I32);
4115 IRTemp op2 = newTemp(Ity_I32);
4116
4117 assign(op1, get_gpr_w1(r1));
4118 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4119 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4120
4121 return "cl";
4122}
4123
4124static HChar *
4125s390_irgen_CLY(UChar r1, IRTemp op2addr)
4126{
4127 IRTemp op1 = newTemp(Ity_I32);
4128 IRTemp op2 = newTemp(Ity_I32);
4129
4130 assign(op1, get_gpr_w1(r1));
4131 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4132 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4133
4134 return "cly";
4135}
4136
4137static HChar *
4138s390_irgen_CLG(UChar r1, IRTemp op2addr)
4139{
4140 IRTemp op1 = newTemp(Ity_I64);
4141 IRTemp op2 = newTemp(Ity_I64);
4142
4143 assign(op1, get_gpr_dw0(r1));
4144 assign(op2, load(Ity_I64, mkexpr(op2addr)));
4145 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4146
4147 return "clg";
4148}
4149
4150static HChar *
4151s390_irgen_CLGF(UChar r1, IRTemp op2addr)
4152{
4153 IRTemp op1 = newTemp(Ity_I64);
4154 IRTemp op2 = newTemp(Ity_I64);
4155
4156 assign(op1, get_gpr_dw0(r1));
4157 assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
4158 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4159
4160 return "clgf";
4161}
4162
4163static HChar *
4164s390_irgen_CLFI(UChar r1, UInt i2)
4165{
4166 IRTemp op1 = newTemp(Ity_I32);
4167 UInt op2;
4168
4169 assign(op1, get_gpr_w1(r1));
4170 op2 = i2;
4171 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I32,
4172 mkU32(op2)));
4173
4174 return "clfi";
4175}
4176
4177static HChar *
4178s390_irgen_CLGFI(UChar r1, UInt i2)
4179{
4180 IRTemp op1 = newTemp(Ity_I64);
4181 ULong op2;
4182
4183 assign(op1, get_gpr_dw0(r1));
4184 op2 = (ULong)i2;
4185 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I64,
4186 mkU64(op2)));
4187
4188 return "clgfi";
4189}
4190
4191static HChar *
4192s390_irgen_CLI(UChar i2, IRTemp op1addr)
4193{
4194 IRTemp op1 = newTemp(Ity_I8);
4195 UChar op2;
4196
4197 assign(op1, load(Ity_I8, mkexpr(op1addr)));
4198 op2 = i2;
4199 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I8,
4200 mkU8(op2)));
4201
4202 return "cli";
4203}
4204
4205static HChar *
4206s390_irgen_CLIY(UChar i2, IRTemp op1addr)
4207{
4208 IRTemp op1 = newTemp(Ity_I8);
4209 UChar op2;
4210
4211 assign(op1, load(Ity_I8, mkexpr(op1addr)));
4212 op2 = i2;
4213 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I8,
4214 mkU8(op2)));
4215
4216 return "cliy";
4217}
4218
4219static HChar *
4220s390_irgen_CLFHSI(UShort i2, IRTemp op1addr)
4221{
4222 IRTemp op1 = newTemp(Ity_I32);
4223 UInt op2;
4224
4225 assign(op1, load(Ity_I32, mkexpr(op1addr)));
4226 op2 = (UInt)i2;
4227 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I32,
4228 mkU32(op2)));
4229
4230 return "clfhsi";
4231}
4232
4233static HChar *
4234s390_irgen_CLGHSI(UShort i2, IRTemp op1addr)
4235{
4236 IRTemp op1 = newTemp(Ity_I64);
4237 ULong op2;
4238
4239 assign(op1, load(Ity_I64, mkexpr(op1addr)));
4240 op2 = (ULong)i2;
4241 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I64,
4242 mkU64(op2)));
4243
4244 return "clghsi";
4245}
4246
4247static HChar *
4248s390_irgen_CLHHSI(UShort i2, IRTemp op1addr)
4249{
4250 IRTemp op1 = newTemp(Ity_I16);
4251 UShort op2;
4252
4253 assign(op1, load(Ity_I16, mkexpr(op1addr)));
4254 op2 = i2;
4255 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I16,
4256 mkU16(op2)));
4257
4258 return "clhhsi";
4259}
4260
4261static HChar *
4262s390_irgen_CLRL(UChar r1, UInt i2)
4263{
4264 IRTemp op1 = newTemp(Ity_I32);
4265 IRTemp op2 = newTemp(Ity_I32);
4266
4267 assign(op1, get_gpr_w1(r1));
4268 assign(op2, load(Ity_I32, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
4269 i2 << 1))));
4270 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4271
4272 return "clrl";
4273}
4274
4275static HChar *
4276s390_irgen_CLGRL(UChar r1, UInt i2)
4277{
4278 IRTemp op1 = newTemp(Ity_I64);
4279 IRTemp op2 = newTemp(Ity_I64);
4280
4281 assign(op1, get_gpr_dw0(r1));
4282 assign(op2, load(Ity_I64, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
4283 i2 << 1))));
4284 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4285
4286 return "clgrl";
4287}
4288
4289static HChar *
4290s390_irgen_CLGFRL(UChar r1, UInt i2)
4291{
4292 IRTemp op1 = newTemp(Ity_I64);
4293 IRTemp op2 = newTemp(Ity_I64);
4294
4295 assign(op1, get_gpr_dw0(r1));
4296 assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
4297 ((ULong)(Long)(Int)i2 << 1)))));
4298 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4299
4300 return "clgfrl";
4301}
4302
4303static HChar *
4304s390_irgen_CLHRL(UChar r1, UInt i2)
4305{
4306 IRTemp op1 = newTemp(Ity_I32);
4307 IRTemp op2 = newTemp(Ity_I32);
4308
4309 assign(op1, get_gpr_w1(r1));
4310 assign(op2, unop(Iop_16Uto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
4311 ((ULong)(Long)(Int)i2 << 1)))));
4312 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4313
4314 return "clhrl";
4315}
4316
4317static HChar *
4318s390_irgen_CLGHRL(UChar r1, UInt i2)
4319{
4320 IRTemp op1 = newTemp(Ity_I64);
4321 IRTemp op2 = newTemp(Ity_I64);
4322
4323 assign(op1, get_gpr_dw0(r1));
4324 assign(op2, unop(Iop_16Uto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
4325 ((ULong)(Long)(Int)i2 << 1)))));
4326 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4327
4328 return "clghrl";
4329}
4330
4331static HChar *
4332s390_irgen_CLRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
4333{
4334 IRTemp op1 = newTemp(Ity_I32);
4335 IRTemp op2 = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00004336 IRTemp cond = newTemp(Ity_I32);
4337
4338 if (m3 == 0) {
4339 } else {
4340 if (m3 == 14) {
4341 always_goto(mkexpr(op4addr));
4342 } else {
4343 assign(op1, get_gpr_w1(r1));
4344 assign(op2, get_gpr_w1(r2));
florianff9613f2012-05-12 15:26:44 +00004345 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4346 op1, op2));
florianf321da72012-07-21 20:32:57 +00004347 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4348 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004349 }
4350 }
4351
4352 return "clrb";
4353}
4354
4355static HChar *
4356s390_irgen_CLGRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
4357{
4358 IRTemp op1 = newTemp(Ity_I64);
4359 IRTemp op2 = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00004360 IRTemp cond = newTemp(Ity_I32);
4361
4362 if (m3 == 0) {
4363 } else {
4364 if (m3 == 14) {
4365 always_goto(mkexpr(op4addr));
4366 } else {
4367 assign(op1, get_gpr_dw0(r1));
4368 assign(op2, get_gpr_dw0(r2));
florianff9613f2012-05-12 15:26:44 +00004369 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4370 op1, op2));
florianf321da72012-07-21 20:32:57 +00004371 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4372 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004373 }
4374 }
4375
4376 return "clgrb";
4377}
4378
4379static HChar *
4380s390_irgen_CLRJ(UChar r1, UChar r2, UShort i4, UChar m3)
4381{
4382 IRTemp op1 = newTemp(Ity_I32);
4383 IRTemp op2 = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00004384 IRTemp cond = newTemp(Ity_I32);
4385
4386 if (m3 == 0) {
4387 } else {
4388 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004389 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004390 } else {
4391 assign(op1, get_gpr_w1(r1));
4392 assign(op2, get_gpr_w1(r2));
florianff9613f2012-05-12 15:26:44 +00004393 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4394 op1, op2));
sewardj2019a972011-03-07 16:04:07 +00004395 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4396 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4397
4398 }
4399 }
4400
4401 return "clrj";
4402}
4403
4404static HChar *
4405s390_irgen_CLGRJ(UChar r1, UChar r2, UShort i4, UChar m3)
4406{
4407 IRTemp op1 = newTemp(Ity_I64);
4408 IRTemp op2 = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00004409 IRTemp cond = newTemp(Ity_I32);
4410
4411 if (m3 == 0) {
4412 } else {
4413 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004414 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004415 } else {
4416 assign(op1, get_gpr_dw0(r1));
4417 assign(op2, get_gpr_dw0(r2));
florianff9613f2012-05-12 15:26:44 +00004418 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4419 op1, op2));
sewardj2019a972011-03-07 16:04:07 +00004420 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4421 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4422
4423 }
4424 }
4425
4426 return "clgrj";
4427}
4428
4429static HChar *
4430s390_irgen_CLIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
4431{
4432 IRTemp op1 = newTemp(Ity_I32);
4433 UInt op2;
sewardj2019a972011-03-07 16:04:07 +00004434 IRTemp cond = newTemp(Ity_I32);
4435
4436 if (m3 == 0) {
4437 } else {
4438 if (m3 == 14) {
4439 always_goto(mkexpr(op4addr));
4440 } else {
4441 assign(op1, get_gpr_w1(r1));
4442 op2 = (UInt)i2;
florianff9613f2012-05-12 15:26:44 +00004443 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4444 mktemp(Ity_I32, mkU32(op2))));
florianf321da72012-07-21 20:32:57 +00004445 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4446 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004447 }
4448 }
4449
4450 return "clib";
4451}
4452
4453static HChar *
4454s390_irgen_CLGIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
4455{
4456 IRTemp op1 = newTemp(Ity_I64);
4457 ULong op2;
sewardj2019a972011-03-07 16:04:07 +00004458 IRTemp cond = newTemp(Ity_I32);
4459
4460 if (m3 == 0) {
4461 } else {
4462 if (m3 == 14) {
4463 always_goto(mkexpr(op4addr));
4464 } else {
4465 assign(op1, get_gpr_dw0(r1));
4466 op2 = (ULong)i2;
florianff9613f2012-05-12 15:26:44 +00004467 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4468 mktemp(Ity_I64, mkU64(op2))));
florianf321da72012-07-21 20:32:57 +00004469 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4470 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004471 }
4472 }
4473
4474 return "clgib";
4475}
4476
4477static HChar *
4478s390_irgen_CLIJ(UChar r1, UChar m3, UShort i4, UChar i2)
4479{
4480 IRTemp op1 = newTemp(Ity_I32);
4481 UInt op2;
sewardj2019a972011-03-07 16:04:07 +00004482 IRTemp cond = newTemp(Ity_I32);
4483
4484 if (m3 == 0) {
4485 } else {
4486 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004487 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004488 } else {
4489 assign(op1, get_gpr_w1(r1));
4490 op2 = (UInt)i2;
florianff9613f2012-05-12 15:26:44 +00004491 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4492 mktemp(Ity_I32, mkU32(op2))));
sewardj2019a972011-03-07 16:04:07 +00004493 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4494 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4495
4496 }
4497 }
4498
4499 return "clij";
4500}
4501
4502static HChar *
4503s390_irgen_CLGIJ(UChar r1, UChar m3, UShort i4, UChar i2)
4504{
4505 IRTemp op1 = newTemp(Ity_I64);
4506 ULong op2;
sewardj2019a972011-03-07 16:04:07 +00004507 IRTemp cond = newTemp(Ity_I32);
4508
4509 if (m3 == 0) {
4510 } else {
4511 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004512 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004513 } else {
4514 assign(op1, get_gpr_dw0(r1));
4515 op2 = (ULong)i2;
florianff9613f2012-05-12 15:26:44 +00004516 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4517 mktemp(Ity_I64, mkU64(op2))));
sewardj2019a972011-03-07 16:04:07 +00004518 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4519 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4520
4521 }
4522 }
4523
4524 return "clgij";
4525}
4526
4527static HChar *
4528s390_irgen_CLM(UChar r1, UChar r3, IRTemp op2addr)
4529{
4530 IRTemp op1 = newTemp(Ity_I32);
4531 IRTemp op2 = newTemp(Ity_I32);
4532 IRTemp b0 = newTemp(Ity_I32);
4533 IRTemp b1 = newTemp(Ity_I32);
4534 IRTemp b2 = newTemp(Ity_I32);
4535 IRTemp b3 = newTemp(Ity_I32);
4536 IRTemp c0 = newTemp(Ity_I32);
4537 IRTemp c1 = newTemp(Ity_I32);
4538 IRTemp c2 = newTemp(Ity_I32);
4539 IRTemp c3 = newTemp(Ity_I32);
4540 UChar n;
4541
4542 n = 0;
4543 if ((r3 & 8) != 0) {
4544 assign(b0, unop(Iop_8Uto32, get_gpr_b4(r1)));
4545 assign(c0, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
4546 n = n + 1;
4547 } else {
4548 assign(b0, mkU32(0));
4549 assign(c0, mkU32(0));
4550 }
4551 if ((r3 & 4) != 0) {
4552 assign(b1, unop(Iop_8Uto32, get_gpr_b5(r1)));
4553 assign(c1, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4554 mkU64(n)))));
4555 n = n + 1;
4556 } else {
4557 assign(b1, mkU32(0));
4558 assign(c1, mkU32(0));
4559 }
4560 if ((r3 & 2) != 0) {
4561 assign(b2, unop(Iop_8Uto32, get_gpr_b6(r1)));
4562 assign(c2, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4563 mkU64(n)))));
4564 n = n + 1;
4565 } else {
4566 assign(b2, mkU32(0));
4567 assign(c2, mkU32(0));
4568 }
4569 if ((r3 & 1) != 0) {
4570 assign(b3, unop(Iop_8Uto32, get_gpr_b7(r1)));
4571 assign(c3, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4572 mkU64(n)))));
4573 n = n + 1;
4574 } else {
4575 assign(b3, mkU32(0));
4576 assign(c3, mkU32(0));
4577 }
4578 assign(op1, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4579 mkexpr(b0), mkU8(24)), binop(Iop_Shl32, mkexpr(b1), mkU8(16))),
4580 binop(Iop_Shl32, mkexpr(b2), mkU8(8))), mkexpr(b3)));
4581 assign(op2, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4582 mkexpr(c0), mkU8(24)), binop(Iop_Shl32, mkexpr(c1), mkU8(16))),
4583 binop(Iop_Shl32, mkexpr(c2), mkU8(8))), mkexpr(c3)));
4584 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4585
4586 return "clm";
4587}
4588
4589static HChar *
4590s390_irgen_CLMY(UChar r1, UChar r3, IRTemp op2addr)
4591{
4592 IRTemp op1 = newTemp(Ity_I32);
4593 IRTemp op2 = newTemp(Ity_I32);
4594 IRTemp b0 = newTemp(Ity_I32);
4595 IRTemp b1 = newTemp(Ity_I32);
4596 IRTemp b2 = newTemp(Ity_I32);
4597 IRTemp b3 = newTemp(Ity_I32);
4598 IRTemp c0 = newTemp(Ity_I32);
4599 IRTemp c1 = newTemp(Ity_I32);
4600 IRTemp c2 = newTemp(Ity_I32);
4601 IRTemp c3 = newTemp(Ity_I32);
4602 UChar n;
4603
4604 n = 0;
4605 if ((r3 & 8) != 0) {
4606 assign(b0, unop(Iop_8Uto32, get_gpr_b4(r1)));
4607 assign(c0, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
4608 n = n + 1;
4609 } else {
4610 assign(b0, mkU32(0));
4611 assign(c0, mkU32(0));
4612 }
4613 if ((r3 & 4) != 0) {
4614 assign(b1, unop(Iop_8Uto32, get_gpr_b5(r1)));
4615 assign(c1, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4616 mkU64(n)))));
4617 n = n + 1;
4618 } else {
4619 assign(b1, mkU32(0));
4620 assign(c1, mkU32(0));
4621 }
4622 if ((r3 & 2) != 0) {
4623 assign(b2, unop(Iop_8Uto32, get_gpr_b6(r1)));
4624 assign(c2, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4625 mkU64(n)))));
4626 n = n + 1;
4627 } else {
4628 assign(b2, mkU32(0));
4629 assign(c2, mkU32(0));
4630 }
4631 if ((r3 & 1) != 0) {
4632 assign(b3, unop(Iop_8Uto32, get_gpr_b7(r1)));
4633 assign(c3, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4634 mkU64(n)))));
4635 n = n + 1;
4636 } else {
4637 assign(b3, mkU32(0));
4638 assign(c3, mkU32(0));
4639 }
4640 assign(op1, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4641 mkexpr(b0), mkU8(24)), binop(Iop_Shl32, mkexpr(b1), mkU8(16))),
4642 binop(Iop_Shl32, mkexpr(b2), mkU8(8))), mkexpr(b3)));
4643 assign(op2, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4644 mkexpr(c0), mkU8(24)), binop(Iop_Shl32, mkexpr(c1), mkU8(16))),
4645 binop(Iop_Shl32, mkexpr(c2), mkU8(8))), mkexpr(c3)));
4646 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4647
4648 return "clmy";
4649}
4650
4651static HChar *
4652s390_irgen_CLMH(UChar r1, UChar r3, IRTemp op2addr)
4653{
4654 IRTemp op1 = newTemp(Ity_I32);
4655 IRTemp op2 = newTemp(Ity_I32);
4656 IRTemp b0 = newTemp(Ity_I32);
4657 IRTemp b1 = newTemp(Ity_I32);
4658 IRTemp b2 = newTemp(Ity_I32);
4659 IRTemp b3 = newTemp(Ity_I32);
4660 IRTemp c0 = newTemp(Ity_I32);
4661 IRTemp c1 = newTemp(Ity_I32);
4662 IRTemp c2 = newTemp(Ity_I32);
4663 IRTemp c3 = newTemp(Ity_I32);
4664 UChar n;
4665
4666 n = 0;
4667 if ((r3 & 8) != 0) {
4668 assign(b0, unop(Iop_8Uto32, get_gpr_b0(r1)));
4669 assign(c0, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
4670 n = n + 1;
4671 } else {
4672 assign(b0, mkU32(0));
4673 assign(c0, mkU32(0));
4674 }
4675 if ((r3 & 4) != 0) {
4676 assign(b1, unop(Iop_8Uto32, get_gpr_b1(r1)));
4677 assign(c1, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4678 mkU64(n)))));
4679 n = n + 1;
4680 } else {
4681 assign(b1, mkU32(0));
4682 assign(c1, mkU32(0));
4683 }
4684 if ((r3 & 2) != 0) {
4685 assign(b2, unop(Iop_8Uto32, get_gpr_b2(r1)));
4686 assign(c2, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4687 mkU64(n)))));
4688 n = n + 1;
4689 } else {
4690 assign(b2, mkU32(0));
4691 assign(c2, mkU32(0));
4692 }
4693 if ((r3 & 1) != 0) {
4694 assign(b3, unop(Iop_8Uto32, get_gpr_b3(r1)));
4695 assign(c3, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4696 mkU64(n)))));
4697 n = n + 1;
4698 } else {
4699 assign(b3, mkU32(0));
4700 assign(c3, mkU32(0));
4701 }
4702 assign(op1, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4703 mkexpr(b0), mkU8(24)), binop(Iop_Shl32, mkexpr(b1), mkU8(16))),
4704 binop(Iop_Shl32, mkexpr(b2), mkU8(8))), mkexpr(b3)));
4705 assign(op2, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4706 mkexpr(c0), mkU8(24)), binop(Iop_Shl32, mkexpr(c1), mkU8(16))),
4707 binop(Iop_Shl32, mkexpr(c2), mkU8(8))), mkexpr(c3)));
4708 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4709
4710 return "clmh";
4711}
4712
4713static HChar *
4714s390_irgen_CLHHR(UChar r1, UChar r2)
4715{
4716 IRTemp op1 = newTemp(Ity_I32);
4717 IRTemp op2 = newTemp(Ity_I32);
4718
4719 assign(op1, get_gpr_w0(r1));
4720 assign(op2, get_gpr_w0(r2));
4721 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4722
4723 return "clhhr";
4724}
4725
4726static HChar *
4727s390_irgen_CLHLR(UChar r1, UChar r2)
4728{
4729 IRTemp op1 = newTemp(Ity_I32);
4730 IRTemp op2 = newTemp(Ity_I32);
4731
4732 assign(op1, get_gpr_w0(r1));
4733 assign(op2, get_gpr_w1(r2));
4734 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4735
4736 return "clhlr";
4737}
4738
4739static HChar *
4740s390_irgen_CLHF(UChar r1, IRTemp op2addr)
4741{
4742 IRTemp op1 = newTemp(Ity_I32);
4743 IRTemp op2 = newTemp(Ity_I32);
4744
4745 assign(op1, get_gpr_w0(r1));
4746 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4747 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4748
4749 return "clhf";
4750}
4751
4752static HChar *
4753s390_irgen_CLIH(UChar r1, UInt i2)
4754{
4755 IRTemp op1 = newTemp(Ity_I32);
4756 UInt op2;
4757
4758 assign(op1, get_gpr_w0(r1));
4759 op2 = i2;
4760 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I32,
4761 mkU32(op2)));
4762
4763 return "clih";
4764}
4765
4766static HChar *
4767s390_irgen_CPYA(UChar r1, UChar r2)
4768{
4769 put_ar_w0(r1, get_ar_w0(r2));
sewardj7ee97522011-05-09 21:45:04 +00004770 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00004771 s390_disasm(ENC3(MNM, AR, AR), "cpya", r1, r2);
4772
4773 return "cpya";
4774}
4775
4776static HChar *
4777s390_irgen_XR(UChar r1, UChar r2)
4778{
4779 IRTemp op1 = newTemp(Ity_I32);
4780 IRTemp op2 = newTemp(Ity_I32);
4781 IRTemp result = newTemp(Ity_I32);
4782
4783 if (r1 == r2) {
4784 assign(result, mkU32(0));
4785 } else {
4786 assign(op1, get_gpr_w1(r1));
4787 assign(op2, get_gpr_w1(r2));
4788 assign(result, binop(Iop_Xor32, mkexpr(op1), mkexpr(op2)));
4789 }
4790 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4791 put_gpr_w1(r1, mkexpr(result));
4792
4793 return "xr";
4794}
4795
4796static HChar *
4797s390_irgen_XGR(UChar r1, UChar r2)
4798{
4799 IRTemp op1 = newTemp(Ity_I64);
4800 IRTemp op2 = newTemp(Ity_I64);
4801 IRTemp result = newTemp(Ity_I64);
4802
4803 if (r1 == r2) {
4804 assign(result, mkU64(0));
4805 } else {
4806 assign(op1, get_gpr_dw0(r1));
4807 assign(op2, get_gpr_dw0(r2));
4808 assign(result, binop(Iop_Xor64, mkexpr(op1), mkexpr(op2)));
4809 }
4810 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4811 put_gpr_dw0(r1, mkexpr(result));
4812
4813 return "xgr";
4814}
4815
4816static HChar *
4817s390_irgen_XRK(UChar r3, UChar r1, UChar r2)
4818{
4819 IRTemp op2 = newTemp(Ity_I32);
4820 IRTemp op3 = newTemp(Ity_I32);
4821 IRTemp result = newTemp(Ity_I32);
4822
4823 assign(op2, get_gpr_w1(r2));
4824 assign(op3, get_gpr_w1(r3));
4825 assign(result, binop(Iop_Xor32, mkexpr(op2), mkexpr(op3)));
4826 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4827 put_gpr_w1(r1, mkexpr(result));
4828
4829 return "xrk";
4830}
4831
4832static HChar *
4833s390_irgen_XGRK(UChar r3, UChar r1, UChar r2)
4834{
4835 IRTemp op2 = newTemp(Ity_I64);
4836 IRTemp op3 = newTemp(Ity_I64);
4837 IRTemp result = newTemp(Ity_I64);
4838
4839 assign(op2, get_gpr_dw0(r2));
4840 assign(op3, get_gpr_dw0(r3));
4841 assign(result, binop(Iop_Xor64, mkexpr(op2), mkexpr(op3)));
4842 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4843 put_gpr_dw0(r1, mkexpr(result));
4844
4845 return "xgrk";
4846}
4847
4848static HChar *
4849s390_irgen_X(UChar r1, IRTemp op2addr)
4850{
4851 IRTemp op1 = newTemp(Ity_I32);
4852 IRTemp op2 = newTemp(Ity_I32);
4853 IRTemp result = newTemp(Ity_I32);
4854
4855 assign(op1, get_gpr_w1(r1));
4856 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4857 assign(result, binop(Iop_Xor32, mkexpr(op1), mkexpr(op2)));
4858 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4859 put_gpr_w1(r1, mkexpr(result));
4860
4861 return "x";
4862}
4863
4864static HChar *
4865s390_irgen_XY(UChar r1, IRTemp op2addr)
4866{
4867 IRTemp op1 = newTemp(Ity_I32);
4868 IRTemp op2 = newTemp(Ity_I32);
4869 IRTemp result = newTemp(Ity_I32);
4870
4871 assign(op1, get_gpr_w1(r1));
4872 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4873 assign(result, binop(Iop_Xor32, mkexpr(op1), mkexpr(op2)));
4874 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4875 put_gpr_w1(r1, mkexpr(result));
4876
4877 return "xy";
4878}
4879
4880static HChar *
4881s390_irgen_XG(UChar r1, IRTemp op2addr)
4882{
4883 IRTemp op1 = newTemp(Ity_I64);
4884 IRTemp op2 = newTemp(Ity_I64);
4885 IRTemp result = newTemp(Ity_I64);
4886
4887 assign(op1, get_gpr_dw0(r1));
4888 assign(op2, load(Ity_I64, mkexpr(op2addr)));
4889 assign(result, binop(Iop_Xor64, mkexpr(op1), mkexpr(op2)));
4890 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4891 put_gpr_dw0(r1, mkexpr(result));
4892
4893 return "xg";
4894}
4895
4896static HChar *
4897s390_irgen_XI(UChar i2, IRTemp op1addr)
4898{
4899 IRTemp op1 = newTemp(Ity_I8);
4900 UChar op2;
4901 IRTemp result = newTemp(Ity_I8);
4902
4903 assign(op1, load(Ity_I8, mkexpr(op1addr)));
4904 op2 = i2;
4905 assign(result, binop(Iop_Xor8, mkexpr(op1), mkU8(op2)));
4906 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4907 store(mkexpr(op1addr), mkexpr(result));
4908
4909 return "xi";
4910}
4911
4912static HChar *
4913s390_irgen_XIY(UChar i2, IRTemp op1addr)
4914{
4915 IRTemp op1 = newTemp(Ity_I8);
4916 UChar op2;
4917 IRTemp result = newTemp(Ity_I8);
4918
4919 assign(op1, load(Ity_I8, mkexpr(op1addr)));
4920 op2 = i2;
4921 assign(result, binop(Iop_Xor8, mkexpr(op1), mkU8(op2)));
4922 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4923 store(mkexpr(op1addr), mkexpr(result));
4924
4925 return "xiy";
4926}
4927
4928static HChar *
4929s390_irgen_XIHF(UChar r1, UInt i2)
4930{
4931 IRTemp op1 = newTemp(Ity_I32);
4932 UInt op2;
4933 IRTemp result = newTemp(Ity_I32);
4934
4935 assign(op1, get_gpr_w0(r1));
4936 op2 = i2;
4937 assign(result, binop(Iop_Xor32, mkexpr(op1), mkU32(op2)));
4938 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4939 put_gpr_w0(r1, mkexpr(result));
4940
4941 return "xihf";
4942}
4943
4944static HChar *
4945s390_irgen_XILF(UChar r1, UInt i2)
4946{
4947 IRTemp op1 = newTemp(Ity_I32);
4948 UInt op2;
4949 IRTemp result = newTemp(Ity_I32);
4950
4951 assign(op1, get_gpr_w1(r1));
4952 op2 = i2;
4953 assign(result, binop(Iop_Xor32, mkexpr(op1), mkU32(op2)));
4954 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4955 put_gpr_w1(r1, mkexpr(result));
4956
4957 return "xilf";
4958}
4959
4960static HChar *
4961s390_irgen_EAR(UChar r1, UChar r2)
4962{
4963 put_gpr_w1(r1, get_ar_w0(r2));
sewardj7ee97522011-05-09 21:45:04 +00004964 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00004965 s390_disasm(ENC3(MNM, GPR, AR), "ear", r1, r2);
4966
4967 return "ear";
4968}
4969
4970static HChar *
4971s390_irgen_IC(UChar r1, IRTemp op2addr)
4972{
4973 put_gpr_b7(r1, load(Ity_I8, mkexpr(op2addr)));
4974
4975 return "ic";
4976}
4977
4978static HChar *
4979s390_irgen_ICY(UChar r1, IRTemp op2addr)
4980{
4981 put_gpr_b7(r1, load(Ity_I8, mkexpr(op2addr)));
4982
4983 return "icy";
4984}
4985
4986static HChar *
4987s390_irgen_ICM(UChar r1, UChar r3, IRTemp op2addr)
4988{
4989 UChar n;
4990 IRTemp result = newTemp(Ity_I32);
4991 UInt mask;
4992
4993 n = 0;
4994 mask = (UInt)r3;
4995 if ((mask & 8) != 0) {
4996 put_gpr_b4(r1, load(Ity_I8, mkexpr(op2addr)));
4997 n = n + 1;
4998 }
4999 if ((mask & 4) != 0) {
5000 put_gpr_b5(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5001
5002 n = n + 1;
5003 }
5004 if ((mask & 2) != 0) {
5005 put_gpr_b6(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5006
5007 n = n + 1;
5008 }
5009 if ((mask & 1) != 0) {
5010 put_gpr_b7(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5011
5012 n = n + 1;
5013 }
5014 assign(result, get_gpr_w1(r1));
5015 s390_cc_thunk_putZZ(S390_CC_OP_INSERT_CHAR_MASK_32, result, mktemp(Ity_I32,
5016 mkU32(mask)));
5017
5018 return "icm";
5019}
5020
5021static HChar *
5022s390_irgen_ICMY(UChar r1, UChar r3, IRTemp op2addr)
5023{
5024 UChar n;
5025 IRTemp result = newTemp(Ity_I32);
5026 UInt mask;
5027
5028 n = 0;
5029 mask = (UInt)r3;
5030 if ((mask & 8) != 0) {
5031 put_gpr_b4(r1, load(Ity_I8, mkexpr(op2addr)));
5032 n = n + 1;
5033 }
5034 if ((mask & 4) != 0) {
5035 put_gpr_b5(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5036
5037 n = n + 1;
5038 }
5039 if ((mask & 2) != 0) {
5040 put_gpr_b6(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5041
5042 n = n + 1;
5043 }
5044 if ((mask & 1) != 0) {
5045 put_gpr_b7(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5046
5047 n = n + 1;
5048 }
5049 assign(result, get_gpr_w1(r1));
5050 s390_cc_thunk_putZZ(S390_CC_OP_INSERT_CHAR_MASK_32, result, mktemp(Ity_I32,
5051 mkU32(mask)));
5052
5053 return "icmy";
5054}
5055
5056static HChar *
5057s390_irgen_ICMH(UChar r1, UChar r3, IRTemp op2addr)
5058{
5059 UChar n;
5060 IRTemp result = newTemp(Ity_I32);
5061 UInt mask;
5062
5063 n = 0;
5064 mask = (UInt)r3;
5065 if ((mask & 8) != 0) {
5066 put_gpr_b0(r1, load(Ity_I8, mkexpr(op2addr)));
5067 n = n + 1;
5068 }
5069 if ((mask & 4) != 0) {
5070 put_gpr_b1(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5071
5072 n = n + 1;
5073 }
5074 if ((mask & 2) != 0) {
5075 put_gpr_b2(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5076
5077 n = n + 1;
5078 }
5079 if ((mask & 1) != 0) {
5080 put_gpr_b3(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5081
5082 n = n + 1;
5083 }
5084 assign(result, get_gpr_w0(r1));
5085 s390_cc_thunk_putZZ(S390_CC_OP_INSERT_CHAR_MASK_32, result, mktemp(Ity_I32,
5086 mkU32(mask)));
5087
5088 return "icmh";
5089}
5090
5091static HChar *
5092s390_irgen_IIHF(UChar r1, UInt i2)
5093{
5094 put_gpr_w0(r1, mkU32(i2));
5095
5096 return "iihf";
5097}
5098
5099static HChar *
5100s390_irgen_IIHH(UChar r1, UShort i2)
5101{
5102 put_gpr_hw0(r1, mkU16(i2));
5103
5104 return "iihh";
5105}
5106
5107static HChar *
5108s390_irgen_IIHL(UChar r1, UShort i2)
5109{
5110 put_gpr_hw1(r1, mkU16(i2));
5111
5112 return "iihl";
5113}
5114
5115static HChar *
5116s390_irgen_IILF(UChar r1, UInt i2)
5117{
5118 put_gpr_w1(r1, mkU32(i2));
5119
5120 return "iilf";
5121}
5122
5123static HChar *
5124s390_irgen_IILH(UChar r1, UShort i2)
5125{
5126 put_gpr_hw2(r1, mkU16(i2));
5127
5128 return "iilh";
5129}
5130
5131static HChar *
5132s390_irgen_IILL(UChar r1, UShort i2)
5133{
5134 put_gpr_hw3(r1, mkU16(i2));
5135
5136 return "iill";
5137}
5138
5139static HChar *
5140s390_irgen_LR(UChar r1, UChar r2)
5141{
5142 put_gpr_w1(r1, get_gpr_w1(r2));
5143
5144 return "lr";
5145}
5146
5147static HChar *
5148s390_irgen_LGR(UChar r1, UChar r2)
5149{
5150 put_gpr_dw0(r1, get_gpr_dw0(r2));
5151
5152 return "lgr";
5153}
5154
5155static HChar *
5156s390_irgen_LGFR(UChar r1, UChar r2)
5157{
5158 put_gpr_dw0(r1, unop(Iop_32Sto64, get_gpr_w1(r2)));
5159
5160 return "lgfr";
5161}
5162
5163static HChar *
5164s390_irgen_L(UChar r1, IRTemp op2addr)
5165{
5166 put_gpr_w1(r1, load(Ity_I32, mkexpr(op2addr)));
5167
5168 return "l";
5169}
5170
5171static HChar *
5172s390_irgen_LY(UChar r1, IRTemp op2addr)
5173{
5174 put_gpr_w1(r1, load(Ity_I32, mkexpr(op2addr)));
5175
5176 return "ly";
5177}
5178
5179static HChar *
5180s390_irgen_LG(UChar r1, IRTemp op2addr)
5181{
5182 put_gpr_dw0(r1, load(Ity_I64, mkexpr(op2addr)));
5183
5184 return "lg";
5185}
5186
5187static HChar *
5188s390_irgen_LGF(UChar r1, IRTemp op2addr)
5189{
5190 put_gpr_dw0(r1, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
5191
5192 return "lgf";
5193}
5194
5195static HChar *
5196s390_irgen_LGFI(UChar r1, UInt i2)
5197{
5198 put_gpr_dw0(r1, mkU64((ULong)(Long)(Int)i2));
5199
5200 return "lgfi";
5201}
5202
5203static HChar *
5204s390_irgen_LRL(UChar r1, UInt i2)
5205{
5206 put_gpr_w1(r1, load(Ity_I32, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
5207 i2 << 1))));
5208
5209 return "lrl";
5210}
5211
5212static HChar *
5213s390_irgen_LGRL(UChar r1, UInt i2)
5214{
5215 put_gpr_dw0(r1, load(Ity_I64, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
5216 i2 << 1))));
5217
5218 return "lgrl";
5219}
5220
5221static HChar *
5222s390_irgen_LGFRL(UChar r1, UInt i2)
5223{
5224 put_gpr_dw0(r1, unop(Iop_32Sto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
5225 ((ULong)(Long)(Int)i2 << 1)))));
5226
5227 return "lgfrl";
5228}
5229
5230static HChar *
5231s390_irgen_LA(UChar r1, IRTemp op2addr)
5232{
5233 put_gpr_dw0(r1, mkexpr(op2addr));
5234
5235 return "la";
5236}
5237
5238static HChar *
5239s390_irgen_LAY(UChar r1, IRTemp op2addr)
5240{
5241 put_gpr_dw0(r1, mkexpr(op2addr));
5242
5243 return "lay";
5244}
5245
5246static HChar *
5247s390_irgen_LAE(UChar r1, IRTemp op2addr)
5248{
5249 put_gpr_dw0(r1, mkexpr(op2addr));
5250
5251 return "lae";
5252}
5253
5254static HChar *
5255s390_irgen_LAEY(UChar r1, IRTemp op2addr)
5256{
5257 put_gpr_dw0(r1, mkexpr(op2addr));
5258
5259 return "laey";
5260}
5261
5262static HChar *
5263s390_irgen_LARL(UChar r1, UInt i2)
5264{
5265 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)));
5266
5267 return "larl";
5268}
5269
5270static HChar *
5271s390_irgen_LAA(UChar r1, UChar r3, IRTemp op2addr)
5272{
5273 IRTemp op2 = newTemp(Ity_I32);
5274 IRTemp op3 = newTemp(Ity_I32);
5275 IRTemp result = newTemp(Ity_I32);
5276
5277 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5278 assign(op3, get_gpr_w1(r3));
5279 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
5280 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
5281 store(mkexpr(op2addr), mkexpr(result));
5282 put_gpr_w1(r1, mkexpr(op2));
5283
5284 return "laa";
5285}
5286
5287static HChar *
5288s390_irgen_LAAG(UChar r1, UChar r3, IRTemp op2addr)
5289{
5290 IRTemp op2 = newTemp(Ity_I64);
5291 IRTemp op3 = newTemp(Ity_I64);
5292 IRTemp result = newTemp(Ity_I64);
5293
5294 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5295 assign(op3, get_gpr_dw0(r3));
5296 assign(result, binop(Iop_Add64, mkexpr(op2), mkexpr(op3)));
5297 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op2, op3);
5298 store(mkexpr(op2addr), mkexpr(result));
5299 put_gpr_dw0(r1, mkexpr(op2));
5300
5301 return "laag";
5302}
5303
5304static HChar *
5305s390_irgen_LAAL(UChar r1, UChar r3, IRTemp op2addr)
5306{
5307 IRTemp op2 = newTemp(Ity_I32);
5308 IRTemp op3 = newTemp(Ity_I32);
5309 IRTemp result = newTemp(Ity_I32);
5310
5311 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5312 assign(op3, get_gpr_w1(r3));
5313 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
5314 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
5315 store(mkexpr(op2addr), mkexpr(result));
5316 put_gpr_w1(r1, mkexpr(op2));
5317
5318 return "laal";
5319}
5320
5321static HChar *
5322s390_irgen_LAALG(UChar r1, UChar r3, IRTemp op2addr)
5323{
5324 IRTemp op2 = newTemp(Ity_I64);
5325 IRTemp op3 = newTemp(Ity_I64);
5326 IRTemp result = newTemp(Ity_I64);
5327
5328 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5329 assign(op3, get_gpr_dw0(r3));
5330 assign(result, binop(Iop_Add64, mkexpr(op2), mkexpr(op3)));
5331 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op2, op3);
5332 store(mkexpr(op2addr), mkexpr(result));
5333 put_gpr_dw0(r1, mkexpr(op2));
5334
5335 return "laalg";
5336}
5337
5338static HChar *
5339s390_irgen_LAN(UChar r1, UChar r3, IRTemp op2addr)
5340{
5341 IRTemp op2 = newTemp(Ity_I32);
5342 IRTemp op3 = newTemp(Ity_I32);
5343 IRTemp result = newTemp(Ity_I32);
5344
5345 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5346 assign(op3, get_gpr_w1(r3));
5347 assign(result, binop(Iop_And32, mkexpr(op2), mkexpr(op3)));
5348 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5349 store(mkexpr(op2addr), mkexpr(result));
5350 put_gpr_w1(r1, mkexpr(op2));
5351
5352 return "lan";
5353}
5354
5355static HChar *
5356s390_irgen_LANG(UChar r1, UChar r3, IRTemp op2addr)
5357{
5358 IRTemp op2 = newTemp(Ity_I64);
5359 IRTemp op3 = newTemp(Ity_I64);
5360 IRTemp result = newTemp(Ity_I64);
5361
5362 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5363 assign(op3, get_gpr_dw0(r3));
5364 assign(result, binop(Iop_And64, mkexpr(op2), mkexpr(op3)));
5365 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5366 store(mkexpr(op2addr), mkexpr(result));
5367 put_gpr_dw0(r1, mkexpr(op2));
5368
5369 return "lang";
5370}
5371
5372static HChar *
5373s390_irgen_LAX(UChar r1, UChar r3, IRTemp op2addr)
5374{
5375 IRTemp op2 = newTemp(Ity_I32);
5376 IRTemp op3 = newTemp(Ity_I32);
5377 IRTemp result = newTemp(Ity_I32);
5378
5379 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5380 assign(op3, get_gpr_w1(r3));
5381 assign(result, binop(Iop_Xor32, mkexpr(op2), mkexpr(op3)));
5382 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5383 store(mkexpr(op2addr), mkexpr(result));
5384 put_gpr_w1(r1, mkexpr(op2));
5385
5386 return "lax";
5387}
5388
5389static HChar *
5390s390_irgen_LAXG(UChar r1, UChar r3, IRTemp op2addr)
5391{
5392 IRTemp op2 = newTemp(Ity_I64);
5393 IRTemp op3 = newTemp(Ity_I64);
5394 IRTemp result = newTemp(Ity_I64);
5395
5396 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5397 assign(op3, get_gpr_dw0(r3));
5398 assign(result, binop(Iop_Xor64, mkexpr(op2), mkexpr(op3)));
5399 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5400 store(mkexpr(op2addr), mkexpr(result));
5401 put_gpr_dw0(r1, mkexpr(op2));
5402
5403 return "laxg";
5404}
5405
5406static HChar *
5407s390_irgen_LAO(UChar r1, UChar r3, IRTemp op2addr)
5408{
5409 IRTemp op2 = newTemp(Ity_I32);
5410 IRTemp op3 = newTemp(Ity_I32);
5411 IRTemp result = newTemp(Ity_I32);
5412
5413 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5414 assign(op3, get_gpr_w1(r3));
5415 assign(result, binop(Iop_Or32, mkexpr(op2), mkexpr(op3)));
5416 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5417 store(mkexpr(op2addr), mkexpr(result));
5418 put_gpr_w1(r1, mkexpr(op2));
5419
5420 return "lao";
5421}
5422
5423static HChar *
5424s390_irgen_LAOG(UChar r1, UChar r3, IRTemp op2addr)
5425{
5426 IRTemp op2 = newTemp(Ity_I64);
5427 IRTemp op3 = newTemp(Ity_I64);
5428 IRTemp result = newTemp(Ity_I64);
5429
5430 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5431 assign(op3, get_gpr_dw0(r3));
5432 assign(result, binop(Iop_Or64, mkexpr(op2), mkexpr(op3)));
5433 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5434 store(mkexpr(op2addr), mkexpr(result));
5435 put_gpr_dw0(r1, mkexpr(op2));
5436
5437 return "laog";
5438}
5439
5440static HChar *
5441s390_irgen_LTR(UChar r1, UChar r2)
5442{
5443 IRTemp op2 = newTemp(Ity_I32);
5444
5445 assign(op2, get_gpr_w1(r2));
5446 put_gpr_w1(r1, mkexpr(op2));
5447 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5448
5449 return "ltr";
5450}
5451
5452static HChar *
5453s390_irgen_LTGR(UChar r1, UChar r2)
5454{
5455 IRTemp op2 = newTemp(Ity_I64);
5456
5457 assign(op2, get_gpr_dw0(r2));
5458 put_gpr_dw0(r1, mkexpr(op2));
5459 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5460
5461 return "ltgr";
5462}
5463
5464static HChar *
5465s390_irgen_LTGFR(UChar r1, UChar r2)
5466{
5467 IRTemp op2 = newTemp(Ity_I64);
5468
5469 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
5470 put_gpr_dw0(r1, mkexpr(op2));
5471 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5472
5473 return "ltgfr";
5474}
5475
5476static HChar *
5477s390_irgen_LT(UChar r1, IRTemp op2addr)
5478{
5479 IRTemp op2 = newTemp(Ity_I32);
5480
5481 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5482 put_gpr_w1(r1, mkexpr(op2));
5483 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5484
5485 return "lt";
5486}
5487
5488static HChar *
5489s390_irgen_LTG(UChar r1, IRTemp op2addr)
5490{
5491 IRTemp op2 = newTemp(Ity_I64);
5492
5493 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5494 put_gpr_dw0(r1, mkexpr(op2));
5495 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5496
5497 return "ltg";
5498}
5499
5500static HChar *
5501s390_irgen_LTGF(UChar r1, IRTemp op2addr)
5502{
5503 IRTemp op2 = newTemp(Ity_I64);
5504
5505 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
5506 put_gpr_dw0(r1, mkexpr(op2));
5507 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5508
5509 return "ltgf";
5510}
5511
5512static HChar *
5513s390_irgen_LBR(UChar r1, UChar r2)
5514{
5515 put_gpr_w1(r1, unop(Iop_8Sto32, get_gpr_b7(r2)));
5516
5517 return "lbr";
5518}
5519
5520static HChar *
5521s390_irgen_LGBR(UChar r1, UChar r2)
5522{
5523 put_gpr_dw0(r1, unop(Iop_8Sto64, get_gpr_b7(r2)));
5524
5525 return "lgbr";
5526}
5527
5528static HChar *
5529s390_irgen_LB(UChar r1, IRTemp op2addr)
5530{
5531 put_gpr_w1(r1, unop(Iop_8Sto32, load(Ity_I8, mkexpr(op2addr))));
5532
5533 return "lb";
5534}
5535
5536static HChar *
5537s390_irgen_LGB(UChar r1, IRTemp op2addr)
5538{
5539 put_gpr_dw0(r1, unop(Iop_8Sto64, load(Ity_I8, mkexpr(op2addr))));
5540
5541 return "lgb";
5542}
5543
5544static HChar *
5545s390_irgen_LBH(UChar r1, IRTemp op2addr)
5546{
5547 put_gpr_w0(r1, unop(Iop_8Sto32, load(Ity_I8, mkexpr(op2addr))));
5548
5549 return "lbh";
5550}
5551
5552static HChar *
5553s390_irgen_LCR(UChar r1, UChar r2)
5554{
5555 Int op1;
5556 IRTemp op2 = newTemp(Ity_I32);
5557 IRTemp result = newTemp(Ity_I32);
5558
5559 op1 = 0;
5560 assign(op2, get_gpr_w1(r2));
5561 assign(result, binop(Iop_Sub32, mkU32((UInt)op1), mkexpr(op2)));
5562 put_gpr_w1(r1, mkexpr(result));
5563 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, mktemp(Ity_I32, mkU32((UInt)
5564 op1)), op2);
5565
5566 return "lcr";
5567}
5568
5569static HChar *
5570s390_irgen_LCGR(UChar r1, UChar r2)
5571{
5572 Long op1;
5573 IRTemp op2 = newTemp(Ity_I64);
5574 IRTemp result = newTemp(Ity_I64);
5575
5576 op1 = 0ULL;
5577 assign(op2, get_gpr_dw0(r2));
5578 assign(result, binop(Iop_Sub64, mkU64((ULong)op1), mkexpr(op2)));
5579 put_gpr_dw0(r1, mkexpr(result));
5580 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, mktemp(Ity_I64, mkU64((ULong)
5581 op1)), op2);
5582
5583 return "lcgr";
5584}
5585
5586static HChar *
5587s390_irgen_LCGFR(UChar r1, UChar r2)
5588{
5589 Long op1;
5590 IRTemp op2 = newTemp(Ity_I64);
5591 IRTemp result = newTemp(Ity_I64);
5592
5593 op1 = 0ULL;
5594 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
5595 assign(result, binop(Iop_Sub64, mkU64((ULong)op1), mkexpr(op2)));
5596 put_gpr_dw0(r1, mkexpr(result));
5597 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, mktemp(Ity_I64, mkU64((ULong)
5598 op1)), op2);
5599
5600 return "lcgfr";
5601}
5602
5603static HChar *
5604s390_irgen_LHR(UChar r1, UChar r2)
5605{
5606 put_gpr_w1(r1, unop(Iop_16Sto32, get_gpr_hw3(r2)));
5607
5608 return "lhr";
5609}
5610
5611static HChar *
5612s390_irgen_LGHR(UChar r1, UChar r2)
5613{
5614 put_gpr_dw0(r1, unop(Iop_16Sto64, get_gpr_hw3(r2)));
5615
5616 return "lghr";
5617}
5618
5619static HChar *
5620s390_irgen_LH(UChar r1, IRTemp op2addr)
5621{
5622 put_gpr_w1(r1, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
5623
5624 return "lh";
5625}
5626
5627static HChar *
5628s390_irgen_LHY(UChar r1, IRTemp op2addr)
5629{
5630 put_gpr_w1(r1, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
5631
5632 return "lhy";
5633}
5634
5635static HChar *
5636s390_irgen_LGH(UChar r1, IRTemp op2addr)
5637{
5638 put_gpr_dw0(r1, unop(Iop_16Sto64, load(Ity_I16, mkexpr(op2addr))));
5639
5640 return "lgh";
5641}
5642
5643static HChar *
5644s390_irgen_LHI(UChar r1, UShort i2)
5645{
5646 put_gpr_w1(r1, mkU32((UInt)(Int)(Short)i2));
5647
5648 return "lhi";
5649}
5650
5651static HChar *
5652s390_irgen_LGHI(UChar r1, UShort i2)
5653{
5654 put_gpr_dw0(r1, mkU64((ULong)(Long)(Short)i2));
5655
5656 return "lghi";
5657}
5658
5659static HChar *
5660s390_irgen_LHRL(UChar r1, UInt i2)
5661{
5662 put_gpr_w1(r1, unop(Iop_16Sto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
5663 ((ULong)(Long)(Int)i2 << 1)))));
5664
5665 return "lhrl";
5666}
5667
5668static HChar *
5669s390_irgen_LGHRL(UChar r1, UInt i2)
5670{
5671 put_gpr_dw0(r1, unop(Iop_16Sto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
5672 ((ULong)(Long)(Int)i2 << 1)))));
5673
5674 return "lghrl";
5675}
5676
5677static HChar *
5678s390_irgen_LHH(UChar r1, IRTemp op2addr)
5679{
5680 put_gpr_w0(r1, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
5681
5682 return "lhh";
5683}
5684
5685static HChar *
5686s390_irgen_LFH(UChar r1, IRTemp op2addr)
5687{
5688 put_gpr_w0(r1, load(Ity_I32, mkexpr(op2addr)));
5689
5690 return "lfh";
5691}
5692
5693static HChar *
5694s390_irgen_LLGFR(UChar r1, UChar r2)
5695{
5696 put_gpr_dw0(r1, unop(Iop_32Uto64, get_gpr_w1(r2)));
5697
5698 return "llgfr";
5699}
5700
5701static HChar *
5702s390_irgen_LLGF(UChar r1, IRTemp op2addr)
5703{
5704 put_gpr_dw0(r1, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
5705
5706 return "llgf";
5707}
5708
5709static HChar *
5710s390_irgen_LLGFRL(UChar r1, UInt i2)
5711{
5712 put_gpr_dw0(r1, unop(Iop_32Uto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
5713 ((ULong)(Long)(Int)i2 << 1)))));
5714
5715 return "llgfrl";
5716}
5717
5718static HChar *
5719s390_irgen_LLCR(UChar r1, UChar r2)
5720{
5721 put_gpr_w1(r1, unop(Iop_8Uto32, get_gpr_b7(r2)));
5722
5723 return "llcr";
5724}
5725
5726static HChar *
5727s390_irgen_LLGCR(UChar r1, UChar r2)
5728{
5729 put_gpr_dw0(r1, unop(Iop_8Uto64, get_gpr_b7(r2)));
5730
5731 return "llgcr";
5732}
5733
5734static HChar *
5735s390_irgen_LLC(UChar r1, IRTemp op2addr)
5736{
5737 put_gpr_w1(r1, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
5738
5739 return "llc";
5740}
5741
5742static HChar *
5743s390_irgen_LLGC(UChar r1, IRTemp op2addr)
5744{
5745 put_gpr_dw0(r1, unop(Iop_8Uto64, load(Ity_I8, mkexpr(op2addr))));
5746
5747 return "llgc";
5748}
5749
5750static HChar *
5751s390_irgen_LLCH(UChar r1, IRTemp op2addr)
5752{
5753 put_gpr_w0(r1, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
5754
5755 return "llch";
5756}
5757
5758static HChar *
5759s390_irgen_LLHR(UChar r1, UChar r2)
5760{
5761 put_gpr_w1(r1, unop(Iop_16Uto32, get_gpr_hw3(r2)));
5762
5763 return "llhr";
5764}
5765
5766static HChar *
5767s390_irgen_LLGHR(UChar r1, UChar r2)
5768{
5769 put_gpr_dw0(r1, unop(Iop_16Uto64, get_gpr_hw3(r2)));
5770
5771 return "llghr";
5772}
5773
5774static HChar *
5775s390_irgen_LLH(UChar r1, IRTemp op2addr)
5776{
5777 put_gpr_w1(r1, unop(Iop_16Uto32, load(Ity_I16, mkexpr(op2addr))));
5778
5779 return "llh";
5780}
5781
5782static HChar *
5783s390_irgen_LLGH(UChar r1, IRTemp op2addr)
5784{
5785 put_gpr_dw0(r1, unop(Iop_16Uto64, load(Ity_I16, mkexpr(op2addr))));
5786
5787 return "llgh";
5788}
5789
5790static HChar *
5791s390_irgen_LLHRL(UChar r1, UInt i2)
5792{
5793 put_gpr_w1(r1, unop(Iop_16Uto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
5794 ((ULong)(Long)(Int)i2 << 1)))));
5795
5796 return "llhrl";
5797}
5798
5799static HChar *
5800s390_irgen_LLGHRL(UChar r1, UInt i2)
5801{
5802 put_gpr_dw0(r1, unop(Iop_16Uto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
5803 ((ULong)(Long)(Int)i2 << 1)))));
5804
5805 return "llghrl";
5806}
5807
5808static HChar *
5809s390_irgen_LLHH(UChar r1, IRTemp op2addr)
5810{
5811 put_gpr_w0(r1, unop(Iop_16Uto32, load(Ity_I16, mkexpr(op2addr))));
5812
5813 return "llhh";
5814}
5815
5816static HChar *
5817s390_irgen_LLIHF(UChar r1, UInt i2)
5818{
5819 put_gpr_dw0(r1, mkU64(((ULong)i2) << 32));
5820
5821 return "llihf";
5822}
5823
5824static HChar *
5825s390_irgen_LLIHH(UChar r1, UShort i2)
5826{
5827 put_gpr_dw0(r1, mkU64(((ULong)i2) << 48));
5828
5829 return "llihh";
5830}
5831
5832static HChar *
5833s390_irgen_LLIHL(UChar r1, UShort i2)
5834{
5835 put_gpr_dw0(r1, mkU64(((ULong)i2) << 32));
5836
5837 return "llihl";
5838}
5839
5840static HChar *
5841s390_irgen_LLILF(UChar r1, UInt i2)
5842{
5843 put_gpr_dw0(r1, mkU64(i2));
5844
5845 return "llilf";
5846}
5847
5848static HChar *
5849s390_irgen_LLILH(UChar r1, UShort i2)
5850{
5851 put_gpr_dw0(r1, mkU64(((ULong)i2) << 16));
5852
5853 return "llilh";
5854}
5855
5856static HChar *
5857s390_irgen_LLILL(UChar r1, UShort i2)
5858{
5859 put_gpr_dw0(r1, mkU64(i2));
5860
5861 return "llill";
5862}
5863
5864static HChar *
5865s390_irgen_LLGTR(UChar r1, UChar r2)
5866{
5867 put_gpr_dw0(r1, unop(Iop_32Uto64, binop(Iop_And32, get_gpr_w1(r2),
5868 mkU32(2147483647))));
5869
5870 return "llgtr";
5871}
5872
5873static HChar *
5874s390_irgen_LLGT(UChar r1, IRTemp op2addr)
5875{
5876 put_gpr_dw0(r1, unop(Iop_32Uto64, binop(Iop_And32, load(Ity_I32,
5877 mkexpr(op2addr)), mkU32(2147483647))));
5878
5879 return "llgt";
5880}
5881
5882static HChar *
5883s390_irgen_LNR(UChar r1, UChar r2)
5884{
5885 IRTemp op2 = newTemp(Ity_I32);
5886 IRTemp result = newTemp(Ity_I32);
5887
5888 assign(op2, get_gpr_w1(r2));
5889 assign(result, mkite(binop(Iop_CmpLE32S, mkexpr(op2), mkU32(0)), mkexpr(op2),
5890 binop(Iop_Sub32, mkU32(0), mkexpr(op2))));
5891 put_gpr_w1(r1, mkexpr(result));
5892 s390_cc_thunk_putS(S390_CC_OP_BITWISE, result);
5893
5894 return "lnr";
5895}
5896
5897static HChar *
5898s390_irgen_LNGR(UChar r1, UChar r2)
5899{
5900 IRTemp op2 = newTemp(Ity_I64);
5901 IRTemp result = newTemp(Ity_I64);
5902
5903 assign(op2, get_gpr_dw0(r2));
5904 assign(result, mkite(binop(Iop_CmpLE64S, mkexpr(op2), mkU64(0)), mkexpr(op2),
5905 binop(Iop_Sub64, mkU64(0), mkexpr(op2))));
5906 put_gpr_dw0(r1, mkexpr(result));
5907 s390_cc_thunk_putS(S390_CC_OP_BITWISE, result);
5908
5909 return "lngr";
5910}
5911
5912static HChar *
5913s390_irgen_LNGFR(UChar r1, UChar r2 __attribute__((unused)))
5914{
5915 IRTemp op2 = newTemp(Ity_I64);
5916 IRTemp result = newTemp(Ity_I64);
5917
5918 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r1)));
5919 assign(result, mkite(binop(Iop_CmpLE64S, mkexpr(op2), mkU64(0)), mkexpr(op2),
5920 binop(Iop_Sub64, mkU64(0), mkexpr(op2))));
5921 put_gpr_dw0(r1, mkexpr(result));
5922 s390_cc_thunk_putS(S390_CC_OP_BITWISE, result);
5923
5924 return "lngfr";
5925}
5926
5927static HChar *
sewardjd7bde722011-04-05 13:19:33 +00005928s390_irgen_LOCR(UChar m3, UChar r1, UChar r2)
5929{
florian6820ba52012-07-26 02:01:50 +00005930 next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0)));
sewardjd7bde722011-04-05 13:19:33 +00005931 put_gpr_w1(r1, get_gpr_w1(r2));
5932
5933 return "locr";
5934}
5935
5936static HChar *
5937s390_irgen_LOCGR(UChar m3, UChar r1, UChar r2)
5938{
florian6820ba52012-07-26 02:01:50 +00005939 next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0)));
sewardjd7bde722011-04-05 13:19:33 +00005940 put_gpr_dw0(r1, get_gpr_dw0(r2));
5941
5942 return "locgr";
5943}
5944
5945static HChar *
5946s390_irgen_LOC(UChar r1, IRTemp op2addr)
5947{
5948 /* condition is checked in format handler */
5949 put_gpr_w1(r1, load(Ity_I32, mkexpr(op2addr)));
5950
5951 return "loc";
5952}
5953
5954static HChar *
5955s390_irgen_LOCG(UChar r1, IRTemp op2addr)
5956{
5957 /* condition is checked in format handler */
5958 put_gpr_dw0(r1, load(Ity_I64, mkexpr(op2addr)));
5959
5960 return "locg";
5961}
5962
5963static HChar *
sewardj2019a972011-03-07 16:04:07 +00005964s390_irgen_LPQ(UChar r1, IRTemp op2addr)
5965{
5966 put_gpr_dw0(r1, load(Ity_I64, mkexpr(op2addr)));
5967 put_gpr_dw0(r1 + 1, load(Ity_I64, binop(Iop_Add64, mkexpr(op2addr), mkU64(8))
5968 ));
5969
5970 return "lpq";
5971}
5972
5973static HChar *
5974s390_irgen_LPR(UChar r1, UChar r2)
5975{
5976 IRTemp op2 = newTemp(Ity_I32);
5977 IRTemp result = newTemp(Ity_I32);
5978
5979 assign(op2, get_gpr_w1(r2));
5980 assign(result, mkite(binop(Iop_CmpLT32S, mkexpr(op2), mkU32(0)),
5981 binop(Iop_Sub32, mkU32(0), mkexpr(op2)), mkexpr(op2)));
5982 put_gpr_w1(r1, mkexpr(result));
5983 s390_cc_thunk_putS(S390_CC_OP_LOAD_POSITIVE_32, op2);
5984
5985 return "lpr";
5986}
5987
5988static HChar *
5989s390_irgen_LPGR(UChar r1, UChar r2)
5990{
5991 IRTemp op2 = newTemp(Ity_I64);
5992 IRTemp result = newTemp(Ity_I64);
5993
5994 assign(op2, get_gpr_dw0(r2));
5995 assign(result, mkite(binop(Iop_CmpLT64S, mkexpr(op2), mkU64(0)),
5996 binop(Iop_Sub64, mkU64(0), mkexpr(op2)), mkexpr(op2)));
5997 put_gpr_dw0(r1, mkexpr(result));
5998 s390_cc_thunk_putS(S390_CC_OP_LOAD_POSITIVE_64, op2);
5999
6000 return "lpgr";
6001}
6002
6003static HChar *
6004s390_irgen_LPGFR(UChar r1, UChar r2)
6005{
6006 IRTemp op2 = newTemp(Ity_I64);
6007 IRTemp result = newTemp(Ity_I64);
6008
6009 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
6010 assign(result, mkite(binop(Iop_CmpLT64S, mkexpr(op2), mkU64(0)),
6011 binop(Iop_Sub64, mkU64(0), mkexpr(op2)), mkexpr(op2)));
6012 put_gpr_dw0(r1, mkexpr(result));
6013 s390_cc_thunk_putS(S390_CC_OP_LOAD_POSITIVE_64, op2);
6014
6015 return "lpgfr";
6016}
6017
6018static HChar *
6019s390_irgen_LRVR(UChar r1, UChar r2)
6020{
6021 IRTemp b0 = newTemp(Ity_I8);
6022 IRTemp b1 = newTemp(Ity_I8);
6023 IRTemp b2 = newTemp(Ity_I8);
6024 IRTemp b3 = newTemp(Ity_I8);
6025
6026 assign(b3, get_gpr_b7(r2));
6027 assign(b2, get_gpr_b6(r2));
6028 assign(b1, get_gpr_b5(r2));
6029 assign(b0, get_gpr_b4(r2));
6030 put_gpr_b4(r1, mkexpr(b3));
6031 put_gpr_b5(r1, mkexpr(b2));
6032 put_gpr_b6(r1, mkexpr(b1));
6033 put_gpr_b7(r1, mkexpr(b0));
6034
6035 return "lrvr";
6036}
6037
6038static HChar *
6039s390_irgen_LRVGR(UChar r1, UChar r2)
6040{
6041 IRTemp b0 = newTemp(Ity_I8);
6042 IRTemp b1 = newTemp(Ity_I8);
6043 IRTemp b2 = newTemp(Ity_I8);
6044 IRTemp b3 = newTemp(Ity_I8);
6045 IRTemp b4 = newTemp(Ity_I8);
6046 IRTemp b5 = newTemp(Ity_I8);
6047 IRTemp b6 = newTemp(Ity_I8);
6048 IRTemp b7 = newTemp(Ity_I8);
6049
6050 assign(b7, get_gpr_b7(r2));
6051 assign(b6, get_gpr_b6(r2));
6052 assign(b5, get_gpr_b5(r2));
6053 assign(b4, get_gpr_b4(r2));
6054 assign(b3, get_gpr_b3(r2));
6055 assign(b2, get_gpr_b2(r2));
6056 assign(b1, get_gpr_b1(r2));
6057 assign(b0, get_gpr_b0(r2));
6058 put_gpr_b0(r1, mkexpr(b7));
6059 put_gpr_b1(r1, mkexpr(b6));
6060 put_gpr_b2(r1, mkexpr(b5));
6061 put_gpr_b3(r1, mkexpr(b4));
6062 put_gpr_b4(r1, mkexpr(b3));
6063 put_gpr_b5(r1, mkexpr(b2));
6064 put_gpr_b6(r1, mkexpr(b1));
6065 put_gpr_b7(r1, mkexpr(b0));
6066
6067 return "lrvgr";
6068}
6069
6070static HChar *
6071s390_irgen_LRVH(UChar r1, IRTemp op2addr)
6072{
6073 IRTemp op2 = newTemp(Ity_I16);
6074
6075 assign(op2, load(Ity_I16, mkexpr(op2addr)));
6076 put_gpr_b6(r1, unop(Iop_16to8, mkexpr(op2)));
6077 put_gpr_b7(r1, unop(Iop_16HIto8, mkexpr(op2)));
6078
6079 return "lrvh";
6080}
6081
6082static HChar *
6083s390_irgen_LRV(UChar r1, IRTemp op2addr)
6084{
6085 IRTemp op2 = newTemp(Ity_I32);
6086
6087 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6088 put_gpr_b4(r1, unop(Iop_32to8, binop(Iop_And32, mkexpr(op2), mkU32(255))));
6089 put_gpr_b5(r1, unop(Iop_32to8, binop(Iop_And32, binop(Iop_Shr32, mkexpr(op2),
6090 mkU8(8)), mkU32(255))));
6091 put_gpr_b6(r1, unop(Iop_32to8, binop(Iop_And32, binop(Iop_Shr32, mkexpr(op2),
6092 mkU8(16)), mkU32(255))));
6093 put_gpr_b7(r1, unop(Iop_32to8, binop(Iop_And32, binop(Iop_Shr32, mkexpr(op2),
6094 mkU8(24)), mkU32(255))));
6095
6096 return "lrv";
6097}
6098
6099static HChar *
6100s390_irgen_LRVG(UChar r1, IRTemp op2addr)
6101{
6102 IRTemp op2 = newTemp(Ity_I64);
6103
6104 assign(op2, load(Ity_I64, mkexpr(op2addr)));
6105 put_gpr_b0(r1, unop(Iop_64to8, binop(Iop_And64, mkexpr(op2), mkU64(255))));
6106 put_gpr_b1(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6107 mkU8(8)), mkU64(255))));
6108 put_gpr_b2(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6109 mkU8(16)), mkU64(255))));
6110 put_gpr_b3(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6111 mkU8(24)), mkU64(255))));
6112 put_gpr_b4(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6113 mkU8(32)), mkU64(255))));
6114 put_gpr_b5(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6115 mkU8(40)), mkU64(255))));
6116 put_gpr_b6(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6117 mkU8(48)), mkU64(255))));
6118 put_gpr_b7(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6119 mkU8(56)), mkU64(255))));
6120
6121 return "lrvg";
6122}
6123
6124static HChar *
6125s390_irgen_MVHHI(UShort i2, IRTemp op1addr)
6126{
6127 store(mkexpr(op1addr), mkU16(i2));
6128
6129 return "mvhhi";
6130}
6131
6132static HChar *
6133s390_irgen_MVHI(UShort i2, IRTemp op1addr)
6134{
6135 store(mkexpr(op1addr), mkU32((UInt)(Int)(Short)i2));
6136
6137 return "mvhi";
6138}
6139
6140static HChar *
6141s390_irgen_MVGHI(UShort i2, IRTemp op1addr)
6142{
6143 store(mkexpr(op1addr), mkU64((ULong)(Long)(Short)i2));
6144
6145 return "mvghi";
6146}
6147
6148static HChar *
6149s390_irgen_MVI(UChar i2, IRTemp op1addr)
6150{
6151 store(mkexpr(op1addr), mkU8(i2));
6152
6153 return "mvi";
6154}
6155
6156static HChar *
6157s390_irgen_MVIY(UChar i2, IRTemp op1addr)
6158{
6159 store(mkexpr(op1addr), mkU8(i2));
6160
6161 return "mviy";
6162}
6163
6164static HChar *
6165s390_irgen_MR(UChar r1, UChar r2)
6166{
6167 IRTemp op1 = newTemp(Ity_I32);
6168 IRTemp op2 = newTemp(Ity_I32);
6169 IRTemp result = newTemp(Ity_I64);
6170
6171 assign(op1, get_gpr_w1(r1 + 1));
6172 assign(op2, get_gpr_w1(r2));
6173 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6174 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6175 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6176
6177 return "mr";
6178}
6179
6180static HChar *
6181s390_irgen_M(UChar r1, IRTemp op2addr)
6182{
6183 IRTemp op1 = newTemp(Ity_I32);
6184 IRTemp op2 = newTemp(Ity_I32);
6185 IRTemp result = newTemp(Ity_I64);
6186
6187 assign(op1, get_gpr_w1(r1 + 1));
6188 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6189 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6190 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6191 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6192
6193 return "m";
6194}
6195
6196static HChar *
6197s390_irgen_MFY(UChar r1, IRTemp op2addr)
6198{
6199 IRTemp op1 = newTemp(Ity_I32);
6200 IRTemp op2 = newTemp(Ity_I32);
6201 IRTemp result = newTemp(Ity_I64);
6202
6203 assign(op1, get_gpr_w1(r1 + 1));
6204 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6205 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6206 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6207 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6208
6209 return "mfy";
6210}
6211
6212static HChar *
6213s390_irgen_MH(UChar r1, IRTemp op2addr)
6214{
6215 IRTemp op1 = newTemp(Ity_I32);
6216 IRTemp op2 = newTemp(Ity_I16);
6217 IRTemp result = newTemp(Ity_I64);
6218
6219 assign(op1, get_gpr_w1(r1));
6220 assign(op2, load(Ity_I16, mkexpr(op2addr)));
6221 assign(result, binop(Iop_MullS32, mkexpr(op1), unop(Iop_16Sto32, mkexpr(op2))
6222 ));
6223 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6224
6225 return "mh";
6226}
6227
6228static HChar *
6229s390_irgen_MHY(UChar r1, IRTemp op2addr)
6230{
6231 IRTemp op1 = newTemp(Ity_I32);
6232 IRTemp op2 = newTemp(Ity_I16);
6233 IRTemp result = newTemp(Ity_I64);
6234
6235 assign(op1, get_gpr_w1(r1));
6236 assign(op2, load(Ity_I16, mkexpr(op2addr)));
6237 assign(result, binop(Iop_MullS32, mkexpr(op1), unop(Iop_16Sto32, mkexpr(op2))
6238 ));
6239 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6240
6241 return "mhy";
6242}
6243
6244static HChar *
6245s390_irgen_MHI(UChar r1, UShort i2)
6246{
6247 IRTemp op1 = newTemp(Ity_I32);
6248 Short op2;
6249 IRTemp result = newTemp(Ity_I64);
6250
6251 assign(op1, get_gpr_w1(r1));
6252 op2 = (Short)i2;
6253 assign(result, binop(Iop_MullS32, mkexpr(op1), unop(Iop_16Sto32,
6254 mkU16((UShort)op2))));
6255 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6256
6257 return "mhi";
6258}
6259
6260static HChar *
6261s390_irgen_MGHI(UChar r1, UShort i2)
6262{
6263 IRTemp op1 = newTemp(Ity_I64);
6264 Short op2;
6265 IRTemp result = newTemp(Ity_I128);
6266
6267 assign(op1, get_gpr_dw0(r1));
6268 op2 = (Short)i2;
6269 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_16Sto64,
6270 mkU16((UShort)op2))));
6271 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6272
6273 return "mghi";
6274}
6275
6276static HChar *
6277s390_irgen_MLR(UChar r1, UChar r2)
6278{
6279 IRTemp op1 = newTemp(Ity_I32);
6280 IRTemp op2 = newTemp(Ity_I32);
6281 IRTemp result = newTemp(Ity_I64);
6282
6283 assign(op1, get_gpr_w1(r1 + 1));
6284 assign(op2, get_gpr_w1(r2));
6285 assign(result, binop(Iop_MullU32, mkexpr(op1), mkexpr(op2)));
6286 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6287 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6288
6289 return "mlr";
6290}
6291
6292static HChar *
6293s390_irgen_MLGR(UChar r1, UChar r2)
6294{
6295 IRTemp op1 = newTemp(Ity_I64);
6296 IRTemp op2 = newTemp(Ity_I64);
6297 IRTemp result = newTemp(Ity_I128);
6298
6299 assign(op1, get_gpr_dw0(r1 + 1));
6300 assign(op2, get_gpr_dw0(r2));
6301 assign(result, binop(Iop_MullU64, mkexpr(op1), mkexpr(op2)));
6302 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result)));
6303 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result)));
6304
6305 return "mlgr";
6306}
6307
6308static HChar *
6309s390_irgen_ML(UChar r1, IRTemp op2addr)
6310{
6311 IRTemp op1 = newTemp(Ity_I32);
6312 IRTemp op2 = newTemp(Ity_I32);
6313 IRTemp result = newTemp(Ity_I64);
6314
6315 assign(op1, get_gpr_w1(r1 + 1));
6316 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6317 assign(result, binop(Iop_MullU32, mkexpr(op1), mkexpr(op2)));
6318 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6319 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6320
6321 return "ml";
6322}
6323
6324static HChar *
6325s390_irgen_MLG(UChar r1, IRTemp op2addr)
6326{
6327 IRTemp op1 = newTemp(Ity_I64);
6328 IRTemp op2 = newTemp(Ity_I64);
6329 IRTemp result = newTemp(Ity_I128);
6330
6331 assign(op1, get_gpr_dw0(r1 + 1));
6332 assign(op2, load(Ity_I64, mkexpr(op2addr)));
6333 assign(result, binop(Iop_MullU64, mkexpr(op1), mkexpr(op2)));
6334 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result)));
6335 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result)));
6336
6337 return "mlg";
6338}
6339
6340static HChar *
6341s390_irgen_MSR(UChar r1, UChar r2)
6342{
6343 IRTemp op1 = newTemp(Ity_I32);
6344 IRTemp op2 = newTemp(Ity_I32);
6345 IRTemp result = newTemp(Ity_I64);
6346
6347 assign(op1, get_gpr_w1(r1));
6348 assign(op2, get_gpr_w1(r2));
6349 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6350 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6351
6352 return "msr";
6353}
6354
6355static HChar *
6356s390_irgen_MSGR(UChar r1, UChar r2)
6357{
6358 IRTemp op1 = newTemp(Ity_I64);
6359 IRTemp op2 = newTemp(Ity_I64);
6360 IRTemp result = newTemp(Ity_I128);
6361
6362 assign(op1, get_gpr_dw0(r1));
6363 assign(op2, get_gpr_dw0(r2));
6364 assign(result, binop(Iop_MullS64, mkexpr(op1), mkexpr(op2)));
6365 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6366
6367 return "msgr";
6368}
6369
6370static HChar *
6371s390_irgen_MSGFR(UChar r1, UChar r2)
6372{
6373 IRTemp op1 = newTemp(Ity_I64);
6374 IRTemp op2 = newTemp(Ity_I32);
6375 IRTemp result = newTemp(Ity_I128);
6376
6377 assign(op1, get_gpr_dw0(r1));
6378 assign(op2, get_gpr_w1(r2));
6379 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_32Sto64, mkexpr(op2))
6380 ));
6381 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6382
6383 return "msgfr";
6384}
6385
6386static HChar *
6387s390_irgen_MS(UChar r1, IRTemp op2addr)
6388{
6389 IRTemp op1 = newTemp(Ity_I32);
6390 IRTemp op2 = newTemp(Ity_I32);
6391 IRTemp result = newTemp(Ity_I64);
6392
6393 assign(op1, get_gpr_w1(r1));
6394 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6395 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6396 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6397
6398 return "ms";
6399}
6400
6401static HChar *
6402s390_irgen_MSY(UChar r1, IRTemp op2addr)
6403{
6404 IRTemp op1 = newTemp(Ity_I32);
6405 IRTemp op2 = newTemp(Ity_I32);
6406 IRTemp result = newTemp(Ity_I64);
6407
6408 assign(op1, get_gpr_w1(r1));
6409 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6410 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6411 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6412
6413 return "msy";
6414}
6415
6416static HChar *
6417s390_irgen_MSG(UChar r1, IRTemp op2addr)
6418{
6419 IRTemp op1 = newTemp(Ity_I64);
6420 IRTemp op2 = newTemp(Ity_I64);
6421 IRTemp result = newTemp(Ity_I128);
6422
6423 assign(op1, get_gpr_dw0(r1));
6424 assign(op2, load(Ity_I64, mkexpr(op2addr)));
6425 assign(result, binop(Iop_MullS64, mkexpr(op1), mkexpr(op2)));
6426 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6427
6428 return "msg";
6429}
6430
6431static HChar *
6432s390_irgen_MSGF(UChar r1, IRTemp op2addr)
6433{
6434 IRTemp op1 = newTemp(Ity_I64);
6435 IRTemp op2 = newTemp(Ity_I32);
6436 IRTemp result = newTemp(Ity_I128);
6437
6438 assign(op1, get_gpr_dw0(r1));
6439 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6440 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_32Sto64, mkexpr(op2))
6441 ));
6442 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6443
6444 return "msgf";
6445}
6446
6447static HChar *
6448s390_irgen_MSFI(UChar r1, UInt i2)
6449{
6450 IRTemp op1 = newTemp(Ity_I32);
6451 Int op2;
6452 IRTemp result = newTemp(Ity_I64);
6453
6454 assign(op1, get_gpr_w1(r1));
6455 op2 = (Int)i2;
6456 assign(result, binop(Iop_MullS32, mkexpr(op1), mkU32((UInt)op2)));
6457 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6458
6459 return "msfi";
6460}
6461
6462static HChar *
6463s390_irgen_MSGFI(UChar r1, UInt i2)
6464{
6465 IRTemp op1 = newTemp(Ity_I64);
6466 Int op2;
6467 IRTemp result = newTemp(Ity_I128);
6468
6469 assign(op1, get_gpr_dw0(r1));
6470 op2 = (Int)i2;
6471 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_32Sto64, mkU32((UInt)
6472 op2))));
6473 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6474
6475 return "msgfi";
6476}
6477
6478static HChar *
6479s390_irgen_OR(UChar r1, UChar r2)
6480{
6481 IRTemp op1 = newTemp(Ity_I32);
6482 IRTemp op2 = newTemp(Ity_I32);
6483 IRTemp result = newTemp(Ity_I32);
6484
6485 assign(op1, get_gpr_w1(r1));
6486 assign(op2, get_gpr_w1(r2));
6487 assign(result, binop(Iop_Or32, mkexpr(op1), mkexpr(op2)));
6488 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6489 put_gpr_w1(r1, mkexpr(result));
6490
6491 return "or";
6492}
6493
6494static HChar *
6495s390_irgen_OGR(UChar r1, UChar r2)
6496{
6497 IRTemp op1 = newTemp(Ity_I64);
6498 IRTemp op2 = newTemp(Ity_I64);
6499 IRTemp result = newTemp(Ity_I64);
6500
6501 assign(op1, get_gpr_dw0(r1));
6502 assign(op2, get_gpr_dw0(r2));
6503 assign(result, binop(Iop_Or64, mkexpr(op1), mkexpr(op2)));
6504 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6505 put_gpr_dw0(r1, mkexpr(result));
6506
6507 return "ogr";
6508}
6509
6510static HChar *
6511s390_irgen_ORK(UChar r3, UChar r1, UChar r2)
6512{
6513 IRTemp op2 = newTemp(Ity_I32);
6514 IRTemp op3 = newTemp(Ity_I32);
6515 IRTemp result = newTemp(Ity_I32);
6516
6517 assign(op2, get_gpr_w1(r2));
6518 assign(op3, get_gpr_w1(r3));
6519 assign(result, binop(Iop_Or32, mkexpr(op2), mkexpr(op3)));
6520 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6521 put_gpr_w1(r1, mkexpr(result));
6522
6523 return "ork";
6524}
6525
6526static HChar *
6527s390_irgen_OGRK(UChar r3, UChar r1, UChar r2)
6528{
6529 IRTemp op2 = newTemp(Ity_I64);
6530 IRTemp op3 = newTemp(Ity_I64);
6531 IRTemp result = newTemp(Ity_I64);
6532
6533 assign(op2, get_gpr_dw0(r2));
6534 assign(op3, get_gpr_dw0(r3));
6535 assign(result, binop(Iop_Or64, mkexpr(op2), mkexpr(op3)));
6536 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6537 put_gpr_dw0(r1, mkexpr(result));
6538
6539 return "ogrk";
6540}
6541
6542static HChar *
6543s390_irgen_O(UChar r1, IRTemp op2addr)
6544{
6545 IRTemp op1 = newTemp(Ity_I32);
6546 IRTemp op2 = newTemp(Ity_I32);
6547 IRTemp result = newTemp(Ity_I32);
6548
6549 assign(op1, get_gpr_w1(r1));
6550 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6551 assign(result, binop(Iop_Or32, mkexpr(op1), mkexpr(op2)));
6552 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6553 put_gpr_w1(r1, mkexpr(result));
6554
6555 return "o";
6556}
6557
6558static HChar *
6559s390_irgen_OY(UChar r1, IRTemp op2addr)
6560{
6561 IRTemp op1 = newTemp(Ity_I32);
6562 IRTemp op2 = newTemp(Ity_I32);
6563 IRTemp result = newTemp(Ity_I32);
6564
6565 assign(op1, get_gpr_w1(r1));
6566 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6567 assign(result, binop(Iop_Or32, mkexpr(op1), mkexpr(op2)));
6568 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6569 put_gpr_w1(r1, mkexpr(result));
6570
6571 return "oy";
6572}
6573
6574static HChar *
6575s390_irgen_OG(UChar r1, IRTemp op2addr)
6576{
6577 IRTemp op1 = newTemp(Ity_I64);
6578 IRTemp op2 = newTemp(Ity_I64);
6579 IRTemp result = newTemp(Ity_I64);
6580
6581 assign(op1, get_gpr_dw0(r1));
6582 assign(op2, load(Ity_I64, mkexpr(op2addr)));
6583 assign(result, binop(Iop_Or64, mkexpr(op1), mkexpr(op2)));
6584 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6585 put_gpr_dw0(r1, mkexpr(result));
6586
6587 return "og";
6588}
6589
6590static HChar *
6591s390_irgen_OI(UChar i2, IRTemp op1addr)
6592{
6593 IRTemp op1 = newTemp(Ity_I8);
6594 UChar op2;
6595 IRTemp result = newTemp(Ity_I8);
6596
6597 assign(op1, load(Ity_I8, mkexpr(op1addr)));
6598 op2 = i2;
6599 assign(result, binop(Iop_Or8, mkexpr(op1), mkU8(op2)));
6600 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6601 store(mkexpr(op1addr), mkexpr(result));
6602
6603 return "oi";
6604}
6605
6606static HChar *
6607s390_irgen_OIY(UChar i2, IRTemp op1addr)
6608{
6609 IRTemp op1 = newTemp(Ity_I8);
6610 UChar op2;
6611 IRTemp result = newTemp(Ity_I8);
6612
6613 assign(op1, load(Ity_I8, mkexpr(op1addr)));
6614 op2 = i2;
6615 assign(result, binop(Iop_Or8, mkexpr(op1), mkU8(op2)));
6616 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6617 store(mkexpr(op1addr), mkexpr(result));
6618
6619 return "oiy";
6620}
6621
6622static HChar *
6623s390_irgen_OIHF(UChar r1, UInt i2)
6624{
6625 IRTemp op1 = newTemp(Ity_I32);
6626 UInt op2;
6627 IRTemp result = newTemp(Ity_I32);
6628
6629 assign(op1, get_gpr_w0(r1));
6630 op2 = i2;
6631 assign(result, binop(Iop_Or32, mkexpr(op1), mkU32(op2)));
6632 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6633 put_gpr_w0(r1, mkexpr(result));
6634
6635 return "oihf";
6636}
6637
6638static HChar *
6639s390_irgen_OIHH(UChar r1, UShort i2)
6640{
6641 IRTemp op1 = newTemp(Ity_I16);
6642 UShort op2;
6643 IRTemp result = newTemp(Ity_I16);
6644
6645 assign(op1, get_gpr_hw0(r1));
6646 op2 = i2;
6647 assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
6648 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6649 put_gpr_hw0(r1, mkexpr(result));
6650
6651 return "oihh";
6652}
6653
6654static HChar *
6655s390_irgen_OIHL(UChar r1, UShort i2)
6656{
6657 IRTemp op1 = newTemp(Ity_I16);
6658 UShort op2;
6659 IRTemp result = newTemp(Ity_I16);
6660
6661 assign(op1, get_gpr_hw1(r1));
6662 op2 = i2;
6663 assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
6664 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6665 put_gpr_hw1(r1, mkexpr(result));
6666
6667 return "oihl";
6668}
6669
6670static HChar *
6671s390_irgen_OILF(UChar r1, UInt i2)
6672{
6673 IRTemp op1 = newTemp(Ity_I32);
6674 UInt op2;
6675 IRTemp result = newTemp(Ity_I32);
6676
6677 assign(op1, get_gpr_w1(r1));
6678 op2 = i2;
6679 assign(result, binop(Iop_Or32, mkexpr(op1), mkU32(op2)));
6680 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6681 put_gpr_w1(r1, mkexpr(result));
6682
6683 return "oilf";
6684}
6685
6686static HChar *
6687s390_irgen_OILH(UChar r1, UShort i2)
6688{
6689 IRTemp op1 = newTemp(Ity_I16);
6690 UShort op2;
6691 IRTemp result = newTemp(Ity_I16);
6692
6693 assign(op1, get_gpr_hw2(r1));
6694 op2 = i2;
6695 assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
6696 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6697 put_gpr_hw2(r1, mkexpr(result));
6698
6699 return "oilh";
6700}
6701
6702static HChar *
6703s390_irgen_OILL(UChar r1, UShort i2)
6704{
6705 IRTemp op1 = newTemp(Ity_I16);
6706 UShort op2;
6707 IRTemp result = newTemp(Ity_I16);
6708
6709 assign(op1, get_gpr_hw3(r1));
6710 op2 = i2;
6711 assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
6712 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6713 put_gpr_hw3(r1, mkexpr(result));
6714
6715 return "oill";
6716}
6717
6718static HChar *
6719s390_irgen_PFD(void)
6720{
6721
6722 return "pfd";
6723}
6724
6725static HChar *
6726s390_irgen_PFDRL(void)
6727{
6728
6729 return "pfdrl";
6730}
6731
6732static HChar *
6733s390_irgen_RLL(UChar r1, UChar r3, IRTemp op2addr)
6734{
6735 IRTemp amount = newTemp(Ity_I64);
6736 IRTemp op = newTemp(Ity_I32);
6737
6738 assign(amount, binop(Iop_And64, mkexpr(op2addr), mkU64(31)));
6739 assign(op, get_gpr_w1(r3));
6740 put_gpr_w1(r1, binop(Iop_Or32, binop(Iop_Shl32, mkexpr(op), unop(Iop_64to8,
6741 mkexpr(amount))), binop(Iop_Shr32, mkexpr(op), unop(Iop_64to8,
6742 binop(Iop_Sub64, mkU64(32), mkexpr(amount))))));
6743
6744 return "rll";
6745}
6746
6747static HChar *
6748s390_irgen_RLLG(UChar r1, UChar r3, IRTemp op2addr)
6749{
6750 IRTemp amount = newTemp(Ity_I64);
6751 IRTemp op = newTemp(Ity_I64);
6752
6753 assign(amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
6754 assign(op, get_gpr_dw0(r3));
6755 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(op), unop(Iop_64to8,
6756 mkexpr(amount))), binop(Iop_Shr64, mkexpr(op), unop(Iop_64to8,
6757 binop(Iop_Sub64, mkU64(64), mkexpr(amount))))));
6758
6759 return "rllg";
6760}
6761
6762static HChar *
6763s390_irgen_RNSBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
6764{
6765 UChar from;
6766 UChar to;
6767 UChar rot;
6768 UChar t_bit;
6769 ULong mask;
6770 ULong maskc;
6771 IRTemp result = newTemp(Ity_I64);
6772 IRTemp op2 = newTemp(Ity_I64);
6773
6774 from = i3 & 63;
6775 to = i4 & 63;
6776 rot = i5 & 63;
6777 t_bit = i3 & 128;
6778 assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
6779 get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
6780 mkU8(64 - rot))));
6781 if (from <= to) {
6782 mask = ~0ULL;
6783 mask = (mask >> from) & (mask << (63 - to));
6784 maskc = ~mask;
6785 } else {
6786 maskc = ~0ULL;
6787 maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
6788 mask = ~maskc;
6789 }
6790 assign(result, binop(Iop_And64, binop(Iop_And64, get_gpr_dw0(r1), mkexpr(op2)
6791 ), mkU64(mask)));
6792 if (t_bit == 0) {
6793 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
6794 mkU64(maskc)), mkexpr(result)));
6795 }
6796 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6797
6798 return "rnsbg";
6799}
6800
6801static HChar *
6802s390_irgen_RXSBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
6803{
6804 UChar from;
6805 UChar to;
6806 UChar rot;
6807 UChar t_bit;
6808 ULong mask;
6809 ULong maskc;
6810 IRTemp result = newTemp(Ity_I64);
6811 IRTemp op2 = newTemp(Ity_I64);
6812
6813 from = i3 & 63;
6814 to = i4 & 63;
6815 rot = i5 & 63;
6816 t_bit = i3 & 128;
6817 assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
6818 get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
6819 mkU8(64 - rot))));
6820 if (from <= to) {
6821 mask = ~0ULL;
6822 mask = (mask >> from) & (mask << (63 - to));
6823 maskc = ~mask;
6824 } else {
6825 maskc = ~0ULL;
6826 maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
6827 mask = ~maskc;
6828 }
6829 assign(result, binop(Iop_And64, binop(Iop_Xor64, get_gpr_dw0(r1), mkexpr(op2)
6830 ), mkU64(mask)));
6831 if (t_bit == 0) {
6832 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
6833 mkU64(maskc)), mkexpr(result)));
6834 }
6835 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6836
6837 return "rxsbg";
6838}
6839
6840static HChar *
6841s390_irgen_ROSBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
6842{
6843 UChar from;
6844 UChar to;
6845 UChar rot;
6846 UChar t_bit;
6847 ULong mask;
6848 ULong maskc;
6849 IRTemp result = newTemp(Ity_I64);
6850 IRTemp op2 = newTemp(Ity_I64);
6851
6852 from = i3 & 63;
6853 to = i4 & 63;
6854 rot = i5 & 63;
6855 t_bit = i3 & 128;
6856 assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
6857 get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
6858 mkU8(64 - rot))));
6859 if (from <= to) {
6860 mask = ~0ULL;
6861 mask = (mask >> from) & (mask << (63 - to));
6862 maskc = ~mask;
6863 } else {
6864 maskc = ~0ULL;
6865 maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
6866 mask = ~maskc;
6867 }
6868 assign(result, binop(Iop_And64, binop(Iop_Or64, get_gpr_dw0(r1), mkexpr(op2)
6869 ), mkU64(mask)));
6870 if (t_bit == 0) {
6871 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
6872 mkU64(maskc)), mkexpr(result)));
6873 }
6874 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6875
6876 return "rosbg";
6877}
6878
6879static HChar *
6880s390_irgen_RISBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
6881{
6882 UChar from;
6883 UChar to;
6884 UChar rot;
6885 UChar z_bit;
6886 ULong mask;
6887 ULong maskc;
6888 IRTemp op2 = newTemp(Ity_I64);
6889 IRTemp result = newTemp(Ity_I64);
6890
6891 from = i3 & 63;
6892 to = i4 & 63;
6893 rot = i5 & 63;
6894 z_bit = i4 & 128;
6895 assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
6896 get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
6897 mkU8(64 - rot))));
6898 if (from <= to) {
6899 mask = ~0ULL;
6900 mask = (mask >> from) & (mask << (63 - to));
6901 maskc = ~mask;
6902 } else {
6903 maskc = ~0ULL;
6904 maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
6905 mask = ~maskc;
6906 }
6907 if (z_bit == 0) {
6908 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
6909 mkU64(maskc)), binop(Iop_And64, mkexpr(op2), mkU64(mask))));
6910 } else {
6911 put_gpr_dw0(r1, binop(Iop_And64, mkexpr(op2), mkU64(mask)));
6912 }
6913 assign(result, get_gpr_dw0(r1));
6914 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
6915
6916 return "risbg";
6917}
6918
6919static HChar *
6920s390_irgen_SAR(UChar r1, UChar r2)
6921{
6922 put_ar_w0(r1, get_gpr_w1(r2));
sewardj7ee97522011-05-09 21:45:04 +00006923 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00006924 s390_disasm(ENC3(MNM, AR, GPR), "sar", r1, r2);
6925
6926 return "sar";
6927}
6928
6929static HChar *
6930s390_irgen_SLDA(UChar r1, IRTemp op2addr)
6931{
6932 IRTemp p1 = newTemp(Ity_I64);
6933 IRTemp p2 = newTemp(Ity_I64);
6934 IRTemp op = newTemp(Ity_I64);
6935 IRTemp result = newTemp(Ity_I64);
florian417b22d2012-07-13 13:41:41 +00006936 ULong sign_mask;
sewardj2019a972011-03-07 16:04:07 +00006937 IRTemp shift_amount = newTemp(Ity_I64);
6938
6939 assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
6940 assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
6941 assign(op, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1), mkU8(32)), mkexpr(p2)
6942 ));
6943 sign_mask = 1ULL << 63;
6944 assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
6945 assign(result, binop(Iop_Or64, binop(Iop_And64, binop(Iop_Shl64, mkexpr(op),
florian417b22d2012-07-13 13:41:41 +00006946 unop(Iop_64to8, mkexpr(shift_amount))), mkU64(~sign_mask)),
6947 binop(Iop_And64, mkexpr(op), mkU64(sign_mask))));
sewardj2019a972011-03-07 16:04:07 +00006948 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6949 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6950 s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_64, op, shift_amount);
6951
6952 return "slda";
6953}
6954
6955static HChar *
6956s390_irgen_SLDL(UChar r1, IRTemp op2addr)
6957{
6958 IRTemp p1 = newTemp(Ity_I64);
6959 IRTemp p2 = newTemp(Ity_I64);
6960 IRTemp result = newTemp(Ity_I64);
6961
6962 assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
6963 assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
6964 assign(result, binop(Iop_Shl64, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1),
6965 mkU8(32)), mkexpr(p2)), unop(Iop_64to8, binop(Iop_And64,
6966 mkexpr(op2addr), mkU64(63)))));
6967 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6968 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6969
6970 return "sldl";
6971}
6972
6973static HChar *
6974s390_irgen_SLA(UChar r1, IRTemp op2addr)
6975{
6976 IRTemp uop = newTemp(Ity_I32);
6977 IRTemp result = newTemp(Ity_I32);
6978 UInt sign_mask;
6979 IRTemp shift_amount = newTemp(Ity_I64);
6980 IRTemp op = newTemp(Ity_I32);
6981
6982 assign(op, get_gpr_w1(r1));
6983 assign(uop, get_gpr_w1(r1));
6984 sign_mask = 2147483648U;
6985 assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
6986 assign(result, binop(Iop_Or32, binop(Iop_And32, binop(Iop_Shl32, mkexpr(uop),
6987 unop(Iop_64to8, mkexpr(shift_amount))), mkU32(~sign_mask)),
6988 binop(Iop_And32, mkexpr(uop), mkU32(sign_mask))));
6989 put_gpr_w1(r1, mkexpr(result));
6990 s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_32, op, shift_amount);
6991
6992 return "sla";
6993}
6994
6995static HChar *
6996s390_irgen_SLAK(UChar r1, UChar r3, IRTemp op2addr)
6997{
6998 IRTemp uop = newTemp(Ity_I32);
6999 IRTemp result = newTemp(Ity_I32);
7000 UInt sign_mask;
7001 IRTemp shift_amount = newTemp(Ity_I64);
7002 IRTemp op = newTemp(Ity_I32);
7003
7004 assign(op, get_gpr_w1(r3));
7005 assign(uop, get_gpr_w1(r3));
7006 sign_mask = 2147483648U;
7007 assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7008 assign(result, binop(Iop_Or32, binop(Iop_And32, binop(Iop_Shl32, mkexpr(uop),
7009 unop(Iop_64to8, mkexpr(shift_amount))), mkU32(~sign_mask)),
7010 binop(Iop_And32, mkexpr(uop), mkU32(sign_mask))));
7011 put_gpr_w1(r1, mkexpr(result));
7012 s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_32, op, shift_amount);
7013
7014 return "slak";
7015}
7016
7017static HChar *
7018s390_irgen_SLAG(UChar r1, UChar r3, IRTemp op2addr)
7019{
7020 IRTemp uop = newTemp(Ity_I64);
7021 IRTemp result = newTemp(Ity_I64);
7022 ULong sign_mask;
7023 IRTemp shift_amount = newTemp(Ity_I64);
7024 IRTemp op = newTemp(Ity_I64);
7025
7026 assign(op, get_gpr_dw0(r3));
7027 assign(uop, get_gpr_dw0(r3));
7028 sign_mask = 9223372036854775808ULL;
7029 assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7030 assign(result, binop(Iop_Or64, binop(Iop_And64, binop(Iop_Shl64, mkexpr(uop),
7031 unop(Iop_64to8, mkexpr(shift_amount))), mkU64(~sign_mask)),
7032 binop(Iop_And64, mkexpr(uop), mkU64(sign_mask))));
7033 put_gpr_dw0(r1, mkexpr(result));
7034 s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_64, op, shift_amount);
7035
7036 return "slag";
7037}
7038
7039static HChar *
7040s390_irgen_SLL(UChar r1, IRTemp op2addr)
7041{
7042 put_gpr_w1(r1, binop(Iop_Shl32, get_gpr_w1(r1), unop(Iop_64to8,
7043 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
7044
7045 return "sll";
7046}
7047
7048static HChar *
7049s390_irgen_SLLK(UChar r1, UChar r3, IRTemp op2addr)
7050{
7051 put_gpr_w1(r1, binop(Iop_Shl32, get_gpr_w1(r3), unop(Iop_64to8,
7052 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
7053
7054 return "sllk";
7055}
7056
7057static HChar *
7058s390_irgen_SLLG(UChar r1, UChar r3, IRTemp op2addr)
7059{
7060 put_gpr_dw0(r1, binop(Iop_Shl64, get_gpr_dw0(r3), unop(Iop_64to8,
7061 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
7062
7063 return "sllg";
7064}
7065
7066static HChar *
7067s390_irgen_SRDA(UChar r1, IRTemp op2addr)
7068{
7069 IRTemp p1 = newTemp(Ity_I64);
7070 IRTemp p2 = newTemp(Ity_I64);
7071 IRTemp result = newTemp(Ity_I64);
7072
7073 assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
7074 assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
7075 assign(result, binop(Iop_Sar64, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1),
7076 mkU8(32)), mkexpr(p2)), unop(Iop_64to8, binop(Iop_And64,
7077 mkexpr(op2addr), mkU64(63)))));
7078 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
7079 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
7080 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7081
7082 return "srda";
7083}
7084
7085static HChar *
7086s390_irgen_SRDL(UChar r1, IRTemp op2addr)
7087{
7088 IRTemp p1 = newTemp(Ity_I64);
7089 IRTemp p2 = newTemp(Ity_I64);
7090 IRTemp result = newTemp(Ity_I64);
7091
7092 assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
7093 assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
7094 assign(result, binop(Iop_Shr64, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1),
7095 mkU8(32)), mkexpr(p2)), unop(Iop_64to8, binop(Iop_And64,
7096 mkexpr(op2addr), mkU64(63)))));
7097 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
7098 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
7099
7100 return "srdl";
7101}
7102
7103static HChar *
7104s390_irgen_SRA(UChar r1, IRTemp op2addr)
7105{
7106 IRTemp result = newTemp(Ity_I32);
7107 IRTemp op = newTemp(Ity_I32);
7108
7109 assign(op, get_gpr_w1(r1));
7110 assign(result, binop(Iop_Sar32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7111 mkexpr(op2addr), mkU64(63)))));
7112 put_gpr_w1(r1, mkexpr(result));
7113 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7114
7115 return "sra";
7116}
7117
7118static HChar *
7119s390_irgen_SRAK(UChar r1, UChar r3, IRTemp op2addr)
7120{
7121 IRTemp result = newTemp(Ity_I32);
7122 IRTemp op = newTemp(Ity_I32);
7123
7124 assign(op, get_gpr_w1(r3));
7125 assign(result, binop(Iop_Sar32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7126 mkexpr(op2addr), mkU64(63)))));
7127 put_gpr_w1(r1, mkexpr(result));
7128 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7129
7130 return "srak";
7131}
7132
7133static HChar *
7134s390_irgen_SRAG(UChar r1, UChar r3, IRTemp op2addr)
7135{
7136 IRTemp result = newTemp(Ity_I64);
7137 IRTemp op = newTemp(Ity_I64);
7138
7139 assign(op, get_gpr_dw0(r3));
7140 assign(result, binop(Iop_Sar64, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7141 mkexpr(op2addr), mkU64(63)))));
7142 put_gpr_dw0(r1, mkexpr(result));
7143 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7144
7145 return "srag";
7146}
7147
7148static HChar *
7149s390_irgen_SRL(UChar r1, IRTemp op2addr)
7150{
7151 IRTemp op = newTemp(Ity_I32);
7152
7153 assign(op, get_gpr_w1(r1));
7154 put_gpr_w1(r1, binop(Iop_Shr32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7155 mkexpr(op2addr), mkU64(63)))));
7156
7157 return "srl";
7158}
7159
7160static HChar *
7161s390_irgen_SRLK(UChar r1, UChar r3, IRTemp op2addr)
7162{
7163 IRTemp op = newTemp(Ity_I32);
7164
7165 assign(op, get_gpr_w1(r3));
7166 put_gpr_w1(r1, binop(Iop_Shr32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7167 mkexpr(op2addr), mkU64(63)))));
7168
7169 return "srlk";
7170}
7171
7172static HChar *
7173s390_irgen_SRLG(UChar r1, UChar r3, IRTemp op2addr)
7174{
7175 IRTemp op = newTemp(Ity_I64);
7176
7177 assign(op, get_gpr_dw0(r3));
7178 put_gpr_dw0(r1, binop(Iop_Shr64, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7179 mkexpr(op2addr), mkU64(63)))));
7180
7181 return "srlg";
7182}
7183
7184static HChar *
7185s390_irgen_ST(UChar r1, IRTemp op2addr)
7186{
7187 store(mkexpr(op2addr), get_gpr_w1(r1));
7188
7189 return "st";
7190}
7191
7192static HChar *
7193s390_irgen_STY(UChar r1, IRTemp op2addr)
7194{
7195 store(mkexpr(op2addr), get_gpr_w1(r1));
7196
7197 return "sty";
7198}
7199
7200static HChar *
7201s390_irgen_STG(UChar r1, IRTemp op2addr)
7202{
7203 store(mkexpr(op2addr), get_gpr_dw0(r1));
7204
7205 return "stg";
7206}
7207
7208static HChar *
7209s390_irgen_STRL(UChar r1, UInt i2)
7210{
7211 store(mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)),
7212 get_gpr_w1(r1));
7213
7214 return "strl";
7215}
7216
7217static HChar *
7218s390_irgen_STGRL(UChar r1, UInt i2)
7219{
7220 store(mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)),
7221 get_gpr_dw0(r1));
7222
7223 return "stgrl";
7224}
7225
7226static HChar *
7227s390_irgen_STC(UChar r1, IRTemp op2addr)
7228{
7229 store(mkexpr(op2addr), get_gpr_b7(r1));
7230
7231 return "stc";
7232}
7233
7234static HChar *
7235s390_irgen_STCY(UChar r1, IRTemp op2addr)
7236{
7237 store(mkexpr(op2addr), get_gpr_b7(r1));
7238
7239 return "stcy";
7240}
7241
7242static HChar *
7243s390_irgen_STCH(UChar r1, IRTemp op2addr)
7244{
7245 store(mkexpr(op2addr), get_gpr_b3(r1));
7246
7247 return "stch";
7248}
7249
7250static HChar *
7251s390_irgen_STCM(UChar r1, UChar r3, IRTemp op2addr)
7252{
7253 UChar mask;
7254 UChar n;
7255
7256 mask = (UChar)r3;
7257 n = 0;
7258 if ((mask & 8) != 0) {
7259 store(mkexpr(op2addr), get_gpr_b4(r1));
7260 n = n + 1;
7261 }
7262 if ((mask & 4) != 0) {
7263 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b5(r1));
7264 n = n + 1;
7265 }
7266 if ((mask & 2) != 0) {
7267 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b6(r1));
7268 n = n + 1;
7269 }
7270 if ((mask & 1) != 0) {
7271 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b7(r1));
7272 }
7273
7274 return "stcm";
7275}
7276
7277static HChar *
7278s390_irgen_STCMY(UChar r1, UChar r3, IRTemp op2addr)
7279{
7280 UChar mask;
7281 UChar n;
7282
7283 mask = (UChar)r3;
7284 n = 0;
7285 if ((mask & 8) != 0) {
7286 store(mkexpr(op2addr), get_gpr_b4(r1));
7287 n = n + 1;
7288 }
7289 if ((mask & 4) != 0) {
7290 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b5(r1));
7291 n = n + 1;
7292 }
7293 if ((mask & 2) != 0) {
7294 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b6(r1));
7295 n = n + 1;
7296 }
7297 if ((mask & 1) != 0) {
7298 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b7(r1));
7299 }
7300
7301 return "stcmy";
7302}
7303
7304static HChar *
7305s390_irgen_STCMH(UChar r1, UChar r3, IRTemp op2addr)
7306{
7307 UChar mask;
7308 UChar n;
7309
7310 mask = (UChar)r3;
7311 n = 0;
7312 if ((mask & 8) != 0) {
7313 store(mkexpr(op2addr), get_gpr_b0(r1));
7314 n = n + 1;
7315 }
7316 if ((mask & 4) != 0) {
7317 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b1(r1));
7318 n = n + 1;
7319 }
7320 if ((mask & 2) != 0) {
7321 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b2(r1));
7322 n = n + 1;
7323 }
7324 if ((mask & 1) != 0) {
7325 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b3(r1));
7326 }
7327
7328 return "stcmh";
7329}
7330
7331static HChar *
7332s390_irgen_STH(UChar r1, IRTemp op2addr)
7333{
7334 store(mkexpr(op2addr), get_gpr_hw3(r1));
7335
7336 return "sth";
7337}
7338
7339static HChar *
7340s390_irgen_STHY(UChar r1, IRTemp op2addr)
7341{
7342 store(mkexpr(op2addr), get_gpr_hw3(r1));
7343
7344 return "sthy";
7345}
7346
7347static HChar *
7348s390_irgen_STHRL(UChar r1, UInt i2)
7349{
7350 store(mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)),
7351 get_gpr_hw3(r1));
7352
7353 return "sthrl";
7354}
7355
7356static HChar *
7357s390_irgen_STHH(UChar r1, IRTemp op2addr)
7358{
7359 store(mkexpr(op2addr), get_gpr_hw1(r1));
7360
7361 return "sthh";
7362}
7363
7364static HChar *
7365s390_irgen_STFH(UChar r1, IRTemp op2addr)
7366{
7367 store(mkexpr(op2addr), get_gpr_w0(r1));
7368
7369 return "stfh";
7370}
7371
7372static HChar *
sewardjd7bde722011-04-05 13:19:33 +00007373s390_irgen_STOC(UChar r1, IRTemp op2addr)
7374{
7375 /* condition is checked in format handler */
7376 store(mkexpr(op2addr), get_gpr_w1(r1));
7377
7378 return "stoc";
7379}
7380
7381static HChar *
7382s390_irgen_STOCG(UChar r1, IRTemp op2addr)
7383{
7384 /* condition is checked in format handler */
7385 store(mkexpr(op2addr), get_gpr_dw0(r1));
7386
7387 return "stocg";
7388}
7389
7390static HChar *
sewardj2019a972011-03-07 16:04:07 +00007391s390_irgen_STPQ(UChar r1, IRTemp op2addr)
7392{
7393 store(mkexpr(op2addr), get_gpr_dw0(r1));
7394 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(8)), get_gpr_dw0(r1 + 1));
7395
7396 return "stpq";
7397}
7398
7399static HChar *
7400s390_irgen_STRVH(UChar r1, IRTemp op2addr)
7401{
7402 store(mkexpr(op2addr), get_gpr_b7(r1));
7403 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(1)), get_gpr_b6(r1));
7404
7405 return "strvh";
7406}
7407
7408static HChar *
7409s390_irgen_STRV(UChar r1, IRTemp op2addr)
7410{
7411 store(mkexpr(op2addr), get_gpr_b7(r1));
7412 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(1)), get_gpr_b6(r1));
7413 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(2)), get_gpr_b5(r1));
7414 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(3)), get_gpr_b4(r1));
7415
7416 return "strv";
7417}
7418
7419static HChar *
7420s390_irgen_STRVG(UChar r1, IRTemp op2addr)
7421{
7422 store(mkexpr(op2addr), get_gpr_b7(r1));
7423 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(1)), get_gpr_b6(r1));
7424 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(2)), get_gpr_b5(r1));
7425 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(3)), get_gpr_b4(r1));
7426 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(4)), get_gpr_b3(r1));
7427 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(5)), get_gpr_b2(r1));
7428 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(6)), get_gpr_b1(r1));
7429 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(7)), get_gpr_b0(r1));
7430
7431 return "strvg";
7432}
7433
7434static HChar *
7435s390_irgen_SR(UChar r1, UChar r2)
7436{
7437 IRTemp op1 = newTemp(Ity_I32);
7438 IRTemp op2 = newTemp(Ity_I32);
7439 IRTemp result = newTemp(Ity_I32);
7440
7441 assign(op1, get_gpr_w1(r1));
7442 assign(op2, get_gpr_w1(r2));
7443 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7444 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
7445 put_gpr_w1(r1, mkexpr(result));
7446
7447 return "sr";
7448}
7449
7450static HChar *
7451s390_irgen_SGR(UChar r1, UChar r2)
7452{
7453 IRTemp op1 = newTemp(Ity_I64);
7454 IRTemp op2 = newTemp(Ity_I64);
7455 IRTemp result = newTemp(Ity_I64);
7456
7457 assign(op1, get_gpr_dw0(r1));
7458 assign(op2, get_gpr_dw0(r2));
7459 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7460 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
7461 put_gpr_dw0(r1, mkexpr(result));
7462
7463 return "sgr";
7464}
7465
7466static HChar *
7467s390_irgen_SGFR(UChar r1, UChar r2)
7468{
7469 IRTemp op1 = newTemp(Ity_I64);
7470 IRTemp op2 = newTemp(Ity_I64);
7471 IRTemp result = newTemp(Ity_I64);
7472
7473 assign(op1, get_gpr_dw0(r1));
7474 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
7475 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7476 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
7477 put_gpr_dw0(r1, mkexpr(result));
7478
7479 return "sgfr";
7480}
7481
7482static HChar *
7483s390_irgen_SRK(UChar r3, UChar r1, UChar r2)
7484{
7485 IRTemp op2 = newTemp(Ity_I32);
7486 IRTemp op3 = newTemp(Ity_I32);
7487 IRTemp result = newTemp(Ity_I32);
7488
7489 assign(op2, get_gpr_w1(r2));
7490 assign(op3, get_gpr_w1(r3));
7491 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
7492 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op2, op3);
7493 put_gpr_w1(r1, mkexpr(result));
7494
7495 return "srk";
7496}
7497
7498static HChar *
7499s390_irgen_SGRK(UChar r3, UChar r1, UChar r2)
7500{
7501 IRTemp op2 = newTemp(Ity_I64);
7502 IRTemp op3 = newTemp(Ity_I64);
7503 IRTemp result = newTemp(Ity_I64);
7504
7505 assign(op2, get_gpr_dw0(r2));
7506 assign(op3, get_gpr_dw0(r3));
7507 assign(result, binop(Iop_Sub64, mkexpr(op2), mkexpr(op3)));
7508 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op2, op3);
7509 put_gpr_dw0(r1, mkexpr(result));
7510
7511 return "sgrk";
7512}
7513
7514static HChar *
7515s390_irgen_S(UChar r1, IRTemp op2addr)
7516{
7517 IRTemp op1 = newTemp(Ity_I32);
7518 IRTemp op2 = newTemp(Ity_I32);
7519 IRTemp result = newTemp(Ity_I32);
7520
7521 assign(op1, get_gpr_w1(r1));
7522 assign(op2, load(Ity_I32, mkexpr(op2addr)));
7523 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7524 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
7525 put_gpr_w1(r1, mkexpr(result));
7526
7527 return "s";
7528}
7529
7530static HChar *
7531s390_irgen_SY(UChar r1, IRTemp op2addr)
7532{
7533 IRTemp op1 = newTemp(Ity_I32);
7534 IRTemp op2 = newTemp(Ity_I32);
7535 IRTemp result = newTemp(Ity_I32);
7536
7537 assign(op1, get_gpr_w1(r1));
7538 assign(op2, load(Ity_I32, mkexpr(op2addr)));
7539 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7540 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
7541 put_gpr_w1(r1, mkexpr(result));
7542
7543 return "sy";
7544}
7545
7546static HChar *
7547s390_irgen_SG(UChar r1, IRTemp op2addr)
7548{
7549 IRTemp op1 = newTemp(Ity_I64);
7550 IRTemp op2 = newTemp(Ity_I64);
7551 IRTemp result = newTemp(Ity_I64);
7552
7553 assign(op1, get_gpr_dw0(r1));
7554 assign(op2, load(Ity_I64, mkexpr(op2addr)));
7555 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7556 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
7557 put_gpr_dw0(r1, mkexpr(result));
7558
7559 return "sg";
7560}
7561
7562static HChar *
7563s390_irgen_SGF(UChar r1, IRTemp op2addr)
7564{
7565 IRTemp op1 = newTemp(Ity_I64);
7566 IRTemp op2 = newTemp(Ity_I64);
7567 IRTemp result = newTemp(Ity_I64);
7568
7569 assign(op1, get_gpr_dw0(r1));
7570 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
7571 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7572 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
7573 put_gpr_dw0(r1, mkexpr(result));
7574
7575 return "sgf";
7576}
7577
7578static HChar *
7579s390_irgen_SH(UChar r1, IRTemp op2addr)
7580{
7581 IRTemp op1 = newTemp(Ity_I32);
7582 IRTemp op2 = newTemp(Ity_I32);
7583 IRTemp result = newTemp(Ity_I32);
7584
7585 assign(op1, get_gpr_w1(r1));
7586 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
7587 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7588 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
7589 put_gpr_w1(r1, mkexpr(result));
7590
7591 return "sh";
7592}
7593
7594static HChar *
7595s390_irgen_SHY(UChar r1, IRTemp op2addr)
7596{
7597 IRTemp op1 = newTemp(Ity_I32);
7598 IRTemp op2 = newTemp(Ity_I32);
7599 IRTemp result = newTemp(Ity_I32);
7600
7601 assign(op1, get_gpr_w1(r1));
7602 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
7603 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7604 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
7605 put_gpr_w1(r1, mkexpr(result));
7606
7607 return "shy";
7608}
7609
7610static HChar *
7611s390_irgen_SHHHR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
7612{
7613 IRTemp op2 = newTemp(Ity_I32);
7614 IRTemp op3 = newTemp(Ity_I32);
7615 IRTemp result = newTemp(Ity_I32);
7616
7617 assign(op2, get_gpr_w0(r1));
7618 assign(op3, get_gpr_w0(r2));
7619 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
7620 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op2, op3);
7621 put_gpr_w0(r1, mkexpr(result));
7622
7623 return "shhhr";
7624}
7625
7626static HChar *
7627s390_irgen_SHHLR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
7628{
7629 IRTemp op2 = newTemp(Ity_I32);
7630 IRTemp op3 = newTemp(Ity_I32);
7631 IRTemp result = newTemp(Ity_I32);
7632
7633 assign(op2, get_gpr_w0(r1));
7634 assign(op3, get_gpr_w1(r2));
7635 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
7636 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op2, op3);
7637 put_gpr_w0(r1, mkexpr(result));
7638
7639 return "shhlr";
7640}
7641
7642static HChar *
7643s390_irgen_SLR(UChar r1, UChar r2)
7644{
7645 IRTemp op1 = newTemp(Ity_I32);
7646 IRTemp op2 = newTemp(Ity_I32);
7647 IRTemp result = newTemp(Ity_I32);
7648
7649 assign(op1, get_gpr_w1(r1));
7650 assign(op2, get_gpr_w1(r2));
7651 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7652 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, op2);
7653 put_gpr_w1(r1, mkexpr(result));
7654
7655 return "slr";
7656}
7657
7658static HChar *
7659s390_irgen_SLGR(UChar r1, UChar r2)
7660{
7661 IRTemp op1 = newTemp(Ity_I64);
7662 IRTemp op2 = newTemp(Ity_I64);
7663 IRTemp result = newTemp(Ity_I64);
7664
7665 assign(op1, get_gpr_dw0(r1));
7666 assign(op2, get_gpr_dw0(r2));
7667 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7668 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
7669 put_gpr_dw0(r1, mkexpr(result));
7670
7671 return "slgr";
7672}
7673
7674static HChar *
7675s390_irgen_SLGFR(UChar r1, UChar r2)
7676{
7677 IRTemp op1 = newTemp(Ity_I64);
7678 IRTemp op2 = newTemp(Ity_I64);
7679 IRTemp result = newTemp(Ity_I64);
7680
7681 assign(op1, get_gpr_dw0(r1));
7682 assign(op2, unop(Iop_32Uto64, get_gpr_w1(r2)));
7683 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7684 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
7685 put_gpr_dw0(r1, mkexpr(result));
7686
7687 return "slgfr";
7688}
7689
7690static HChar *
7691s390_irgen_SLRK(UChar r3, UChar r1, UChar r2)
7692{
7693 IRTemp op2 = newTemp(Ity_I32);
7694 IRTemp op3 = newTemp(Ity_I32);
7695 IRTemp result = newTemp(Ity_I32);
7696
7697 assign(op2, get_gpr_w1(r2));
7698 assign(op3, get_gpr_w1(r3));
7699 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
7700 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op2, op3);
7701 put_gpr_w1(r1, mkexpr(result));
7702
7703 return "slrk";
7704}
7705
7706static HChar *
7707s390_irgen_SLGRK(UChar r3, UChar r1, UChar r2)
7708{
7709 IRTemp op2 = newTemp(Ity_I64);
7710 IRTemp op3 = newTemp(Ity_I64);
7711 IRTemp result = newTemp(Ity_I64);
7712
7713 assign(op2, get_gpr_dw0(r2));
7714 assign(op3, get_gpr_dw0(r3));
7715 assign(result, binop(Iop_Sub64, mkexpr(op2), mkexpr(op3)));
7716 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op2, op3);
7717 put_gpr_dw0(r1, mkexpr(result));
7718
7719 return "slgrk";
7720}
7721
7722static HChar *
7723s390_irgen_SL(UChar r1, IRTemp op2addr)
7724{
7725 IRTemp op1 = newTemp(Ity_I32);
7726 IRTemp op2 = newTemp(Ity_I32);
7727 IRTemp result = newTemp(Ity_I32);
7728
7729 assign(op1, get_gpr_w1(r1));
7730 assign(op2, load(Ity_I32, mkexpr(op2addr)));
7731 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7732 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, op2);
7733 put_gpr_w1(r1, mkexpr(result));
7734
7735 return "sl";
7736}
7737
7738static HChar *
7739s390_irgen_SLY(UChar r1, IRTemp op2addr)
7740{
7741 IRTemp op1 = newTemp(Ity_I32);
7742 IRTemp op2 = newTemp(Ity_I32);
7743 IRTemp result = newTemp(Ity_I32);
7744
7745 assign(op1, get_gpr_w1(r1));
7746 assign(op2, load(Ity_I32, mkexpr(op2addr)));
7747 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7748 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, op2);
7749 put_gpr_w1(r1, mkexpr(result));
7750
7751 return "sly";
7752}
7753
7754static HChar *
7755s390_irgen_SLG(UChar r1, IRTemp op2addr)
7756{
7757 IRTemp op1 = newTemp(Ity_I64);
7758 IRTemp op2 = newTemp(Ity_I64);
7759 IRTemp result = newTemp(Ity_I64);
7760
7761 assign(op1, get_gpr_dw0(r1));
7762 assign(op2, load(Ity_I64, mkexpr(op2addr)));
7763 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7764 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
7765 put_gpr_dw0(r1, mkexpr(result));
7766
7767 return "slg";
7768}
7769
7770static HChar *
7771s390_irgen_SLGF(UChar r1, IRTemp op2addr)
7772{
7773 IRTemp op1 = newTemp(Ity_I64);
7774 IRTemp op2 = newTemp(Ity_I64);
7775 IRTemp result = newTemp(Ity_I64);
7776
7777 assign(op1, get_gpr_dw0(r1));
7778 assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
7779 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7780 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
7781 put_gpr_dw0(r1, mkexpr(result));
7782
7783 return "slgf";
7784}
7785
7786static HChar *
7787s390_irgen_SLFI(UChar r1, UInt i2)
7788{
7789 IRTemp op1 = newTemp(Ity_I32);
7790 UInt op2;
7791 IRTemp result = newTemp(Ity_I32);
7792
7793 assign(op1, get_gpr_w1(r1));
7794 op2 = i2;
7795 assign(result, binop(Iop_Sub32, mkexpr(op1), mkU32(op2)));
7796 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, mktemp(Ity_I32,
7797 mkU32(op2)));
7798 put_gpr_w1(r1, mkexpr(result));
7799
7800 return "slfi";
7801}
7802
7803static HChar *
7804s390_irgen_SLGFI(UChar r1, UInt i2)
7805{
7806 IRTemp op1 = newTemp(Ity_I64);
7807 ULong op2;
7808 IRTemp result = newTemp(Ity_I64);
7809
7810 assign(op1, get_gpr_dw0(r1));
7811 op2 = (ULong)i2;
7812 assign(result, binop(Iop_Sub64, mkexpr(op1), mkU64(op2)));
7813 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, mktemp(Ity_I64,
7814 mkU64(op2)));
7815 put_gpr_dw0(r1, mkexpr(result));
7816
7817 return "slgfi";
7818}
7819
7820static HChar *
7821s390_irgen_SLHHHR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
7822{
7823 IRTemp op2 = newTemp(Ity_I32);
7824 IRTemp op3 = newTemp(Ity_I32);
7825 IRTemp result = newTemp(Ity_I32);
7826
7827 assign(op2, get_gpr_w0(r1));
7828 assign(op3, get_gpr_w0(r2));
7829 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
7830 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op2, op3);
7831 put_gpr_w0(r1, mkexpr(result));
7832
7833 return "slhhhr";
7834}
7835
7836static HChar *
7837s390_irgen_SLHHLR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
7838{
7839 IRTemp op2 = newTemp(Ity_I32);
7840 IRTemp op3 = newTemp(Ity_I32);
7841 IRTemp result = newTemp(Ity_I32);
7842
7843 assign(op2, get_gpr_w0(r1));
7844 assign(op3, get_gpr_w1(r2));
7845 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
7846 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op2, op3);
7847 put_gpr_w0(r1, mkexpr(result));
7848
7849 return "slhhlr";
7850}
7851
7852static HChar *
7853s390_irgen_SLBR(UChar r1, UChar r2)
7854{
7855 IRTemp op1 = newTemp(Ity_I32);
7856 IRTemp op2 = newTemp(Ity_I32);
7857 IRTemp result = newTemp(Ity_I32);
7858 IRTemp borrow_in = newTemp(Ity_I32);
7859
7860 assign(op1, get_gpr_w1(r1));
7861 assign(op2, get_gpr_w1(r2));
7862 assign(borrow_in, binop(Iop_Sub32, mkU32(1), binop(Iop_Shr32,
7863 s390_call_calculate_cc(), mkU8(1))));
7864 assign(result, binop(Iop_Sub32, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)),
7865 mkexpr(borrow_in)));
7866 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_32, op1, op2, borrow_in);
7867 put_gpr_w1(r1, mkexpr(result));
7868
7869 return "slbr";
7870}
7871
7872static HChar *
7873s390_irgen_SLBGR(UChar r1, UChar r2)
7874{
7875 IRTemp op1 = newTemp(Ity_I64);
7876 IRTemp op2 = newTemp(Ity_I64);
7877 IRTemp result = newTemp(Ity_I64);
7878 IRTemp borrow_in = newTemp(Ity_I64);
7879
7880 assign(op1, get_gpr_dw0(r1));
7881 assign(op2, get_gpr_dw0(r2));
7882 assign(borrow_in, unop(Iop_32Uto64, binop(Iop_Sub32, mkU32(1),
7883 binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)))));
7884 assign(result, binop(Iop_Sub64, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)),
7885 mkexpr(borrow_in)));
7886 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_64, op1, op2, borrow_in);
7887 put_gpr_dw0(r1, mkexpr(result));
7888
7889 return "slbgr";
7890}
7891
7892static HChar *
7893s390_irgen_SLB(UChar r1, IRTemp op2addr)
7894{
7895 IRTemp op1 = newTemp(Ity_I32);
7896 IRTemp op2 = newTemp(Ity_I32);
7897 IRTemp result = newTemp(Ity_I32);
7898 IRTemp borrow_in = newTemp(Ity_I32);
7899
7900 assign(op1, get_gpr_w1(r1));
7901 assign(op2, load(Ity_I32, mkexpr(op2addr)));
7902 assign(borrow_in, binop(Iop_Sub32, mkU32(1), binop(Iop_Shr32,
7903 s390_call_calculate_cc(), mkU8(1))));
7904 assign(result, binop(Iop_Sub32, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)),
7905 mkexpr(borrow_in)));
7906 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_32, op1, op2, borrow_in);
7907 put_gpr_w1(r1, mkexpr(result));
7908
7909 return "slb";
7910}
7911
7912static HChar *
7913s390_irgen_SLBG(UChar r1, IRTemp op2addr)
7914{
7915 IRTemp op1 = newTemp(Ity_I64);
7916 IRTemp op2 = newTemp(Ity_I64);
7917 IRTemp result = newTemp(Ity_I64);
7918 IRTemp borrow_in = newTemp(Ity_I64);
7919
7920 assign(op1, get_gpr_dw0(r1));
7921 assign(op2, load(Ity_I64, mkexpr(op2addr)));
7922 assign(borrow_in, unop(Iop_32Uto64, binop(Iop_Sub32, mkU32(1),
7923 binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)))));
7924 assign(result, binop(Iop_Sub64, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)),
7925 mkexpr(borrow_in)));
7926 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_64, op1, op2, borrow_in);
7927 put_gpr_dw0(r1, mkexpr(result));
7928
7929 return "slbg";
7930}
7931
7932static HChar *
7933s390_irgen_SVC(UChar i)
7934{
7935 IRTemp sysno = newTemp(Ity_I64);
7936
7937 if (i != 0) {
7938 assign(sysno, mkU64(i));
7939 } else {
7940 assign(sysno, unop(Iop_32Uto64, get_gpr_w1(1)));
7941 }
7942 system_call(mkexpr(sysno));
7943
7944 return "svc";
7945}
7946
7947static HChar *
sewardj2019a972011-03-07 16:04:07 +00007948s390_irgen_TM(UChar i2, IRTemp op1addr)
7949{
7950 UChar mask;
7951 IRTemp value = newTemp(Ity_I8);
7952
7953 mask = i2;
7954 assign(value, load(Ity_I8, mkexpr(op1addr)));
7955 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_8, value, mktemp(Ity_I8,
7956 mkU8(mask)));
7957
7958 return "tm";
7959}
7960
7961static HChar *
7962s390_irgen_TMY(UChar i2, IRTemp op1addr)
7963{
7964 UChar mask;
7965 IRTemp value = newTemp(Ity_I8);
7966
7967 mask = i2;
7968 assign(value, load(Ity_I8, mkexpr(op1addr)));
7969 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_8, value, mktemp(Ity_I8,
7970 mkU8(mask)));
7971
7972 return "tmy";
7973}
7974
7975static HChar *
7976s390_irgen_TMHH(UChar r1, UShort i2)
7977{
7978 UShort mask;
7979 IRTemp value = newTemp(Ity_I16);
7980
7981 mask = i2;
7982 assign(value, get_gpr_hw0(r1));
7983 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
7984 mkU16(mask)));
7985
7986 return "tmhh";
7987}
7988
7989static HChar *
7990s390_irgen_TMHL(UChar r1, UShort i2)
7991{
7992 UShort mask;
7993 IRTemp value = newTemp(Ity_I16);
7994
7995 mask = i2;
7996 assign(value, get_gpr_hw1(r1));
7997 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
7998 mkU16(mask)));
7999
8000 return "tmhl";
8001}
8002
8003static HChar *
8004s390_irgen_TMLH(UChar r1, UShort i2)
8005{
8006 UShort mask;
8007 IRTemp value = newTemp(Ity_I16);
8008
8009 mask = i2;
8010 assign(value, get_gpr_hw2(r1));
8011 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
8012 mkU16(mask)));
8013
8014 return "tmlh";
8015}
8016
8017static HChar *
8018s390_irgen_TMLL(UChar r1, UShort i2)
8019{
8020 UShort mask;
8021 IRTemp value = newTemp(Ity_I16);
8022
8023 mask = i2;
8024 assign(value, get_gpr_hw3(r1));
8025 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
8026 mkU16(mask)));
8027
8028 return "tmll";
8029}
8030
8031static HChar *
8032s390_irgen_EFPC(UChar r1)
8033{
8034 put_gpr_w1(r1, get_fpc_w0());
8035
8036 return "efpc";
8037}
8038
8039static HChar *
8040s390_irgen_LER(UChar r1, UChar r2)
8041{
8042 put_fpr_w0(r1, get_fpr_w0(r2));
8043
8044 return "ler";
8045}
8046
8047static HChar *
8048s390_irgen_LDR(UChar r1, UChar r2)
8049{
8050 put_fpr_dw0(r1, get_fpr_dw0(r2));
8051
8052 return "ldr";
8053}
8054
8055static HChar *
8056s390_irgen_LXR(UChar r1, UChar r2)
8057{
8058 put_fpr_dw0(r1, get_fpr_dw0(r2));
8059 put_fpr_dw0(r1 + 2, get_fpr_dw0(r2 + 2));
8060
8061 return "lxr";
8062}
8063
8064static HChar *
8065s390_irgen_LE(UChar r1, IRTemp op2addr)
8066{
8067 put_fpr_w0(r1, load(Ity_F32, mkexpr(op2addr)));
8068
8069 return "le";
8070}
8071
8072static HChar *
8073s390_irgen_LD(UChar r1, IRTemp op2addr)
8074{
8075 put_fpr_dw0(r1, load(Ity_F64, mkexpr(op2addr)));
8076
8077 return "ld";
8078}
8079
8080static HChar *
8081s390_irgen_LEY(UChar r1, IRTemp op2addr)
8082{
8083 put_fpr_w0(r1, load(Ity_F32, mkexpr(op2addr)));
8084
8085 return "ley";
8086}
8087
8088static HChar *
8089s390_irgen_LDY(UChar r1, IRTemp op2addr)
8090{
8091 put_fpr_dw0(r1, load(Ity_F64, mkexpr(op2addr)));
8092
8093 return "ldy";
8094}
8095
8096static HChar *
8097s390_irgen_LFPC(IRTemp op2addr)
8098{
8099 put_fpc_w0(load(Ity_I32, mkexpr(op2addr)));
8100
8101 return "lfpc";
8102}
8103
8104static HChar *
8105s390_irgen_LZER(UChar r1)
8106{
8107 put_fpr_w0(r1, mkF32i(0x0));
8108
8109 return "lzer";
8110}
8111
8112static HChar *
8113s390_irgen_LZDR(UChar r1)
8114{
8115 put_fpr_dw0(r1, mkF64i(0x0));
8116
8117 return "lzdr";
8118}
8119
8120static HChar *
8121s390_irgen_LZXR(UChar r1)
8122{
8123 put_fpr_dw0(r1, mkF64i(0x0));
8124 put_fpr_dw0(r1 + 2, mkF64i(0x0));
8125
8126 return "lzxr";
8127}
8128
8129static HChar *
8130s390_irgen_SRNM(IRTemp op2addr)
8131{
8132 UInt mask;
8133
8134 mask = 3;
8135 put_fpc_w0(binop(Iop_Or32, binop(Iop_And32, get_fpc_w0(), mkU32(~mask)),
8136 binop(Iop_And32, unop(Iop_64to32, mkexpr(op2addr)), mkU32(mask)))
8137 );
8138
8139 return "srnm";
8140}
8141
8142static HChar *
8143s390_irgen_SFPC(UChar r1)
8144{
8145 put_fpc_w0(get_gpr_w1(r1));
8146
8147 return "sfpc";
8148}
8149
8150static HChar *
8151s390_irgen_STE(UChar r1, IRTemp op2addr)
8152{
8153 store(mkexpr(op2addr), get_fpr_w0(r1));
8154
8155 return "ste";
8156}
8157
8158static HChar *
8159s390_irgen_STD(UChar r1, IRTemp op2addr)
8160{
8161 store(mkexpr(op2addr), get_fpr_dw0(r1));
8162
8163 return "std";
8164}
8165
8166static HChar *
8167s390_irgen_STEY(UChar r1, IRTemp op2addr)
8168{
8169 store(mkexpr(op2addr), get_fpr_w0(r1));
8170
8171 return "stey";
8172}
8173
8174static HChar *
8175s390_irgen_STDY(UChar r1, IRTemp op2addr)
8176{
8177 store(mkexpr(op2addr), get_fpr_dw0(r1));
8178
8179 return "stdy";
8180}
8181
8182static HChar *
8183s390_irgen_STFPC(IRTemp op2addr)
8184{
8185 store(mkexpr(op2addr), get_fpc_w0());
8186
8187 return "stfpc";
8188}
8189
8190static HChar *
8191s390_irgen_AEBR(UChar r1, UChar r2)
8192{
8193 IRTemp op1 = newTemp(Ity_F32);
8194 IRTemp op2 = newTemp(Ity_F32);
8195 IRTemp result = newTemp(Ity_F32);
floriandb4fcaa2012-09-05 19:54:08 +00008196 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008197
8198 assign(op1, get_fpr_w0(r1));
8199 assign(op2, get_fpr_w0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008200 assign(result, triop(Iop_AddF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008201 mkexpr(op2)));
8202 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
8203 put_fpr_w0(r1, mkexpr(result));
8204
8205 return "aebr";
8206}
8207
8208static HChar *
8209s390_irgen_ADBR(UChar r1, UChar r2)
8210{
8211 IRTemp op1 = newTemp(Ity_F64);
8212 IRTemp op2 = newTemp(Ity_F64);
8213 IRTemp result = newTemp(Ity_F64);
floriandb4fcaa2012-09-05 19:54:08 +00008214 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008215
8216 assign(op1, get_fpr_dw0(r1));
8217 assign(op2, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008218 assign(result, triop(Iop_AddF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008219 mkexpr(op2)));
8220 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
8221 put_fpr_dw0(r1, mkexpr(result));
8222
8223 return "adbr";
8224}
8225
8226static HChar *
8227s390_irgen_AEB(UChar r1, IRTemp op2addr)
8228{
8229 IRTemp op1 = newTemp(Ity_F32);
8230 IRTemp op2 = newTemp(Ity_F32);
8231 IRTemp result = newTemp(Ity_F32);
floriandb4fcaa2012-09-05 19:54:08 +00008232 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008233
8234 assign(op1, get_fpr_w0(r1));
8235 assign(op2, load(Ity_F32, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00008236 assign(result, triop(Iop_AddF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008237 mkexpr(op2)));
8238 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
8239 put_fpr_w0(r1, mkexpr(result));
8240
8241 return "aeb";
8242}
8243
8244static HChar *
8245s390_irgen_ADB(UChar r1, IRTemp op2addr)
8246{
8247 IRTemp op1 = newTemp(Ity_F64);
8248 IRTemp op2 = newTemp(Ity_F64);
8249 IRTemp result = newTemp(Ity_F64);
floriandb4fcaa2012-09-05 19:54:08 +00008250 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008251
8252 assign(op1, get_fpr_dw0(r1));
8253 assign(op2, load(Ity_F64, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00008254 assign(result, triop(Iop_AddF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008255 mkexpr(op2)));
8256 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
8257 put_fpr_dw0(r1, mkexpr(result));
8258
8259 return "adb";
8260}
8261
8262static HChar *
florian4b8efad2012-09-02 18:07:08 +00008263s390_irgen_CEFBR(UChar m3, UChar m4 __attribute__((unused)),
8264 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008265{
florian847684d2012-09-05 04:19:09 +00008266 if (! s390_host_has_fpext && m3 != S390_ROUND_PER_FPC) {
florian4b8efad2012-09-02 18:07:08 +00008267 emulation_warning(EmWarn_S390X_fpext_rounding);
florian847684d2012-09-05 04:19:09 +00008268 m3 = S390_ROUND_PER_FPC;
florian4b8efad2012-09-02 18:07:08 +00008269 }
sewardj2019a972011-03-07 16:04:07 +00008270 IRTemp op2 = newTemp(Ity_I32);
8271
8272 assign(op2, get_gpr_w1(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008273 put_fpr_w0(r1, binop(Iop_I32StoF32, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +00008274 mkexpr(op2)));
sewardj2019a972011-03-07 16:04:07 +00008275
8276 return "cefbr";
8277}
8278
8279static HChar *
florian4b8efad2012-09-02 18:07:08 +00008280s390_irgen_CDFBR(UChar m3 __attribute__((unused)),
8281 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008282{
8283 IRTemp op2 = newTemp(Ity_I32);
8284
8285 assign(op2, get_gpr_w1(r2));
8286 put_fpr_dw0(r1, unop(Iop_I32StoF64, mkexpr(op2)));
8287
8288 return "cdfbr";
8289}
8290
8291static HChar *
florian4b8efad2012-09-02 18:07:08 +00008292s390_irgen_CEGBR(UChar m3, UChar m4 __attribute__((unused)),
8293 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008294{
florian847684d2012-09-05 04:19:09 +00008295 if (! s390_host_has_fpext && m3 != S390_ROUND_PER_FPC) {
florian4b8efad2012-09-02 18:07:08 +00008296 emulation_warning(EmWarn_S390X_fpext_rounding);
florian847684d2012-09-05 04:19:09 +00008297 m3 = S390_ROUND_PER_FPC;
florian4b8efad2012-09-02 18:07:08 +00008298 }
sewardj2019a972011-03-07 16:04:07 +00008299 IRTemp op2 = newTemp(Ity_I64);
8300
8301 assign(op2, get_gpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008302 put_fpr_w0(r1, binop(Iop_I64StoF32, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +00008303 mkexpr(op2)));
sewardj2019a972011-03-07 16:04:07 +00008304
8305 return "cegbr";
8306}
8307
8308static HChar *
florian4b8efad2012-09-02 18:07:08 +00008309s390_irgen_CDGBR(UChar m3, UChar m4 __attribute__((unused)),
8310 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008311{
florian847684d2012-09-05 04:19:09 +00008312 if (! s390_host_has_fpext && m3 != S390_ROUND_PER_FPC) {
florian4b8efad2012-09-02 18:07:08 +00008313 emulation_warning(EmWarn_S390X_fpext_rounding);
florian847684d2012-09-05 04:19:09 +00008314 m3 = S390_ROUND_PER_FPC;
florian4b8efad2012-09-02 18:07:08 +00008315 }
sewardj2019a972011-03-07 16:04:07 +00008316 IRTemp op2 = newTemp(Ity_I64);
8317
8318 assign(op2, get_gpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008319 put_fpr_dw0(r1, binop(Iop_I64StoF64, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +00008320 mkexpr(op2)));
sewardj2019a972011-03-07 16:04:07 +00008321
8322 return "cdgbr";
8323}
8324
8325static HChar *
florian1c8f7ff2012-09-01 00:12:11 +00008326s390_irgen_CELFBR(UChar m3, UChar m4 __attribute__((unused)),
8327 UChar r1, UChar r2)
8328{
floriane75dafa2012-09-01 17:54:09 +00008329 if (! s390_host_has_fpext) {
8330 emulation_failure(EmFail_S390X_fpext);
8331 } else {
8332 IRTemp op2 = newTemp(Ity_I32);
florian1c8f7ff2012-09-01 00:12:11 +00008333
floriane75dafa2012-09-01 17:54:09 +00008334 assign(op2, get_gpr_w1(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008335 put_fpr_w0(r1, binop(Iop_I32UtoF32, mkexpr(encode_bfp_rounding_mode(m3)),
floriane75dafa2012-09-01 17:54:09 +00008336 mkexpr(op2)));
8337 }
florian1c8f7ff2012-09-01 00:12:11 +00008338 return "celfbr";
8339}
8340
8341static HChar *
floriand2129202012-09-01 20:01:39 +00008342s390_irgen_CDLFBR(UChar m3 __attribute__((unused)),
8343 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
florian1c8f7ff2012-09-01 00:12:11 +00008344{
floriane75dafa2012-09-01 17:54:09 +00008345 if (! s390_host_has_fpext) {
8346 emulation_failure(EmFail_S390X_fpext);
8347 } else {
8348 IRTemp op2 = newTemp(Ity_I32);
florian1c8f7ff2012-09-01 00:12:11 +00008349
floriane75dafa2012-09-01 17:54:09 +00008350 assign(op2, get_gpr_w1(r2));
8351 put_fpr_dw0(r1, unop(Iop_I32UtoF64, mkexpr(op2)));
8352 }
florian1c8f7ff2012-09-01 00:12:11 +00008353 return "cdlfbr";
8354}
8355
8356static HChar *
8357s390_irgen_CELGBR(UChar m3, UChar m4 __attribute__((unused)),
8358 UChar r1, UChar r2)
8359{
floriane75dafa2012-09-01 17:54:09 +00008360 if (! s390_host_has_fpext) {
8361 emulation_failure(EmFail_S390X_fpext);
8362 } else {
8363 IRTemp op2 = newTemp(Ity_I64);
florian1c8f7ff2012-09-01 00:12:11 +00008364
floriane75dafa2012-09-01 17:54:09 +00008365 assign(op2, get_gpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008366 put_fpr_w0(r1, binop(Iop_I64UtoF32, mkexpr(encode_bfp_rounding_mode(m3)),
floriane75dafa2012-09-01 17:54:09 +00008367 mkexpr(op2)));
8368 }
florian1c8f7ff2012-09-01 00:12:11 +00008369 return "celgbr";
8370}
8371
8372static HChar *
8373s390_irgen_CDLGBR(UChar m3, UChar m4 __attribute__((unused)),
8374 UChar r1, UChar r2)
8375{
floriane75dafa2012-09-01 17:54:09 +00008376 if (! s390_host_has_fpext) {
8377 emulation_failure(EmFail_S390X_fpext);
8378 } else {
8379 IRTemp op2 = newTemp(Ity_I64);
florian1c8f7ff2012-09-01 00:12:11 +00008380
floriane75dafa2012-09-01 17:54:09 +00008381 assign(op2, get_gpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008382 put_fpr_dw0(r1, binop(Iop_I64UtoF64,
8383 mkexpr(encode_bfp_rounding_mode(m3)),
floriane75dafa2012-09-01 17:54:09 +00008384 mkexpr(op2)));
8385 }
florian1c8f7ff2012-09-01 00:12:11 +00008386 return "cdlgbr";
8387}
8388
8389static HChar *
8390s390_irgen_CLFEBR(UChar m3, UChar m4 __attribute__((unused)),
8391 UChar r1, UChar r2)
8392{
floriane75dafa2012-09-01 17:54:09 +00008393 if (! s390_host_has_fpext) {
8394 emulation_failure(EmFail_S390X_fpext);
8395 } else {
8396 IRTemp op = newTemp(Ity_F32);
8397 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +00008398 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +00008399
floriane75dafa2012-09-01 17:54:09 +00008400 assign(op, get_fpr_w0(r2));
florian19e00772012-09-06 03:13:22 +00008401 assign(result, binop(Iop_F32toI32U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +00008402 mkexpr(op)));
8403 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008404 s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_UINT_32, op, rounding_mode);
floriane75dafa2012-09-01 17:54:09 +00008405 }
florian1c8f7ff2012-09-01 00:12:11 +00008406 return "clfebr";
8407}
8408
8409static HChar *
8410s390_irgen_CLFDBR(UChar m3, UChar m4 __attribute__((unused)),
8411 UChar r1, UChar r2)
8412{
floriane75dafa2012-09-01 17:54:09 +00008413 if (! s390_host_has_fpext) {
8414 emulation_failure(EmFail_S390X_fpext);
8415 } else {
8416 IRTemp op = newTemp(Ity_F64);
8417 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +00008418 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +00008419
floriane75dafa2012-09-01 17:54:09 +00008420 assign(op, get_fpr_dw0(r2));
florian19e00772012-09-06 03:13:22 +00008421 assign(result, binop(Iop_F64toI32U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +00008422 mkexpr(op)));
8423 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008424 s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_UINT_32, op, rounding_mode);
floriane75dafa2012-09-01 17:54:09 +00008425 }
florian1c8f7ff2012-09-01 00:12:11 +00008426 return "clfdbr";
8427}
8428
8429static HChar *
8430s390_irgen_CLGEBR(UChar m3, UChar m4 __attribute__((unused)),
8431 UChar r1, UChar r2)
8432{
floriane75dafa2012-09-01 17:54:09 +00008433 if (! s390_host_has_fpext) {
8434 emulation_failure(EmFail_S390X_fpext);
8435 } else {
8436 IRTemp op = newTemp(Ity_F32);
8437 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +00008438 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +00008439
floriane75dafa2012-09-01 17:54:09 +00008440 assign(op, get_fpr_w0(r2));
florian19e00772012-09-06 03:13:22 +00008441 assign(result, binop(Iop_F32toI64U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +00008442 mkexpr(op)));
8443 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008444 s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_UINT_64, op, rounding_mode);
floriane75dafa2012-09-01 17:54:09 +00008445 }
florian1c8f7ff2012-09-01 00:12:11 +00008446 return "clgebr";
8447}
8448
8449static HChar *
8450s390_irgen_CLGDBR(UChar m3, UChar m4 __attribute__((unused)),
8451 UChar r1, UChar r2)
8452{
floriane75dafa2012-09-01 17:54:09 +00008453 if (! s390_host_has_fpext) {
8454 emulation_failure(EmFail_S390X_fpext);
8455 } else {
8456 IRTemp op = newTemp(Ity_F64);
8457 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +00008458 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +00008459
floriane75dafa2012-09-01 17:54:09 +00008460 assign(op, get_fpr_dw0(r2));
florian19e00772012-09-06 03:13:22 +00008461 assign(result, binop(Iop_F64toI64U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +00008462 mkexpr(op)));
8463 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008464 s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_UINT_64, op, rounding_mode);
floriane75dafa2012-09-01 17:54:09 +00008465 }
florian1c8f7ff2012-09-01 00:12:11 +00008466 return "clgdbr";
8467}
8468
8469static HChar *
florian4b8efad2012-09-02 18:07:08 +00008470s390_irgen_CFEBR(UChar m3, UChar m4 __attribute__((unused)),
8471 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008472{
8473 IRTemp op = newTemp(Ity_F32);
8474 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +00008475 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +00008476
8477 assign(op, get_fpr_w0(r2));
florian19e00772012-09-06 03:13:22 +00008478 assign(result, binop(Iop_F32toI32S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +00008479 mkexpr(op)));
8480 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008481 s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_INT_32, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +00008482
8483 return "cfebr";
8484}
8485
8486static HChar *
florian4b8efad2012-09-02 18:07:08 +00008487s390_irgen_CFDBR(UChar m3, UChar m4 __attribute__((unused)),
8488 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008489{
8490 IRTemp op = newTemp(Ity_F64);
8491 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +00008492 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +00008493
8494 assign(op, get_fpr_dw0(r2));
florian19e00772012-09-06 03:13:22 +00008495 assign(result, binop(Iop_F64toI32S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +00008496 mkexpr(op)));
8497 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008498 s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_INT_32, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +00008499
8500 return "cfdbr";
8501}
8502
8503static HChar *
florian4b8efad2012-09-02 18:07:08 +00008504s390_irgen_CGEBR(UChar m3, UChar m4 __attribute__((unused)),
8505 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008506{
8507 IRTemp op = newTemp(Ity_F32);
8508 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +00008509 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +00008510
8511 assign(op, get_fpr_w0(r2));
florian19e00772012-09-06 03:13:22 +00008512 assign(result, binop(Iop_F32toI64S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +00008513 mkexpr(op)));
8514 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008515 s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_INT_64, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +00008516
8517 return "cgebr";
8518}
8519
8520static HChar *
florian4b8efad2012-09-02 18:07:08 +00008521s390_irgen_CGDBR(UChar m3, UChar m4 __attribute__((unused)),
8522 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008523{
8524 IRTemp op = newTemp(Ity_F64);
8525 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +00008526 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +00008527
8528 assign(op, get_fpr_dw0(r2));
florian19e00772012-09-06 03:13:22 +00008529 assign(result, binop(Iop_F64toI64S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +00008530 mkexpr(op)));
8531 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008532 s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_INT_64, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +00008533
8534 return "cgdbr";
8535}
8536
8537static HChar *
8538s390_irgen_DEBR(UChar r1, UChar r2)
8539{
8540 IRTemp op1 = newTemp(Ity_F32);
8541 IRTemp op2 = newTemp(Ity_F32);
8542 IRTemp result = newTemp(Ity_F32);
floriandb4fcaa2012-09-05 19:54:08 +00008543 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008544
8545 assign(op1, get_fpr_w0(r1));
8546 assign(op2, get_fpr_w0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008547 assign(result, triop(Iop_DivF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008548 mkexpr(op2)));
8549 put_fpr_w0(r1, mkexpr(result));
8550
8551 return "debr";
8552}
8553
8554static HChar *
8555s390_irgen_DDBR(UChar r1, UChar r2)
8556{
8557 IRTemp op1 = newTemp(Ity_F64);
8558 IRTemp op2 = newTemp(Ity_F64);
8559 IRTemp result = newTemp(Ity_F64);
floriandb4fcaa2012-09-05 19:54:08 +00008560 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008561
8562 assign(op1, get_fpr_dw0(r1));
8563 assign(op2, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008564 assign(result, triop(Iop_DivF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008565 mkexpr(op2)));
8566 put_fpr_dw0(r1, mkexpr(result));
8567
8568 return "ddbr";
8569}
8570
8571static HChar *
8572s390_irgen_DEB(UChar r1, IRTemp op2addr)
8573{
8574 IRTemp op1 = newTemp(Ity_F32);
8575 IRTemp op2 = newTemp(Ity_F32);
8576 IRTemp result = newTemp(Ity_F32);
floriandb4fcaa2012-09-05 19:54:08 +00008577 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008578
8579 assign(op1, get_fpr_w0(r1));
8580 assign(op2, load(Ity_F32, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00008581 assign(result, triop(Iop_DivF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008582 mkexpr(op2)));
8583 put_fpr_w0(r1, mkexpr(result));
8584
8585 return "deb";
8586}
8587
8588static HChar *
8589s390_irgen_DDB(UChar r1, IRTemp op2addr)
8590{
8591 IRTemp op1 = newTemp(Ity_F64);
8592 IRTemp op2 = newTemp(Ity_F64);
8593 IRTemp result = newTemp(Ity_F64);
floriandb4fcaa2012-09-05 19:54:08 +00008594 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008595
8596 assign(op1, get_fpr_dw0(r1));
8597 assign(op2, load(Ity_F64, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00008598 assign(result, triop(Iop_DivF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008599 mkexpr(op2)));
8600 put_fpr_dw0(r1, mkexpr(result));
8601
8602 return "ddb";
8603}
8604
8605static HChar *
8606s390_irgen_LTEBR(UChar r1, UChar r2)
8607{
8608 IRTemp result = newTemp(Ity_F32);
8609
8610 assign(result, get_fpr_w0(r2));
8611 put_fpr_w0(r1, mkexpr(result));
8612 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
8613
8614 return "ltebr";
8615}
8616
8617static HChar *
8618s390_irgen_LTDBR(UChar r1, UChar r2)
8619{
8620 IRTemp result = newTemp(Ity_F64);
8621
8622 assign(result, get_fpr_dw0(r2));
8623 put_fpr_dw0(r1, mkexpr(result));
8624 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
8625
8626 return "ltdbr";
8627}
8628
8629static HChar *
8630s390_irgen_LCEBR(UChar r1, UChar r2)
8631{
8632 IRTemp result = newTemp(Ity_F32);
8633
8634 assign(result, unop(Iop_NegF32, get_fpr_w0(r2)));
8635 put_fpr_w0(r1, mkexpr(result));
8636 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
8637
8638 return "lcebr";
8639}
8640
8641static HChar *
8642s390_irgen_LCDBR(UChar r1, UChar r2)
8643{
8644 IRTemp result = newTemp(Ity_F64);
8645
8646 assign(result, unop(Iop_NegF64, get_fpr_dw0(r2)));
8647 put_fpr_dw0(r1, mkexpr(result));
8648 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
8649
8650 return "lcdbr";
8651}
8652
8653static HChar *
8654s390_irgen_LDEBR(UChar r1, UChar r2)
8655{
8656 IRTemp op = newTemp(Ity_F32);
8657
8658 assign(op, get_fpr_w0(r2));
8659 put_fpr_dw0(r1, unop(Iop_F32toF64, mkexpr(op)));
8660
8661 return "ldebr";
8662}
8663
8664static HChar *
8665s390_irgen_LDEB(UChar r1, IRTemp op2addr)
8666{
8667 IRTemp op = newTemp(Ity_F32);
8668
8669 assign(op, load(Ity_F32, mkexpr(op2addr)));
8670 put_fpr_dw0(r1, unop(Iop_F32toF64, mkexpr(op)));
8671
8672 return "ldeb";
8673}
8674
8675static HChar *
florian4b8efad2012-09-02 18:07:08 +00008676s390_irgen_LEDBR(UChar m3, UChar m4 __attribute__((unused)),
8677 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008678{
florian12b0bca2012-09-05 20:05:20 +00008679 if (! s390_host_has_fpext && m3 != S390_ROUND_PER_FPC) {
8680 emulation_warning(EmWarn_S390X_fpext_rounding);
8681 m3 = S390_ROUND_PER_FPC;
8682 }
sewardj2019a972011-03-07 16:04:07 +00008683 IRTemp op = newTemp(Ity_F64);
8684
8685 assign(op, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008686 put_fpr_w0(r1, binop(Iop_F64toF32, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +00008687 mkexpr(op)));
sewardj2019a972011-03-07 16:04:07 +00008688
8689 return "ledbr";
8690}
8691
8692static HChar *
8693s390_irgen_MEEBR(UChar r1, UChar r2)
8694{
8695 IRTemp op1 = newTemp(Ity_F32);
8696 IRTemp op2 = newTemp(Ity_F32);
8697 IRTemp result = newTemp(Ity_F32);
floriandb4fcaa2012-09-05 19:54:08 +00008698 IRRoundingMode rounding_mode = encode_bfp_rounding_mode(S390_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008699
8700 assign(op1, get_fpr_w0(r1));
8701 assign(op2, get_fpr_w0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008702 assign(result, triop(Iop_MulF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008703 mkexpr(op2)));
8704 put_fpr_w0(r1, mkexpr(result));
8705
8706 return "meebr";
8707}
8708
8709static HChar *
8710s390_irgen_MDBR(UChar r1, UChar r2)
8711{
8712 IRTemp op1 = newTemp(Ity_F64);
8713 IRTemp op2 = newTemp(Ity_F64);
8714 IRTemp result = newTemp(Ity_F64);
floriandb4fcaa2012-09-05 19:54:08 +00008715 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008716
8717 assign(op1, get_fpr_dw0(r1));
8718 assign(op2, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008719 assign(result, triop(Iop_MulF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008720 mkexpr(op2)));
8721 put_fpr_dw0(r1, mkexpr(result));
8722
8723 return "mdbr";
8724}
8725
8726static HChar *
8727s390_irgen_MEEB(UChar r1, IRTemp op2addr)
8728{
8729 IRTemp op1 = newTemp(Ity_F32);
8730 IRTemp op2 = newTemp(Ity_F32);
8731 IRTemp result = newTemp(Ity_F32);
floriandb4fcaa2012-09-05 19:54:08 +00008732 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008733
8734 assign(op1, get_fpr_w0(r1));
8735 assign(op2, load(Ity_F32, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00008736 assign(result, triop(Iop_MulF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008737 mkexpr(op2)));
8738 put_fpr_w0(r1, mkexpr(result));
8739
8740 return "meeb";
8741}
8742
8743static HChar *
8744s390_irgen_MDB(UChar r1, IRTemp op2addr)
8745{
8746 IRTemp op1 = newTemp(Ity_F64);
8747 IRTemp op2 = newTemp(Ity_F64);
8748 IRTemp result = newTemp(Ity_F64);
floriandb4fcaa2012-09-05 19:54:08 +00008749 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008750
8751 assign(op1, get_fpr_dw0(r1));
8752 assign(op2, load(Ity_F64, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00008753 assign(result, triop(Iop_MulF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008754 mkexpr(op2)));
8755 put_fpr_dw0(r1, mkexpr(result));
8756
8757 return "mdb";
8758}
8759
8760static HChar *
8761s390_irgen_SEBR(UChar r1, UChar r2)
8762{
8763 IRTemp op1 = newTemp(Ity_F32);
8764 IRTemp op2 = newTemp(Ity_F32);
8765 IRTemp result = newTemp(Ity_F32);
floriandb4fcaa2012-09-05 19:54:08 +00008766 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008767
8768 assign(op1, get_fpr_w0(r1));
8769 assign(op2, get_fpr_w0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008770 assign(result, triop(Iop_SubF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008771 mkexpr(op2)));
8772 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
8773 put_fpr_w0(r1, mkexpr(result));
8774
8775 return "sebr";
8776}
8777
8778static HChar *
8779s390_irgen_SDBR(UChar r1, UChar r2)
8780{
8781 IRTemp op1 = newTemp(Ity_F64);
8782 IRTemp op2 = newTemp(Ity_F64);
8783 IRTemp result = newTemp(Ity_F64);
floriandb4fcaa2012-09-05 19:54:08 +00008784 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008785
8786 assign(op1, get_fpr_dw0(r1));
8787 assign(op2, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008788 assign(result, triop(Iop_SubF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008789 mkexpr(op2)));
8790 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
8791 put_fpr_dw0(r1, mkexpr(result));
8792
8793 return "sdbr";
8794}
8795
8796static HChar *
8797s390_irgen_SEB(UChar r1, IRTemp op2addr)
8798{
8799 IRTemp op1 = newTemp(Ity_F32);
8800 IRTemp op2 = newTemp(Ity_F32);
8801 IRTemp result = newTemp(Ity_F32);
floriandb4fcaa2012-09-05 19:54:08 +00008802 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008803
8804 assign(op1, get_fpr_w0(r1));
8805 assign(op2, load(Ity_F32, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00008806 assign(result, triop(Iop_SubF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008807 mkexpr(op2)));
8808 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
8809 put_fpr_w0(r1, mkexpr(result));
8810
8811 return "seb";
8812}
8813
8814static HChar *
8815s390_irgen_SDB(UChar r1, IRTemp op2addr)
8816{
8817 IRTemp op1 = newTemp(Ity_F64);
8818 IRTemp op2 = newTemp(Ity_F64);
8819 IRTemp result = newTemp(Ity_F64);
floriandb4fcaa2012-09-05 19:54:08 +00008820 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008821
8822 assign(op1, get_fpr_dw0(r1));
8823 assign(op2, load(Ity_F64, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00008824 assign(result, triop(Iop_SubF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008825 mkexpr(op2)));
8826 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
8827 put_fpr_dw0(r1, mkexpr(result));
8828
8829 return "sdb";
8830}
8831
8832
8833static HChar *
8834s390_irgen_CLC(UChar length, IRTemp start1, IRTemp start2)
8835{
florian79e839e2012-05-05 02:20:30 +00008836 IRTemp len = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00008837
florian79e839e2012-05-05 02:20:30 +00008838 assign(len, mkU64(length));
8839 s390_irgen_CLC_EX(len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +00008840
8841 return "clc";
8842}
8843
8844static HChar *
florianb0c9a132011-09-08 15:37:39 +00008845s390_irgen_CLCL(UChar r1, UChar r2)
8846{
8847 IRTemp addr1 = newTemp(Ity_I64);
8848 IRTemp addr2 = newTemp(Ity_I64);
8849 IRTemp addr1_load = newTemp(Ity_I64);
8850 IRTemp addr2_load = newTemp(Ity_I64);
8851 IRTemp len1 = newTemp(Ity_I32);
8852 IRTemp len2 = newTemp(Ity_I32);
8853 IRTemp r1p1 = newTemp(Ity_I32); /* contents of r1 + 1 */
8854 IRTemp r2p1 = newTemp(Ity_I32); /* contents of r2 + 1 */
8855 IRTemp single1 = newTemp(Ity_I8);
8856 IRTemp single2 = newTemp(Ity_I8);
8857 IRTemp pad = newTemp(Ity_I8);
8858
8859 assign(addr1, get_gpr_dw0(r1));
8860 assign(r1p1, get_gpr_w1(r1 + 1));
8861 assign(len1, binop(Iop_And32, mkexpr(r1p1), mkU32(0x00ffffff)));
8862 assign(addr2, get_gpr_dw0(r2));
8863 assign(r2p1, get_gpr_w1(r2 + 1));
8864 assign(len2, binop(Iop_And32, mkexpr(r2p1), mkU32(0x00ffffff)));
8865 assign(pad, get_gpr_b4(r2 + 1));
8866
8867 /* len1 == 0 and len2 == 0? Exit */
8868 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +00008869 next_insn_if(binop(Iop_CmpEQ32, binop(Iop_Or32, mkexpr(len1),
8870 mkexpr(len2)), mkU32(0)));
florianb0c9a132011-09-08 15:37:39 +00008871
8872 /* Because mkite evaluates both the then-clause and the else-clause
8873 we cannot load directly from addr1 here. If len1 is 0, then adddr1
8874 may be NULL and loading from there would segfault. So we provide a
8875 valid dummy address in that case. Loading from there does no harm and
8876 the value will be discarded at runtime. */
8877 assign(addr1_load,
8878 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
8879 mkU64(guest_IA_curr_instr), mkexpr(addr1)));
8880 assign(single1,
8881 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
8882 mkexpr(pad), load(Ity_I8, mkexpr(addr1_load))));
8883
8884 assign(addr2_load,
8885 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
8886 mkU64(guest_IA_curr_instr), mkexpr(addr2)));
8887 assign(single2,
8888 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
8889 mkexpr(pad), load(Ity_I8, mkexpr(addr2_load))));
8890
8891 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, single1, single2, False);
8892 /* Fields differ ? */
florian6820ba52012-07-26 02:01:50 +00008893 next_insn_if(binop(Iop_CmpNE8, mkexpr(single1), mkexpr(single2)));
florianb0c9a132011-09-08 15:37:39 +00008894
8895 /* Update len1 and addr1, unless len1 == 0. */
8896 put_gpr_dw0(r1,
8897 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
8898 mkexpr(addr1),
8899 binop(Iop_Add64, mkexpr(addr1), mkU64(1))));
8900
8901 /* When updating len1 we must not modify bits (r1+1)[0:39] */
8902 put_gpr_w1(r1 + 1,
8903 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
8904 binop(Iop_And32, mkexpr(r1p1), mkU32(0xFF000000u)),
8905 binop(Iop_Sub32, mkexpr(r1p1), mkU32(1))));
8906
8907 /* Update len2 and addr2, unless len2 == 0. */
8908 put_gpr_dw0(r2,
8909 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
8910 mkexpr(addr2),
8911 binop(Iop_Add64, mkexpr(addr2), mkU64(1))));
8912
8913 /* When updating len2 we must not modify bits (r2+1)[0:39] */
8914 put_gpr_w1(r2 + 1,
8915 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
8916 binop(Iop_And32, mkexpr(r2p1), mkU32(0xFF000000u)),
8917 binop(Iop_Sub32, mkexpr(r2p1), mkU32(1))));
8918
florian6820ba52012-07-26 02:01:50 +00008919 iterate();
florianb0c9a132011-09-08 15:37:39 +00008920
8921 return "clcl";
8922}
8923
8924static HChar *
sewardj2019a972011-03-07 16:04:07 +00008925s390_irgen_CLCLE(UChar r1, UChar r3, IRTemp pad2)
8926{
8927 IRTemp addr1, addr3, addr1_load, addr3_load, len1, len3, single1, single3;
8928
8929 addr1 = newTemp(Ity_I64);
8930 addr3 = newTemp(Ity_I64);
8931 addr1_load = newTemp(Ity_I64);
8932 addr3_load = newTemp(Ity_I64);
8933 len1 = newTemp(Ity_I64);
8934 len3 = newTemp(Ity_I64);
8935 single1 = newTemp(Ity_I8);
8936 single3 = newTemp(Ity_I8);
8937
8938 assign(addr1, get_gpr_dw0(r1));
8939 assign(len1, get_gpr_dw0(r1 + 1));
8940 assign(addr3, get_gpr_dw0(r3));
8941 assign(len3, get_gpr_dw0(r3 + 1));
8942
8943 /* len1 == 0 and len3 == 0? Exit */
8944 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +00008945 next_insn_if(binop(Iop_CmpEQ64,binop(Iop_Or64, mkexpr(len1),
8946 mkexpr(len3)), mkU64(0)));
sewardj2019a972011-03-07 16:04:07 +00008947
8948 /* A mux requires both ways to be possible. This is a way to prevent clcle
8949 from reading from addr1 if it should read from the pad. Since the pad
8950 has no address, just read from the instruction, we discard that anyway */
8951 assign(addr1_load,
florian6ad49522011-09-09 02:38:55 +00008952 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
8953 mkU64(guest_IA_curr_instr), mkexpr(addr1)));
sewardj2019a972011-03-07 16:04:07 +00008954
8955 /* same for addr3 */
8956 assign(addr3_load,
florian6ad49522011-09-09 02:38:55 +00008957 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
8958 mkU64(guest_IA_curr_instr), mkexpr(addr3)));
sewardj2019a972011-03-07 16:04:07 +00008959
8960 assign(single1,
florian6ad49522011-09-09 02:38:55 +00008961 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
8962 unop(Iop_64to8, mkexpr(pad2)),
8963 load(Ity_I8, mkexpr(addr1_load))));
sewardj2019a972011-03-07 16:04:07 +00008964
8965 assign(single3,
florian6ad49522011-09-09 02:38:55 +00008966 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
8967 unop(Iop_64to8, mkexpr(pad2)),
8968 load(Ity_I8, mkexpr(addr3_load))));
sewardj2019a972011-03-07 16:04:07 +00008969
8970 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, single1, single3, False);
8971 /* Both fields differ ? */
florian6820ba52012-07-26 02:01:50 +00008972 next_insn_if(binop(Iop_CmpNE8, mkexpr(single1), mkexpr(single3)));
sewardj2019a972011-03-07 16:04:07 +00008973
8974 /* If a length in 0 we must not change this length and the address */
8975 put_gpr_dw0(r1,
florian6ad49522011-09-09 02:38:55 +00008976 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
8977 mkexpr(addr1),
8978 binop(Iop_Add64, mkexpr(addr1), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +00008979
8980 put_gpr_dw0(r1 + 1,
florian6ad49522011-09-09 02:38:55 +00008981 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
8982 mkU64(0), binop(Iop_Sub64, mkexpr(len1), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +00008983
8984 put_gpr_dw0(r3,
florian6ad49522011-09-09 02:38:55 +00008985 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
8986 mkexpr(addr3),
8987 binop(Iop_Add64, mkexpr(addr3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +00008988
8989 put_gpr_dw0(r3 + 1,
florian6ad49522011-09-09 02:38:55 +00008990 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
8991 mkU64(0), binop(Iop_Sub64, mkexpr(len3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +00008992
florian6820ba52012-07-26 02:01:50 +00008993 iterate();
sewardj2019a972011-03-07 16:04:07 +00008994
8995 return "clcle";
8996}
floriana64c2432011-07-16 02:11:50 +00008997
florianb0bf6602012-05-05 00:01:16 +00008998
sewardj2019a972011-03-07 16:04:07 +00008999static void
9000s390_irgen_XC_EX(IRTemp length, IRTemp start1, IRTemp start2)
9001{
florianb0bf6602012-05-05 00:01:16 +00009002 s390_irgen_xonc(Iop_Xor8, length, start1, start2);
9003}
sewardj2019a972011-03-07 16:04:07 +00009004
sewardj2019a972011-03-07 16:04:07 +00009005
florianb0bf6602012-05-05 00:01:16 +00009006static void
9007s390_irgen_NC_EX(IRTemp length, IRTemp start1, IRTemp start2)
9008{
9009 s390_irgen_xonc(Iop_And8, length, start1, start2);
9010}
sewardj2019a972011-03-07 16:04:07 +00009011
sewardj2019a972011-03-07 16:04:07 +00009012
florianb0bf6602012-05-05 00:01:16 +00009013static void
9014s390_irgen_OC_EX(IRTemp length, IRTemp start1, IRTemp start2)
9015{
9016 s390_irgen_xonc(Iop_Or8, length, start1, start2);
sewardj2019a972011-03-07 16:04:07 +00009017}
9018
9019
9020static void
9021s390_irgen_CLC_EX(IRTemp length, IRTemp start1, IRTemp start2)
9022{
9023 IRTemp current1 = newTemp(Ity_I8);
9024 IRTemp current2 = newTemp(Ity_I8);
9025 IRTemp counter = newTemp(Ity_I64);
9026
9027 assign(counter, get_counter_dw0());
9028 put_counter_dw0(mkU64(0));
9029
9030 assign(current1, load(Ity_I8, binop(Iop_Add64, mkexpr(start1),
9031 mkexpr(counter))));
9032 assign(current2, load(Ity_I8, binop(Iop_Add64, mkexpr(start2),
9033 mkexpr(counter))));
9034 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, current1, current2,
9035 False);
9036
9037 /* Both fields differ ? */
florian6820ba52012-07-26 02:01:50 +00009038 next_insn_if(binop(Iop_CmpNE8, mkexpr(current1), mkexpr(current2)));
sewardj2019a972011-03-07 16:04:07 +00009039
9040 /* Check for end of field */
9041 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
florian6820ba52012-07-26 02:01:50 +00009042 iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)));
sewardj2019a972011-03-07 16:04:07 +00009043 put_counter_dw0(mkU64(0));
9044}
9045
9046static void
9047s390_irgen_MVC_EX(IRTemp length, IRTemp start1, IRTemp start2)
9048{
9049 IRTemp counter = newTemp(Ity_I64);
9050
9051 assign(counter, get_counter_dw0());
9052
9053 store(binop(Iop_Add64, mkexpr(start1), mkexpr(counter)),
9054 load(Ity_I8, binop(Iop_Add64, mkexpr(start2), mkexpr(counter))));
9055
9056 /* Check for end of field */
9057 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
florian6820ba52012-07-26 02:01:50 +00009058 iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)));
sewardj2019a972011-03-07 16:04:07 +00009059 put_counter_dw0(mkU64(0));
9060}
9061
florianf87d4fb2012-05-05 02:55:24 +00009062static void
9063s390_irgen_TR_EX(IRTemp length, IRTemp start1, IRTemp start2)
9064{
9065 IRTemp op = newTemp(Ity_I8);
9066 IRTemp op1 = newTemp(Ity_I8);
9067 IRTemp result = newTemp(Ity_I64);
9068 IRTemp counter = newTemp(Ity_I64);
9069
9070 assign(counter, get_counter_dw0());
9071
9072 assign(op, load(Ity_I8, binop(Iop_Add64, mkexpr(start1), mkexpr(counter))));
9073
9074 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)), mkexpr(start2)));
9075
9076 assign(op1, load(Ity_I8, mkexpr(result)));
9077 store(binop(Iop_Add64, mkexpr(start1), mkexpr(counter)), mkexpr(op1));
9078
9079 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
florian6820ba52012-07-26 02:01:50 +00009080 iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)));
florianf87d4fb2012-05-05 02:55:24 +00009081 put_counter_dw0(mkU64(0));
9082}
sewardj2019a972011-03-07 16:04:07 +00009083
9084
9085static void
9086s390_irgen_EX_SS(UChar r, IRTemp addr2,
florian6820ba52012-07-26 02:01:50 +00009087 void (*irgen)(IRTemp length, IRTemp start1, IRTemp start2),
9088 int lensize)
sewardj2019a972011-03-07 16:04:07 +00009089{
9090 struct SS {
9091 unsigned int op : 8;
9092 unsigned int l : 8;
9093 unsigned int b1 : 4;
9094 unsigned int d1 : 12;
9095 unsigned int b2 : 4;
9096 unsigned int d2 : 12;
9097 };
9098 union {
9099 struct SS dec;
9100 unsigned long bytes;
9101 } ss;
9102 IRTemp cond;
9103 IRDirty *d;
9104 IRTemp torun;
9105
9106 IRTemp start1 = newTemp(Ity_I64);
9107 IRTemp start2 = newTemp(Ity_I64);
9108 IRTemp len = newTemp(lensize == 64 ? Ity_I64 : Ity_I32);
9109 cond = newTemp(Ity_I1);
9110 torun = newTemp(Ity_I64);
9111
9112 assign(torun, load(Ity_I64, mkexpr(addr2)));
9113 /* Start with a check that the saved code is still correct */
9114 assign(cond, binop(Iop_CmpNE64, mkexpr(torun), mkU64(last_execute_target)));
9115 /* If not, save the new value */
9116 d = unsafeIRDirty_0_N (0, "s390x_dirtyhelper_EX", &s390x_dirtyhelper_EX,
9117 mkIRExprVec_1(mkexpr(torun)));
9118 d->guard = mkexpr(cond);
9119 stmt(IRStmt_Dirty(d));
9120
9121 /* and restart */
florian428dfdd2012-03-27 03:09:49 +00009122 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TISTART),
9123 mkU64(guest_IA_curr_instr)));
9124 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TILEN), mkU64(4)));
florian6820ba52012-07-26 02:01:50 +00009125 restart_if(mkexpr(cond));
sewardj2019a972011-03-07 16:04:07 +00009126
9127 ss.bytes = last_execute_target;
9128 assign(start1, binop(Iop_Add64, mkU64(ss.dec.d1),
9129 ss.dec.b1 != 0 ? get_gpr_dw0(ss.dec.b1) : mkU64(0)));
9130 assign(start2, binop(Iop_Add64, mkU64(ss.dec.d2),
9131 ss.dec.b2 != 0 ? get_gpr_dw0(ss.dec.b2) : mkU64(0)));
9132 assign(len, unop(lensize == 64 ? Iop_8Uto64 : Iop_8Uto32, binop(Iop_Or8,
9133 r != 0 ? get_gpr_b7(r): mkU8(0), mkU8(ss.dec.l))));
9134 irgen(len, start1, start2);
florian8844a632012-04-13 04:04:06 +00009135
sewardj2019a972011-03-07 16:04:07 +00009136 last_execute_target = 0;
9137}
9138
9139static HChar *
9140s390_irgen_EX(UChar r1, IRTemp addr2)
9141{
9142 switch(last_execute_target & 0xff00000000000000ULL) {
9143 case 0:
9144 {
9145 /* no code information yet */
9146 IRDirty *d;
9147
9148 /* so safe the code... */
9149 d = unsafeIRDirty_0_N (0, "s390x_dirtyhelper_EX", &s390x_dirtyhelper_EX,
9150 mkIRExprVec_1(load(Ity_I64, mkexpr(addr2))));
9151 stmt(IRStmt_Dirty(d));
9152 /* and restart */
florian428dfdd2012-03-27 03:09:49 +00009153 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TISTART),
9154 mkU64(guest_IA_curr_instr)));
9155 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TILEN), mkU64(4)));
florian6820ba52012-07-26 02:01:50 +00009156 restart_if(IRExpr_Const(IRConst_U1(True)));
9157
sewardj2019a972011-03-07 16:04:07 +00009158 /* we know that this will be invalidated */
florianf9e1ed72012-04-17 02:41:56 +00009159 put_IA(mkaddr_expr(guest_IA_next_instr));
sewardj2019a972011-03-07 16:04:07 +00009160 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +00009161 dis_res->jk_StopHere = Ijk_TInval;
sewardj2019a972011-03-07 16:04:07 +00009162 break;
9163 }
9164
9165 case 0xd200000000000000ULL:
9166 /* special case MVC */
9167 s390_irgen_EX_SS(r1, addr2, s390_irgen_MVC_EX, 64);
9168 return "mvc via ex";
9169
9170 case 0xd500000000000000ULL:
9171 /* special case CLC */
9172 s390_irgen_EX_SS(r1, addr2, s390_irgen_CLC_EX, 64);
9173 return "clc via ex";
9174
9175 case 0xd700000000000000ULL:
9176 /* special case XC */
9177 s390_irgen_EX_SS(r1, addr2, s390_irgen_XC_EX, 32);
9178 return "xc via ex";
9179
florianb0bf6602012-05-05 00:01:16 +00009180 case 0xd600000000000000ULL:
9181 /* special case OC */
9182 s390_irgen_EX_SS(r1, addr2, s390_irgen_OC_EX, 32);
9183 return "oc via ex";
9184
9185 case 0xd400000000000000ULL:
9186 /* special case NC */
9187 s390_irgen_EX_SS(r1, addr2, s390_irgen_NC_EX, 32);
9188 return "nc via ex";
sewardj2019a972011-03-07 16:04:07 +00009189
florianf87d4fb2012-05-05 02:55:24 +00009190 case 0xdc00000000000000ULL:
9191 /* special case TR */
9192 s390_irgen_EX_SS(r1, addr2, s390_irgen_TR_EX, 64);
9193 return "tr via ex";
9194
sewardj2019a972011-03-07 16:04:07 +00009195 default:
9196 {
9197 /* everything else will get a self checking prefix that also checks the
9198 register content */
9199 IRDirty *d;
9200 UChar *bytes;
9201 IRTemp cond;
9202 IRTemp orperand;
9203 IRTemp torun;
9204
9205 cond = newTemp(Ity_I1);
9206 orperand = newTemp(Ity_I64);
9207 torun = newTemp(Ity_I64);
9208
9209 if (r1 == 0)
9210 assign(orperand, mkU64(0));
9211 else
9212 assign(orperand, unop(Iop_8Uto64,get_gpr_b7(r1)));
9213 /* This code is going to be translated */
9214 assign(torun, binop(Iop_Or64, load(Ity_I64, mkexpr(addr2)),
9215 binop(Iop_Shl64, mkexpr(orperand), mkU8(48))));
9216
9217 /* Start with a check that saved code is still correct */
9218 assign(cond, binop(Iop_CmpNE64, mkexpr(torun),
9219 mkU64(last_execute_target)));
9220 /* If not, save the new value */
9221 d = unsafeIRDirty_0_N (0, "s390x_dirtyhelper_EX", &s390x_dirtyhelper_EX,
9222 mkIRExprVec_1(mkexpr(torun)));
9223 d->guard = mkexpr(cond);
9224 stmt(IRStmt_Dirty(d));
9225
9226 /* and restart */
florian428dfdd2012-03-27 03:09:49 +00009227 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TISTART), mkU64(guest_IA_curr_instr)));
9228 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TILEN), mkU64(4)));
florian6820ba52012-07-26 02:01:50 +00009229 restart_if(mkexpr(cond));
sewardj2019a972011-03-07 16:04:07 +00009230
9231 /* Now comes the actual translation */
9232 bytes = (UChar *) &last_execute_target;
9233 s390_decode_and_irgen(bytes, ((((bytes[0] >> 6) + 1) >> 1) + 1) << 1,
9234 dis_res);
sewardj7ee97522011-05-09 21:45:04 +00009235 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00009236 vex_printf(" which was executed by\n");
9237 /* dont make useless translations in the next execute */
9238 last_execute_target = 0;
9239 }
9240 }
9241 return "ex";
9242}
9243
9244static HChar *
9245s390_irgen_EXRL(UChar r1, UInt offset)
9246{
9247 IRTemp addr = newTemp(Ity_I64);
9248 /* we might save one round trip because we know the target */
9249 if (!last_execute_target)
9250 last_execute_target = *(ULong *)(HWord)
9251 (guest_IA_curr_instr + offset * 2UL);
9252 assign(addr, mkU64(guest_IA_curr_instr + offset * 2UL));
9253 s390_irgen_EX(r1, addr);
9254 return "exrl";
9255}
9256
9257static HChar *
9258s390_irgen_IPM(UChar r1)
9259{
9260 // As long as we dont support SPM, lets just assume 0 as program mask
9261 put_gpr_b4(r1, unop(Iop_32to8, binop(Iop_Or32, mkU32(0 /* program mask */),
9262 binop(Iop_Shl32, s390_call_calculate_cc(), mkU8(4)))));
9263
9264 return "ipm";
9265}
9266
9267
9268static HChar *
9269s390_irgen_SRST(UChar r1, UChar r2)
9270{
9271 IRTemp address = newTemp(Ity_I64);
9272 IRTemp next = newTemp(Ity_I64);
9273 IRTemp delim = newTemp(Ity_I8);
9274 IRTemp counter = newTemp(Ity_I64);
9275 IRTemp byte = newTemp(Ity_I8);
9276
9277 assign(address, get_gpr_dw0(r2));
9278 assign(next, get_gpr_dw0(r1));
9279
9280 assign(counter, get_counter_dw0());
9281 put_counter_dw0(mkU64(0));
9282
9283 // start = next? CC=2 and out r1 and r2 unchanged
9284 s390_cc_set(2);
9285 put_gpr_dw0(r2, binop(Iop_Sub64, mkexpr(address), mkexpr(counter)));
florian6820ba52012-07-26 02:01:50 +00009286 next_insn_if(binop(Iop_CmpEQ64, mkexpr(address), mkexpr(next)));
sewardj2019a972011-03-07 16:04:07 +00009287
9288 assign(byte, load(Ity_I8, mkexpr(address)));
9289 assign(delim, get_gpr_b7(0));
9290
9291 // byte = delim? CC=1, R1=address
9292 s390_cc_set(1);
9293 put_gpr_dw0(r1, mkexpr(address));
florian6820ba52012-07-26 02:01:50 +00009294 next_insn_if(binop(Iop_CmpEQ8, mkexpr(delim), mkexpr(byte)));
sewardj2019a972011-03-07 16:04:07 +00009295
9296 // else: all equal, no end yet, loop
9297 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
9298 put_gpr_dw0(r1, mkexpr(next));
9299 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(address), mkU64(1)));
floriancf87c942012-07-25 00:52:21 +00009300
florian6820ba52012-07-26 02:01:50 +00009301 iterate();
sewardj2019a972011-03-07 16:04:07 +00009302
9303 return "srst";
9304}
9305
9306static HChar *
9307s390_irgen_CLST(UChar r1, UChar r2)
9308{
9309 IRTemp address1 = newTemp(Ity_I64);
9310 IRTemp address2 = newTemp(Ity_I64);
9311 IRTemp end = newTemp(Ity_I8);
9312 IRTemp counter = newTemp(Ity_I64);
9313 IRTemp byte1 = newTemp(Ity_I8);
9314 IRTemp byte2 = newTemp(Ity_I8);
9315
9316 assign(address1, get_gpr_dw0(r1));
9317 assign(address2, get_gpr_dw0(r2));
9318 assign(end, get_gpr_b7(0));
9319 assign(counter, get_counter_dw0());
9320 put_counter_dw0(mkU64(0));
9321 assign(byte1, load(Ity_I8, mkexpr(address1)));
9322 assign(byte2, load(Ity_I8, mkexpr(address2)));
9323
9324 // end in both? all equal, reset r1 and r2 to start values
9325 s390_cc_set(0);
9326 put_gpr_dw0(r1, binop(Iop_Sub64, mkexpr(address1), mkexpr(counter)));
9327 put_gpr_dw0(r2, binop(Iop_Sub64, mkexpr(address2), mkexpr(counter)));
florian6820ba52012-07-26 02:01:50 +00009328 next_insn_if(binop(Iop_CmpEQ8, mkU8(0),
9329 binop(Iop_Or8,
9330 binop(Iop_Xor8, mkexpr(byte1), mkexpr(end)),
9331 binop(Iop_Xor8, mkexpr(byte2), mkexpr(end)))));
sewardj2019a972011-03-07 16:04:07 +00009332
9333 put_gpr_dw0(r1, mkexpr(address1));
9334 put_gpr_dw0(r2, mkexpr(address2));
9335
9336 // End found in string1
9337 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +00009338 next_insn_if(binop(Iop_CmpEQ8, mkexpr(end), mkexpr(byte1)));
sewardj2019a972011-03-07 16:04:07 +00009339
9340 // End found in string2
9341 s390_cc_set(2);
florian6820ba52012-07-26 02:01:50 +00009342 next_insn_if(binop(Iop_CmpEQ8, mkexpr(end), mkexpr(byte2)));
sewardj2019a972011-03-07 16:04:07 +00009343
9344 // string1 < string2
9345 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +00009346 next_insn_if(binop(Iop_CmpLT32U, unop(Iop_8Uto32, mkexpr(byte1)),
9347 unop(Iop_8Uto32, mkexpr(byte2))));
sewardj2019a972011-03-07 16:04:07 +00009348
9349 // string2 < string1
9350 s390_cc_set(2);
florian6820ba52012-07-26 02:01:50 +00009351 next_insn_if(binop(Iop_CmpLT32U, unop(Iop_8Uto32, mkexpr(byte2)),
9352 unop(Iop_8Uto32, mkexpr(byte1))));
sewardj2019a972011-03-07 16:04:07 +00009353
9354 // else: all equal, no end yet, loop
9355 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
9356 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), mkU64(1)));
9357 put_gpr_dw0(r2, binop(Iop_Add64, get_gpr_dw0(r2), mkU64(1)));
floriancf87c942012-07-25 00:52:21 +00009358
florian6820ba52012-07-26 02:01:50 +00009359 iterate();
sewardj2019a972011-03-07 16:04:07 +00009360
9361 return "clst";
9362}
9363
9364static void
9365s390_irgen_load_multiple_32bit(UChar r1, UChar r3, IRTemp op2addr)
9366{
9367 UChar reg;
9368 IRTemp addr = newTemp(Ity_I64);
9369
9370 assign(addr, mkexpr(op2addr));
9371 reg = r1;
9372 do {
9373 IRTemp old = addr;
9374
9375 reg %= 16;
9376 put_gpr_w1(reg, load(Ity_I32, mkexpr(addr)));
9377 addr = newTemp(Ity_I64);
9378 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
9379 reg++;
9380 } while (reg != (r3 + 1));
9381}
9382
9383static HChar *
9384s390_irgen_LM(UChar r1, UChar r3, IRTemp op2addr)
9385{
9386 s390_irgen_load_multiple_32bit(r1, r3, op2addr);
9387
9388 return "lm";
9389}
9390
9391static HChar *
9392s390_irgen_LMY(UChar r1, UChar r3, IRTemp op2addr)
9393{
9394 s390_irgen_load_multiple_32bit(r1, r3, op2addr);
9395
9396 return "lmy";
9397}
9398
9399static HChar *
9400s390_irgen_LMH(UChar r1, UChar r3, IRTemp op2addr)
9401{
9402 UChar reg;
9403 IRTemp addr = newTemp(Ity_I64);
9404
9405 assign(addr, mkexpr(op2addr));
9406 reg = r1;
9407 do {
9408 IRTemp old = addr;
9409
9410 reg %= 16;
9411 put_gpr_w0(reg, load(Ity_I32, mkexpr(addr)));
9412 addr = newTemp(Ity_I64);
9413 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
9414 reg++;
9415 } while (reg != (r3 + 1));
9416
9417 return "lmh";
9418}
9419
9420static HChar *
9421s390_irgen_LMG(UChar r1, UChar r3, IRTemp op2addr)
9422{
9423 UChar reg;
9424 IRTemp addr = newTemp(Ity_I64);
9425
9426 assign(addr, mkexpr(op2addr));
9427 reg = r1;
9428 do {
9429 IRTemp old = addr;
9430
9431 reg %= 16;
9432 put_gpr_dw0(reg, load(Ity_I64, mkexpr(addr)));
9433 addr = newTemp(Ity_I64);
9434 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(8)));
9435 reg++;
9436 } while (reg != (r3 + 1));
9437
9438 return "lmg";
9439}
9440
9441static void
9442s390_irgen_store_multiple_32bit(UChar r1, UChar r3, IRTemp op2addr)
9443{
9444 UChar reg;
9445 IRTemp addr = newTemp(Ity_I64);
9446
9447 assign(addr, mkexpr(op2addr));
9448 reg = r1;
9449 do {
9450 IRTemp old = addr;
9451
9452 reg %= 16;
9453 store(mkexpr(addr), get_gpr_w1(reg));
9454 addr = newTemp(Ity_I64);
9455 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
9456 reg++;
9457 } while( reg != (r3 + 1));
9458}
9459
9460static HChar *
9461s390_irgen_STM(UChar r1, UChar r3, IRTemp op2addr)
9462{
9463 s390_irgen_store_multiple_32bit(r1, r3, op2addr);
9464
9465 return "stm";
9466}
9467
9468static HChar *
9469s390_irgen_STMY(UChar r1, UChar r3, IRTemp op2addr)
9470{
9471 s390_irgen_store_multiple_32bit(r1, r3, op2addr);
9472
9473 return "stmy";
9474}
9475
9476static HChar *
9477s390_irgen_STMH(UChar r1, UChar r3, IRTemp op2addr)
9478{
9479 UChar reg;
9480 IRTemp addr = newTemp(Ity_I64);
9481
9482 assign(addr, mkexpr(op2addr));
9483 reg = r1;
9484 do {
9485 IRTemp old = addr;
9486
9487 reg %= 16;
9488 store(mkexpr(addr), get_gpr_w0(reg));
9489 addr = newTemp(Ity_I64);
9490 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
9491 reg++;
9492 } while( reg != (r3 + 1));
9493
9494 return "stmh";
9495}
9496
9497static HChar *
9498s390_irgen_STMG(UChar r1, UChar r3, IRTemp op2addr)
9499{
9500 UChar reg;
9501 IRTemp addr = newTemp(Ity_I64);
9502
9503 assign(addr, mkexpr(op2addr));
9504 reg = r1;
9505 do {
9506 IRTemp old = addr;
9507
9508 reg %= 16;
9509 store(mkexpr(addr), get_gpr_dw0(reg));
9510 addr = newTemp(Ity_I64);
9511 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(8)));
9512 reg++;
9513 } while( reg != (r3 + 1));
9514
9515 return "stmg";
9516}
9517
9518static void
florianb0bf6602012-05-05 00:01:16 +00009519s390_irgen_xonc(IROp op, IRTemp length, IRTemp start1, IRTemp start2)
sewardj2019a972011-03-07 16:04:07 +00009520{
9521 IRTemp old1 = newTemp(Ity_I8);
9522 IRTemp old2 = newTemp(Ity_I8);
9523 IRTemp new1 = newTemp(Ity_I8);
9524 IRTemp counter = newTemp(Ity_I32);
9525 IRTemp addr1 = newTemp(Ity_I64);
9526
9527 assign(counter, get_counter_w0());
9528
9529 assign(addr1, binop(Iop_Add64, mkexpr(start1),
9530 unop(Iop_32Uto64, mkexpr(counter))));
9531
9532 assign(old1, load(Ity_I8, mkexpr(addr1)));
9533 assign(old2, load(Ity_I8, binop(Iop_Add64, mkexpr(start2),
9534 unop(Iop_32Uto64,mkexpr(counter)))));
9535 assign(new1, binop(op, mkexpr(old1), mkexpr(old2)));
9536
9537 /* Special case: xc is used to zero memory */
sewardj2019a972011-03-07 16:04:07 +00009538 if (op == Iop_Xor8) {
9539 store(mkexpr(addr1),
florian6ad49522011-09-09 02:38:55 +00009540 mkite(binop(Iop_CmpEQ64, mkexpr(start1), mkexpr(start2)),
9541 mkU8(0), mkexpr(new1)));
sewardj2019a972011-03-07 16:04:07 +00009542 } else
9543 store(mkexpr(addr1), mkexpr(new1));
9544 put_counter_w1(binop(Iop_Or32, unop(Iop_8Uto32, mkexpr(new1)),
9545 get_counter_w1()));
9546
9547 /* Check for end of field */
9548 put_counter_w0(binop(Iop_Add32, mkexpr(counter), mkU32(1)));
florian6820ba52012-07-26 02:01:50 +00009549 iterate_if(binop(Iop_CmpNE32, mkexpr(counter), mkexpr(length)));
sewardj2019a972011-03-07 16:04:07 +00009550 s390_cc_thunk_put1(S390_CC_OP_BITWISE, mktemp(Ity_I32, get_counter_w1()),
9551 False);
9552 put_counter_dw0(mkU64(0));
9553}
9554
9555static HChar *
9556s390_irgen_XC(UChar length, IRTemp start1, IRTemp start2)
9557{
florianb0bf6602012-05-05 00:01:16 +00009558 IRTemp len = newTemp(Ity_I32);
9559
9560 assign(len, mkU32(length));
9561 s390_irgen_xonc(Iop_Xor8, len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +00009562
9563 return "xc";
9564}
9565
sewardjb63967e2011-03-24 08:50:04 +00009566static void
9567s390_irgen_XC_sameloc(UChar length, UChar b, UShort d)
9568{
9569 IRTemp counter = newTemp(Ity_I32);
9570 IRTemp start = newTemp(Ity_I64);
9571 IRTemp addr = newTemp(Ity_I64);
9572
9573 assign(start,
9574 binop(Iop_Add64, mkU64(d), b != 0 ? get_gpr_dw0(b) : mkU64(0)));
9575
9576 if (length < 8) {
9577 UInt i;
9578
9579 for (i = 0; i <= length; ++i) {
9580 store(binop(Iop_Add64, mkexpr(start), mkU64(i)), mkU8(0));
9581 }
9582 } else {
9583 assign(counter, get_counter_w0());
9584
9585 assign(addr, binop(Iop_Add64, mkexpr(start),
9586 unop(Iop_32Uto64, mkexpr(counter))));
9587
9588 store(mkexpr(addr), mkU8(0));
9589
9590 /* Check for end of field */
9591 put_counter_w0(binop(Iop_Add32, mkexpr(counter), mkU32(1)));
florian6820ba52012-07-26 02:01:50 +00009592 iterate_if(binop(Iop_CmpNE32, mkexpr(counter), mkU32(length)));
sewardjb63967e2011-03-24 08:50:04 +00009593
9594 /* Reset counter */
9595 put_counter_dw0(mkU64(0));
9596 }
9597
9598 s390_cc_thunk_put1(S390_CC_OP_BITWISE, mktemp(Ity_I32, mkU32(0)), False);
9599
sewardj7ee97522011-05-09 21:45:04 +00009600 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardjb63967e2011-03-24 08:50:04 +00009601 s390_disasm(ENC3(MNM, UDLB, UDXB), "xc", d, length, b, d, 0, b);
9602}
9603
sewardj2019a972011-03-07 16:04:07 +00009604static HChar *
9605s390_irgen_NC(UChar length, IRTemp start1, IRTemp start2)
9606{
florianb0bf6602012-05-05 00:01:16 +00009607 IRTemp len = newTemp(Ity_I32);
9608
9609 assign(len, mkU32(length));
9610 s390_irgen_xonc(Iop_And8, len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +00009611
9612 return "nc";
9613}
9614
9615static HChar *
9616s390_irgen_OC(UChar length, IRTemp start1, IRTemp start2)
9617{
florianb0bf6602012-05-05 00:01:16 +00009618 IRTemp len = newTemp(Ity_I32);
9619
9620 assign(len, mkU32(length));
9621 s390_irgen_xonc(Iop_Or8, len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +00009622
9623 return "oc";
9624}
9625
9626
9627static HChar *
9628s390_irgen_MVC(UChar length, IRTemp start1, IRTemp start2)
9629{
florian79e839e2012-05-05 02:20:30 +00009630 IRTemp len = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00009631
florian79e839e2012-05-05 02:20:30 +00009632 assign(len, mkU64(length));
9633 s390_irgen_MVC_EX(len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +00009634
9635 return "mvc";
9636}
9637
9638static HChar *
florianb0c9a132011-09-08 15:37:39 +00009639s390_irgen_MVCL(UChar r1, UChar r2)
9640{
9641 IRTemp addr1 = newTemp(Ity_I64);
9642 IRTemp addr2 = newTemp(Ity_I64);
9643 IRTemp addr2_load = newTemp(Ity_I64);
9644 IRTemp r1p1 = newTemp(Ity_I32); /* contents of r1 + 1 */
9645 IRTemp r2p1 = newTemp(Ity_I32); /* contents of r2 + 1 */
9646 IRTemp len1 = newTemp(Ity_I32);
9647 IRTemp len2 = newTemp(Ity_I32);
9648 IRTemp pad = newTemp(Ity_I8);
9649 IRTemp single = newTemp(Ity_I8);
9650
9651 assign(addr1, get_gpr_dw0(r1));
9652 assign(r1p1, get_gpr_w1(r1 + 1));
9653 assign(len1, binop(Iop_And32, mkexpr(r1p1), mkU32(0x00ffffff)));
9654 assign(addr2, get_gpr_dw0(r2));
9655 assign(r2p1, get_gpr_w1(r2 + 1));
9656 assign(len2, binop(Iop_And32, mkexpr(r2p1), mkU32(0x00ffffff)));
9657 assign(pad, get_gpr_b4(r2 + 1));
9658
9659 /* len1 == 0 ? */
9660 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len2, False);
florian6820ba52012-07-26 02:01:50 +00009661 next_insn_if(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)));
florianb0c9a132011-09-08 15:37:39 +00009662
9663 /* Check for destructive overlap:
9664 addr1 > addr2 && addr2 + len1 > addr1 && (addr2 + len2) > addr1 */
9665 s390_cc_set(3);
9666 IRTemp cond1 = newTemp(Ity_I32);
9667 assign(cond1, unop(Iop_1Uto32,
9668 binop(Iop_CmpLT64U, mkexpr(addr2), mkexpr(addr1))));
9669 IRTemp cond2 = newTemp(Ity_I32);
9670 assign(cond2, unop(Iop_1Uto32,
9671 binop(Iop_CmpLT64U, mkexpr(addr1),
9672 binop(Iop_Add64, mkexpr(addr2),
9673 unop(Iop_32Uto64, mkexpr(len1))))));
9674 IRTemp cond3 = newTemp(Ity_I32);
9675 assign(cond3, unop(Iop_1Uto32,
9676 binop(Iop_CmpLT64U,
9677 mkexpr(addr1),
9678 binop(Iop_Add64, mkexpr(addr2),
9679 unop(Iop_32Uto64, mkexpr(len2))))));
9680
florian6820ba52012-07-26 02:01:50 +00009681 next_insn_if(binop(Iop_CmpEQ32,
9682 binop(Iop_And32,
9683 binop(Iop_And32, mkexpr(cond1), mkexpr(cond2)),
9684 mkexpr(cond3)),
9685 mkU32(1)));
florianb0c9a132011-09-08 15:37:39 +00009686
9687 /* See s390_irgen_CLCL for explanation why we cannot load directly
9688 and need two steps. */
9689 assign(addr2_load,
9690 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
9691 mkU64(guest_IA_curr_instr), mkexpr(addr2)));
9692 assign(single,
9693 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
9694 mkexpr(pad), load(Ity_I8, mkexpr(addr2_load))));
9695
9696 store(mkexpr(addr1), mkexpr(single));
9697
9698 /* Update addr1 and len1 */
9699 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkU64(1)));
9700 put_gpr_w1(r1 + 1, binop(Iop_Sub32, mkexpr(r1p1), mkU32(1)));
9701
9702 /* Update addr2 and len2 */
9703 put_gpr_dw0(r2,
9704 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
9705 mkexpr(addr2),
9706 binop(Iop_Add64, mkexpr(addr2), mkU64(1))));
9707
9708 /* When updating len2 we must not modify bits (r2+1)[0:39] */
9709 put_gpr_w1(r2 + 1,
9710 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
9711 binop(Iop_And32, mkexpr(r2p1), mkU32(0xFF000000u)),
9712 binop(Iop_Sub32, mkexpr(r2p1), mkU32(1))));
9713
9714 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len2, False);
florian6820ba52012-07-26 02:01:50 +00009715 iterate_if(binop(Iop_CmpNE32, mkexpr(len1), mkU32(1)));
florianb0c9a132011-09-08 15:37:39 +00009716
9717 return "mvcl";
9718}
9719
9720
9721static HChar *
sewardj2019a972011-03-07 16:04:07 +00009722s390_irgen_MVCLE(UChar r1, UChar r3, IRTemp pad2)
9723{
9724 IRTemp addr1, addr3, addr3_load, len1, len3, single;
9725
9726 addr1 = newTemp(Ity_I64);
9727 addr3 = newTemp(Ity_I64);
9728 addr3_load = newTemp(Ity_I64);
9729 len1 = newTemp(Ity_I64);
9730 len3 = newTemp(Ity_I64);
9731 single = newTemp(Ity_I8);
9732
9733 assign(addr1, get_gpr_dw0(r1));
9734 assign(len1, get_gpr_dw0(r1 + 1));
9735 assign(addr3, get_gpr_dw0(r3));
9736 assign(len3, get_gpr_dw0(r3 + 1));
9737
9738 // len1 == 0 ?
9739 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len3, False);
florian6820ba52012-07-26 02:01:50 +00009740 next_insn_if(binop(Iop_CmpEQ64,mkexpr(len1), mkU64(0)));
sewardj2019a972011-03-07 16:04:07 +00009741
9742 /* This is a hack to prevent mvcle from reading from addr3 if it
9743 should read from the pad. Since the pad has no address, just
9744 read from the instruction, we discard that anyway */
9745 assign(addr3_load,
florian6ad49522011-09-09 02:38:55 +00009746 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
9747 mkU64(guest_IA_curr_instr), mkexpr(addr3)));
sewardj2019a972011-03-07 16:04:07 +00009748
9749 assign(single,
florian6ad49522011-09-09 02:38:55 +00009750 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
9751 unop(Iop_64to8, mkexpr(pad2)),
9752 load(Ity_I8, mkexpr(addr3_load))));
sewardj2019a972011-03-07 16:04:07 +00009753 store(mkexpr(addr1), mkexpr(single));
9754
9755 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkU64(1)));
9756
9757 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkU64(1)));
9758
9759 put_gpr_dw0(r3,
florian6ad49522011-09-09 02:38:55 +00009760 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
9761 mkexpr(addr3),
9762 binop(Iop_Add64, mkexpr(addr3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +00009763
9764 put_gpr_dw0(r3 + 1,
florian6ad49522011-09-09 02:38:55 +00009765 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
9766 mkU64(0), binop(Iop_Sub64, mkexpr(len3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +00009767
sewardj2019a972011-03-07 16:04:07 +00009768 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len3, False);
florian6820ba52012-07-26 02:01:50 +00009769 iterate_if(binop(Iop_CmpNE64, mkexpr(len1), mkU64(1)));
sewardj2019a972011-03-07 16:04:07 +00009770
9771 return "mvcle";
9772}
9773
9774static HChar *
9775s390_irgen_MVST(UChar r1, UChar r2)
9776{
9777 IRTemp addr1 = newTemp(Ity_I64);
9778 IRTemp addr2 = newTemp(Ity_I64);
9779 IRTemp end = newTemp(Ity_I8);
9780 IRTemp byte = newTemp(Ity_I8);
9781 IRTemp counter = newTemp(Ity_I64);
9782
9783 assign(addr1, get_gpr_dw0(r1));
9784 assign(addr2, get_gpr_dw0(r2));
9785 assign(counter, get_counter_dw0());
9786 assign(end, get_gpr_b7(0));
9787 assign(byte, load(Ity_I8, binop(Iop_Add64, mkexpr(addr2),mkexpr(counter))));
9788 store(binop(Iop_Add64,mkexpr(addr1),mkexpr(counter)), mkexpr(byte));
9789
9790 // We use unlimited as cpu-determined number
9791 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
florian6820ba52012-07-26 02:01:50 +00009792 iterate_if(binop(Iop_CmpNE8, mkexpr(end), mkexpr(byte)));
sewardj2019a972011-03-07 16:04:07 +00009793
9794 // and always set cc=1 at the end + update r1
9795 s390_cc_set(1);
9796 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(counter)));
9797 put_counter_dw0(mkU64(0));
9798
9799 return "mvst";
9800}
9801
9802static void
9803s390_irgen_divide_64to32(IROp op, UChar r1, IRTemp op2)
9804{
9805 IRTemp op1 = newTemp(Ity_I64);
9806 IRTemp result = newTemp(Ity_I64);
9807
9808 assign(op1, binop(Iop_32HLto64,
9809 get_gpr_w1(r1), // high 32 bits
9810 get_gpr_w1(r1 + 1))); // low 32 bits
9811 assign(result, binop(op, mkexpr(op1), mkexpr(op2)));
9812 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result))); // remainder
9813 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result))); // quotient
9814}
9815
9816static void
9817s390_irgen_divide_128to64(IROp op, UChar r1, IRTemp op2)
9818{
9819 IRTemp op1 = newTemp(Ity_I128);
9820 IRTemp result = newTemp(Ity_I128);
9821
9822 assign(op1, binop(Iop_64HLto128,
9823 get_gpr_dw0(r1), // high 64 bits
9824 get_gpr_dw0(r1 + 1))); // low 64 bits
9825 assign(result, binop(op, mkexpr(op1), mkexpr(op2)));
9826 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result))); // remainder
9827 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result))); // quotient
9828}
9829
9830static void
9831s390_irgen_divide_64to64(IROp op, UChar r1, IRTemp op2)
9832{
9833 IRTemp op1 = newTemp(Ity_I64);
9834 IRTemp result = newTemp(Ity_I128);
9835
9836 assign(op1, get_gpr_dw0(r1 + 1));
9837 assign(result, binop(op, mkexpr(op1), mkexpr(op2)));
9838 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result))); // remainder
9839 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result))); // quotient
9840}
9841
9842static HChar *
9843s390_irgen_DR(UChar r1, UChar r2)
9844{
9845 IRTemp op2 = newTemp(Ity_I32);
9846
9847 assign(op2, get_gpr_w1(r2));
9848
9849 s390_irgen_divide_64to32(Iop_DivModS64to32, r1, op2);
9850
9851 return "dr";
9852}
9853
9854static HChar *
9855s390_irgen_D(UChar r1, IRTemp op2addr)
9856{
9857 IRTemp op2 = newTemp(Ity_I32);
9858
9859 assign(op2, load(Ity_I32, mkexpr(op2addr)));
9860
9861 s390_irgen_divide_64to32(Iop_DivModS64to32, r1, op2);
9862
9863 return "d";
9864}
9865
9866static HChar *
9867s390_irgen_DLR(UChar r1, UChar r2)
9868{
9869 IRTemp op2 = newTemp(Ity_I32);
9870
9871 assign(op2, get_gpr_w1(r2));
9872
9873 s390_irgen_divide_64to32(Iop_DivModU64to32, r1, op2);
9874
florian7cd1cde2012-08-16 23:57:43 +00009875 return "dlr";
sewardj2019a972011-03-07 16:04:07 +00009876}
9877
9878static HChar *
9879s390_irgen_DL(UChar r1, IRTemp op2addr)
9880{
9881 IRTemp op2 = newTemp(Ity_I32);
9882
9883 assign(op2, load(Ity_I32, mkexpr(op2addr)));
9884
9885 s390_irgen_divide_64to32(Iop_DivModU64to32, r1, op2);
9886
9887 return "dl";
9888}
9889
9890static HChar *
9891s390_irgen_DLG(UChar r1, IRTemp op2addr)
9892{
9893 IRTemp op2 = newTemp(Ity_I64);
9894
9895 assign(op2, load(Ity_I64, mkexpr(op2addr)));
9896
9897 s390_irgen_divide_128to64(Iop_DivModU128to64, r1, op2);
9898
9899 return "dlg";
9900}
9901
9902static HChar *
9903s390_irgen_DLGR(UChar r1, UChar r2)
9904{
9905 IRTemp op2 = newTemp(Ity_I64);
9906
9907 assign(op2, get_gpr_dw0(r2));
9908
9909 s390_irgen_divide_128to64(Iop_DivModU128to64, r1, op2);
9910
9911 return "dlgr";
9912}
9913
9914static HChar *
9915s390_irgen_DSGR(UChar r1, UChar r2)
9916{
9917 IRTemp op2 = newTemp(Ity_I64);
9918
9919 assign(op2, get_gpr_dw0(r2));
9920
9921 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
9922
9923 return "dsgr";
9924}
9925
9926static HChar *
9927s390_irgen_DSG(UChar r1, IRTemp op2addr)
9928{
9929 IRTemp op2 = newTemp(Ity_I64);
9930
9931 assign(op2, load(Ity_I64, mkexpr(op2addr)));
9932
9933 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
9934
9935 return "dsg";
9936}
9937
9938static HChar *
9939s390_irgen_DSGFR(UChar r1, UChar r2)
9940{
9941 IRTemp op2 = newTemp(Ity_I64);
9942
9943 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
9944
9945 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
9946
9947 return "dsgfr";
9948}
9949
9950static HChar *
9951s390_irgen_DSGF(UChar r1, IRTemp op2addr)
9952{
9953 IRTemp op2 = newTemp(Ity_I64);
9954
9955 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
9956
9957 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
9958
9959 return "dsgf";
9960}
9961
9962static void
9963s390_irgen_load_ar_multiple(UChar r1, UChar r3, IRTemp op2addr)
9964{
9965 UChar reg;
9966 IRTemp addr = newTemp(Ity_I64);
9967
9968 assign(addr, mkexpr(op2addr));
9969 reg = r1;
9970 do {
9971 IRTemp old = addr;
9972
9973 reg %= 16;
9974 put_ar_w0(reg, load(Ity_I32, mkexpr(addr)));
9975 addr = newTemp(Ity_I64);
9976 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
9977 reg++;
9978 } while (reg != (r3 + 1));
9979}
9980
9981static HChar *
9982s390_irgen_LAM(UChar r1, UChar r3, IRTemp op2addr)
9983{
9984 s390_irgen_load_ar_multiple(r1, r3, op2addr);
9985
9986 return "lam";
9987}
9988
9989static HChar *
9990s390_irgen_LAMY(UChar r1, UChar r3, IRTemp op2addr)
9991{
9992 s390_irgen_load_ar_multiple(r1, r3, op2addr);
9993
9994 return "lamy";
9995}
9996
9997static void
9998s390_irgen_store_ar_multiple(UChar r1, UChar r3, IRTemp op2addr)
9999{
10000 UChar reg;
10001 IRTemp addr = newTemp(Ity_I64);
10002
10003 assign(addr, mkexpr(op2addr));
10004 reg = r1;
10005 do {
10006 IRTemp old = addr;
10007
10008 reg %= 16;
10009 store(mkexpr(addr), get_ar_w0(reg));
10010 addr = newTemp(Ity_I64);
10011 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
10012 reg++;
10013 } while (reg != (r3 + 1));
10014}
10015
10016static HChar *
10017s390_irgen_STAM(UChar r1, UChar r3, IRTemp op2addr)
10018{
10019 s390_irgen_store_ar_multiple(r1, r3, op2addr);
10020
10021 return "stam";
10022}
10023
10024static HChar *
10025s390_irgen_STAMY(UChar r1, UChar r3, IRTemp op2addr)
10026{
10027 s390_irgen_store_ar_multiple(r1, r3, op2addr);
10028
10029 return "stamy";
10030}
10031
10032
10033/* Implementation for 32-bit compare-and-swap */
10034static void
10035s390_irgen_cas_32(UChar r1, UChar r3, IRTemp op2addr)
10036{
10037 IRCAS *cas;
10038 IRTemp op1 = newTemp(Ity_I32);
10039 IRTemp old_mem = newTemp(Ity_I32);
10040 IRTemp op3 = newTemp(Ity_I32);
10041 IRTemp result = newTemp(Ity_I32);
10042 IRTemp nequal = newTemp(Ity_I1);
10043
10044 assign(op1, get_gpr_w1(r1));
10045 assign(op3, get_gpr_w1(r3));
10046
10047 /* The first and second operands are compared. If they are equal,
10048 the third operand is stored at the second- operand location. */
10049 cas = mkIRCAS(IRTemp_INVALID, old_mem,
10050 Iend_BE, mkexpr(op2addr),
10051 NULL, mkexpr(op1), /* expected value */
10052 NULL, mkexpr(op3) /* new value */);
10053 stmt(IRStmt_CAS(cas));
10054
10055 /* Set CC. Operands compared equal -> 0, else 1. */
10056 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(old_mem)));
10057 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
10058
10059 /* If operands were equal (cc == 0) just store the old value op1 in r1.
10060 Otherwise, store the old_value from memory in r1 and yield. */
10061 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
10062 put_gpr_w1(r1, mkite(mkexpr(nequal), mkexpr(old_mem), mkexpr(op1)));
florian6820ba52012-07-26 02:01:50 +000010063 yield_if(mkexpr(nequal));
sewardj2019a972011-03-07 16:04:07 +000010064}
10065
10066static HChar *
10067s390_irgen_CS(UChar r1, UChar r3, IRTemp op2addr)
10068{
10069 s390_irgen_cas_32(r1, r3, op2addr);
10070
10071 return "cs";
10072}
10073
10074static HChar *
10075s390_irgen_CSY(UChar r1, UChar r3, IRTemp op2addr)
10076{
10077 s390_irgen_cas_32(r1, r3, op2addr);
10078
10079 return "csy";
10080}
10081
10082static HChar *
10083s390_irgen_CSG(UChar r1, UChar r3, IRTemp op2addr)
10084{
10085 IRCAS *cas;
10086 IRTemp op1 = newTemp(Ity_I64);
10087 IRTemp old_mem = newTemp(Ity_I64);
10088 IRTemp op3 = newTemp(Ity_I64);
10089 IRTemp result = newTemp(Ity_I64);
10090 IRTemp nequal = newTemp(Ity_I1);
10091
10092 assign(op1, get_gpr_dw0(r1));
10093 assign(op3, get_gpr_dw0(r3));
10094
10095 /* The first and second operands are compared. If they are equal,
10096 the third operand is stored at the second- operand location. */
10097 cas = mkIRCAS(IRTemp_INVALID, old_mem,
10098 Iend_BE, mkexpr(op2addr),
10099 NULL, mkexpr(op1), /* expected value */
10100 NULL, mkexpr(op3) /* new value */);
10101 stmt(IRStmt_CAS(cas));
10102
10103 /* Set CC. Operands compared equal -> 0, else 1. */
10104 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(old_mem)));
10105 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
10106
10107 /* If operands were equal (cc == 0) just store the old value op1 in r1.
10108 Otherwise, store the old_value from memory in r1 and yield. */
10109 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
10110 put_gpr_dw0(r1, mkite(mkexpr(nequal), mkexpr(old_mem), mkexpr(op1)));
florian6820ba52012-07-26 02:01:50 +000010111 yield_if(mkexpr(nequal));
sewardj2019a972011-03-07 16:04:07 +000010112
10113 return "csg";
10114}
10115
florian448cbba2012-06-06 02:26:01 +000010116/* Implementation for 32-bit compare-double-and-swap */
10117static void
10118s390_irgen_cdas_32(UChar r1, UChar r3, IRTemp op2addr)
10119{
10120 IRCAS *cas;
10121 IRTemp op1_high = newTemp(Ity_I32);
10122 IRTemp op1_low = newTemp(Ity_I32);
10123 IRTemp old_mem_high = newTemp(Ity_I32);
10124 IRTemp old_mem_low = newTemp(Ity_I32);
10125 IRTemp op3_high = newTemp(Ity_I32);
10126 IRTemp op3_low = newTemp(Ity_I32);
10127 IRTemp result = newTemp(Ity_I32);
10128 IRTemp nequal = newTemp(Ity_I1);
10129
10130 assign(op1_high, get_gpr_w1(r1));
10131 assign(op1_low, get_gpr_w1(r1+1));
10132 assign(op3_high, get_gpr_w1(r3));
10133 assign(op3_low, get_gpr_w1(r3+1));
10134
10135 /* The first and second operands are compared. If they are equal,
10136 the third operand is stored at the second-operand location. */
10137 cas = mkIRCAS(old_mem_high, old_mem_low,
10138 Iend_BE, mkexpr(op2addr),
10139 mkexpr(op1_high), mkexpr(op1_low), /* expected value */
10140 mkexpr(op3_high), mkexpr(op3_low) /* new value */);
10141 stmt(IRStmt_CAS(cas));
10142
10143 /* Set CC. Operands compared equal -> 0, else 1. */
10144 assign(result, unop(Iop_1Uto32,
10145 binop(Iop_CmpNE32,
10146 binop(Iop_Or32,
10147 binop(Iop_Xor32, mkexpr(op1_high), mkexpr(old_mem_high)),
10148 binop(Iop_Xor32, mkexpr(op1_low), mkexpr(old_mem_low))),
10149 mkU32(0))));
10150
10151 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
10152
10153 /* If operands were equal (cc == 0) just store the old value op1 in r1.
10154 Otherwise, store the old_value from memory in r1 and yield. */
10155 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
10156 put_gpr_w1(r1, mkite(mkexpr(nequal), mkexpr(old_mem_high), mkexpr(op1_high)));
10157 put_gpr_w1(r1+1, mkite(mkexpr(nequal), mkexpr(old_mem_low), mkexpr(op1_low)));
florian6820ba52012-07-26 02:01:50 +000010158 yield_if(mkexpr(nequal));
florian448cbba2012-06-06 02:26:01 +000010159}
10160
10161static HChar *
10162s390_irgen_CDS(UChar r1, UChar r3, IRTemp op2addr)
10163{
10164 s390_irgen_cdas_32(r1, r3, op2addr);
10165
10166 return "cds";
10167}
10168
10169static HChar *
10170s390_irgen_CDSY(UChar r1, UChar r3, IRTemp op2addr)
10171{
10172 s390_irgen_cdas_32(r1, r3, op2addr);
10173
10174 return "cdsy";
10175}
10176
10177static HChar *
10178s390_irgen_CDSG(UChar r1, UChar r3, IRTemp op2addr)
10179{
10180 IRCAS *cas;
10181 IRTemp op1_high = newTemp(Ity_I64);
10182 IRTemp op1_low = newTemp(Ity_I64);
10183 IRTemp old_mem_high = newTemp(Ity_I64);
10184 IRTemp old_mem_low = newTemp(Ity_I64);
10185 IRTemp op3_high = newTemp(Ity_I64);
10186 IRTemp op3_low = newTemp(Ity_I64);
10187 IRTemp result = newTemp(Ity_I64);
10188 IRTemp nequal = newTemp(Ity_I1);
10189
10190 assign(op1_high, get_gpr_dw0(r1));
10191 assign(op1_low, get_gpr_dw0(r1+1));
10192 assign(op3_high, get_gpr_dw0(r3));
10193 assign(op3_low, get_gpr_dw0(r3+1));
10194
10195 /* The first and second operands are compared. If they are equal,
10196 the third operand is stored at the second-operand location. */
10197 cas = mkIRCAS(old_mem_high, old_mem_low,
10198 Iend_BE, mkexpr(op2addr),
10199 mkexpr(op1_high), mkexpr(op1_low), /* expected value */
10200 mkexpr(op3_high), mkexpr(op3_low) /* new value */);
10201 stmt(IRStmt_CAS(cas));
10202
10203 /* Set CC. Operands compared equal -> 0, else 1. */
10204 assign(result, unop(Iop_1Uto64,
10205 binop(Iop_CmpNE64,
10206 binop(Iop_Or64,
10207 binop(Iop_Xor64, mkexpr(op1_high), mkexpr(old_mem_high)),
10208 binop(Iop_Xor64, mkexpr(op1_low), mkexpr(old_mem_low))),
10209 mkU64(0))));
10210
10211 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
10212
10213 /* If operands were equal (cc == 0) just store the old value op1 in r1.
10214 Otherwise, store the old_value from memory in r1 and yield. */
10215 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
10216 put_gpr_dw0(r1, mkite(mkexpr(nequal), mkexpr(old_mem_high), mkexpr(op1_high)));
10217 put_gpr_dw0(r1+1, mkite(mkexpr(nequal), mkexpr(old_mem_low), mkexpr(op1_low)));
florian6820ba52012-07-26 02:01:50 +000010218 yield_if(mkexpr(nequal));
10219
florian448cbba2012-06-06 02:26:01 +000010220 return "cdsg";
10221}
10222
sewardj2019a972011-03-07 16:04:07 +000010223
10224/* Binary floating point */
10225
10226static HChar *
10227s390_irgen_AXBR(UChar r1, UChar r2)
10228{
10229 IRTemp op1 = newTemp(Ity_F128);
10230 IRTemp op2 = newTemp(Ity_F128);
10231 IRTemp result = newTemp(Ity_F128);
floriandb4fcaa2012-09-05 19:54:08 +000010232 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000010233
10234 assign(op1, get_fpr_pair(r1));
10235 assign(op2, get_fpr_pair(r2));
floriandb4fcaa2012-09-05 19:54:08 +000010236 assign(result, triop(Iop_AddF128, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +000010237 mkexpr(op2)));
10238 put_fpr_pair(r1, mkexpr(result));
10239
10240 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
10241
10242 return "axbr";
10243}
10244
10245/* The result of a Iop_CmdFxx operation is a condition code. It is
10246 encoded using the values defined in type IRCmpFxxResult.
10247 Before we can store the condition code into the guest state (or do
10248 anything else with it for that matter) we need to convert it to
10249 the encoding that s390 uses. This is what this function does.
10250
10251 s390 VEX b6 b2 b0 cc.1 cc.0
10252 0 0x40 EQ 1 0 0 0 0
10253 1 0x01 LT 0 0 1 0 1
10254 2 0x00 GT 0 0 0 1 0
10255 3 0x45 Unordered 1 1 1 1 1
10256
10257 The following bits from the VEX encoding are interesting:
10258 b0, b2, b6 with b0 being the LSB. We observe:
10259
10260 cc.0 = b0;
10261 cc.1 = b2 | (~b0 & ~b6)
10262
10263 with cc being the s390 condition code.
10264*/
10265static IRExpr *
10266convert_vex_fpcc_to_s390(IRTemp vex_cc)
10267{
10268 IRTemp cc0 = newTemp(Ity_I32);
10269 IRTemp cc1 = newTemp(Ity_I32);
10270 IRTemp b0 = newTemp(Ity_I32);
10271 IRTemp b2 = newTemp(Ity_I32);
10272 IRTemp b6 = newTemp(Ity_I32);
10273
10274 assign(b0, binop(Iop_And32, mkexpr(vex_cc), mkU32(1)));
10275 assign(b2, binop(Iop_And32, binop(Iop_Shr32, mkexpr(vex_cc), mkU8(2)),
10276 mkU32(1)));
10277 assign(b6, binop(Iop_And32, binop(Iop_Shr32, mkexpr(vex_cc), mkU8(6)),
10278 mkU32(1)));
10279
10280 assign(cc0, mkexpr(b0));
10281 assign(cc1, binop(Iop_Or32, mkexpr(b2),
10282 binop(Iop_And32,
10283 binop(Iop_Sub32, mkU32(1), mkexpr(b0)), /* ~b0 */
10284 binop(Iop_Sub32, mkU32(1), mkexpr(b6)) /* ~b6 */
10285 )));
10286
10287 return binop(Iop_Or32, mkexpr(cc0), binop(Iop_Shl32, mkexpr(cc1), mkU8(1)));
10288}
10289
10290static HChar *
10291s390_irgen_CEBR(UChar r1, UChar r2)
10292{
10293 IRTemp op1 = newTemp(Ity_F32);
10294 IRTemp op2 = newTemp(Ity_F32);
10295 IRTemp cc_vex = newTemp(Ity_I32);
10296 IRTemp cc_s390 = newTemp(Ity_I32);
10297
10298 assign(op1, get_fpr_w0(r1));
10299 assign(op2, get_fpr_w0(r2));
10300 assign(cc_vex, binop(Iop_CmpF32, mkexpr(op1), mkexpr(op2)));
10301
10302 assign(cc_s390, convert_vex_fpcc_to_s390(cc_vex));
10303 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
10304
10305 return "cebr";
10306}
10307
10308static HChar *
10309s390_irgen_CDBR(UChar r1, UChar r2)
10310{
10311 IRTemp op1 = newTemp(Ity_F64);
10312 IRTemp op2 = newTemp(Ity_F64);
10313 IRTemp cc_vex = newTemp(Ity_I32);
10314 IRTemp cc_s390 = newTemp(Ity_I32);
10315
10316 assign(op1, get_fpr_dw0(r1));
10317 assign(op2, get_fpr_dw0(r2));
10318 assign(cc_vex, binop(Iop_CmpF64, mkexpr(op1), mkexpr(op2)));
10319
10320 assign(cc_s390, convert_vex_fpcc_to_s390(cc_vex));
10321 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
10322
10323 return "cdbr";
10324}
10325
10326static HChar *
10327s390_irgen_CXBR(UChar r1, UChar r2)
10328{
10329 IRTemp op1 = newTemp(Ity_F128);
10330 IRTemp op2 = newTemp(Ity_F128);
10331 IRTemp cc_vex = newTemp(Ity_I32);
10332 IRTemp cc_s390 = newTemp(Ity_I32);
10333
10334 assign(op1, get_fpr_pair(r1));
10335 assign(op2, get_fpr_pair(r2));
10336 assign(cc_vex, binop(Iop_CmpF128, mkexpr(op1), mkexpr(op2)));
10337
10338 assign(cc_s390, convert_vex_fpcc_to_s390(cc_vex));
10339 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
10340
10341 return "cxbr";
10342}
10343
10344static HChar *
10345s390_irgen_CEB(UChar r1, IRTemp op2addr)
10346{
10347 IRTemp op1 = newTemp(Ity_F32);
10348 IRTemp op2 = newTemp(Ity_F32);
10349 IRTemp cc_vex = newTemp(Ity_I32);
10350 IRTemp cc_s390 = newTemp(Ity_I32);
10351
10352 assign(op1, get_fpr_w0(r1));
10353 assign(op2, load(Ity_F32, mkexpr(op2addr)));
10354 assign(cc_vex, binop(Iop_CmpF32, mkexpr(op1), mkexpr(op2)));
10355
10356 assign(cc_s390, convert_vex_fpcc_to_s390(cc_vex));
10357 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
10358
10359 return "ceb";
10360}
10361
10362static HChar *
10363s390_irgen_CDB(UChar r1, IRTemp op2addr)
10364{
10365 IRTemp op1 = newTemp(Ity_F64);
10366 IRTemp op2 = newTemp(Ity_F64);
10367 IRTemp cc_vex = newTemp(Ity_I32);
10368 IRTemp cc_s390 = newTemp(Ity_I32);
10369
10370 assign(op1, get_fpr_dw0(r1));
10371 assign(op2, load(Ity_F64, mkexpr(op2addr)));
10372 assign(cc_vex, binop(Iop_CmpF64, mkexpr(op1), mkexpr(op2)));
10373
10374 assign(cc_s390, convert_vex_fpcc_to_s390(cc_vex));
10375 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
10376
10377 return "cdb";
10378}
10379
10380static HChar *
florian4b8efad2012-09-02 18:07:08 +000010381s390_irgen_CXFBR(UChar m3 __attribute__((unused)),
10382 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000010383{
10384 IRTemp op2 = newTemp(Ity_I32);
10385
10386 assign(op2, get_gpr_w1(r2));
10387 put_fpr_pair(r1, unop(Iop_I32StoF128, mkexpr(op2)));
10388
10389 return "cxfbr";
10390}
10391
10392static HChar *
floriand2129202012-09-01 20:01:39 +000010393s390_irgen_CXLFBR(UChar m3 __attribute__((unused)),
10394 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
florian1c8f7ff2012-09-01 00:12:11 +000010395{
floriane75dafa2012-09-01 17:54:09 +000010396 if (! s390_host_has_fpext) {
10397 emulation_failure(EmFail_S390X_fpext);
10398 } else {
10399 IRTemp op2 = newTemp(Ity_I32);
florian1c8f7ff2012-09-01 00:12:11 +000010400
floriane75dafa2012-09-01 17:54:09 +000010401 assign(op2, get_gpr_w1(r2));
10402 put_fpr_pair(r1, unop(Iop_I32UtoF128, mkexpr(op2)));
10403 }
florian1c8f7ff2012-09-01 00:12:11 +000010404 return "cxlfbr";
10405}
10406
10407
10408static HChar *
florian4b8efad2012-09-02 18:07:08 +000010409s390_irgen_CXGBR(UChar m3 __attribute__((unused)),
10410 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000010411{
10412 IRTemp op2 = newTemp(Ity_I64);
10413
10414 assign(op2, get_gpr_dw0(r2));
10415 put_fpr_pair(r1, unop(Iop_I64StoF128, mkexpr(op2)));
10416
10417 return "cxgbr";
10418}
10419
10420static HChar *
floriand2129202012-09-01 20:01:39 +000010421s390_irgen_CXLGBR(UChar m3 __attribute__((unused)),
10422 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
florian1c8f7ff2012-09-01 00:12:11 +000010423{
floriane75dafa2012-09-01 17:54:09 +000010424 if (! s390_host_has_fpext) {
10425 emulation_failure(EmFail_S390X_fpext);
10426 } else {
10427 IRTemp op2 = newTemp(Ity_I64);
florian1c8f7ff2012-09-01 00:12:11 +000010428
floriane75dafa2012-09-01 17:54:09 +000010429 assign(op2, get_gpr_dw0(r2));
10430 put_fpr_pair(r1, unop(Iop_I64UtoF128, mkexpr(op2)));
10431 }
florian1c8f7ff2012-09-01 00:12:11 +000010432 return "cxlgbr";
10433}
10434
10435static HChar *
florian4b8efad2012-09-02 18:07:08 +000010436s390_irgen_CFXBR(UChar m3, UChar m4 __attribute__((unused)),
10437 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000010438{
10439 IRTemp op = newTemp(Ity_F128);
10440 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +000010441 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +000010442
10443 assign(op, get_fpr_pair(r2));
florian19e00772012-09-06 03:13:22 +000010444 assign(result, binop(Iop_F128toI32S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +000010445 mkexpr(op)));
10446 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +000010447 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_INT_32, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +000010448
10449 return "cfxbr";
10450}
10451
10452static HChar *
florian1c8f7ff2012-09-01 00:12:11 +000010453s390_irgen_CLFXBR(UChar m3, UChar m4 __attribute__((unused)),
10454 UChar r1, UChar r2)
10455{
floriane75dafa2012-09-01 17:54:09 +000010456 if (! s390_host_has_fpext) {
10457 emulation_failure(EmFail_S390X_fpext);
10458 } else {
10459 IRTemp op = newTemp(Ity_F128);
10460 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +000010461 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +000010462
floriane75dafa2012-09-01 17:54:09 +000010463 assign(op, get_fpr_pair(r2));
florian19e00772012-09-06 03:13:22 +000010464 assign(result, binop(Iop_F128toI32U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +000010465 mkexpr(op)));
10466 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +000010467 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_UINT_32, op, rounding_mode);
floriane75dafa2012-09-01 17:54:09 +000010468 }
florian1c8f7ff2012-09-01 00:12:11 +000010469 return "clfxbr";
10470}
10471
10472
10473static HChar *
florian4b8efad2012-09-02 18:07:08 +000010474s390_irgen_CGXBR(UChar m3, UChar m4 __attribute__((unused)),
10475 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000010476{
10477 IRTemp op = newTemp(Ity_F128);
10478 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +000010479 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +000010480
10481 assign(op, get_fpr_pair(r2));
florian19e00772012-09-06 03:13:22 +000010482 assign(result, binop(Iop_F128toI64S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +000010483 mkexpr(op)));
10484 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +000010485 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_INT_64, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +000010486
10487 return "cgxbr";
10488}
10489
10490static HChar *
florian1c8f7ff2012-09-01 00:12:11 +000010491s390_irgen_CLGXBR(UChar m3, UChar m4 __attribute__((unused)),
10492 UChar r1, UChar r2)
10493{
floriane75dafa2012-09-01 17:54:09 +000010494 if (! s390_host_has_fpext) {
10495 emulation_failure(EmFail_S390X_fpext);
10496 } else {
10497 IRTemp op = newTemp(Ity_F128);
10498 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +000010499 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +000010500
floriane75dafa2012-09-01 17:54:09 +000010501 assign(op, get_fpr_pair(r2));
florian19e00772012-09-06 03:13:22 +000010502 assign(result, binop(Iop_F128toI64U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +000010503 mkexpr(op)));
10504 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +000010505 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_UINT_64, op,
10506 rounding_mode);
floriane75dafa2012-09-01 17:54:09 +000010507 }
florian1c8f7ff2012-09-01 00:12:11 +000010508 return "clgxbr";
10509}
10510
10511static HChar *
sewardj2019a972011-03-07 16:04:07 +000010512s390_irgen_DXBR(UChar r1, UChar r2)
10513{
10514 IRTemp op1 = newTemp(Ity_F128);
10515 IRTemp op2 = newTemp(Ity_F128);
10516 IRTemp result = newTemp(Ity_F128);
floriandb4fcaa2012-09-05 19:54:08 +000010517 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000010518
10519 assign(op1, get_fpr_pair(r1));
10520 assign(op2, get_fpr_pair(r2));
floriandb4fcaa2012-09-05 19:54:08 +000010521 assign(result, triop(Iop_DivF128, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +000010522 mkexpr(op2)));
10523 put_fpr_pair(r1, mkexpr(result));
10524
10525 return "dxbr";
10526}
10527
10528static HChar *
10529s390_irgen_LTXBR(UChar r1, UChar r2)
10530{
10531 IRTemp result = newTemp(Ity_F128);
10532
10533 assign(result, get_fpr_pair(r2));
10534 put_fpr_pair(r1, mkexpr(result));
10535 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
10536
10537 return "ltxbr";
10538}
10539
10540static HChar *
10541s390_irgen_LCXBR(UChar r1, UChar r2)
10542{
10543 IRTemp result = newTemp(Ity_F128);
10544
10545 assign(result, unop(Iop_NegF128, get_fpr_pair(r2)));
10546 put_fpr_pair(r1, mkexpr(result));
10547 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
10548
10549 return "lcxbr";
10550}
10551
10552static HChar *
10553s390_irgen_LXDBR(UChar r1, UChar r2)
10554{
10555 IRTemp op = newTemp(Ity_F64);
10556
10557 assign(op, get_fpr_dw0(r2));
10558 put_fpr_pair(r1, unop(Iop_F64toF128, mkexpr(op)));
10559
10560 return "lxdbr";
10561}
10562
10563static HChar *
10564s390_irgen_LXEBR(UChar r1, UChar r2)
10565{
10566 IRTemp op = newTemp(Ity_F32);
10567
10568 assign(op, get_fpr_w0(r2));
10569 put_fpr_pair(r1, unop(Iop_F32toF128, mkexpr(op)));
10570
10571 return "lxebr";
10572}
10573
10574static HChar *
10575s390_irgen_LXDB(UChar r1, IRTemp op2addr)
10576{
10577 IRTemp op = newTemp(Ity_F64);
10578
10579 assign(op, load(Ity_F64, mkexpr(op2addr)));
10580 put_fpr_pair(r1, unop(Iop_F64toF128, mkexpr(op)));
10581
10582 return "lxdb";
10583}
10584
10585static HChar *
10586s390_irgen_LXEB(UChar r1, IRTemp op2addr)
10587{
10588 IRTemp op = newTemp(Ity_F32);
10589
10590 assign(op, load(Ity_F32, mkexpr(op2addr)));
10591 put_fpr_pair(r1, unop(Iop_F32toF128, mkexpr(op)));
10592
10593 return "lxeb";
10594}
10595
10596static HChar *
10597s390_irgen_LNEBR(UChar r1, UChar r2)
10598{
10599 IRTemp result = newTemp(Ity_F32);
10600
10601 assign(result, unop(Iop_NegF32, unop(Iop_AbsF32, get_fpr_w0(r2))));
10602 put_fpr_w0(r1, mkexpr(result));
10603 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_32, result);
10604
10605 return "lnebr";
10606}
10607
10608static HChar *
10609s390_irgen_LNDBR(UChar r1, UChar r2)
10610{
10611 IRTemp result = newTemp(Ity_F64);
10612
10613 assign(result, unop(Iop_NegF64, unop(Iop_AbsF64, get_fpr_dw0(r2))));
10614 put_fpr_dw0(r1, mkexpr(result));
10615 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_64, result);
10616
10617 return "lndbr";
10618}
10619
10620static HChar *
10621s390_irgen_LNXBR(UChar r1, UChar r2)
10622{
10623 IRTemp result = newTemp(Ity_F128);
10624
10625 assign(result, unop(Iop_NegF128, unop(Iop_AbsF128, get_fpr_pair(r2))));
10626 put_fpr_pair(r1, mkexpr(result));
10627 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
10628
10629 return "lnxbr";
10630}
10631
10632static HChar *
10633s390_irgen_LPEBR(UChar r1, UChar r2)
10634{
10635 IRTemp result = newTemp(Ity_F32);
10636
10637 assign(result, unop(Iop_AbsF32, get_fpr_w0(r2)));
10638 put_fpr_w0(r1, mkexpr(result));
10639 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_32, result);
10640
10641 return "lpebr";
10642}
10643
10644static HChar *
10645s390_irgen_LPDBR(UChar r1, UChar r2)
10646{
10647 IRTemp result = newTemp(Ity_F64);
10648
10649 assign(result, unop(Iop_AbsF64, get_fpr_dw0(r2)));
10650 put_fpr_dw0(r1, mkexpr(result));
10651 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_64, result);
10652
10653 return "lpdbr";
10654}
10655
10656static HChar *
10657s390_irgen_LPXBR(UChar r1, UChar r2)
10658{
10659 IRTemp result = newTemp(Ity_F128);
10660
10661 assign(result, unop(Iop_AbsF128, get_fpr_pair(r2)));
10662 put_fpr_pair(r1, mkexpr(result));
10663 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
10664
10665 return "lpxbr";
10666}
10667
10668static HChar *
florian4b8efad2012-09-02 18:07:08 +000010669s390_irgen_LDXBR(UChar m3, UChar m4 __attribute__((unused)),
10670 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000010671{
florian12b0bca2012-09-05 20:05:20 +000010672 if (! s390_host_has_fpext && m3 != S390_ROUND_PER_FPC) {
10673 emulation_warning(EmWarn_S390X_fpext_rounding);
10674 m3 = S390_ROUND_PER_FPC;
10675 }
sewardj2019a972011-03-07 16:04:07 +000010676 IRTemp result = newTemp(Ity_F64);
10677
floriandb4fcaa2012-09-05 19:54:08 +000010678 assign(result, binop(Iop_F128toF64, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +000010679 get_fpr_pair(r2)));
sewardj2019a972011-03-07 16:04:07 +000010680 put_fpr_dw0(r1, mkexpr(result));
10681
10682 return "ldxbr";
10683}
10684
10685static HChar *
florian4b8efad2012-09-02 18:07:08 +000010686s390_irgen_LEXBR(UChar m3, UChar m4 __attribute__((unused)),
10687 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000010688{
florian12b0bca2012-09-05 20:05:20 +000010689 if (! s390_host_has_fpext && m3 != S390_ROUND_PER_FPC) {
10690 emulation_warning(EmWarn_S390X_fpext_rounding);
10691 m3 = S390_ROUND_PER_FPC;
10692 }
sewardj2019a972011-03-07 16:04:07 +000010693 IRTemp result = newTemp(Ity_F32);
10694
floriandb4fcaa2012-09-05 19:54:08 +000010695 assign(result, binop(Iop_F128toF32, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +000010696 get_fpr_pair(r2)));
sewardj2019a972011-03-07 16:04:07 +000010697 put_fpr_w0(r1, mkexpr(result));
10698
10699 return "lexbr";
10700}
10701
10702static HChar *
10703s390_irgen_MXBR(UChar r1, UChar r2)
10704{
10705 IRTemp op1 = newTemp(Ity_F128);
10706 IRTemp op2 = newTemp(Ity_F128);
10707 IRTemp result = newTemp(Ity_F128);
floriandb4fcaa2012-09-05 19:54:08 +000010708 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000010709
10710 assign(op1, get_fpr_pair(r1));
10711 assign(op2, get_fpr_pair(r2));
floriandb4fcaa2012-09-05 19:54:08 +000010712 assign(result, triop(Iop_MulF128, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +000010713 mkexpr(op2)));
10714 put_fpr_pair(r1, mkexpr(result));
10715
10716 return "mxbr";
10717}
10718
10719static HChar *
10720s390_irgen_MAEBR(UChar r1, UChar r3, UChar r2)
10721{
floriandb4fcaa2012-09-05 19:54:08 +000010722 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_ROUND_PER_FPC);
florian847684d2012-09-05 04:19:09 +000010723
floriandb4fcaa2012-09-05 19:54:08 +000010724 put_fpr_w0(r1, qop(Iop_MAddF32, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +000010725 get_fpr_w0(r1), get_fpr_w0(r2), get_fpr_w0(r3)));
10726
10727 return "maebr";
10728}
10729
10730static HChar *
10731s390_irgen_MADBR(UChar r1, UChar r3, UChar r2)
10732{
floriandb4fcaa2012-09-05 19:54:08 +000010733 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_ROUND_PER_FPC);
florian847684d2012-09-05 04:19:09 +000010734
floriandb4fcaa2012-09-05 19:54:08 +000010735 put_fpr_dw0(r1, qop(Iop_MAddF64, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +000010736 get_fpr_dw0(r1), get_fpr_dw0(r2), get_fpr_dw0(r3)));
10737
10738 return "madbr";
10739}
10740
10741static HChar *
10742s390_irgen_MAEB(UChar r3, IRTemp op2addr, UChar r1)
10743{
10744 IRExpr *op2 = load(Ity_F32, mkexpr(op2addr));
floriandb4fcaa2012-09-05 19:54:08 +000010745 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000010746
floriandb4fcaa2012-09-05 19:54:08 +000010747 put_fpr_w0(r1, qop(Iop_MAddF32, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +000010748 get_fpr_w0(r1), op2, get_fpr_w0(r3)));
10749
10750 return "maeb";
10751}
10752
10753static HChar *
10754s390_irgen_MADB(UChar r3, IRTemp op2addr, UChar r1)
10755{
10756 IRExpr *op2 = load(Ity_F64, mkexpr(op2addr));
floriandb4fcaa2012-09-05 19:54:08 +000010757 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000010758
floriandb4fcaa2012-09-05 19:54:08 +000010759 put_fpr_dw0(r1, qop(Iop_MAddF64, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +000010760 get_fpr_dw0(r1), op2, get_fpr_dw0(r3)));
10761
10762 return "madb";
10763}
10764
10765static HChar *
10766s390_irgen_MSEBR(UChar r1, UChar r3, UChar r2)
10767{
floriandb4fcaa2012-09-05 19:54:08 +000010768 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_ROUND_PER_FPC);
florian847684d2012-09-05 04:19:09 +000010769
floriandb4fcaa2012-09-05 19:54:08 +000010770 put_fpr_w0(r1, qop(Iop_MSubF32, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +000010771 get_fpr_w0(r1), get_fpr_w0(r2), get_fpr_w0(r3)));
10772
10773 return "msebr";
10774}
10775
10776static HChar *
10777s390_irgen_MSDBR(UChar r1, UChar r3, UChar r2)
10778{
floriandb4fcaa2012-09-05 19:54:08 +000010779 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_ROUND_PER_FPC);
florian847684d2012-09-05 04:19:09 +000010780
floriandb4fcaa2012-09-05 19:54:08 +000010781 put_fpr_dw0(r1, qop(Iop_MSubF64, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +000010782 get_fpr_dw0(r1), get_fpr_dw0(r2), get_fpr_dw0(r3)));
10783
10784 return "msdbr";
10785}
10786
10787static HChar *
10788s390_irgen_MSEB(UChar r3, IRTemp op2addr, UChar r1)
10789{
10790 IRExpr *op2 = load(Ity_F32, mkexpr(op2addr));
floriandb4fcaa2012-09-05 19:54:08 +000010791 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000010792
floriandb4fcaa2012-09-05 19:54:08 +000010793 put_fpr_w0(r1, qop(Iop_MSubF32, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +000010794 get_fpr_w0(r1), op2, get_fpr_w0(r3)));
10795
10796 return "mseb";
10797}
10798
10799static HChar *
10800s390_irgen_MSDB(UChar r3, IRTemp op2addr, UChar r1)
10801{
10802 IRExpr *op2 = load(Ity_F64, mkexpr(op2addr));
floriandb4fcaa2012-09-05 19:54:08 +000010803 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000010804
floriandb4fcaa2012-09-05 19:54:08 +000010805 put_fpr_dw0(r1, qop(Iop_MSubF64, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +000010806 get_fpr_dw0(r1), op2, get_fpr_dw0(r3)));
10807
10808 return "msdb";
10809}
10810
10811static HChar *
10812s390_irgen_SQEBR(UChar r1, UChar r2)
10813{
10814 IRTemp result = newTemp(Ity_F32);
floriandb4fcaa2012-09-05 19:54:08 +000010815 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000010816
floriandb4fcaa2012-09-05 19:54:08 +000010817 assign(result, binop(Iop_SqrtF32, mkexpr(rounding_mode), get_fpr_w0(r2)));
sewardj2019a972011-03-07 16:04:07 +000010818 put_fpr_w0(r1, mkexpr(result));
10819
10820 return "sqebr";
10821}
10822
10823static HChar *
10824s390_irgen_SQDBR(UChar r1, UChar r2)
10825{
10826 IRTemp result = newTemp(Ity_F64);
floriandb4fcaa2012-09-05 19:54:08 +000010827 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000010828
floriandb4fcaa2012-09-05 19:54:08 +000010829 assign(result, binop(Iop_SqrtF64, mkexpr(rounding_mode), get_fpr_dw0(r2)));
sewardj2019a972011-03-07 16:04:07 +000010830 put_fpr_dw0(r1, mkexpr(result));
10831
10832 return "sqdbr";
10833}
10834
10835static HChar *
10836s390_irgen_SQXBR(UChar r1, UChar r2)
10837{
10838 IRTemp result = newTemp(Ity_F128);
floriandb4fcaa2012-09-05 19:54:08 +000010839 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000010840
floriandb4fcaa2012-09-05 19:54:08 +000010841 assign(result, binop(Iop_SqrtF128, mkexpr(rounding_mode),
10842 get_fpr_pair(r2)));
sewardj2019a972011-03-07 16:04:07 +000010843 put_fpr_pair(r1, mkexpr(result));
10844
10845 return "sqxbr";
10846}
10847
10848static HChar *
10849s390_irgen_SQEB(UChar r1, IRTemp op2addr)
10850{
10851 IRTemp op = newTemp(Ity_F32);
floriandb4fcaa2012-09-05 19:54:08 +000010852 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000010853
10854 assign(op, load(Ity_F32, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +000010855 put_fpr_w0(r1, binop(Iop_SqrtF32, mkexpr(rounding_mode), mkexpr(op)));
sewardj2019a972011-03-07 16:04:07 +000010856
10857 return "sqeb";
10858}
10859
10860static HChar *
10861s390_irgen_SQDB(UChar r1, IRTemp op2addr)
10862{
10863 IRTemp op = newTemp(Ity_F64);
floriandb4fcaa2012-09-05 19:54:08 +000010864 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000010865
10866 assign(op, load(Ity_F64, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +000010867 put_fpr_dw0(r1, binop(Iop_SqrtF64, mkexpr(rounding_mode), mkexpr(op)));
sewardj2019a972011-03-07 16:04:07 +000010868
10869 return "sqdb";
10870}
10871
10872static HChar *
10873s390_irgen_SXBR(UChar r1, UChar r2)
10874{
10875 IRTemp op1 = newTemp(Ity_F128);
10876 IRTemp op2 = newTemp(Ity_F128);
10877 IRTemp result = newTemp(Ity_F128);
floriandb4fcaa2012-09-05 19:54:08 +000010878 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000010879
10880 assign(op1, get_fpr_pair(r1));
10881 assign(op2, get_fpr_pair(r2));
floriandb4fcaa2012-09-05 19:54:08 +000010882 assign(result, triop(Iop_SubF128, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +000010883 mkexpr(op2)));
10884 put_fpr_pair(r1, mkexpr(result));
10885 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
10886
10887 return "sxbr";
10888}
10889
10890static HChar *
10891s390_irgen_TCEB(UChar r1, IRTemp op2addr)
10892{
10893 IRTemp value = newTemp(Ity_F32);
10894
10895 assign(value, get_fpr_w0(r1));
10896
10897 s390_cc_thunk_putFZ(S390_CC_OP_BFP_TDC_32, value, op2addr);
10898
10899 return "tceb";
10900}
10901
10902static HChar *
10903s390_irgen_TCDB(UChar r1, IRTemp op2addr)
10904{
10905 IRTemp value = newTemp(Ity_F64);
10906
10907 assign(value, get_fpr_dw0(r1));
10908
10909 s390_cc_thunk_putFZ(S390_CC_OP_BFP_TDC_64, value, op2addr);
10910
10911 return "tcdb";
10912}
10913
10914static HChar *
10915s390_irgen_TCXB(UChar r1, IRTemp op2addr)
10916{
10917 IRTemp value = newTemp(Ity_F128);
10918
10919 assign(value, get_fpr_pair(r1));
10920
10921 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_TDC_128, value, op2addr);
10922
10923 return "tcxb";
10924}
10925
10926static HChar *
10927s390_irgen_LCDFR(UChar r1, UChar r2)
10928{
10929 IRTemp result = newTemp(Ity_F64);
10930
10931 assign(result, unop(Iop_NegF64, get_fpr_dw0(r2)));
10932 put_fpr_dw0(r1, mkexpr(result));
10933
10934 return "lcdfr";
10935}
10936
10937static HChar *
10938s390_irgen_LNDFR(UChar r1, UChar r2)
10939{
10940 IRTemp result = newTemp(Ity_F64);
10941
10942 assign(result, unop(Iop_NegF64, unop(Iop_AbsF64, get_fpr_dw0(r2))));
10943 put_fpr_dw0(r1, mkexpr(result));
10944
10945 return "lndfr";
10946}
10947
10948static HChar *
10949s390_irgen_LPDFR(UChar r1, UChar r2)
10950{
10951 IRTemp result = newTemp(Ity_F64);
10952
10953 assign(result, unop(Iop_AbsF64, get_fpr_dw0(r2)));
10954 put_fpr_dw0(r1, mkexpr(result));
10955
10956 return "lpdfr";
10957}
10958
10959static HChar *
10960s390_irgen_LDGR(UChar r1, UChar r2)
10961{
10962 put_fpr_dw0(r1, unop(Iop_ReinterpI64asF64, get_gpr_dw0(r2)));
10963
10964 return "ldgr";
10965}
10966
10967static HChar *
10968s390_irgen_LGDR(UChar r1, UChar r2)
10969{
10970 put_gpr_dw0(r1, unop(Iop_ReinterpF64asI64, get_fpr_dw0(r2)));
10971
10972 return "lgdr";
10973}
10974
10975
10976static HChar *
10977s390_irgen_CPSDR(UChar r3, UChar r1, UChar r2)
10978{
10979 IRTemp sign = newTemp(Ity_I64);
10980 IRTemp value = newTemp(Ity_I64);
10981
10982 assign(sign, binop(Iop_And64, unop(Iop_ReinterpF64asI64, get_fpr_dw0(r3)),
10983 mkU64(1ULL << 63)));
10984 assign(value, binop(Iop_And64, unop(Iop_ReinterpF64asI64, get_fpr_dw0(r2)),
10985 mkU64((1ULL << 63) - 1)));
10986 put_fpr_dw0(r1, unop(Iop_ReinterpI64asF64, binop(Iop_Or64, mkexpr(value),
10987 mkexpr(sign))));
10988
10989 return "cpsdr";
10990}
10991
10992
sewardj2019a972011-03-07 16:04:07 +000010993static IRExpr *
10994s390_call_cvb(IRExpr *in)
10995{
10996 IRExpr **args, *call;
10997
10998 args = mkIRExprVec_1(in);
10999 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
11000 "s390_do_cvb", &s390_do_cvb, args);
11001
11002 /* Nothing is excluded from definedness checking. */
11003 call->Iex.CCall.cee->mcx_mask = 0;
11004
11005 return call;
11006}
11007
11008static HChar *
11009s390_irgen_CVB(UChar r1, IRTemp op2addr)
11010{
11011 put_gpr_w1(r1, s390_call_cvb(load(Ity_I64, mkexpr(op2addr))));
11012
11013 return "cvb";
11014}
11015
11016static HChar *
11017s390_irgen_CVBY(UChar r1, IRTemp op2addr)
11018{
11019 put_gpr_w1(r1, s390_call_cvb(load(Ity_I64, mkexpr(op2addr))));
11020
11021 return "cvby";
11022}
11023
11024
sewardj2019a972011-03-07 16:04:07 +000011025static IRExpr *
11026s390_call_cvd(IRExpr *in)
11027{
11028 IRExpr **args, *call;
11029
11030 args = mkIRExprVec_1(in);
11031 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
11032 "s390_do_cvd", &s390_do_cvd, args);
11033
11034 /* Nothing is excluded from definedness checking. */
11035 call->Iex.CCall.cee->mcx_mask = 0;
11036
11037 return call;
11038}
11039
11040static HChar *
11041s390_irgen_CVD(UChar r1, IRTemp op2addr)
11042{
florian11b8ee82012-08-06 13:35:33 +000011043 store(mkexpr(op2addr), s390_call_cvd(unop(Iop_32Uto64, get_gpr_w1(r1))));
sewardj2019a972011-03-07 16:04:07 +000011044
11045 return "cvd";
11046}
11047
11048static HChar *
11049s390_irgen_CVDY(UChar r1, IRTemp op2addr)
11050{
11051 store(mkexpr(op2addr), s390_call_cvd(get_gpr_w1(r1)));
11052
11053 return "cvdy";
11054}
11055
11056static HChar *
11057s390_irgen_FLOGR(UChar r1, UChar r2)
11058{
11059 IRTemp input = newTemp(Ity_I64);
11060 IRTemp not_zero = newTemp(Ity_I64);
11061 IRTemp tmpnum = newTemp(Ity_I64);
11062 IRTemp num = newTemp(Ity_I64);
11063 IRTemp shift_amount = newTemp(Ity_I8);
11064
11065 /* We use the "count leading zeroes" operator because the number of
11066 leading zeroes is identical with the bit position of the first '1' bit.
11067 However, that operator does not work when the input value is zero.
11068 Therefore, we set the LSB of the input value to 1 and use Clz64 on
11069 the modified value. If input == 0, then the result is 64. Otherwise,
11070 the result of Clz64 is what we want. */
11071
11072 assign(input, get_gpr_dw0(r2));
11073 assign(not_zero, binop(Iop_Or64, mkexpr(input), mkU64(1)));
11074 assign(tmpnum, unop(Iop_Clz64, mkexpr(not_zero)));
11075
11076 /* num = (input == 0) ? 64 : tmpnum */
11077 assign(num, mkite(binop(Iop_CmpEQ64, mkexpr(input), mkU64(0)),
11078 /* == 0 */ mkU64(64),
11079 /* != 0 */ mkexpr(tmpnum)));
11080
11081 put_gpr_dw0(r1, mkexpr(num));
11082
11083 /* Set the leftmost '1' bit of the input value to zero. The general scheme
11084 is to first shift the input value by NUM + 1 bits to the left which
11085 causes the leftmost '1' bit to disappear. Then we shift logically to
11086 the right by NUM + 1 bits. Because the semantics of Iop_Shl64 and
11087 Iop_Shr64 are undefined if the shift-amount is greater than or equal to
11088 the width of the value-to-be-shifted, we need to special case
11089 NUM + 1 >= 64. This is equivalent to INPUT != 0 && INPUT != 1.
11090 For both such INPUT values the result will be 0. */
11091
11092 assign(shift_amount, unop(Iop_64to8, binop(Iop_Add64, mkexpr(num),
11093 mkU64(1))));
11094
11095 put_gpr_dw0(r1 + 1,
florian6ad49522011-09-09 02:38:55 +000011096 mkite(binop(Iop_CmpLE64U, mkexpr(input), mkU64(1)),
11097 /* == 0 || == 1*/ mkU64(0),
11098 /* otherwise */
11099 binop(Iop_Shr64,
11100 binop(Iop_Shl64, mkexpr(input),
11101 mkexpr(shift_amount)),
11102 mkexpr(shift_amount))));
sewardj2019a972011-03-07 16:04:07 +000011103
11104 /* Compare the original value as an unsigned integer with 0. */
11105 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, input,
11106 mktemp(Ity_I64, mkU64(0)), False);
11107
11108 return "flogr";
11109}
11110
sewardj1e5fea62011-05-17 16:18:36 +000011111static HChar *
11112s390_irgen_STCK(IRTemp op2addr)
11113{
11114 IRDirty *d;
11115 IRTemp cc = newTemp(Ity_I64);
11116
11117 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STCK",
11118 &s390x_dirtyhelper_STCK,
11119 mkIRExprVec_1(mkexpr(op2addr)));
11120 d->mFx = Ifx_Write;
11121 d->mAddr = mkexpr(op2addr);
11122 d->mSize = 8;
11123 stmt(IRStmt_Dirty(d));
11124 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
11125 mkexpr(cc), mkU64(0), mkU64(0));
11126 return "stck";
11127}
11128
11129static HChar *
11130s390_irgen_STCKF(IRTemp op2addr)
11131{
florianc5c669b2012-08-26 14:32:28 +000011132 if (! s390_host_has_stckf) {
floriane75dafa2012-09-01 17:54:09 +000011133 emulation_failure(EmFail_S390X_stckf);
florianc5c669b2012-08-26 14:32:28 +000011134 } else {
11135 IRTemp cc = newTemp(Ity_I64);
sewardj1e5fea62011-05-17 16:18:36 +000011136
florianc5c669b2012-08-26 14:32:28 +000011137 IRDirty *d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STCKF",
11138 &s390x_dirtyhelper_STCKF,
11139 mkIRExprVec_1(mkexpr(op2addr)));
11140 d->mFx = Ifx_Write;
11141 d->mAddr = mkexpr(op2addr);
11142 d->mSize = 8;
11143 stmt(IRStmt_Dirty(d));
11144 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
11145 mkexpr(cc), mkU64(0), mkU64(0));
11146 }
sewardj1e5fea62011-05-17 16:18:36 +000011147 return "stckf";
11148}
11149
11150static HChar *
11151s390_irgen_STCKE(IRTemp op2addr)
11152{
11153 IRDirty *d;
11154 IRTemp cc = newTemp(Ity_I64);
11155
11156 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STCKE",
11157 &s390x_dirtyhelper_STCKE,
11158 mkIRExprVec_1(mkexpr(op2addr)));
11159 d->mFx = Ifx_Write;
11160 d->mAddr = mkexpr(op2addr);
11161 d->mSize = 16;
11162 stmt(IRStmt_Dirty(d));
11163 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
11164 mkexpr(cc), mkU64(0), mkU64(0));
11165 return "stcke";
11166}
11167
florian933065d2011-07-11 01:48:02 +000011168static HChar *
11169s390_irgen_STFLE(IRTemp op2addr)
11170{
florian4e0083e2012-08-26 03:41:56 +000011171 if (! s390_host_has_stfle) {
floriane75dafa2012-09-01 17:54:09 +000011172 emulation_failure(EmFail_S390X_stfle);
florian4e0083e2012-08-26 03:41:56 +000011173 return "stfle";
11174 }
11175
florian933065d2011-07-11 01:48:02 +000011176 IRDirty *d;
11177 IRTemp cc = newTemp(Ity_I64);
11178
11179 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STFLE",
11180 &s390x_dirtyhelper_STFLE,
11181 mkIRExprVec_1(mkexpr(op2addr)));
11182
11183 d->needsBBP = 1; /* Need to pass pointer to guest state to helper */
11184
sewardjc9069f22012-06-01 16:09:50 +000011185 d->nFxState = 1;
11186 vex_bzero(&d->fxState, sizeof(d->fxState));
11187
florian933065d2011-07-11 01:48:02 +000011188 d->fxState[0].fx = Ifx_Modify; /* read then write */
11189 d->fxState[0].offset = S390X_GUEST_OFFSET(guest_r0);
11190 d->fxState[0].size = sizeof(ULong);
florian933065d2011-07-11 01:48:02 +000011191
11192 d->mAddr = mkexpr(op2addr);
11193 /* Pretend all double words are written */
11194 d->mSize = S390_NUM_FACILITY_DW * sizeof(ULong);
11195 d->mFx = Ifx_Write;
11196
11197 stmt(IRStmt_Dirty(d));
11198
11199 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET), mkexpr(cc), mkU64(0), mkU64(0));
11200
11201 return "stfle";
11202}
11203
floriana4384a32011-08-11 16:58:45 +000011204static HChar *
11205s390_irgen_CKSM(UChar r1,UChar r2)
11206{
11207 IRTemp addr = newTemp(Ity_I64);
11208 IRTemp op = newTemp(Ity_I32);
11209 IRTemp len = newTemp(Ity_I64);
11210 IRTemp oldval = newTemp(Ity_I32);
11211 IRTemp mask = newTemp(Ity_I32);
11212 IRTemp newop = newTemp(Ity_I32);
11213 IRTemp result = newTemp(Ity_I32);
11214 IRTemp result1 = newTemp(Ity_I32);
11215 IRTemp inc = newTemp(Ity_I64);
11216
11217 assign(oldval, get_gpr_w1(r1));
11218 assign(addr, get_gpr_dw0(r2));
11219 assign(len, get_gpr_dw0(r2+1));
11220
11221 /* Condition code is always zero. */
11222 s390_cc_set(0);
11223
11224 /* If length is zero, there is no need to calculate the checksum */
florian6820ba52012-07-26 02:01:50 +000011225 next_insn_if(binop(Iop_CmpEQ64, mkexpr(len), mkU64(0)));
floriana4384a32011-08-11 16:58:45 +000011226
11227 /* Assiging the increment variable to adjust address and length
11228 later on. */
11229 assign(inc, mkite(binop(Iop_CmpLT64U, mkexpr(len), mkU64(4)),
11230 mkexpr(len), mkU64(4)));
11231
11232 /* If length < 4 the final 4-byte 2nd operand value is computed by
11233 appending the remaining bytes to the right with 0. This is done
11234 by AND'ing the 4 bytes loaded from memory with an appropriate
11235 mask. If length >= 4, that mask is simply 0xffffffff. */
11236
11237 assign(mask, mkite(binop(Iop_CmpLT64U, mkexpr(len), mkU64(4)),
11238 /* Mask computation when len < 4:
11239 0xffffffff << (32 - (len % 4)*8) */
11240 binop(Iop_Shl32, mkU32(0xffffffff),
11241 unop(Iop_32to8,
11242 binop(Iop_Sub32, mkU32(32),
11243 binop(Iop_Shl32,
11244 unop(Iop_64to32,
11245 binop(Iop_And64,
11246 mkexpr(len), mkU64(3))),
11247 mkU8(3))))),
11248 mkU32(0xffffffff)));
11249
11250 assign(op, load(Ity_I32, mkexpr(addr)));
11251 assign(newop, binop(Iop_And32, mkexpr(op), mkexpr(mask)));
11252 assign(result, binop(Iop_Add32, mkexpr(newop), mkexpr(oldval)));
11253
11254 /* Checking for carry */
11255 assign(result1, mkite(binop(Iop_CmpLT32U, mkexpr(result), mkexpr(newop)),
11256 binop(Iop_Add32, mkexpr(result), mkU32(1)),
11257 mkexpr(result)));
11258
11259 put_gpr_w1(r1, mkexpr(result1));
11260 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr), mkexpr(inc)));
11261 put_gpr_dw0(r2+1, binop(Iop_Sub64, mkexpr(len), mkexpr(inc)));
11262
florian6820ba52012-07-26 02:01:50 +000011263 iterate_if(binop(Iop_CmpNE64, mkexpr(len), mkU64(0)));
floriana4384a32011-08-11 16:58:45 +000011264
11265 return "cksm";
11266}
11267
florian9af37692012-01-15 21:01:16 +000011268static HChar *
11269s390_irgen_TROO(UChar m3, UChar r1, UChar r2)
11270{
11271 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
11272 src_addr = newTemp(Ity_I64);
11273 des_addr = newTemp(Ity_I64);
11274 tab_addr = newTemp(Ity_I64);
11275 test_byte = newTemp(Ity_I8);
11276 src_len = newTemp(Ity_I64);
11277
11278 assign(src_addr, get_gpr_dw0(r2));
11279 assign(des_addr, get_gpr_dw0(r1));
11280 assign(tab_addr, get_gpr_dw0(1));
florian53518532012-01-18 14:00:31 +000011281 assign(src_len, get_gpr_dw0(r1+1));
florian9af37692012-01-15 21:01:16 +000011282 assign(test_byte, get_gpr_b7(0));
11283
11284 IRTemp op = newTemp(Ity_I8);
11285 IRTemp op1 = newTemp(Ity_I8);
11286 IRTemp result = newTemp(Ity_I64);
11287
11288 /* End of source string? We're done; proceed to next insn */
11289 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000011290 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian9af37692012-01-15 21:01:16 +000011291
11292 /* Load character from source string, index translation table and
11293 store translated character in op1. */
11294 assign(op, load(Ity_I8, mkexpr(src_addr)));
11295
11296 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)),
11297 mkexpr(tab_addr)));
11298 assign(op1, load(Ity_I8, mkexpr(result)));
11299
11300 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
11301 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000011302 next_insn_if(binop(Iop_CmpEQ8, mkexpr(op1), mkexpr(test_byte)));
florian9af37692012-01-15 21:01:16 +000011303 }
11304 store(get_gpr_dw0(r1), mkexpr(op1));
11305
11306 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(1)));
11307 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(1)));
11308 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(1)));
11309
florian6820ba52012-07-26 02:01:50 +000011310 iterate();
florian9af37692012-01-15 21:01:16 +000011311
11312 return "troo";
11313}
11314
florian730448f2012-02-04 17:07:07 +000011315static HChar *
11316s390_irgen_TRTO(UChar m3, UChar r1, UChar r2)
11317{
11318 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
11319 src_addr = newTemp(Ity_I64);
11320 des_addr = newTemp(Ity_I64);
11321 tab_addr = newTemp(Ity_I64);
11322 test_byte = newTemp(Ity_I8);
11323 src_len = newTemp(Ity_I64);
11324
11325 assign(src_addr, get_gpr_dw0(r2));
11326 assign(des_addr, get_gpr_dw0(r1));
11327 assign(tab_addr, get_gpr_dw0(1));
11328 assign(src_len, get_gpr_dw0(r1+1));
11329 assign(test_byte, get_gpr_b7(0));
11330
11331 IRTemp op = newTemp(Ity_I16);
11332 IRTemp op1 = newTemp(Ity_I8);
11333 IRTemp result = newTemp(Ity_I64);
11334
11335 /* End of source string? We're done; proceed to next insn */
11336 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000011337 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian730448f2012-02-04 17:07:07 +000011338
11339 /* Load character from source string, index translation table and
11340 store translated character in op1. */
11341 assign(op, load(Ity_I16, mkexpr(src_addr)));
11342
11343 assign(result, binop(Iop_Add64, unop(Iop_16Uto64, mkexpr(op)),
11344 mkexpr(tab_addr)));
11345
11346 assign(op1, load(Ity_I8, mkexpr(result)));
11347
11348 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
11349 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000011350 next_insn_if(binop(Iop_CmpEQ8, mkexpr(op1), mkexpr(test_byte)));
florian730448f2012-02-04 17:07:07 +000011351 }
11352 store(get_gpr_dw0(r1), mkexpr(op1));
11353
11354 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(2)));
11355 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(1)));
11356 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(2)));
11357
florian6820ba52012-07-26 02:01:50 +000011358 iterate();
florian730448f2012-02-04 17:07:07 +000011359
11360 return "trto";
11361}
11362
11363static HChar *
11364s390_irgen_TROT(UChar m3, UChar r1, UChar r2)
11365{
11366 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
11367 src_addr = newTemp(Ity_I64);
11368 des_addr = newTemp(Ity_I64);
11369 tab_addr = newTemp(Ity_I64);
11370 test_byte = newTemp(Ity_I16);
11371 src_len = newTemp(Ity_I64);
11372
11373 assign(src_addr, get_gpr_dw0(r2));
11374 assign(des_addr, get_gpr_dw0(r1));
11375 assign(tab_addr, get_gpr_dw0(1));
11376 assign(src_len, get_gpr_dw0(r1+1));
11377 assign(test_byte, get_gpr_hw3(0));
11378
11379 IRTemp op = newTemp(Ity_I8);
11380 IRTemp op1 = newTemp(Ity_I16);
11381 IRTemp result = newTemp(Ity_I64);
11382
11383 /* End of source string? We're done; proceed to next insn */
11384 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000011385 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian730448f2012-02-04 17:07:07 +000011386
11387 /* Load character from source string, index translation table and
11388 store translated character in op1. */
11389 assign(op, binop(Iop_Shl8, load(Ity_I8, mkexpr(src_addr)), mkU8(1)));
11390
11391 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)),
11392 mkexpr(tab_addr)));
11393 assign(op1, load(Ity_I16, mkexpr(result)));
11394
11395 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
11396 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000011397 next_insn_if(binop(Iop_CmpEQ16, mkexpr(op1), mkexpr(test_byte)));
florian730448f2012-02-04 17:07:07 +000011398 }
11399 store(get_gpr_dw0(r1), mkexpr(op1));
11400
11401 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(1)));
11402 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(2)));
11403 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(1)));
11404
florian6820ba52012-07-26 02:01:50 +000011405 iterate();
florian730448f2012-02-04 17:07:07 +000011406
11407 return "trot";
11408}
11409
11410static HChar *
11411s390_irgen_TRTT(UChar m3, UChar r1, UChar r2)
11412{
11413 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
11414 src_addr = newTemp(Ity_I64);
11415 des_addr = newTemp(Ity_I64);
11416 tab_addr = newTemp(Ity_I64);
11417 test_byte = newTemp(Ity_I16);
11418 src_len = newTemp(Ity_I64);
11419
11420 assign(src_addr, get_gpr_dw0(r2));
11421 assign(des_addr, get_gpr_dw0(r1));
11422 assign(tab_addr, get_gpr_dw0(1));
11423 assign(src_len, get_gpr_dw0(r1+1));
11424 assign(test_byte, get_gpr_hw3(0));
11425
11426 IRTemp op = newTemp(Ity_I16);
11427 IRTemp op1 = newTemp(Ity_I16);
11428 IRTemp result = newTemp(Ity_I64);
11429
11430 /* End of source string? We're done; proceed to next insn */
11431 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000011432 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian730448f2012-02-04 17:07:07 +000011433
11434 /* Load character from source string, index translation table and
11435 store translated character in op1. */
11436 assign(op, binop(Iop_Shl16, load(Ity_I16, mkexpr(src_addr)), mkU8(1)));
11437
11438 assign(result, binop(Iop_Add64, unop(Iop_16Uto64, mkexpr(op)),
11439 mkexpr(tab_addr)));
11440 assign(op1, load(Ity_I16, mkexpr(result)));
11441
11442 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
11443 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000011444 next_insn_if(binop(Iop_CmpEQ16, mkexpr(op1), mkexpr(test_byte)));
florian730448f2012-02-04 17:07:07 +000011445 }
11446
11447 store(get_gpr_dw0(r1), mkexpr(op1));
11448
11449 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(2)));
11450 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(2)));
11451 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(2)));
11452
florian6820ba52012-07-26 02:01:50 +000011453 iterate();
florian730448f2012-02-04 17:07:07 +000011454
11455 return "trtt";
11456}
11457
11458static HChar *
11459s390_irgen_TR(UChar length, IRTemp start1, IRTemp start2)
11460{
florianf87d4fb2012-05-05 02:55:24 +000011461 IRTemp len = newTemp(Ity_I64);
florian730448f2012-02-04 17:07:07 +000011462
florianf87d4fb2012-05-05 02:55:24 +000011463 assign(len, mkU64(length));
11464 s390_irgen_TR_EX(len, start1, start2);
florian730448f2012-02-04 17:07:07 +000011465
11466 return "tr";
11467}
11468
11469static HChar *
11470s390_irgen_TRE(UChar r1,UChar r2)
11471{
11472 IRTemp src_addr, tab_addr, src_len, test_byte;
11473 src_addr = newTemp(Ity_I64);
11474 tab_addr = newTemp(Ity_I64);
11475 src_len = newTemp(Ity_I64);
11476 test_byte = newTemp(Ity_I8);
11477
11478 assign(src_addr, get_gpr_dw0(r1));
11479 assign(src_len, get_gpr_dw0(r1+1));
11480 assign(tab_addr, get_gpr_dw0(r2));
11481 assign(test_byte, get_gpr_b7(0));
11482
11483 IRTemp op = newTemp(Ity_I8);
11484 IRTemp op1 = newTemp(Ity_I8);
11485 IRTemp result = newTemp(Ity_I64);
11486
11487 /* End of source string? We're done; proceed to next insn */
11488 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000011489 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian730448f2012-02-04 17:07:07 +000011490
11491 /* Load character from source string and compare with test byte */
11492 assign(op, load(Ity_I8, mkexpr(src_addr)));
11493
11494 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000011495 next_insn_if(binop(Iop_CmpEQ8, mkexpr(op), mkexpr(test_byte)));
florian730448f2012-02-04 17:07:07 +000011496
11497 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)),
11498 mkexpr(tab_addr)));
11499
11500 assign(op1, load(Ity_I8, mkexpr(result)));
11501
11502 store(get_gpr_dw0(r1), mkexpr(op1));
11503 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(src_addr), mkU64(1)));
11504 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(1)));
11505
florian6820ba52012-07-26 02:01:50 +000011506 iterate();
florian730448f2012-02-04 17:07:07 +000011507
11508 return "tre";
11509}
11510
floriana0100c92012-07-20 00:06:35 +000011511static IRExpr *
11512s390_call_cu21(IRExpr *srcval, IRExpr *low_surrogate)
11513{
11514 IRExpr **args, *call;
11515 args = mkIRExprVec_2(srcval, low_surrogate);
11516 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
11517 "s390_do_cu21", &s390_do_cu21, args);
11518
11519 /* Nothing is excluded from definedness checking. */
11520 call->Iex.CCall.cee->mcx_mask = 0;
11521
11522 return call;
11523}
11524
11525static HChar *
11526s390_irgen_CU21(UChar m3, UChar r1, UChar r2)
11527{
11528 IRTemp addr1 = newTemp(Ity_I64);
11529 IRTemp addr2 = newTemp(Ity_I64);
11530 IRTemp len1 = newTemp(Ity_I64);
11531 IRTemp len2 = newTemp(Ity_I64);
11532
11533 assign(addr1, get_gpr_dw0(r1));
11534 assign(addr2, get_gpr_dw0(r2));
11535 assign(len1, get_gpr_dw0(r1 + 1));
11536 assign(len2, get_gpr_dw0(r2 + 1));
11537
11538 /* We're processing the 2nd operand 2 bytes at a time. Therefore, if
11539 there are less than 2 bytes left, then the 2nd operand is exhausted
11540 and we're done here. cc = 0 */
11541 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000011542 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(2)));
floriana0100c92012-07-20 00:06:35 +000011543
11544 /* There are at least two bytes there. Read them. */
11545 IRTemp srcval = newTemp(Ity_I32);
11546 assign(srcval, unop(Iop_16Uto32, load(Ity_I16, mkexpr(addr2))));
11547
11548 /* Find out whether this is a high surrogate. I.e. SRCVAL lies
11549 inside the interval [0xd800 - 0xdbff] */
11550 IRTemp is_high_surrogate = newTemp(Ity_I32);
11551 IRExpr *flag1 = mkite(binop(Iop_CmpLE32U, mkU32(0xd800), mkexpr(srcval)),
11552 mkU32(1), mkU32(0));
11553 IRExpr *flag2 = mkite(binop(Iop_CmpLE32U, mkexpr(srcval), mkU32(0xdbff)),
11554 mkU32(1), mkU32(0));
11555 assign(is_high_surrogate, binop(Iop_And32, flag1, flag2));
11556
11557 /* If SRCVAL is a high surrogate and there are less than 4 bytes left,
11558 then the 2nd operand is exhausted and we're done here. cc = 0 */
11559 IRExpr *not_enough_bytes =
11560 mkite(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)), mkU32(1), mkU32(0));
11561
florian6820ba52012-07-26 02:01:50 +000011562 next_insn_if(binop(Iop_CmpEQ32,
11563 binop(Iop_And32, mkexpr(is_high_surrogate),
11564 not_enough_bytes), mkU32(1)));
floriana0100c92012-07-20 00:06:35 +000011565
11566 /* The 2nd operand is not exhausted. If the first 2 bytes are a high
11567 surrogate, read the next two bytes (low surrogate). */
11568 IRTemp low_surrogate = newTemp(Ity_I32);
11569 IRExpr *low_surrogate_addr = binop(Iop_Add64, mkexpr(addr2), mkU64(2));
11570
11571 assign(low_surrogate,
11572 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
11573 unop(Iop_16Uto32, load(Ity_I16, low_surrogate_addr)),
11574 mkU32(0))); // any value is fine; it will not be used
11575
11576 /* Call the helper */
11577 IRTemp retval = newTemp(Ity_I64);
florian11b8ee82012-08-06 13:35:33 +000011578 assign(retval, s390_call_cu21(unop(Iop_32Uto64, mkexpr(srcval)),
11579 unop(Iop_32Uto64, mkexpr(low_surrogate))));
floriana0100c92012-07-20 00:06:35 +000011580
11581 /* Before we can test whether the 1st operand is exhausted we need to
11582 test for an invalid low surrogate. Because cc=2 outranks cc=1. */
11583 if (s390_host_has_etf3 && (m3 & 0x1) == 1) {
11584 IRExpr *invalid_low_surrogate =
11585 binop(Iop_And64, mkexpr(retval), mkU64(0xff));
11586
11587 s390_cc_set(2);
florian6820ba52012-07-26 02:01:50 +000011588 next_insn_if(binop(Iop_CmpEQ64, invalid_low_surrogate, mkU64(1)));
floriana0100c92012-07-20 00:06:35 +000011589 }
11590
11591 /* Now test whether the 1st operand is exhausted */
11592 IRTemp num_bytes = newTemp(Ity_I64);
11593 assign(num_bytes, binop(Iop_And64,
11594 binop(Iop_Shr64, mkexpr(retval), mkU8(8)),
11595 mkU64(0xff)));
11596 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000011597 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
floriana0100c92012-07-20 00:06:35 +000011598
11599 /* Extract the bytes to be stored at addr1 */
11600 IRTemp data = newTemp(Ity_I64);
11601 assign(data, binop(Iop_Shr64, mkexpr(retval), mkU8(16)));
11602
11603 /* To store the bytes construct 4 dirty helper calls. The helper calls
11604 are guarded (num_bytes == 1, num_bytes == 2, etc) such that only
11605 one of them will be called at runtime. */
11606 int i;
11607 for (i = 1; i <= 4; ++i) {
11608 IRDirty *d;
11609
11610 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
11611 &s390x_dirtyhelper_CUxy,
11612 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
11613 mkexpr(num_bytes)));
11614 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
11615 d->mFx = Ifx_Write;
11616 d->mAddr = mkexpr(addr1);
11617 d->mSize = i;
11618 stmt(IRStmt_Dirty(d));
11619 }
11620
11621 /* Update source address and length */
11622 IRTemp num_src_bytes = newTemp(Ity_I64);
11623 assign(num_src_bytes,
11624 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
11625 mkU64(4), mkU64(2)));
11626 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkexpr(num_src_bytes)));
11627 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkexpr(num_src_bytes)));
11628
11629 /* Update destination address and length */
11630 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
11631 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
11632
florian6820ba52012-07-26 02:01:50 +000011633 iterate();
floriana0100c92012-07-20 00:06:35 +000011634
11635 return "cu21";
11636}
11637
florian2a415a12012-07-21 17:41:36 +000011638static IRExpr *
11639s390_call_cu24(IRExpr *srcval, IRExpr *low_surrogate)
11640{
11641 IRExpr **args, *call;
11642 args = mkIRExprVec_2(srcval, low_surrogate);
11643 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
11644 "s390_do_cu24", &s390_do_cu24, args);
11645
11646 /* Nothing is excluded from definedness checking. */
11647 call->Iex.CCall.cee->mcx_mask = 0;
11648
11649 return call;
11650}
11651
11652static HChar *
11653s390_irgen_CU24(UChar m3, UChar r1, UChar r2)
11654{
11655 IRTemp addr1 = newTemp(Ity_I64);
11656 IRTemp addr2 = newTemp(Ity_I64);
11657 IRTemp len1 = newTemp(Ity_I64);
11658 IRTemp len2 = newTemp(Ity_I64);
11659
11660 assign(addr1, get_gpr_dw0(r1));
11661 assign(addr2, get_gpr_dw0(r2));
11662 assign(len1, get_gpr_dw0(r1 + 1));
11663 assign(len2, get_gpr_dw0(r2 + 1));
11664
11665 /* We're processing the 2nd operand 2 bytes at a time. Therefore, if
11666 there are less than 2 bytes left, then the 2nd operand is exhausted
11667 and we're done here. cc = 0 */
11668 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000011669 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(2)));
florian2a415a12012-07-21 17:41:36 +000011670
11671 /* There are at least two bytes there. Read them. */
11672 IRTemp srcval = newTemp(Ity_I32);
11673 assign(srcval, unop(Iop_16Uto32, load(Ity_I16, mkexpr(addr2))));
11674
11675 /* Find out whether this is a high surrogate. I.e. SRCVAL lies
11676 inside the interval [0xd800 - 0xdbff] */
11677 IRTemp is_high_surrogate = newTemp(Ity_I32);
11678 IRExpr *flag1 = mkite(binop(Iop_CmpLE32U, mkU32(0xd800), mkexpr(srcval)),
11679 mkU32(1), mkU32(0));
11680 IRExpr *flag2 = mkite(binop(Iop_CmpLE32U, mkexpr(srcval), mkU32(0xdbff)),
11681 mkU32(1), mkU32(0));
11682 assign(is_high_surrogate, binop(Iop_And32, flag1, flag2));
11683
11684 /* If SRCVAL is a high surrogate and there are less than 4 bytes left,
11685 then the 2nd operand is exhausted and we're done here. cc = 0 */
11686 IRExpr *not_enough_bytes =
11687 mkite(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)), mkU32(1), mkU32(0));
11688
florian6820ba52012-07-26 02:01:50 +000011689 next_insn_if(binop(Iop_CmpEQ32,
11690 binop(Iop_And32, mkexpr(is_high_surrogate),
11691 not_enough_bytes),
11692 mkU32(1)));
florian2a415a12012-07-21 17:41:36 +000011693
11694 /* The 2nd operand is not exhausted. If the first 2 bytes are a high
11695 surrogate, read the next two bytes (low surrogate). */
11696 IRTemp low_surrogate = newTemp(Ity_I32);
11697 IRExpr *low_surrogate_addr = binop(Iop_Add64, mkexpr(addr2), mkU64(2));
11698
11699 assign(low_surrogate,
11700 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
11701 unop(Iop_16Uto32, load(Ity_I16, low_surrogate_addr)),
11702 mkU32(0))); // any value is fine; it will not be used
11703
11704 /* Call the helper */
11705 IRTemp retval = newTemp(Ity_I64);
florian11b8ee82012-08-06 13:35:33 +000011706 assign(retval, s390_call_cu24(unop(Iop_32Uto64, mkexpr(srcval)),
11707 unop(Iop_32Uto64, mkexpr(low_surrogate))));
florian2a415a12012-07-21 17:41:36 +000011708
11709 /* Before we can test whether the 1st operand is exhausted we need to
11710 test for an invalid low surrogate. Because cc=2 outranks cc=1. */
11711 if (s390_host_has_etf3 && (m3 & 0x1) == 1) {
11712 IRExpr *invalid_low_surrogate =
11713 binop(Iop_And64, mkexpr(retval), mkU64(0xff));
11714
11715 s390_cc_set(2);
florian6820ba52012-07-26 02:01:50 +000011716 next_insn_if(binop(Iop_CmpEQ64, invalid_low_surrogate, mkU64(1)));
florian2a415a12012-07-21 17:41:36 +000011717 }
11718
11719 /* Now test whether the 1st operand is exhausted */
11720 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000011721 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkU64(4)));
florian2a415a12012-07-21 17:41:36 +000011722
11723 /* Extract the bytes to be stored at addr1 */
11724 IRExpr *data = unop(Iop_64to32, binop(Iop_Shr64, mkexpr(retval), mkU8(8)));
11725
11726 store(mkexpr(addr1), data);
11727
11728 /* Update source address and length */
11729 IRTemp num_src_bytes = newTemp(Ity_I64);
11730 assign(num_src_bytes,
11731 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
11732 mkU64(4), mkU64(2)));
11733 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkexpr(num_src_bytes)));
11734 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkexpr(num_src_bytes)));
11735
11736 /* Update destination address and length */
11737 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkU64(4)));
11738 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkU64(4)));
11739
florian6820ba52012-07-26 02:01:50 +000011740 iterate();
florian2a415a12012-07-21 17:41:36 +000011741
11742 return "cu24";
11743}
floriana4384a32011-08-11 16:58:45 +000011744
florian956194b2012-07-28 22:18:32 +000011745static IRExpr *
11746s390_call_cu42(IRExpr *srcval)
11747{
11748 IRExpr **args, *call;
11749 args = mkIRExprVec_1(srcval);
11750 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
11751 "s390_do_cu42", &s390_do_cu42, args);
11752
11753 /* Nothing is excluded from definedness checking. */
11754 call->Iex.CCall.cee->mcx_mask = 0;
11755
11756 return call;
11757}
11758
11759static HChar *
11760s390_irgen_CU42(UChar r1, UChar r2)
11761{
11762 IRTemp addr1 = newTemp(Ity_I64);
11763 IRTemp addr2 = newTemp(Ity_I64);
11764 IRTemp len1 = newTemp(Ity_I64);
11765 IRTemp len2 = newTemp(Ity_I64);
11766
11767 assign(addr1, get_gpr_dw0(r1));
11768 assign(addr2, get_gpr_dw0(r2));
11769 assign(len1, get_gpr_dw0(r1 + 1));
11770 assign(len2, get_gpr_dw0(r2 + 1));
11771
11772 /* We're processing the 2nd operand 4 bytes at a time. Therefore, if
11773 there are less than 4 bytes left, then the 2nd operand is exhausted
11774 and we're done here. cc = 0 */
11775 s390_cc_set(0);
11776 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)));
11777
11778 /* Read the 2nd operand. */
11779 IRTemp srcval = newTemp(Ity_I32);
11780 assign(srcval, load(Ity_I32, mkexpr(addr2)));
11781
11782 /* Call the helper */
11783 IRTemp retval = newTemp(Ity_I64);
florian11b8ee82012-08-06 13:35:33 +000011784 assign(retval, s390_call_cu42(unop(Iop_32Uto64, mkexpr(srcval))));
florian956194b2012-07-28 22:18:32 +000011785
11786 /* If the UTF-32 character was invalid, set cc=2 and we're done.
11787 cc=2 outranks cc=1 (1st operand exhausted) */
11788 IRExpr *invalid_character = binop(Iop_And64, mkexpr(retval), mkU64(0xff));
11789
11790 s390_cc_set(2);
11791 next_insn_if(binop(Iop_CmpEQ64, invalid_character, mkU64(1)));
11792
11793 /* Now test whether the 1st operand is exhausted */
11794 IRTemp num_bytes = newTemp(Ity_I64);
11795 assign(num_bytes, binop(Iop_And64,
11796 binop(Iop_Shr64, mkexpr(retval), mkU8(8)),
11797 mkU64(0xff)));
11798 s390_cc_set(1);
11799 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
11800
11801 /* Extract the bytes to be stored at addr1 */
11802 IRTemp data = newTemp(Ity_I64);
11803 assign(data, binop(Iop_Shr64, mkexpr(retval), mkU8(16)));
11804
11805 /* To store the bytes construct 2 dirty helper calls. The helper calls
11806 are guarded (num_bytes == 2 and num_bytes == 4, respectively) such
11807 that only one of them will be called at runtime. */
11808
11809 Int i;
11810 for (i = 2; i <= 4; ++i) {
11811 IRDirty *d;
11812
11813 if (i == 3) continue; // skip this one
11814
11815 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
11816 &s390x_dirtyhelper_CUxy,
11817 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
11818 mkexpr(num_bytes)));
11819 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
11820 d->mFx = Ifx_Write;
11821 d->mAddr = mkexpr(addr1);
11822 d->mSize = i;
11823 stmt(IRStmt_Dirty(d));
11824 }
11825
11826 /* Update source address and length */
11827 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkU64(4)));
11828 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkU64(4)));
11829
11830 /* Update destination address and length */
11831 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
11832 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
11833
11834 iterate();
11835
11836 return "cu42";
11837}
11838
florian6d9b9b22012-08-03 18:35:39 +000011839static IRExpr *
florianaf2194f2012-08-06 00:07:54 +000011840s390_call_cu41(IRExpr *srcval)
11841{
11842 IRExpr **args, *call;
11843 args = mkIRExprVec_1(srcval);
11844 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
11845 "s390_do_cu41", &s390_do_cu41, args);
11846
11847 /* Nothing is excluded from definedness checking. */
11848 call->Iex.CCall.cee->mcx_mask = 0;
11849
11850 return call;
11851}
11852
11853static HChar *
11854s390_irgen_CU41(UChar r1, UChar r2)
11855{
11856 IRTemp addr1 = newTemp(Ity_I64);
11857 IRTemp addr2 = newTemp(Ity_I64);
11858 IRTemp len1 = newTemp(Ity_I64);
11859 IRTemp len2 = newTemp(Ity_I64);
11860
11861 assign(addr1, get_gpr_dw0(r1));
11862 assign(addr2, get_gpr_dw0(r2));
11863 assign(len1, get_gpr_dw0(r1 + 1));
11864 assign(len2, get_gpr_dw0(r2 + 1));
11865
11866 /* We're processing the 2nd operand 4 bytes at a time. Therefore, if
11867 there are less than 4 bytes left, then the 2nd operand is exhausted
11868 and we're done here. cc = 0 */
11869 s390_cc_set(0);
11870 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)));
11871
11872 /* Read the 2nd operand. */
11873 IRTemp srcval = newTemp(Ity_I32);
11874 assign(srcval, load(Ity_I32, mkexpr(addr2)));
11875
11876 /* Call the helper */
11877 IRTemp retval = newTemp(Ity_I64);
florian11b8ee82012-08-06 13:35:33 +000011878 assign(retval, s390_call_cu41(unop(Iop_32Uto64, mkexpr(srcval))));
florianaf2194f2012-08-06 00:07:54 +000011879
11880 /* If the UTF-32 character was invalid, set cc=2 and we're done.
11881 cc=2 outranks cc=1 (1st operand exhausted) */
11882 IRExpr *invalid_character = binop(Iop_And64, mkexpr(retval), mkU64(0xff));
11883
11884 s390_cc_set(2);
11885 next_insn_if(binop(Iop_CmpEQ64, invalid_character, mkU64(1)));
11886
11887 /* Now test whether the 1st operand is exhausted */
11888 IRTemp num_bytes = newTemp(Ity_I64);
11889 assign(num_bytes, binop(Iop_And64,
11890 binop(Iop_Shr64, mkexpr(retval), mkU8(8)),
11891 mkU64(0xff)));
11892 s390_cc_set(1);
11893 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
11894
11895 /* Extract the bytes to be stored at addr1 */
11896 IRTemp data = newTemp(Ity_I64);
11897 assign(data, binop(Iop_Shr64, mkexpr(retval), mkU8(16)));
11898
11899 /* To store the bytes construct 4 dirty helper calls. The helper calls
11900 are guarded (num_bytes == 1, num_bytes == 2, etc) such that only
11901 one of them will be called at runtime. */
11902 int i;
11903 for (i = 1; i <= 4; ++i) {
11904 IRDirty *d;
11905
11906 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
11907 &s390x_dirtyhelper_CUxy,
11908 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
11909 mkexpr(num_bytes)));
11910 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
11911 d->mFx = Ifx_Write;
11912 d->mAddr = mkexpr(addr1);
11913 d->mSize = i;
11914 stmt(IRStmt_Dirty(d));
11915 }
11916
11917 /* Update source address and length */
11918 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkU64(4)));
11919 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkU64(4)));
11920
11921 /* Update destination address and length */
11922 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
11923 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
11924
11925 iterate();
11926
11927 return "cu41";
11928}
11929
11930static IRExpr *
florian3f8a96a2012-08-05 02:59:55 +000011931s390_call_cu12_cu14_helper1(IRExpr *byte1, IRExpr *etf3_and_m3_is_1)
florian6d9b9b22012-08-03 18:35:39 +000011932{
11933 IRExpr **args, *call;
11934 args = mkIRExprVec_2(byte1, etf3_and_m3_is_1);
florian3f8a96a2012-08-05 02:59:55 +000011935 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/, "s390_do_cu12_cu14_helper1",
11936 &s390_do_cu12_cu14_helper1, args);
florian6d9b9b22012-08-03 18:35:39 +000011937
11938 /* Nothing is excluded from definedness checking. */
11939 call->Iex.CCall.cee->mcx_mask = 0;
11940
11941 return call;
11942}
11943
11944static IRExpr *
11945s390_call_cu12_helper2(IRExpr *byte1, IRExpr *byte2, IRExpr *byte3,
11946 IRExpr *byte4, IRExpr *stuff)
11947{
11948 IRExpr **args, *call;
11949 args = mkIRExprVec_5(byte1, byte2, byte3, byte4, stuff);
11950 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
11951 "s390_do_cu12_helper2", &s390_do_cu12_helper2, args);
11952
11953 /* Nothing is excluded from definedness checking. */
11954 call->Iex.CCall.cee->mcx_mask = 0;
11955
11956 return call;
11957}
11958
florian3f8a96a2012-08-05 02:59:55 +000011959static IRExpr *
11960s390_call_cu14_helper2(IRExpr *byte1, IRExpr *byte2, IRExpr *byte3,
11961 IRExpr *byte4, IRExpr *stuff)
11962{
11963 IRExpr **args, *call;
11964 args = mkIRExprVec_5(byte1, byte2, byte3, byte4, stuff);
11965 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
11966 "s390_do_cu14_helper2", &s390_do_cu14_helper2, args);
11967
11968 /* Nothing is excluded from definedness checking. */
11969 call->Iex.CCall.cee->mcx_mask = 0;
11970
11971 return call;
11972}
11973
11974static void
11975s390_irgen_cu12_cu14(UChar m3, UChar r1, UChar r2, Bool is_cu12)
florian6d9b9b22012-08-03 18:35:39 +000011976{
11977 IRTemp addr1 = newTemp(Ity_I64);
11978 IRTemp addr2 = newTemp(Ity_I64);
11979 IRTemp len1 = newTemp(Ity_I64);
11980 IRTemp len2 = newTemp(Ity_I64);
11981
11982 assign(addr1, get_gpr_dw0(r1));
11983 assign(addr2, get_gpr_dw0(r2));
11984 assign(len1, get_gpr_dw0(r1 + 1));
11985 assign(len2, get_gpr_dw0(r2 + 1));
11986
11987 UInt extended_checking = s390_host_has_etf3 && (m3 & 0x1) == 1;
11988
11989 /* We're processing the 2nd operand 1 byte at a time. Therefore, if
11990 there is less than 1 byte left, then the 2nd operand is exhausted
11991 and we're done here. cc = 0 */
11992 s390_cc_set(0);
11993 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(1)));
11994
11995 /* There is at least one byte there. Read it. */
florian11b8ee82012-08-06 13:35:33 +000011996 IRTemp byte1 = newTemp(Ity_I64);
11997 assign(byte1, unop(Iop_8Uto64, load(Ity_I8, mkexpr(addr2))));
florian6d9b9b22012-08-03 18:35:39 +000011998
11999 /* Call the helper to get number of bytes and invalid byte indicator */
12000 IRTemp retval1 = newTemp(Ity_I64);
florian3f8a96a2012-08-05 02:59:55 +000012001 assign(retval1, s390_call_cu12_cu14_helper1(mkexpr(byte1),
florian11b8ee82012-08-06 13:35:33 +000012002 mkU64(extended_checking)));
florian6d9b9b22012-08-03 18:35:39 +000012003
12004 /* Check for invalid 1st byte */
12005 IRExpr *is_invalid = unop(Iop_64to1, mkexpr(retval1));
12006 s390_cc_set(2);
12007 next_insn_if(is_invalid);
12008
12009 /* How many bytes do we have to read? */
12010 IRTemp num_src_bytes = newTemp(Ity_I64);
12011 assign(num_src_bytes, binop(Iop_Shr64, mkexpr(retval1), mkU8(8)));
12012
12013 /* Now test whether the 2nd operand is exhausted */
12014 s390_cc_set(0);
12015 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkexpr(num_src_bytes)));
12016
12017 /* Read the remaining bytes */
12018 IRExpr *cond, *addr, *byte2, *byte3, *byte4;
12019
12020 cond = binop(Iop_CmpLE64U, mkU64(2), mkexpr(num_src_bytes));
12021 addr = binop(Iop_Add64, mkexpr(addr2), mkU64(1));
florian11b8ee82012-08-06 13:35:33 +000012022 byte2 = mkite(cond, unop(Iop_8Uto64, load(Ity_I8, addr)), mkU64(0));
florian6d9b9b22012-08-03 18:35:39 +000012023 cond = binop(Iop_CmpLE64U, mkU64(3), mkexpr(num_src_bytes));
12024 addr = binop(Iop_Add64, mkexpr(addr2), mkU64(2));
florian11b8ee82012-08-06 13:35:33 +000012025 byte3 = mkite(cond, unop(Iop_8Uto64, load(Ity_I8, addr)), mkU64(0));
florian6d9b9b22012-08-03 18:35:39 +000012026 cond = binop(Iop_CmpLE64U, mkU64(4), mkexpr(num_src_bytes));
12027 addr = binop(Iop_Add64, mkexpr(addr2), mkU64(3));
florian11b8ee82012-08-06 13:35:33 +000012028 byte4 = mkite(cond, unop(Iop_8Uto64, load(Ity_I8, addr)), mkU64(0));
florian6d9b9b22012-08-03 18:35:39 +000012029
12030 /* Call the helper to get the converted value and invalid byte indicator.
12031 We can pass at most 5 arguments; therefore some encoding is needed
12032 here */
12033 IRExpr *stuff = binop(Iop_Or64,
12034 binop(Iop_Shl64, mkexpr(num_src_bytes), mkU8(1)),
12035 mkU64(extended_checking));
12036 IRTemp retval2 = newTemp(Ity_I64);
florian3f8a96a2012-08-05 02:59:55 +000012037
12038 if (is_cu12) {
12039 assign(retval2, s390_call_cu12_helper2(mkexpr(byte1), byte2, byte3,
12040 byte4, stuff));
12041 } else {
12042 assign(retval2, s390_call_cu14_helper2(mkexpr(byte1), byte2, byte3,
12043 byte4, stuff));
12044 }
florian6d9b9b22012-08-03 18:35:39 +000012045
12046 /* Check for invalid character */
12047 s390_cc_set(2);
12048 is_invalid = unop(Iop_64to1, mkexpr(retval2));
12049 next_insn_if(is_invalid);
12050
12051 /* Now test whether the 1st operand is exhausted */
12052 IRTemp num_bytes = newTemp(Ity_I64);
12053 assign(num_bytes, binop(Iop_And64,
12054 binop(Iop_Shr64, mkexpr(retval2), mkU8(8)),
12055 mkU64(0xff)));
12056 s390_cc_set(1);
12057 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
12058
12059 /* Extract the bytes to be stored at addr1 */
12060 IRTemp data = newTemp(Ity_I64);
12061 assign(data, binop(Iop_Shr64, mkexpr(retval2), mkU8(16)));
12062
florian3f8a96a2012-08-05 02:59:55 +000012063 if (is_cu12) {
12064 /* To store the bytes construct 2 dirty helper calls. The helper calls
12065 are guarded (num_bytes == 2 and num_bytes == 4, respectively) such
12066 that only one of them will be called at runtime. */
florian6d9b9b22012-08-03 18:35:39 +000012067
florian3f8a96a2012-08-05 02:59:55 +000012068 Int i;
12069 for (i = 2; i <= 4; ++i) {
12070 IRDirty *d;
florian6d9b9b22012-08-03 18:35:39 +000012071
florian3f8a96a2012-08-05 02:59:55 +000012072 if (i == 3) continue; // skip this one
florian6d9b9b22012-08-03 18:35:39 +000012073
florian3f8a96a2012-08-05 02:59:55 +000012074 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
12075 &s390x_dirtyhelper_CUxy,
12076 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
12077 mkexpr(num_bytes)));
12078 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
12079 d->mFx = Ifx_Write;
12080 d->mAddr = mkexpr(addr1);
12081 d->mSize = i;
12082 stmt(IRStmt_Dirty(d));
12083 }
12084 } else {
12085 // cu14
12086 store(mkexpr(addr1), unop(Iop_64to32, mkexpr(data)));
florian6d9b9b22012-08-03 18:35:39 +000012087 }
12088
12089 /* Update source address and length */
12090 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkexpr(num_src_bytes)));
12091 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkexpr(num_src_bytes)));
12092
12093 /* Update destination address and length */
12094 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
12095 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
12096
12097 iterate();
florian3f8a96a2012-08-05 02:59:55 +000012098}
12099
12100static HChar *
12101s390_irgen_CU12(UChar m3, UChar r1, UChar r2)
12102{
12103 s390_irgen_cu12_cu14(m3, r1, r2, /* is_cu12 = */ 1);
florian6d9b9b22012-08-03 18:35:39 +000012104
12105 return "cu12";
12106}
12107
florian3f8a96a2012-08-05 02:59:55 +000012108static HChar *
12109s390_irgen_CU14(UChar m3, UChar r1, UChar r2)
12110{
12111 s390_irgen_cu12_cu14(m3, r1, r2, /* is_cu12 = */ 0);
12112
12113 return "cu14";
12114}
12115
florian8c88cb62012-08-26 18:58:13 +000012116static IRExpr *
12117s390_call_ecag(IRExpr *op2addr)
12118{
12119 IRExpr **args, *call;
12120
12121 args = mkIRExprVec_1(op2addr);
12122 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
12123 "s390_do_ecag", &s390_do_ecag, args);
12124
12125 /* Nothing is excluded from definedness checking. */
12126 call->Iex.CCall.cee->mcx_mask = 0;
12127
12128 return call;
12129}
12130
12131static HChar *
floriand2129202012-09-01 20:01:39 +000012132s390_irgen_ECAG(UChar r1, UChar r3 __attribute__((unused)), IRTemp op2addr)
florian8c88cb62012-08-26 18:58:13 +000012133{
12134 if (! s390_host_has_gie) {
floriane75dafa2012-09-01 17:54:09 +000012135 emulation_failure(EmFail_S390X_ecag);
florian8c88cb62012-08-26 18:58:13 +000012136 } else {
12137 put_gpr_dw0(r1, s390_call_ecag(mkexpr(op2addr)));
12138 }
12139
12140 return "ecag";
12141}
12142
12143
sewardj2019a972011-03-07 16:04:07 +000012144/*------------------------------------------------------------*/
12145/*--- Build IR for special instructions ---*/
12146/*------------------------------------------------------------*/
12147
florianb4df7682011-07-05 02:09:01 +000012148static void
sewardj2019a972011-03-07 16:04:07 +000012149s390_irgen_client_request(void)
12150{
12151 if (0)
12152 vex_printf("%%R3 = client_request ( %%R2 )\n");
12153
florianf9e1ed72012-04-17 02:41:56 +000012154 Addr64 next = guest_IA_curr_instr + S390_SPECIAL_OP_PREAMBLE_SIZE
12155 + S390_SPECIAL_OP_SIZE;
sewardj2019a972011-03-07 16:04:07 +000012156
florianf9e1ed72012-04-17 02:41:56 +000012157 dis_res->jk_StopHere = Ijk_ClientReq;
sewardj2019a972011-03-07 16:04:07 +000012158 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +000012159
12160 put_IA(mkaddr_expr(next));
sewardj2019a972011-03-07 16:04:07 +000012161}
12162
florianb4df7682011-07-05 02:09:01 +000012163static void
sewardj2019a972011-03-07 16:04:07 +000012164s390_irgen_guest_NRADDR(void)
12165{
12166 if (0)
12167 vex_printf("%%R3 = guest_NRADDR\n");
12168
floriane88b3c92011-07-05 02:48:39 +000012169 put_gpr_dw0(3, IRExpr_Get(S390X_GUEST_OFFSET(guest_NRADDR), Ity_I64));
sewardj2019a972011-03-07 16:04:07 +000012170}
12171
florianb4df7682011-07-05 02:09:01 +000012172static void
sewardj2019a972011-03-07 16:04:07 +000012173s390_irgen_call_noredir(void)
12174{
florianf9e1ed72012-04-17 02:41:56 +000012175 Addr64 next = guest_IA_curr_instr + S390_SPECIAL_OP_PREAMBLE_SIZE
12176 + S390_SPECIAL_OP_SIZE;
12177
sewardj2019a972011-03-07 16:04:07 +000012178 /* Continue after special op */
florianf9e1ed72012-04-17 02:41:56 +000012179 put_gpr_dw0(14, mkaddr_expr(next));
sewardj2019a972011-03-07 16:04:07 +000012180
12181 /* The address is in REG1, all parameters are in the right (guest) places */
florianf9e1ed72012-04-17 02:41:56 +000012182 put_IA(get_gpr_dw0(1));
sewardj2019a972011-03-07 16:04:07 +000012183
12184 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +000012185 dis_res->jk_StopHere = Ijk_NoRedir;
sewardj2019a972011-03-07 16:04:07 +000012186}
12187
12188/* Force proper alignment for the structures below. */
12189#pragma pack(1)
12190
12191
12192static s390_decode_t
12193s390_decode_2byte_and_irgen(UChar *bytes)
12194{
12195 typedef union {
12196 struct {
12197 unsigned int op : 16;
12198 } E;
12199 struct {
12200 unsigned int op : 8;
12201 unsigned int i : 8;
12202 } I;
12203 struct {
12204 unsigned int op : 8;
12205 unsigned int r1 : 4;
12206 unsigned int r2 : 4;
12207 } RR;
12208 } formats;
12209 union {
12210 formats fmt;
12211 UShort value;
12212 } ovl;
12213
12214 vassert(sizeof(formats) == 2);
12215
12216 ((char *)(&ovl.value))[0] = bytes[0];
12217 ((char *)(&ovl.value))[1] = bytes[1];
12218
12219 switch (ovl.value & 0xffff) {
12220 case 0x0101: /* PR */ goto unimplemented;
12221 case 0x0102: /* UPT */ goto unimplemented;
12222 case 0x0104: /* PTFF */ goto unimplemented;
12223 case 0x0107: /* SCKPF */ goto unimplemented;
12224 case 0x010a: /* PFPO */ goto unimplemented;
12225 case 0x010b: /* TAM */ goto unimplemented;
12226 case 0x010c: /* SAM24 */ goto unimplemented;
12227 case 0x010d: /* SAM31 */ goto unimplemented;
12228 case 0x010e: /* SAM64 */ goto unimplemented;
12229 case 0x01ff: /* TRAP2 */ goto unimplemented;
12230 }
12231
12232 switch ((ovl.value & 0xff00) >> 8) {
12233 case 0x04: /* SPM */ goto unimplemented;
12234 case 0x05: /* BALR */ goto unimplemented;
12235 case 0x06: s390_format_RR_RR(s390_irgen_BCTR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12236 goto ok;
12237 case 0x07: s390_format_RR(s390_irgen_BCR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12238 goto ok;
12239 case 0x0a: s390_format_I(s390_irgen_SVC, ovl.fmt.I.i); goto ok;
12240 case 0x0b: /* BSM */ goto unimplemented;
12241 case 0x0c: /* BASSM */ goto unimplemented;
12242 case 0x0d: s390_format_RR_RR(s390_irgen_BASR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12243 goto ok;
florianb0c9a132011-09-08 15:37:39 +000012244 case 0x0e: s390_format_RR(s390_irgen_MVCL, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12245 goto ok;
12246 case 0x0f: s390_format_RR(s390_irgen_CLCL, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12247 goto ok;
sewardj2019a972011-03-07 16:04:07 +000012248 case 0x10: s390_format_RR_RR(s390_irgen_LPR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12249 goto ok;
12250 case 0x11: s390_format_RR_RR(s390_irgen_LNR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12251 goto ok;
12252 case 0x12: s390_format_RR_RR(s390_irgen_LTR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12253 goto ok;
12254 case 0x13: s390_format_RR_RR(s390_irgen_LCR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12255 goto ok;
12256 case 0x14: s390_format_RR_RR(s390_irgen_NR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12257 goto ok;
12258 case 0x15: s390_format_RR_RR(s390_irgen_CLR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12259 goto ok;
12260 case 0x16: s390_format_RR_RR(s390_irgen_OR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12261 goto ok;
12262 case 0x17: s390_format_RR_RR(s390_irgen_XR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12263 goto ok;
12264 case 0x18: s390_format_RR_RR(s390_irgen_LR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12265 goto ok;
12266 case 0x19: s390_format_RR_RR(s390_irgen_CR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12267 goto ok;
12268 case 0x1a: s390_format_RR_RR(s390_irgen_AR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12269 goto ok;
12270 case 0x1b: s390_format_RR_RR(s390_irgen_SR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12271 goto ok;
12272 case 0x1c: s390_format_RR_RR(s390_irgen_MR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12273 goto ok;
12274 case 0x1d: s390_format_RR_RR(s390_irgen_DR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12275 goto ok;
12276 case 0x1e: s390_format_RR_RR(s390_irgen_ALR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12277 goto ok;
12278 case 0x1f: s390_format_RR_RR(s390_irgen_SLR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12279 goto ok;
12280 case 0x20: /* LPDR */ goto unimplemented;
12281 case 0x21: /* LNDR */ goto unimplemented;
12282 case 0x22: /* LTDR */ goto unimplemented;
12283 case 0x23: /* LCDR */ goto unimplemented;
12284 case 0x24: /* HDR */ goto unimplemented;
12285 case 0x25: /* LDXR */ goto unimplemented;
12286 case 0x26: /* MXR */ goto unimplemented;
12287 case 0x27: /* MXDR */ goto unimplemented;
12288 case 0x28: s390_format_RR_FF(s390_irgen_LDR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12289 goto ok;
12290 case 0x29: /* CDR */ goto unimplemented;
12291 case 0x2a: /* ADR */ goto unimplemented;
12292 case 0x2b: /* SDR */ goto unimplemented;
12293 case 0x2c: /* MDR */ goto unimplemented;
12294 case 0x2d: /* DDR */ goto unimplemented;
12295 case 0x2e: /* AWR */ goto unimplemented;
12296 case 0x2f: /* SWR */ goto unimplemented;
12297 case 0x30: /* LPER */ goto unimplemented;
12298 case 0x31: /* LNER */ goto unimplemented;
12299 case 0x32: /* LTER */ goto unimplemented;
12300 case 0x33: /* LCER */ goto unimplemented;
12301 case 0x34: /* HER */ goto unimplemented;
12302 case 0x35: /* LEDR */ goto unimplemented;
12303 case 0x36: /* AXR */ goto unimplemented;
12304 case 0x37: /* SXR */ goto unimplemented;
12305 case 0x38: s390_format_RR_FF(s390_irgen_LER, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12306 goto ok;
12307 case 0x39: /* CER */ goto unimplemented;
12308 case 0x3a: /* AER */ goto unimplemented;
12309 case 0x3b: /* SER */ goto unimplemented;
12310 case 0x3c: /* MDER */ goto unimplemented;
12311 case 0x3d: /* DER */ goto unimplemented;
12312 case 0x3e: /* AUR */ goto unimplemented;
12313 case 0x3f: /* SUR */ goto unimplemented;
12314 }
12315
12316 return S390_DECODE_UNKNOWN_INSN;
12317
12318ok:
12319 return S390_DECODE_OK;
12320
12321unimplemented:
12322 return S390_DECODE_UNIMPLEMENTED_INSN;
12323}
12324
12325static s390_decode_t
12326s390_decode_4byte_and_irgen(UChar *bytes)
12327{
12328 typedef union {
12329 struct {
12330 unsigned int op1 : 8;
12331 unsigned int r1 : 4;
12332 unsigned int op2 : 4;
12333 unsigned int i2 : 16;
12334 } RI;
12335 struct {
12336 unsigned int op : 16;
12337 unsigned int : 8;
12338 unsigned int r1 : 4;
12339 unsigned int r2 : 4;
12340 } RRE;
12341 struct {
12342 unsigned int op : 16;
12343 unsigned int r1 : 4;
12344 unsigned int : 4;
12345 unsigned int r3 : 4;
12346 unsigned int r2 : 4;
12347 } RRF;
12348 struct {
12349 unsigned int op : 16;
florian1c8f7ff2012-09-01 00:12:11 +000012350 unsigned int m3 : 4;
sewardj2019a972011-03-07 16:04:07 +000012351 unsigned int m4 : 4;
12352 unsigned int r1 : 4;
12353 unsigned int r2 : 4;
12354 } RRF2;
12355 struct {
12356 unsigned int op : 16;
12357 unsigned int r3 : 4;
12358 unsigned int : 4;
12359 unsigned int r1 : 4;
12360 unsigned int r2 : 4;
12361 } RRF3;
12362 struct {
12363 unsigned int op : 16;
12364 unsigned int r3 : 4;
12365 unsigned int : 4;
12366 unsigned int r1 : 4;
12367 unsigned int r2 : 4;
12368 } RRR;
12369 struct {
12370 unsigned int op : 16;
12371 unsigned int r3 : 4;
12372 unsigned int : 4;
12373 unsigned int r1 : 4;
12374 unsigned int r2 : 4;
12375 } RRF4;
12376 struct {
12377 unsigned int op : 8;
12378 unsigned int r1 : 4;
12379 unsigned int r3 : 4;
12380 unsigned int b2 : 4;
12381 unsigned int d2 : 12;
12382 } RS;
12383 struct {
12384 unsigned int op : 8;
12385 unsigned int r1 : 4;
12386 unsigned int r3 : 4;
12387 unsigned int i2 : 16;
12388 } RSI;
12389 struct {
12390 unsigned int op : 8;
12391 unsigned int r1 : 4;
12392 unsigned int x2 : 4;
12393 unsigned int b2 : 4;
12394 unsigned int d2 : 12;
12395 } RX;
12396 struct {
12397 unsigned int op : 16;
12398 unsigned int b2 : 4;
12399 unsigned int d2 : 12;
12400 } S;
12401 struct {
12402 unsigned int op : 8;
12403 unsigned int i2 : 8;
12404 unsigned int b1 : 4;
12405 unsigned int d1 : 12;
12406 } SI;
12407 } formats;
12408 union {
12409 formats fmt;
12410 UInt value;
12411 } ovl;
12412
12413 vassert(sizeof(formats) == 4);
12414
12415 ((char *)(&ovl.value))[0] = bytes[0];
12416 ((char *)(&ovl.value))[1] = bytes[1];
12417 ((char *)(&ovl.value))[2] = bytes[2];
12418 ((char *)(&ovl.value))[3] = bytes[3];
12419
12420 switch ((ovl.value & 0xff0f0000) >> 16) {
12421 case 0xa500: s390_format_RI_RU(s390_irgen_IIHH, ovl.fmt.RI.r1,
12422 ovl.fmt.RI.i2); goto ok;
12423 case 0xa501: s390_format_RI_RU(s390_irgen_IIHL, ovl.fmt.RI.r1,
12424 ovl.fmt.RI.i2); goto ok;
12425 case 0xa502: s390_format_RI_RU(s390_irgen_IILH, ovl.fmt.RI.r1,
12426 ovl.fmt.RI.i2); goto ok;
12427 case 0xa503: s390_format_RI_RU(s390_irgen_IILL, ovl.fmt.RI.r1,
12428 ovl.fmt.RI.i2); goto ok;
12429 case 0xa504: s390_format_RI_RU(s390_irgen_NIHH, ovl.fmt.RI.r1,
12430 ovl.fmt.RI.i2); goto ok;
12431 case 0xa505: s390_format_RI_RU(s390_irgen_NIHL, ovl.fmt.RI.r1,
12432 ovl.fmt.RI.i2); goto ok;
12433 case 0xa506: s390_format_RI_RU(s390_irgen_NILH, ovl.fmt.RI.r1,
12434 ovl.fmt.RI.i2); goto ok;
12435 case 0xa507: s390_format_RI_RU(s390_irgen_NILL, ovl.fmt.RI.r1,
12436 ovl.fmt.RI.i2); goto ok;
12437 case 0xa508: s390_format_RI_RU(s390_irgen_OIHH, ovl.fmt.RI.r1,
12438 ovl.fmt.RI.i2); goto ok;
12439 case 0xa509: s390_format_RI_RU(s390_irgen_OIHL, ovl.fmt.RI.r1,
12440 ovl.fmt.RI.i2); goto ok;
12441 case 0xa50a: s390_format_RI_RU(s390_irgen_OILH, ovl.fmt.RI.r1,
12442 ovl.fmt.RI.i2); goto ok;
12443 case 0xa50b: s390_format_RI_RU(s390_irgen_OILL, ovl.fmt.RI.r1,
12444 ovl.fmt.RI.i2); goto ok;
12445 case 0xa50c: s390_format_RI_RU(s390_irgen_LLIHH, ovl.fmt.RI.r1,
12446 ovl.fmt.RI.i2); goto ok;
12447 case 0xa50d: s390_format_RI_RU(s390_irgen_LLIHL, ovl.fmt.RI.r1,
12448 ovl.fmt.RI.i2); goto ok;
12449 case 0xa50e: s390_format_RI_RU(s390_irgen_LLILH, ovl.fmt.RI.r1,
12450 ovl.fmt.RI.i2); goto ok;
12451 case 0xa50f: s390_format_RI_RU(s390_irgen_LLILL, ovl.fmt.RI.r1,
12452 ovl.fmt.RI.i2); goto ok;
12453 case 0xa700: s390_format_RI_RU(s390_irgen_TMLH, ovl.fmt.RI.r1,
12454 ovl.fmt.RI.i2); goto ok;
12455 case 0xa701: s390_format_RI_RU(s390_irgen_TMLL, ovl.fmt.RI.r1,
12456 ovl.fmt.RI.i2); goto ok;
12457 case 0xa702: s390_format_RI_RU(s390_irgen_TMHH, ovl.fmt.RI.r1,
12458 ovl.fmt.RI.i2); goto ok;
12459 case 0xa703: s390_format_RI_RU(s390_irgen_TMHL, ovl.fmt.RI.r1,
12460 ovl.fmt.RI.i2); goto ok;
12461 case 0xa704: s390_format_RI(s390_irgen_BRC, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
12462 goto ok;
12463 case 0xa705: s390_format_RI_RP(s390_irgen_BRAS, ovl.fmt.RI.r1,
12464 ovl.fmt.RI.i2); goto ok;
12465 case 0xa706: s390_format_RI_RP(s390_irgen_BRCT, ovl.fmt.RI.r1,
12466 ovl.fmt.RI.i2); goto ok;
12467 case 0xa707: s390_format_RI_RP(s390_irgen_BRCTG, ovl.fmt.RI.r1,
12468 ovl.fmt.RI.i2); goto ok;
12469 case 0xa708: s390_format_RI_RI(s390_irgen_LHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
12470 goto ok;
12471 case 0xa709: s390_format_RI_RI(s390_irgen_LGHI, ovl.fmt.RI.r1,
12472 ovl.fmt.RI.i2); goto ok;
12473 case 0xa70a: s390_format_RI_RI(s390_irgen_AHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
12474 goto ok;
12475 case 0xa70b: s390_format_RI_RI(s390_irgen_AGHI, ovl.fmt.RI.r1,
12476 ovl.fmt.RI.i2); goto ok;
12477 case 0xa70c: s390_format_RI_RI(s390_irgen_MHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
12478 goto ok;
12479 case 0xa70d: s390_format_RI_RI(s390_irgen_MGHI, ovl.fmt.RI.r1,
12480 ovl.fmt.RI.i2); goto ok;
12481 case 0xa70e: s390_format_RI_RI(s390_irgen_CHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
12482 goto ok;
12483 case 0xa70f: s390_format_RI_RI(s390_irgen_CGHI, ovl.fmt.RI.r1,
12484 ovl.fmt.RI.i2); goto ok;
12485 }
12486
12487 switch ((ovl.value & 0xffff0000) >> 16) {
12488 case 0x8000: /* SSM */ goto unimplemented;
12489 case 0x8200: /* LPSW */ goto unimplemented;
florian7700fc92012-01-16 17:25:55 +000012490 case 0x9300: /* TS */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000012491 case 0xb202: /* STIDP */ goto unimplemented;
12492 case 0xb204: /* SCK */ goto unimplemented;
florian7700fc92012-01-16 17:25:55 +000012493 case 0xb205: s390_format_S_RD(s390_irgen_STCK, ovl.fmt.S.b2, ovl.fmt.S.d2);
12494 goto ok;
sewardj2019a972011-03-07 16:04:07 +000012495 case 0xb206: /* SCKC */ goto unimplemented;
12496 case 0xb207: /* STCKC */ goto unimplemented;
12497 case 0xb208: /* SPT */ goto unimplemented;
12498 case 0xb209: /* STPT */ goto unimplemented;
12499 case 0xb20a: /* SPKA */ goto unimplemented;
12500 case 0xb20b: /* IPK */ goto unimplemented;
12501 case 0xb20d: /* PTLB */ goto unimplemented;
12502 case 0xb210: /* SPX */ goto unimplemented;
12503 case 0xb211: /* STPX */ goto unimplemented;
12504 case 0xb212: /* STAP */ goto unimplemented;
12505 case 0xb214: /* SIE */ goto unimplemented;
12506 case 0xb218: /* PC */ goto unimplemented;
12507 case 0xb219: /* SAC */ goto unimplemented;
12508 case 0xb21a: /* CFC */ goto unimplemented;
12509 case 0xb221: /* IPTE */ goto unimplemented;
12510 case 0xb222: s390_format_RRE_R0(s390_irgen_IPM, ovl.fmt.RRE.r1); goto ok;
12511 case 0xb223: /* IVSK */ goto unimplemented;
12512 case 0xb224: /* IAC */ goto unimplemented;
12513 case 0xb225: /* SSAR */ goto unimplemented;
12514 case 0xb226: /* EPAR */ goto unimplemented;
12515 case 0xb227: /* ESAR */ goto unimplemented;
12516 case 0xb228: /* PT */ goto unimplemented;
12517 case 0xb229: /* ISKE */ goto unimplemented;
12518 case 0xb22a: /* RRBE */ goto unimplemented;
12519 case 0xb22b: /* SSKE */ goto unimplemented;
12520 case 0xb22c: /* TB */ goto unimplemented;
12521 case 0xb22d: /* DXR */ goto unimplemented;
12522 case 0xb22e: /* PGIN */ goto unimplemented;
12523 case 0xb22f: /* PGOUT */ goto unimplemented;
12524 case 0xb230: /* CSCH */ goto unimplemented;
12525 case 0xb231: /* HSCH */ goto unimplemented;
12526 case 0xb232: /* MSCH */ goto unimplemented;
12527 case 0xb233: /* SSCH */ goto unimplemented;
12528 case 0xb234: /* STSCH */ goto unimplemented;
12529 case 0xb235: /* TSCH */ goto unimplemented;
12530 case 0xb236: /* TPI */ goto unimplemented;
12531 case 0xb237: /* SAL */ goto unimplemented;
12532 case 0xb238: /* RSCH */ goto unimplemented;
12533 case 0xb239: /* STCRW */ goto unimplemented;
12534 case 0xb23a: /* STCPS */ goto unimplemented;
12535 case 0xb23b: /* RCHP */ goto unimplemented;
12536 case 0xb23c: /* SCHM */ goto unimplemented;
12537 case 0xb240: /* BAKR */ goto unimplemented;
floriana4384a32011-08-11 16:58:45 +000012538 case 0xb241: s390_format_RRE(s390_irgen_CKSM, ovl.fmt.RRE.r1,
12539 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000012540 case 0xb244: /* SQDR */ goto unimplemented;
12541 case 0xb245: /* SQER */ goto unimplemented;
12542 case 0xb246: /* STURA */ goto unimplemented;
12543 case 0xb247: /* MSTA */ goto unimplemented;
12544 case 0xb248: /* PALB */ goto unimplemented;
12545 case 0xb249: /* EREG */ goto unimplemented;
12546 case 0xb24a: /* ESTA */ goto unimplemented;
12547 case 0xb24b: /* LURA */ goto unimplemented;
12548 case 0xb24c: /* TAR */ goto unimplemented;
12549 case 0xb24d: s390_format_RRE(s390_irgen_CPYA, ovl.fmt.RRE.r1,
12550 ovl.fmt.RRE.r2); goto ok;
12551 case 0xb24e: s390_format_RRE(s390_irgen_SAR, ovl.fmt.RRE.r1, ovl.fmt.RRE.r2);
12552 goto ok;
12553 case 0xb24f: s390_format_RRE(s390_irgen_EAR, ovl.fmt.RRE.r1, ovl.fmt.RRE.r2);
12554 goto ok;
12555 case 0xb250: /* CSP */ goto unimplemented;
12556 case 0xb252: s390_format_RRE_RR(s390_irgen_MSR, ovl.fmt.RRE.r1,
12557 ovl.fmt.RRE.r2); goto ok;
12558 case 0xb254: /* MVPG */ goto unimplemented;
12559 case 0xb255: s390_format_RRE_RR(s390_irgen_MVST, ovl.fmt.RRE.r1,
12560 ovl.fmt.RRE.r2); goto ok;
12561 case 0xb257: /* CUSE */ goto unimplemented;
12562 case 0xb258: /* BSG */ goto unimplemented;
12563 case 0xb25a: /* BSA */ goto unimplemented;
12564 case 0xb25d: s390_format_RRE_RR(s390_irgen_CLST, ovl.fmt.RRE.r1,
12565 ovl.fmt.RRE.r2); goto ok;
12566 case 0xb25e: s390_format_RRE_RR(s390_irgen_SRST, ovl.fmt.RRE.r1,
12567 ovl.fmt.RRE.r2); goto ok;
12568 case 0xb263: /* CMPSC */ goto unimplemented;
12569 case 0xb274: /* SIGA */ goto unimplemented;
12570 case 0xb276: /* XSCH */ goto unimplemented;
12571 case 0xb277: /* RP */ goto unimplemented;
sewardj1e5fea62011-05-17 16:18:36 +000012572 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 +000012573 case 0xb279: /* SACF */ goto unimplemented;
sewardj1e5fea62011-05-17 16:18:36 +000012574 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 +000012575 case 0xb27d: /* STSI */ goto unimplemented;
12576 case 0xb299: s390_format_S_RD(s390_irgen_SRNM, ovl.fmt.S.b2, ovl.fmt.S.d2);
12577 goto ok;
12578 case 0xb29c: s390_format_S_RD(s390_irgen_STFPC, ovl.fmt.S.b2, ovl.fmt.S.d2);
12579 goto ok;
12580 case 0xb29d: s390_format_S_RD(s390_irgen_LFPC, ovl.fmt.S.b2, ovl.fmt.S.d2);
12581 goto ok;
florian730448f2012-02-04 17:07:07 +000012582 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 +000012583 case 0xb2a6: s390_format_RRF_M0RERE(s390_irgen_CU21, ovl.fmt.RRF3.r3,
12584 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
12585 goto ok;
florian6d9b9b22012-08-03 18:35:39 +000012586 case 0xb2a7: s390_format_RRF_M0RERE(s390_irgen_CU12, ovl.fmt.RRF3.r3,
12587 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
12588 goto ok;
florian933065d2011-07-11 01:48:02 +000012589 case 0xb2b0: s390_format_S_RD(s390_irgen_STFLE, ovl.fmt.S.b2, ovl.fmt.S.d2);
12590 goto ok;
sewardj2019a972011-03-07 16:04:07 +000012591 case 0xb2b1: /* STFL */ goto unimplemented;
12592 case 0xb2b2: /* LPSWE */ goto unimplemented;
12593 case 0xb2b8: /* SRNMB */ goto unimplemented;
12594 case 0xb2b9: /* SRNMT */ goto unimplemented;
12595 case 0xb2bd: /* LFAS */ goto unimplemented;
12596 case 0xb2ff: /* TRAP4 */ goto unimplemented;
12597 case 0xb300: s390_format_RRE_FF(s390_irgen_LPEBR, ovl.fmt.RRE.r1,
12598 ovl.fmt.RRE.r2); goto ok;
12599 case 0xb301: s390_format_RRE_FF(s390_irgen_LNEBR, ovl.fmt.RRE.r1,
12600 ovl.fmt.RRE.r2); goto ok;
12601 case 0xb302: s390_format_RRE_FF(s390_irgen_LTEBR, ovl.fmt.RRE.r1,
12602 ovl.fmt.RRE.r2); goto ok;
12603 case 0xb303: s390_format_RRE_FF(s390_irgen_LCEBR, ovl.fmt.RRE.r1,
12604 ovl.fmt.RRE.r2); goto ok;
12605 case 0xb304: s390_format_RRE_FF(s390_irgen_LDEBR, ovl.fmt.RRE.r1,
12606 ovl.fmt.RRE.r2); goto ok;
12607 case 0xb305: s390_format_RRE_FF(s390_irgen_LXDBR, ovl.fmt.RRE.r1,
12608 ovl.fmt.RRE.r2); goto ok;
12609 case 0xb306: s390_format_RRE_FF(s390_irgen_LXEBR, ovl.fmt.RRE.r1,
12610 ovl.fmt.RRE.r2); goto ok;
12611 case 0xb307: /* MXDBR */ goto unimplemented;
12612 case 0xb308: /* KEBR */ goto unimplemented;
12613 case 0xb309: s390_format_RRE_FF(s390_irgen_CEBR, ovl.fmt.RRE.r1,
12614 ovl.fmt.RRE.r2); goto ok;
12615 case 0xb30a: s390_format_RRE_FF(s390_irgen_AEBR, ovl.fmt.RRE.r1,
12616 ovl.fmt.RRE.r2); goto ok;
12617 case 0xb30b: s390_format_RRE_FF(s390_irgen_SEBR, ovl.fmt.RRE.r1,
12618 ovl.fmt.RRE.r2); goto ok;
12619 case 0xb30c: /* MDEBR */ goto unimplemented;
12620 case 0xb30d: s390_format_RRE_FF(s390_irgen_DEBR, ovl.fmt.RRE.r1,
12621 ovl.fmt.RRE.r2); goto ok;
12622 case 0xb30e: s390_format_RRF_F0FF(s390_irgen_MAEBR, ovl.fmt.RRF.r1,
12623 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
12624 case 0xb30f: s390_format_RRF_F0FF(s390_irgen_MSEBR, ovl.fmt.RRF.r1,
12625 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
12626 case 0xb310: s390_format_RRE_FF(s390_irgen_LPDBR, ovl.fmt.RRE.r1,
12627 ovl.fmt.RRE.r2); goto ok;
12628 case 0xb311: s390_format_RRE_FF(s390_irgen_LNDBR, ovl.fmt.RRE.r1,
12629 ovl.fmt.RRE.r2); goto ok;
12630 case 0xb312: s390_format_RRE_FF(s390_irgen_LTDBR, ovl.fmt.RRE.r1,
12631 ovl.fmt.RRE.r2); goto ok;
12632 case 0xb313: s390_format_RRE_FF(s390_irgen_LCDBR, ovl.fmt.RRE.r1,
12633 ovl.fmt.RRE.r2); goto ok;
12634 case 0xb314: s390_format_RRE_FF(s390_irgen_SQEBR, ovl.fmt.RRE.r1,
12635 ovl.fmt.RRE.r2); goto ok;
12636 case 0xb315: s390_format_RRE_FF(s390_irgen_SQDBR, ovl.fmt.RRE.r1,
12637 ovl.fmt.RRE.r2); goto ok;
12638 case 0xb316: s390_format_RRE_FF(s390_irgen_SQXBR, ovl.fmt.RRE.r1,
12639 ovl.fmt.RRE.r2); goto ok;
12640 case 0xb317: s390_format_RRE_FF(s390_irgen_MEEBR, ovl.fmt.RRE.r1,
12641 ovl.fmt.RRE.r2); goto ok;
12642 case 0xb318: /* KDBR */ goto unimplemented;
12643 case 0xb319: s390_format_RRE_FF(s390_irgen_CDBR, ovl.fmt.RRE.r1,
12644 ovl.fmt.RRE.r2); goto ok;
12645 case 0xb31a: s390_format_RRE_FF(s390_irgen_ADBR, ovl.fmt.RRE.r1,
12646 ovl.fmt.RRE.r2); goto ok;
12647 case 0xb31b: s390_format_RRE_FF(s390_irgen_SDBR, ovl.fmt.RRE.r1,
12648 ovl.fmt.RRE.r2); goto ok;
12649 case 0xb31c: s390_format_RRE_FF(s390_irgen_MDBR, ovl.fmt.RRE.r1,
12650 ovl.fmt.RRE.r2); goto ok;
12651 case 0xb31d: s390_format_RRE_FF(s390_irgen_DDBR, ovl.fmt.RRE.r1,
12652 ovl.fmt.RRE.r2); goto ok;
12653 case 0xb31e: s390_format_RRF_F0FF(s390_irgen_MADBR, ovl.fmt.RRF.r1,
12654 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
12655 case 0xb31f: s390_format_RRF_F0FF(s390_irgen_MSDBR, ovl.fmt.RRF.r1,
12656 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
12657 case 0xb324: /* LDER */ goto unimplemented;
12658 case 0xb325: /* LXDR */ goto unimplemented;
12659 case 0xb326: /* LXER */ goto unimplemented;
12660 case 0xb32e: /* MAER */ goto unimplemented;
12661 case 0xb32f: /* MSER */ goto unimplemented;
12662 case 0xb336: /* SQXR */ goto unimplemented;
12663 case 0xb337: /* MEER */ goto unimplemented;
12664 case 0xb338: /* MAYLR */ goto unimplemented;
12665 case 0xb339: /* MYLR */ goto unimplemented;
12666 case 0xb33a: /* MAYR */ goto unimplemented;
12667 case 0xb33b: /* MYR */ goto unimplemented;
12668 case 0xb33c: /* MAYHR */ goto unimplemented;
12669 case 0xb33d: /* MYHR */ goto unimplemented;
12670 case 0xb33e: /* MADR */ goto unimplemented;
12671 case 0xb33f: /* MSDR */ goto unimplemented;
12672 case 0xb340: s390_format_RRE_FF(s390_irgen_LPXBR, ovl.fmt.RRE.r1,
12673 ovl.fmt.RRE.r2); goto ok;
12674 case 0xb341: s390_format_RRE_FF(s390_irgen_LNXBR, ovl.fmt.RRE.r1,
12675 ovl.fmt.RRE.r2); goto ok;
12676 case 0xb342: s390_format_RRE_FF(s390_irgen_LTXBR, ovl.fmt.RRE.r1,
12677 ovl.fmt.RRE.r2); goto ok;
12678 case 0xb343: s390_format_RRE_FF(s390_irgen_LCXBR, ovl.fmt.RRE.r1,
12679 ovl.fmt.RRE.r2); goto ok;
florian4b8efad2012-09-02 18:07:08 +000012680 case 0xb344: s390_format_RRF_UUFF(s390_irgen_LEDBR, ovl.fmt.RRF2.m3,
12681 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12682 ovl.fmt.RRF2.r2); goto ok;
12683 case 0xb345: s390_format_RRF_UUFF(s390_irgen_LDXBR, ovl.fmt.RRF2.m3,
12684 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12685 ovl.fmt.RRF2.r2); goto ok;
12686 case 0xb346: s390_format_RRF_UUFF(s390_irgen_LEXBR, ovl.fmt.RRF2.m3,
12687 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12688 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000012689 case 0xb347: /* FIXBR */ goto unimplemented;
12690 case 0xb348: /* KXBR */ goto unimplemented;
12691 case 0xb349: s390_format_RRE_FF(s390_irgen_CXBR, ovl.fmt.RRE.r1,
12692 ovl.fmt.RRE.r2); goto ok;
12693 case 0xb34a: s390_format_RRE_FF(s390_irgen_AXBR, ovl.fmt.RRE.r1,
12694 ovl.fmt.RRE.r2); goto ok;
12695 case 0xb34b: s390_format_RRE_FF(s390_irgen_SXBR, ovl.fmt.RRE.r1,
12696 ovl.fmt.RRE.r2); goto ok;
12697 case 0xb34c: s390_format_RRE_FF(s390_irgen_MXBR, ovl.fmt.RRE.r1,
12698 ovl.fmt.RRE.r2); goto ok;
12699 case 0xb34d: s390_format_RRE_FF(s390_irgen_DXBR, ovl.fmt.RRE.r1,
12700 ovl.fmt.RRE.r2); goto ok;
12701 case 0xb350: /* TBEDR */ goto unimplemented;
12702 case 0xb351: /* TBDR */ goto unimplemented;
12703 case 0xb353: /* DIEBR */ goto unimplemented;
12704 case 0xb357: /* FIEBR */ goto unimplemented;
12705 case 0xb358: /* THDER */ goto unimplemented;
12706 case 0xb359: /* THDR */ goto unimplemented;
12707 case 0xb35b: /* DIDBR */ goto unimplemented;
12708 case 0xb35f: /* FIDBR */ goto unimplemented;
12709 case 0xb360: /* LPXR */ goto unimplemented;
12710 case 0xb361: /* LNXR */ goto unimplemented;
12711 case 0xb362: /* LTXR */ goto unimplemented;
12712 case 0xb363: /* LCXR */ goto unimplemented;
12713 case 0xb365: s390_format_RRE_FF(s390_irgen_LXR, ovl.fmt.RRE.r1,
12714 ovl.fmt.RRE.r2); goto ok;
12715 case 0xb366: /* LEXR */ goto unimplemented;
12716 case 0xb367: /* FIXR */ goto unimplemented;
12717 case 0xb369: /* CXR */ goto unimplemented;
12718 case 0xb370: s390_format_RRE_FF(s390_irgen_LPDFR, ovl.fmt.RRE.r1,
12719 ovl.fmt.RRE.r2); goto ok;
12720 case 0xb371: s390_format_RRE_FF(s390_irgen_LNDFR, ovl.fmt.RRE.r1,
12721 ovl.fmt.RRE.r2); goto ok;
12722 case 0xb372: s390_format_RRF_F0FF2(s390_irgen_CPSDR, ovl.fmt.RRF3.r3,
12723 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
12724 goto ok;
12725 case 0xb373: s390_format_RRE_FF(s390_irgen_LCDFR, ovl.fmt.RRE.r1,
12726 ovl.fmt.RRE.r2); goto ok;
12727 case 0xb374: s390_format_RRE_F0(s390_irgen_LZER, ovl.fmt.RRE.r1); goto ok;
12728 case 0xb375: s390_format_RRE_F0(s390_irgen_LZDR, ovl.fmt.RRE.r1); goto ok;
12729 case 0xb376: s390_format_RRE_F0(s390_irgen_LZXR, ovl.fmt.RRE.r1); goto ok;
12730 case 0xb377: /* FIER */ goto unimplemented;
12731 case 0xb37f: /* FIDR */ goto unimplemented;
12732 case 0xb384: s390_format_RRE_R0(s390_irgen_SFPC, ovl.fmt.RRE.r1); goto ok;
12733 case 0xb385: /* SFASR */ goto unimplemented;
12734 case 0xb38c: s390_format_RRE_R0(s390_irgen_EFPC, ovl.fmt.RRE.r1); goto ok;
florian1c8f7ff2012-09-01 00:12:11 +000012735 case 0xb390: s390_format_RRF_UUFR(s390_irgen_CELFBR, ovl.fmt.RRF2.m3,
12736 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12737 ovl.fmt.RRF2.r2); goto ok;
12738 case 0xb391: s390_format_RRF_UUFR(s390_irgen_CDLFBR, ovl.fmt.RRF2.m3,
12739 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12740 ovl.fmt.RRF2.r2); goto ok;
12741 case 0xb392: s390_format_RRF_UUFR(s390_irgen_CXLFBR, ovl.fmt.RRF2.m3,
12742 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12743 ovl.fmt.RRF2.r2); goto ok;
florian4b8efad2012-09-02 18:07:08 +000012744 case 0xb394: s390_format_RRF_UUFR(s390_irgen_CEFBR, ovl.fmt.RRF2.m3,
12745 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12746 ovl.fmt.RRF2.r2); goto ok;
12747 case 0xb395: s390_format_RRF_UUFR(s390_irgen_CDFBR, ovl.fmt.RRF2.m3,
12748 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12749 ovl.fmt.RRF2.r2); goto ok;
12750 case 0xb396: s390_format_RRF_UUFR(s390_irgen_CXFBR, ovl.fmt.RRF2.m3,
12751 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12752 ovl.fmt.RRF2.r2); goto ok;
12753 case 0xb398: s390_format_RRF_UURF(s390_irgen_CFEBR, ovl.fmt.RRF2.m3,
12754 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12755 ovl.fmt.RRF2.r2); goto ok;
12756 case 0xb399: s390_format_RRF_UURF(s390_irgen_CFDBR, ovl.fmt.RRF2.m3,
12757 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12758 ovl.fmt.RRF2.r2); goto ok;
12759 case 0xb39a: s390_format_RRF_UURF(s390_irgen_CFXBR, ovl.fmt.RRF2.m3,
12760 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12761 ovl.fmt.RRF2.r2); goto ok;
florian1c8f7ff2012-09-01 00:12:11 +000012762 case 0xb39c: s390_format_RRF_UURF(s390_irgen_CLFEBR, ovl.fmt.RRF2.m3,
12763 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12764 ovl.fmt.RRF2.r2); goto ok;
12765 case 0xb39d: s390_format_RRF_UURF(s390_irgen_CLFDBR, ovl.fmt.RRF2.m3,
12766 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12767 ovl.fmt.RRF2.r2); goto ok;
12768 case 0xb39e: s390_format_RRF_UURF(s390_irgen_CLFXBR, ovl.fmt.RRF2.m3,
12769 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12770 ovl.fmt.RRF2.r2); goto ok;
12771 case 0xb3a0: s390_format_RRF_UUFR(s390_irgen_CELGBR, ovl.fmt.RRF2.m3,
12772 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12773 ovl.fmt.RRF2.r2); goto ok;
12774 case 0xb3a1: s390_format_RRF_UUFR(s390_irgen_CDLGBR, ovl.fmt.RRF2.m3,
12775 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12776 ovl.fmt.RRF2.r2); goto ok;
12777 case 0xb3a2: s390_format_RRF_UUFR(s390_irgen_CXLGBR, ovl.fmt.RRF2.m3,
12778 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12779 ovl.fmt.RRF2.r2); goto ok;
florian4b8efad2012-09-02 18:07:08 +000012780 case 0xb3a4: s390_format_RRF_UUFR(s390_irgen_CEGBR, ovl.fmt.RRF2.m3,
12781 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12782 ovl.fmt.RRF2.r2); goto ok;
12783 case 0xb3a5: s390_format_RRF_UUFR(s390_irgen_CDGBR, ovl.fmt.RRF2.m3,
12784 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12785 ovl.fmt.RRF2.r2); goto ok;
12786 case 0xb3a6: s390_format_RRF_UUFR(s390_irgen_CXGBR, ovl.fmt.RRF2.m3,
12787 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12788 ovl.fmt.RRF2.r2); goto ok;
12789 case 0xb3a8: s390_format_RRF_UURF(s390_irgen_CGEBR, ovl.fmt.RRF2.m3,
12790 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12791 ovl.fmt.RRF2.r2); goto ok;
12792 case 0xb3a9: s390_format_RRF_UURF(s390_irgen_CGDBR, ovl.fmt.RRF2.m3,
12793 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12794 ovl.fmt.RRF2.r2); goto ok;
12795 case 0xb3aa: s390_format_RRF_UURF(s390_irgen_CGXBR, ovl.fmt.RRF2.m3,
12796 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12797 ovl.fmt.RRF2.r2); goto ok;
florian1c8f7ff2012-09-01 00:12:11 +000012798 case 0xb3ac: s390_format_RRF_UURF(s390_irgen_CLGEBR, ovl.fmt.RRF2.m3,
12799 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12800 ovl.fmt.RRF2.r2); goto ok;
12801 case 0xb3ad: s390_format_RRF_UURF(s390_irgen_CLGDBR, ovl.fmt.RRF2.m3,
12802 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12803 ovl.fmt.RRF2.r2); goto ok;
12804 case 0xb3ae: s390_format_RRF_UURF(s390_irgen_CLGXBR, ovl.fmt.RRF2.m3,
12805 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12806 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000012807 case 0xb3b4: /* CEFR */ goto unimplemented;
12808 case 0xb3b5: /* CDFR */ goto unimplemented;
12809 case 0xb3b6: /* CXFR */ goto unimplemented;
12810 case 0xb3b8: /* CFER */ goto unimplemented;
12811 case 0xb3b9: /* CFDR */ goto unimplemented;
12812 case 0xb3ba: /* CFXR */ goto unimplemented;
12813 case 0xb3c1: s390_format_RRE_FR(s390_irgen_LDGR, ovl.fmt.RRE.r1,
12814 ovl.fmt.RRE.r2); goto ok;
12815 case 0xb3c4: /* CEGR */ goto unimplemented;
12816 case 0xb3c5: /* CDGR */ goto unimplemented;
12817 case 0xb3c6: /* CXGR */ goto unimplemented;
12818 case 0xb3c8: /* CGER */ goto unimplemented;
12819 case 0xb3c9: /* CGDR */ goto unimplemented;
12820 case 0xb3ca: /* CGXR */ goto unimplemented;
12821 case 0xb3cd: s390_format_RRE_RF(s390_irgen_LGDR, ovl.fmt.RRE.r1,
12822 ovl.fmt.RRE.r2); goto ok;
12823 case 0xb3d0: /* MDTR */ goto unimplemented;
12824 case 0xb3d1: /* DDTR */ goto unimplemented;
12825 case 0xb3d2: /* ADTR */ goto unimplemented;
12826 case 0xb3d3: /* SDTR */ goto unimplemented;
12827 case 0xb3d4: /* LDETR */ goto unimplemented;
12828 case 0xb3d5: /* LEDTR */ goto unimplemented;
12829 case 0xb3d6: /* LTDTR */ goto unimplemented;
12830 case 0xb3d7: /* FIDTR */ goto unimplemented;
12831 case 0xb3d8: /* MXTR */ goto unimplemented;
12832 case 0xb3d9: /* DXTR */ goto unimplemented;
12833 case 0xb3da: /* AXTR */ goto unimplemented;
12834 case 0xb3db: /* SXTR */ goto unimplemented;
12835 case 0xb3dc: /* LXDTR */ goto unimplemented;
12836 case 0xb3dd: /* LDXTR */ goto unimplemented;
12837 case 0xb3de: /* LTXTR */ goto unimplemented;
12838 case 0xb3df: /* FIXTR */ goto unimplemented;
12839 case 0xb3e0: /* KDTR */ goto unimplemented;
12840 case 0xb3e1: /* CGDTR */ goto unimplemented;
12841 case 0xb3e2: /* CUDTR */ goto unimplemented;
12842 case 0xb3e3: /* CSDTR */ goto unimplemented;
12843 case 0xb3e4: /* CDTR */ goto unimplemented;
12844 case 0xb3e5: /* EEDTR */ goto unimplemented;
12845 case 0xb3e7: /* ESDTR */ goto unimplemented;
12846 case 0xb3e8: /* KXTR */ goto unimplemented;
12847 case 0xb3e9: /* CGXTR */ goto unimplemented;
12848 case 0xb3ea: /* CUXTR */ goto unimplemented;
12849 case 0xb3eb: /* CSXTR */ goto unimplemented;
12850 case 0xb3ec: /* CXTR */ goto unimplemented;
12851 case 0xb3ed: /* EEXTR */ goto unimplemented;
12852 case 0xb3ef: /* ESXTR */ goto unimplemented;
12853 case 0xb3f1: /* CDGTR */ goto unimplemented;
12854 case 0xb3f2: /* CDUTR */ goto unimplemented;
12855 case 0xb3f3: /* CDSTR */ goto unimplemented;
12856 case 0xb3f4: /* CEDTR */ goto unimplemented;
12857 case 0xb3f5: /* QADTR */ goto unimplemented;
12858 case 0xb3f6: /* IEDTR */ goto unimplemented;
12859 case 0xb3f7: /* RRDTR */ goto unimplemented;
12860 case 0xb3f9: /* CXGTR */ goto unimplemented;
12861 case 0xb3fa: /* CXUTR */ goto unimplemented;
12862 case 0xb3fb: /* CXSTR */ goto unimplemented;
12863 case 0xb3fc: /* CEXTR */ goto unimplemented;
12864 case 0xb3fd: /* QAXTR */ goto unimplemented;
12865 case 0xb3fe: /* IEXTR */ goto unimplemented;
12866 case 0xb3ff: /* RRXTR */ goto unimplemented;
12867 case 0xb900: s390_format_RRE_RR(s390_irgen_LPGR, ovl.fmt.RRE.r1,
12868 ovl.fmt.RRE.r2); goto ok;
12869 case 0xb901: s390_format_RRE_RR(s390_irgen_LNGR, ovl.fmt.RRE.r1,
12870 ovl.fmt.RRE.r2); goto ok;
12871 case 0xb902: s390_format_RRE_RR(s390_irgen_LTGR, ovl.fmt.RRE.r1,
12872 ovl.fmt.RRE.r2); goto ok;
12873 case 0xb903: s390_format_RRE_RR(s390_irgen_LCGR, ovl.fmt.RRE.r1,
12874 ovl.fmt.RRE.r2); goto ok;
12875 case 0xb904: s390_format_RRE_RR(s390_irgen_LGR, ovl.fmt.RRE.r1,
12876 ovl.fmt.RRE.r2); goto ok;
12877 case 0xb905: /* LURAG */ goto unimplemented;
12878 case 0xb906: s390_format_RRE_RR(s390_irgen_LGBR, ovl.fmt.RRE.r1,
12879 ovl.fmt.RRE.r2); goto ok;
12880 case 0xb907: s390_format_RRE_RR(s390_irgen_LGHR, ovl.fmt.RRE.r1,
12881 ovl.fmt.RRE.r2); goto ok;
12882 case 0xb908: s390_format_RRE_RR(s390_irgen_AGR, ovl.fmt.RRE.r1,
12883 ovl.fmt.RRE.r2); goto ok;
12884 case 0xb909: s390_format_RRE_RR(s390_irgen_SGR, ovl.fmt.RRE.r1,
12885 ovl.fmt.RRE.r2); goto ok;
12886 case 0xb90a: s390_format_RRE_RR(s390_irgen_ALGR, ovl.fmt.RRE.r1,
12887 ovl.fmt.RRE.r2); goto ok;
12888 case 0xb90b: s390_format_RRE_RR(s390_irgen_SLGR, ovl.fmt.RRE.r1,
12889 ovl.fmt.RRE.r2); goto ok;
12890 case 0xb90c: s390_format_RRE_RR(s390_irgen_MSGR, ovl.fmt.RRE.r1,
12891 ovl.fmt.RRE.r2); goto ok;
12892 case 0xb90d: s390_format_RRE_RR(s390_irgen_DSGR, ovl.fmt.RRE.r1,
12893 ovl.fmt.RRE.r2); goto ok;
12894 case 0xb90e: /* EREGG */ goto unimplemented;
12895 case 0xb90f: s390_format_RRE_RR(s390_irgen_LRVGR, ovl.fmt.RRE.r1,
12896 ovl.fmt.RRE.r2); goto ok;
12897 case 0xb910: s390_format_RRE_RR(s390_irgen_LPGFR, ovl.fmt.RRE.r1,
12898 ovl.fmt.RRE.r2); goto ok;
12899 case 0xb911: s390_format_RRE_RR(s390_irgen_LNGFR, ovl.fmt.RRE.r1,
12900 ovl.fmt.RRE.r2); goto ok;
12901 case 0xb912: s390_format_RRE_RR(s390_irgen_LTGFR, ovl.fmt.RRE.r1,
12902 ovl.fmt.RRE.r2); goto ok;
12903 case 0xb913: s390_format_RRE_RR(s390_irgen_LCGFR, ovl.fmt.RRE.r1,
12904 ovl.fmt.RRE.r2); goto ok;
12905 case 0xb914: s390_format_RRE_RR(s390_irgen_LGFR, ovl.fmt.RRE.r1,
12906 ovl.fmt.RRE.r2); goto ok;
12907 case 0xb916: s390_format_RRE_RR(s390_irgen_LLGFR, ovl.fmt.RRE.r1,
12908 ovl.fmt.RRE.r2); goto ok;
12909 case 0xb917: s390_format_RRE_RR(s390_irgen_LLGTR, ovl.fmt.RRE.r1,
12910 ovl.fmt.RRE.r2); goto ok;
12911 case 0xb918: s390_format_RRE_RR(s390_irgen_AGFR, ovl.fmt.RRE.r1,
12912 ovl.fmt.RRE.r2); goto ok;
12913 case 0xb919: s390_format_RRE_RR(s390_irgen_SGFR, ovl.fmt.RRE.r1,
12914 ovl.fmt.RRE.r2); goto ok;
12915 case 0xb91a: s390_format_RRE_RR(s390_irgen_ALGFR, ovl.fmt.RRE.r1,
12916 ovl.fmt.RRE.r2); goto ok;
12917 case 0xb91b: s390_format_RRE_RR(s390_irgen_SLGFR, ovl.fmt.RRE.r1,
12918 ovl.fmt.RRE.r2); goto ok;
12919 case 0xb91c: s390_format_RRE_RR(s390_irgen_MSGFR, ovl.fmt.RRE.r1,
12920 ovl.fmt.RRE.r2); goto ok;
12921 case 0xb91d: s390_format_RRE_RR(s390_irgen_DSGFR, ovl.fmt.RRE.r1,
12922 ovl.fmt.RRE.r2); goto ok;
12923 case 0xb91e: /* KMAC */ goto unimplemented;
12924 case 0xb91f: s390_format_RRE_RR(s390_irgen_LRVR, ovl.fmt.RRE.r1,
12925 ovl.fmt.RRE.r2); goto ok;
12926 case 0xb920: s390_format_RRE_RR(s390_irgen_CGR, ovl.fmt.RRE.r1,
12927 ovl.fmt.RRE.r2); goto ok;
12928 case 0xb921: s390_format_RRE_RR(s390_irgen_CLGR, ovl.fmt.RRE.r1,
12929 ovl.fmt.RRE.r2); goto ok;
12930 case 0xb925: /* STURG */ goto unimplemented;
12931 case 0xb926: s390_format_RRE_RR(s390_irgen_LBR, ovl.fmt.RRE.r1,
12932 ovl.fmt.RRE.r2); goto ok;
12933 case 0xb927: s390_format_RRE_RR(s390_irgen_LHR, ovl.fmt.RRE.r1,
12934 ovl.fmt.RRE.r2); goto ok;
12935 case 0xb928: /* PCKMO */ goto unimplemented;
12936 case 0xb92b: /* KMO */ goto unimplemented;
12937 case 0xb92c: /* PCC */ goto unimplemented;
12938 case 0xb92d: /* KMCTR */ goto unimplemented;
12939 case 0xb92e: /* KM */ goto unimplemented;
12940 case 0xb92f: /* KMC */ goto unimplemented;
12941 case 0xb930: s390_format_RRE_RR(s390_irgen_CGFR, ovl.fmt.RRE.r1,
12942 ovl.fmt.RRE.r2); goto ok;
12943 case 0xb931: s390_format_RRE_RR(s390_irgen_CLGFR, ovl.fmt.RRE.r1,
12944 ovl.fmt.RRE.r2); goto ok;
12945 case 0xb93e: /* KIMD */ goto unimplemented;
12946 case 0xb93f: /* KLMD */ goto unimplemented;
12947 case 0xb941: /* CFDTR */ goto unimplemented;
12948 case 0xb942: /* CLGDTR */ goto unimplemented;
12949 case 0xb943: /* CLFDTR */ goto unimplemented;
12950 case 0xb946: s390_format_RRE_RR(s390_irgen_BCTGR, ovl.fmt.RRE.r1,
12951 ovl.fmt.RRE.r2); goto ok;
12952 case 0xb949: /* CFXTR */ goto unimplemented;
12953 case 0xb94a: /* CLGXTR */ goto unimplemented;
12954 case 0xb94b: /* CLFXTR */ goto unimplemented;
12955 case 0xb951: /* CDFTR */ goto unimplemented;
12956 case 0xb952: /* CDLGTR */ goto unimplemented;
12957 case 0xb953: /* CDLFTR */ goto unimplemented;
12958 case 0xb959: /* CXFTR */ goto unimplemented;
12959 case 0xb95a: /* CXLGTR */ goto unimplemented;
12960 case 0xb95b: /* CXLFTR */ goto unimplemented;
12961 case 0xb960: /* CGRT */ goto unimplemented;
12962 case 0xb961: /* CLGRT */ goto unimplemented;
12963 case 0xb972: /* CRT */ goto unimplemented;
12964 case 0xb973: /* CLRT */ goto unimplemented;
12965 case 0xb980: s390_format_RRE_RR(s390_irgen_NGR, ovl.fmt.RRE.r1,
12966 ovl.fmt.RRE.r2); goto ok;
12967 case 0xb981: s390_format_RRE_RR(s390_irgen_OGR, ovl.fmt.RRE.r1,
12968 ovl.fmt.RRE.r2); goto ok;
12969 case 0xb982: s390_format_RRE_RR(s390_irgen_XGR, ovl.fmt.RRE.r1,
12970 ovl.fmt.RRE.r2); goto ok;
12971 case 0xb983: s390_format_RRE_RR(s390_irgen_FLOGR, ovl.fmt.RRE.r1,
12972 ovl.fmt.RRE.r2); goto ok;
12973 case 0xb984: s390_format_RRE_RR(s390_irgen_LLGCR, ovl.fmt.RRE.r1,
12974 ovl.fmt.RRE.r2); goto ok;
12975 case 0xb985: s390_format_RRE_RR(s390_irgen_LLGHR, ovl.fmt.RRE.r1,
12976 ovl.fmt.RRE.r2); goto ok;
12977 case 0xb986: s390_format_RRE_RR(s390_irgen_MLGR, ovl.fmt.RRE.r1,
12978 ovl.fmt.RRE.r2); goto ok;
12979 case 0xb987: s390_format_RRE_RR(s390_irgen_DLGR, ovl.fmt.RRE.r1,
12980 ovl.fmt.RRE.r2); goto ok;
12981 case 0xb988: s390_format_RRE_RR(s390_irgen_ALCGR, ovl.fmt.RRE.r1,
12982 ovl.fmt.RRE.r2); goto ok;
12983 case 0xb989: s390_format_RRE_RR(s390_irgen_SLBGR, ovl.fmt.RRE.r1,
12984 ovl.fmt.RRE.r2); goto ok;
12985 case 0xb98a: /* CSPG */ goto unimplemented;
12986 case 0xb98d: /* EPSW */ goto unimplemented;
12987 case 0xb98e: /* IDTE */ goto unimplemented;
florian730448f2012-02-04 17:07:07 +000012988 case 0xb990: s390_format_RRF_M0RERE(s390_irgen_TRTT, ovl.fmt.RRF3.r3,
12989 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
12990 case 0xb991: s390_format_RRF_M0RERE(s390_irgen_TRTO, ovl.fmt.RRF3.r3,
12991 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
12992 case 0xb992: s390_format_RRF_M0RERE(s390_irgen_TROT, ovl.fmt.RRF3.r3,
12993 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
florian9af37692012-01-15 21:01:16 +000012994 case 0xb993: s390_format_RRF_M0RERE(s390_irgen_TROO, ovl.fmt.RRF3.r3,
12995 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000012996 case 0xb994: s390_format_RRE_RR(s390_irgen_LLCR, ovl.fmt.RRE.r1,
12997 ovl.fmt.RRE.r2); goto ok;
12998 case 0xb995: s390_format_RRE_RR(s390_irgen_LLHR, ovl.fmt.RRE.r1,
12999 ovl.fmt.RRE.r2); goto ok;
13000 case 0xb996: s390_format_RRE_RR(s390_irgen_MLR, ovl.fmt.RRE.r1,
13001 ovl.fmt.RRE.r2); goto ok;
13002 case 0xb997: s390_format_RRE_RR(s390_irgen_DLR, ovl.fmt.RRE.r1,
13003 ovl.fmt.RRE.r2); goto ok;
13004 case 0xb998: s390_format_RRE_RR(s390_irgen_ALCR, ovl.fmt.RRE.r1,
13005 ovl.fmt.RRE.r2); goto ok;
13006 case 0xb999: s390_format_RRE_RR(s390_irgen_SLBR, ovl.fmt.RRE.r1,
13007 ovl.fmt.RRE.r2); goto ok;
13008 case 0xb99a: /* EPAIR */ goto unimplemented;
13009 case 0xb99b: /* ESAIR */ goto unimplemented;
13010 case 0xb99d: /* ESEA */ goto unimplemented;
13011 case 0xb99e: /* PTI */ goto unimplemented;
13012 case 0xb99f: /* SSAIR */ goto unimplemented;
13013 case 0xb9a2: /* PTF */ goto unimplemented;
13014 case 0xb9aa: /* LPTEA */ goto unimplemented;
13015 case 0xb9ae: /* RRBM */ goto unimplemented;
13016 case 0xb9af: /* PFMF */ goto unimplemented;
florian3f8a96a2012-08-05 02:59:55 +000013017 case 0xb9b0: s390_format_RRF_M0RERE(s390_irgen_CU14, ovl.fmt.RRF3.r3,
13018 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
13019 goto ok;
florian2a415a12012-07-21 17:41:36 +000013020 case 0xb9b1: s390_format_RRF_M0RERE(s390_irgen_CU24, ovl.fmt.RRF3.r3,
13021 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
13022 goto ok;
florianaf2194f2012-08-06 00:07:54 +000013023 case 0xb9b2: s390_format_RRE_RR(s390_irgen_CU41, ovl.fmt.RRE.r1,
13024 ovl.fmt.RRE.r2); goto ok;
florian956194b2012-07-28 22:18:32 +000013025 case 0xb9b3: s390_format_RRE_RR(s390_irgen_CU42, ovl.fmt.RRE.r1,
13026 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013027 case 0xb9bd: /* TRTRE */ goto unimplemented;
13028 case 0xb9be: /* SRSTU */ goto unimplemented;
13029 case 0xb9bf: /* TRTE */ goto unimplemented;
13030 case 0xb9c8: s390_format_RRF_R0RR2(s390_irgen_AHHHR, ovl.fmt.RRF4.r3,
13031 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13032 goto ok;
13033 case 0xb9c9: s390_format_RRF_R0RR2(s390_irgen_SHHHR, ovl.fmt.RRF4.r3,
13034 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13035 goto ok;
13036 case 0xb9ca: s390_format_RRF_R0RR2(s390_irgen_ALHHHR, ovl.fmt.RRF4.r3,
13037 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13038 goto ok;
13039 case 0xb9cb: s390_format_RRF_R0RR2(s390_irgen_SLHHHR, ovl.fmt.RRF4.r3,
13040 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13041 goto ok;
13042 case 0xb9cd: s390_format_RRE_RR(s390_irgen_CHHR, ovl.fmt.RRE.r1,
13043 ovl.fmt.RRE.r2); goto ok;
13044 case 0xb9cf: s390_format_RRE_RR(s390_irgen_CLHHR, ovl.fmt.RRE.r1,
13045 ovl.fmt.RRE.r2); goto ok;
13046 case 0xb9d8: s390_format_RRF_R0RR2(s390_irgen_AHHLR, ovl.fmt.RRF4.r3,
13047 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13048 goto ok;
13049 case 0xb9d9: s390_format_RRF_R0RR2(s390_irgen_SHHLR, ovl.fmt.RRF4.r3,
13050 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13051 goto ok;
13052 case 0xb9da: s390_format_RRF_R0RR2(s390_irgen_ALHHLR, ovl.fmt.RRF4.r3,
13053 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13054 goto ok;
13055 case 0xb9db: s390_format_RRF_R0RR2(s390_irgen_SLHHLR, ovl.fmt.RRF4.r3,
13056 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13057 goto ok;
13058 case 0xb9dd: s390_format_RRE_RR(s390_irgen_CHLR, ovl.fmt.RRE.r1,
13059 ovl.fmt.RRE.r2); goto ok;
13060 case 0xb9df: s390_format_RRE_RR(s390_irgen_CLHLR, ovl.fmt.RRE.r1,
13061 ovl.fmt.RRE.r2); goto ok;
13062 case 0xb9e1: /* POPCNT */ goto unimplemented;
sewardjd7bde722011-04-05 13:19:33 +000013063 case 0xb9e2: s390_format_RRF_U0RR(s390_irgen_LOCGR, ovl.fmt.RRF3.r3,
13064 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2,
13065 S390_XMNM_LOCGR); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013066 case 0xb9e4: s390_format_RRF_R0RR2(s390_irgen_NGRK, ovl.fmt.RRF4.r3,
13067 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13068 goto ok;
13069 case 0xb9e6: s390_format_RRF_R0RR2(s390_irgen_OGRK, ovl.fmt.RRF4.r3,
13070 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13071 goto ok;
13072 case 0xb9e7: s390_format_RRF_R0RR2(s390_irgen_XGRK, ovl.fmt.RRF4.r3,
13073 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13074 goto ok;
13075 case 0xb9e8: s390_format_RRF_R0RR2(s390_irgen_AGRK, ovl.fmt.RRF4.r3,
13076 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13077 goto ok;
13078 case 0xb9e9: s390_format_RRF_R0RR2(s390_irgen_SGRK, ovl.fmt.RRF4.r3,
13079 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13080 goto ok;
13081 case 0xb9ea: s390_format_RRF_R0RR2(s390_irgen_ALGRK, ovl.fmt.RRF4.r3,
13082 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13083 goto ok;
13084 case 0xb9eb: s390_format_RRF_R0RR2(s390_irgen_SLGRK, ovl.fmt.RRF4.r3,
13085 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13086 goto ok;
sewardjd7bde722011-04-05 13:19:33 +000013087 case 0xb9f2: s390_format_RRF_U0RR(s390_irgen_LOCR, ovl.fmt.RRF3.r3,
13088 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2,
13089 S390_XMNM_LOCR); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013090 case 0xb9f4: s390_format_RRF_R0RR2(s390_irgen_NRK, ovl.fmt.RRF4.r3,
13091 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13092 goto ok;
13093 case 0xb9f6: s390_format_RRF_R0RR2(s390_irgen_ORK, ovl.fmt.RRF4.r3,
13094 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13095 goto ok;
13096 case 0xb9f7: s390_format_RRF_R0RR2(s390_irgen_XRK, ovl.fmt.RRF4.r3,
13097 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13098 goto ok;
13099 case 0xb9f8: s390_format_RRF_R0RR2(s390_irgen_ARK, ovl.fmt.RRF4.r3,
13100 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13101 goto ok;
13102 case 0xb9f9: s390_format_RRF_R0RR2(s390_irgen_SRK, ovl.fmt.RRF4.r3,
13103 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13104 goto ok;
13105 case 0xb9fa: s390_format_RRF_R0RR2(s390_irgen_ALRK, ovl.fmt.RRF4.r3,
13106 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13107 goto ok;
13108 case 0xb9fb: s390_format_RRF_R0RR2(s390_irgen_SLRK, ovl.fmt.RRF4.r3,
13109 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13110 goto ok;
13111 }
13112
13113 switch ((ovl.value & 0xff000000) >> 24) {
13114 case 0x40: s390_format_RX_RRRD(s390_irgen_STH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13115 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13116 case 0x41: s390_format_RX_RRRD(s390_irgen_LA, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13117 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13118 case 0x42: s390_format_RX_RRRD(s390_irgen_STC, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13119 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13120 case 0x43: s390_format_RX_RRRD(s390_irgen_IC, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13121 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13122 case 0x44: s390_format_RX_RRRD(s390_irgen_EX, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13123 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13124 case 0x45: /* BAL */ goto unimplemented;
13125 case 0x46: s390_format_RX_RRRD(s390_irgen_BCT, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13126 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13127 case 0x47: s390_format_RX(s390_irgen_BC, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13128 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13129 case 0x48: s390_format_RX_RRRD(s390_irgen_LH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13130 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13131 case 0x49: s390_format_RX_RRRD(s390_irgen_CH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13132 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13133 case 0x4a: s390_format_RX_RRRD(s390_irgen_AH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13134 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13135 case 0x4b: s390_format_RX_RRRD(s390_irgen_SH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13136 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13137 case 0x4c: s390_format_RX_RRRD(s390_irgen_MH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13138 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13139 case 0x4d: s390_format_RX_RRRD(s390_irgen_BAS, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13140 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13141 case 0x4e: s390_format_RX_RRRD(s390_irgen_CVD, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13142 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13143 case 0x4f: s390_format_RX_RRRD(s390_irgen_CVB, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13144 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13145 case 0x50: s390_format_RX_RRRD(s390_irgen_ST, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13146 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13147 case 0x51: s390_format_RX_RRRD(s390_irgen_LAE, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13148 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13149 case 0x54: s390_format_RX_RRRD(s390_irgen_N, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13150 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13151 case 0x55: s390_format_RX_RRRD(s390_irgen_CL, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13152 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13153 case 0x56: s390_format_RX_RRRD(s390_irgen_O, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13154 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13155 case 0x57: s390_format_RX_RRRD(s390_irgen_X, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13156 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13157 case 0x58: s390_format_RX_RRRD(s390_irgen_L, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13158 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13159 case 0x59: s390_format_RX_RRRD(s390_irgen_C, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13160 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13161 case 0x5a: s390_format_RX_RRRD(s390_irgen_A, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13162 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13163 case 0x5b: s390_format_RX_RRRD(s390_irgen_S, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13164 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13165 case 0x5c: s390_format_RX_RRRD(s390_irgen_M, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13166 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13167 case 0x5d: s390_format_RX_RRRD(s390_irgen_D, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13168 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13169 case 0x5e: s390_format_RX_RRRD(s390_irgen_AL, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13170 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13171 case 0x5f: s390_format_RX_RRRD(s390_irgen_SL, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13172 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13173 case 0x60: s390_format_RX_FRRD(s390_irgen_STD, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13174 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13175 case 0x67: /* MXD */ goto unimplemented;
13176 case 0x68: s390_format_RX_FRRD(s390_irgen_LD, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13177 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13178 case 0x69: /* CD */ goto unimplemented;
13179 case 0x6a: /* AD */ goto unimplemented;
13180 case 0x6b: /* SD */ goto unimplemented;
13181 case 0x6c: /* MD */ goto unimplemented;
13182 case 0x6d: /* DD */ goto unimplemented;
13183 case 0x6e: /* AW */ goto unimplemented;
13184 case 0x6f: /* SW */ goto unimplemented;
13185 case 0x70: s390_format_RX_FRRD(s390_irgen_STE, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13186 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13187 case 0x71: s390_format_RX_RRRD(s390_irgen_MS, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13188 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13189 case 0x78: s390_format_RX_FRRD(s390_irgen_LE, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13190 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13191 case 0x79: /* CE */ goto unimplemented;
13192 case 0x7a: /* AE */ goto unimplemented;
13193 case 0x7b: /* SE */ goto unimplemented;
13194 case 0x7c: /* MDE */ goto unimplemented;
13195 case 0x7d: /* DE */ goto unimplemented;
13196 case 0x7e: /* AU */ goto unimplemented;
13197 case 0x7f: /* SU */ goto unimplemented;
13198 case 0x83: /* DIAG */ goto unimplemented;
13199 case 0x84: s390_format_RSI_RRP(s390_irgen_BRXH, ovl.fmt.RSI.r1,
13200 ovl.fmt.RSI.r3, ovl.fmt.RSI.i2); goto ok;
13201 case 0x85: s390_format_RSI_RRP(s390_irgen_BRXLE, ovl.fmt.RSI.r1,
13202 ovl.fmt.RSI.r3, ovl.fmt.RSI.i2); goto ok;
13203 case 0x86: s390_format_RS_RRRD(s390_irgen_BXH, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13204 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13205 case 0x87: s390_format_RS_RRRD(s390_irgen_BXLE, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13206 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13207 case 0x88: s390_format_RS_R0RD(s390_irgen_SRL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
13208 ovl.fmt.RS.d2); goto ok;
13209 case 0x89: s390_format_RS_R0RD(s390_irgen_SLL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
13210 ovl.fmt.RS.d2); goto ok;
13211 case 0x8a: s390_format_RS_R0RD(s390_irgen_SRA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
13212 ovl.fmt.RS.d2); goto ok;
13213 case 0x8b: s390_format_RS_R0RD(s390_irgen_SLA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
13214 ovl.fmt.RS.d2); goto ok;
13215 case 0x8c: s390_format_RS_R0RD(s390_irgen_SRDL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
13216 ovl.fmt.RS.d2); goto ok;
13217 case 0x8d: s390_format_RS_R0RD(s390_irgen_SLDL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
13218 ovl.fmt.RS.d2); goto ok;
13219 case 0x8e: s390_format_RS_R0RD(s390_irgen_SRDA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
13220 ovl.fmt.RS.d2); goto ok;
13221 case 0x8f: s390_format_RS_R0RD(s390_irgen_SLDA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
13222 ovl.fmt.RS.d2); goto ok;
13223 case 0x90: s390_format_RS_RRRD(s390_irgen_STM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13224 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13225 case 0x91: s390_format_SI_URD(s390_irgen_TM, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
13226 ovl.fmt.SI.d1); goto ok;
13227 case 0x92: s390_format_SI_URD(s390_irgen_MVI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
13228 ovl.fmt.SI.d1); goto ok;
13229 case 0x94: s390_format_SI_URD(s390_irgen_NI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
13230 ovl.fmt.SI.d1); goto ok;
13231 case 0x95: s390_format_SI_URD(s390_irgen_CLI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
13232 ovl.fmt.SI.d1); goto ok;
13233 case 0x96: s390_format_SI_URD(s390_irgen_OI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
13234 ovl.fmt.SI.d1); goto ok;
13235 case 0x97: s390_format_SI_URD(s390_irgen_XI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
13236 ovl.fmt.SI.d1); goto ok;
13237 case 0x98: s390_format_RS_RRRD(s390_irgen_LM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13238 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13239 case 0x99: /* TRACE */ goto unimplemented;
13240 case 0x9a: s390_format_RS_AARD(s390_irgen_LAM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13241 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13242 case 0x9b: s390_format_RS_AARD(s390_irgen_STAM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13243 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13244 case 0xa8: s390_format_RS_RRRD(s390_irgen_MVCLE, ovl.fmt.RS.r1,
13245 ovl.fmt.RS.r3, ovl.fmt.RS.b2, ovl.fmt.RS.d2);
13246 goto ok;
13247 case 0xa9: s390_format_RS_RRRD(s390_irgen_CLCLE, ovl.fmt.RS.r1,
13248 ovl.fmt.RS.r3, ovl.fmt.RS.b2, ovl.fmt.RS.d2);
13249 goto ok;
13250 case 0xac: /* STNSM */ goto unimplemented;
13251 case 0xad: /* STOSM */ goto unimplemented;
13252 case 0xae: /* SIGP */ goto unimplemented;
13253 case 0xaf: /* MC */ goto unimplemented;
13254 case 0xb1: /* LRA */ goto unimplemented;
13255 case 0xb6: /* STCTL */ goto unimplemented;
13256 case 0xb7: /* LCTL */ goto unimplemented;
13257 case 0xba: s390_format_RS_RRRD(s390_irgen_CS, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13258 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
florian448cbba2012-06-06 02:26:01 +000013259 case 0xbb: s390_format_RS_RRRD(s390_irgen_CDS, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13260 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013261 case 0xbd: s390_format_RS_RURD(s390_irgen_CLM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13262 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13263 case 0xbe: s390_format_RS_RURD(s390_irgen_STCM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13264 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13265 case 0xbf: s390_format_RS_RURD(s390_irgen_ICM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13266 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13267 }
13268
13269 return S390_DECODE_UNKNOWN_INSN;
13270
13271ok:
13272 return S390_DECODE_OK;
13273
13274unimplemented:
13275 return S390_DECODE_UNIMPLEMENTED_INSN;
13276}
13277
13278static s390_decode_t
13279s390_decode_6byte_and_irgen(UChar *bytes)
13280{
13281 typedef union {
13282 struct {
13283 unsigned int op1 : 8;
13284 unsigned int r1 : 4;
13285 unsigned int r3 : 4;
13286 unsigned int i2 : 16;
13287 unsigned int : 8;
13288 unsigned int op2 : 8;
13289 } RIE;
13290 struct {
13291 unsigned int op1 : 8;
13292 unsigned int r1 : 4;
13293 unsigned int r2 : 4;
13294 unsigned int i3 : 8;
13295 unsigned int i4 : 8;
13296 unsigned int i5 : 8;
13297 unsigned int op2 : 8;
13298 } RIE_RRUUU;
13299 struct {
13300 unsigned int op1 : 8;
13301 unsigned int r1 : 4;
13302 unsigned int : 4;
13303 unsigned int i2 : 16;
13304 unsigned int m3 : 4;
13305 unsigned int : 4;
13306 unsigned int op2 : 8;
13307 } RIEv1;
13308 struct {
13309 unsigned int op1 : 8;
13310 unsigned int r1 : 4;
13311 unsigned int r2 : 4;
13312 unsigned int i4 : 16;
13313 unsigned int m3 : 4;
13314 unsigned int : 4;
13315 unsigned int op2 : 8;
13316 } RIE_RRPU;
13317 struct {
13318 unsigned int op1 : 8;
13319 unsigned int r1 : 4;
13320 unsigned int m3 : 4;
13321 unsigned int i4 : 16;
13322 unsigned int i2 : 8;
13323 unsigned int op2 : 8;
13324 } RIEv3;
13325 struct {
13326 unsigned int op1 : 8;
13327 unsigned int r1 : 4;
13328 unsigned int op2 : 4;
13329 unsigned int i2 : 32;
13330 } RIL;
13331 struct {
13332 unsigned int op1 : 8;
13333 unsigned int r1 : 4;
13334 unsigned int m3 : 4;
13335 unsigned int b4 : 4;
13336 unsigned int d4 : 12;
13337 unsigned int i2 : 8;
13338 unsigned int op2 : 8;
13339 } RIS;
13340 struct {
13341 unsigned int op1 : 8;
13342 unsigned int r1 : 4;
13343 unsigned int r2 : 4;
13344 unsigned int b4 : 4;
13345 unsigned int d4 : 12;
13346 unsigned int m3 : 4;
13347 unsigned int : 4;
13348 unsigned int op2 : 8;
13349 } RRS;
13350 struct {
13351 unsigned int op1 : 8;
13352 unsigned int l1 : 4;
13353 unsigned int : 4;
13354 unsigned int b1 : 4;
13355 unsigned int d1 : 12;
13356 unsigned int : 8;
13357 unsigned int op2 : 8;
13358 } RSL;
13359 struct {
13360 unsigned int op1 : 8;
13361 unsigned int r1 : 4;
13362 unsigned int r3 : 4;
13363 unsigned int b2 : 4;
13364 unsigned int dl2 : 12;
13365 unsigned int dh2 : 8;
13366 unsigned int op2 : 8;
13367 } RSY;
13368 struct {
13369 unsigned int op1 : 8;
13370 unsigned int r1 : 4;
13371 unsigned int x2 : 4;
13372 unsigned int b2 : 4;
13373 unsigned int d2 : 12;
13374 unsigned int : 8;
13375 unsigned int op2 : 8;
13376 } RXE;
13377 struct {
13378 unsigned int op1 : 8;
13379 unsigned int r3 : 4;
13380 unsigned int x2 : 4;
13381 unsigned int b2 : 4;
13382 unsigned int d2 : 12;
13383 unsigned int r1 : 4;
13384 unsigned int : 4;
13385 unsigned int op2 : 8;
13386 } RXF;
13387 struct {
13388 unsigned int op1 : 8;
13389 unsigned int r1 : 4;
13390 unsigned int x2 : 4;
13391 unsigned int b2 : 4;
13392 unsigned int dl2 : 12;
13393 unsigned int dh2 : 8;
13394 unsigned int op2 : 8;
13395 } RXY;
13396 struct {
13397 unsigned int op1 : 8;
13398 unsigned int i2 : 8;
13399 unsigned int b1 : 4;
13400 unsigned int dl1 : 12;
13401 unsigned int dh1 : 8;
13402 unsigned int op2 : 8;
13403 } SIY;
13404 struct {
13405 unsigned int op : 8;
13406 unsigned int l : 8;
13407 unsigned int b1 : 4;
13408 unsigned int d1 : 12;
13409 unsigned int b2 : 4;
13410 unsigned int d2 : 12;
13411 } SS;
13412 struct {
13413 unsigned int op : 8;
13414 unsigned int l1 : 4;
13415 unsigned int l2 : 4;
13416 unsigned int b1 : 4;
13417 unsigned int d1 : 12;
13418 unsigned int b2 : 4;
13419 unsigned int d2 : 12;
13420 } SS_LLRDRD;
13421 struct {
13422 unsigned int op : 8;
13423 unsigned int r1 : 4;
13424 unsigned int r3 : 4;
13425 unsigned int b2 : 4;
13426 unsigned int d2 : 12;
13427 unsigned int b4 : 4;
13428 unsigned int d4 : 12;
13429 } SS_RRRDRD2;
13430 struct {
13431 unsigned int op : 16;
13432 unsigned int b1 : 4;
13433 unsigned int d1 : 12;
13434 unsigned int b2 : 4;
13435 unsigned int d2 : 12;
13436 } SSE;
13437 struct {
13438 unsigned int op1 : 8;
13439 unsigned int r3 : 4;
13440 unsigned int op2 : 4;
13441 unsigned int b1 : 4;
13442 unsigned int d1 : 12;
13443 unsigned int b2 : 4;
13444 unsigned int d2 : 12;
13445 } SSF;
13446 struct {
13447 unsigned int op : 16;
13448 unsigned int b1 : 4;
13449 unsigned int d1 : 12;
13450 unsigned int i2 : 16;
13451 } SIL;
13452 } formats;
13453 union {
13454 formats fmt;
13455 ULong value;
13456 } ovl;
13457
13458 vassert(sizeof(formats) == 6);
13459
13460 ((char *)(&ovl.value))[0] = bytes[0];
13461 ((char *)(&ovl.value))[1] = bytes[1];
13462 ((char *)(&ovl.value))[2] = bytes[2];
13463 ((char *)(&ovl.value))[3] = bytes[3];
13464 ((char *)(&ovl.value))[4] = bytes[4];
13465 ((char *)(&ovl.value))[5] = bytes[5];
13466 ((char *)(&ovl.value))[6] = 0x0;
13467 ((char *)(&ovl.value))[7] = 0x0;
13468
13469 switch ((ovl.value >> 16) & 0xff00000000ffULL) {
13470 case 0xe30000000002ULL: s390_format_RXY_RRRD(s390_irgen_LTG, ovl.fmt.RXY.r1,
13471 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13472 ovl.fmt.RXY.dl2,
13473 ovl.fmt.RXY.dh2); goto ok;
13474 case 0xe30000000003ULL: /* LRAG */ goto unimplemented;
13475 case 0xe30000000004ULL: s390_format_RXY_RRRD(s390_irgen_LG, ovl.fmt.RXY.r1,
13476 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13477 ovl.fmt.RXY.dl2,
13478 ovl.fmt.RXY.dh2); goto ok;
13479 case 0xe30000000006ULL: s390_format_RXY_RRRD(s390_irgen_CVBY, ovl.fmt.RXY.r1,
13480 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13481 ovl.fmt.RXY.dl2,
13482 ovl.fmt.RXY.dh2); goto ok;
13483 case 0xe30000000008ULL: s390_format_RXY_RRRD(s390_irgen_AG, ovl.fmt.RXY.r1,
13484 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13485 ovl.fmt.RXY.dl2,
13486 ovl.fmt.RXY.dh2); goto ok;
13487 case 0xe30000000009ULL: s390_format_RXY_RRRD(s390_irgen_SG, ovl.fmt.RXY.r1,
13488 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13489 ovl.fmt.RXY.dl2,
13490 ovl.fmt.RXY.dh2); goto ok;
13491 case 0xe3000000000aULL: s390_format_RXY_RRRD(s390_irgen_ALG, ovl.fmt.RXY.r1,
13492 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13493 ovl.fmt.RXY.dl2,
13494 ovl.fmt.RXY.dh2); goto ok;
13495 case 0xe3000000000bULL: s390_format_RXY_RRRD(s390_irgen_SLG, ovl.fmt.RXY.r1,
13496 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13497 ovl.fmt.RXY.dl2,
13498 ovl.fmt.RXY.dh2); goto ok;
13499 case 0xe3000000000cULL: s390_format_RXY_RRRD(s390_irgen_MSG, ovl.fmt.RXY.r1,
13500 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13501 ovl.fmt.RXY.dl2,
13502 ovl.fmt.RXY.dh2); goto ok;
13503 case 0xe3000000000dULL: s390_format_RXY_RRRD(s390_irgen_DSG, ovl.fmt.RXY.r1,
13504 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13505 ovl.fmt.RXY.dl2,
13506 ovl.fmt.RXY.dh2); goto ok;
13507 case 0xe3000000000eULL: /* CVBG */ goto unimplemented;
13508 case 0xe3000000000fULL: s390_format_RXY_RRRD(s390_irgen_LRVG, ovl.fmt.RXY.r1,
13509 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13510 ovl.fmt.RXY.dl2,
13511 ovl.fmt.RXY.dh2); goto ok;
13512 case 0xe30000000012ULL: s390_format_RXY_RRRD(s390_irgen_LT, ovl.fmt.RXY.r1,
13513 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13514 ovl.fmt.RXY.dl2,
13515 ovl.fmt.RXY.dh2); goto ok;
13516 case 0xe30000000013ULL: /* LRAY */ goto unimplemented;
13517 case 0xe30000000014ULL: s390_format_RXY_RRRD(s390_irgen_LGF, ovl.fmt.RXY.r1,
13518 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13519 ovl.fmt.RXY.dl2,
13520 ovl.fmt.RXY.dh2); goto ok;
13521 case 0xe30000000015ULL: s390_format_RXY_RRRD(s390_irgen_LGH, ovl.fmt.RXY.r1,
13522 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13523 ovl.fmt.RXY.dl2,
13524 ovl.fmt.RXY.dh2); goto ok;
13525 case 0xe30000000016ULL: s390_format_RXY_RRRD(s390_irgen_LLGF, ovl.fmt.RXY.r1,
13526 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13527 ovl.fmt.RXY.dl2,
13528 ovl.fmt.RXY.dh2); goto ok;
13529 case 0xe30000000017ULL: s390_format_RXY_RRRD(s390_irgen_LLGT, ovl.fmt.RXY.r1,
13530 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13531 ovl.fmt.RXY.dl2,
13532 ovl.fmt.RXY.dh2); goto ok;
13533 case 0xe30000000018ULL: s390_format_RXY_RRRD(s390_irgen_AGF, ovl.fmt.RXY.r1,
13534 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13535 ovl.fmt.RXY.dl2,
13536 ovl.fmt.RXY.dh2); goto ok;
13537 case 0xe30000000019ULL: s390_format_RXY_RRRD(s390_irgen_SGF, ovl.fmt.RXY.r1,
13538 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13539 ovl.fmt.RXY.dl2,
13540 ovl.fmt.RXY.dh2); goto ok;
13541 case 0xe3000000001aULL: s390_format_RXY_RRRD(s390_irgen_ALGF, ovl.fmt.RXY.r1,
13542 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13543 ovl.fmt.RXY.dl2,
13544 ovl.fmt.RXY.dh2); goto ok;
13545 case 0xe3000000001bULL: s390_format_RXY_RRRD(s390_irgen_SLGF, ovl.fmt.RXY.r1,
13546 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13547 ovl.fmt.RXY.dl2,
13548 ovl.fmt.RXY.dh2); goto ok;
13549 case 0xe3000000001cULL: s390_format_RXY_RRRD(s390_irgen_MSGF, ovl.fmt.RXY.r1,
13550 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13551 ovl.fmt.RXY.dl2,
13552 ovl.fmt.RXY.dh2); goto ok;
13553 case 0xe3000000001dULL: s390_format_RXY_RRRD(s390_irgen_DSGF, ovl.fmt.RXY.r1,
13554 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13555 ovl.fmt.RXY.dl2,
13556 ovl.fmt.RXY.dh2); goto ok;
13557 case 0xe3000000001eULL: s390_format_RXY_RRRD(s390_irgen_LRV, ovl.fmt.RXY.r1,
13558 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13559 ovl.fmt.RXY.dl2,
13560 ovl.fmt.RXY.dh2); goto ok;
13561 case 0xe3000000001fULL: s390_format_RXY_RRRD(s390_irgen_LRVH, ovl.fmt.RXY.r1,
13562 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13563 ovl.fmt.RXY.dl2,
13564 ovl.fmt.RXY.dh2); goto ok;
13565 case 0xe30000000020ULL: s390_format_RXY_RRRD(s390_irgen_CG, ovl.fmt.RXY.r1,
13566 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13567 ovl.fmt.RXY.dl2,
13568 ovl.fmt.RXY.dh2); goto ok;
13569 case 0xe30000000021ULL: s390_format_RXY_RRRD(s390_irgen_CLG, ovl.fmt.RXY.r1,
13570 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13571 ovl.fmt.RXY.dl2,
13572 ovl.fmt.RXY.dh2); goto ok;
13573 case 0xe30000000024ULL: s390_format_RXY_RRRD(s390_irgen_STG, ovl.fmt.RXY.r1,
13574 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13575 ovl.fmt.RXY.dl2,
13576 ovl.fmt.RXY.dh2); goto ok;
13577 case 0xe30000000026ULL: s390_format_RXY_RRRD(s390_irgen_CVDY, ovl.fmt.RXY.r1,
13578 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13579 ovl.fmt.RXY.dl2,
13580 ovl.fmt.RXY.dh2); goto ok;
13581 case 0xe3000000002eULL: /* CVDG */ goto unimplemented;
13582 case 0xe3000000002fULL: s390_format_RXY_RRRD(s390_irgen_STRVG,
13583 ovl.fmt.RXY.r1, ovl.fmt.RXY.x2,
13584 ovl.fmt.RXY.b2, ovl.fmt.RXY.dl2,
13585 ovl.fmt.RXY.dh2); goto ok;
13586 case 0xe30000000030ULL: s390_format_RXY_RRRD(s390_irgen_CGF, ovl.fmt.RXY.r1,
13587 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13588 ovl.fmt.RXY.dl2,
13589 ovl.fmt.RXY.dh2); goto ok;
13590 case 0xe30000000031ULL: s390_format_RXY_RRRD(s390_irgen_CLGF, ovl.fmt.RXY.r1,
13591 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13592 ovl.fmt.RXY.dl2,
13593 ovl.fmt.RXY.dh2); goto ok;
13594 case 0xe30000000032ULL: s390_format_RXY_RRRD(s390_irgen_LTGF, ovl.fmt.RXY.r1,
13595 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13596 ovl.fmt.RXY.dl2,
13597 ovl.fmt.RXY.dh2); goto ok;
13598 case 0xe30000000034ULL: s390_format_RXY_RRRD(s390_irgen_CGH, ovl.fmt.RXY.r1,
13599 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13600 ovl.fmt.RXY.dl2,
13601 ovl.fmt.RXY.dh2); goto ok;
13602 case 0xe30000000036ULL: s390_format_RXY_URRD(s390_irgen_PFD, ovl.fmt.RXY.r1,
13603 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13604 ovl.fmt.RXY.dl2,
13605 ovl.fmt.RXY.dh2); goto ok;
13606 case 0xe3000000003eULL: s390_format_RXY_RRRD(s390_irgen_STRV, ovl.fmt.RXY.r1,
13607 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13608 ovl.fmt.RXY.dl2,
13609 ovl.fmt.RXY.dh2); goto ok;
13610 case 0xe3000000003fULL: s390_format_RXY_RRRD(s390_irgen_STRVH,
13611 ovl.fmt.RXY.r1, ovl.fmt.RXY.x2,
13612 ovl.fmt.RXY.b2, ovl.fmt.RXY.dl2,
13613 ovl.fmt.RXY.dh2); goto ok;
13614 case 0xe30000000046ULL: s390_format_RXY_RRRD(s390_irgen_BCTG, ovl.fmt.RXY.r1,
13615 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13616 ovl.fmt.RXY.dl2,
13617 ovl.fmt.RXY.dh2); goto ok;
13618 case 0xe30000000050ULL: s390_format_RXY_RRRD(s390_irgen_STY, ovl.fmt.RXY.r1,
13619 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13620 ovl.fmt.RXY.dl2,
13621 ovl.fmt.RXY.dh2); goto ok;
13622 case 0xe30000000051ULL: s390_format_RXY_RRRD(s390_irgen_MSY, ovl.fmt.RXY.r1,
13623 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13624 ovl.fmt.RXY.dl2,
13625 ovl.fmt.RXY.dh2); goto ok;
13626 case 0xe30000000054ULL: s390_format_RXY_RRRD(s390_irgen_NY, ovl.fmt.RXY.r1,
13627 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13628 ovl.fmt.RXY.dl2,
13629 ovl.fmt.RXY.dh2); goto ok;
13630 case 0xe30000000055ULL: s390_format_RXY_RRRD(s390_irgen_CLY, ovl.fmt.RXY.r1,
13631 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13632 ovl.fmt.RXY.dl2,
13633 ovl.fmt.RXY.dh2); goto ok;
13634 case 0xe30000000056ULL: s390_format_RXY_RRRD(s390_irgen_OY, ovl.fmt.RXY.r1,
13635 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13636 ovl.fmt.RXY.dl2,
13637 ovl.fmt.RXY.dh2); goto ok;
13638 case 0xe30000000057ULL: s390_format_RXY_RRRD(s390_irgen_XY, ovl.fmt.RXY.r1,
13639 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13640 ovl.fmt.RXY.dl2,
13641 ovl.fmt.RXY.dh2); goto ok;
13642 case 0xe30000000058ULL: s390_format_RXY_RRRD(s390_irgen_LY, ovl.fmt.RXY.r1,
13643 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13644 ovl.fmt.RXY.dl2,
13645 ovl.fmt.RXY.dh2); goto ok;
13646 case 0xe30000000059ULL: s390_format_RXY_RRRD(s390_irgen_CY, ovl.fmt.RXY.r1,
13647 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13648 ovl.fmt.RXY.dl2,
13649 ovl.fmt.RXY.dh2); goto ok;
13650 case 0xe3000000005aULL: s390_format_RXY_RRRD(s390_irgen_AY, ovl.fmt.RXY.r1,
13651 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13652 ovl.fmt.RXY.dl2,
13653 ovl.fmt.RXY.dh2); goto ok;
13654 case 0xe3000000005bULL: s390_format_RXY_RRRD(s390_irgen_SY, ovl.fmt.RXY.r1,
13655 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13656 ovl.fmt.RXY.dl2,
13657 ovl.fmt.RXY.dh2); goto ok;
13658 case 0xe3000000005cULL: s390_format_RXY_RRRD(s390_irgen_MFY, ovl.fmt.RXY.r1,
13659 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13660 ovl.fmt.RXY.dl2,
13661 ovl.fmt.RXY.dh2); goto ok;
13662 case 0xe3000000005eULL: s390_format_RXY_RRRD(s390_irgen_ALY, ovl.fmt.RXY.r1,
13663 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13664 ovl.fmt.RXY.dl2,
13665 ovl.fmt.RXY.dh2); goto ok;
13666 case 0xe3000000005fULL: s390_format_RXY_RRRD(s390_irgen_SLY, ovl.fmt.RXY.r1,
13667 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13668 ovl.fmt.RXY.dl2,
13669 ovl.fmt.RXY.dh2); goto ok;
13670 case 0xe30000000070ULL: s390_format_RXY_RRRD(s390_irgen_STHY, ovl.fmt.RXY.r1,
13671 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13672 ovl.fmt.RXY.dl2,
13673 ovl.fmt.RXY.dh2); goto ok;
13674 case 0xe30000000071ULL: s390_format_RXY_RRRD(s390_irgen_LAY, ovl.fmt.RXY.r1,
13675 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13676 ovl.fmt.RXY.dl2,
13677 ovl.fmt.RXY.dh2); goto ok;
13678 case 0xe30000000072ULL: s390_format_RXY_RRRD(s390_irgen_STCY, ovl.fmt.RXY.r1,
13679 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13680 ovl.fmt.RXY.dl2,
13681 ovl.fmt.RXY.dh2); goto ok;
13682 case 0xe30000000073ULL: s390_format_RXY_RRRD(s390_irgen_ICY, ovl.fmt.RXY.r1,
13683 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13684 ovl.fmt.RXY.dl2,
13685 ovl.fmt.RXY.dh2); goto ok;
13686 case 0xe30000000075ULL: s390_format_RXY_RRRD(s390_irgen_LAEY, ovl.fmt.RXY.r1,
13687 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13688 ovl.fmt.RXY.dl2,
13689 ovl.fmt.RXY.dh2); goto ok;
13690 case 0xe30000000076ULL: s390_format_RXY_RRRD(s390_irgen_LB, ovl.fmt.RXY.r1,
13691 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13692 ovl.fmt.RXY.dl2,
13693 ovl.fmt.RXY.dh2); goto ok;
13694 case 0xe30000000077ULL: s390_format_RXY_RRRD(s390_irgen_LGB, ovl.fmt.RXY.r1,
13695 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13696 ovl.fmt.RXY.dl2,
13697 ovl.fmt.RXY.dh2); goto ok;
13698 case 0xe30000000078ULL: s390_format_RXY_RRRD(s390_irgen_LHY, ovl.fmt.RXY.r1,
13699 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13700 ovl.fmt.RXY.dl2,
13701 ovl.fmt.RXY.dh2); goto ok;
13702 case 0xe30000000079ULL: s390_format_RXY_RRRD(s390_irgen_CHY, ovl.fmt.RXY.r1,
13703 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13704 ovl.fmt.RXY.dl2,
13705 ovl.fmt.RXY.dh2); goto ok;
13706 case 0xe3000000007aULL: s390_format_RXY_RRRD(s390_irgen_AHY, ovl.fmt.RXY.r1,
13707 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13708 ovl.fmt.RXY.dl2,
13709 ovl.fmt.RXY.dh2); goto ok;
13710 case 0xe3000000007bULL: s390_format_RXY_RRRD(s390_irgen_SHY, ovl.fmt.RXY.r1,
13711 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13712 ovl.fmt.RXY.dl2,
13713 ovl.fmt.RXY.dh2); goto ok;
13714 case 0xe3000000007cULL: s390_format_RXY_RRRD(s390_irgen_MHY, ovl.fmt.RXY.r1,
13715 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13716 ovl.fmt.RXY.dl2,
13717 ovl.fmt.RXY.dh2); goto ok;
13718 case 0xe30000000080ULL: s390_format_RXY_RRRD(s390_irgen_NG, ovl.fmt.RXY.r1,
13719 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13720 ovl.fmt.RXY.dl2,
13721 ovl.fmt.RXY.dh2); goto ok;
13722 case 0xe30000000081ULL: s390_format_RXY_RRRD(s390_irgen_OG, ovl.fmt.RXY.r1,
13723 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13724 ovl.fmt.RXY.dl2,
13725 ovl.fmt.RXY.dh2); goto ok;
13726 case 0xe30000000082ULL: s390_format_RXY_RRRD(s390_irgen_XG, ovl.fmt.RXY.r1,
13727 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13728 ovl.fmt.RXY.dl2,
13729 ovl.fmt.RXY.dh2); goto ok;
13730 case 0xe30000000086ULL: s390_format_RXY_RRRD(s390_irgen_MLG, ovl.fmt.RXY.r1,
13731 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13732 ovl.fmt.RXY.dl2,
13733 ovl.fmt.RXY.dh2); goto ok;
13734 case 0xe30000000087ULL: s390_format_RXY_RRRD(s390_irgen_DLG, ovl.fmt.RXY.r1,
13735 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13736 ovl.fmt.RXY.dl2,
13737 ovl.fmt.RXY.dh2); goto ok;
13738 case 0xe30000000088ULL: s390_format_RXY_RRRD(s390_irgen_ALCG, ovl.fmt.RXY.r1,
13739 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13740 ovl.fmt.RXY.dl2,
13741 ovl.fmt.RXY.dh2); goto ok;
13742 case 0xe30000000089ULL: s390_format_RXY_RRRD(s390_irgen_SLBG, ovl.fmt.RXY.r1,
13743 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13744 ovl.fmt.RXY.dl2,
13745 ovl.fmt.RXY.dh2); goto ok;
13746 case 0xe3000000008eULL: s390_format_RXY_RRRD(s390_irgen_STPQ, ovl.fmt.RXY.r1,
13747 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13748 ovl.fmt.RXY.dl2,
13749 ovl.fmt.RXY.dh2); goto ok;
13750 case 0xe3000000008fULL: s390_format_RXY_RRRD(s390_irgen_LPQ, ovl.fmt.RXY.r1,
13751 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13752 ovl.fmt.RXY.dl2,
13753 ovl.fmt.RXY.dh2); goto ok;
13754 case 0xe30000000090ULL: s390_format_RXY_RRRD(s390_irgen_LLGC, ovl.fmt.RXY.r1,
13755 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13756 ovl.fmt.RXY.dl2,
13757 ovl.fmt.RXY.dh2); goto ok;
13758 case 0xe30000000091ULL: s390_format_RXY_RRRD(s390_irgen_LLGH, ovl.fmt.RXY.r1,
13759 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13760 ovl.fmt.RXY.dl2,
13761 ovl.fmt.RXY.dh2); goto ok;
13762 case 0xe30000000094ULL: s390_format_RXY_RRRD(s390_irgen_LLC, ovl.fmt.RXY.r1,
13763 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13764 ovl.fmt.RXY.dl2,
13765 ovl.fmt.RXY.dh2); goto ok;
13766 case 0xe30000000095ULL: s390_format_RXY_RRRD(s390_irgen_LLH, ovl.fmt.RXY.r1,
13767 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13768 ovl.fmt.RXY.dl2,
13769 ovl.fmt.RXY.dh2); goto ok;
13770 case 0xe30000000096ULL: s390_format_RXY_RRRD(s390_irgen_ML, ovl.fmt.RXY.r1,
13771 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13772 ovl.fmt.RXY.dl2,
13773 ovl.fmt.RXY.dh2); goto ok;
13774 case 0xe30000000097ULL: s390_format_RXY_RRRD(s390_irgen_DL, ovl.fmt.RXY.r1,
13775 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13776 ovl.fmt.RXY.dl2,
13777 ovl.fmt.RXY.dh2); goto ok;
13778 case 0xe30000000098ULL: s390_format_RXY_RRRD(s390_irgen_ALC, ovl.fmt.RXY.r1,
13779 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13780 ovl.fmt.RXY.dl2,
13781 ovl.fmt.RXY.dh2); goto ok;
13782 case 0xe30000000099ULL: s390_format_RXY_RRRD(s390_irgen_SLB, ovl.fmt.RXY.r1,
13783 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13784 ovl.fmt.RXY.dl2,
13785 ovl.fmt.RXY.dh2); goto ok;
13786 case 0xe300000000c0ULL: s390_format_RXY_RRRD(s390_irgen_LBH, ovl.fmt.RXY.r1,
13787 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13788 ovl.fmt.RXY.dl2,
13789 ovl.fmt.RXY.dh2); goto ok;
13790 case 0xe300000000c2ULL: s390_format_RXY_RRRD(s390_irgen_LLCH, ovl.fmt.RXY.r1,
13791 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13792 ovl.fmt.RXY.dl2,
13793 ovl.fmt.RXY.dh2); goto ok;
13794 case 0xe300000000c3ULL: s390_format_RXY_RRRD(s390_irgen_STCH, ovl.fmt.RXY.r1,
13795 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13796 ovl.fmt.RXY.dl2,
13797 ovl.fmt.RXY.dh2); goto ok;
13798 case 0xe300000000c4ULL: s390_format_RXY_RRRD(s390_irgen_LHH, ovl.fmt.RXY.r1,
13799 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13800 ovl.fmt.RXY.dl2,
13801 ovl.fmt.RXY.dh2); goto ok;
13802 case 0xe300000000c6ULL: s390_format_RXY_RRRD(s390_irgen_LLHH, ovl.fmt.RXY.r1,
13803 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13804 ovl.fmt.RXY.dl2,
13805 ovl.fmt.RXY.dh2); goto ok;
13806 case 0xe300000000c7ULL: s390_format_RXY_RRRD(s390_irgen_STHH, ovl.fmt.RXY.r1,
13807 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13808 ovl.fmt.RXY.dl2,
13809 ovl.fmt.RXY.dh2); goto ok;
13810 case 0xe300000000caULL: s390_format_RXY_RRRD(s390_irgen_LFH, ovl.fmt.RXY.r1,
13811 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13812 ovl.fmt.RXY.dl2,
13813 ovl.fmt.RXY.dh2); goto ok;
13814 case 0xe300000000cbULL: s390_format_RXY_RRRD(s390_irgen_STFH, ovl.fmt.RXY.r1,
13815 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13816 ovl.fmt.RXY.dl2,
13817 ovl.fmt.RXY.dh2); goto ok;
13818 case 0xe300000000cdULL: s390_format_RXY_RRRD(s390_irgen_CHF, ovl.fmt.RXY.r1,
13819 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13820 ovl.fmt.RXY.dl2,
13821 ovl.fmt.RXY.dh2); goto ok;
13822 case 0xe300000000cfULL: s390_format_RXY_RRRD(s390_irgen_CLHF, ovl.fmt.RXY.r1,
13823 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13824 ovl.fmt.RXY.dl2,
13825 ovl.fmt.RXY.dh2); goto ok;
13826 case 0xeb0000000004ULL: s390_format_RSY_RRRD(s390_irgen_LMG, ovl.fmt.RSY.r1,
13827 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13828 ovl.fmt.RSY.dl2,
13829 ovl.fmt.RSY.dh2); goto ok;
13830 case 0xeb000000000aULL: s390_format_RSY_RRRD(s390_irgen_SRAG, ovl.fmt.RSY.r1,
13831 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13832 ovl.fmt.RSY.dl2,
13833 ovl.fmt.RSY.dh2); goto ok;
13834 case 0xeb000000000bULL: s390_format_RSY_RRRD(s390_irgen_SLAG, ovl.fmt.RSY.r1,
13835 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13836 ovl.fmt.RSY.dl2,
13837 ovl.fmt.RSY.dh2); goto ok;
13838 case 0xeb000000000cULL: s390_format_RSY_RRRD(s390_irgen_SRLG, ovl.fmt.RSY.r1,
13839 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13840 ovl.fmt.RSY.dl2,
13841 ovl.fmt.RSY.dh2); goto ok;
13842 case 0xeb000000000dULL: s390_format_RSY_RRRD(s390_irgen_SLLG, ovl.fmt.RSY.r1,
13843 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13844 ovl.fmt.RSY.dl2,
13845 ovl.fmt.RSY.dh2); goto ok;
13846 case 0xeb000000000fULL: /* TRACG */ goto unimplemented;
13847 case 0xeb0000000014ULL: s390_format_RSY_RRRD(s390_irgen_CSY, ovl.fmt.RSY.r1,
13848 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13849 ovl.fmt.RSY.dl2,
13850 ovl.fmt.RSY.dh2); goto ok;
13851 case 0xeb000000001cULL: s390_format_RSY_RRRD(s390_irgen_RLLG, ovl.fmt.RSY.r1,
13852 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13853 ovl.fmt.RSY.dl2,
13854 ovl.fmt.RSY.dh2); goto ok;
13855 case 0xeb000000001dULL: s390_format_RSY_RRRD(s390_irgen_RLL, ovl.fmt.RSY.r1,
13856 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13857 ovl.fmt.RSY.dl2,
13858 ovl.fmt.RSY.dh2); goto ok;
13859 case 0xeb0000000020ULL: s390_format_RSY_RURD(s390_irgen_CLMH, ovl.fmt.RSY.r1,
13860 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13861 ovl.fmt.RSY.dl2,
13862 ovl.fmt.RSY.dh2); goto ok;
13863 case 0xeb0000000021ULL: s390_format_RSY_RURD(s390_irgen_CLMY, ovl.fmt.RSY.r1,
13864 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13865 ovl.fmt.RSY.dl2,
13866 ovl.fmt.RSY.dh2); goto ok;
13867 case 0xeb0000000024ULL: s390_format_RSY_RRRD(s390_irgen_STMG, ovl.fmt.RSY.r1,
13868 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13869 ovl.fmt.RSY.dl2,
13870 ovl.fmt.RSY.dh2); goto ok;
13871 case 0xeb0000000025ULL: /* STCTG */ goto unimplemented;
13872 case 0xeb0000000026ULL: s390_format_RSY_RRRD(s390_irgen_STMH, ovl.fmt.RSY.r1,
13873 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13874 ovl.fmt.RSY.dl2,
13875 ovl.fmt.RSY.dh2); goto ok;
13876 case 0xeb000000002cULL: s390_format_RSY_RURD(s390_irgen_STCMH,
13877 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
13878 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
13879 ovl.fmt.RSY.dh2); goto ok;
13880 case 0xeb000000002dULL: s390_format_RSY_RURD(s390_irgen_STCMY,
13881 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
13882 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
13883 ovl.fmt.RSY.dh2); goto ok;
13884 case 0xeb000000002fULL: /* LCTLG */ goto unimplemented;
13885 case 0xeb0000000030ULL: s390_format_RSY_RRRD(s390_irgen_CSG, ovl.fmt.RSY.r1,
13886 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13887 ovl.fmt.RSY.dl2,
13888 ovl.fmt.RSY.dh2); goto ok;
florian448cbba2012-06-06 02:26:01 +000013889 case 0xeb0000000031ULL: s390_format_RSY_RRRD(s390_irgen_CDSY, ovl.fmt.RSY.r1,
13890 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13891 ovl.fmt.RSY.dl2,
13892 ovl.fmt.RSY.dh2); goto ok;
13893 case 0xeb000000003eULL: s390_format_RSY_RRRD(s390_irgen_CDSG, ovl.fmt.RSY.r1,
13894 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13895 ovl.fmt.RSY.dl2,
13896 ovl.fmt.RSY.dh2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013897 case 0xeb0000000044ULL: s390_format_RSY_RRRD(s390_irgen_BXHG, ovl.fmt.RSY.r1,
13898 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13899 ovl.fmt.RSY.dl2,
13900 ovl.fmt.RSY.dh2); goto ok;
13901 case 0xeb0000000045ULL: s390_format_RSY_RRRD(s390_irgen_BXLEG,
13902 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
13903 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
13904 ovl.fmt.RSY.dh2); goto ok;
florian8c88cb62012-08-26 18:58:13 +000013905 case 0xeb000000004cULL: s390_format_RSY_RRRD(s390_irgen_ECAG, ovl.fmt.RSY.r1,
13906 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13907 ovl.fmt.RSY.dl2,
13908 ovl.fmt.RSY.dh2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013909 case 0xeb0000000051ULL: s390_format_SIY_URD(s390_irgen_TMY, ovl.fmt.SIY.i2,
13910 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
13911 ovl.fmt.SIY.dh1); goto ok;
13912 case 0xeb0000000052ULL: s390_format_SIY_URD(s390_irgen_MVIY, ovl.fmt.SIY.i2,
13913 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
13914 ovl.fmt.SIY.dh1); goto ok;
13915 case 0xeb0000000054ULL: s390_format_SIY_URD(s390_irgen_NIY, ovl.fmt.SIY.i2,
13916 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
13917 ovl.fmt.SIY.dh1); goto ok;
13918 case 0xeb0000000055ULL: s390_format_SIY_URD(s390_irgen_CLIY, ovl.fmt.SIY.i2,
13919 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
13920 ovl.fmt.SIY.dh1); goto ok;
13921 case 0xeb0000000056ULL: s390_format_SIY_URD(s390_irgen_OIY, ovl.fmt.SIY.i2,
13922 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
13923 ovl.fmt.SIY.dh1); goto ok;
13924 case 0xeb0000000057ULL: s390_format_SIY_URD(s390_irgen_XIY, ovl.fmt.SIY.i2,
13925 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
13926 ovl.fmt.SIY.dh1); goto ok;
13927 case 0xeb000000006aULL: s390_format_SIY_IRD(s390_irgen_ASI, ovl.fmt.SIY.i2,
13928 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
13929 ovl.fmt.SIY.dh1); goto ok;
13930 case 0xeb000000006eULL: s390_format_SIY_IRD(s390_irgen_ALSI, ovl.fmt.SIY.i2,
13931 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
13932 ovl.fmt.SIY.dh1); goto ok;
13933 case 0xeb000000007aULL: s390_format_SIY_IRD(s390_irgen_AGSI, ovl.fmt.SIY.i2,
13934 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
13935 ovl.fmt.SIY.dh1); goto ok;
13936 case 0xeb000000007eULL: s390_format_SIY_IRD(s390_irgen_ALGSI, ovl.fmt.SIY.i2,
13937 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
13938 ovl.fmt.SIY.dh1); goto ok;
13939 case 0xeb0000000080ULL: s390_format_RSY_RURD(s390_irgen_ICMH, ovl.fmt.RSY.r1,
13940 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13941 ovl.fmt.RSY.dl2,
13942 ovl.fmt.RSY.dh2); goto ok;
13943 case 0xeb0000000081ULL: s390_format_RSY_RURD(s390_irgen_ICMY, ovl.fmt.RSY.r1,
13944 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13945 ovl.fmt.RSY.dl2,
13946 ovl.fmt.RSY.dh2); goto ok;
13947 case 0xeb000000008eULL: /* MVCLU */ goto unimplemented;
13948 case 0xeb000000008fULL: /* CLCLU */ goto unimplemented;
13949 case 0xeb0000000090ULL: s390_format_RSY_RRRD(s390_irgen_STMY, ovl.fmt.RSY.r1,
13950 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13951 ovl.fmt.RSY.dl2,
13952 ovl.fmt.RSY.dh2); goto ok;
13953 case 0xeb0000000096ULL: s390_format_RSY_RRRD(s390_irgen_LMH, ovl.fmt.RSY.r1,
13954 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13955 ovl.fmt.RSY.dl2,
13956 ovl.fmt.RSY.dh2); goto ok;
13957 case 0xeb0000000098ULL: s390_format_RSY_RRRD(s390_irgen_LMY, ovl.fmt.RSY.r1,
13958 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13959 ovl.fmt.RSY.dl2,
13960 ovl.fmt.RSY.dh2); goto ok;
13961 case 0xeb000000009aULL: s390_format_RSY_AARD(s390_irgen_LAMY, ovl.fmt.RSY.r1,
13962 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13963 ovl.fmt.RSY.dl2,
13964 ovl.fmt.RSY.dh2); goto ok;
13965 case 0xeb000000009bULL: s390_format_RSY_AARD(s390_irgen_STAMY,
13966 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
13967 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
13968 ovl.fmt.RSY.dh2); goto ok;
13969 case 0xeb00000000c0ULL: /* TP */ goto unimplemented;
13970 case 0xeb00000000dcULL: s390_format_RSY_RRRD(s390_irgen_SRAK, ovl.fmt.RSY.r1,
13971 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13972 ovl.fmt.RSY.dl2,
13973 ovl.fmt.RSY.dh2); goto ok;
13974 case 0xeb00000000ddULL: s390_format_RSY_RRRD(s390_irgen_SLAK, ovl.fmt.RSY.r1,
13975 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13976 ovl.fmt.RSY.dl2,
13977 ovl.fmt.RSY.dh2); goto ok;
13978 case 0xeb00000000deULL: s390_format_RSY_RRRD(s390_irgen_SRLK, ovl.fmt.RSY.r1,
13979 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13980 ovl.fmt.RSY.dl2,
13981 ovl.fmt.RSY.dh2); goto ok;
13982 case 0xeb00000000dfULL: s390_format_RSY_RRRD(s390_irgen_SLLK, ovl.fmt.RSY.r1,
13983 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13984 ovl.fmt.RSY.dl2,
13985 ovl.fmt.RSY.dh2); goto ok;
sewardjd7bde722011-04-05 13:19:33 +000013986 case 0xeb00000000e2ULL: s390_format_RSY_RDRM(s390_irgen_LOCG, ovl.fmt.RSY.r1,
13987 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13988 ovl.fmt.RSY.dl2,
13989 ovl.fmt.RSY.dh2,
13990 S390_XMNM_LOCG); goto ok;
13991 case 0xeb00000000e3ULL: s390_format_RSY_RDRM(s390_irgen_STOCG,
13992 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
13993 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
13994 ovl.fmt.RSY.dh2,
13995 S390_XMNM_STOCG); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013996 case 0xeb00000000e4ULL: s390_format_RSY_RRRD(s390_irgen_LANG, ovl.fmt.RSY.r1,
13997 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13998 ovl.fmt.RSY.dl2,
13999 ovl.fmt.RSY.dh2); goto ok;
14000 case 0xeb00000000e6ULL: s390_format_RSY_RRRD(s390_irgen_LAOG, ovl.fmt.RSY.r1,
14001 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14002 ovl.fmt.RSY.dl2,
14003 ovl.fmt.RSY.dh2); goto ok;
14004 case 0xeb00000000e7ULL: s390_format_RSY_RRRD(s390_irgen_LAXG, ovl.fmt.RSY.r1,
14005 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14006 ovl.fmt.RSY.dl2,
14007 ovl.fmt.RSY.dh2); goto ok;
14008 case 0xeb00000000e8ULL: s390_format_RSY_RRRD(s390_irgen_LAAG, ovl.fmt.RSY.r1,
14009 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14010 ovl.fmt.RSY.dl2,
14011 ovl.fmt.RSY.dh2); goto ok;
14012 case 0xeb00000000eaULL: s390_format_RSY_RRRD(s390_irgen_LAALG,
14013 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
14014 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
14015 ovl.fmt.RSY.dh2); goto ok;
sewardjd7bde722011-04-05 13:19:33 +000014016 case 0xeb00000000f2ULL: s390_format_RSY_RDRM(s390_irgen_LOC, ovl.fmt.RSY.r1,
14017 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14018 ovl.fmt.RSY.dl2,
14019 ovl.fmt.RSY.dh2, S390_XMNM_LOC);
14020 goto ok;
14021 case 0xeb00000000f3ULL: s390_format_RSY_RDRM(s390_irgen_STOC, ovl.fmt.RSY.r1,
14022 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14023 ovl.fmt.RSY.dl2,
14024 ovl.fmt.RSY.dh2,
14025 S390_XMNM_STOC); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014026 case 0xeb00000000f4ULL: s390_format_RSY_RRRD(s390_irgen_LAN, ovl.fmt.RSY.r1,
14027 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14028 ovl.fmt.RSY.dl2,
14029 ovl.fmt.RSY.dh2); goto ok;
14030 case 0xeb00000000f6ULL: s390_format_RSY_RRRD(s390_irgen_LAO, ovl.fmt.RSY.r1,
14031 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14032 ovl.fmt.RSY.dl2,
14033 ovl.fmt.RSY.dh2); goto ok;
14034 case 0xeb00000000f7ULL: s390_format_RSY_RRRD(s390_irgen_LAX, ovl.fmt.RSY.r1,
14035 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14036 ovl.fmt.RSY.dl2,
14037 ovl.fmt.RSY.dh2); goto ok;
14038 case 0xeb00000000f8ULL: s390_format_RSY_RRRD(s390_irgen_LAA, ovl.fmt.RSY.r1,
14039 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14040 ovl.fmt.RSY.dl2,
14041 ovl.fmt.RSY.dh2); goto ok;
14042 case 0xeb00000000faULL: s390_format_RSY_RRRD(s390_irgen_LAAL, ovl.fmt.RSY.r1,
14043 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14044 ovl.fmt.RSY.dl2,
14045 ovl.fmt.RSY.dh2); goto ok;
14046 case 0xec0000000044ULL: s390_format_RIE_RRP(s390_irgen_BRXHG, ovl.fmt.RIE.r1,
14047 ovl.fmt.RIE.r3, ovl.fmt.RIE.i2);
14048 goto ok;
14049 case 0xec0000000045ULL: s390_format_RIE_RRP(s390_irgen_BRXLG, ovl.fmt.RIE.r1,
14050 ovl.fmt.RIE.r3, ovl.fmt.RIE.i2);
14051 goto ok;
14052 case 0xec0000000051ULL: /* RISBLG */ goto unimplemented;
14053 case 0xec0000000054ULL: s390_format_RIE_RRUUU(s390_irgen_RNSBG,
14054 ovl.fmt.RIE_RRUUU.r1,
14055 ovl.fmt.RIE_RRUUU.r2,
14056 ovl.fmt.RIE_RRUUU.i3,
14057 ovl.fmt.RIE_RRUUU.i4,
14058 ovl.fmt.RIE_RRUUU.i5);
14059 goto ok;
14060 case 0xec0000000055ULL: s390_format_RIE_RRUUU(s390_irgen_RISBG,
14061 ovl.fmt.RIE_RRUUU.r1,
14062 ovl.fmt.RIE_RRUUU.r2,
14063 ovl.fmt.RIE_RRUUU.i3,
14064 ovl.fmt.RIE_RRUUU.i4,
14065 ovl.fmt.RIE_RRUUU.i5);
14066 goto ok;
14067 case 0xec0000000056ULL: s390_format_RIE_RRUUU(s390_irgen_ROSBG,
14068 ovl.fmt.RIE_RRUUU.r1,
14069 ovl.fmt.RIE_RRUUU.r2,
14070 ovl.fmt.RIE_RRUUU.i3,
14071 ovl.fmt.RIE_RRUUU.i4,
14072 ovl.fmt.RIE_RRUUU.i5);
14073 goto ok;
14074 case 0xec0000000057ULL: s390_format_RIE_RRUUU(s390_irgen_RXSBG,
14075 ovl.fmt.RIE_RRUUU.r1,
14076 ovl.fmt.RIE_RRUUU.r2,
14077 ovl.fmt.RIE_RRUUU.i3,
14078 ovl.fmt.RIE_RRUUU.i4,
14079 ovl.fmt.RIE_RRUUU.i5);
14080 goto ok;
14081 case 0xec000000005dULL: /* RISBHG */ goto unimplemented;
14082 case 0xec0000000064ULL: s390_format_RIE_RRPU(s390_irgen_CGRJ,
14083 ovl.fmt.RIE_RRPU.r1,
14084 ovl.fmt.RIE_RRPU.r2,
14085 ovl.fmt.RIE_RRPU.i4,
14086 ovl.fmt.RIE_RRPU.m3); goto ok;
14087 case 0xec0000000065ULL: s390_format_RIE_RRPU(s390_irgen_CLGRJ,
14088 ovl.fmt.RIE_RRPU.r1,
14089 ovl.fmt.RIE_RRPU.r2,
14090 ovl.fmt.RIE_RRPU.i4,
14091 ovl.fmt.RIE_RRPU.m3); goto ok;
14092 case 0xec0000000070ULL: /* CGIT */ goto unimplemented;
14093 case 0xec0000000071ULL: /* CLGIT */ goto unimplemented;
14094 case 0xec0000000072ULL: /* CIT */ goto unimplemented;
14095 case 0xec0000000073ULL: /* CLFIT */ goto unimplemented;
14096 case 0xec0000000076ULL: s390_format_RIE_RRPU(s390_irgen_CRJ,
14097 ovl.fmt.RIE_RRPU.r1,
14098 ovl.fmt.RIE_RRPU.r2,
14099 ovl.fmt.RIE_RRPU.i4,
14100 ovl.fmt.RIE_RRPU.m3); goto ok;
14101 case 0xec0000000077ULL: s390_format_RIE_RRPU(s390_irgen_CLRJ,
14102 ovl.fmt.RIE_RRPU.r1,
14103 ovl.fmt.RIE_RRPU.r2,
14104 ovl.fmt.RIE_RRPU.i4,
14105 ovl.fmt.RIE_RRPU.m3); goto ok;
14106 case 0xec000000007cULL: s390_format_RIE_RUPI(s390_irgen_CGIJ,
14107 ovl.fmt.RIEv3.r1,
14108 ovl.fmt.RIEv3.m3,
14109 ovl.fmt.RIEv3.i4,
14110 ovl.fmt.RIEv3.i2); goto ok;
14111 case 0xec000000007dULL: s390_format_RIE_RUPU(s390_irgen_CLGIJ,
14112 ovl.fmt.RIEv3.r1,
14113 ovl.fmt.RIEv3.m3,
14114 ovl.fmt.RIEv3.i4,
14115 ovl.fmt.RIEv3.i2); goto ok;
14116 case 0xec000000007eULL: s390_format_RIE_RUPI(s390_irgen_CIJ,
14117 ovl.fmt.RIEv3.r1,
14118 ovl.fmt.RIEv3.m3,
14119 ovl.fmt.RIEv3.i4,
14120 ovl.fmt.RIEv3.i2); goto ok;
14121 case 0xec000000007fULL: s390_format_RIE_RUPU(s390_irgen_CLIJ,
14122 ovl.fmt.RIEv3.r1,
14123 ovl.fmt.RIEv3.m3,
14124 ovl.fmt.RIEv3.i4,
14125 ovl.fmt.RIEv3.i2); goto ok;
14126 case 0xec00000000d8ULL: s390_format_RIE_RRI0(s390_irgen_AHIK, ovl.fmt.RIE.r1,
14127 ovl.fmt.RIE.r3, ovl.fmt.RIE.i2);
14128 goto ok;
14129 case 0xec00000000d9ULL: s390_format_RIE_RRI0(s390_irgen_AGHIK,
14130 ovl.fmt.RIE.r1, ovl.fmt.RIE.r3,
14131 ovl.fmt.RIE.i2); goto ok;
14132 case 0xec00000000daULL: s390_format_RIE_RRI0(s390_irgen_ALHSIK,
14133 ovl.fmt.RIE.r1, ovl.fmt.RIE.r3,
14134 ovl.fmt.RIE.i2); goto ok;
14135 case 0xec00000000dbULL: s390_format_RIE_RRI0(s390_irgen_ALGHSIK,
14136 ovl.fmt.RIE.r1, ovl.fmt.RIE.r3,
14137 ovl.fmt.RIE.i2); goto ok;
14138 case 0xec00000000e4ULL: s390_format_RRS(s390_irgen_CGRB, ovl.fmt.RRS.r1,
14139 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
14140 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
14141 goto ok;
14142 case 0xec00000000e5ULL: s390_format_RRS(s390_irgen_CLGRB, ovl.fmt.RRS.r1,
14143 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
14144 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
14145 goto ok;
14146 case 0xec00000000f6ULL: s390_format_RRS(s390_irgen_CRB, ovl.fmt.RRS.r1,
14147 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
14148 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
14149 goto ok;
14150 case 0xec00000000f7ULL: s390_format_RRS(s390_irgen_CLRB, ovl.fmt.RRS.r1,
14151 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
14152 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
14153 goto ok;
14154 case 0xec00000000fcULL: s390_format_RIS_RURDI(s390_irgen_CGIB,
14155 ovl.fmt.RIS.r1, ovl.fmt.RIS.m3,
14156 ovl.fmt.RIS.b4, ovl.fmt.RIS.d4,
14157 ovl.fmt.RIS.i2); goto ok;
14158 case 0xec00000000fdULL: s390_format_RIS_RURDU(s390_irgen_CLGIB,
14159 ovl.fmt.RIS.r1, ovl.fmt.RIS.m3,
14160 ovl.fmt.RIS.b4, ovl.fmt.RIS.d4,
14161 ovl.fmt.RIS.i2); goto ok;
14162 case 0xec00000000feULL: s390_format_RIS_RURDI(s390_irgen_CIB, ovl.fmt.RIS.r1,
14163 ovl.fmt.RIS.m3, ovl.fmt.RIS.b4,
14164 ovl.fmt.RIS.d4,
14165 ovl.fmt.RIS.i2); goto ok;
14166 case 0xec00000000ffULL: s390_format_RIS_RURDU(s390_irgen_CLIB,
14167 ovl.fmt.RIS.r1, ovl.fmt.RIS.m3,
14168 ovl.fmt.RIS.b4, ovl.fmt.RIS.d4,
14169 ovl.fmt.RIS.i2); goto ok;
14170 case 0xed0000000004ULL: s390_format_RXE_FRRD(s390_irgen_LDEB, ovl.fmt.RXE.r1,
14171 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14172 ovl.fmt.RXE.d2); goto ok;
14173 case 0xed0000000005ULL: s390_format_RXE_FRRD(s390_irgen_LXDB, ovl.fmt.RXE.r1,
14174 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14175 ovl.fmt.RXE.d2); goto ok;
14176 case 0xed0000000006ULL: s390_format_RXE_FRRD(s390_irgen_LXEB, ovl.fmt.RXE.r1,
14177 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14178 ovl.fmt.RXE.d2); goto ok;
14179 case 0xed0000000007ULL: /* MXDB */ goto unimplemented;
14180 case 0xed0000000008ULL: /* KEB */ goto unimplemented;
14181 case 0xed0000000009ULL: s390_format_RXE_FRRD(s390_irgen_CEB, ovl.fmt.RXE.r1,
14182 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14183 ovl.fmt.RXE.d2); goto ok;
14184 case 0xed000000000aULL: s390_format_RXE_FRRD(s390_irgen_AEB, ovl.fmt.RXE.r1,
14185 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14186 ovl.fmt.RXE.d2); goto ok;
14187 case 0xed000000000bULL: s390_format_RXE_FRRD(s390_irgen_SEB, ovl.fmt.RXE.r1,
14188 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14189 ovl.fmt.RXE.d2); goto ok;
14190 case 0xed000000000cULL: /* MDEB */ goto unimplemented;
14191 case 0xed000000000dULL: s390_format_RXE_FRRD(s390_irgen_DEB, ovl.fmt.RXE.r1,
14192 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14193 ovl.fmt.RXE.d2); goto ok;
14194 case 0xed000000000eULL: s390_format_RXF_FRRDF(s390_irgen_MAEB,
14195 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
14196 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
14197 ovl.fmt.RXF.r1); goto ok;
14198 case 0xed000000000fULL: s390_format_RXF_FRRDF(s390_irgen_MSEB,
14199 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
14200 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
14201 ovl.fmt.RXF.r1); goto ok;
14202 case 0xed0000000010ULL: s390_format_RXE_FRRD(s390_irgen_TCEB, ovl.fmt.RXE.r1,
14203 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14204 ovl.fmt.RXE.d2); goto ok;
14205 case 0xed0000000011ULL: s390_format_RXE_FRRD(s390_irgen_TCDB, ovl.fmt.RXE.r1,
14206 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14207 ovl.fmt.RXE.d2); goto ok;
14208 case 0xed0000000012ULL: s390_format_RXE_FRRD(s390_irgen_TCXB, ovl.fmt.RXE.r1,
14209 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14210 ovl.fmt.RXE.d2); goto ok;
14211 case 0xed0000000014ULL: s390_format_RXE_FRRD(s390_irgen_SQEB, ovl.fmt.RXE.r1,
14212 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14213 ovl.fmt.RXE.d2); goto ok;
14214 case 0xed0000000015ULL: s390_format_RXE_FRRD(s390_irgen_SQDB, ovl.fmt.RXE.r1,
14215 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14216 ovl.fmt.RXE.d2); goto ok;
14217 case 0xed0000000017ULL: s390_format_RXE_FRRD(s390_irgen_MEEB, ovl.fmt.RXE.r1,
14218 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14219 ovl.fmt.RXE.d2); goto ok;
14220 case 0xed0000000018ULL: /* KDB */ goto unimplemented;
14221 case 0xed0000000019ULL: s390_format_RXE_FRRD(s390_irgen_CDB, ovl.fmt.RXE.r1,
14222 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14223 ovl.fmt.RXE.d2); goto ok;
14224 case 0xed000000001aULL: s390_format_RXE_FRRD(s390_irgen_ADB, ovl.fmt.RXE.r1,
14225 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14226 ovl.fmt.RXE.d2); goto ok;
14227 case 0xed000000001bULL: s390_format_RXE_FRRD(s390_irgen_SDB, ovl.fmt.RXE.r1,
14228 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14229 ovl.fmt.RXE.d2); goto ok;
14230 case 0xed000000001cULL: s390_format_RXE_FRRD(s390_irgen_MDB, ovl.fmt.RXE.r1,
14231 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14232 ovl.fmt.RXE.d2); goto ok;
14233 case 0xed000000001dULL: s390_format_RXE_FRRD(s390_irgen_DDB, ovl.fmt.RXE.r1,
14234 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14235 ovl.fmt.RXE.d2); goto ok;
14236 case 0xed000000001eULL: s390_format_RXF_FRRDF(s390_irgen_MADB,
14237 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
14238 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
14239 ovl.fmt.RXF.r1); goto ok;
14240 case 0xed000000001fULL: s390_format_RXF_FRRDF(s390_irgen_MSDB,
14241 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
14242 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
14243 ovl.fmt.RXF.r1); goto ok;
14244 case 0xed0000000024ULL: /* LDE */ goto unimplemented;
14245 case 0xed0000000025ULL: /* LXD */ goto unimplemented;
14246 case 0xed0000000026ULL: /* LXE */ goto unimplemented;
14247 case 0xed000000002eULL: /* MAE */ goto unimplemented;
14248 case 0xed000000002fULL: /* MSE */ goto unimplemented;
14249 case 0xed0000000034ULL: /* SQE */ goto unimplemented;
14250 case 0xed0000000035ULL: /* SQD */ goto unimplemented;
14251 case 0xed0000000037ULL: /* MEE */ goto unimplemented;
14252 case 0xed0000000038ULL: /* MAYL */ goto unimplemented;
14253 case 0xed0000000039ULL: /* MYL */ goto unimplemented;
14254 case 0xed000000003aULL: /* MAY */ goto unimplemented;
14255 case 0xed000000003bULL: /* MY */ goto unimplemented;
14256 case 0xed000000003cULL: /* MAYH */ goto unimplemented;
14257 case 0xed000000003dULL: /* MYH */ goto unimplemented;
14258 case 0xed000000003eULL: /* MAD */ goto unimplemented;
14259 case 0xed000000003fULL: /* MSD */ goto unimplemented;
14260 case 0xed0000000040ULL: /* SLDT */ goto unimplemented;
14261 case 0xed0000000041ULL: /* SRDT */ goto unimplemented;
14262 case 0xed0000000048ULL: /* SLXT */ goto unimplemented;
14263 case 0xed0000000049ULL: /* SRXT */ goto unimplemented;
14264 case 0xed0000000050ULL: /* TDCET */ goto unimplemented;
14265 case 0xed0000000051ULL: /* TDGET */ goto unimplemented;
14266 case 0xed0000000054ULL: /* TDCDT */ goto unimplemented;
14267 case 0xed0000000055ULL: /* TDGDT */ goto unimplemented;
14268 case 0xed0000000058ULL: /* TDCXT */ goto unimplemented;
14269 case 0xed0000000059ULL: /* TDGXT */ goto unimplemented;
14270 case 0xed0000000064ULL: s390_format_RXY_FRRD(s390_irgen_LEY, ovl.fmt.RXY.r1,
14271 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14272 ovl.fmt.RXY.dl2,
14273 ovl.fmt.RXY.dh2); goto ok;
14274 case 0xed0000000065ULL: s390_format_RXY_FRRD(s390_irgen_LDY, ovl.fmt.RXY.r1,
14275 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14276 ovl.fmt.RXY.dl2,
14277 ovl.fmt.RXY.dh2); goto ok;
14278 case 0xed0000000066ULL: s390_format_RXY_FRRD(s390_irgen_STEY, ovl.fmt.RXY.r1,
14279 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14280 ovl.fmt.RXY.dl2,
14281 ovl.fmt.RXY.dh2); goto ok;
14282 case 0xed0000000067ULL: s390_format_RXY_FRRD(s390_irgen_STDY, ovl.fmt.RXY.r1,
14283 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14284 ovl.fmt.RXY.dl2,
14285 ovl.fmt.RXY.dh2); goto ok;
14286 }
14287
14288 switch (((ovl.value >> 16) & 0xff0f00000000ULL) >> 32) {
14289 case 0xc000ULL: s390_format_RIL_RP(s390_irgen_LARL, ovl.fmt.RIL.r1,
14290 ovl.fmt.RIL.i2); goto ok;
14291 case 0xc001ULL: s390_format_RIL_RI(s390_irgen_LGFI, ovl.fmt.RIL.r1,
14292 ovl.fmt.RIL.i2); goto ok;
14293 case 0xc004ULL: s390_format_RIL(s390_irgen_BRCL, ovl.fmt.RIL.r1,
14294 ovl.fmt.RIL.i2); goto ok;
14295 case 0xc005ULL: s390_format_RIL_RP(s390_irgen_BRASL, ovl.fmt.RIL.r1,
14296 ovl.fmt.RIL.i2); goto ok;
14297 case 0xc006ULL: s390_format_RIL_RU(s390_irgen_XIHF, ovl.fmt.RIL.r1,
14298 ovl.fmt.RIL.i2); goto ok;
14299 case 0xc007ULL: s390_format_RIL_RU(s390_irgen_XILF, ovl.fmt.RIL.r1,
14300 ovl.fmt.RIL.i2); goto ok;
14301 case 0xc008ULL: s390_format_RIL_RU(s390_irgen_IIHF, ovl.fmt.RIL.r1,
14302 ovl.fmt.RIL.i2); goto ok;
14303 case 0xc009ULL: s390_format_RIL_RU(s390_irgen_IILF, ovl.fmt.RIL.r1,
14304 ovl.fmt.RIL.i2); goto ok;
14305 case 0xc00aULL: s390_format_RIL_RU(s390_irgen_NIHF, ovl.fmt.RIL.r1,
14306 ovl.fmt.RIL.i2); goto ok;
14307 case 0xc00bULL: s390_format_RIL_RU(s390_irgen_NILF, ovl.fmt.RIL.r1,
14308 ovl.fmt.RIL.i2); goto ok;
14309 case 0xc00cULL: s390_format_RIL_RU(s390_irgen_OIHF, ovl.fmt.RIL.r1,
14310 ovl.fmt.RIL.i2); goto ok;
14311 case 0xc00dULL: s390_format_RIL_RU(s390_irgen_OILF, ovl.fmt.RIL.r1,
14312 ovl.fmt.RIL.i2); goto ok;
14313 case 0xc00eULL: s390_format_RIL_RU(s390_irgen_LLIHF, ovl.fmt.RIL.r1,
14314 ovl.fmt.RIL.i2); goto ok;
14315 case 0xc00fULL: s390_format_RIL_RU(s390_irgen_LLILF, ovl.fmt.RIL.r1,
14316 ovl.fmt.RIL.i2); goto ok;
14317 case 0xc200ULL: s390_format_RIL_RI(s390_irgen_MSGFI, ovl.fmt.RIL.r1,
14318 ovl.fmt.RIL.i2); goto ok;
14319 case 0xc201ULL: s390_format_RIL_RI(s390_irgen_MSFI, ovl.fmt.RIL.r1,
14320 ovl.fmt.RIL.i2); goto ok;
14321 case 0xc204ULL: s390_format_RIL_RU(s390_irgen_SLGFI, ovl.fmt.RIL.r1,
14322 ovl.fmt.RIL.i2); goto ok;
14323 case 0xc205ULL: s390_format_RIL_RU(s390_irgen_SLFI, ovl.fmt.RIL.r1,
14324 ovl.fmt.RIL.i2); goto ok;
14325 case 0xc208ULL: s390_format_RIL_RI(s390_irgen_AGFI, ovl.fmt.RIL.r1,
14326 ovl.fmt.RIL.i2); goto ok;
14327 case 0xc209ULL: s390_format_RIL_RI(s390_irgen_AFI, ovl.fmt.RIL.r1,
14328 ovl.fmt.RIL.i2); goto ok;
14329 case 0xc20aULL: s390_format_RIL_RU(s390_irgen_ALGFI, ovl.fmt.RIL.r1,
14330 ovl.fmt.RIL.i2); goto ok;
14331 case 0xc20bULL: s390_format_RIL_RU(s390_irgen_ALFI, ovl.fmt.RIL.r1,
14332 ovl.fmt.RIL.i2); goto ok;
14333 case 0xc20cULL: s390_format_RIL_RI(s390_irgen_CGFI, ovl.fmt.RIL.r1,
14334 ovl.fmt.RIL.i2); goto ok;
14335 case 0xc20dULL: s390_format_RIL_RI(s390_irgen_CFI, ovl.fmt.RIL.r1,
14336 ovl.fmt.RIL.i2); goto ok;
14337 case 0xc20eULL: s390_format_RIL_RU(s390_irgen_CLGFI, ovl.fmt.RIL.r1,
14338 ovl.fmt.RIL.i2); goto ok;
14339 case 0xc20fULL: s390_format_RIL_RU(s390_irgen_CLFI, ovl.fmt.RIL.r1,
14340 ovl.fmt.RIL.i2); goto ok;
14341 case 0xc402ULL: s390_format_RIL_RP(s390_irgen_LLHRL, ovl.fmt.RIL.r1,
14342 ovl.fmt.RIL.i2); goto ok;
14343 case 0xc404ULL: s390_format_RIL_RP(s390_irgen_LGHRL, ovl.fmt.RIL.r1,
14344 ovl.fmt.RIL.i2); goto ok;
14345 case 0xc405ULL: s390_format_RIL_RP(s390_irgen_LHRL, ovl.fmt.RIL.r1,
14346 ovl.fmt.RIL.i2); goto ok;
14347 case 0xc406ULL: s390_format_RIL_RP(s390_irgen_LLGHRL, ovl.fmt.RIL.r1,
14348 ovl.fmt.RIL.i2); goto ok;
14349 case 0xc407ULL: s390_format_RIL_RP(s390_irgen_STHRL, ovl.fmt.RIL.r1,
14350 ovl.fmt.RIL.i2); goto ok;
14351 case 0xc408ULL: s390_format_RIL_RP(s390_irgen_LGRL, ovl.fmt.RIL.r1,
14352 ovl.fmt.RIL.i2); goto ok;
14353 case 0xc40bULL: s390_format_RIL_RP(s390_irgen_STGRL, ovl.fmt.RIL.r1,
14354 ovl.fmt.RIL.i2); goto ok;
14355 case 0xc40cULL: s390_format_RIL_RP(s390_irgen_LGFRL, ovl.fmt.RIL.r1,
14356 ovl.fmt.RIL.i2); goto ok;
14357 case 0xc40dULL: s390_format_RIL_RP(s390_irgen_LRL, ovl.fmt.RIL.r1,
14358 ovl.fmt.RIL.i2); goto ok;
14359 case 0xc40eULL: s390_format_RIL_RP(s390_irgen_LLGFRL, ovl.fmt.RIL.r1,
14360 ovl.fmt.RIL.i2); goto ok;
14361 case 0xc40fULL: s390_format_RIL_RP(s390_irgen_STRL, ovl.fmt.RIL.r1,
14362 ovl.fmt.RIL.i2); goto ok;
14363 case 0xc600ULL: s390_format_RIL_RP(s390_irgen_EXRL, ovl.fmt.RIL.r1,
14364 ovl.fmt.RIL.i2); goto ok;
14365 case 0xc602ULL: s390_format_RIL_UP(s390_irgen_PFDRL, ovl.fmt.RIL.r1,
14366 ovl.fmt.RIL.i2); goto ok;
14367 case 0xc604ULL: s390_format_RIL_RP(s390_irgen_CGHRL, ovl.fmt.RIL.r1,
14368 ovl.fmt.RIL.i2); goto ok;
14369 case 0xc605ULL: s390_format_RIL_RP(s390_irgen_CHRL, ovl.fmt.RIL.r1,
14370 ovl.fmt.RIL.i2); goto ok;
14371 case 0xc606ULL: s390_format_RIL_RP(s390_irgen_CLGHRL, ovl.fmt.RIL.r1,
14372 ovl.fmt.RIL.i2); goto ok;
14373 case 0xc607ULL: s390_format_RIL_RP(s390_irgen_CLHRL, ovl.fmt.RIL.r1,
14374 ovl.fmt.RIL.i2); goto ok;
14375 case 0xc608ULL: s390_format_RIL_RP(s390_irgen_CGRL, ovl.fmt.RIL.r1,
14376 ovl.fmt.RIL.i2); goto ok;
14377 case 0xc60aULL: s390_format_RIL_RP(s390_irgen_CLGRL, ovl.fmt.RIL.r1,
14378 ovl.fmt.RIL.i2); goto ok;
14379 case 0xc60cULL: s390_format_RIL_RP(s390_irgen_CGFRL, ovl.fmt.RIL.r1,
14380 ovl.fmt.RIL.i2); goto ok;
14381 case 0xc60dULL: s390_format_RIL_RP(s390_irgen_CRL, ovl.fmt.RIL.r1,
14382 ovl.fmt.RIL.i2); goto ok;
14383 case 0xc60eULL: s390_format_RIL_RP(s390_irgen_CLGFRL, ovl.fmt.RIL.r1,
14384 ovl.fmt.RIL.i2); goto ok;
14385 case 0xc60fULL: s390_format_RIL_RP(s390_irgen_CLRL, ovl.fmt.RIL.r1,
14386 ovl.fmt.RIL.i2); goto ok;
14387 case 0xc800ULL: /* MVCOS */ goto unimplemented;
14388 case 0xc801ULL: /* ECTG */ goto unimplemented;
14389 case 0xc802ULL: /* CSST */ goto unimplemented;
14390 case 0xc804ULL: /* LPD */ goto unimplemented;
14391 case 0xc805ULL: /* LPDG */ goto unimplemented;
14392 case 0xcc06ULL: /* BRCTH */ goto unimplemented;
14393 case 0xcc08ULL: s390_format_RIL_RI(s390_irgen_AIH, ovl.fmt.RIL.r1,
14394 ovl.fmt.RIL.i2); goto ok;
14395 case 0xcc0aULL: s390_format_RIL_RI(s390_irgen_ALSIH, ovl.fmt.RIL.r1,
14396 ovl.fmt.RIL.i2); goto ok;
14397 case 0xcc0bULL: s390_format_RIL_RI(s390_irgen_ALSIHN, ovl.fmt.RIL.r1,
14398 ovl.fmt.RIL.i2); goto ok;
14399 case 0xcc0dULL: s390_format_RIL_RI(s390_irgen_CIH, ovl.fmt.RIL.r1,
14400 ovl.fmt.RIL.i2); goto ok;
14401 case 0xcc0fULL: s390_format_RIL_RU(s390_irgen_CLIH, ovl.fmt.RIL.r1,
14402 ovl.fmt.RIL.i2); goto ok;
14403 }
14404
14405 switch (((ovl.value >> 16) & 0xff0000000000ULL) >> 40) {
14406 case 0xd0ULL: /* TRTR */ goto unimplemented;
14407 case 0xd1ULL: /* MVN */ goto unimplemented;
14408 case 0xd2ULL: s390_format_SS_L0RDRD(s390_irgen_MVC, ovl.fmt.SS.l,
14409 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
14410 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
14411 case 0xd3ULL: /* MVZ */ goto unimplemented;
14412 case 0xd4ULL: s390_format_SS_L0RDRD(s390_irgen_NC, ovl.fmt.SS.l,
14413 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
14414 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
14415 case 0xd5ULL: s390_format_SS_L0RDRD(s390_irgen_CLC, ovl.fmt.SS.l,
14416 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
14417 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
14418 case 0xd6ULL: s390_format_SS_L0RDRD(s390_irgen_OC, ovl.fmt.SS.l,
14419 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
14420 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
sewardjb63967e2011-03-24 08:50:04 +000014421 case 0xd7ULL:
14422 if (ovl.fmt.SS.b1 == ovl.fmt.SS.b2 && ovl.fmt.SS.d1 == ovl.fmt.SS.d2)
14423 s390_irgen_XC_sameloc(ovl.fmt.SS.l, ovl.fmt.SS.b1, ovl.fmt.SS.d1);
14424 else
14425 s390_format_SS_L0RDRD(s390_irgen_XC, ovl.fmt.SS.l,
14426 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
14427 ovl.fmt.SS.b2, ovl.fmt.SS.d2);
14428 goto ok;
sewardj2019a972011-03-07 16:04:07 +000014429 case 0xd9ULL: /* MVCK */ goto unimplemented;
14430 case 0xdaULL: /* MVCP */ goto unimplemented;
14431 case 0xdbULL: /* MVCS */ goto unimplemented;
florian730448f2012-02-04 17:07:07 +000014432 case 0xdcULL: s390_format_SS_L0RDRD(s390_irgen_TR, ovl.fmt.SS.l,
14433 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
14434 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014435 case 0xddULL: /* TRT */ goto unimplemented;
14436 case 0xdeULL: /* ED */ goto unimplemented;
14437 case 0xdfULL: /* EDMK */ goto unimplemented;
14438 case 0xe1ULL: /* PKU */ goto unimplemented;
14439 case 0xe2ULL: /* UNPKU */ goto unimplemented;
14440 case 0xe8ULL: /* MVCIN */ goto unimplemented;
14441 case 0xe9ULL: /* PKA */ goto unimplemented;
14442 case 0xeaULL: /* UNPKA */ goto unimplemented;
14443 case 0xeeULL: /* PLO */ goto unimplemented;
14444 case 0xefULL: /* LMD */ goto unimplemented;
14445 case 0xf0ULL: /* SRP */ goto unimplemented;
14446 case 0xf1ULL: /* MVO */ goto unimplemented;
14447 case 0xf2ULL: /* PACK */ goto unimplemented;
14448 case 0xf3ULL: /* UNPK */ goto unimplemented;
14449 case 0xf8ULL: /* ZAP */ goto unimplemented;
14450 case 0xf9ULL: /* CP */ goto unimplemented;
14451 case 0xfaULL: /* AP */ goto unimplemented;
14452 case 0xfbULL: /* SP */ goto unimplemented;
14453 case 0xfcULL: /* MP */ goto unimplemented;
14454 case 0xfdULL: /* DP */ goto unimplemented;
14455 }
14456
14457 switch (((ovl.value >> 16) & 0xffff00000000ULL) >> 32) {
14458 case 0xe500ULL: /* LASP */ goto unimplemented;
14459 case 0xe501ULL: /* TPROT */ goto unimplemented;
14460 case 0xe502ULL: /* STRAG */ goto unimplemented;
14461 case 0xe50eULL: /* MVCSK */ goto unimplemented;
14462 case 0xe50fULL: /* MVCDK */ goto unimplemented;
14463 case 0xe544ULL: s390_format_SIL_RDI(s390_irgen_MVHHI, ovl.fmt.SIL.b1,
14464 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14465 goto ok;
14466 case 0xe548ULL: s390_format_SIL_RDI(s390_irgen_MVGHI, ovl.fmt.SIL.b1,
14467 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14468 goto ok;
14469 case 0xe54cULL: s390_format_SIL_RDI(s390_irgen_MVHI, ovl.fmt.SIL.b1,
14470 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14471 goto ok;
14472 case 0xe554ULL: s390_format_SIL_RDI(s390_irgen_CHHSI, ovl.fmt.SIL.b1,
14473 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14474 goto ok;
14475 case 0xe555ULL: s390_format_SIL_RDU(s390_irgen_CLHHSI, ovl.fmt.SIL.b1,
14476 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14477 goto ok;
14478 case 0xe558ULL: s390_format_SIL_RDI(s390_irgen_CGHSI, ovl.fmt.SIL.b1,
14479 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14480 goto ok;
14481 case 0xe559ULL: s390_format_SIL_RDU(s390_irgen_CLGHSI, ovl.fmt.SIL.b1,
14482 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14483 goto ok;
14484 case 0xe55cULL: s390_format_SIL_RDI(s390_irgen_CHSI, ovl.fmt.SIL.b1,
14485 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14486 goto ok;
14487 case 0xe55dULL: s390_format_SIL_RDU(s390_irgen_CLFHSI, ovl.fmt.SIL.b1,
14488 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14489 goto ok;
14490 }
14491
14492 return S390_DECODE_UNKNOWN_INSN;
14493
14494ok:
14495 return S390_DECODE_OK;
14496
14497unimplemented:
14498 return S390_DECODE_UNIMPLEMENTED_INSN;
14499}
14500
14501/* Handle "special" instructions. */
14502static s390_decode_t
14503s390_decode_special_and_irgen(UChar *bytes)
14504{
14505 s390_decode_t status = S390_DECODE_OK;
14506
14507 /* Got a "Special" instruction preamble. Which one is it? */
14508 if (bytes[0] == 0x18 && bytes[1] == 0x22 /* lr %r2, %r2 */) {
14509 s390_irgen_client_request();
14510 } else if (bytes[0] == 0x18 && bytes[1] == 0x33 /* lr %r3, %r3 */) {
14511 s390_irgen_guest_NRADDR();
14512 } else if (bytes[0] == 0x18 && bytes[1] == 0x44 /* lr %r4, %r4 */) {
14513 s390_irgen_call_noredir();
florian2245ce92012-08-28 16:49:30 +000014514 } else if (bytes[0] == 0x18 && bytes[1] == 0x55 /* lr %r5, %r5 */) {
14515 vex_inject_ir(irsb, Iend_BE);
14516
14517 /* Invalidate the current insn. The reason is that the IRop we're
14518 injecting here can change. In which case the translation has to
14519 be redone. For ease of handling, we simply invalidate all the
14520 time. */
14521 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TISTART),
14522 mkU64(guest_IA_curr_instr)));
14523 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TILEN),
14524 mkU64(guest_IA_next_instr - guest_IA_curr_instr)));
14525 vassert(guest_IA_next_instr - guest_IA_curr_instr ==
14526 S390_SPECIAL_OP_PREAMBLE_SIZE + S390_SPECIAL_OP_SIZE);
14527
14528 put_IA(mkaddr_expr(guest_IA_next_instr));
14529 dis_res->whatNext = Dis_StopHere;
14530 dis_res->jk_StopHere = Ijk_TInval;
sewardj2019a972011-03-07 16:04:07 +000014531 } else {
14532 /* We don't know what it is. */
14533 return S390_DECODE_UNKNOWN_SPECIAL_INSN;
14534 }
14535
14536 dis_res->len = S390_SPECIAL_OP_PREAMBLE_SIZE + S390_SPECIAL_OP_SIZE;
14537
14538 return status;
14539}
14540
14541
14542/* Function returns # bytes that were decoded or 0 in case of failure */
florianb4df7682011-07-05 02:09:01 +000014543static UInt
sewardj2019a972011-03-07 16:04:07 +000014544s390_decode_and_irgen(UChar *bytes, UInt insn_length, DisResult *dres)
14545{
14546 s390_decode_t status;
14547
14548 dis_res = dres;
14549
14550 /* Spot the 8-byte preamble: 18ff lr r15,r15
14551 1811 lr r1,r1
14552 1822 lr r2,r2
14553 1833 lr r3,r3 */
14554 if (bytes[ 0] == 0x18 && bytes[ 1] == 0xff && bytes[ 2] == 0x18 &&
14555 bytes[ 3] == 0x11 && bytes[ 4] == 0x18 && bytes[ 5] == 0x22 &&
14556 bytes[ 6] == 0x18 && bytes[ 7] == 0x33) {
14557
14558 /* Handle special instruction that follows that preamble. */
14559 if (0) vex_printf("special function handling...\n");
florian2c8ed942011-08-01 22:07:51 +000014560
14561 insn_length = S390_SPECIAL_OP_PREAMBLE_SIZE + S390_SPECIAL_OP_SIZE;
14562 guest_IA_next_instr = guest_IA_curr_instr + insn_length;
14563
14564 status =
14565 s390_decode_special_and_irgen(bytes + S390_SPECIAL_OP_PREAMBLE_SIZE);
sewardj2019a972011-03-07 16:04:07 +000014566 } else {
14567 /* Handle normal instructions. */
14568 switch (insn_length) {
14569 case 2:
14570 status = s390_decode_2byte_and_irgen(bytes);
14571 break;
14572
14573 case 4:
14574 status = s390_decode_4byte_and_irgen(bytes);
14575 break;
14576
14577 case 6:
14578 status = s390_decode_6byte_and_irgen(bytes);
14579 break;
14580
14581 default:
14582 status = S390_DECODE_ERROR;
14583 break;
14584 }
14585 }
florian5fcbba22011-07-27 20:40:22 +000014586 /* If next instruction is execute, stop here */
florianf9e1ed72012-04-17 02:41:56 +000014587 if (dis_res->whatNext == Dis_Continue && bytes[insn_length] == 0x44) {
14588 put_IA(mkaddr_expr(guest_IA_next_instr));
sewardj2019a972011-03-07 16:04:07 +000014589 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +000014590 dis_res->jk_StopHere = Ijk_Boring;
sewardj2019a972011-03-07 16:04:07 +000014591 }
14592
14593 if (status == S390_DECODE_OK) return insn_length; /* OK */
14594
14595 /* Decoding failed somehow */
14596 vex_printf("vex s390->IR: ");
14597 switch (status) {
14598 case S390_DECODE_UNKNOWN_INSN:
14599 vex_printf("unknown insn: ");
14600 break;
14601
14602 case S390_DECODE_UNIMPLEMENTED_INSN:
14603 vex_printf("unimplemented insn: ");
14604 break;
14605
14606 case S390_DECODE_UNKNOWN_SPECIAL_INSN:
14607 vex_printf("unimplemented special insn: ");
14608 break;
14609
14610 default:
14611 case S390_DECODE_ERROR:
14612 vex_printf("decoding error: ");
14613 break;
14614 }
14615
14616 vex_printf("%02x%02x", bytes[0], bytes[1]);
14617 if (insn_length > 2) {
14618 vex_printf(" %02x%02x", bytes[2], bytes[3]);
14619 }
14620 if (insn_length > 4) {
14621 vex_printf(" %02x%02x", bytes[4], bytes[5]);
14622 }
14623 vex_printf("\n");
14624
14625 return 0; /* Failed */
14626}
14627
14628
sewardj2019a972011-03-07 16:04:07 +000014629/* Disassemble a single instruction INSN into IR. */
14630static DisResult
florian420c5012011-07-22 02:12:28 +000014631disInstr_S390_WRK(UChar *insn)
sewardj2019a972011-03-07 16:04:07 +000014632{
14633 UChar byte;
14634 UInt insn_length;
14635 DisResult dres;
14636
14637 /* ---------------------------------------------------- */
14638 /* --- Compute instruction length -- */
14639 /* ---------------------------------------------------- */
14640
14641 /* Get the first byte of the insn. */
14642 byte = insn[0];
14643
14644 /* The leftmost two bits (0:1) encode the length of the insn in bytes.
14645 00 -> 2 bytes, 01 -> 4 bytes, 10 -> 4 bytes, 11 -> 6 bytes. */
14646 insn_length = ((((byte >> 6) + 1) >> 1) + 1) << 1;
14647
14648 guest_IA_next_instr = guest_IA_curr_instr + insn_length;
14649
14650 /* ---------------------------------------------------- */
14651 /* --- Initialise the DisResult data -- */
14652 /* ---------------------------------------------------- */
14653 dres.whatNext = Dis_Continue;
14654 dres.len = insn_length;
14655 dres.continueAt = 0;
florian8844a632012-04-13 04:04:06 +000014656 dres.jk_StopHere = Ijk_INVALID;
sewardj2019a972011-03-07 16:04:07 +000014657
floriana99f20e2011-07-17 14:16:41 +000014658 /* fixs390: consider chasing of conditional jumps */
14659
sewardj2019a972011-03-07 16:04:07 +000014660 /* Normal and special instruction handling starts here. */
14661 if (s390_decode_and_irgen(insn, insn_length, &dres) == 0) {
14662 /* All decode failures end up here. The decoder has already issued an
14663 error message.
14664 Tell the dispatcher that this insn cannot be decoded, and so has
florian342e01a2012-07-26 02:37:49 +000014665 not been executed, and (is currently) the next to be executed.
14666 The insn address in the guest state needs to be set to
14667 guest_IA_curr_instr, otherwise the complaint will report an
14668 incorrect address. */
14669 put_IA(mkaddr_expr(guest_IA_curr_instr));
sewardj2019a972011-03-07 16:04:07 +000014670
florian8844a632012-04-13 04:04:06 +000014671 dres.whatNext = Dis_StopHere;
14672 dres.jk_StopHere = Ijk_NoDecode;
14673 dres.continueAt = 0;
14674 dres.len = 0;
14675 } else {
14676 /* Decode success */
14677 switch (dres.whatNext) {
14678 case Dis_Continue:
florian8559e412012-04-19 14:23:48 +000014679 put_IA(mkaddr_expr(guest_IA_next_instr));
florian8844a632012-04-13 04:04:06 +000014680 break;
14681 case Dis_ResteerU:
14682 case Dis_ResteerC:
14683 put_IA(mkaddr_expr(dres.continueAt));
14684 break;
14685 case Dis_StopHere:
florian4b8efad2012-09-02 18:07:08 +000014686 if (dres.jk_StopHere == Ijk_EmWarn ||
14687 dres.jk_StopHere == Ijk_EmFail) {
14688 /* We assume here, that emulation warnings are not given for
14689 insns that transfer control. There is no good way to
14690 do that. */
14691 put_IA(mkaddr_expr(guest_IA_next_instr));
14692 }
florian8844a632012-04-13 04:04:06 +000014693 break;
14694 default:
14695 vassert(0);
14696 }
sewardj2019a972011-03-07 16:04:07 +000014697 }
14698
14699 return dres;
14700}
14701
14702
14703/*------------------------------------------------------------*/
14704/*--- Top-level fn ---*/
14705/*------------------------------------------------------------*/
14706
14707/* Disassemble a single instruction into IR. The instruction
14708 is located in host memory at &guest_code[delta]. */
14709
14710DisResult
14711disInstr_S390(IRSB *irsb_IN,
sewardj2019a972011-03-07 16:04:07 +000014712 Bool (*resteerOkFn)(void *, Addr64),
14713 Bool resteerCisOk,
14714 void *callback_opaque,
14715 UChar *guest_code,
14716 Long delta,
14717 Addr64 guest_IP,
14718 VexArch guest_arch,
14719 VexArchInfo *archinfo,
14720 VexAbiInfo *abiinfo,
14721 Bool host_bigendian)
14722{
14723 vassert(guest_arch == VexArchS390X);
14724
14725 /* The instruction decoder requires a big-endian machine. */
14726 vassert(host_bigendian == True);
14727
14728 /* Set globals (see top of this file) */
14729 guest_IA_curr_instr = guest_IP;
sewardj2019a972011-03-07 16:04:07 +000014730 irsb = irsb_IN;
florian420c5012011-07-22 02:12:28 +000014731 resteer_fn = resteerOkFn;
14732 resteer_data = callback_opaque;
sewardj2019a972011-03-07 16:04:07 +000014733
florian420c5012011-07-22 02:12:28 +000014734 return disInstr_S390_WRK(guest_code + delta);
sewardj2019a972011-03-07 16:04:07 +000014735}
14736
14737/*---------------------------------------------------------------*/
14738/*--- end guest_s390_toIR.c ---*/
14739/*---------------------------------------------------------------*/