blob: aaf2cab74adf3b9183088866cdd913d008ca4045 [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);
florian1c8f7ff2012-09-01 00:12:11 +00008398
floriane75dafa2012-09-01 17:54:09 +00008399 assign(op, get_fpr_w0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008400 assign(result, binop(Iop_F32toI32U, mkexpr(encode_bfp_rounding_mode(m3)),
floriane75dafa2012-09-01 17:54:09 +00008401 mkexpr(op)));
8402 put_gpr_w1(r1, mkexpr(result));
8403 s390_cc_thunk_putF(S390_CC_OP_BFP_32_TO_UINT_32, op);
8404 }
florian1c8f7ff2012-09-01 00:12:11 +00008405 return "clfebr";
8406}
8407
8408static HChar *
8409s390_irgen_CLFDBR(UChar m3, UChar m4 __attribute__((unused)),
8410 UChar r1, UChar r2)
8411{
floriane75dafa2012-09-01 17:54:09 +00008412 if (! s390_host_has_fpext) {
8413 emulation_failure(EmFail_S390X_fpext);
8414 } else {
8415 IRTemp op = newTemp(Ity_F64);
8416 IRTemp result = newTemp(Ity_I32);
florian1c8f7ff2012-09-01 00:12:11 +00008417
floriane75dafa2012-09-01 17:54:09 +00008418 assign(op, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008419 assign(result, binop(Iop_F64toI32U, mkexpr(encode_bfp_rounding_mode(m3)),
floriane75dafa2012-09-01 17:54:09 +00008420 mkexpr(op)));
8421 put_gpr_w1(r1, mkexpr(result));
8422 s390_cc_thunk_putF(S390_CC_OP_BFP_64_TO_UINT_32, op);
8423 }
florian1c8f7ff2012-09-01 00:12:11 +00008424 return "clfdbr";
8425}
8426
8427static HChar *
8428s390_irgen_CLGEBR(UChar m3, UChar m4 __attribute__((unused)),
8429 UChar r1, UChar r2)
8430{
floriane75dafa2012-09-01 17:54:09 +00008431 if (! s390_host_has_fpext) {
8432 emulation_failure(EmFail_S390X_fpext);
8433 } else {
8434 IRTemp op = newTemp(Ity_F32);
8435 IRTemp result = newTemp(Ity_I64);
florian1c8f7ff2012-09-01 00:12:11 +00008436
floriane75dafa2012-09-01 17:54:09 +00008437 assign(op, get_fpr_w0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008438 assign(result, binop(Iop_F32toI64U, mkexpr(encode_bfp_rounding_mode(m3)),
floriane75dafa2012-09-01 17:54:09 +00008439 mkexpr(op)));
8440 put_gpr_dw0(r1, mkexpr(result));
8441 s390_cc_thunk_putF(S390_CC_OP_BFP_32_TO_UINT_64, op);
8442 }
florian1c8f7ff2012-09-01 00:12:11 +00008443 return "clgebr";
8444}
8445
8446static HChar *
8447s390_irgen_CLGDBR(UChar m3, UChar m4 __attribute__((unused)),
8448 UChar r1, UChar r2)
8449{
floriane75dafa2012-09-01 17:54:09 +00008450 if (! s390_host_has_fpext) {
8451 emulation_failure(EmFail_S390X_fpext);
8452 } else {
8453 IRTemp op = newTemp(Ity_F64);
8454 IRTemp result = newTemp(Ity_I64);
florian1c8f7ff2012-09-01 00:12:11 +00008455
floriane75dafa2012-09-01 17:54:09 +00008456 assign(op, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008457 assign(result, binop(Iop_F64toI64U, mkexpr(encode_bfp_rounding_mode(m3)),
floriane75dafa2012-09-01 17:54:09 +00008458 mkexpr(op)));
8459 put_gpr_dw0(r1, mkexpr(result));
8460 s390_cc_thunk_putF(S390_CC_OP_BFP_64_TO_UINT_64, op);
8461 }
florian1c8f7ff2012-09-01 00:12:11 +00008462 return "clgdbr";
8463}
8464
8465static HChar *
florian4b8efad2012-09-02 18:07:08 +00008466s390_irgen_CFEBR(UChar m3, UChar m4 __attribute__((unused)),
8467 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008468{
8469 IRTemp op = newTemp(Ity_F32);
8470 IRTemp result = newTemp(Ity_I32);
8471
8472 assign(op, get_fpr_w0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008473 assign(result, binop(Iop_F32toI32S, mkexpr(encode_bfp_rounding_mode(m3)),
sewardj2019a972011-03-07 16:04:07 +00008474 mkexpr(op)));
8475 put_gpr_w1(r1, mkexpr(result));
8476 s390_cc_thunk_putF(S390_CC_OP_BFP_32_TO_INT_32, op);
8477
8478 return "cfebr";
8479}
8480
8481static HChar *
florian4b8efad2012-09-02 18:07:08 +00008482s390_irgen_CFDBR(UChar m3, UChar m4 __attribute__((unused)),
8483 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008484{
8485 IRTemp op = newTemp(Ity_F64);
8486 IRTemp result = newTemp(Ity_I32);
8487
8488 assign(op, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008489 assign(result, binop(Iop_F64toI32S, mkexpr(encode_bfp_rounding_mode(m3)),
sewardj2019a972011-03-07 16:04:07 +00008490 mkexpr(op)));
8491 put_gpr_w1(r1, mkexpr(result));
8492 s390_cc_thunk_putF(S390_CC_OP_BFP_64_TO_INT_32, op);
8493
8494 return "cfdbr";
8495}
8496
8497static HChar *
florian4b8efad2012-09-02 18:07:08 +00008498s390_irgen_CGEBR(UChar m3, UChar m4 __attribute__((unused)),
8499 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008500{
8501 IRTemp op = newTemp(Ity_F32);
8502 IRTemp result = newTemp(Ity_I64);
8503
8504 assign(op, get_fpr_w0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008505 assign(result, binop(Iop_F32toI64S, mkexpr(encode_bfp_rounding_mode(m3)),
sewardj2019a972011-03-07 16:04:07 +00008506 mkexpr(op)));
8507 put_gpr_dw0(r1, mkexpr(result));
8508 s390_cc_thunk_putF(S390_CC_OP_BFP_32_TO_INT_64, op);
8509
8510 return "cgebr";
8511}
8512
8513static HChar *
florian4b8efad2012-09-02 18:07:08 +00008514s390_irgen_CGDBR(UChar m3, UChar m4 __attribute__((unused)),
8515 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008516{
8517 IRTemp op = newTemp(Ity_F64);
8518 IRTemp result = newTemp(Ity_I64);
8519
8520 assign(op, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008521 assign(result, binop(Iop_F64toI64S, mkexpr(encode_bfp_rounding_mode(m3)),
sewardj2019a972011-03-07 16:04:07 +00008522 mkexpr(op)));
8523 put_gpr_dw0(r1, mkexpr(result));
8524 s390_cc_thunk_putF(S390_CC_OP_BFP_64_TO_INT_64, op);
8525
8526 return "cgdbr";
8527}
8528
8529static HChar *
8530s390_irgen_DEBR(UChar r1, UChar r2)
8531{
8532 IRTemp op1 = newTemp(Ity_F32);
8533 IRTemp op2 = newTemp(Ity_F32);
8534 IRTemp result = newTemp(Ity_F32);
floriandb4fcaa2012-09-05 19:54:08 +00008535 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008536
8537 assign(op1, get_fpr_w0(r1));
8538 assign(op2, get_fpr_w0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008539 assign(result, triop(Iop_DivF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008540 mkexpr(op2)));
8541 put_fpr_w0(r1, mkexpr(result));
8542
8543 return "debr";
8544}
8545
8546static HChar *
8547s390_irgen_DDBR(UChar r1, UChar r2)
8548{
8549 IRTemp op1 = newTemp(Ity_F64);
8550 IRTemp op2 = newTemp(Ity_F64);
8551 IRTemp result = newTemp(Ity_F64);
floriandb4fcaa2012-09-05 19:54:08 +00008552 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008553
8554 assign(op1, get_fpr_dw0(r1));
8555 assign(op2, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008556 assign(result, triop(Iop_DivF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008557 mkexpr(op2)));
8558 put_fpr_dw0(r1, mkexpr(result));
8559
8560 return "ddbr";
8561}
8562
8563static HChar *
8564s390_irgen_DEB(UChar r1, IRTemp op2addr)
8565{
8566 IRTemp op1 = newTemp(Ity_F32);
8567 IRTemp op2 = newTemp(Ity_F32);
8568 IRTemp result = newTemp(Ity_F32);
floriandb4fcaa2012-09-05 19:54:08 +00008569 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008570
8571 assign(op1, get_fpr_w0(r1));
8572 assign(op2, load(Ity_F32, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00008573 assign(result, triop(Iop_DivF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008574 mkexpr(op2)));
8575 put_fpr_w0(r1, mkexpr(result));
8576
8577 return "deb";
8578}
8579
8580static HChar *
8581s390_irgen_DDB(UChar r1, IRTemp op2addr)
8582{
8583 IRTemp op1 = newTemp(Ity_F64);
8584 IRTemp op2 = newTemp(Ity_F64);
8585 IRTemp result = newTemp(Ity_F64);
floriandb4fcaa2012-09-05 19:54:08 +00008586 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008587
8588 assign(op1, get_fpr_dw0(r1));
8589 assign(op2, load(Ity_F64, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00008590 assign(result, triop(Iop_DivF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008591 mkexpr(op2)));
8592 put_fpr_dw0(r1, mkexpr(result));
8593
8594 return "ddb";
8595}
8596
8597static HChar *
8598s390_irgen_LTEBR(UChar r1, UChar r2)
8599{
8600 IRTemp result = newTemp(Ity_F32);
8601
8602 assign(result, get_fpr_w0(r2));
8603 put_fpr_w0(r1, mkexpr(result));
8604 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
8605
8606 return "ltebr";
8607}
8608
8609static HChar *
8610s390_irgen_LTDBR(UChar r1, UChar r2)
8611{
8612 IRTemp result = newTemp(Ity_F64);
8613
8614 assign(result, get_fpr_dw0(r2));
8615 put_fpr_dw0(r1, mkexpr(result));
8616 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
8617
8618 return "ltdbr";
8619}
8620
8621static HChar *
8622s390_irgen_LCEBR(UChar r1, UChar r2)
8623{
8624 IRTemp result = newTemp(Ity_F32);
8625
8626 assign(result, unop(Iop_NegF32, get_fpr_w0(r2)));
8627 put_fpr_w0(r1, mkexpr(result));
8628 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
8629
8630 return "lcebr";
8631}
8632
8633static HChar *
8634s390_irgen_LCDBR(UChar r1, UChar r2)
8635{
8636 IRTemp result = newTemp(Ity_F64);
8637
8638 assign(result, unop(Iop_NegF64, get_fpr_dw0(r2)));
8639 put_fpr_dw0(r1, mkexpr(result));
8640 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
8641
8642 return "lcdbr";
8643}
8644
8645static HChar *
8646s390_irgen_LDEBR(UChar r1, UChar r2)
8647{
8648 IRTemp op = newTemp(Ity_F32);
8649
8650 assign(op, get_fpr_w0(r2));
8651 put_fpr_dw0(r1, unop(Iop_F32toF64, mkexpr(op)));
8652
8653 return "ldebr";
8654}
8655
8656static HChar *
8657s390_irgen_LDEB(UChar r1, IRTemp op2addr)
8658{
8659 IRTemp op = newTemp(Ity_F32);
8660
8661 assign(op, load(Ity_F32, mkexpr(op2addr)));
8662 put_fpr_dw0(r1, unop(Iop_F32toF64, mkexpr(op)));
8663
8664 return "ldeb";
8665}
8666
8667static HChar *
florian4b8efad2012-09-02 18:07:08 +00008668s390_irgen_LEDBR(UChar m3, UChar m4 __attribute__((unused)),
8669 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008670{
8671 IRTemp op = newTemp(Ity_F64);
8672
8673 assign(op, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008674 put_fpr_w0(r1, binop(Iop_F64toF32, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +00008675 mkexpr(op)));
sewardj2019a972011-03-07 16:04:07 +00008676
8677 return "ledbr";
8678}
8679
8680static HChar *
8681s390_irgen_MEEBR(UChar r1, UChar r2)
8682{
8683 IRTemp op1 = newTemp(Ity_F32);
8684 IRTemp op2 = newTemp(Ity_F32);
8685 IRTemp result = newTemp(Ity_F32);
floriandb4fcaa2012-09-05 19:54:08 +00008686 IRRoundingMode rounding_mode = encode_bfp_rounding_mode(S390_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008687
8688 assign(op1, get_fpr_w0(r1));
8689 assign(op2, get_fpr_w0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008690 assign(result, triop(Iop_MulF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008691 mkexpr(op2)));
8692 put_fpr_w0(r1, mkexpr(result));
8693
8694 return "meebr";
8695}
8696
8697static HChar *
8698s390_irgen_MDBR(UChar r1, UChar r2)
8699{
8700 IRTemp op1 = newTemp(Ity_F64);
8701 IRTemp op2 = newTemp(Ity_F64);
8702 IRTemp result = newTemp(Ity_F64);
floriandb4fcaa2012-09-05 19:54:08 +00008703 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008704
8705 assign(op1, get_fpr_dw0(r1));
8706 assign(op2, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008707 assign(result, triop(Iop_MulF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008708 mkexpr(op2)));
8709 put_fpr_dw0(r1, mkexpr(result));
8710
8711 return "mdbr";
8712}
8713
8714static HChar *
8715s390_irgen_MEEB(UChar r1, IRTemp op2addr)
8716{
8717 IRTemp op1 = newTemp(Ity_F32);
8718 IRTemp op2 = newTemp(Ity_F32);
8719 IRTemp result = newTemp(Ity_F32);
floriandb4fcaa2012-09-05 19:54:08 +00008720 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008721
8722 assign(op1, get_fpr_w0(r1));
8723 assign(op2, load(Ity_F32, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00008724 assign(result, triop(Iop_MulF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008725 mkexpr(op2)));
8726 put_fpr_w0(r1, mkexpr(result));
8727
8728 return "meeb";
8729}
8730
8731static HChar *
8732s390_irgen_MDB(UChar r1, IRTemp op2addr)
8733{
8734 IRTemp op1 = newTemp(Ity_F64);
8735 IRTemp op2 = newTemp(Ity_F64);
8736 IRTemp result = newTemp(Ity_F64);
floriandb4fcaa2012-09-05 19:54:08 +00008737 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008738
8739 assign(op1, get_fpr_dw0(r1));
8740 assign(op2, load(Ity_F64, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00008741 assign(result, triop(Iop_MulF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008742 mkexpr(op2)));
8743 put_fpr_dw0(r1, mkexpr(result));
8744
8745 return "mdb";
8746}
8747
8748static HChar *
8749s390_irgen_SEBR(UChar r1, UChar r2)
8750{
8751 IRTemp op1 = newTemp(Ity_F32);
8752 IRTemp op2 = newTemp(Ity_F32);
8753 IRTemp result = newTemp(Ity_F32);
floriandb4fcaa2012-09-05 19:54:08 +00008754 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008755
8756 assign(op1, get_fpr_w0(r1));
8757 assign(op2, get_fpr_w0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008758 assign(result, triop(Iop_SubF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008759 mkexpr(op2)));
8760 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
8761 put_fpr_w0(r1, mkexpr(result));
8762
8763 return "sebr";
8764}
8765
8766static HChar *
8767s390_irgen_SDBR(UChar r1, UChar r2)
8768{
8769 IRTemp op1 = newTemp(Ity_F64);
8770 IRTemp op2 = newTemp(Ity_F64);
8771 IRTemp result = newTemp(Ity_F64);
floriandb4fcaa2012-09-05 19:54:08 +00008772 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008773
8774 assign(op1, get_fpr_dw0(r1));
8775 assign(op2, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008776 assign(result, triop(Iop_SubF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008777 mkexpr(op2)));
8778 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
8779 put_fpr_dw0(r1, mkexpr(result));
8780
8781 return "sdbr";
8782}
8783
8784static HChar *
8785s390_irgen_SEB(UChar r1, IRTemp op2addr)
8786{
8787 IRTemp op1 = newTemp(Ity_F32);
8788 IRTemp op2 = newTemp(Ity_F32);
8789 IRTemp result = newTemp(Ity_F32);
floriandb4fcaa2012-09-05 19:54:08 +00008790 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008791
8792 assign(op1, get_fpr_w0(r1));
8793 assign(op2, load(Ity_F32, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00008794 assign(result, triop(Iop_SubF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008795 mkexpr(op2)));
8796 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
8797 put_fpr_w0(r1, mkexpr(result));
8798
8799 return "seb";
8800}
8801
8802static HChar *
8803s390_irgen_SDB(UChar r1, IRTemp op2addr)
8804{
8805 IRTemp op1 = newTemp(Ity_F64);
8806 IRTemp op2 = newTemp(Ity_F64);
8807 IRTemp result = newTemp(Ity_F64);
floriandb4fcaa2012-09-05 19:54:08 +00008808 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008809
8810 assign(op1, get_fpr_dw0(r1));
8811 assign(op2, load(Ity_F64, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00008812 assign(result, triop(Iop_SubF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008813 mkexpr(op2)));
8814 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
8815 put_fpr_dw0(r1, mkexpr(result));
8816
8817 return "sdb";
8818}
8819
8820
8821static HChar *
8822s390_irgen_CLC(UChar length, IRTemp start1, IRTemp start2)
8823{
florian79e839e2012-05-05 02:20:30 +00008824 IRTemp len = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00008825
florian79e839e2012-05-05 02:20:30 +00008826 assign(len, mkU64(length));
8827 s390_irgen_CLC_EX(len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +00008828
8829 return "clc";
8830}
8831
8832static HChar *
florianb0c9a132011-09-08 15:37:39 +00008833s390_irgen_CLCL(UChar r1, UChar r2)
8834{
8835 IRTemp addr1 = newTemp(Ity_I64);
8836 IRTemp addr2 = newTemp(Ity_I64);
8837 IRTemp addr1_load = newTemp(Ity_I64);
8838 IRTemp addr2_load = newTemp(Ity_I64);
8839 IRTemp len1 = newTemp(Ity_I32);
8840 IRTemp len2 = newTemp(Ity_I32);
8841 IRTemp r1p1 = newTemp(Ity_I32); /* contents of r1 + 1 */
8842 IRTemp r2p1 = newTemp(Ity_I32); /* contents of r2 + 1 */
8843 IRTemp single1 = newTemp(Ity_I8);
8844 IRTemp single2 = newTemp(Ity_I8);
8845 IRTemp pad = newTemp(Ity_I8);
8846
8847 assign(addr1, get_gpr_dw0(r1));
8848 assign(r1p1, get_gpr_w1(r1 + 1));
8849 assign(len1, binop(Iop_And32, mkexpr(r1p1), mkU32(0x00ffffff)));
8850 assign(addr2, get_gpr_dw0(r2));
8851 assign(r2p1, get_gpr_w1(r2 + 1));
8852 assign(len2, binop(Iop_And32, mkexpr(r2p1), mkU32(0x00ffffff)));
8853 assign(pad, get_gpr_b4(r2 + 1));
8854
8855 /* len1 == 0 and len2 == 0? Exit */
8856 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +00008857 next_insn_if(binop(Iop_CmpEQ32, binop(Iop_Or32, mkexpr(len1),
8858 mkexpr(len2)), mkU32(0)));
florianb0c9a132011-09-08 15:37:39 +00008859
8860 /* Because mkite evaluates both the then-clause and the else-clause
8861 we cannot load directly from addr1 here. If len1 is 0, then adddr1
8862 may be NULL and loading from there would segfault. So we provide a
8863 valid dummy address in that case. Loading from there does no harm and
8864 the value will be discarded at runtime. */
8865 assign(addr1_load,
8866 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
8867 mkU64(guest_IA_curr_instr), mkexpr(addr1)));
8868 assign(single1,
8869 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
8870 mkexpr(pad), load(Ity_I8, mkexpr(addr1_load))));
8871
8872 assign(addr2_load,
8873 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
8874 mkU64(guest_IA_curr_instr), mkexpr(addr2)));
8875 assign(single2,
8876 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
8877 mkexpr(pad), load(Ity_I8, mkexpr(addr2_load))));
8878
8879 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, single1, single2, False);
8880 /* Fields differ ? */
florian6820ba52012-07-26 02:01:50 +00008881 next_insn_if(binop(Iop_CmpNE8, mkexpr(single1), mkexpr(single2)));
florianb0c9a132011-09-08 15:37:39 +00008882
8883 /* Update len1 and addr1, unless len1 == 0. */
8884 put_gpr_dw0(r1,
8885 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
8886 mkexpr(addr1),
8887 binop(Iop_Add64, mkexpr(addr1), mkU64(1))));
8888
8889 /* When updating len1 we must not modify bits (r1+1)[0:39] */
8890 put_gpr_w1(r1 + 1,
8891 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
8892 binop(Iop_And32, mkexpr(r1p1), mkU32(0xFF000000u)),
8893 binop(Iop_Sub32, mkexpr(r1p1), mkU32(1))));
8894
8895 /* Update len2 and addr2, unless len2 == 0. */
8896 put_gpr_dw0(r2,
8897 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
8898 mkexpr(addr2),
8899 binop(Iop_Add64, mkexpr(addr2), mkU64(1))));
8900
8901 /* When updating len2 we must not modify bits (r2+1)[0:39] */
8902 put_gpr_w1(r2 + 1,
8903 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
8904 binop(Iop_And32, mkexpr(r2p1), mkU32(0xFF000000u)),
8905 binop(Iop_Sub32, mkexpr(r2p1), mkU32(1))));
8906
florian6820ba52012-07-26 02:01:50 +00008907 iterate();
florianb0c9a132011-09-08 15:37:39 +00008908
8909 return "clcl";
8910}
8911
8912static HChar *
sewardj2019a972011-03-07 16:04:07 +00008913s390_irgen_CLCLE(UChar r1, UChar r3, IRTemp pad2)
8914{
8915 IRTemp addr1, addr3, addr1_load, addr3_load, len1, len3, single1, single3;
8916
8917 addr1 = newTemp(Ity_I64);
8918 addr3 = newTemp(Ity_I64);
8919 addr1_load = newTemp(Ity_I64);
8920 addr3_load = newTemp(Ity_I64);
8921 len1 = newTemp(Ity_I64);
8922 len3 = newTemp(Ity_I64);
8923 single1 = newTemp(Ity_I8);
8924 single3 = newTemp(Ity_I8);
8925
8926 assign(addr1, get_gpr_dw0(r1));
8927 assign(len1, get_gpr_dw0(r1 + 1));
8928 assign(addr3, get_gpr_dw0(r3));
8929 assign(len3, get_gpr_dw0(r3 + 1));
8930
8931 /* len1 == 0 and len3 == 0? Exit */
8932 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +00008933 next_insn_if(binop(Iop_CmpEQ64,binop(Iop_Or64, mkexpr(len1),
8934 mkexpr(len3)), mkU64(0)));
sewardj2019a972011-03-07 16:04:07 +00008935
8936 /* A mux requires both ways to be possible. This is a way to prevent clcle
8937 from reading from addr1 if it should read from the pad. Since the pad
8938 has no address, just read from the instruction, we discard that anyway */
8939 assign(addr1_load,
florian6ad49522011-09-09 02:38:55 +00008940 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
8941 mkU64(guest_IA_curr_instr), mkexpr(addr1)));
sewardj2019a972011-03-07 16:04:07 +00008942
8943 /* same for addr3 */
8944 assign(addr3_load,
florian6ad49522011-09-09 02:38:55 +00008945 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
8946 mkU64(guest_IA_curr_instr), mkexpr(addr3)));
sewardj2019a972011-03-07 16:04:07 +00008947
8948 assign(single1,
florian6ad49522011-09-09 02:38:55 +00008949 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
8950 unop(Iop_64to8, mkexpr(pad2)),
8951 load(Ity_I8, mkexpr(addr1_load))));
sewardj2019a972011-03-07 16:04:07 +00008952
8953 assign(single3,
florian6ad49522011-09-09 02:38:55 +00008954 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
8955 unop(Iop_64to8, mkexpr(pad2)),
8956 load(Ity_I8, mkexpr(addr3_load))));
sewardj2019a972011-03-07 16:04:07 +00008957
8958 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, single1, single3, False);
8959 /* Both fields differ ? */
florian6820ba52012-07-26 02:01:50 +00008960 next_insn_if(binop(Iop_CmpNE8, mkexpr(single1), mkexpr(single3)));
sewardj2019a972011-03-07 16:04:07 +00008961
8962 /* If a length in 0 we must not change this length and the address */
8963 put_gpr_dw0(r1,
florian6ad49522011-09-09 02:38:55 +00008964 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
8965 mkexpr(addr1),
8966 binop(Iop_Add64, mkexpr(addr1), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +00008967
8968 put_gpr_dw0(r1 + 1,
florian6ad49522011-09-09 02:38:55 +00008969 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
8970 mkU64(0), binop(Iop_Sub64, mkexpr(len1), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +00008971
8972 put_gpr_dw0(r3,
florian6ad49522011-09-09 02:38:55 +00008973 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
8974 mkexpr(addr3),
8975 binop(Iop_Add64, mkexpr(addr3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +00008976
8977 put_gpr_dw0(r3 + 1,
florian6ad49522011-09-09 02:38:55 +00008978 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
8979 mkU64(0), binop(Iop_Sub64, mkexpr(len3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +00008980
florian6820ba52012-07-26 02:01:50 +00008981 iterate();
sewardj2019a972011-03-07 16:04:07 +00008982
8983 return "clcle";
8984}
floriana64c2432011-07-16 02:11:50 +00008985
florianb0bf6602012-05-05 00:01:16 +00008986
sewardj2019a972011-03-07 16:04:07 +00008987static void
8988s390_irgen_XC_EX(IRTemp length, IRTemp start1, IRTemp start2)
8989{
florianb0bf6602012-05-05 00:01:16 +00008990 s390_irgen_xonc(Iop_Xor8, length, start1, start2);
8991}
sewardj2019a972011-03-07 16:04:07 +00008992
sewardj2019a972011-03-07 16:04:07 +00008993
florianb0bf6602012-05-05 00:01:16 +00008994static void
8995s390_irgen_NC_EX(IRTemp length, IRTemp start1, IRTemp start2)
8996{
8997 s390_irgen_xonc(Iop_And8, length, start1, start2);
8998}
sewardj2019a972011-03-07 16:04:07 +00008999
sewardj2019a972011-03-07 16:04:07 +00009000
florianb0bf6602012-05-05 00:01:16 +00009001static void
9002s390_irgen_OC_EX(IRTemp length, IRTemp start1, IRTemp start2)
9003{
9004 s390_irgen_xonc(Iop_Or8, length, start1, start2);
sewardj2019a972011-03-07 16:04:07 +00009005}
9006
9007
9008static void
9009s390_irgen_CLC_EX(IRTemp length, IRTemp start1, IRTemp start2)
9010{
9011 IRTemp current1 = newTemp(Ity_I8);
9012 IRTemp current2 = newTemp(Ity_I8);
9013 IRTemp counter = newTemp(Ity_I64);
9014
9015 assign(counter, get_counter_dw0());
9016 put_counter_dw0(mkU64(0));
9017
9018 assign(current1, load(Ity_I8, binop(Iop_Add64, mkexpr(start1),
9019 mkexpr(counter))));
9020 assign(current2, load(Ity_I8, binop(Iop_Add64, mkexpr(start2),
9021 mkexpr(counter))));
9022 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, current1, current2,
9023 False);
9024
9025 /* Both fields differ ? */
florian6820ba52012-07-26 02:01:50 +00009026 next_insn_if(binop(Iop_CmpNE8, mkexpr(current1), mkexpr(current2)));
sewardj2019a972011-03-07 16:04:07 +00009027
9028 /* Check for end of field */
9029 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
florian6820ba52012-07-26 02:01:50 +00009030 iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)));
sewardj2019a972011-03-07 16:04:07 +00009031 put_counter_dw0(mkU64(0));
9032}
9033
9034static void
9035s390_irgen_MVC_EX(IRTemp length, IRTemp start1, IRTemp start2)
9036{
9037 IRTemp counter = newTemp(Ity_I64);
9038
9039 assign(counter, get_counter_dw0());
9040
9041 store(binop(Iop_Add64, mkexpr(start1), mkexpr(counter)),
9042 load(Ity_I8, binop(Iop_Add64, mkexpr(start2), mkexpr(counter))));
9043
9044 /* Check for end of field */
9045 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
florian6820ba52012-07-26 02:01:50 +00009046 iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)));
sewardj2019a972011-03-07 16:04:07 +00009047 put_counter_dw0(mkU64(0));
9048}
9049
florianf87d4fb2012-05-05 02:55:24 +00009050static void
9051s390_irgen_TR_EX(IRTemp length, IRTemp start1, IRTemp start2)
9052{
9053 IRTemp op = newTemp(Ity_I8);
9054 IRTemp op1 = newTemp(Ity_I8);
9055 IRTemp result = newTemp(Ity_I64);
9056 IRTemp counter = newTemp(Ity_I64);
9057
9058 assign(counter, get_counter_dw0());
9059
9060 assign(op, load(Ity_I8, binop(Iop_Add64, mkexpr(start1), mkexpr(counter))));
9061
9062 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)), mkexpr(start2)));
9063
9064 assign(op1, load(Ity_I8, mkexpr(result)));
9065 store(binop(Iop_Add64, mkexpr(start1), mkexpr(counter)), mkexpr(op1));
9066
9067 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
florian6820ba52012-07-26 02:01:50 +00009068 iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)));
florianf87d4fb2012-05-05 02:55:24 +00009069 put_counter_dw0(mkU64(0));
9070}
sewardj2019a972011-03-07 16:04:07 +00009071
9072
9073static void
9074s390_irgen_EX_SS(UChar r, IRTemp addr2,
florian6820ba52012-07-26 02:01:50 +00009075 void (*irgen)(IRTemp length, IRTemp start1, IRTemp start2),
9076 int lensize)
sewardj2019a972011-03-07 16:04:07 +00009077{
9078 struct SS {
9079 unsigned int op : 8;
9080 unsigned int l : 8;
9081 unsigned int b1 : 4;
9082 unsigned int d1 : 12;
9083 unsigned int b2 : 4;
9084 unsigned int d2 : 12;
9085 };
9086 union {
9087 struct SS dec;
9088 unsigned long bytes;
9089 } ss;
9090 IRTemp cond;
9091 IRDirty *d;
9092 IRTemp torun;
9093
9094 IRTemp start1 = newTemp(Ity_I64);
9095 IRTemp start2 = newTemp(Ity_I64);
9096 IRTemp len = newTemp(lensize == 64 ? Ity_I64 : Ity_I32);
9097 cond = newTemp(Ity_I1);
9098 torun = newTemp(Ity_I64);
9099
9100 assign(torun, load(Ity_I64, mkexpr(addr2)));
9101 /* Start with a check that the saved code is still correct */
9102 assign(cond, binop(Iop_CmpNE64, mkexpr(torun), mkU64(last_execute_target)));
9103 /* If not, save the new value */
9104 d = unsafeIRDirty_0_N (0, "s390x_dirtyhelper_EX", &s390x_dirtyhelper_EX,
9105 mkIRExprVec_1(mkexpr(torun)));
9106 d->guard = mkexpr(cond);
9107 stmt(IRStmt_Dirty(d));
9108
9109 /* and restart */
florian428dfdd2012-03-27 03:09:49 +00009110 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TISTART),
9111 mkU64(guest_IA_curr_instr)));
9112 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TILEN), mkU64(4)));
florian6820ba52012-07-26 02:01:50 +00009113 restart_if(mkexpr(cond));
sewardj2019a972011-03-07 16:04:07 +00009114
9115 ss.bytes = last_execute_target;
9116 assign(start1, binop(Iop_Add64, mkU64(ss.dec.d1),
9117 ss.dec.b1 != 0 ? get_gpr_dw0(ss.dec.b1) : mkU64(0)));
9118 assign(start2, binop(Iop_Add64, mkU64(ss.dec.d2),
9119 ss.dec.b2 != 0 ? get_gpr_dw0(ss.dec.b2) : mkU64(0)));
9120 assign(len, unop(lensize == 64 ? Iop_8Uto64 : Iop_8Uto32, binop(Iop_Or8,
9121 r != 0 ? get_gpr_b7(r): mkU8(0), mkU8(ss.dec.l))));
9122 irgen(len, start1, start2);
florian8844a632012-04-13 04:04:06 +00009123
sewardj2019a972011-03-07 16:04:07 +00009124 last_execute_target = 0;
9125}
9126
9127static HChar *
9128s390_irgen_EX(UChar r1, IRTemp addr2)
9129{
9130 switch(last_execute_target & 0xff00000000000000ULL) {
9131 case 0:
9132 {
9133 /* no code information yet */
9134 IRDirty *d;
9135
9136 /* so safe the code... */
9137 d = unsafeIRDirty_0_N (0, "s390x_dirtyhelper_EX", &s390x_dirtyhelper_EX,
9138 mkIRExprVec_1(load(Ity_I64, mkexpr(addr2))));
9139 stmt(IRStmt_Dirty(d));
9140 /* and restart */
florian428dfdd2012-03-27 03:09:49 +00009141 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TISTART),
9142 mkU64(guest_IA_curr_instr)));
9143 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TILEN), mkU64(4)));
florian6820ba52012-07-26 02:01:50 +00009144 restart_if(IRExpr_Const(IRConst_U1(True)));
9145
sewardj2019a972011-03-07 16:04:07 +00009146 /* we know that this will be invalidated */
florianf9e1ed72012-04-17 02:41:56 +00009147 put_IA(mkaddr_expr(guest_IA_next_instr));
sewardj2019a972011-03-07 16:04:07 +00009148 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +00009149 dis_res->jk_StopHere = Ijk_TInval;
sewardj2019a972011-03-07 16:04:07 +00009150 break;
9151 }
9152
9153 case 0xd200000000000000ULL:
9154 /* special case MVC */
9155 s390_irgen_EX_SS(r1, addr2, s390_irgen_MVC_EX, 64);
9156 return "mvc via ex";
9157
9158 case 0xd500000000000000ULL:
9159 /* special case CLC */
9160 s390_irgen_EX_SS(r1, addr2, s390_irgen_CLC_EX, 64);
9161 return "clc via ex";
9162
9163 case 0xd700000000000000ULL:
9164 /* special case XC */
9165 s390_irgen_EX_SS(r1, addr2, s390_irgen_XC_EX, 32);
9166 return "xc via ex";
9167
florianb0bf6602012-05-05 00:01:16 +00009168 case 0xd600000000000000ULL:
9169 /* special case OC */
9170 s390_irgen_EX_SS(r1, addr2, s390_irgen_OC_EX, 32);
9171 return "oc via ex";
9172
9173 case 0xd400000000000000ULL:
9174 /* special case NC */
9175 s390_irgen_EX_SS(r1, addr2, s390_irgen_NC_EX, 32);
9176 return "nc via ex";
sewardj2019a972011-03-07 16:04:07 +00009177
florianf87d4fb2012-05-05 02:55:24 +00009178 case 0xdc00000000000000ULL:
9179 /* special case TR */
9180 s390_irgen_EX_SS(r1, addr2, s390_irgen_TR_EX, 64);
9181 return "tr via ex";
9182
sewardj2019a972011-03-07 16:04:07 +00009183 default:
9184 {
9185 /* everything else will get a self checking prefix that also checks the
9186 register content */
9187 IRDirty *d;
9188 UChar *bytes;
9189 IRTemp cond;
9190 IRTemp orperand;
9191 IRTemp torun;
9192
9193 cond = newTemp(Ity_I1);
9194 orperand = newTemp(Ity_I64);
9195 torun = newTemp(Ity_I64);
9196
9197 if (r1 == 0)
9198 assign(orperand, mkU64(0));
9199 else
9200 assign(orperand, unop(Iop_8Uto64,get_gpr_b7(r1)));
9201 /* This code is going to be translated */
9202 assign(torun, binop(Iop_Or64, load(Ity_I64, mkexpr(addr2)),
9203 binop(Iop_Shl64, mkexpr(orperand), mkU8(48))));
9204
9205 /* Start with a check that saved code is still correct */
9206 assign(cond, binop(Iop_CmpNE64, mkexpr(torun),
9207 mkU64(last_execute_target)));
9208 /* If not, save the new value */
9209 d = unsafeIRDirty_0_N (0, "s390x_dirtyhelper_EX", &s390x_dirtyhelper_EX,
9210 mkIRExprVec_1(mkexpr(torun)));
9211 d->guard = mkexpr(cond);
9212 stmt(IRStmt_Dirty(d));
9213
9214 /* and restart */
florian428dfdd2012-03-27 03:09:49 +00009215 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TISTART), mkU64(guest_IA_curr_instr)));
9216 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TILEN), mkU64(4)));
florian6820ba52012-07-26 02:01:50 +00009217 restart_if(mkexpr(cond));
sewardj2019a972011-03-07 16:04:07 +00009218
9219 /* Now comes the actual translation */
9220 bytes = (UChar *) &last_execute_target;
9221 s390_decode_and_irgen(bytes, ((((bytes[0] >> 6) + 1) >> 1) + 1) << 1,
9222 dis_res);
sewardj7ee97522011-05-09 21:45:04 +00009223 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00009224 vex_printf(" which was executed by\n");
9225 /* dont make useless translations in the next execute */
9226 last_execute_target = 0;
9227 }
9228 }
9229 return "ex";
9230}
9231
9232static HChar *
9233s390_irgen_EXRL(UChar r1, UInt offset)
9234{
9235 IRTemp addr = newTemp(Ity_I64);
9236 /* we might save one round trip because we know the target */
9237 if (!last_execute_target)
9238 last_execute_target = *(ULong *)(HWord)
9239 (guest_IA_curr_instr + offset * 2UL);
9240 assign(addr, mkU64(guest_IA_curr_instr + offset * 2UL));
9241 s390_irgen_EX(r1, addr);
9242 return "exrl";
9243}
9244
9245static HChar *
9246s390_irgen_IPM(UChar r1)
9247{
9248 // As long as we dont support SPM, lets just assume 0 as program mask
9249 put_gpr_b4(r1, unop(Iop_32to8, binop(Iop_Or32, mkU32(0 /* program mask */),
9250 binop(Iop_Shl32, s390_call_calculate_cc(), mkU8(4)))));
9251
9252 return "ipm";
9253}
9254
9255
9256static HChar *
9257s390_irgen_SRST(UChar r1, UChar r2)
9258{
9259 IRTemp address = newTemp(Ity_I64);
9260 IRTemp next = newTemp(Ity_I64);
9261 IRTemp delim = newTemp(Ity_I8);
9262 IRTemp counter = newTemp(Ity_I64);
9263 IRTemp byte = newTemp(Ity_I8);
9264
9265 assign(address, get_gpr_dw0(r2));
9266 assign(next, get_gpr_dw0(r1));
9267
9268 assign(counter, get_counter_dw0());
9269 put_counter_dw0(mkU64(0));
9270
9271 // start = next? CC=2 and out r1 and r2 unchanged
9272 s390_cc_set(2);
9273 put_gpr_dw0(r2, binop(Iop_Sub64, mkexpr(address), mkexpr(counter)));
florian6820ba52012-07-26 02:01:50 +00009274 next_insn_if(binop(Iop_CmpEQ64, mkexpr(address), mkexpr(next)));
sewardj2019a972011-03-07 16:04:07 +00009275
9276 assign(byte, load(Ity_I8, mkexpr(address)));
9277 assign(delim, get_gpr_b7(0));
9278
9279 // byte = delim? CC=1, R1=address
9280 s390_cc_set(1);
9281 put_gpr_dw0(r1, mkexpr(address));
florian6820ba52012-07-26 02:01:50 +00009282 next_insn_if(binop(Iop_CmpEQ8, mkexpr(delim), mkexpr(byte)));
sewardj2019a972011-03-07 16:04:07 +00009283
9284 // else: all equal, no end yet, loop
9285 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
9286 put_gpr_dw0(r1, mkexpr(next));
9287 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(address), mkU64(1)));
floriancf87c942012-07-25 00:52:21 +00009288
florian6820ba52012-07-26 02:01:50 +00009289 iterate();
sewardj2019a972011-03-07 16:04:07 +00009290
9291 return "srst";
9292}
9293
9294static HChar *
9295s390_irgen_CLST(UChar r1, UChar r2)
9296{
9297 IRTemp address1 = newTemp(Ity_I64);
9298 IRTemp address2 = newTemp(Ity_I64);
9299 IRTemp end = newTemp(Ity_I8);
9300 IRTemp counter = newTemp(Ity_I64);
9301 IRTemp byte1 = newTemp(Ity_I8);
9302 IRTemp byte2 = newTemp(Ity_I8);
9303
9304 assign(address1, get_gpr_dw0(r1));
9305 assign(address2, get_gpr_dw0(r2));
9306 assign(end, get_gpr_b7(0));
9307 assign(counter, get_counter_dw0());
9308 put_counter_dw0(mkU64(0));
9309 assign(byte1, load(Ity_I8, mkexpr(address1)));
9310 assign(byte2, load(Ity_I8, mkexpr(address2)));
9311
9312 // end in both? all equal, reset r1 and r2 to start values
9313 s390_cc_set(0);
9314 put_gpr_dw0(r1, binop(Iop_Sub64, mkexpr(address1), mkexpr(counter)));
9315 put_gpr_dw0(r2, binop(Iop_Sub64, mkexpr(address2), mkexpr(counter)));
florian6820ba52012-07-26 02:01:50 +00009316 next_insn_if(binop(Iop_CmpEQ8, mkU8(0),
9317 binop(Iop_Or8,
9318 binop(Iop_Xor8, mkexpr(byte1), mkexpr(end)),
9319 binop(Iop_Xor8, mkexpr(byte2), mkexpr(end)))));
sewardj2019a972011-03-07 16:04:07 +00009320
9321 put_gpr_dw0(r1, mkexpr(address1));
9322 put_gpr_dw0(r2, mkexpr(address2));
9323
9324 // End found in string1
9325 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +00009326 next_insn_if(binop(Iop_CmpEQ8, mkexpr(end), mkexpr(byte1)));
sewardj2019a972011-03-07 16:04:07 +00009327
9328 // End found in string2
9329 s390_cc_set(2);
florian6820ba52012-07-26 02:01:50 +00009330 next_insn_if(binop(Iop_CmpEQ8, mkexpr(end), mkexpr(byte2)));
sewardj2019a972011-03-07 16:04:07 +00009331
9332 // string1 < string2
9333 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +00009334 next_insn_if(binop(Iop_CmpLT32U, unop(Iop_8Uto32, mkexpr(byte1)),
9335 unop(Iop_8Uto32, mkexpr(byte2))));
sewardj2019a972011-03-07 16:04:07 +00009336
9337 // string2 < string1
9338 s390_cc_set(2);
florian6820ba52012-07-26 02:01:50 +00009339 next_insn_if(binop(Iop_CmpLT32U, unop(Iop_8Uto32, mkexpr(byte2)),
9340 unop(Iop_8Uto32, mkexpr(byte1))));
sewardj2019a972011-03-07 16:04:07 +00009341
9342 // else: all equal, no end yet, loop
9343 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
9344 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), mkU64(1)));
9345 put_gpr_dw0(r2, binop(Iop_Add64, get_gpr_dw0(r2), mkU64(1)));
floriancf87c942012-07-25 00:52:21 +00009346
florian6820ba52012-07-26 02:01:50 +00009347 iterate();
sewardj2019a972011-03-07 16:04:07 +00009348
9349 return "clst";
9350}
9351
9352static void
9353s390_irgen_load_multiple_32bit(UChar r1, UChar r3, IRTemp op2addr)
9354{
9355 UChar reg;
9356 IRTemp addr = newTemp(Ity_I64);
9357
9358 assign(addr, mkexpr(op2addr));
9359 reg = r1;
9360 do {
9361 IRTemp old = addr;
9362
9363 reg %= 16;
9364 put_gpr_w1(reg, load(Ity_I32, mkexpr(addr)));
9365 addr = newTemp(Ity_I64);
9366 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
9367 reg++;
9368 } while (reg != (r3 + 1));
9369}
9370
9371static HChar *
9372s390_irgen_LM(UChar r1, UChar r3, IRTemp op2addr)
9373{
9374 s390_irgen_load_multiple_32bit(r1, r3, op2addr);
9375
9376 return "lm";
9377}
9378
9379static HChar *
9380s390_irgen_LMY(UChar r1, UChar r3, IRTemp op2addr)
9381{
9382 s390_irgen_load_multiple_32bit(r1, r3, op2addr);
9383
9384 return "lmy";
9385}
9386
9387static HChar *
9388s390_irgen_LMH(UChar r1, UChar r3, IRTemp op2addr)
9389{
9390 UChar reg;
9391 IRTemp addr = newTemp(Ity_I64);
9392
9393 assign(addr, mkexpr(op2addr));
9394 reg = r1;
9395 do {
9396 IRTemp old = addr;
9397
9398 reg %= 16;
9399 put_gpr_w0(reg, load(Ity_I32, mkexpr(addr)));
9400 addr = newTemp(Ity_I64);
9401 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
9402 reg++;
9403 } while (reg != (r3 + 1));
9404
9405 return "lmh";
9406}
9407
9408static HChar *
9409s390_irgen_LMG(UChar r1, UChar r3, IRTemp op2addr)
9410{
9411 UChar reg;
9412 IRTemp addr = newTemp(Ity_I64);
9413
9414 assign(addr, mkexpr(op2addr));
9415 reg = r1;
9416 do {
9417 IRTemp old = addr;
9418
9419 reg %= 16;
9420 put_gpr_dw0(reg, load(Ity_I64, mkexpr(addr)));
9421 addr = newTemp(Ity_I64);
9422 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(8)));
9423 reg++;
9424 } while (reg != (r3 + 1));
9425
9426 return "lmg";
9427}
9428
9429static void
9430s390_irgen_store_multiple_32bit(UChar r1, UChar r3, IRTemp op2addr)
9431{
9432 UChar reg;
9433 IRTemp addr = newTemp(Ity_I64);
9434
9435 assign(addr, mkexpr(op2addr));
9436 reg = r1;
9437 do {
9438 IRTemp old = addr;
9439
9440 reg %= 16;
9441 store(mkexpr(addr), get_gpr_w1(reg));
9442 addr = newTemp(Ity_I64);
9443 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
9444 reg++;
9445 } while( reg != (r3 + 1));
9446}
9447
9448static HChar *
9449s390_irgen_STM(UChar r1, UChar r3, IRTemp op2addr)
9450{
9451 s390_irgen_store_multiple_32bit(r1, r3, op2addr);
9452
9453 return "stm";
9454}
9455
9456static HChar *
9457s390_irgen_STMY(UChar r1, UChar r3, IRTemp op2addr)
9458{
9459 s390_irgen_store_multiple_32bit(r1, r3, op2addr);
9460
9461 return "stmy";
9462}
9463
9464static HChar *
9465s390_irgen_STMH(UChar r1, UChar r3, IRTemp op2addr)
9466{
9467 UChar reg;
9468 IRTemp addr = newTemp(Ity_I64);
9469
9470 assign(addr, mkexpr(op2addr));
9471 reg = r1;
9472 do {
9473 IRTemp old = addr;
9474
9475 reg %= 16;
9476 store(mkexpr(addr), get_gpr_w0(reg));
9477 addr = newTemp(Ity_I64);
9478 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
9479 reg++;
9480 } while( reg != (r3 + 1));
9481
9482 return "stmh";
9483}
9484
9485static HChar *
9486s390_irgen_STMG(UChar r1, UChar r3, IRTemp op2addr)
9487{
9488 UChar reg;
9489 IRTemp addr = newTemp(Ity_I64);
9490
9491 assign(addr, mkexpr(op2addr));
9492 reg = r1;
9493 do {
9494 IRTemp old = addr;
9495
9496 reg %= 16;
9497 store(mkexpr(addr), get_gpr_dw0(reg));
9498 addr = newTemp(Ity_I64);
9499 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(8)));
9500 reg++;
9501 } while( reg != (r3 + 1));
9502
9503 return "stmg";
9504}
9505
9506static void
florianb0bf6602012-05-05 00:01:16 +00009507s390_irgen_xonc(IROp op, IRTemp length, IRTemp start1, IRTemp start2)
sewardj2019a972011-03-07 16:04:07 +00009508{
9509 IRTemp old1 = newTemp(Ity_I8);
9510 IRTemp old2 = newTemp(Ity_I8);
9511 IRTemp new1 = newTemp(Ity_I8);
9512 IRTemp counter = newTemp(Ity_I32);
9513 IRTemp addr1 = newTemp(Ity_I64);
9514
9515 assign(counter, get_counter_w0());
9516
9517 assign(addr1, binop(Iop_Add64, mkexpr(start1),
9518 unop(Iop_32Uto64, mkexpr(counter))));
9519
9520 assign(old1, load(Ity_I8, mkexpr(addr1)));
9521 assign(old2, load(Ity_I8, binop(Iop_Add64, mkexpr(start2),
9522 unop(Iop_32Uto64,mkexpr(counter)))));
9523 assign(new1, binop(op, mkexpr(old1), mkexpr(old2)));
9524
9525 /* Special case: xc is used to zero memory */
sewardj2019a972011-03-07 16:04:07 +00009526 if (op == Iop_Xor8) {
9527 store(mkexpr(addr1),
florian6ad49522011-09-09 02:38:55 +00009528 mkite(binop(Iop_CmpEQ64, mkexpr(start1), mkexpr(start2)),
9529 mkU8(0), mkexpr(new1)));
sewardj2019a972011-03-07 16:04:07 +00009530 } else
9531 store(mkexpr(addr1), mkexpr(new1));
9532 put_counter_w1(binop(Iop_Or32, unop(Iop_8Uto32, mkexpr(new1)),
9533 get_counter_w1()));
9534
9535 /* Check for end of field */
9536 put_counter_w0(binop(Iop_Add32, mkexpr(counter), mkU32(1)));
florian6820ba52012-07-26 02:01:50 +00009537 iterate_if(binop(Iop_CmpNE32, mkexpr(counter), mkexpr(length)));
sewardj2019a972011-03-07 16:04:07 +00009538 s390_cc_thunk_put1(S390_CC_OP_BITWISE, mktemp(Ity_I32, get_counter_w1()),
9539 False);
9540 put_counter_dw0(mkU64(0));
9541}
9542
9543static HChar *
9544s390_irgen_XC(UChar length, IRTemp start1, IRTemp start2)
9545{
florianb0bf6602012-05-05 00:01:16 +00009546 IRTemp len = newTemp(Ity_I32);
9547
9548 assign(len, mkU32(length));
9549 s390_irgen_xonc(Iop_Xor8, len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +00009550
9551 return "xc";
9552}
9553
sewardjb63967e2011-03-24 08:50:04 +00009554static void
9555s390_irgen_XC_sameloc(UChar length, UChar b, UShort d)
9556{
9557 IRTemp counter = newTemp(Ity_I32);
9558 IRTemp start = newTemp(Ity_I64);
9559 IRTemp addr = newTemp(Ity_I64);
9560
9561 assign(start,
9562 binop(Iop_Add64, mkU64(d), b != 0 ? get_gpr_dw0(b) : mkU64(0)));
9563
9564 if (length < 8) {
9565 UInt i;
9566
9567 for (i = 0; i <= length; ++i) {
9568 store(binop(Iop_Add64, mkexpr(start), mkU64(i)), mkU8(0));
9569 }
9570 } else {
9571 assign(counter, get_counter_w0());
9572
9573 assign(addr, binop(Iop_Add64, mkexpr(start),
9574 unop(Iop_32Uto64, mkexpr(counter))));
9575
9576 store(mkexpr(addr), mkU8(0));
9577
9578 /* Check for end of field */
9579 put_counter_w0(binop(Iop_Add32, mkexpr(counter), mkU32(1)));
florian6820ba52012-07-26 02:01:50 +00009580 iterate_if(binop(Iop_CmpNE32, mkexpr(counter), mkU32(length)));
sewardjb63967e2011-03-24 08:50:04 +00009581
9582 /* Reset counter */
9583 put_counter_dw0(mkU64(0));
9584 }
9585
9586 s390_cc_thunk_put1(S390_CC_OP_BITWISE, mktemp(Ity_I32, mkU32(0)), False);
9587
sewardj7ee97522011-05-09 21:45:04 +00009588 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardjb63967e2011-03-24 08:50:04 +00009589 s390_disasm(ENC3(MNM, UDLB, UDXB), "xc", d, length, b, d, 0, b);
9590}
9591
sewardj2019a972011-03-07 16:04:07 +00009592static HChar *
9593s390_irgen_NC(UChar length, IRTemp start1, IRTemp start2)
9594{
florianb0bf6602012-05-05 00:01:16 +00009595 IRTemp len = newTemp(Ity_I32);
9596
9597 assign(len, mkU32(length));
9598 s390_irgen_xonc(Iop_And8, len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +00009599
9600 return "nc";
9601}
9602
9603static HChar *
9604s390_irgen_OC(UChar length, IRTemp start1, IRTemp start2)
9605{
florianb0bf6602012-05-05 00:01:16 +00009606 IRTemp len = newTemp(Ity_I32);
9607
9608 assign(len, mkU32(length));
9609 s390_irgen_xonc(Iop_Or8, len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +00009610
9611 return "oc";
9612}
9613
9614
9615static HChar *
9616s390_irgen_MVC(UChar length, IRTemp start1, IRTemp start2)
9617{
florian79e839e2012-05-05 02:20:30 +00009618 IRTemp len = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00009619
florian79e839e2012-05-05 02:20:30 +00009620 assign(len, mkU64(length));
9621 s390_irgen_MVC_EX(len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +00009622
9623 return "mvc";
9624}
9625
9626static HChar *
florianb0c9a132011-09-08 15:37:39 +00009627s390_irgen_MVCL(UChar r1, UChar r2)
9628{
9629 IRTemp addr1 = newTemp(Ity_I64);
9630 IRTemp addr2 = newTemp(Ity_I64);
9631 IRTemp addr2_load = newTemp(Ity_I64);
9632 IRTemp r1p1 = newTemp(Ity_I32); /* contents of r1 + 1 */
9633 IRTemp r2p1 = newTemp(Ity_I32); /* contents of r2 + 1 */
9634 IRTemp len1 = newTemp(Ity_I32);
9635 IRTemp len2 = newTemp(Ity_I32);
9636 IRTemp pad = newTemp(Ity_I8);
9637 IRTemp single = newTemp(Ity_I8);
9638
9639 assign(addr1, get_gpr_dw0(r1));
9640 assign(r1p1, get_gpr_w1(r1 + 1));
9641 assign(len1, binop(Iop_And32, mkexpr(r1p1), mkU32(0x00ffffff)));
9642 assign(addr2, get_gpr_dw0(r2));
9643 assign(r2p1, get_gpr_w1(r2 + 1));
9644 assign(len2, binop(Iop_And32, mkexpr(r2p1), mkU32(0x00ffffff)));
9645 assign(pad, get_gpr_b4(r2 + 1));
9646
9647 /* len1 == 0 ? */
9648 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len2, False);
florian6820ba52012-07-26 02:01:50 +00009649 next_insn_if(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)));
florianb0c9a132011-09-08 15:37:39 +00009650
9651 /* Check for destructive overlap:
9652 addr1 > addr2 && addr2 + len1 > addr1 && (addr2 + len2) > addr1 */
9653 s390_cc_set(3);
9654 IRTemp cond1 = newTemp(Ity_I32);
9655 assign(cond1, unop(Iop_1Uto32,
9656 binop(Iop_CmpLT64U, mkexpr(addr2), mkexpr(addr1))));
9657 IRTemp cond2 = newTemp(Ity_I32);
9658 assign(cond2, unop(Iop_1Uto32,
9659 binop(Iop_CmpLT64U, mkexpr(addr1),
9660 binop(Iop_Add64, mkexpr(addr2),
9661 unop(Iop_32Uto64, mkexpr(len1))))));
9662 IRTemp cond3 = newTemp(Ity_I32);
9663 assign(cond3, unop(Iop_1Uto32,
9664 binop(Iop_CmpLT64U,
9665 mkexpr(addr1),
9666 binop(Iop_Add64, mkexpr(addr2),
9667 unop(Iop_32Uto64, mkexpr(len2))))));
9668
florian6820ba52012-07-26 02:01:50 +00009669 next_insn_if(binop(Iop_CmpEQ32,
9670 binop(Iop_And32,
9671 binop(Iop_And32, mkexpr(cond1), mkexpr(cond2)),
9672 mkexpr(cond3)),
9673 mkU32(1)));
florianb0c9a132011-09-08 15:37:39 +00009674
9675 /* See s390_irgen_CLCL for explanation why we cannot load directly
9676 and need two steps. */
9677 assign(addr2_load,
9678 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
9679 mkU64(guest_IA_curr_instr), mkexpr(addr2)));
9680 assign(single,
9681 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
9682 mkexpr(pad), load(Ity_I8, mkexpr(addr2_load))));
9683
9684 store(mkexpr(addr1), mkexpr(single));
9685
9686 /* Update addr1 and len1 */
9687 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkU64(1)));
9688 put_gpr_w1(r1 + 1, binop(Iop_Sub32, mkexpr(r1p1), mkU32(1)));
9689
9690 /* Update addr2 and len2 */
9691 put_gpr_dw0(r2,
9692 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
9693 mkexpr(addr2),
9694 binop(Iop_Add64, mkexpr(addr2), mkU64(1))));
9695
9696 /* When updating len2 we must not modify bits (r2+1)[0:39] */
9697 put_gpr_w1(r2 + 1,
9698 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
9699 binop(Iop_And32, mkexpr(r2p1), mkU32(0xFF000000u)),
9700 binop(Iop_Sub32, mkexpr(r2p1), mkU32(1))));
9701
9702 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len2, False);
florian6820ba52012-07-26 02:01:50 +00009703 iterate_if(binop(Iop_CmpNE32, mkexpr(len1), mkU32(1)));
florianb0c9a132011-09-08 15:37:39 +00009704
9705 return "mvcl";
9706}
9707
9708
9709static HChar *
sewardj2019a972011-03-07 16:04:07 +00009710s390_irgen_MVCLE(UChar r1, UChar r3, IRTemp pad2)
9711{
9712 IRTemp addr1, addr3, addr3_load, len1, len3, single;
9713
9714 addr1 = newTemp(Ity_I64);
9715 addr3 = newTemp(Ity_I64);
9716 addr3_load = newTemp(Ity_I64);
9717 len1 = newTemp(Ity_I64);
9718 len3 = newTemp(Ity_I64);
9719 single = newTemp(Ity_I8);
9720
9721 assign(addr1, get_gpr_dw0(r1));
9722 assign(len1, get_gpr_dw0(r1 + 1));
9723 assign(addr3, get_gpr_dw0(r3));
9724 assign(len3, get_gpr_dw0(r3 + 1));
9725
9726 // len1 == 0 ?
9727 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len3, False);
florian6820ba52012-07-26 02:01:50 +00009728 next_insn_if(binop(Iop_CmpEQ64,mkexpr(len1), mkU64(0)));
sewardj2019a972011-03-07 16:04:07 +00009729
9730 /* This is a hack to prevent mvcle from reading from addr3 if it
9731 should read from the pad. Since the pad has no address, just
9732 read from the instruction, we discard that anyway */
9733 assign(addr3_load,
florian6ad49522011-09-09 02:38:55 +00009734 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
9735 mkU64(guest_IA_curr_instr), mkexpr(addr3)));
sewardj2019a972011-03-07 16:04:07 +00009736
9737 assign(single,
florian6ad49522011-09-09 02:38:55 +00009738 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
9739 unop(Iop_64to8, mkexpr(pad2)),
9740 load(Ity_I8, mkexpr(addr3_load))));
sewardj2019a972011-03-07 16:04:07 +00009741 store(mkexpr(addr1), mkexpr(single));
9742
9743 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkU64(1)));
9744
9745 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkU64(1)));
9746
9747 put_gpr_dw0(r3,
florian6ad49522011-09-09 02:38:55 +00009748 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
9749 mkexpr(addr3),
9750 binop(Iop_Add64, mkexpr(addr3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +00009751
9752 put_gpr_dw0(r3 + 1,
florian6ad49522011-09-09 02:38:55 +00009753 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
9754 mkU64(0), binop(Iop_Sub64, mkexpr(len3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +00009755
sewardj2019a972011-03-07 16:04:07 +00009756 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len3, False);
florian6820ba52012-07-26 02:01:50 +00009757 iterate_if(binop(Iop_CmpNE64, mkexpr(len1), mkU64(1)));
sewardj2019a972011-03-07 16:04:07 +00009758
9759 return "mvcle";
9760}
9761
9762static HChar *
9763s390_irgen_MVST(UChar r1, UChar r2)
9764{
9765 IRTemp addr1 = newTemp(Ity_I64);
9766 IRTemp addr2 = newTemp(Ity_I64);
9767 IRTemp end = newTemp(Ity_I8);
9768 IRTemp byte = newTemp(Ity_I8);
9769 IRTemp counter = newTemp(Ity_I64);
9770
9771 assign(addr1, get_gpr_dw0(r1));
9772 assign(addr2, get_gpr_dw0(r2));
9773 assign(counter, get_counter_dw0());
9774 assign(end, get_gpr_b7(0));
9775 assign(byte, load(Ity_I8, binop(Iop_Add64, mkexpr(addr2),mkexpr(counter))));
9776 store(binop(Iop_Add64,mkexpr(addr1),mkexpr(counter)), mkexpr(byte));
9777
9778 // We use unlimited as cpu-determined number
9779 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
florian6820ba52012-07-26 02:01:50 +00009780 iterate_if(binop(Iop_CmpNE8, mkexpr(end), mkexpr(byte)));
sewardj2019a972011-03-07 16:04:07 +00009781
9782 // and always set cc=1 at the end + update r1
9783 s390_cc_set(1);
9784 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(counter)));
9785 put_counter_dw0(mkU64(0));
9786
9787 return "mvst";
9788}
9789
9790static void
9791s390_irgen_divide_64to32(IROp op, UChar r1, IRTemp op2)
9792{
9793 IRTemp op1 = newTemp(Ity_I64);
9794 IRTemp result = newTemp(Ity_I64);
9795
9796 assign(op1, binop(Iop_32HLto64,
9797 get_gpr_w1(r1), // high 32 bits
9798 get_gpr_w1(r1 + 1))); // low 32 bits
9799 assign(result, binop(op, mkexpr(op1), mkexpr(op2)));
9800 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result))); // remainder
9801 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result))); // quotient
9802}
9803
9804static void
9805s390_irgen_divide_128to64(IROp op, UChar r1, IRTemp op2)
9806{
9807 IRTemp op1 = newTemp(Ity_I128);
9808 IRTemp result = newTemp(Ity_I128);
9809
9810 assign(op1, binop(Iop_64HLto128,
9811 get_gpr_dw0(r1), // high 64 bits
9812 get_gpr_dw0(r1 + 1))); // low 64 bits
9813 assign(result, binop(op, mkexpr(op1), mkexpr(op2)));
9814 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result))); // remainder
9815 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result))); // quotient
9816}
9817
9818static void
9819s390_irgen_divide_64to64(IROp op, UChar r1, IRTemp op2)
9820{
9821 IRTemp op1 = newTemp(Ity_I64);
9822 IRTemp result = newTemp(Ity_I128);
9823
9824 assign(op1, get_gpr_dw0(r1 + 1));
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 HChar *
9831s390_irgen_DR(UChar r1, UChar r2)
9832{
9833 IRTemp op2 = newTemp(Ity_I32);
9834
9835 assign(op2, get_gpr_w1(r2));
9836
9837 s390_irgen_divide_64to32(Iop_DivModS64to32, r1, op2);
9838
9839 return "dr";
9840}
9841
9842static HChar *
9843s390_irgen_D(UChar r1, IRTemp op2addr)
9844{
9845 IRTemp op2 = newTemp(Ity_I32);
9846
9847 assign(op2, load(Ity_I32, mkexpr(op2addr)));
9848
9849 s390_irgen_divide_64to32(Iop_DivModS64to32, r1, op2);
9850
9851 return "d";
9852}
9853
9854static HChar *
9855s390_irgen_DLR(UChar r1, UChar r2)
9856{
9857 IRTemp op2 = newTemp(Ity_I32);
9858
9859 assign(op2, get_gpr_w1(r2));
9860
9861 s390_irgen_divide_64to32(Iop_DivModU64to32, r1, op2);
9862
florian7cd1cde2012-08-16 23:57:43 +00009863 return "dlr";
sewardj2019a972011-03-07 16:04:07 +00009864}
9865
9866static HChar *
9867s390_irgen_DL(UChar r1, IRTemp op2addr)
9868{
9869 IRTemp op2 = newTemp(Ity_I32);
9870
9871 assign(op2, load(Ity_I32, mkexpr(op2addr)));
9872
9873 s390_irgen_divide_64to32(Iop_DivModU64to32, r1, op2);
9874
9875 return "dl";
9876}
9877
9878static HChar *
9879s390_irgen_DLG(UChar r1, IRTemp op2addr)
9880{
9881 IRTemp op2 = newTemp(Ity_I64);
9882
9883 assign(op2, load(Ity_I64, mkexpr(op2addr)));
9884
9885 s390_irgen_divide_128to64(Iop_DivModU128to64, r1, op2);
9886
9887 return "dlg";
9888}
9889
9890static HChar *
9891s390_irgen_DLGR(UChar r1, UChar r2)
9892{
9893 IRTemp op2 = newTemp(Ity_I64);
9894
9895 assign(op2, get_gpr_dw0(r2));
9896
9897 s390_irgen_divide_128to64(Iop_DivModU128to64, r1, op2);
9898
9899 return "dlgr";
9900}
9901
9902static HChar *
9903s390_irgen_DSGR(UChar r1, UChar r2)
9904{
9905 IRTemp op2 = newTemp(Ity_I64);
9906
9907 assign(op2, get_gpr_dw0(r2));
9908
9909 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
9910
9911 return "dsgr";
9912}
9913
9914static HChar *
9915s390_irgen_DSG(UChar r1, IRTemp op2addr)
9916{
9917 IRTemp op2 = newTemp(Ity_I64);
9918
9919 assign(op2, load(Ity_I64, mkexpr(op2addr)));
9920
9921 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
9922
9923 return "dsg";
9924}
9925
9926static HChar *
9927s390_irgen_DSGFR(UChar r1, UChar r2)
9928{
9929 IRTemp op2 = newTemp(Ity_I64);
9930
9931 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
9932
9933 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
9934
9935 return "dsgfr";
9936}
9937
9938static HChar *
9939s390_irgen_DSGF(UChar r1, IRTemp op2addr)
9940{
9941 IRTemp op2 = newTemp(Ity_I64);
9942
9943 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
9944
9945 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
9946
9947 return "dsgf";
9948}
9949
9950static void
9951s390_irgen_load_ar_multiple(UChar r1, UChar r3, IRTemp op2addr)
9952{
9953 UChar reg;
9954 IRTemp addr = newTemp(Ity_I64);
9955
9956 assign(addr, mkexpr(op2addr));
9957 reg = r1;
9958 do {
9959 IRTemp old = addr;
9960
9961 reg %= 16;
9962 put_ar_w0(reg, load(Ity_I32, mkexpr(addr)));
9963 addr = newTemp(Ity_I64);
9964 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
9965 reg++;
9966 } while (reg != (r3 + 1));
9967}
9968
9969static HChar *
9970s390_irgen_LAM(UChar r1, UChar r3, IRTemp op2addr)
9971{
9972 s390_irgen_load_ar_multiple(r1, r3, op2addr);
9973
9974 return "lam";
9975}
9976
9977static HChar *
9978s390_irgen_LAMY(UChar r1, UChar r3, IRTemp op2addr)
9979{
9980 s390_irgen_load_ar_multiple(r1, r3, op2addr);
9981
9982 return "lamy";
9983}
9984
9985static void
9986s390_irgen_store_ar_multiple(UChar r1, UChar r3, IRTemp op2addr)
9987{
9988 UChar reg;
9989 IRTemp addr = newTemp(Ity_I64);
9990
9991 assign(addr, mkexpr(op2addr));
9992 reg = r1;
9993 do {
9994 IRTemp old = addr;
9995
9996 reg %= 16;
9997 store(mkexpr(addr), get_ar_w0(reg));
9998 addr = newTemp(Ity_I64);
9999 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
10000 reg++;
10001 } while (reg != (r3 + 1));
10002}
10003
10004static HChar *
10005s390_irgen_STAM(UChar r1, UChar r3, IRTemp op2addr)
10006{
10007 s390_irgen_store_ar_multiple(r1, r3, op2addr);
10008
10009 return "stam";
10010}
10011
10012static HChar *
10013s390_irgen_STAMY(UChar r1, UChar r3, IRTemp op2addr)
10014{
10015 s390_irgen_store_ar_multiple(r1, r3, op2addr);
10016
10017 return "stamy";
10018}
10019
10020
10021/* Implementation for 32-bit compare-and-swap */
10022static void
10023s390_irgen_cas_32(UChar r1, UChar r3, IRTemp op2addr)
10024{
10025 IRCAS *cas;
10026 IRTemp op1 = newTemp(Ity_I32);
10027 IRTemp old_mem = newTemp(Ity_I32);
10028 IRTemp op3 = newTemp(Ity_I32);
10029 IRTemp result = newTemp(Ity_I32);
10030 IRTemp nequal = newTemp(Ity_I1);
10031
10032 assign(op1, get_gpr_w1(r1));
10033 assign(op3, get_gpr_w1(r3));
10034
10035 /* The first and second operands are compared. If they are equal,
10036 the third operand is stored at the second- operand location. */
10037 cas = mkIRCAS(IRTemp_INVALID, old_mem,
10038 Iend_BE, mkexpr(op2addr),
10039 NULL, mkexpr(op1), /* expected value */
10040 NULL, mkexpr(op3) /* new value */);
10041 stmt(IRStmt_CAS(cas));
10042
10043 /* Set CC. Operands compared equal -> 0, else 1. */
10044 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(old_mem)));
10045 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
10046
10047 /* If operands were equal (cc == 0) just store the old value op1 in r1.
10048 Otherwise, store the old_value from memory in r1 and yield. */
10049 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
10050 put_gpr_w1(r1, mkite(mkexpr(nequal), mkexpr(old_mem), mkexpr(op1)));
florian6820ba52012-07-26 02:01:50 +000010051 yield_if(mkexpr(nequal));
sewardj2019a972011-03-07 16:04:07 +000010052}
10053
10054static HChar *
10055s390_irgen_CS(UChar r1, UChar r3, IRTemp op2addr)
10056{
10057 s390_irgen_cas_32(r1, r3, op2addr);
10058
10059 return "cs";
10060}
10061
10062static HChar *
10063s390_irgen_CSY(UChar r1, UChar r3, IRTemp op2addr)
10064{
10065 s390_irgen_cas_32(r1, r3, op2addr);
10066
10067 return "csy";
10068}
10069
10070static HChar *
10071s390_irgen_CSG(UChar r1, UChar r3, IRTemp op2addr)
10072{
10073 IRCAS *cas;
10074 IRTemp op1 = newTemp(Ity_I64);
10075 IRTemp old_mem = newTemp(Ity_I64);
10076 IRTemp op3 = newTemp(Ity_I64);
10077 IRTemp result = newTemp(Ity_I64);
10078 IRTemp nequal = newTemp(Ity_I1);
10079
10080 assign(op1, get_gpr_dw0(r1));
10081 assign(op3, get_gpr_dw0(r3));
10082
10083 /* The first and second operands are compared. If they are equal,
10084 the third operand is stored at the second- operand location. */
10085 cas = mkIRCAS(IRTemp_INVALID, old_mem,
10086 Iend_BE, mkexpr(op2addr),
10087 NULL, mkexpr(op1), /* expected value */
10088 NULL, mkexpr(op3) /* new value */);
10089 stmt(IRStmt_CAS(cas));
10090
10091 /* Set CC. Operands compared equal -> 0, else 1. */
10092 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(old_mem)));
10093 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
10094
10095 /* If operands were equal (cc == 0) just store the old value op1 in r1.
10096 Otherwise, store the old_value from memory in r1 and yield. */
10097 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
10098 put_gpr_dw0(r1, mkite(mkexpr(nequal), mkexpr(old_mem), mkexpr(op1)));
florian6820ba52012-07-26 02:01:50 +000010099 yield_if(mkexpr(nequal));
sewardj2019a972011-03-07 16:04:07 +000010100
10101 return "csg";
10102}
10103
florian448cbba2012-06-06 02:26:01 +000010104/* Implementation for 32-bit compare-double-and-swap */
10105static void
10106s390_irgen_cdas_32(UChar r1, UChar r3, IRTemp op2addr)
10107{
10108 IRCAS *cas;
10109 IRTemp op1_high = newTemp(Ity_I32);
10110 IRTemp op1_low = newTemp(Ity_I32);
10111 IRTemp old_mem_high = newTemp(Ity_I32);
10112 IRTemp old_mem_low = newTemp(Ity_I32);
10113 IRTemp op3_high = newTemp(Ity_I32);
10114 IRTemp op3_low = newTemp(Ity_I32);
10115 IRTemp result = newTemp(Ity_I32);
10116 IRTemp nequal = newTemp(Ity_I1);
10117
10118 assign(op1_high, get_gpr_w1(r1));
10119 assign(op1_low, get_gpr_w1(r1+1));
10120 assign(op3_high, get_gpr_w1(r3));
10121 assign(op3_low, get_gpr_w1(r3+1));
10122
10123 /* The first and second operands are compared. If they are equal,
10124 the third operand is stored at the second-operand location. */
10125 cas = mkIRCAS(old_mem_high, old_mem_low,
10126 Iend_BE, mkexpr(op2addr),
10127 mkexpr(op1_high), mkexpr(op1_low), /* expected value */
10128 mkexpr(op3_high), mkexpr(op3_low) /* new value */);
10129 stmt(IRStmt_CAS(cas));
10130
10131 /* Set CC. Operands compared equal -> 0, else 1. */
10132 assign(result, unop(Iop_1Uto32,
10133 binop(Iop_CmpNE32,
10134 binop(Iop_Or32,
10135 binop(Iop_Xor32, mkexpr(op1_high), mkexpr(old_mem_high)),
10136 binop(Iop_Xor32, mkexpr(op1_low), mkexpr(old_mem_low))),
10137 mkU32(0))));
10138
10139 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
10140
10141 /* If operands were equal (cc == 0) just store the old value op1 in r1.
10142 Otherwise, store the old_value from memory in r1 and yield. */
10143 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
10144 put_gpr_w1(r1, mkite(mkexpr(nequal), mkexpr(old_mem_high), mkexpr(op1_high)));
10145 put_gpr_w1(r1+1, mkite(mkexpr(nequal), mkexpr(old_mem_low), mkexpr(op1_low)));
florian6820ba52012-07-26 02:01:50 +000010146 yield_if(mkexpr(nequal));
florian448cbba2012-06-06 02:26:01 +000010147}
10148
10149static HChar *
10150s390_irgen_CDS(UChar r1, UChar r3, IRTemp op2addr)
10151{
10152 s390_irgen_cdas_32(r1, r3, op2addr);
10153
10154 return "cds";
10155}
10156
10157static HChar *
10158s390_irgen_CDSY(UChar r1, UChar r3, IRTemp op2addr)
10159{
10160 s390_irgen_cdas_32(r1, r3, op2addr);
10161
10162 return "cdsy";
10163}
10164
10165static HChar *
10166s390_irgen_CDSG(UChar r1, UChar r3, IRTemp op2addr)
10167{
10168 IRCAS *cas;
10169 IRTemp op1_high = newTemp(Ity_I64);
10170 IRTemp op1_low = newTemp(Ity_I64);
10171 IRTemp old_mem_high = newTemp(Ity_I64);
10172 IRTemp old_mem_low = newTemp(Ity_I64);
10173 IRTemp op3_high = newTemp(Ity_I64);
10174 IRTemp op3_low = newTemp(Ity_I64);
10175 IRTemp result = newTemp(Ity_I64);
10176 IRTemp nequal = newTemp(Ity_I1);
10177
10178 assign(op1_high, get_gpr_dw0(r1));
10179 assign(op1_low, get_gpr_dw0(r1+1));
10180 assign(op3_high, get_gpr_dw0(r3));
10181 assign(op3_low, get_gpr_dw0(r3+1));
10182
10183 /* The first and second operands are compared. If they are equal,
10184 the third operand is stored at the second-operand location. */
10185 cas = mkIRCAS(old_mem_high, old_mem_low,
10186 Iend_BE, mkexpr(op2addr),
10187 mkexpr(op1_high), mkexpr(op1_low), /* expected value */
10188 mkexpr(op3_high), mkexpr(op3_low) /* new value */);
10189 stmt(IRStmt_CAS(cas));
10190
10191 /* Set CC. Operands compared equal -> 0, else 1. */
10192 assign(result, unop(Iop_1Uto64,
10193 binop(Iop_CmpNE64,
10194 binop(Iop_Or64,
10195 binop(Iop_Xor64, mkexpr(op1_high), mkexpr(old_mem_high)),
10196 binop(Iop_Xor64, mkexpr(op1_low), mkexpr(old_mem_low))),
10197 mkU64(0))));
10198
10199 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
10200
10201 /* If operands were equal (cc == 0) just store the old value op1 in r1.
10202 Otherwise, store the old_value from memory in r1 and yield. */
10203 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
10204 put_gpr_dw0(r1, mkite(mkexpr(nequal), mkexpr(old_mem_high), mkexpr(op1_high)));
10205 put_gpr_dw0(r1+1, mkite(mkexpr(nequal), mkexpr(old_mem_low), mkexpr(op1_low)));
florian6820ba52012-07-26 02:01:50 +000010206 yield_if(mkexpr(nequal));
10207
florian448cbba2012-06-06 02:26:01 +000010208 return "cdsg";
10209}
10210
sewardj2019a972011-03-07 16:04:07 +000010211
10212/* Binary floating point */
10213
10214static HChar *
10215s390_irgen_AXBR(UChar r1, UChar r2)
10216{
10217 IRTemp op1 = newTemp(Ity_F128);
10218 IRTemp op2 = newTemp(Ity_F128);
10219 IRTemp result = newTemp(Ity_F128);
floriandb4fcaa2012-09-05 19:54:08 +000010220 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000010221
10222 assign(op1, get_fpr_pair(r1));
10223 assign(op2, get_fpr_pair(r2));
floriandb4fcaa2012-09-05 19:54:08 +000010224 assign(result, triop(Iop_AddF128, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +000010225 mkexpr(op2)));
10226 put_fpr_pair(r1, mkexpr(result));
10227
10228 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
10229
10230 return "axbr";
10231}
10232
10233/* The result of a Iop_CmdFxx operation is a condition code. It is
10234 encoded using the values defined in type IRCmpFxxResult.
10235 Before we can store the condition code into the guest state (or do
10236 anything else with it for that matter) we need to convert it to
10237 the encoding that s390 uses. This is what this function does.
10238
10239 s390 VEX b6 b2 b0 cc.1 cc.0
10240 0 0x40 EQ 1 0 0 0 0
10241 1 0x01 LT 0 0 1 0 1
10242 2 0x00 GT 0 0 0 1 0
10243 3 0x45 Unordered 1 1 1 1 1
10244
10245 The following bits from the VEX encoding are interesting:
10246 b0, b2, b6 with b0 being the LSB. We observe:
10247
10248 cc.0 = b0;
10249 cc.1 = b2 | (~b0 & ~b6)
10250
10251 with cc being the s390 condition code.
10252*/
10253static IRExpr *
10254convert_vex_fpcc_to_s390(IRTemp vex_cc)
10255{
10256 IRTemp cc0 = newTemp(Ity_I32);
10257 IRTemp cc1 = newTemp(Ity_I32);
10258 IRTemp b0 = newTemp(Ity_I32);
10259 IRTemp b2 = newTemp(Ity_I32);
10260 IRTemp b6 = newTemp(Ity_I32);
10261
10262 assign(b0, binop(Iop_And32, mkexpr(vex_cc), mkU32(1)));
10263 assign(b2, binop(Iop_And32, binop(Iop_Shr32, mkexpr(vex_cc), mkU8(2)),
10264 mkU32(1)));
10265 assign(b6, binop(Iop_And32, binop(Iop_Shr32, mkexpr(vex_cc), mkU8(6)),
10266 mkU32(1)));
10267
10268 assign(cc0, mkexpr(b0));
10269 assign(cc1, binop(Iop_Or32, mkexpr(b2),
10270 binop(Iop_And32,
10271 binop(Iop_Sub32, mkU32(1), mkexpr(b0)), /* ~b0 */
10272 binop(Iop_Sub32, mkU32(1), mkexpr(b6)) /* ~b6 */
10273 )));
10274
10275 return binop(Iop_Or32, mkexpr(cc0), binop(Iop_Shl32, mkexpr(cc1), mkU8(1)));
10276}
10277
10278static HChar *
10279s390_irgen_CEBR(UChar r1, UChar r2)
10280{
10281 IRTemp op1 = newTemp(Ity_F32);
10282 IRTemp op2 = newTemp(Ity_F32);
10283 IRTemp cc_vex = newTemp(Ity_I32);
10284 IRTemp cc_s390 = newTemp(Ity_I32);
10285
10286 assign(op1, get_fpr_w0(r1));
10287 assign(op2, get_fpr_w0(r2));
10288 assign(cc_vex, binop(Iop_CmpF32, mkexpr(op1), mkexpr(op2)));
10289
10290 assign(cc_s390, convert_vex_fpcc_to_s390(cc_vex));
10291 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
10292
10293 return "cebr";
10294}
10295
10296static HChar *
10297s390_irgen_CDBR(UChar r1, UChar r2)
10298{
10299 IRTemp op1 = newTemp(Ity_F64);
10300 IRTemp op2 = newTemp(Ity_F64);
10301 IRTemp cc_vex = newTemp(Ity_I32);
10302 IRTemp cc_s390 = newTemp(Ity_I32);
10303
10304 assign(op1, get_fpr_dw0(r1));
10305 assign(op2, get_fpr_dw0(r2));
10306 assign(cc_vex, binop(Iop_CmpF64, mkexpr(op1), mkexpr(op2)));
10307
10308 assign(cc_s390, convert_vex_fpcc_to_s390(cc_vex));
10309 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
10310
10311 return "cdbr";
10312}
10313
10314static HChar *
10315s390_irgen_CXBR(UChar r1, UChar r2)
10316{
10317 IRTemp op1 = newTemp(Ity_F128);
10318 IRTemp op2 = newTemp(Ity_F128);
10319 IRTemp cc_vex = newTemp(Ity_I32);
10320 IRTemp cc_s390 = newTemp(Ity_I32);
10321
10322 assign(op1, get_fpr_pair(r1));
10323 assign(op2, get_fpr_pair(r2));
10324 assign(cc_vex, binop(Iop_CmpF128, mkexpr(op1), mkexpr(op2)));
10325
10326 assign(cc_s390, convert_vex_fpcc_to_s390(cc_vex));
10327 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
10328
10329 return "cxbr";
10330}
10331
10332static HChar *
10333s390_irgen_CEB(UChar r1, IRTemp op2addr)
10334{
10335 IRTemp op1 = newTemp(Ity_F32);
10336 IRTemp op2 = newTemp(Ity_F32);
10337 IRTemp cc_vex = newTemp(Ity_I32);
10338 IRTemp cc_s390 = newTemp(Ity_I32);
10339
10340 assign(op1, get_fpr_w0(r1));
10341 assign(op2, load(Ity_F32, mkexpr(op2addr)));
10342 assign(cc_vex, binop(Iop_CmpF32, mkexpr(op1), mkexpr(op2)));
10343
10344 assign(cc_s390, convert_vex_fpcc_to_s390(cc_vex));
10345 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
10346
10347 return "ceb";
10348}
10349
10350static HChar *
10351s390_irgen_CDB(UChar r1, IRTemp op2addr)
10352{
10353 IRTemp op1 = newTemp(Ity_F64);
10354 IRTemp op2 = newTemp(Ity_F64);
10355 IRTemp cc_vex = newTemp(Ity_I32);
10356 IRTemp cc_s390 = newTemp(Ity_I32);
10357
10358 assign(op1, get_fpr_dw0(r1));
10359 assign(op2, load(Ity_F64, mkexpr(op2addr)));
10360 assign(cc_vex, binop(Iop_CmpF64, mkexpr(op1), mkexpr(op2)));
10361
10362 assign(cc_s390, convert_vex_fpcc_to_s390(cc_vex));
10363 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
10364
10365 return "cdb";
10366}
10367
10368static HChar *
florian4b8efad2012-09-02 18:07:08 +000010369s390_irgen_CXFBR(UChar m3 __attribute__((unused)),
10370 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000010371{
10372 IRTemp op2 = newTemp(Ity_I32);
10373
10374 assign(op2, get_gpr_w1(r2));
10375 put_fpr_pair(r1, unop(Iop_I32StoF128, mkexpr(op2)));
10376
10377 return "cxfbr";
10378}
10379
10380static HChar *
floriand2129202012-09-01 20:01:39 +000010381s390_irgen_CXLFBR(UChar m3 __attribute__((unused)),
10382 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
florian1c8f7ff2012-09-01 00:12:11 +000010383{
floriane75dafa2012-09-01 17:54:09 +000010384 if (! s390_host_has_fpext) {
10385 emulation_failure(EmFail_S390X_fpext);
10386 } else {
10387 IRTemp op2 = newTemp(Ity_I32);
florian1c8f7ff2012-09-01 00:12:11 +000010388
floriane75dafa2012-09-01 17:54:09 +000010389 assign(op2, get_gpr_w1(r2));
10390 put_fpr_pair(r1, unop(Iop_I32UtoF128, mkexpr(op2)));
10391 }
florian1c8f7ff2012-09-01 00:12:11 +000010392 return "cxlfbr";
10393}
10394
10395
10396static HChar *
florian4b8efad2012-09-02 18:07:08 +000010397s390_irgen_CXGBR(UChar m3 __attribute__((unused)),
10398 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000010399{
10400 IRTemp op2 = newTemp(Ity_I64);
10401
10402 assign(op2, get_gpr_dw0(r2));
10403 put_fpr_pair(r1, unop(Iop_I64StoF128, mkexpr(op2)));
10404
10405 return "cxgbr";
10406}
10407
10408static HChar *
floriand2129202012-09-01 20:01:39 +000010409s390_irgen_CXLGBR(UChar m3 __attribute__((unused)),
10410 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
florian1c8f7ff2012-09-01 00:12:11 +000010411{
floriane75dafa2012-09-01 17:54:09 +000010412 if (! s390_host_has_fpext) {
10413 emulation_failure(EmFail_S390X_fpext);
10414 } else {
10415 IRTemp op2 = newTemp(Ity_I64);
florian1c8f7ff2012-09-01 00:12:11 +000010416
floriane75dafa2012-09-01 17:54:09 +000010417 assign(op2, get_gpr_dw0(r2));
10418 put_fpr_pair(r1, unop(Iop_I64UtoF128, mkexpr(op2)));
10419 }
florian1c8f7ff2012-09-01 00:12:11 +000010420 return "cxlgbr";
10421}
10422
10423static HChar *
florian4b8efad2012-09-02 18:07:08 +000010424s390_irgen_CFXBR(UChar m3, UChar m4 __attribute__((unused)),
10425 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000010426{
10427 IRTemp op = newTemp(Ity_F128);
10428 IRTemp result = newTemp(Ity_I32);
10429
10430 assign(op, get_fpr_pair(r2));
floriandb4fcaa2012-09-05 19:54:08 +000010431 assign(result, binop(Iop_F128toI32S, mkexpr(encode_bfp_rounding_mode(m3)),
sewardj2019a972011-03-07 16:04:07 +000010432 mkexpr(op)));
10433 put_gpr_w1(r1, mkexpr(result));
10434 s390_cc_thunk_put1f128(S390_CC_OP_BFP_128_TO_INT_32, op);
10435
10436 return "cfxbr";
10437}
10438
10439static HChar *
florian1c8f7ff2012-09-01 00:12:11 +000010440s390_irgen_CLFXBR(UChar m3, UChar m4 __attribute__((unused)),
10441 UChar r1, UChar r2)
10442{
floriane75dafa2012-09-01 17:54:09 +000010443 if (! s390_host_has_fpext) {
10444 emulation_failure(EmFail_S390X_fpext);
10445 } else {
10446 IRTemp op = newTemp(Ity_F128);
10447 IRTemp result = newTemp(Ity_I32);
florian1c8f7ff2012-09-01 00:12:11 +000010448
floriane75dafa2012-09-01 17:54:09 +000010449 assign(op, get_fpr_pair(r2));
floriandb4fcaa2012-09-05 19:54:08 +000010450 assign(result, binop(Iop_F128toI32U, mkexpr(encode_bfp_rounding_mode(m3)),
floriane75dafa2012-09-01 17:54:09 +000010451 mkexpr(op)));
10452 put_gpr_w1(r1, mkexpr(result));
10453 s390_cc_thunk_put1f128(S390_CC_OP_BFP_128_TO_UINT_32, op);
10454 }
florian1c8f7ff2012-09-01 00:12:11 +000010455 return "clfxbr";
10456}
10457
10458
10459static HChar *
florian4b8efad2012-09-02 18:07:08 +000010460s390_irgen_CGXBR(UChar m3, UChar m4 __attribute__((unused)),
10461 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000010462{
10463 IRTemp op = newTemp(Ity_F128);
10464 IRTemp result = newTemp(Ity_I64);
10465
10466 assign(op, get_fpr_pair(r2));
floriandb4fcaa2012-09-05 19:54:08 +000010467 assign(result, binop(Iop_F128toI64S, mkexpr(encode_bfp_rounding_mode(m3)),
sewardj2019a972011-03-07 16:04:07 +000010468 mkexpr(op)));
10469 put_gpr_dw0(r1, mkexpr(result));
10470 s390_cc_thunk_put1f128(S390_CC_OP_BFP_128_TO_INT_64, op);
10471
10472 return "cgxbr";
10473}
10474
10475static HChar *
florian1c8f7ff2012-09-01 00:12:11 +000010476s390_irgen_CLGXBR(UChar m3, UChar m4 __attribute__((unused)),
10477 UChar r1, UChar r2)
10478{
floriane75dafa2012-09-01 17:54:09 +000010479 if (! s390_host_has_fpext) {
10480 emulation_failure(EmFail_S390X_fpext);
10481 } else {
10482 IRTemp op = newTemp(Ity_F128);
10483 IRTemp result = newTemp(Ity_I64);
florian1c8f7ff2012-09-01 00:12:11 +000010484
floriane75dafa2012-09-01 17:54:09 +000010485 assign(op, get_fpr_pair(r2));
floriandb4fcaa2012-09-05 19:54:08 +000010486 assign(result, binop(Iop_F128toI64U, mkexpr(encode_bfp_rounding_mode(m3)),
floriane75dafa2012-09-01 17:54:09 +000010487 mkexpr(op)));
10488 put_gpr_dw0(r1, mkexpr(result));
10489 s390_cc_thunk_put1f128(S390_CC_OP_BFP_128_TO_UINT_64, op);
10490 }
florian1c8f7ff2012-09-01 00:12:11 +000010491 return "clgxbr";
10492}
10493
10494static HChar *
sewardj2019a972011-03-07 16:04:07 +000010495s390_irgen_DXBR(UChar r1, UChar r2)
10496{
10497 IRTemp op1 = newTemp(Ity_F128);
10498 IRTemp op2 = newTemp(Ity_F128);
10499 IRTemp result = newTemp(Ity_F128);
floriandb4fcaa2012-09-05 19:54:08 +000010500 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000010501
10502 assign(op1, get_fpr_pair(r1));
10503 assign(op2, get_fpr_pair(r2));
floriandb4fcaa2012-09-05 19:54:08 +000010504 assign(result, triop(Iop_DivF128, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +000010505 mkexpr(op2)));
10506 put_fpr_pair(r1, mkexpr(result));
10507
10508 return "dxbr";
10509}
10510
10511static HChar *
10512s390_irgen_LTXBR(UChar r1, UChar r2)
10513{
10514 IRTemp result = newTemp(Ity_F128);
10515
10516 assign(result, get_fpr_pair(r2));
10517 put_fpr_pair(r1, mkexpr(result));
10518 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
10519
10520 return "ltxbr";
10521}
10522
10523static HChar *
10524s390_irgen_LCXBR(UChar r1, UChar r2)
10525{
10526 IRTemp result = newTemp(Ity_F128);
10527
10528 assign(result, unop(Iop_NegF128, get_fpr_pair(r2)));
10529 put_fpr_pair(r1, mkexpr(result));
10530 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
10531
10532 return "lcxbr";
10533}
10534
10535static HChar *
10536s390_irgen_LXDBR(UChar r1, UChar r2)
10537{
10538 IRTemp op = newTemp(Ity_F64);
10539
10540 assign(op, get_fpr_dw0(r2));
10541 put_fpr_pair(r1, unop(Iop_F64toF128, mkexpr(op)));
10542
10543 return "lxdbr";
10544}
10545
10546static HChar *
10547s390_irgen_LXEBR(UChar r1, UChar r2)
10548{
10549 IRTemp op = newTemp(Ity_F32);
10550
10551 assign(op, get_fpr_w0(r2));
10552 put_fpr_pair(r1, unop(Iop_F32toF128, mkexpr(op)));
10553
10554 return "lxebr";
10555}
10556
10557static HChar *
10558s390_irgen_LXDB(UChar r1, IRTemp op2addr)
10559{
10560 IRTemp op = newTemp(Ity_F64);
10561
10562 assign(op, load(Ity_F64, mkexpr(op2addr)));
10563 put_fpr_pair(r1, unop(Iop_F64toF128, mkexpr(op)));
10564
10565 return "lxdb";
10566}
10567
10568static HChar *
10569s390_irgen_LXEB(UChar r1, IRTemp op2addr)
10570{
10571 IRTemp op = newTemp(Ity_F32);
10572
10573 assign(op, load(Ity_F32, mkexpr(op2addr)));
10574 put_fpr_pair(r1, unop(Iop_F32toF128, mkexpr(op)));
10575
10576 return "lxeb";
10577}
10578
10579static HChar *
10580s390_irgen_LNEBR(UChar r1, UChar r2)
10581{
10582 IRTemp result = newTemp(Ity_F32);
10583
10584 assign(result, unop(Iop_NegF32, unop(Iop_AbsF32, get_fpr_w0(r2))));
10585 put_fpr_w0(r1, mkexpr(result));
10586 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_32, result);
10587
10588 return "lnebr";
10589}
10590
10591static HChar *
10592s390_irgen_LNDBR(UChar r1, UChar r2)
10593{
10594 IRTemp result = newTemp(Ity_F64);
10595
10596 assign(result, unop(Iop_NegF64, unop(Iop_AbsF64, get_fpr_dw0(r2))));
10597 put_fpr_dw0(r1, mkexpr(result));
10598 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_64, result);
10599
10600 return "lndbr";
10601}
10602
10603static HChar *
10604s390_irgen_LNXBR(UChar r1, UChar r2)
10605{
10606 IRTemp result = newTemp(Ity_F128);
10607
10608 assign(result, unop(Iop_NegF128, unop(Iop_AbsF128, get_fpr_pair(r2))));
10609 put_fpr_pair(r1, mkexpr(result));
10610 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
10611
10612 return "lnxbr";
10613}
10614
10615static HChar *
10616s390_irgen_LPEBR(UChar r1, UChar r2)
10617{
10618 IRTemp result = newTemp(Ity_F32);
10619
10620 assign(result, unop(Iop_AbsF32, get_fpr_w0(r2)));
10621 put_fpr_w0(r1, mkexpr(result));
10622 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_32, result);
10623
10624 return "lpebr";
10625}
10626
10627static HChar *
10628s390_irgen_LPDBR(UChar r1, UChar r2)
10629{
10630 IRTemp result = newTemp(Ity_F64);
10631
10632 assign(result, unop(Iop_AbsF64, get_fpr_dw0(r2)));
10633 put_fpr_dw0(r1, mkexpr(result));
10634 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_64, result);
10635
10636 return "lpdbr";
10637}
10638
10639static HChar *
10640s390_irgen_LPXBR(UChar r1, UChar r2)
10641{
10642 IRTemp result = newTemp(Ity_F128);
10643
10644 assign(result, unop(Iop_AbsF128, get_fpr_pair(r2)));
10645 put_fpr_pair(r1, mkexpr(result));
10646 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
10647
10648 return "lpxbr";
10649}
10650
10651static HChar *
florian4b8efad2012-09-02 18:07:08 +000010652s390_irgen_LDXBR(UChar m3, UChar m4 __attribute__((unused)),
10653 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000010654{
10655 IRTemp result = newTemp(Ity_F64);
10656
floriandb4fcaa2012-09-05 19:54:08 +000010657 assign(result, binop(Iop_F128toF64, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +000010658 get_fpr_pair(r2)));
sewardj2019a972011-03-07 16:04:07 +000010659 put_fpr_dw0(r1, mkexpr(result));
10660
10661 return "ldxbr";
10662}
10663
10664static HChar *
florian4b8efad2012-09-02 18:07:08 +000010665s390_irgen_LEXBR(UChar m3, UChar m4 __attribute__((unused)),
10666 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000010667{
10668 IRTemp result = newTemp(Ity_F32);
10669
floriandb4fcaa2012-09-05 19:54:08 +000010670 assign(result, binop(Iop_F128toF32, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +000010671 get_fpr_pair(r2)));
sewardj2019a972011-03-07 16:04:07 +000010672 put_fpr_w0(r1, mkexpr(result));
10673
10674 return "lexbr";
10675}
10676
10677static HChar *
10678s390_irgen_MXBR(UChar r1, UChar r2)
10679{
10680 IRTemp op1 = newTemp(Ity_F128);
10681 IRTemp op2 = newTemp(Ity_F128);
10682 IRTemp result = newTemp(Ity_F128);
floriandb4fcaa2012-09-05 19:54:08 +000010683 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000010684
10685 assign(op1, get_fpr_pair(r1));
10686 assign(op2, get_fpr_pair(r2));
floriandb4fcaa2012-09-05 19:54:08 +000010687 assign(result, triop(Iop_MulF128, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +000010688 mkexpr(op2)));
10689 put_fpr_pair(r1, mkexpr(result));
10690
10691 return "mxbr";
10692}
10693
10694static HChar *
10695s390_irgen_MAEBR(UChar r1, UChar r3, UChar r2)
10696{
floriandb4fcaa2012-09-05 19:54:08 +000010697 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_ROUND_PER_FPC);
florian847684d2012-09-05 04:19:09 +000010698
floriandb4fcaa2012-09-05 19:54:08 +000010699 put_fpr_w0(r1, qop(Iop_MAddF32, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +000010700 get_fpr_w0(r1), get_fpr_w0(r2), get_fpr_w0(r3)));
10701
10702 return "maebr";
10703}
10704
10705static HChar *
10706s390_irgen_MADBR(UChar r1, UChar r3, UChar r2)
10707{
floriandb4fcaa2012-09-05 19:54:08 +000010708 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_ROUND_PER_FPC);
florian847684d2012-09-05 04:19:09 +000010709
floriandb4fcaa2012-09-05 19:54:08 +000010710 put_fpr_dw0(r1, qop(Iop_MAddF64, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +000010711 get_fpr_dw0(r1), get_fpr_dw0(r2), get_fpr_dw0(r3)));
10712
10713 return "madbr";
10714}
10715
10716static HChar *
10717s390_irgen_MAEB(UChar r3, IRTemp op2addr, UChar r1)
10718{
10719 IRExpr *op2 = load(Ity_F32, mkexpr(op2addr));
floriandb4fcaa2012-09-05 19:54:08 +000010720 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000010721
floriandb4fcaa2012-09-05 19:54:08 +000010722 put_fpr_w0(r1, qop(Iop_MAddF32, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +000010723 get_fpr_w0(r1), op2, get_fpr_w0(r3)));
10724
10725 return "maeb";
10726}
10727
10728static HChar *
10729s390_irgen_MADB(UChar r3, IRTemp op2addr, UChar r1)
10730{
10731 IRExpr *op2 = load(Ity_F64, mkexpr(op2addr));
floriandb4fcaa2012-09-05 19:54:08 +000010732 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000010733
floriandb4fcaa2012-09-05 19:54:08 +000010734 put_fpr_dw0(r1, qop(Iop_MAddF64, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +000010735 get_fpr_dw0(r1), op2, get_fpr_dw0(r3)));
10736
10737 return "madb";
10738}
10739
10740static HChar *
10741s390_irgen_MSEBR(UChar r1, UChar r3, UChar r2)
10742{
floriandb4fcaa2012-09-05 19:54:08 +000010743 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_ROUND_PER_FPC);
florian847684d2012-09-05 04:19:09 +000010744
floriandb4fcaa2012-09-05 19:54:08 +000010745 put_fpr_w0(r1, qop(Iop_MSubF32, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +000010746 get_fpr_w0(r1), get_fpr_w0(r2), get_fpr_w0(r3)));
10747
10748 return "msebr";
10749}
10750
10751static HChar *
10752s390_irgen_MSDBR(UChar r1, UChar r3, UChar r2)
10753{
floriandb4fcaa2012-09-05 19:54:08 +000010754 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_ROUND_PER_FPC);
florian847684d2012-09-05 04:19:09 +000010755
floriandb4fcaa2012-09-05 19:54:08 +000010756 put_fpr_dw0(r1, qop(Iop_MSubF64, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +000010757 get_fpr_dw0(r1), get_fpr_dw0(r2), get_fpr_dw0(r3)));
10758
10759 return "msdbr";
10760}
10761
10762static HChar *
10763s390_irgen_MSEB(UChar r3, IRTemp op2addr, UChar r1)
10764{
10765 IRExpr *op2 = load(Ity_F32, mkexpr(op2addr));
floriandb4fcaa2012-09-05 19:54:08 +000010766 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000010767
floriandb4fcaa2012-09-05 19:54:08 +000010768 put_fpr_w0(r1, qop(Iop_MSubF32, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +000010769 get_fpr_w0(r1), op2, get_fpr_w0(r3)));
10770
10771 return "mseb";
10772}
10773
10774static HChar *
10775s390_irgen_MSDB(UChar r3, IRTemp op2addr, UChar r1)
10776{
10777 IRExpr *op2 = load(Ity_F64, mkexpr(op2addr));
floriandb4fcaa2012-09-05 19:54:08 +000010778 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000010779
floriandb4fcaa2012-09-05 19:54:08 +000010780 put_fpr_dw0(r1, qop(Iop_MSubF64, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +000010781 get_fpr_dw0(r1), op2, get_fpr_dw0(r3)));
10782
10783 return "msdb";
10784}
10785
10786static HChar *
10787s390_irgen_SQEBR(UChar r1, UChar r2)
10788{
10789 IRTemp result = newTemp(Ity_F32);
floriandb4fcaa2012-09-05 19:54:08 +000010790 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000010791
floriandb4fcaa2012-09-05 19:54:08 +000010792 assign(result, binop(Iop_SqrtF32, mkexpr(rounding_mode), get_fpr_w0(r2)));
sewardj2019a972011-03-07 16:04:07 +000010793 put_fpr_w0(r1, mkexpr(result));
10794
10795 return "sqebr";
10796}
10797
10798static HChar *
10799s390_irgen_SQDBR(UChar r1, UChar r2)
10800{
10801 IRTemp result = newTemp(Ity_F64);
floriandb4fcaa2012-09-05 19:54:08 +000010802 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000010803
floriandb4fcaa2012-09-05 19:54:08 +000010804 assign(result, binop(Iop_SqrtF64, mkexpr(rounding_mode), get_fpr_dw0(r2)));
sewardj2019a972011-03-07 16:04:07 +000010805 put_fpr_dw0(r1, mkexpr(result));
10806
10807 return "sqdbr";
10808}
10809
10810static HChar *
10811s390_irgen_SQXBR(UChar r1, UChar r2)
10812{
10813 IRTemp result = newTemp(Ity_F128);
floriandb4fcaa2012-09-05 19:54:08 +000010814 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000010815
floriandb4fcaa2012-09-05 19:54:08 +000010816 assign(result, binop(Iop_SqrtF128, mkexpr(rounding_mode),
10817 get_fpr_pair(r2)));
sewardj2019a972011-03-07 16:04:07 +000010818 put_fpr_pair(r1, mkexpr(result));
10819
10820 return "sqxbr";
10821}
10822
10823static HChar *
10824s390_irgen_SQEB(UChar r1, IRTemp op2addr)
10825{
10826 IRTemp op = newTemp(Ity_F32);
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
10829 assign(op, load(Ity_F32, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +000010830 put_fpr_w0(r1, binop(Iop_SqrtF32, mkexpr(rounding_mode), mkexpr(op)));
sewardj2019a972011-03-07 16:04:07 +000010831
10832 return "sqeb";
10833}
10834
10835static HChar *
10836s390_irgen_SQDB(UChar r1, IRTemp op2addr)
10837{
10838 IRTemp op = newTemp(Ity_F64);
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
10841 assign(op, load(Ity_F64, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +000010842 put_fpr_dw0(r1, binop(Iop_SqrtF64, mkexpr(rounding_mode), mkexpr(op)));
sewardj2019a972011-03-07 16:04:07 +000010843
10844 return "sqdb";
10845}
10846
10847static HChar *
10848s390_irgen_SXBR(UChar r1, UChar r2)
10849{
10850 IRTemp op1 = newTemp(Ity_F128);
10851 IRTemp op2 = newTemp(Ity_F128);
10852 IRTemp result = newTemp(Ity_F128);
floriandb4fcaa2012-09-05 19:54:08 +000010853 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000010854
10855 assign(op1, get_fpr_pair(r1));
10856 assign(op2, get_fpr_pair(r2));
floriandb4fcaa2012-09-05 19:54:08 +000010857 assign(result, triop(Iop_SubF128, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +000010858 mkexpr(op2)));
10859 put_fpr_pair(r1, mkexpr(result));
10860 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
10861
10862 return "sxbr";
10863}
10864
10865static HChar *
10866s390_irgen_TCEB(UChar r1, IRTemp op2addr)
10867{
10868 IRTemp value = newTemp(Ity_F32);
10869
10870 assign(value, get_fpr_w0(r1));
10871
10872 s390_cc_thunk_putFZ(S390_CC_OP_BFP_TDC_32, value, op2addr);
10873
10874 return "tceb";
10875}
10876
10877static HChar *
10878s390_irgen_TCDB(UChar r1, IRTemp op2addr)
10879{
10880 IRTemp value = newTemp(Ity_F64);
10881
10882 assign(value, get_fpr_dw0(r1));
10883
10884 s390_cc_thunk_putFZ(S390_CC_OP_BFP_TDC_64, value, op2addr);
10885
10886 return "tcdb";
10887}
10888
10889static HChar *
10890s390_irgen_TCXB(UChar r1, IRTemp op2addr)
10891{
10892 IRTemp value = newTemp(Ity_F128);
10893
10894 assign(value, get_fpr_pair(r1));
10895
10896 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_TDC_128, value, op2addr);
10897
10898 return "tcxb";
10899}
10900
10901static HChar *
10902s390_irgen_LCDFR(UChar r1, UChar r2)
10903{
10904 IRTemp result = newTemp(Ity_F64);
10905
10906 assign(result, unop(Iop_NegF64, get_fpr_dw0(r2)));
10907 put_fpr_dw0(r1, mkexpr(result));
10908
10909 return "lcdfr";
10910}
10911
10912static HChar *
10913s390_irgen_LNDFR(UChar r1, UChar r2)
10914{
10915 IRTemp result = newTemp(Ity_F64);
10916
10917 assign(result, unop(Iop_NegF64, unop(Iop_AbsF64, get_fpr_dw0(r2))));
10918 put_fpr_dw0(r1, mkexpr(result));
10919
10920 return "lndfr";
10921}
10922
10923static HChar *
10924s390_irgen_LPDFR(UChar r1, UChar r2)
10925{
10926 IRTemp result = newTemp(Ity_F64);
10927
10928 assign(result, unop(Iop_AbsF64, get_fpr_dw0(r2)));
10929 put_fpr_dw0(r1, mkexpr(result));
10930
10931 return "lpdfr";
10932}
10933
10934static HChar *
10935s390_irgen_LDGR(UChar r1, UChar r2)
10936{
10937 put_fpr_dw0(r1, unop(Iop_ReinterpI64asF64, get_gpr_dw0(r2)));
10938
10939 return "ldgr";
10940}
10941
10942static HChar *
10943s390_irgen_LGDR(UChar r1, UChar r2)
10944{
10945 put_gpr_dw0(r1, unop(Iop_ReinterpF64asI64, get_fpr_dw0(r2)));
10946
10947 return "lgdr";
10948}
10949
10950
10951static HChar *
10952s390_irgen_CPSDR(UChar r3, UChar r1, UChar r2)
10953{
10954 IRTemp sign = newTemp(Ity_I64);
10955 IRTemp value = newTemp(Ity_I64);
10956
10957 assign(sign, binop(Iop_And64, unop(Iop_ReinterpF64asI64, get_fpr_dw0(r3)),
10958 mkU64(1ULL << 63)));
10959 assign(value, binop(Iop_And64, unop(Iop_ReinterpF64asI64, get_fpr_dw0(r2)),
10960 mkU64((1ULL << 63) - 1)));
10961 put_fpr_dw0(r1, unop(Iop_ReinterpI64asF64, binop(Iop_Or64, mkexpr(value),
10962 mkexpr(sign))));
10963
10964 return "cpsdr";
10965}
10966
10967
sewardj2019a972011-03-07 16:04:07 +000010968static IRExpr *
10969s390_call_cvb(IRExpr *in)
10970{
10971 IRExpr **args, *call;
10972
10973 args = mkIRExprVec_1(in);
10974 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
10975 "s390_do_cvb", &s390_do_cvb, args);
10976
10977 /* Nothing is excluded from definedness checking. */
10978 call->Iex.CCall.cee->mcx_mask = 0;
10979
10980 return call;
10981}
10982
10983static HChar *
10984s390_irgen_CVB(UChar r1, IRTemp op2addr)
10985{
10986 put_gpr_w1(r1, s390_call_cvb(load(Ity_I64, mkexpr(op2addr))));
10987
10988 return "cvb";
10989}
10990
10991static HChar *
10992s390_irgen_CVBY(UChar r1, IRTemp op2addr)
10993{
10994 put_gpr_w1(r1, s390_call_cvb(load(Ity_I64, mkexpr(op2addr))));
10995
10996 return "cvby";
10997}
10998
10999
sewardj2019a972011-03-07 16:04:07 +000011000static IRExpr *
11001s390_call_cvd(IRExpr *in)
11002{
11003 IRExpr **args, *call;
11004
11005 args = mkIRExprVec_1(in);
11006 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
11007 "s390_do_cvd", &s390_do_cvd, args);
11008
11009 /* Nothing is excluded from definedness checking. */
11010 call->Iex.CCall.cee->mcx_mask = 0;
11011
11012 return call;
11013}
11014
11015static HChar *
11016s390_irgen_CVD(UChar r1, IRTemp op2addr)
11017{
florian11b8ee82012-08-06 13:35:33 +000011018 store(mkexpr(op2addr), s390_call_cvd(unop(Iop_32Uto64, get_gpr_w1(r1))));
sewardj2019a972011-03-07 16:04:07 +000011019
11020 return "cvd";
11021}
11022
11023static HChar *
11024s390_irgen_CVDY(UChar r1, IRTemp op2addr)
11025{
11026 store(mkexpr(op2addr), s390_call_cvd(get_gpr_w1(r1)));
11027
11028 return "cvdy";
11029}
11030
11031static HChar *
11032s390_irgen_FLOGR(UChar r1, UChar r2)
11033{
11034 IRTemp input = newTemp(Ity_I64);
11035 IRTemp not_zero = newTemp(Ity_I64);
11036 IRTemp tmpnum = newTemp(Ity_I64);
11037 IRTemp num = newTemp(Ity_I64);
11038 IRTemp shift_amount = newTemp(Ity_I8);
11039
11040 /* We use the "count leading zeroes" operator because the number of
11041 leading zeroes is identical with the bit position of the first '1' bit.
11042 However, that operator does not work when the input value is zero.
11043 Therefore, we set the LSB of the input value to 1 and use Clz64 on
11044 the modified value. If input == 0, then the result is 64. Otherwise,
11045 the result of Clz64 is what we want. */
11046
11047 assign(input, get_gpr_dw0(r2));
11048 assign(not_zero, binop(Iop_Or64, mkexpr(input), mkU64(1)));
11049 assign(tmpnum, unop(Iop_Clz64, mkexpr(not_zero)));
11050
11051 /* num = (input == 0) ? 64 : tmpnum */
11052 assign(num, mkite(binop(Iop_CmpEQ64, mkexpr(input), mkU64(0)),
11053 /* == 0 */ mkU64(64),
11054 /* != 0 */ mkexpr(tmpnum)));
11055
11056 put_gpr_dw0(r1, mkexpr(num));
11057
11058 /* Set the leftmost '1' bit of the input value to zero. The general scheme
11059 is to first shift the input value by NUM + 1 bits to the left which
11060 causes the leftmost '1' bit to disappear. Then we shift logically to
11061 the right by NUM + 1 bits. Because the semantics of Iop_Shl64 and
11062 Iop_Shr64 are undefined if the shift-amount is greater than or equal to
11063 the width of the value-to-be-shifted, we need to special case
11064 NUM + 1 >= 64. This is equivalent to INPUT != 0 && INPUT != 1.
11065 For both such INPUT values the result will be 0. */
11066
11067 assign(shift_amount, unop(Iop_64to8, binop(Iop_Add64, mkexpr(num),
11068 mkU64(1))));
11069
11070 put_gpr_dw0(r1 + 1,
florian6ad49522011-09-09 02:38:55 +000011071 mkite(binop(Iop_CmpLE64U, mkexpr(input), mkU64(1)),
11072 /* == 0 || == 1*/ mkU64(0),
11073 /* otherwise */
11074 binop(Iop_Shr64,
11075 binop(Iop_Shl64, mkexpr(input),
11076 mkexpr(shift_amount)),
11077 mkexpr(shift_amount))));
sewardj2019a972011-03-07 16:04:07 +000011078
11079 /* Compare the original value as an unsigned integer with 0. */
11080 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, input,
11081 mktemp(Ity_I64, mkU64(0)), False);
11082
11083 return "flogr";
11084}
11085
sewardj1e5fea62011-05-17 16:18:36 +000011086static HChar *
11087s390_irgen_STCK(IRTemp op2addr)
11088{
11089 IRDirty *d;
11090 IRTemp cc = newTemp(Ity_I64);
11091
11092 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STCK",
11093 &s390x_dirtyhelper_STCK,
11094 mkIRExprVec_1(mkexpr(op2addr)));
11095 d->mFx = Ifx_Write;
11096 d->mAddr = mkexpr(op2addr);
11097 d->mSize = 8;
11098 stmt(IRStmt_Dirty(d));
11099 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
11100 mkexpr(cc), mkU64(0), mkU64(0));
11101 return "stck";
11102}
11103
11104static HChar *
11105s390_irgen_STCKF(IRTemp op2addr)
11106{
florianc5c669b2012-08-26 14:32:28 +000011107 if (! s390_host_has_stckf) {
floriane75dafa2012-09-01 17:54:09 +000011108 emulation_failure(EmFail_S390X_stckf);
florianc5c669b2012-08-26 14:32:28 +000011109 } else {
11110 IRTemp cc = newTemp(Ity_I64);
sewardj1e5fea62011-05-17 16:18:36 +000011111
florianc5c669b2012-08-26 14:32:28 +000011112 IRDirty *d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STCKF",
11113 &s390x_dirtyhelper_STCKF,
11114 mkIRExprVec_1(mkexpr(op2addr)));
11115 d->mFx = Ifx_Write;
11116 d->mAddr = mkexpr(op2addr);
11117 d->mSize = 8;
11118 stmt(IRStmt_Dirty(d));
11119 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
11120 mkexpr(cc), mkU64(0), mkU64(0));
11121 }
sewardj1e5fea62011-05-17 16:18:36 +000011122 return "stckf";
11123}
11124
11125static HChar *
11126s390_irgen_STCKE(IRTemp op2addr)
11127{
11128 IRDirty *d;
11129 IRTemp cc = newTemp(Ity_I64);
11130
11131 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STCKE",
11132 &s390x_dirtyhelper_STCKE,
11133 mkIRExprVec_1(mkexpr(op2addr)));
11134 d->mFx = Ifx_Write;
11135 d->mAddr = mkexpr(op2addr);
11136 d->mSize = 16;
11137 stmt(IRStmt_Dirty(d));
11138 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
11139 mkexpr(cc), mkU64(0), mkU64(0));
11140 return "stcke";
11141}
11142
florian933065d2011-07-11 01:48:02 +000011143static HChar *
11144s390_irgen_STFLE(IRTemp op2addr)
11145{
florian4e0083e2012-08-26 03:41:56 +000011146 if (! s390_host_has_stfle) {
floriane75dafa2012-09-01 17:54:09 +000011147 emulation_failure(EmFail_S390X_stfle);
florian4e0083e2012-08-26 03:41:56 +000011148 return "stfle";
11149 }
11150
florian933065d2011-07-11 01:48:02 +000011151 IRDirty *d;
11152 IRTemp cc = newTemp(Ity_I64);
11153
11154 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STFLE",
11155 &s390x_dirtyhelper_STFLE,
11156 mkIRExprVec_1(mkexpr(op2addr)));
11157
11158 d->needsBBP = 1; /* Need to pass pointer to guest state to helper */
11159
sewardjc9069f22012-06-01 16:09:50 +000011160 d->nFxState = 1;
11161 vex_bzero(&d->fxState, sizeof(d->fxState));
11162
florian933065d2011-07-11 01:48:02 +000011163 d->fxState[0].fx = Ifx_Modify; /* read then write */
11164 d->fxState[0].offset = S390X_GUEST_OFFSET(guest_r0);
11165 d->fxState[0].size = sizeof(ULong);
florian933065d2011-07-11 01:48:02 +000011166
11167 d->mAddr = mkexpr(op2addr);
11168 /* Pretend all double words are written */
11169 d->mSize = S390_NUM_FACILITY_DW * sizeof(ULong);
11170 d->mFx = Ifx_Write;
11171
11172 stmt(IRStmt_Dirty(d));
11173
11174 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET), mkexpr(cc), mkU64(0), mkU64(0));
11175
11176 return "stfle";
11177}
11178
floriana4384a32011-08-11 16:58:45 +000011179static HChar *
11180s390_irgen_CKSM(UChar r1,UChar r2)
11181{
11182 IRTemp addr = newTemp(Ity_I64);
11183 IRTemp op = newTemp(Ity_I32);
11184 IRTemp len = newTemp(Ity_I64);
11185 IRTemp oldval = newTemp(Ity_I32);
11186 IRTemp mask = newTemp(Ity_I32);
11187 IRTemp newop = newTemp(Ity_I32);
11188 IRTemp result = newTemp(Ity_I32);
11189 IRTemp result1 = newTemp(Ity_I32);
11190 IRTemp inc = newTemp(Ity_I64);
11191
11192 assign(oldval, get_gpr_w1(r1));
11193 assign(addr, get_gpr_dw0(r2));
11194 assign(len, get_gpr_dw0(r2+1));
11195
11196 /* Condition code is always zero. */
11197 s390_cc_set(0);
11198
11199 /* If length is zero, there is no need to calculate the checksum */
florian6820ba52012-07-26 02:01:50 +000011200 next_insn_if(binop(Iop_CmpEQ64, mkexpr(len), mkU64(0)));
floriana4384a32011-08-11 16:58:45 +000011201
11202 /* Assiging the increment variable to adjust address and length
11203 later on. */
11204 assign(inc, mkite(binop(Iop_CmpLT64U, mkexpr(len), mkU64(4)),
11205 mkexpr(len), mkU64(4)));
11206
11207 /* If length < 4 the final 4-byte 2nd operand value is computed by
11208 appending the remaining bytes to the right with 0. This is done
11209 by AND'ing the 4 bytes loaded from memory with an appropriate
11210 mask. If length >= 4, that mask is simply 0xffffffff. */
11211
11212 assign(mask, mkite(binop(Iop_CmpLT64U, mkexpr(len), mkU64(4)),
11213 /* Mask computation when len < 4:
11214 0xffffffff << (32 - (len % 4)*8) */
11215 binop(Iop_Shl32, mkU32(0xffffffff),
11216 unop(Iop_32to8,
11217 binop(Iop_Sub32, mkU32(32),
11218 binop(Iop_Shl32,
11219 unop(Iop_64to32,
11220 binop(Iop_And64,
11221 mkexpr(len), mkU64(3))),
11222 mkU8(3))))),
11223 mkU32(0xffffffff)));
11224
11225 assign(op, load(Ity_I32, mkexpr(addr)));
11226 assign(newop, binop(Iop_And32, mkexpr(op), mkexpr(mask)));
11227 assign(result, binop(Iop_Add32, mkexpr(newop), mkexpr(oldval)));
11228
11229 /* Checking for carry */
11230 assign(result1, mkite(binop(Iop_CmpLT32U, mkexpr(result), mkexpr(newop)),
11231 binop(Iop_Add32, mkexpr(result), mkU32(1)),
11232 mkexpr(result)));
11233
11234 put_gpr_w1(r1, mkexpr(result1));
11235 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr), mkexpr(inc)));
11236 put_gpr_dw0(r2+1, binop(Iop_Sub64, mkexpr(len), mkexpr(inc)));
11237
florian6820ba52012-07-26 02:01:50 +000011238 iterate_if(binop(Iop_CmpNE64, mkexpr(len), mkU64(0)));
floriana4384a32011-08-11 16:58:45 +000011239
11240 return "cksm";
11241}
11242
florian9af37692012-01-15 21:01:16 +000011243static HChar *
11244s390_irgen_TROO(UChar m3, UChar r1, UChar r2)
11245{
11246 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
11247 src_addr = newTemp(Ity_I64);
11248 des_addr = newTemp(Ity_I64);
11249 tab_addr = newTemp(Ity_I64);
11250 test_byte = newTemp(Ity_I8);
11251 src_len = newTemp(Ity_I64);
11252
11253 assign(src_addr, get_gpr_dw0(r2));
11254 assign(des_addr, get_gpr_dw0(r1));
11255 assign(tab_addr, get_gpr_dw0(1));
florian53518532012-01-18 14:00:31 +000011256 assign(src_len, get_gpr_dw0(r1+1));
florian9af37692012-01-15 21:01:16 +000011257 assign(test_byte, get_gpr_b7(0));
11258
11259 IRTemp op = newTemp(Ity_I8);
11260 IRTemp op1 = newTemp(Ity_I8);
11261 IRTemp result = newTemp(Ity_I64);
11262
11263 /* End of source string? We're done; proceed to next insn */
11264 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000011265 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian9af37692012-01-15 21:01:16 +000011266
11267 /* Load character from source string, index translation table and
11268 store translated character in op1. */
11269 assign(op, load(Ity_I8, mkexpr(src_addr)));
11270
11271 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)),
11272 mkexpr(tab_addr)));
11273 assign(op1, load(Ity_I8, mkexpr(result)));
11274
11275 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
11276 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000011277 next_insn_if(binop(Iop_CmpEQ8, mkexpr(op1), mkexpr(test_byte)));
florian9af37692012-01-15 21:01:16 +000011278 }
11279 store(get_gpr_dw0(r1), mkexpr(op1));
11280
11281 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(1)));
11282 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(1)));
11283 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(1)));
11284
florian6820ba52012-07-26 02:01:50 +000011285 iterate();
florian9af37692012-01-15 21:01:16 +000011286
11287 return "troo";
11288}
11289
florian730448f2012-02-04 17:07:07 +000011290static HChar *
11291s390_irgen_TRTO(UChar m3, UChar r1, UChar r2)
11292{
11293 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
11294 src_addr = newTemp(Ity_I64);
11295 des_addr = newTemp(Ity_I64);
11296 tab_addr = newTemp(Ity_I64);
11297 test_byte = newTemp(Ity_I8);
11298 src_len = newTemp(Ity_I64);
11299
11300 assign(src_addr, get_gpr_dw0(r2));
11301 assign(des_addr, get_gpr_dw0(r1));
11302 assign(tab_addr, get_gpr_dw0(1));
11303 assign(src_len, get_gpr_dw0(r1+1));
11304 assign(test_byte, get_gpr_b7(0));
11305
11306 IRTemp op = newTemp(Ity_I16);
11307 IRTemp op1 = newTemp(Ity_I8);
11308 IRTemp result = newTemp(Ity_I64);
11309
11310 /* End of source string? We're done; proceed to next insn */
11311 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000011312 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian730448f2012-02-04 17:07:07 +000011313
11314 /* Load character from source string, index translation table and
11315 store translated character in op1. */
11316 assign(op, load(Ity_I16, mkexpr(src_addr)));
11317
11318 assign(result, binop(Iop_Add64, unop(Iop_16Uto64, mkexpr(op)),
11319 mkexpr(tab_addr)));
11320
11321 assign(op1, load(Ity_I8, mkexpr(result)));
11322
11323 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
11324 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000011325 next_insn_if(binop(Iop_CmpEQ8, mkexpr(op1), mkexpr(test_byte)));
florian730448f2012-02-04 17:07:07 +000011326 }
11327 store(get_gpr_dw0(r1), mkexpr(op1));
11328
11329 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(2)));
11330 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(1)));
11331 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(2)));
11332
florian6820ba52012-07-26 02:01:50 +000011333 iterate();
florian730448f2012-02-04 17:07:07 +000011334
11335 return "trto";
11336}
11337
11338static HChar *
11339s390_irgen_TROT(UChar m3, UChar r1, UChar r2)
11340{
11341 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
11342 src_addr = newTemp(Ity_I64);
11343 des_addr = newTemp(Ity_I64);
11344 tab_addr = newTemp(Ity_I64);
11345 test_byte = newTemp(Ity_I16);
11346 src_len = newTemp(Ity_I64);
11347
11348 assign(src_addr, get_gpr_dw0(r2));
11349 assign(des_addr, get_gpr_dw0(r1));
11350 assign(tab_addr, get_gpr_dw0(1));
11351 assign(src_len, get_gpr_dw0(r1+1));
11352 assign(test_byte, get_gpr_hw3(0));
11353
11354 IRTemp op = newTemp(Ity_I8);
11355 IRTemp op1 = newTemp(Ity_I16);
11356 IRTemp result = newTemp(Ity_I64);
11357
11358 /* End of source string? We're done; proceed to next insn */
11359 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000011360 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian730448f2012-02-04 17:07:07 +000011361
11362 /* Load character from source string, index translation table and
11363 store translated character in op1. */
11364 assign(op, binop(Iop_Shl8, load(Ity_I8, mkexpr(src_addr)), mkU8(1)));
11365
11366 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)),
11367 mkexpr(tab_addr)));
11368 assign(op1, load(Ity_I16, mkexpr(result)));
11369
11370 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
11371 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000011372 next_insn_if(binop(Iop_CmpEQ16, mkexpr(op1), mkexpr(test_byte)));
florian730448f2012-02-04 17:07:07 +000011373 }
11374 store(get_gpr_dw0(r1), mkexpr(op1));
11375
11376 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(1)));
11377 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(2)));
11378 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(1)));
11379
florian6820ba52012-07-26 02:01:50 +000011380 iterate();
florian730448f2012-02-04 17:07:07 +000011381
11382 return "trot";
11383}
11384
11385static HChar *
11386s390_irgen_TRTT(UChar m3, UChar r1, UChar r2)
11387{
11388 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
11389 src_addr = newTemp(Ity_I64);
11390 des_addr = newTemp(Ity_I64);
11391 tab_addr = newTemp(Ity_I64);
11392 test_byte = newTemp(Ity_I16);
11393 src_len = newTemp(Ity_I64);
11394
11395 assign(src_addr, get_gpr_dw0(r2));
11396 assign(des_addr, get_gpr_dw0(r1));
11397 assign(tab_addr, get_gpr_dw0(1));
11398 assign(src_len, get_gpr_dw0(r1+1));
11399 assign(test_byte, get_gpr_hw3(0));
11400
11401 IRTemp op = newTemp(Ity_I16);
11402 IRTemp op1 = newTemp(Ity_I16);
11403 IRTemp result = newTemp(Ity_I64);
11404
11405 /* End of source string? We're done; proceed to next insn */
11406 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000011407 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian730448f2012-02-04 17:07:07 +000011408
11409 /* Load character from source string, index translation table and
11410 store translated character in op1. */
11411 assign(op, binop(Iop_Shl16, load(Ity_I16, mkexpr(src_addr)), mkU8(1)));
11412
11413 assign(result, binop(Iop_Add64, unop(Iop_16Uto64, mkexpr(op)),
11414 mkexpr(tab_addr)));
11415 assign(op1, load(Ity_I16, mkexpr(result)));
11416
11417 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
11418 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000011419 next_insn_if(binop(Iop_CmpEQ16, mkexpr(op1), mkexpr(test_byte)));
florian730448f2012-02-04 17:07:07 +000011420 }
11421
11422 store(get_gpr_dw0(r1), mkexpr(op1));
11423
11424 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(2)));
11425 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(2)));
11426 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(2)));
11427
florian6820ba52012-07-26 02:01:50 +000011428 iterate();
florian730448f2012-02-04 17:07:07 +000011429
11430 return "trtt";
11431}
11432
11433static HChar *
11434s390_irgen_TR(UChar length, IRTemp start1, IRTemp start2)
11435{
florianf87d4fb2012-05-05 02:55:24 +000011436 IRTemp len = newTemp(Ity_I64);
florian730448f2012-02-04 17:07:07 +000011437
florianf87d4fb2012-05-05 02:55:24 +000011438 assign(len, mkU64(length));
11439 s390_irgen_TR_EX(len, start1, start2);
florian730448f2012-02-04 17:07:07 +000011440
11441 return "tr";
11442}
11443
11444static HChar *
11445s390_irgen_TRE(UChar r1,UChar r2)
11446{
11447 IRTemp src_addr, tab_addr, src_len, test_byte;
11448 src_addr = newTemp(Ity_I64);
11449 tab_addr = newTemp(Ity_I64);
11450 src_len = newTemp(Ity_I64);
11451 test_byte = newTemp(Ity_I8);
11452
11453 assign(src_addr, get_gpr_dw0(r1));
11454 assign(src_len, get_gpr_dw0(r1+1));
11455 assign(tab_addr, get_gpr_dw0(r2));
11456 assign(test_byte, get_gpr_b7(0));
11457
11458 IRTemp op = newTemp(Ity_I8);
11459 IRTemp op1 = newTemp(Ity_I8);
11460 IRTemp result = newTemp(Ity_I64);
11461
11462 /* End of source string? We're done; proceed to next insn */
11463 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000011464 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian730448f2012-02-04 17:07:07 +000011465
11466 /* Load character from source string and compare with test byte */
11467 assign(op, load(Ity_I8, mkexpr(src_addr)));
11468
11469 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000011470 next_insn_if(binop(Iop_CmpEQ8, mkexpr(op), mkexpr(test_byte)));
florian730448f2012-02-04 17:07:07 +000011471
11472 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)),
11473 mkexpr(tab_addr)));
11474
11475 assign(op1, load(Ity_I8, mkexpr(result)));
11476
11477 store(get_gpr_dw0(r1), mkexpr(op1));
11478 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(src_addr), mkU64(1)));
11479 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(1)));
11480
florian6820ba52012-07-26 02:01:50 +000011481 iterate();
florian730448f2012-02-04 17:07:07 +000011482
11483 return "tre";
11484}
11485
floriana0100c92012-07-20 00:06:35 +000011486static IRExpr *
11487s390_call_cu21(IRExpr *srcval, IRExpr *low_surrogate)
11488{
11489 IRExpr **args, *call;
11490 args = mkIRExprVec_2(srcval, low_surrogate);
11491 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
11492 "s390_do_cu21", &s390_do_cu21, args);
11493
11494 /* Nothing is excluded from definedness checking. */
11495 call->Iex.CCall.cee->mcx_mask = 0;
11496
11497 return call;
11498}
11499
11500static HChar *
11501s390_irgen_CU21(UChar m3, UChar r1, UChar r2)
11502{
11503 IRTemp addr1 = newTemp(Ity_I64);
11504 IRTemp addr2 = newTemp(Ity_I64);
11505 IRTemp len1 = newTemp(Ity_I64);
11506 IRTemp len2 = newTemp(Ity_I64);
11507
11508 assign(addr1, get_gpr_dw0(r1));
11509 assign(addr2, get_gpr_dw0(r2));
11510 assign(len1, get_gpr_dw0(r1 + 1));
11511 assign(len2, get_gpr_dw0(r2 + 1));
11512
11513 /* We're processing the 2nd operand 2 bytes at a time. Therefore, if
11514 there are less than 2 bytes left, then the 2nd operand is exhausted
11515 and we're done here. cc = 0 */
11516 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000011517 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(2)));
floriana0100c92012-07-20 00:06:35 +000011518
11519 /* There are at least two bytes there. Read them. */
11520 IRTemp srcval = newTemp(Ity_I32);
11521 assign(srcval, unop(Iop_16Uto32, load(Ity_I16, mkexpr(addr2))));
11522
11523 /* Find out whether this is a high surrogate. I.e. SRCVAL lies
11524 inside the interval [0xd800 - 0xdbff] */
11525 IRTemp is_high_surrogate = newTemp(Ity_I32);
11526 IRExpr *flag1 = mkite(binop(Iop_CmpLE32U, mkU32(0xd800), mkexpr(srcval)),
11527 mkU32(1), mkU32(0));
11528 IRExpr *flag2 = mkite(binop(Iop_CmpLE32U, mkexpr(srcval), mkU32(0xdbff)),
11529 mkU32(1), mkU32(0));
11530 assign(is_high_surrogate, binop(Iop_And32, flag1, flag2));
11531
11532 /* If SRCVAL is a high surrogate and there are less than 4 bytes left,
11533 then the 2nd operand is exhausted and we're done here. cc = 0 */
11534 IRExpr *not_enough_bytes =
11535 mkite(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)), mkU32(1), mkU32(0));
11536
florian6820ba52012-07-26 02:01:50 +000011537 next_insn_if(binop(Iop_CmpEQ32,
11538 binop(Iop_And32, mkexpr(is_high_surrogate),
11539 not_enough_bytes), mkU32(1)));
floriana0100c92012-07-20 00:06:35 +000011540
11541 /* The 2nd operand is not exhausted. If the first 2 bytes are a high
11542 surrogate, read the next two bytes (low surrogate). */
11543 IRTemp low_surrogate = newTemp(Ity_I32);
11544 IRExpr *low_surrogate_addr = binop(Iop_Add64, mkexpr(addr2), mkU64(2));
11545
11546 assign(low_surrogate,
11547 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
11548 unop(Iop_16Uto32, load(Ity_I16, low_surrogate_addr)),
11549 mkU32(0))); // any value is fine; it will not be used
11550
11551 /* Call the helper */
11552 IRTemp retval = newTemp(Ity_I64);
florian11b8ee82012-08-06 13:35:33 +000011553 assign(retval, s390_call_cu21(unop(Iop_32Uto64, mkexpr(srcval)),
11554 unop(Iop_32Uto64, mkexpr(low_surrogate))));
floriana0100c92012-07-20 00:06:35 +000011555
11556 /* Before we can test whether the 1st operand is exhausted we need to
11557 test for an invalid low surrogate. Because cc=2 outranks cc=1. */
11558 if (s390_host_has_etf3 && (m3 & 0x1) == 1) {
11559 IRExpr *invalid_low_surrogate =
11560 binop(Iop_And64, mkexpr(retval), mkU64(0xff));
11561
11562 s390_cc_set(2);
florian6820ba52012-07-26 02:01:50 +000011563 next_insn_if(binop(Iop_CmpEQ64, invalid_low_surrogate, mkU64(1)));
floriana0100c92012-07-20 00:06:35 +000011564 }
11565
11566 /* Now test whether the 1st operand is exhausted */
11567 IRTemp num_bytes = newTemp(Ity_I64);
11568 assign(num_bytes, binop(Iop_And64,
11569 binop(Iop_Shr64, mkexpr(retval), mkU8(8)),
11570 mkU64(0xff)));
11571 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000011572 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
floriana0100c92012-07-20 00:06:35 +000011573
11574 /* Extract the bytes to be stored at addr1 */
11575 IRTemp data = newTemp(Ity_I64);
11576 assign(data, binop(Iop_Shr64, mkexpr(retval), mkU8(16)));
11577
11578 /* To store the bytes construct 4 dirty helper calls. The helper calls
11579 are guarded (num_bytes == 1, num_bytes == 2, etc) such that only
11580 one of them will be called at runtime. */
11581 int i;
11582 for (i = 1; i <= 4; ++i) {
11583 IRDirty *d;
11584
11585 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
11586 &s390x_dirtyhelper_CUxy,
11587 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
11588 mkexpr(num_bytes)));
11589 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
11590 d->mFx = Ifx_Write;
11591 d->mAddr = mkexpr(addr1);
11592 d->mSize = i;
11593 stmt(IRStmt_Dirty(d));
11594 }
11595
11596 /* Update source address and length */
11597 IRTemp num_src_bytes = newTemp(Ity_I64);
11598 assign(num_src_bytes,
11599 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
11600 mkU64(4), mkU64(2)));
11601 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkexpr(num_src_bytes)));
11602 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkexpr(num_src_bytes)));
11603
11604 /* Update destination address and length */
11605 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
11606 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
11607
florian6820ba52012-07-26 02:01:50 +000011608 iterate();
floriana0100c92012-07-20 00:06:35 +000011609
11610 return "cu21";
11611}
11612
florian2a415a12012-07-21 17:41:36 +000011613static IRExpr *
11614s390_call_cu24(IRExpr *srcval, IRExpr *low_surrogate)
11615{
11616 IRExpr **args, *call;
11617 args = mkIRExprVec_2(srcval, low_surrogate);
11618 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
11619 "s390_do_cu24", &s390_do_cu24, args);
11620
11621 /* Nothing is excluded from definedness checking. */
11622 call->Iex.CCall.cee->mcx_mask = 0;
11623
11624 return call;
11625}
11626
11627static HChar *
11628s390_irgen_CU24(UChar m3, UChar r1, UChar r2)
11629{
11630 IRTemp addr1 = newTemp(Ity_I64);
11631 IRTemp addr2 = newTemp(Ity_I64);
11632 IRTemp len1 = newTemp(Ity_I64);
11633 IRTemp len2 = newTemp(Ity_I64);
11634
11635 assign(addr1, get_gpr_dw0(r1));
11636 assign(addr2, get_gpr_dw0(r2));
11637 assign(len1, get_gpr_dw0(r1 + 1));
11638 assign(len2, get_gpr_dw0(r2 + 1));
11639
11640 /* We're processing the 2nd operand 2 bytes at a time. Therefore, if
11641 there are less than 2 bytes left, then the 2nd operand is exhausted
11642 and we're done here. cc = 0 */
11643 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000011644 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(2)));
florian2a415a12012-07-21 17:41:36 +000011645
11646 /* There are at least two bytes there. Read them. */
11647 IRTemp srcval = newTemp(Ity_I32);
11648 assign(srcval, unop(Iop_16Uto32, load(Ity_I16, mkexpr(addr2))));
11649
11650 /* Find out whether this is a high surrogate. I.e. SRCVAL lies
11651 inside the interval [0xd800 - 0xdbff] */
11652 IRTemp is_high_surrogate = newTemp(Ity_I32);
11653 IRExpr *flag1 = mkite(binop(Iop_CmpLE32U, mkU32(0xd800), mkexpr(srcval)),
11654 mkU32(1), mkU32(0));
11655 IRExpr *flag2 = mkite(binop(Iop_CmpLE32U, mkexpr(srcval), mkU32(0xdbff)),
11656 mkU32(1), mkU32(0));
11657 assign(is_high_surrogate, binop(Iop_And32, flag1, flag2));
11658
11659 /* If SRCVAL is a high surrogate and there are less than 4 bytes left,
11660 then the 2nd operand is exhausted and we're done here. cc = 0 */
11661 IRExpr *not_enough_bytes =
11662 mkite(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)), mkU32(1), mkU32(0));
11663
florian6820ba52012-07-26 02:01:50 +000011664 next_insn_if(binop(Iop_CmpEQ32,
11665 binop(Iop_And32, mkexpr(is_high_surrogate),
11666 not_enough_bytes),
11667 mkU32(1)));
florian2a415a12012-07-21 17:41:36 +000011668
11669 /* The 2nd operand is not exhausted. If the first 2 bytes are a high
11670 surrogate, read the next two bytes (low surrogate). */
11671 IRTemp low_surrogate = newTemp(Ity_I32);
11672 IRExpr *low_surrogate_addr = binop(Iop_Add64, mkexpr(addr2), mkU64(2));
11673
11674 assign(low_surrogate,
11675 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
11676 unop(Iop_16Uto32, load(Ity_I16, low_surrogate_addr)),
11677 mkU32(0))); // any value is fine; it will not be used
11678
11679 /* Call the helper */
11680 IRTemp retval = newTemp(Ity_I64);
florian11b8ee82012-08-06 13:35:33 +000011681 assign(retval, s390_call_cu24(unop(Iop_32Uto64, mkexpr(srcval)),
11682 unop(Iop_32Uto64, mkexpr(low_surrogate))));
florian2a415a12012-07-21 17:41:36 +000011683
11684 /* Before we can test whether the 1st operand is exhausted we need to
11685 test for an invalid low surrogate. Because cc=2 outranks cc=1. */
11686 if (s390_host_has_etf3 && (m3 & 0x1) == 1) {
11687 IRExpr *invalid_low_surrogate =
11688 binop(Iop_And64, mkexpr(retval), mkU64(0xff));
11689
11690 s390_cc_set(2);
florian6820ba52012-07-26 02:01:50 +000011691 next_insn_if(binop(Iop_CmpEQ64, invalid_low_surrogate, mkU64(1)));
florian2a415a12012-07-21 17:41:36 +000011692 }
11693
11694 /* Now test whether the 1st operand is exhausted */
11695 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000011696 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkU64(4)));
florian2a415a12012-07-21 17:41:36 +000011697
11698 /* Extract the bytes to be stored at addr1 */
11699 IRExpr *data = unop(Iop_64to32, binop(Iop_Shr64, mkexpr(retval), mkU8(8)));
11700
11701 store(mkexpr(addr1), data);
11702
11703 /* Update source address and length */
11704 IRTemp num_src_bytes = newTemp(Ity_I64);
11705 assign(num_src_bytes,
11706 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
11707 mkU64(4), mkU64(2)));
11708 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkexpr(num_src_bytes)));
11709 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkexpr(num_src_bytes)));
11710
11711 /* Update destination address and length */
11712 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkU64(4)));
11713 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkU64(4)));
11714
florian6820ba52012-07-26 02:01:50 +000011715 iterate();
florian2a415a12012-07-21 17:41:36 +000011716
11717 return "cu24";
11718}
floriana4384a32011-08-11 16:58:45 +000011719
florian956194b2012-07-28 22:18:32 +000011720static IRExpr *
11721s390_call_cu42(IRExpr *srcval)
11722{
11723 IRExpr **args, *call;
11724 args = mkIRExprVec_1(srcval);
11725 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
11726 "s390_do_cu42", &s390_do_cu42, args);
11727
11728 /* Nothing is excluded from definedness checking. */
11729 call->Iex.CCall.cee->mcx_mask = 0;
11730
11731 return call;
11732}
11733
11734static HChar *
11735s390_irgen_CU42(UChar r1, UChar r2)
11736{
11737 IRTemp addr1 = newTemp(Ity_I64);
11738 IRTemp addr2 = newTemp(Ity_I64);
11739 IRTemp len1 = newTemp(Ity_I64);
11740 IRTemp len2 = newTemp(Ity_I64);
11741
11742 assign(addr1, get_gpr_dw0(r1));
11743 assign(addr2, get_gpr_dw0(r2));
11744 assign(len1, get_gpr_dw0(r1 + 1));
11745 assign(len2, get_gpr_dw0(r2 + 1));
11746
11747 /* We're processing the 2nd operand 4 bytes at a time. Therefore, if
11748 there are less than 4 bytes left, then the 2nd operand is exhausted
11749 and we're done here. cc = 0 */
11750 s390_cc_set(0);
11751 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)));
11752
11753 /* Read the 2nd operand. */
11754 IRTemp srcval = newTemp(Ity_I32);
11755 assign(srcval, load(Ity_I32, mkexpr(addr2)));
11756
11757 /* Call the helper */
11758 IRTemp retval = newTemp(Ity_I64);
florian11b8ee82012-08-06 13:35:33 +000011759 assign(retval, s390_call_cu42(unop(Iop_32Uto64, mkexpr(srcval))));
florian956194b2012-07-28 22:18:32 +000011760
11761 /* If the UTF-32 character was invalid, set cc=2 and we're done.
11762 cc=2 outranks cc=1 (1st operand exhausted) */
11763 IRExpr *invalid_character = binop(Iop_And64, mkexpr(retval), mkU64(0xff));
11764
11765 s390_cc_set(2);
11766 next_insn_if(binop(Iop_CmpEQ64, invalid_character, mkU64(1)));
11767
11768 /* Now test whether the 1st operand is exhausted */
11769 IRTemp num_bytes = newTemp(Ity_I64);
11770 assign(num_bytes, binop(Iop_And64,
11771 binop(Iop_Shr64, mkexpr(retval), mkU8(8)),
11772 mkU64(0xff)));
11773 s390_cc_set(1);
11774 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
11775
11776 /* Extract the bytes to be stored at addr1 */
11777 IRTemp data = newTemp(Ity_I64);
11778 assign(data, binop(Iop_Shr64, mkexpr(retval), mkU8(16)));
11779
11780 /* To store the bytes construct 2 dirty helper calls. The helper calls
11781 are guarded (num_bytes == 2 and num_bytes == 4, respectively) such
11782 that only one of them will be called at runtime. */
11783
11784 Int i;
11785 for (i = 2; i <= 4; ++i) {
11786 IRDirty *d;
11787
11788 if (i == 3) continue; // skip this one
11789
11790 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
11791 &s390x_dirtyhelper_CUxy,
11792 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
11793 mkexpr(num_bytes)));
11794 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
11795 d->mFx = Ifx_Write;
11796 d->mAddr = mkexpr(addr1);
11797 d->mSize = i;
11798 stmt(IRStmt_Dirty(d));
11799 }
11800
11801 /* Update source address and length */
11802 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkU64(4)));
11803 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkU64(4)));
11804
11805 /* Update destination address and length */
11806 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
11807 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
11808
11809 iterate();
11810
11811 return "cu42";
11812}
11813
florian6d9b9b22012-08-03 18:35:39 +000011814static IRExpr *
florianaf2194f2012-08-06 00:07:54 +000011815s390_call_cu41(IRExpr *srcval)
11816{
11817 IRExpr **args, *call;
11818 args = mkIRExprVec_1(srcval);
11819 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
11820 "s390_do_cu41", &s390_do_cu41, args);
11821
11822 /* Nothing is excluded from definedness checking. */
11823 call->Iex.CCall.cee->mcx_mask = 0;
11824
11825 return call;
11826}
11827
11828static HChar *
11829s390_irgen_CU41(UChar r1, UChar r2)
11830{
11831 IRTemp addr1 = newTemp(Ity_I64);
11832 IRTemp addr2 = newTemp(Ity_I64);
11833 IRTemp len1 = newTemp(Ity_I64);
11834 IRTemp len2 = newTemp(Ity_I64);
11835
11836 assign(addr1, get_gpr_dw0(r1));
11837 assign(addr2, get_gpr_dw0(r2));
11838 assign(len1, get_gpr_dw0(r1 + 1));
11839 assign(len2, get_gpr_dw0(r2 + 1));
11840
11841 /* We're processing the 2nd operand 4 bytes at a time. Therefore, if
11842 there are less than 4 bytes left, then the 2nd operand is exhausted
11843 and we're done here. cc = 0 */
11844 s390_cc_set(0);
11845 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)));
11846
11847 /* Read the 2nd operand. */
11848 IRTemp srcval = newTemp(Ity_I32);
11849 assign(srcval, load(Ity_I32, mkexpr(addr2)));
11850
11851 /* Call the helper */
11852 IRTemp retval = newTemp(Ity_I64);
florian11b8ee82012-08-06 13:35:33 +000011853 assign(retval, s390_call_cu41(unop(Iop_32Uto64, mkexpr(srcval))));
florianaf2194f2012-08-06 00:07:54 +000011854
11855 /* If the UTF-32 character was invalid, set cc=2 and we're done.
11856 cc=2 outranks cc=1 (1st operand exhausted) */
11857 IRExpr *invalid_character = binop(Iop_And64, mkexpr(retval), mkU64(0xff));
11858
11859 s390_cc_set(2);
11860 next_insn_if(binop(Iop_CmpEQ64, invalid_character, mkU64(1)));
11861
11862 /* Now test whether the 1st operand is exhausted */
11863 IRTemp num_bytes = newTemp(Ity_I64);
11864 assign(num_bytes, binop(Iop_And64,
11865 binop(Iop_Shr64, mkexpr(retval), mkU8(8)),
11866 mkU64(0xff)));
11867 s390_cc_set(1);
11868 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
11869
11870 /* Extract the bytes to be stored at addr1 */
11871 IRTemp data = newTemp(Ity_I64);
11872 assign(data, binop(Iop_Shr64, mkexpr(retval), mkU8(16)));
11873
11874 /* To store the bytes construct 4 dirty helper calls. The helper calls
11875 are guarded (num_bytes == 1, num_bytes == 2, etc) such that only
11876 one of them will be called at runtime. */
11877 int i;
11878 for (i = 1; i <= 4; ++i) {
11879 IRDirty *d;
11880
11881 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
11882 &s390x_dirtyhelper_CUxy,
11883 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
11884 mkexpr(num_bytes)));
11885 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
11886 d->mFx = Ifx_Write;
11887 d->mAddr = mkexpr(addr1);
11888 d->mSize = i;
11889 stmt(IRStmt_Dirty(d));
11890 }
11891
11892 /* Update source address and length */
11893 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkU64(4)));
11894 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkU64(4)));
11895
11896 /* Update destination address and length */
11897 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
11898 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
11899
11900 iterate();
11901
11902 return "cu41";
11903}
11904
11905static IRExpr *
florian3f8a96a2012-08-05 02:59:55 +000011906s390_call_cu12_cu14_helper1(IRExpr *byte1, IRExpr *etf3_and_m3_is_1)
florian6d9b9b22012-08-03 18:35:39 +000011907{
11908 IRExpr **args, *call;
11909 args = mkIRExprVec_2(byte1, etf3_and_m3_is_1);
florian3f8a96a2012-08-05 02:59:55 +000011910 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/, "s390_do_cu12_cu14_helper1",
11911 &s390_do_cu12_cu14_helper1, args);
florian6d9b9b22012-08-03 18:35:39 +000011912
11913 /* Nothing is excluded from definedness checking. */
11914 call->Iex.CCall.cee->mcx_mask = 0;
11915
11916 return call;
11917}
11918
11919static IRExpr *
11920s390_call_cu12_helper2(IRExpr *byte1, IRExpr *byte2, IRExpr *byte3,
11921 IRExpr *byte4, IRExpr *stuff)
11922{
11923 IRExpr **args, *call;
11924 args = mkIRExprVec_5(byte1, byte2, byte3, byte4, stuff);
11925 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
11926 "s390_do_cu12_helper2", &s390_do_cu12_helper2, args);
11927
11928 /* Nothing is excluded from definedness checking. */
11929 call->Iex.CCall.cee->mcx_mask = 0;
11930
11931 return call;
11932}
11933
florian3f8a96a2012-08-05 02:59:55 +000011934static IRExpr *
11935s390_call_cu14_helper2(IRExpr *byte1, IRExpr *byte2, IRExpr *byte3,
11936 IRExpr *byte4, IRExpr *stuff)
11937{
11938 IRExpr **args, *call;
11939 args = mkIRExprVec_5(byte1, byte2, byte3, byte4, stuff);
11940 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
11941 "s390_do_cu14_helper2", &s390_do_cu14_helper2, args);
11942
11943 /* Nothing is excluded from definedness checking. */
11944 call->Iex.CCall.cee->mcx_mask = 0;
11945
11946 return call;
11947}
11948
11949static void
11950s390_irgen_cu12_cu14(UChar m3, UChar r1, UChar r2, Bool is_cu12)
florian6d9b9b22012-08-03 18:35:39 +000011951{
11952 IRTemp addr1 = newTemp(Ity_I64);
11953 IRTemp addr2 = newTemp(Ity_I64);
11954 IRTemp len1 = newTemp(Ity_I64);
11955 IRTemp len2 = newTemp(Ity_I64);
11956
11957 assign(addr1, get_gpr_dw0(r1));
11958 assign(addr2, get_gpr_dw0(r2));
11959 assign(len1, get_gpr_dw0(r1 + 1));
11960 assign(len2, get_gpr_dw0(r2 + 1));
11961
11962 UInt extended_checking = s390_host_has_etf3 && (m3 & 0x1) == 1;
11963
11964 /* We're processing the 2nd operand 1 byte at a time. Therefore, if
11965 there is less than 1 byte left, then the 2nd operand is exhausted
11966 and we're done here. cc = 0 */
11967 s390_cc_set(0);
11968 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(1)));
11969
11970 /* There is at least one byte there. Read it. */
florian11b8ee82012-08-06 13:35:33 +000011971 IRTemp byte1 = newTemp(Ity_I64);
11972 assign(byte1, unop(Iop_8Uto64, load(Ity_I8, mkexpr(addr2))));
florian6d9b9b22012-08-03 18:35:39 +000011973
11974 /* Call the helper to get number of bytes and invalid byte indicator */
11975 IRTemp retval1 = newTemp(Ity_I64);
florian3f8a96a2012-08-05 02:59:55 +000011976 assign(retval1, s390_call_cu12_cu14_helper1(mkexpr(byte1),
florian11b8ee82012-08-06 13:35:33 +000011977 mkU64(extended_checking)));
florian6d9b9b22012-08-03 18:35:39 +000011978
11979 /* Check for invalid 1st byte */
11980 IRExpr *is_invalid = unop(Iop_64to1, mkexpr(retval1));
11981 s390_cc_set(2);
11982 next_insn_if(is_invalid);
11983
11984 /* How many bytes do we have to read? */
11985 IRTemp num_src_bytes = newTemp(Ity_I64);
11986 assign(num_src_bytes, binop(Iop_Shr64, mkexpr(retval1), mkU8(8)));
11987
11988 /* Now test whether the 2nd operand is exhausted */
11989 s390_cc_set(0);
11990 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkexpr(num_src_bytes)));
11991
11992 /* Read the remaining bytes */
11993 IRExpr *cond, *addr, *byte2, *byte3, *byte4;
11994
11995 cond = binop(Iop_CmpLE64U, mkU64(2), mkexpr(num_src_bytes));
11996 addr = binop(Iop_Add64, mkexpr(addr2), mkU64(1));
florian11b8ee82012-08-06 13:35:33 +000011997 byte2 = mkite(cond, unop(Iop_8Uto64, load(Ity_I8, addr)), mkU64(0));
florian6d9b9b22012-08-03 18:35:39 +000011998 cond = binop(Iop_CmpLE64U, mkU64(3), mkexpr(num_src_bytes));
11999 addr = binop(Iop_Add64, mkexpr(addr2), mkU64(2));
florian11b8ee82012-08-06 13:35:33 +000012000 byte3 = mkite(cond, unop(Iop_8Uto64, load(Ity_I8, addr)), mkU64(0));
florian6d9b9b22012-08-03 18:35:39 +000012001 cond = binop(Iop_CmpLE64U, mkU64(4), mkexpr(num_src_bytes));
12002 addr = binop(Iop_Add64, mkexpr(addr2), mkU64(3));
florian11b8ee82012-08-06 13:35:33 +000012003 byte4 = mkite(cond, unop(Iop_8Uto64, load(Ity_I8, addr)), mkU64(0));
florian6d9b9b22012-08-03 18:35:39 +000012004
12005 /* Call the helper to get the converted value and invalid byte indicator.
12006 We can pass at most 5 arguments; therefore some encoding is needed
12007 here */
12008 IRExpr *stuff = binop(Iop_Or64,
12009 binop(Iop_Shl64, mkexpr(num_src_bytes), mkU8(1)),
12010 mkU64(extended_checking));
12011 IRTemp retval2 = newTemp(Ity_I64);
florian3f8a96a2012-08-05 02:59:55 +000012012
12013 if (is_cu12) {
12014 assign(retval2, s390_call_cu12_helper2(mkexpr(byte1), byte2, byte3,
12015 byte4, stuff));
12016 } else {
12017 assign(retval2, s390_call_cu14_helper2(mkexpr(byte1), byte2, byte3,
12018 byte4, stuff));
12019 }
florian6d9b9b22012-08-03 18:35:39 +000012020
12021 /* Check for invalid character */
12022 s390_cc_set(2);
12023 is_invalid = unop(Iop_64to1, mkexpr(retval2));
12024 next_insn_if(is_invalid);
12025
12026 /* Now test whether the 1st operand is exhausted */
12027 IRTemp num_bytes = newTemp(Ity_I64);
12028 assign(num_bytes, binop(Iop_And64,
12029 binop(Iop_Shr64, mkexpr(retval2), mkU8(8)),
12030 mkU64(0xff)));
12031 s390_cc_set(1);
12032 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
12033
12034 /* Extract the bytes to be stored at addr1 */
12035 IRTemp data = newTemp(Ity_I64);
12036 assign(data, binop(Iop_Shr64, mkexpr(retval2), mkU8(16)));
12037
florian3f8a96a2012-08-05 02:59:55 +000012038 if (is_cu12) {
12039 /* To store the bytes construct 2 dirty helper calls. The helper calls
12040 are guarded (num_bytes == 2 and num_bytes == 4, respectively) such
12041 that only one of them will be called at runtime. */
florian6d9b9b22012-08-03 18:35:39 +000012042
florian3f8a96a2012-08-05 02:59:55 +000012043 Int i;
12044 for (i = 2; i <= 4; ++i) {
12045 IRDirty *d;
florian6d9b9b22012-08-03 18:35:39 +000012046
florian3f8a96a2012-08-05 02:59:55 +000012047 if (i == 3) continue; // skip this one
florian6d9b9b22012-08-03 18:35:39 +000012048
florian3f8a96a2012-08-05 02:59:55 +000012049 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
12050 &s390x_dirtyhelper_CUxy,
12051 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
12052 mkexpr(num_bytes)));
12053 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
12054 d->mFx = Ifx_Write;
12055 d->mAddr = mkexpr(addr1);
12056 d->mSize = i;
12057 stmt(IRStmt_Dirty(d));
12058 }
12059 } else {
12060 // cu14
12061 store(mkexpr(addr1), unop(Iop_64to32, mkexpr(data)));
florian6d9b9b22012-08-03 18:35:39 +000012062 }
12063
12064 /* Update source address and length */
12065 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkexpr(num_src_bytes)));
12066 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkexpr(num_src_bytes)));
12067
12068 /* Update destination address and length */
12069 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
12070 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
12071
12072 iterate();
florian3f8a96a2012-08-05 02:59:55 +000012073}
12074
12075static HChar *
12076s390_irgen_CU12(UChar m3, UChar r1, UChar r2)
12077{
12078 s390_irgen_cu12_cu14(m3, r1, r2, /* is_cu12 = */ 1);
florian6d9b9b22012-08-03 18:35:39 +000012079
12080 return "cu12";
12081}
12082
florian3f8a96a2012-08-05 02:59:55 +000012083static HChar *
12084s390_irgen_CU14(UChar m3, UChar r1, UChar r2)
12085{
12086 s390_irgen_cu12_cu14(m3, r1, r2, /* is_cu12 = */ 0);
12087
12088 return "cu14";
12089}
12090
florian8c88cb62012-08-26 18:58:13 +000012091static IRExpr *
12092s390_call_ecag(IRExpr *op2addr)
12093{
12094 IRExpr **args, *call;
12095
12096 args = mkIRExprVec_1(op2addr);
12097 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
12098 "s390_do_ecag", &s390_do_ecag, args);
12099
12100 /* Nothing is excluded from definedness checking. */
12101 call->Iex.CCall.cee->mcx_mask = 0;
12102
12103 return call;
12104}
12105
12106static HChar *
floriand2129202012-09-01 20:01:39 +000012107s390_irgen_ECAG(UChar r1, UChar r3 __attribute__((unused)), IRTemp op2addr)
florian8c88cb62012-08-26 18:58:13 +000012108{
12109 if (! s390_host_has_gie) {
floriane75dafa2012-09-01 17:54:09 +000012110 emulation_failure(EmFail_S390X_ecag);
florian8c88cb62012-08-26 18:58:13 +000012111 } else {
12112 put_gpr_dw0(r1, s390_call_ecag(mkexpr(op2addr)));
12113 }
12114
12115 return "ecag";
12116}
12117
12118
sewardj2019a972011-03-07 16:04:07 +000012119/*------------------------------------------------------------*/
12120/*--- Build IR for special instructions ---*/
12121/*------------------------------------------------------------*/
12122
florianb4df7682011-07-05 02:09:01 +000012123static void
sewardj2019a972011-03-07 16:04:07 +000012124s390_irgen_client_request(void)
12125{
12126 if (0)
12127 vex_printf("%%R3 = client_request ( %%R2 )\n");
12128
florianf9e1ed72012-04-17 02:41:56 +000012129 Addr64 next = guest_IA_curr_instr + S390_SPECIAL_OP_PREAMBLE_SIZE
12130 + S390_SPECIAL_OP_SIZE;
sewardj2019a972011-03-07 16:04:07 +000012131
florianf9e1ed72012-04-17 02:41:56 +000012132 dis_res->jk_StopHere = Ijk_ClientReq;
sewardj2019a972011-03-07 16:04:07 +000012133 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +000012134
12135 put_IA(mkaddr_expr(next));
sewardj2019a972011-03-07 16:04:07 +000012136}
12137
florianb4df7682011-07-05 02:09:01 +000012138static void
sewardj2019a972011-03-07 16:04:07 +000012139s390_irgen_guest_NRADDR(void)
12140{
12141 if (0)
12142 vex_printf("%%R3 = guest_NRADDR\n");
12143
floriane88b3c92011-07-05 02:48:39 +000012144 put_gpr_dw0(3, IRExpr_Get(S390X_GUEST_OFFSET(guest_NRADDR), Ity_I64));
sewardj2019a972011-03-07 16:04:07 +000012145}
12146
florianb4df7682011-07-05 02:09:01 +000012147static void
sewardj2019a972011-03-07 16:04:07 +000012148s390_irgen_call_noredir(void)
12149{
florianf9e1ed72012-04-17 02:41:56 +000012150 Addr64 next = guest_IA_curr_instr + S390_SPECIAL_OP_PREAMBLE_SIZE
12151 + S390_SPECIAL_OP_SIZE;
12152
sewardj2019a972011-03-07 16:04:07 +000012153 /* Continue after special op */
florianf9e1ed72012-04-17 02:41:56 +000012154 put_gpr_dw0(14, mkaddr_expr(next));
sewardj2019a972011-03-07 16:04:07 +000012155
12156 /* The address is in REG1, all parameters are in the right (guest) places */
florianf9e1ed72012-04-17 02:41:56 +000012157 put_IA(get_gpr_dw0(1));
sewardj2019a972011-03-07 16:04:07 +000012158
12159 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +000012160 dis_res->jk_StopHere = Ijk_NoRedir;
sewardj2019a972011-03-07 16:04:07 +000012161}
12162
12163/* Force proper alignment for the structures below. */
12164#pragma pack(1)
12165
12166
12167static s390_decode_t
12168s390_decode_2byte_and_irgen(UChar *bytes)
12169{
12170 typedef union {
12171 struct {
12172 unsigned int op : 16;
12173 } E;
12174 struct {
12175 unsigned int op : 8;
12176 unsigned int i : 8;
12177 } I;
12178 struct {
12179 unsigned int op : 8;
12180 unsigned int r1 : 4;
12181 unsigned int r2 : 4;
12182 } RR;
12183 } formats;
12184 union {
12185 formats fmt;
12186 UShort value;
12187 } ovl;
12188
12189 vassert(sizeof(formats) == 2);
12190
12191 ((char *)(&ovl.value))[0] = bytes[0];
12192 ((char *)(&ovl.value))[1] = bytes[1];
12193
12194 switch (ovl.value & 0xffff) {
12195 case 0x0101: /* PR */ goto unimplemented;
12196 case 0x0102: /* UPT */ goto unimplemented;
12197 case 0x0104: /* PTFF */ goto unimplemented;
12198 case 0x0107: /* SCKPF */ goto unimplemented;
12199 case 0x010a: /* PFPO */ goto unimplemented;
12200 case 0x010b: /* TAM */ goto unimplemented;
12201 case 0x010c: /* SAM24 */ goto unimplemented;
12202 case 0x010d: /* SAM31 */ goto unimplemented;
12203 case 0x010e: /* SAM64 */ goto unimplemented;
12204 case 0x01ff: /* TRAP2 */ goto unimplemented;
12205 }
12206
12207 switch ((ovl.value & 0xff00) >> 8) {
12208 case 0x04: /* SPM */ goto unimplemented;
12209 case 0x05: /* BALR */ goto unimplemented;
12210 case 0x06: s390_format_RR_RR(s390_irgen_BCTR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12211 goto ok;
12212 case 0x07: s390_format_RR(s390_irgen_BCR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12213 goto ok;
12214 case 0x0a: s390_format_I(s390_irgen_SVC, ovl.fmt.I.i); goto ok;
12215 case 0x0b: /* BSM */ goto unimplemented;
12216 case 0x0c: /* BASSM */ goto unimplemented;
12217 case 0x0d: s390_format_RR_RR(s390_irgen_BASR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12218 goto ok;
florianb0c9a132011-09-08 15:37:39 +000012219 case 0x0e: s390_format_RR(s390_irgen_MVCL, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12220 goto ok;
12221 case 0x0f: s390_format_RR(s390_irgen_CLCL, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12222 goto ok;
sewardj2019a972011-03-07 16:04:07 +000012223 case 0x10: s390_format_RR_RR(s390_irgen_LPR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12224 goto ok;
12225 case 0x11: s390_format_RR_RR(s390_irgen_LNR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12226 goto ok;
12227 case 0x12: s390_format_RR_RR(s390_irgen_LTR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12228 goto ok;
12229 case 0x13: s390_format_RR_RR(s390_irgen_LCR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12230 goto ok;
12231 case 0x14: s390_format_RR_RR(s390_irgen_NR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12232 goto ok;
12233 case 0x15: s390_format_RR_RR(s390_irgen_CLR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12234 goto ok;
12235 case 0x16: s390_format_RR_RR(s390_irgen_OR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12236 goto ok;
12237 case 0x17: s390_format_RR_RR(s390_irgen_XR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12238 goto ok;
12239 case 0x18: s390_format_RR_RR(s390_irgen_LR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12240 goto ok;
12241 case 0x19: s390_format_RR_RR(s390_irgen_CR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12242 goto ok;
12243 case 0x1a: s390_format_RR_RR(s390_irgen_AR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12244 goto ok;
12245 case 0x1b: s390_format_RR_RR(s390_irgen_SR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12246 goto ok;
12247 case 0x1c: s390_format_RR_RR(s390_irgen_MR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12248 goto ok;
12249 case 0x1d: s390_format_RR_RR(s390_irgen_DR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12250 goto ok;
12251 case 0x1e: s390_format_RR_RR(s390_irgen_ALR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12252 goto ok;
12253 case 0x1f: s390_format_RR_RR(s390_irgen_SLR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12254 goto ok;
12255 case 0x20: /* LPDR */ goto unimplemented;
12256 case 0x21: /* LNDR */ goto unimplemented;
12257 case 0x22: /* LTDR */ goto unimplemented;
12258 case 0x23: /* LCDR */ goto unimplemented;
12259 case 0x24: /* HDR */ goto unimplemented;
12260 case 0x25: /* LDXR */ goto unimplemented;
12261 case 0x26: /* MXR */ goto unimplemented;
12262 case 0x27: /* MXDR */ goto unimplemented;
12263 case 0x28: s390_format_RR_FF(s390_irgen_LDR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12264 goto ok;
12265 case 0x29: /* CDR */ goto unimplemented;
12266 case 0x2a: /* ADR */ goto unimplemented;
12267 case 0x2b: /* SDR */ goto unimplemented;
12268 case 0x2c: /* MDR */ goto unimplemented;
12269 case 0x2d: /* DDR */ goto unimplemented;
12270 case 0x2e: /* AWR */ goto unimplemented;
12271 case 0x2f: /* SWR */ goto unimplemented;
12272 case 0x30: /* LPER */ goto unimplemented;
12273 case 0x31: /* LNER */ goto unimplemented;
12274 case 0x32: /* LTER */ goto unimplemented;
12275 case 0x33: /* LCER */ goto unimplemented;
12276 case 0x34: /* HER */ goto unimplemented;
12277 case 0x35: /* LEDR */ goto unimplemented;
12278 case 0x36: /* AXR */ goto unimplemented;
12279 case 0x37: /* SXR */ goto unimplemented;
12280 case 0x38: s390_format_RR_FF(s390_irgen_LER, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12281 goto ok;
12282 case 0x39: /* CER */ goto unimplemented;
12283 case 0x3a: /* AER */ goto unimplemented;
12284 case 0x3b: /* SER */ goto unimplemented;
12285 case 0x3c: /* MDER */ goto unimplemented;
12286 case 0x3d: /* DER */ goto unimplemented;
12287 case 0x3e: /* AUR */ goto unimplemented;
12288 case 0x3f: /* SUR */ goto unimplemented;
12289 }
12290
12291 return S390_DECODE_UNKNOWN_INSN;
12292
12293ok:
12294 return S390_DECODE_OK;
12295
12296unimplemented:
12297 return S390_DECODE_UNIMPLEMENTED_INSN;
12298}
12299
12300static s390_decode_t
12301s390_decode_4byte_and_irgen(UChar *bytes)
12302{
12303 typedef union {
12304 struct {
12305 unsigned int op1 : 8;
12306 unsigned int r1 : 4;
12307 unsigned int op2 : 4;
12308 unsigned int i2 : 16;
12309 } RI;
12310 struct {
12311 unsigned int op : 16;
12312 unsigned int : 8;
12313 unsigned int r1 : 4;
12314 unsigned int r2 : 4;
12315 } RRE;
12316 struct {
12317 unsigned int op : 16;
12318 unsigned int r1 : 4;
12319 unsigned int : 4;
12320 unsigned int r3 : 4;
12321 unsigned int r2 : 4;
12322 } RRF;
12323 struct {
12324 unsigned int op : 16;
florian1c8f7ff2012-09-01 00:12:11 +000012325 unsigned int m3 : 4;
sewardj2019a972011-03-07 16:04:07 +000012326 unsigned int m4 : 4;
12327 unsigned int r1 : 4;
12328 unsigned int r2 : 4;
12329 } RRF2;
12330 struct {
12331 unsigned int op : 16;
12332 unsigned int r3 : 4;
12333 unsigned int : 4;
12334 unsigned int r1 : 4;
12335 unsigned int r2 : 4;
12336 } RRF3;
12337 struct {
12338 unsigned int op : 16;
12339 unsigned int r3 : 4;
12340 unsigned int : 4;
12341 unsigned int r1 : 4;
12342 unsigned int r2 : 4;
12343 } RRR;
12344 struct {
12345 unsigned int op : 16;
12346 unsigned int r3 : 4;
12347 unsigned int : 4;
12348 unsigned int r1 : 4;
12349 unsigned int r2 : 4;
12350 } RRF4;
12351 struct {
12352 unsigned int op : 8;
12353 unsigned int r1 : 4;
12354 unsigned int r3 : 4;
12355 unsigned int b2 : 4;
12356 unsigned int d2 : 12;
12357 } RS;
12358 struct {
12359 unsigned int op : 8;
12360 unsigned int r1 : 4;
12361 unsigned int r3 : 4;
12362 unsigned int i2 : 16;
12363 } RSI;
12364 struct {
12365 unsigned int op : 8;
12366 unsigned int r1 : 4;
12367 unsigned int x2 : 4;
12368 unsigned int b2 : 4;
12369 unsigned int d2 : 12;
12370 } RX;
12371 struct {
12372 unsigned int op : 16;
12373 unsigned int b2 : 4;
12374 unsigned int d2 : 12;
12375 } S;
12376 struct {
12377 unsigned int op : 8;
12378 unsigned int i2 : 8;
12379 unsigned int b1 : 4;
12380 unsigned int d1 : 12;
12381 } SI;
12382 } formats;
12383 union {
12384 formats fmt;
12385 UInt value;
12386 } ovl;
12387
12388 vassert(sizeof(formats) == 4);
12389
12390 ((char *)(&ovl.value))[0] = bytes[0];
12391 ((char *)(&ovl.value))[1] = bytes[1];
12392 ((char *)(&ovl.value))[2] = bytes[2];
12393 ((char *)(&ovl.value))[3] = bytes[3];
12394
12395 switch ((ovl.value & 0xff0f0000) >> 16) {
12396 case 0xa500: s390_format_RI_RU(s390_irgen_IIHH, ovl.fmt.RI.r1,
12397 ovl.fmt.RI.i2); goto ok;
12398 case 0xa501: s390_format_RI_RU(s390_irgen_IIHL, ovl.fmt.RI.r1,
12399 ovl.fmt.RI.i2); goto ok;
12400 case 0xa502: s390_format_RI_RU(s390_irgen_IILH, ovl.fmt.RI.r1,
12401 ovl.fmt.RI.i2); goto ok;
12402 case 0xa503: s390_format_RI_RU(s390_irgen_IILL, ovl.fmt.RI.r1,
12403 ovl.fmt.RI.i2); goto ok;
12404 case 0xa504: s390_format_RI_RU(s390_irgen_NIHH, ovl.fmt.RI.r1,
12405 ovl.fmt.RI.i2); goto ok;
12406 case 0xa505: s390_format_RI_RU(s390_irgen_NIHL, ovl.fmt.RI.r1,
12407 ovl.fmt.RI.i2); goto ok;
12408 case 0xa506: s390_format_RI_RU(s390_irgen_NILH, ovl.fmt.RI.r1,
12409 ovl.fmt.RI.i2); goto ok;
12410 case 0xa507: s390_format_RI_RU(s390_irgen_NILL, ovl.fmt.RI.r1,
12411 ovl.fmt.RI.i2); goto ok;
12412 case 0xa508: s390_format_RI_RU(s390_irgen_OIHH, ovl.fmt.RI.r1,
12413 ovl.fmt.RI.i2); goto ok;
12414 case 0xa509: s390_format_RI_RU(s390_irgen_OIHL, ovl.fmt.RI.r1,
12415 ovl.fmt.RI.i2); goto ok;
12416 case 0xa50a: s390_format_RI_RU(s390_irgen_OILH, ovl.fmt.RI.r1,
12417 ovl.fmt.RI.i2); goto ok;
12418 case 0xa50b: s390_format_RI_RU(s390_irgen_OILL, ovl.fmt.RI.r1,
12419 ovl.fmt.RI.i2); goto ok;
12420 case 0xa50c: s390_format_RI_RU(s390_irgen_LLIHH, ovl.fmt.RI.r1,
12421 ovl.fmt.RI.i2); goto ok;
12422 case 0xa50d: s390_format_RI_RU(s390_irgen_LLIHL, ovl.fmt.RI.r1,
12423 ovl.fmt.RI.i2); goto ok;
12424 case 0xa50e: s390_format_RI_RU(s390_irgen_LLILH, ovl.fmt.RI.r1,
12425 ovl.fmt.RI.i2); goto ok;
12426 case 0xa50f: s390_format_RI_RU(s390_irgen_LLILL, ovl.fmt.RI.r1,
12427 ovl.fmt.RI.i2); goto ok;
12428 case 0xa700: s390_format_RI_RU(s390_irgen_TMLH, ovl.fmt.RI.r1,
12429 ovl.fmt.RI.i2); goto ok;
12430 case 0xa701: s390_format_RI_RU(s390_irgen_TMLL, ovl.fmt.RI.r1,
12431 ovl.fmt.RI.i2); goto ok;
12432 case 0xa702: s390_format_RI_RU(s390_irgen_TMHH, ovl.fmt.RI.r1,
12433 ovl.fmt.RI.i2); goto ok;
12434 case 0xa703: s390_format_RI_RU(s390_irgen_TMHL, ovl.fmt.RI.r1,
12435 ovl.fmt.RI.i2); goto ok;
12436 case 0xa704: s390_format_RI(s390_irgen_BRC, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
12437 goto ok;
12438 case 0xa705: s390_format_RI_RP(s390_irgen_BRAS, ovl.fmt.RI.r1,
12439 ovl.fmt.RI.i2); goto ok;
12440 case 0xa706: s390_format_RI_RP(s390_irgen_BRCT, ovl.fmt.RI.r1,
12441 ovl.fmt.RI.i2); goto ok;
12442 case 0xa707: s390_format_RI_RP(s390_irgen_BRCTG, ovl.fmt.RI.r1,
12443 ovl.fmt.RI.i2); goto ok;
12444 case 0xa708: s390_format_RI_RI(s390_irgen_LHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
12445 goto ok;
12446 case 0xa709: s390_format_RI_RI(s390_irgen_LGHI, ovl.fmt.RI.r1,
12447 ovl.fmt.RI.i2); goto ok;
12448 case 0xa70a: s390_format_RI_RI(s390_irgen_AHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
12449 goto ok;
12450 case 0xa70b: s390_format_RI_RI(s390_irgen_AGHI, ovl.fmt.RI.r1,
12451 ovl.fmt.RI.i2); goto ok;
12452 case 0xa70c: s390_format_RI_RI(s390_irgen_MHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
12453 goto ok;
12454 case 0xa70d: s390_format_RI_RI(s390_irgen_MGHI, ovl.fmt.RI.r1,
12455 ovl.fmt.RI.i2); goto ok;
12456 case 0xa70e: s390_format_RI_RI(s390_irgen_CHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
12457 goto ok;
12458 case 0xa70f: s390_format_RI_RI(s390_irgen_CGHI, ovl.fmt.RI.r1,
12459 ovl.fmt.RI.i2); goto ok;
12460 }
12461
12462 switch ((ovl.value & 0xffff0000) >> 16) {
12463 case 0x8000: /* SSM */ goto unimplemented;
12464 case 0x8200: /* LPSW */ goto unimplemented;
florian7700fc92012-01-16 17:25:55 +000012465 case 0x9300: /* TS */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000012466 case 0xb202: /* STIDP */ goto unimplemented;
12467 case 0xb204: /* SCK */ goto unimplemented;
florian7700fc92012-01-16 17:25:55 +000012468 case 0xb205: s390_format_S_RD(s390_irgen_STCK, ovl.fmt.S.b2, ovl.fmt.S.d2);
12469 goto ok;
sewardj2019a972011-03-07 16:04:07 +000012470 case 0xb206: /* SCKC */ goto unimplemented;
12471 case 0xb207: /* STCKC */ goto unimplemented;
12472 case 0xb208: /* SPT */ goto unimplemented;
12473 case 0xb209: /* STPT */ goto unimplemented;
12474 case 0xb20a: /* SPKA */ goto unimplemented;
12475 case 0xb20b: /* IPK */ goto unimplemented;
12476 case 0xb20d: /* PTLB */ goto unimplemented;
12477 case 0xb210: /* SPX */ goto unimplemented;
12478 case 0xb211: /* STPX */ goto unimplemented;
12479 case 0xb212: /* STAP */ goto unimplemented;
12480 case 0xb214: /* SIE */ goto unimplemented;
12481 case 0xb218: /* PC */ goto unimplemented;
12482 case 0xb219: /* SAC */ goto unimplemented;
12483 case 0xb21a: /* CFC */ goto unimplemented;
12484 case 0xb221: /* IPTE */ goto unimplemented;
12485 case 0xb222: s390_format_RRE_R0(s390_irgen_IPM, ovl.fmt.RRE.r1); goto ok;
12486 case 0xb223: /* IVSK */ goto unimplemented;
12487 case 0xb224: /* IAC */ goto unimplemented;
12488 case 0xb225: /* SSAR */ goto unimplemented;
12489 case 0xb226: /* EPAR */ goto unimplemented;
12490 case 0xb227: /* ESAR */ goto unimplemented;
12491 case 0xb228: /* PT */ goto unimplemented;
12492 case 0xb229: /* ISKE */ goto unimplemented;
12493 case 0xb22a: /* RRBE */ goto unimplemented;
12494 case 0xb22b: /* SSKE */ goto unimplemented;
12495 case 0xb22c: /* TB */ goto unimplemented;
12496 case 0xb22d: /* DXR */ goto unimplemented;
12497 case 0xb22e: /* PGIN */ goto unimplemented;
12498 case 0xb22f: /* PGOUT */ goto unimplemented;
12499 case 0xb230: /* CSCH */ goto unimplemented;
12500 case 0xb231: /* HSCH */ goto unimplemented;
12501 case 0xb232: /* MSCH */ goto unimplemented;
12502 case 0xb233: /* SSCH */ goto unimplemented;
12503 case 0xb234: /* STSCH */ goto unimplemented;
12504 case 0xb235: /* TSCH */ goto unimplemented;
12505 case 0xb236: /* TPI */ goto unimplemented;
12506 case 0xb237: /* SAL */ goto unimplemented;
12507 case 0xb238: /* RSCH */ goto unimplemented;
12508 case 0xb239: /* STCRW */ goto unimplemented;
12509 case 0xb23a: /* STCPS */ goto unimplemented;
12510 case 0xb23b: /* RCHP */ goto unimplemented;
12511 case 0xb23c: /* SCHM */ goto unimplemented;
12512 case 0xb240: /* BAKR */ goto unimplemented;
floriana4384a32011-08-11 16:58:45 +000012513 case 0xb241: s390_format_RRE(s390_irgen_CKSM, ovl.fmt.RRE.r1,
12514 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000012515 case 0xb244: /* SQDR */ goto unimplemented;
12516 case 0xb245: /* SQER */ goto unimplemented;
12517 case 0xb246: /* STURA */ goto unimplemented;
12518 case 0xb247: /* MSTA */ goto unimplemented;
12519 case 0xb248: /* PALB */ goto unimplemented;
12520 case 0xb249: /* EREG */ goto unimplemented;
12521 case 0xb24a: /* ESTA */ goto unimplemented;
12522 case 0xb24b: /* LURA */ goto unimplemented;
12523 case 0xb24c: /* TAR */ goto unimplemented;
12524 case 0xb24d: s390_format_RRE(s390_irgen_CPYA, ovl.fmt.RRE.r1,
12525 ovl.fmt.RRE.r2); goto ok;
12526 case 0xb24e: s390_format_RRE(s390_irgen_SAR, ovl.fmt.RRE.r1, ovl.fmt.RRE.r2);
12527 goto ok;
12528 case 0xb24f: s390_format_RRE(s390_irgen_EAR, ovl.fmt.RRE.r1, ovl.fmt.RRE.r2);
12529 goto ok;
12530 case 0xb250: /* CSP */ goto unimplemented;
12531 case 0xb252: s390_format_RRE_RR(s390_irgen_MSR, ovl.fmt.RRE.r1,
12532 ovl.fmt.RRE.r2); goto ok;
12533 case 0xb254: /* MVPG */ goto unimplemented;
12534 case 0xb255: s390_format_RRE_RR(s390_irgen_MVST, ovl.fmt.RRE.r1,
12535 ovl.fmt.RRE.r2); goto ok;
12536 case 0xb257: /* CUSE */ goto unimplemented;
12537 case 0xb258: /* BSG */ goto unimplemented;
12538 case 0xb25a: /* BSA */ goto unimplemented;
12539 case 0xb25d: s390_format_RRE_RR(s390_irgen_CLST, ovl.fmt.RRE.r1,
12540 ovl.fmt.RRE.r2); goto ok;
12541 case 0xb25e: s390_format_RRE_RR(s390_irgen_SRST, ovl.fmt.RRE.r1,
12542 ovl.fmt.RRE.r2); goto ok;
12543 case 0xb263: /* CMPSC */ goto unimplemented;
12544 case 0xb274: /* SIGA */ goto unimplemented;
12545 case 0xb276: /* XSCH */ goto unimplemented;
12546 case 0xb277: /* RP */ goto unimplemented;
sewardj1e5fea62011-05-17 16:18:36 +000012547 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 +000012548 case 0xb279: /* SACF */ goto unimplemented;
sewardj1e5fea62011-05-17 16:18:36 +000012549 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 +000012550 case 0xb27d: /* STSI */ goto unimplemented;
12551 case 0xb299: s390_format_S_RD(s390_irgen_SRNM, ovl.fmt.S.b2, ovl.fmt.S.d2);
12552 goto ok;
12553 case 0xb29c: s390_format_S_RD(s390_irgen_STFPC, ovl.fmt.S.b2, ovl.fmt.S.d2);
12554 goto ok;
12555 case 0xb29d: s390_format_S_RD(s390_irgen_LFPC, ovl.fmt.S.b2, ovl.fmt.S.d2);
12556 goto ok;
florian730448f2012-02-04 17:07:07 +000012557 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 +000012558 case 0xb2a6: s390_format_RRF_M0RERE(s390_irgen_CU21, ovl.fmt.RRF3.r3,
12559 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
12560 goto ok;
florian6d9b9b22012-08-03 18:35:39 +000012561 case 0xb2a7: s390_format_RRF_M0RERE(s390_irgen_CU12, ovl.fmt.RRF3.r3,
12562 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
12563 goto ok;
florian933065d2011-07-11 01:48:02 +000012564 case 0xb2b0: s390_format_S_RD(s390_irgen_STFLE, ovl.fmt.S.b2, ovl.fmt.S.d2);
12565 goto ok;
sewardj2019a972011-03-07 16:04:07 +000012566 case 0xb2b1: /* STFL */ goto unimplemented;
12567 case 0xb2b2: /* LPSWE */ goto unimplemented;
12568 case 0xb2b8: /* SRNMB */ goto unimplemented;
12569 case 0xb2b9: /* SRNMT */ goto unimplemented;
12570 case 0xb2bd: /* LFAS */ goto unimplemented;
12571 case 0xb2ff: /* TRAP4 */ goto unimplemented;
12572 case 0xb300: s390_format_RRE_FF(s390_irgen_LPEBR, ovl.fmt.RRE.r1,
12573 ovl.fmt.RRE.r2); goto ok;
12574 case 0xb301: s390_format_RRE_FF(s390_irgen_LNEBR, ovl.fmt.RRE.r1,
12575 ovl.fmt.RRE.r2); goto ok;
12576 case 0xb302: s390_format_RRE_FF(s390_irgen_LTEBR, ovl.fmt.RRE.r1,
12577 ovl.fmt.RRE.r2); goto ok;
12578 case 0xb303: s390_format_RRE_FF(s390_irgen_LCEBR, ovl.fmt.RRE.r1,
12579 ovl.fmt.RRE.r2); goto ok;
12580 case 0xb304: s390_format_RRE_FF(s390_irgen_LDEBR, ovl.fmt.RRE.r1,
12581 ovl.fmt.RRE.r2); goto ok;
12582 case 0xb305: s390_format_RRE_FF(s390_irgen_LXDBR, ovl.fmt.RRE.r1,
12583 ovl.fmt.RRE.r2); goto ok;
12584 case 0xb306: s390_format_RRE_FF(s390_irgen_LXEBR, ovl.fmt.RRE.r1,
12585 ovl.fmt.RRE.r2); goto ok;
12586 case 0xb307: /* MXDBR */ goto unimplemented;
12587 case 0xb308: /* KEBR */ goto unimplemented;
12588 case 0xb309: s390_format_RRE_FF(s390_irgen_CEBR, ovl.fmt.RRE.r1,
12589 ovl.fmt.RRE.r2); goto ok;
12590 case 0xb30a: s390_format_RRE_FF(s390_irgen_AEBR, ovl.fmt.RRE.r1,
12591 ovl.fmt.RRE.r2); goto ok;
12592 case 0xb30b: s390_format_RRE_FF(s390_irgen_SEBR, ovl.fmt.RRE.r1,
12593 ovl.fmt.RRE.r2); goto ok;
12594 case 0xb30c: /* MDEBR */ goto unimplemented;
12595 case 0xb30d: s390_format_RRE_FF(s390_irgen_DEBR, ovl.fmt.RRE.r1,
12596 ovl.fmt.RRE.r2); goto ok;
12597 case 0xb30e: s390_format_RRF_F0FF(s390_irgen_MAEBR, ovl.fmt.RRF.r1,
12598 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
12599 case 0xb30f: s390_format_RRF_F0FF(s390_irgen_MSEBR, ovl.fmt.RRF.r1,
12600 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
12601 case 0xb310: s390_format_RRE_FF(s390_irgen_LPDBR, ovl.fmt.RRE.r1,
12602 ovl.fmt.RRE.r2); goto ok;
12603 case 0xb311: s390_format_RRE_FF(s390_irgen_LNDBR, ovl.fmt.RRE.r1,
12604 ovl.fmt.RRE.r2); goto ok;
12605 case 0xb312: s390_format_RRE_FF(s390_irgen_LTDBR, ovl.fmt.RRE.r1,
12606 ovl.fmt.RRE.r2); goto ok;
12607 case 0xb313: s390_format_RRE_FF(s390_irgen_LCDBR, ovl.fmt.RRE.r1,
12608 ovl.fmt.RRE.r2); goto ok;
12609 case 0xb314: s390_format_RRE_FF(s390_irgen_SQEBR, ovl.fmt.RRE.r1,
12610 ovl.fmt.RRE.r2); goto ok;
12611 case 0xb315: s390_format_RRE_FF(s390_irgen_SQDBR, ovl.fmt.RRE.r1,
12612 ovl.fmt.RRE.r2); goto ok;
12613 case 0xb316: s390_format_RRE_FF(s390_irgen_SQXBR, ovl.fmt.RRE.r1,
12614 ovl.fmt.RRE.r2); goto ok;
12615 case 0xb317: s390_format_RRE_FF(s390_irgen_MEEBR, ovl.fmt.RRE.r1,
12616 ovl.fmt.RRE.r2); goto ok;
12617 case 0xb318: /* KDBR */ goto unimplemented;
12618 case 0xb319: s390_format_RRE_FF(s390_irgen_CDBR, ovl.fmt.RRE.r1,
12619 ovl.fmt.RRE.r2); goto ok;
12620 case 0xb31a: s390_format_RRE_FF(s390_irgen_ADBR, ovl.fmt.RRE.r1,
12621 ovl.fmt.RRE.r2); goto ok;
12622 case 0xb31b: s390_format_RRE_FF(s390_irgen_SDBR, ovl.fmt.RRE.r1,
12623 ovl.fmt.RRE.r2); goto ok;
12624 case 0xb31c: s390_format_RRE_FF(s390_irgen_MDBR, ovl.fmt.RRE.r1,
12625 ovl.fmt.RRE.r2); goto ok;
12626 case 0xb31d: s390_format_RRE_FF(s390_irgen_DDBR, ovl.fmt.RRE.r1,
12627 ovl.fmt.RRE.r2); goto ok;
12628 case 0xb31e: s390_format_RRF_F0FF(s390_irgen_MADBR, ovl.fmt.RRF.r1,
12629 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
12630 case 0xb31f: s390_format_RRF_F0FF(s390_irgen_MSDBR, ovl.fmt.RRF.r1,
12631 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
12632 case 0xb324: /* LDER */ goto unimplemented;
12633 case 0xb325: /* LXDR */ goto unimplemented;
12634 case 0xb326: /* LXER */ goto unimplemented;
12635 case 0xb32e: /* MAER */ goto unimplemented;
12636 case 0xb32f: /* MSER */ goto unimplemented;
12637 case 0xb336: /* SQXR */ goto unimplemented;
12638 case 0xb337: /* MEER */ goto unimplemented;
12639 case 0xb338: /* MAYLR */ goto unimplemented;
12640 case 0xb339: /* MYLR */ goto unimplemented;
12641 case 0xb33a: /* MAYR */ goto unimplemented;
12642 case 0xb33b: /* MYR */ goto unimplemented;
12643 case 0xb33c: /* MAYHR */ goto unimplemented;
12644 case 0xb33d: /* MYHR */ goto unimplemented;
12645 case 0xb33e: /* MADR */ goto unimplemented;
12646 case 0xb33f: /* MSDR */ goto unimplemented;
12647 case 0xb340: s390_format_RRE_FF(s390_irgen_LPXBR, ovl.fmt.RRE.r1,
12648 ovl.fmt.RRE.r2); goto ok;
12649 case 0xb341: s390_format_RRE_FF(s390_irgen_LNXBR, ovl.fmt.RRE.r1,
12650 ovl.fmt.RRE.r2); goto ok;
12651 case 0xb342: s390_format_RRE_FF(s390_irgen_LTXBR, ovl.fmt.RRE.r1,
12652 ovl.fmt.RRE.r2); goto ok;
12653 case 0xb343: s390_format_RRE_FF(s390_irgen_LCXBR, ovl.fmt.RRE.r1,
12654 ovl.fmt.RRE.r2); goto ok;
florian4b8efad2012-09-02 18:07:08 +000012655 case 0xb344: s390_format_RRF_UUFF(s390_irgen_LEDBR, ovl.fmt.RRF2.m3,
12656 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12657 ovl.fmt.RRF2.r2); goto ok;
12658 case 0xb345: s390_format_RRF_UUFF(s390_irgen_LDXBR, ovl.fmt.RRF2.m3,
12659 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12660 ovl.fmt.RRF2.r2); goto ok;
12661 case 0xb346: s390_format_RRF_UUFF(s390_irgen_LEXBR, ovl.fmt.RRF2.m3,
12662 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12663 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000012664 case 0xb347: /* FIXBR */ goto unimplemented;
12665 case 0xb348: /* KXBR */ goto unimplemented;
12666 case 0xb349: s390_format_RRE_FF(s390_irgen_CXBR, ovl.fmt.RRE.r1,
12667 ovl.fmt.RRE.r2); goto ok;
12668 case 0xb34a: s390_format_RRE_FF(s390_irgen_AXBR, ovl.fmt.RRE.r1,
12669 ovl.fmt.RRE.r2); goto ok;
12670 case 0xb34b: s390_format_RRE_FF(s390_irgen_SXBR, ovl.fmt.RRE.r1,
12671 ovl.fmt.RRE.r2); goto ok;
12672 case 0xb34c: s390_format_RRE_FF(s390_irgen_MXBR, ovl.fmt.RRE.r1,
12673 ovl.fmt.RRE.r2); goto ok;
12674 case 0xb34d: s390_format_RRE_FF(s390_irgen_DXBR, ovl.fmt.RRE.r1,
12675 ovl.fmt.RRE.r2); goto ok;
12676 case 0xb350: /* TBEDR */ goto unimplemented;
12677 case 0xb351: /* TBDR */ goto unimplemented;
12678 case 0xb353: /* DIEBR */ goto unimplemented;
12679 case 0xb357: /* FIEBR */ goto unimplemented;
12680 case 0xb358: /* THDER */ goto unimplemented;
12681 case 0xb359: /* THDR */ goto unimplemented;
12682 case 0xb35b: /* DIDBR */ goto unimplemented;
12683 case 0xb35f: /* FIDBR */ goto unimplemented;
12684 case 0xb360: /* LPXR */ goto unimplemented;
12685 case 0xb361: /* LNXR */ goto unimplemented;
12686 case 0xb362: /* LTXR */ goto unimplemented;
12687 case 0xb363: /* LCXR */ goto unimplemented;
12688 case 0xb365: s390_format_RRE_FF(s390_irgen_LXR, ovl.fmt.RRE.r1,
12689 ovl.fmt.RRE.r2); goto ok;
12690 case 0xb366: /* LEXR */ goto unimplemented;
12691 case 0xb367: /* FIXR */ goto unimplemented;
12692 case 0xb369: /* CXR */ goto unimplemented;
12693 case 0xb370: s390_format_RRE_FF(s390_irgen_LPDFR, ovl.fmt.RRE.r1,
12694 ovl.fmt.RRE.r2); goto ok;
12695 case 0xb371: s390_format_RRE_FF(s390_irgen_LNDFR, ovl.fmt.RRE.r1,
12696 ovl.fmt.RRE.r2); goto ok;
12697 case 0xb372: s390_format_RRF_F0FF2(s390_irgen_CPSDR, ovl.fmt.RRF3.r3,
12698 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
12699 goto ok;
12700 case 0xb373: s390_format_RRE_FF(s390_irgen_LCDFR, ovl.fmt.RRE.r1,
12701 ovl.fmt.RRE.r2); goto ok;
12702 case 0xb374: s390_format_RRE_F0(s390_irgen_LZER, ovl.fmt.RRE.r1); goto ok;
12703 case 0xb375: s390_format_RRE_F0(s390_irgen_LZDR, ovl.fmt.RRE.r1); goto ok;
12704 case 0xb376: s390_format_RRE_F0(s390_irgen_LZXR, ovl.fmt.RRE.r1); goto ok;
12705 case 0xb377: /* FIER */ goto unimplemented;
12706 case 0xb37f: /* FIDR */ goto unimplemented;
12707 case 0xb384: s390_format_RRE_R0(s390_irgen_SFPC, ovl.fmt.RRE.r1); goto ok;
12708 case 0xb385: /* SFASR */ goto unimplemented;
12709 case 0xb38c: s390_format_RRE_R0(s390_irgen_EFPC, ovl.fmt.RRE.r1); goto ok;
florian1c8f7ff2012-09-01 00:12:11 +000012710 case 0xb390: s390_format_RRF_UUFR(s390_irgen_CELFBR, ovl.fmt.RRF2.m3,
12711 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12712 ovl.fmt.RRF2.r2); goto ok;
12713 case 0xb391: s390_format_RRF_UUFR(s390_irgen_CDLFBR, ovl.fmt.RRF2.m3,
12714 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12715 ovl.fmt.RRF2.r2); goto ok;
12716 case 0xb392: s390_format_RRF_UUFR(s390_irgen_CXLFBR, ovl.fmt.RRF2.m3,
12717 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12718 ovl.fmt.RRF2.r2); goto ok;
florian4b8efad2012-09-02 18:07:08 +000012719 case 0xb394: s390_format_RRF_UUFR(s390_irgen_CEFBR, ovl.fmt.RRF2.m3,
12720 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12721 ovl.fmt.RRF2.r2); goto ok;
12722 case 0xb395: s390_format_RRF_UUFR(s390_irgen_CDFBR, ovl.fmt.RRF2.m3,
12723 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12724 ovl.fmt.RRF2.r2); goto ok;
12725 case 0xb396: s390_format_RRF_UUFR(s390_irgen_CXFBR, ovl.fmt.RRF2.m3,
12726 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12727 ovl.fmt.RRF2.r2); goto ok;
12728 case 0xb398: s390_format_RRF_UURF(s390_irgen_CFEBR, ovl.fmt.RRF2.m3,
12729 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12730 ovl.fmt.RRF2.r2); goto ok;
12731 case 0xb399: s390_format_RRF_UURF(s390_irgen_CFDBR, ovl.fmt.RRF2.m3,
12732 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12733 ovl.fmt.RRF2.r2); goto ok;
12734 case 0xb39a: s390_format_RRF_UURF(s390_irgen_CFXBR, ovl.fmt.RRF2.m3,
12735 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12736 ovl.fmt.RRF2.r2); goto ok;
florian1c8f7ff2012-09-01 00:12:11 +000012737 case 0xb39c: s390_format_RRF_UURF(s390_irgen_CLFEBR, ovl.fmt.RRF2.m3,
12738 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12739 ovl.fmt.RRF2.r2); goto ok;
12740 case 0xb39d: s390_format_RRF_UURF(s390_irgen_CLFDBR, ovl.fmt.RRF2.m3,
12741 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12742 ovl.fmt.RRF2.r2); goto ok;
12743 case 0xb39e: s390_format_RRF_UURF(s390_irgen_CLFXBR, ovl.fmt.RRF2.m3,
12744 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12745 ovl.fmt.RRF2.r2); goto ok;
12746 case 0xb3a0: s390_format_RRF_UUFR(s390_irgen_CELGBR, ovl.fmt.RRF2.m3,
12747 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12748 ovl.fmt.RRF2.r2); goto ok;
12749 case 0xb3a1: s390_format_RRF_UUFR(s390_irgen_CDLGBR, ovl.fmt.RRF2.m3,
12750 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12751 ovl.fmt.RRF2.r2); goto ok;
12752 case 0xb3a2: s390_format_RRF_UUFR(s390_irgen_CXLGBR, ovl.fmt.RRF2.m3,
12753 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12754 ovl.fmt.RRF2.r2); goto ok;
florian4b8efad2012-09-02 18:07:08 +000012755 case 0xb3a4: s390_format_RRF_UUFR(s390_irgen_CEGBR, ovl.fmt.RRF2.m3,
12756 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12757 ovl.fmt.RRF2.r2); goto ok;
12758 case 0xb3a5: s390_format_RRF_UUFR(s390_irgen_CDGBR, ovl.fmt.RRF2.m3,
12759 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12760 ovl.fmt.RRF2.r2); goto ok;
12761 case 0xb3a6: s390_format_RRF_UUFR(s390_irgen_CXGBR, ovl.fmt.RRF2.m3,
12762 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12763 ovl.fmt.RRF2.r2); goto ok;
12764 case 0xb3a8: s390_format_RRF_UURF(s390_irgen_CGEBR, ovl.fmt.RRF2.m3,
12765 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12766 ovl.fmt.RRF2.r2); goto ok;
12767 case 0xb3a9: s390_format_RRF_UURF(s390_irgen_CGDBR, ovl.fmt.RRF2.m3,
12768 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12769 ovl.fmt.RRF2.r2); goto ok;
12770 case 0xb3aa: s390_format_RRF_UURF(s390_irgen_CGXBR, ovl.fmt.RRF2.m3,
12771 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12772 ovl.fmt.RRF2.r2); goto ok;
florian1c8f7ff2012-09-01 00:12:11 +000012773 case 0xb3ac: s390_format_RRF_UURF(s390_irgen_CLGEBR, ovl.fmt.RRF2.m3,
12774 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12775 ovl.fmt.RRF2.r2); goto ok;
12776 case 0xb3ad: s390_format_RRF_UURF(s390_irgen_CLGDBR, ovl.fmt.RRF2.m3,
12777 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12778 ovl.fmt.RRF2.r2); goto ok;
12779 case 0xb3ae: s390_format_RRF_UURF(s390_irgen_CLGXBR, ovl.fmt.RRF2.m3,
12780 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12781 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000012782 case 0xb3b4: /* CEFR */ goto unimplemented;
12783 case 0xb3b5: /* CDFR */ goto unimplemented;
12784 case 0xb3b6: /* CXFR */ goto unimplemented;
12785 case 0xb3b8: /* CFER */ goto unimplemented;
12786 case 0xb3b9: /* CFDR */ goto unimplemented;
12787 case 0xb3ba: /* CFXR */ goto unimplemented;
12788 case 0xb3c1: s390_format_RRE_FR(s390_irgen_LDGR, ovl.fmt.RRE.r1,
12789 ovl.fmt.RRE.r2); goto ok;
12790 case 0xb3c4: /* CEGR */ goto unimplemented;
12791 case 0xb3c5: /* CDGR */ goto unimplemented;
12792 case 0xb3c6: /* CXGR */ goto unimplemented;
12793 case 0xb3c8: /* CGER */ goto unimplemented;
12794 case 0xb3c9: /* CGDR */ goto unimplemented;
12795 case 0xb3ca: /* CGXR */ goto unimplemented;
12796 case 0xb3cd: s390_format_RRE_RF(s390_irgen_LGDR, ovl.fmt.RRE.r1,
12797 ovl.fmt.RRE.r2); goto ok;
12798 case 0xb3d0: /* MDTR */ goto unimplemented;
12799 case 0xb3d1: /* DDTR */ goto unimplemented;
12800 case 0xb3d2: /* ADTR */ goto unimplemented;
12801 case 0xb3d3: /* SDTR */ goto unimplemented;
12802 case 0xb3d4: /* LDETR */ goto unimplemented;
12803 case 0xb3d5: /* LEDTR */ goto unimplemented;
12804 case 0xb3d6: /* LTDTR */ goto unimplemented;
12805 case 0xb3d7: /* FIDTR */ goto unimplemented;
12806 case 0xb3d8: /* MXTR */ goto unimplemented;
12807 case 0xb3d9: /* DXTR */ goto unimplemented;
12808 case 0xb3da: /* AXTR */ goto unimplemented;
12809 case 0xb3db: /* SXTR */ goto unimplemented;
12810 case 0xb3dc: /* LXDTR */ goto unimplemented;
12811 case 0xb3dd: /* LDXTR */ goto unimplemented;
12812 case 0xb3de: /* LTXTR */ goto unimplemented;
12813 case 0xb3df: /* FIXTR */ goto unimplemented;
12814 case 0xb3e0: /* KDTR */ goto unimplemented;
12815 case 0xb3e1: /* CGDTR */ goto unimplemented;
12816 case 0xb3e2: /* CUDTR */ goto unimplemented;
12817 case 0xb3e3: /* CSDTR */ goto unimplemented;
12818 case 0xb3e4: /* CDTR */ goto unimplemented;
12819 case 0xb3e5: /* EEDTR */ goto unimplemented;
12820 case 0xb3e7: /* ESDTR */ goto unimplemented;
12821 case 0xb3e8: /* KXTR */ goto unimplemented;
12822 case 0xb3e9: /* CGXTR */ goto unimplemented;
12823 case 0xb3ea: /* CUXTR */ goto unimplemented;
12824 case 0xb3eb: /* CSXTR */ goto unimplemented;
12825 case 0xb3ec: /* CXTR */ goto unimplemented;
12826 case 0xb3ed: /* EEXTR */ goto unimplemented;
12827 case 0xb3ef: /* ESXTR */ goto unimplemented;
12828 case 0xb3f1: /* CDGTR */ goto unimplemented;
12829 case 0xb3f2: /* CDUTR */ goto unimplemented;
12830 case 0xb3f3: /* CDSTR */ goto unimplemented;
12831 case 0xb3f4: /* CEDTR */ goto unimplemented;
12832 case 0xb3f5: /* QADTR */ goto unimplemented;
12833 case 0xb3f6: /* IEDTR */ goto unimplemented;
12834 case 0xb3f7: /* RRDTR */ goto unimplemented;
12835 case 0xb3f9: /* CXGTR */ goto unimplemented;
12836 case 0xb3fa: /* CXUTR */ goto unimplemented;
12837 case 0xb3fb: /* CXSTR */ goto unimplemented;
12838 case 0xb3fc: /* CEXTR */ goto unimplemented;
12839 case 0xb3fd: /* QAXTR */ goto unimplemented;
12840 case 0xb3fe: /* IEXTR */ goto unimplemented;
12841 case 0xb3ff: /* RRXTR */ goto unimplemented;
12842 case 0xb900: s390_format_RRE_RR(s390_irgen_LPGR, ovl.fmt.RRE.r1,
12843 ovl.fmt.RRE.r2); goto ok;
12844 case 0xb901: s390_format_RRE_RR(s390_irgen_LNGR, ovl.fmt.RRE.r1,
12845 ovl.fmt.RRE.r2); goto ok;
12846 case 0xb902: s390_format_RRE_RR(s390_irgen_LTGR, ovl.fmt.RRE.r1,
12847 ovl.fmt.RRE.r2); goto ok;
12848 case 0xb903: s390_format_RRE_RR(s390_irgen_LCGR, ovl.fmt.RRE.r1,
12849 ovl.fmt.RRE.r2); goto ok;
12850 case 0xb904: s390_format_RRE_RR(s390_irgen_LGR, ovl.fmt.RRE.r1,
12851 ovl.fmt.RRE.r2); goto ok;
12852 case 0xb905: /* LURAG */ goto unimplemented;
12853 case 0xb906: s390_format_RRE_RR(s390_irgen_LGBR, ovl.fmt.RRE.r1,
12854 ovl.fmt.RRE.r2); goto ok;
12855 case 0xb907: s390_format_RRE_RR(s390_irgen_LGHR, ovl.fmt.RRE.r1,
12856 ovl.fmt.RRE.r2); goto ok;
12857 case 0xb908: s390_format_RRE_RR(s390_irgen_AGR, ovl.fmt.RRE.r1,
12858 ovl.fmt.RRE.r2); goto ok;
12859 case 0xb909: s390_format_RRE_RR(s390_irgen_SGR, ovl.fmt.RRE.r1,
12860 ovl.fmt.RRE.r2); goto ok;
12861 case 0xb90a: s390_format_RRE_RR(s390_irgen_ALGR, ovl.fmt.RRE.r1,
12862 ovl.fmt.RRE.r2); goto ok;
12863 case 0xb90b: s390_format_RRE_RR(s390_irgen_SLGR, ovl.fmt.RRE.r1,
12864 ovl.fmt.RRE.r2); goto ok;
12865 case 0xb90c: s390_format_RRE_RR(s390_irgen_MSGR, ovl.fmt.RRE.r1,
12866 ovl.fmt.RRE.r2); goto ok;
12867 case 0xb90d: s390_format_RRE_RR(s390_irgen_DSGR, ovl.fmt.RRE.r1,
12868 ovl.fmt.RRE.r2); goto ok;
12869 case 0xb90e: /* EREGG */ goto unimplemented;
12870 case 0xb90f: s390_format_RRE_RR(s390_irgen_LRVGR, ovl.fmt.RRE.r1,
12871 ovl.fmt.RRE.r2); goto ok;
12872 case 0xb910: s390_format_RRE_RR(s390_irgen_LPGFR, ovl.fmt.RRE.r1,
12873 ovl.fmt.RRE.r2); goto ok;
12874 case 0xb911: s390_format_RRE_RR(s390_irgen_LNGFR, ovl.fmt.RRE.r1,
12875 ovl.fmt.RRE.r2); goto ok;
12876 case 0xb912: s390_format_RRE_RR(s390_irgen_LTGFR, ovl.fmt.RRE.r1,
12877 ovl.fmt.RRE.r2); goto ok;
12878 case 0xb913: s390_format_RRE_RR(s390_irgen_LCGFR, ovl.fmt.RRE.r1,
12879 ovl.fmt.RRE.r2); goto ok;
12880 case 0xb914: s390_format_RRE_RR(s390_irgen_LGFR, ovl.fmt.RRE.r1,
12881 ovl.fmt.RRE.r2); goto ok;
12882 case 0xb916: s390_format_RRE_RR(s390_irgen_LLGFR, ovl.fmt.RRE.r1,
12883 ovl.fmt.RRE.r2); goto ok;
12884 case 0xb917: s390_format_RRE_RR(s390_irgen_LLGTR, ovl.fmt.RRE.r1,
12885 ovl.fmt.RRE.r2); goto ok;
12886 case 0xb918: s390_format_RRE_RR(s390_irgen_AGFR, ovl.fmt.RRE.r1,
12887 ovl.fmt.RRE.r2); goto ok;
12888 case 0xb919: s390_format_RRE_RR(s390_irgen_SGFR, ovl.fmt.RRE.r1,
12889 ovl.fmt.RRE.r2); goto ok;
12890 case 0xb91a: s390_format_RRE_RR(s390_irgen_ALGFR, ovl.fmt.RRE.r1,
12891 ovl.fmt.RRE.r2); goto ok;
12892 case 0xb91b: s390_format_RRE_RR(s390_irgen_SLGFR, ovl.fmt.RRE.r1,
12893 ovl.fmt.RRE.r2); goto ok;
12894 case 0xb91c: s390_format_RRE_RR(s390_irgen_MSGFR, ovl.fmt.RRE.r1,
12895 ovl.fmt.RRE.r2); goto ok;
12896 case 0xb91d: s390_format_RRE_RR(s390_irgen_DSGFR, ovl.fmt.RRE.r1,
12897 ovl.fmt.RRE.r2); goto ok;
12898 case 0xb91e: /* KMAC */ goto unimplemented;
12899 case 0xb91f: s390_format_RRE_RR(s390_irgen_LRVR, ovl.fmt.RRE.r1,
12900 ovl.fmt.RRE.r2); goto ok;
12901 case 0xb920: s390_format_RRE_RR(s390_irgen_CGR, ovl.fmt.RRE.r1,
12902 ovl.fmt.RRE.r2); goto ok;
12903 case 0xb921: s390_format_RRE_RR(s390_irgen_CLGR, ovl.fmt.RRE.r1,
12904 ovl.fmt.RRE.r2); goto ok;
12905 case 0xb925: /* STURG */ goto unimplemented;
12906 case 0xb926: s390_format_RRE_RR(s390_irgen_LBR, ovl.fmt.RRE.r1,
12907 ovl.fmt.RRE.r2); goto ok;
12908 case 0xb927: s390_format_RRE_RR(s390_irgen_LHR, ovl.fmt.RRE.r1,
12909 ovl.fmt.RRE.r2); goto ok;
12910 case 0xb928: /* PCKMO */ goto unimplemented;
12911 case 0xb92b: /* KMO */ goto unimplemented;
12912 case 0xb92c: /* PCC */ goto unimplemented;
12913 case 0xb92d: /* KMCTR */ goto unimplemented;
12914 case 0xb92e: /* KM */ goto unimplemented;
12915 case 0xb92f: /* KMC */ goto unimplemented;
12916 case 0xb930: s390_format_RRE_RR(s390_irgen_CGFR, ovl.fmt.RRE.r1,
12917 ovl.fmt.RRE.r2); goto ok;
12918 case 0xb931: s390_format_RRE_RR(s390_irgen_CLGFR, ovl.fmt.RRE.r1,
12919 ovl.fmt.RRE.r2); goto ok;
12920 case 0xb93e: /* KIMD */ goto unimplemented;
12921 case 0xb93f: /* KLMD */ goto unimplemented;
12922 case 0xb941: /* CFDTR */ goto unimplemented;
12923 case 0xb942: /* CLGDTR */ goto unimplemented;
12924 case 0xb943: /* CLFDTR */ goto unimplemented;
12925 case 0xb946: s390_format_RRE_RR(s390_irgen_BCTGR, ovl.fmt.RRE.r1,
12926 ovl.fmt.RRE.r2); goto ok;
12927 case 0xb949: /* CFXTR */ goto unimplemented;
12928 case 0xb94a: /* CLGXTR */ goto unimplemented;
12929 case 0xb94b: /* CLFXTR */ goto unimplemented;
12930 case 0xb951: /* CDFTR */ goto unimplemented;
12931 case 0xb952: /* CDLGTR */ goto unimplemented;
12932 case 0xb953: /* CDLFTR */ goto unimplemented;
12933 case 0xb959: /* CXFTR */ goto unimplemented;
12934 case 0xb95a: /* CXLGTR */ goto unimplemented;
12935 case 0xb95b: /* CXLFTR */ goto unimplemented;
12936 case 0xb960: /* CGRT */ goto unimplemented;
12937 case 0xb961: /* CLGRT */ goto unimplemented;
12938 case 0xb972: /* CRT */ goto unimplemented;
12939 case 0xb973: /* CLRT */ goto unimplemented;
12940 case 0xb980: s390_format_RRE_RR(s390_irgen_NGR, ovl.fmt.RRE.r1,
12941 ovl.fmt.RRE.r2); goto ok;
12942 case 0xb981: s390_format_RRE_RR(s390_irgen_OGR, ovl.fmt.RRE.r1,
12943 ovl.fmt.RRE.r2); goto ok;
12944 case 0xb982: s390_format_RRE_RR(s390_irgen_XGR, ovl.fmt.RRE.r1,
12945 ovl.fmt.RRE.r2); goto ok;
12946 case 0xb983: s390_format_RRE_RR(s390_irgen_FLOGR, ovl.fmt.RRE.r1,
12947 ovl.fmt.RRE.r2); goto ok;
12948 case 0xb984: s390_format_RRE_RR(s390_irgen_LLGCR, ovl.fmt.RRE.r1,
12949 ovl.fmt.RRE.r2); goto ok;
12950 case 0xb985: s390_format_RRE_RR(s390_irgen_LLGHR, ovl.fmt.RRE.r1,
12951 ovl.fmt.RRE.r2); goto ok;
12952 case 0xb986: s390_format_RRE_RR(s390_irgen_MLGR, ovl.fmt.RRE.r1,
12953 ovl.fmt.RRE.r2); goto ok;
12954 case 0xb987: s390_format_RRE_RR(s390_irgen_DLGR, ovl.fmt.RRE.r1,
12955 ovl.fmt.RRE.r2); goto ok;
12956 case 0xb988: s390_format_RRE_RR(s390_irgen_ALCGR, ovl.fmt.RRE.r1,
12957 ovl.fmt.RRE.r2); goto ok;
12958 case 0xb989: s390_format_RRE_RR(s390_irgen_SLBGR, ovl.fmt.RRE.r1,
12959 ovl.fmt.RRE.r2); goto ok;
12960 case 0xb98a: /* CSPG */ goto unimplemented;
12961 case 0xb98d: /* EPSW */ goto unimplemented;
12962 case 0xb98e: /* IDTE */ goto unimplemented;
florian730448f2012-02-04 17:07:07 +000012963 case 0xb990: s390_format_RRF_M0RERE(s390_irgen_TRTT, ovl.fmt.RRF3.r3,
12964 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
12965 case 0xb991: s390_format_RRF_M0RERE(s390_irgen_TRTO, ovl.fmt.RRF3.r3,
12966 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
12967 case 0xb992: s390_format_RRF_M0RERE(s390_irgen_TROT, ovl.fmt.RRF3.r3,
12968 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
florian9af37692012-01-15 21:01:16 +000012969 case 0xb993: s390_format_RRF_M0RERE(s390_irgen_TROO, ovl.fmt.RRF3.r3,
12970 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000012971 case 0xb994: s390_format_RRE_RR(s390_irgen_LLCR, ovl.fmt.RRE.r1,
12972 ovl.fmt.RRE.r2); goto ok;
12973 case 0xb995: s390_format_RRE_RR(s390_irgen_LLHR, ovl.fmt.RRE.r1,
12974 ovl.fmt.RRE.r2); goto ok;
12975 case 0xb996: s390_format_RRE_RR(s390_irgen_MLR, ovl.fmt.RRE.r1,
12976 ovl.fmt.RRE.r2); goto ok;
12977 case 0xb997: s390_format_RRE_RR(s390_irgen_DLR, ovl.fmt.RRE.r1,
12978 ovl.fmt.RRE.r2); goto ok;
12979 case 0xb998: s390_format_RRE_RR(s390_irgen_ALCR, ovl.fmt.RRE.r1,
12980 ovl.fmt.RRE.r2); goto ok;
12981 case 0xb999: s390_format_RRE_RR(s390_irgen_SLBR, ovl.fmt.RRE.r1,
12982 ovl.fmt.RRE.r2); goto ok;
12983 case 0xb99a: /* EPAIR */ goto unimplemented;
12984 case 0xb99b: /* ESAIR */ goto unimplemented;
12985 case 0xb99d: /* ESEA */ goto unimplemented;
12986 case 0xb99e: /* PTI */ goto unimplemented;
12987 case 0xb99f: /* SSAIR */ goto unimplemented;
12988 case 0xb9a2: /* PTF */ goto unimplemented;
12989 case 0xb9aa: /* LPTEA */ goto unimplemented;
12990 case 0xb9ae: /* RRBM */ goto unimplemented;
12991 case 0xb9af: /* PFMF */ goto unimplemented;
florian3f8a96a2012-08-05 02:59:55 +000012992 case 0xb9b0: s390_format_RRF_M0RERE(s390_irgen_CU14, ovl.fmt.RRF3.r3,
12993 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
12994 goto ok;
florian2a415a12012-07-21 17:41:36 +000012995 case 0xb9b1: s390_format_RRF_M0RERE(s390_irgen_CU24, ovl.fmt.RRF3.r3,
12996 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
12997 goto ok;
florianaf2194f2012-08-06 00:07:54 +000012998 case 0xb9b2: s390_format_RRE_RR(s390_irgen_CU41, ovl.fmt.RRE.r1,
12999 ovl.fmt.RRE.r2); goto ok;
florian956194b2012-07-28 22:18:32 +000013000 case 0xb9b3: s390_format_RRE_RR(s390_irgen_CU42, ovl.fmt.RRE.r1,
13001 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013002 case 0xb9bd: /* TRTRE */ goto unimplemented;
13003 case 0xb9be: /* SRSTU */ goto unimplemented;
13004 case 0xb9bf: /* TRTE */ goto unimplemented;
13005 case 0xb9c8: s390_format_RRF_R0RR2(s390_irgen_AHHHR, ovl.fmt.RRF4.r3,
13006 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13007 goto ok;
13008 case 0xb9c9: s390_format_RRF_R0RR2(s390_irgen_SHHHR, ovl.fmt.RRF4.r3,
13009 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13010 goto ok;
13011 case 0xb9ca: s390_format_RRF_R0RR2(s390_irgen_ALHHHR, ovl.fmt.RRF4.r3,
13012 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13013 goto ok;
13014 case 0xb9cb: s390_format_RRF_R0RR2(s390_irgen_SLHHHR, ovl.fmt.RRF4.r3,
13015 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13016 goto ok;
13017 case 0xb9cd: s390_format_RRE_RR(s390_irgen_CHHR, ovl.fmt.RRE.r1,
13018 ovl.fmt.RRE.r2); goto ok;
13019 case 0xb9cf: s390_format_RRE_RR(s390_irgen_CLHHR, ovl.fmt.RRE.r1,
13020 ovl.fmt.RRE.r2); goto ok;
13021 case 0xb9d8: s390_format_RRF_R0RR2(s390_irgen_AHHLR, ovl.fmt.RRF4.r3,
13022 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13023 goto ok;
13024 case 0xb9d9: s390_format_RRF_R0RR2(s390_irgen_SHHLR, ovl.fmt.RRF4.r3,
13025 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13026 goto ok;
13027 case 0xb9da: s390_format_RRF_R0RR2(s390_irgen_ALHHLR, ovl.fmt.RRF4.r3,
13028 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13029 goto ok;
13030 case 0xb9db: s390_format_RRF_R0RR2(s390_irgen_SLHHLR, ovl.fmt.RRF4.r3,
13031 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13032 goto ok;
13033 case 0xb9dd: s390_format_RRE_RR(s390_irgen_CHLR, ovl.fmt.RRE.r1,
13034 ovl.fmt.RRE.r2); goto ok;
13035 case 0xb9df: s390_format_RRE_RR(s390_irgen_CLHLR, ovl.fmt.RRE.r1,
13036 ovl.fmt.RRE.r2); goto ok;
13037 case 0xb9e1: /* POPCNT */ goto unimplemented;
sewardjd7bde722011-04-05 13:19:33 +000013038 case 0xb9e2: s390_format_RRF_U0RR(s390_irgen_LOCGR, ovl.fmt.RRF3.r3,
13039 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2,
13040 S390_XMNM_LOCGR); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013041 case 0xb9e4: s390_format_RRF_R0RR2(s390_irgen_NGRK, ovl.fmt.RRF4.r3,
13042 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13043 goto ok;
13044 case 0xb9e6: s390_format_RRF_R0RR2(s390_irgen_OGRK, ovl.fmt.RRF4.r3,
13045 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13046 goto ok;
13047 case 0xb9e7: s390_format_RRF_R0RR2(s390_irgen_XGRK, ovl.fmt.RRF4.r3,
13048 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13049 goto ok;
13050 case 0xb9e8: s390_format_RRF_R0RR2(s390_irgen_AGRK, ovl.fmt.RRF4.r3,
13051 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13052 goto ok;
13053 case 0xb9e9: s390_format_RRF_R0RR2(s390_irgen_SGRK, ovl.fmt.RRF4.r3,
13054 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13055 goto ok;
13056 case 0xb9ea: s390_format_RRF_R0RR2(s390_irgen_ALGRK, ovl.fmt.RRF4.r3,
13057 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13058 goto ok;
13059 case 0xb9eb: s390_format_RRF_R0RR2(s390_irgen_SLGRK, ovl.fmt.RRF4.r3,
13060 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13061 goto ok;
sewardjd7bde722011-04-05 13:19:33 +000013062 case 0xb9f2: s390_format_RRF_U0RR(s390_irgen_LOCR, ovl.fmt.RRF3.r3,
13063 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2,
13064 S390_XMNM_LOCR); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013065 case 0xb9f4: s390_format_RRF_R0RR2(s390_irgen_NRK, ovl.fmt.RRF4.r3,
13066 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13067 goto ok;
13068 case 0xb9f6: s390_format_RRF_R0RR2(s390_irgen_ORK, ovl.fmt.RRF4.r3,
13069 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13070 goto ok;
13071 case 0xb9f7: s390_format_RRF_R0RR2(s390_irgen_XRK, ovl.fmt.RRF4.r3,
13072 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13073 goto ok;
13074 case 0xb9f8: s390_format_RRF_R0RR2(s390_irgen_ARK, ovl.fmt.RRF4.r3,
13075 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13076 goto ok;
13077 case 0xb9f9: s390_format_RRF_R0RR2(s390_irgen_SRK, ovl.fmt.RRF4.r3,
13078 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13079 goto ok;
13080 case 0xb9fa: s390_format_RRF_R0RR2(s390_irgen_ALRK, ovl.fmt.RRF4.r3,
13081 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13082 goto ok;
13083 case 0xb9fb: s390_format_RRF_R0RR2(s390_irgen_SLRK, ovl.fmt.RRF4.r3,
13084 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13085 goto ok;
13086 }
13087
13088 switch ((ovl.value & 0xff000000) >> 24) {
13089 case 0x40: s390_format_RX_RRRD(s390_irgen_STH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13090 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13091 case 0x41: s390_format_RX_RRRD(s390_irgen_LA, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13092 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13093 case 0x42: s390_format_RX_RRRD(s390_irgen_STC, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13094 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13095 case 0x43: s390_format_RX_RRRD(s390_irgen_IC, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13096 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13097 case 0x44: s390_format_RX_RRRD(s390_irgen_EX, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13098 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13099 case 0x45: /* BAL */ goto unimplemented;
13100 case 0x46: s390_format_RX_RRRD(s390_irgen_BCT, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13101 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13102 case 0x47: s390_format_RX(s390_irgen_BC, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13103 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13104 case 0x48: s390_format_RX_RRRD(s390_irgen_LH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13105 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13106 case 0x49: s390_format_RX_RRRD(s390_irgen_CH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13107 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13108 case 0x4a: s390_format_RX_RRRD(s390_irgen_AH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13109 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13110 case 0x4b: s390_format_RX_RRRD(s390_irgen_SH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13111 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13112 case 0x4c: s390_format_RX_RRRD(s390_irgen_MH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13113 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13114 case 0x4d: s390_format_RX_RRRD(s390_irgen_BAS, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13115 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13116 case 0x4e: s390_format_RX_RRRD(s390_irgen_CVD, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13117 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13118 case 0x4f: s390_format_RX_RRRD(s390_irgen_CVB, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13119 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13120 case 0x50: s390_format_RX_RRRD(s390_irgen_ST, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13121 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13122 case 0x51: s390_format_RX_RRRD(s390_irgen_LAE, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13123 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13124 case 0x54: s390_format_RX_RRRD(s390_irgen_N, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13125 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13126 case 0x55: s390_format_RX_RRRD(s390_irgen_CL, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13127 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13128 case 0x56: s390_format_RX_RRRD(s390_irgen_O, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13129 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13130 case 0x57: s390_format_RX_RRRD(s390_irgen_X, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13131 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13132 case 0x58: s390_format_RX_RRRD(s390_irgen_L, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13133 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13134 case 0x59: s390_format_RX_RRRD(s390_irgen_C, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13135 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13136 case 0x5a: s390_format_RX_RRRD(s390_irgen_A, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13137 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13138 case 0x5b: s390_format_RX_RRRD(s390_irgen_S, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13139 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13140 case 0x5c: s390_format_RX_RRRD(s390_irgen_M, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13141 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13142 case 0x5d: s390_format_RX_RRRD(s390_irgen_D, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13143 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13144 case 0x5e: s390_format_RX_RRRD(s390_irgen_AL, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13145 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13146 case 0x5f: s390_format_RX_RRRD(s390_irgen_SL, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13147 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13148 case 0x60: s390_format_RX_FRRD(s390_irgen_STD, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13149 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13150 case 0x67: /* MXD */ goto unimplemented;
13151 case 0x68: s390_format_RX_FRRD(s390_irgen_LD, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13152 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13153 case 0x69: /* CD */ goto unimplemented;
13154 case 0x6a: /* AD */ goto unimplemented;
13155 case 0x6b: /* SD */ goto unimplemented;
13156 case 0x6c: /* MD */ goto unimplemented;
13157 case 0x6d: /* DD */ goto unimplemented;
13158 case 0x6e: /* AW */ goto unimplemented;
13159 case 0x6f: /* SW */ goto unimplemented;
13160 case 0x70: s390_format_RX_FRRD(s390_irgen_STE, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13161 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13162 case 0x71: s390_format_RX_RRRD(s390_irgen_MS, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13163 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13164 case 0x78: s390_format_RX_FRRD(s390_irgen_LE, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13165 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13166 case 0x79: /* CE */ goto unimplemented;
13167 case 0x7a: /* AE */ goto unimplemented;
13168 case 0x7b: /* SE */ goto unimplemented;
13169 case 0x7c: /* MDE */ goto unimplemented;
13170 case 0x7d: /* DE */ goto unimplemented;
13171 case 0x7e: /* AU */ goto unimplemented;
13172 case 0x7f: /* SU */ goto unimplemented;
13173 case 0x83: /* DIAG */ goto unimplemented;
13174 case 0x84: s390_format_RSI_RRP(s390_irgen_BRXH, ovl.fmt.RSI.r1,
13175 ovl.fmt.RSI.r3, ovl.fmt.RSI.i2); goto ok;
13176 case 0x85: s390_format_RSI_RRP(s390_irgen_BRXLE, ovl.fmt.RSI.r1,
13177 ovl.fmt.RSI.r3, ovl.fmt.RSI.i2); goto ok;
13178 case 0x86: s390_format_RS_RRRD(s390_irgen_BXH, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13179 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13180 case 0x87: s390_format_RS_RRRD(s390_irgen_BXLE, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13181 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13182 case 0x88: s390_format_RS_R0RD(s390_irgen_SRL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
13183 ovl.fmt.RS.d2); goto ok;
13184 case 0x89: s390_format_RS_R0RD(s390_irgen_SLL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
13185 ovl.fmt.RS.d2); goto ok;
13186 case 0x8a: s390_format_RS_R0RD(s390_irgen_SRA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
13187 ovl.fmt.RS.d2); goto ok;
13188 case 0x8b: s390_format_RS_R0RD(s390_irgen_SLA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
13189 ovl.fmt.RS.d2); goto ok;
13190 case 0x8c: s390_format_RS_R0RD(s390_irgen_SRDL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
13191 ovl.fmt.RS.d2); goto ok;
13192 case 0x8d: s390_format_RS_R0RD(s390_irgen_SLDL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
13193 ovl.fmt.RS.d2); goto ok;
13194 case 0x8e: s390_format_RS_R0RD(s390_irgen_SRDA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
13195 ovl.fmt.RS.d2); goto ok;
13196 case 0x8f: s390_format_RS_R0RD(s390_irgen_SLDA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
13197 ovl.fmt.RS.d2); goto ok;
13198 case 0x90: s390_format_RS_RRRD(s390_irgen_STM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13199 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13200 case 0x91: s390_format_SI_URD(s390_irgen_TM, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
13201 ovl.fmt.SI.d1); goto ok;
13202 case 0x92: s390_format_SI_URD(s390_irgen_MVI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
13203 ovl.fmt.SI.d1); goto ok;
13204 case 0x94: s390_format_SI_URD(s390_irgen_NI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
13205 ovl.fmt.SI.d1); goto ok;
13206 case 0x95: s390_format_SI_URD(s390_irgen_CLI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
13207 ovl.fmt.SI.d1); goto ok;
13208 case 0x96: s390_format_SI_URD(s390_irgen_OI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
13209 ovl.fmt.SI.d1); goto ok;
13210 case 0x97: s390_format_SI_URD(s390_irgen_XI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
13211 ovl.fmt.SI.d1); goto ok;
13212 case 0x98: s390_format_RS_RRRD(s390_irgen_LM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13213 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13214 case 0x99: /* TRACE */ goto unimplemented;
13215 case 0x9a: s390_format_RS_AARD(s390_irgen_LAM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13216 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13217 case 0x9b: s390_format_RS_AARD(s390_irgen_STAM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13218 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13219 case 0xa8: s390_format_RS_RRRD(s390_irgen_MVCLE, ovl.fmt.RS.r1,
13220 ovl.fmt.RS.r3, ovl.fmt.RS.b2, ovl.fmt.RS.d2);
13221 goto ok;
13222 case 0xa9: s390_format_RS_RRRD(s390_irgen_CLCLE, ovl.fmt.RS.r1,
13223 ovl.fmt.RS.r3, ovl.fmt.RS.b2, ovl.fmt.RS.d2);
13224 goto ok;
13225 case 0xac: /* STNSM */ goto unimplemented;
13226 case 0xad: /* STOSM */ goto unimplemented;
13227 case 0xae: /* SIGP */ goto unimplemented;
13228 case 0xaf: /* MC */ goto unimplemented;
13229 case 0xb1: /* LRA */ goto unimplemented;
13230 case 0xb6: /* STCTL */ goto unimplemented;
13231 case 0xb7: /* LCTL */ goto unimplemented;
13232 case 0xba: s390_format_RS_RRRD(s390_irgen_CS, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13233 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
florian448cbba2012-06-06 02:26:01 +000013234 case 0xbb: s390_format_RS_RRRD(s390_irgen_CDS, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13235 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013236 case 0xbd: s390_format_RS_RURD(s390_irgen_CLM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13237 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13238 case 0xbe: s390_format_RS_RURD(s390_irgen_STCM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13239 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13240 case 0xbf: s390_format_RS_RURD(s390_irgen_ICM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13241 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13242 }
13243
13244 return S390_DECODE_UNKNOWN_INSN;
13245
13246ok:
13247 return S390_DECODE_OK;
13248
13249unimplemented:
13250 return S390_DECODE_UNIMPLEMENTED_INSN;
13251}
13252
13253static s390_decode_t
13254s390_decode_6byte_and_irgen(UChar *bytes)
13255{
13256 typedef union {
13257 struct {
13258 unsigned int op1 : 8;
13259 unsigned int r1 : 4;
13260 unsigned int r3 : 4;
13261 unsigned int i2 : 16;
13262 unsigned int : 8;
13263 unsigned int op2 : 8;
13264 } RIE;
13265 struct {
13266 unsigned int op1 : 8;
13267 unsigned int r1 : 4;
13268 unsigned int r2 : 4;
13269 unsigned int i3 : 8;
13270 unsigned int i4 : 8;
13271 unsigned int i5 : 8;
13272 unsigned int op2 : 8;
13273 } RIE_RRUUU;
13274 struct {
13275 unsigned int op1 : 8;
13276 unsigned int r1 : 4;
13277 unsigned int : 4;
13278 unsigned int i2 : 16;
13279 unsigned int m3 : 4;
13280 unsigned int : 4;
13281 unsigned int op2 : 8;
13282 } RIEv1;
13283 struct {
13284 unsigned int op1 : 8;
13285 unsigned int r1 : 4;
13286 unsigned int r2 : 4;
13287 unsigned int i4 : 16;
13288 unsigned int m3 : 4;
13289 unsigned int : 4;
13290 unsigned int op2 : 8;
13291 } RIE_RRPU;
13292 struct {
13293 unsigned int op1 : 8;
13294 unsigned int r1 : 4;
13295 unsigned int m3 : 4;
13296 unsigned int i4 : 16;
13297 unsigned int i2 : 8;
13298 unsigned int op2 : 8;
13299 } RIEv3;
13300 struct {
13301 unsigned int op1 : 8;
13302 unsigned int r1 : 4;
13303 unsigned int op2 : 4;
13304 unsigned int i2 : 32;
13305 } RIL;
13306 struct {
13307 unsigned int op1 : 8;
13308 unsigned int r1 : 4;
13309 unsigned int m3 : 4;
13310 unsigned int b4 : 4;
13311 unsigned int d4 : 12;
13312 unsigned int i2 : 8;
13313 unsigned int op2 : 8;
13314 } RIS;
13315 struct {
13316 unsigned int op1 : 8;
13317 unsigned int r1 : 4;
13318 unsigned int r2 : 4;
13319 unsigned int b4 : 4;
13320 unsigned int d4 : 12;
13321 unsigned int m3 : 4;
13322 unsigned int : 4;
13323 unsigned int op2 : 8;
13324 } RRS;
13325 struct {
13326 unsigned int op1 : 8;
13327 unsigned int l1 : 4;
13328 unsigned int : 4;
13329 unsigned int b1 : 4;
13330 unsigned int d1 : 12;
13331 unsigned int : 8;
13332 unsigned int op2 : 8;
13333 } RSL;
13334 struct {
13335 unsigned int op1 : 8;
13336 unsigned int r1 : 4;
13337 unsigned int r3 : 4;
13338 unsigned int b2 : 4;
13339 unsigned int dl2 : 12;
13340 unsigned int dh2 : 8;
13341 unsigned int op2 : 8;
13342 } RSY;
13343 struct {
13344 unsigned int op1 : 8;
13345 unsigned int r1 : 4;
13346 unsigned int x2 : 4;
13347 unsigned int b2 : 4;
13348 unsigned int d2 : 12;
13349 unsigned int : 8;
13350 unsigned int op2 : 8;
13351 } RXE;
13352 struct {
13353 unsigned int op1 : 8;
13354 unsigned int r3 : 4;
13355 unsigned int x2 : 4;
13356 unsigned int b2 : 4;
13357 unsigned int d2 : 12;
13358 unsigned int r1 : 4;
13359 unsigned int : 4;
13360 unsigned int op2 : 8;
13361 } RXF;
13362 struct {
13363 unsigned int op1 : 8;
13364 unsigned int r1 : 4;
13365 unsigned int x2 : 4;
13366 unsigned int b2 : 4;
13367 unsigned int dl2 : 12;
13368 unsigned int dh2 : 8;
13369 unsigned int op2 : 8;
13370 } RXY;
13371 struct {
13372 unsigned int op1 : 8;
13373 unsigned int i2 : 8;
13374 unsigned int b1 : 4;
13375 unsigned int dl1 : 12;
13376 unsigned int dh1 : 8;
13377 unsigned int op2 : 8;
13378 } SIY;
13379 struct {
13380 unsigned int op : 8;
13381 unsigned int l : 8;
13382 unsigned int b1 : 4;
13383 unsigned int d1 : 12;
13384 unsigned int b2 : 4;
13385 unsigned int d2 : 12;
13386 } SS;
13387 struct {
13388 unsigned int op : 8;
13389 unsigned int l1 : 4;
13390 unsigned int l2 : 4;
13391 unsigned int b1 : 4;
13392 unsigned int d1 : 12;
13393 unsigned int b2 : 4;
13394 unsigned int d2 : 12;
13395 } SS_LLRDRD;
13396 struct {
13397 unsigned int op : 8;
13398 unsigned int r1 : 4;
13399 unsigned int r3 : 4;
13400 unsigned int b2 : 4;
13401 unsigned int d2 : 12;
13402 unsigned int b4 : 4;
13403 unsigned int d4 : 12;
13404 } SS_RRRDRD2;
13405 struct {
13406 unsigned int op : 16;
13407 unsigned int b1 : 4;
13408 unsigned int d1 : 12;
13409 unsigned int b2 : 4;
13410 unsigned int d2 : 12;
13411 } SSE;
13412 struct {
13413 unsigned int op1 : 8;
13414 unsigned int r3 : 4;
13415 unsigned int op2 : 4;
13416 unsigned int b1 : 4;
13417 unsigned int d1 : 12;
13418 unsigned int b2 : 4;
13419 unsigned int d2 : 12;
13420 } SSF;
13421 struct {
13422 unsigned int op : 16;
13423 unsigned int b1 : 4;
13424 unsigned int d1 : 12;
13425 unsigned int i2 : 16;
13426 } SIL;
13427 } formats;
13428 union {
13429 formats fmt;
13430 ULong value;
13431 } ovl;
13432
13433 vassert(sizeof(formats) == 6);
13434
13435 ((char *)(&ovl.value))[0] = bytes[0];
13436 ((char *)(&ovl.value))[1] = bytes[1];
13437 ((char *)(&ovl.value))[2] = bytes[2];
13438 ((char *)(&ovl.value))[3] = bytes[3];
13439 ((char *)(&ovl.value))[4] = bytes[4];
13440 ((char *)(&ovl.value))[5] = bytes[5];
13441 ((char *)(&ovl.value))[6] = 0x0;
13442 ((char *)(&ovl.value))[7] = 0x0;
13443
13444 switch ((ovl.value >> 16) & 0xff00000000ffULL) {
13445 case 0xe30000000002ULL: s390_format_RXY_RRRD(s390_irgen_LTG, ovl.fmt.RXY.r1,
13446 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13447 ovl.fmt.RXY.dl2,
13448 ovl.fmt.RXY.dh2); goto ok;
13449 case 0xe30000000003ULL: /* LRAG */ goto unimplemented;
13450 case 0xe30000000004ULL: s390_format_RXY_RRRD(s390_irgen_LG, ovl.fmt.RXY.r1,
13451 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13452 ovl.fmt.RXY.dl2,
13453 ovl.fmt.RXY.dh2); goto ok;
13454 case 0xe30000000006ULL: s390_format_RXY_RRRD(s390_irgen_CVBY, ovl.fmt.RXY.r1,
13455 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13456 ovl.fmt.RXY.dl2,
13457 ovl.fmt.RXY.dh2); goto ok;
13458 case 0xe30000000008ULL: s390_format_RXY_RRRD(s390_irgen_AG, ovl.fmt.RXY.r1,
13459 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13460 ovl.fmt.RXY.dl2,
13461 ovl.fmt.RXY.dh2); goto ok;
13462 case 0xe30000000009ULL: s390_format_RXY_RRRD(s390_irgen_SG, ovl.fmt.RXY.r1,
13463 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13464 ovl.fmt.RXY.dl2,
13465 ovl.fmt.RXY.dh2); goto ok;
13466 case 0xe3000000000aULL: s390_format_RXY_RRRD(s390_irgen_ALG, ovl.fmt.RXY.r1,
13467 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13468 ovl.fmt.RXY.dl2,
13469 ovl.fmt.RXY.dh2); goto ok;
13470 case 0xe3000000000bULL: s390_format_RXY_RRRD(s390_irgen_SLG, 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 0xe3000000000cULL: s390_format_RXY_RRRD(s390_irgen_MSG, ovl.fmt.RXY.r1,
13475 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13476 ovl.fmt.RXY.dl2,
13477 ovl.fmt.RXY.dh2); goto ok;
13478 case 0xe3000000000dULL: s390_format_RXY_RRRD(s390_irgen_DSG, ovl.fmt.RXY.r1,
13479 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13480 ovl.fmt.RXY.dl2,
13481 ovl.fmt.RXY.dh2); goto ok;
13482 case 0xe3000000000eULL: /* CVBG */ goto unimplemented;
13483 case 0xe3000000000fULL: s390_format_RXY_RRRD(s390_irgen_LRVG, 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 0xe30000000012ULL: s390_format_RXY_RRRD(s390_irgen_LT, 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 0xe30000000013ULL: /* LRAY */ goto unimplemented;
13492 case 0xe30000000014ULL: s390_format_RXY_RRRD(s390_irgen_LGF, ovl.fmt.RXY.r1,
13493 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13494 ovl.fmt.RXY.dl2,
13495 ovl.fmt.RXY.dh2); goto ok;
13496 case 0xe30000000015ULL: s390_format_RXY_RRRD(s390_irgen_LGH, ovl.fmt.RXY.r1,
13497 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13498 ovl.fmt.RXY.dl2,
13499 ovl.fmt.RXY.dh2); goto ok;
13500 case 0xe30000000016ULL: s390_format_RXY_RRRD(s390_irgen_LLGF, ovl.fmt.RXY.r1,
13501 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13502 ovl.fmt.RXY.dl2,
13503 ovl.fmt.RXY.dh2); goto ok;
13504 case 0xe30000000017ULL: s390_format_RXY_RRRD(s390_irgen_LLGT, ovl.fmt.RXY.r1,
13505 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13506 ovl.fmt.RXY.dl2,
13507 ovl.fmt.RXY.dh2); goto ok;
13508 case 0xe30000000018ULL: s390_format_RXY_RRRD(s390_irgen_AGF, 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 0xe30000000019ULL: s390_format_RXY_RRRD(s390_irgen_SGF, 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 0xe3000000001aULL: s390_format_RXY_RRRD(s390_irgen_ALGF, ovl.fmt.RXY.r1,
13517 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13518 ovl.fmt.RXY.dl2,
13519 ovl.fmt.RXY.dh2); goto ok;
13520 case 0xe3000000001bULL: s390_format_RXY_RRRD(s390_irgen_SLGF, ovl.fmt.RXY.r1,
13521 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13522 ovl.fmt.RXY.dl2,
13523 ovl.fmt.RXY.dh2); goto ok;
13524 case 0xe3000000001cULL: s390_format_RXY_RRRD(s390_irgen_MSGF, ovl.fmt.RXY.r1,
13525 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13526 ovl.fmt.RXY.dl2,
13527 ovl.fmt.RXY.dh2); goto ok;
13528 case 0xe3000000001dULL: s390_format_RXY_RRRD(s390_irgen_DSGF, ovl.fmt.RXY.r1,
13529 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13530 ovl.fmt.RXY.dl2,
13531 ovl.fmt.RXY.dh2); goto ok;
13532 case 0xe3000000001eULL: s390_format_RXY_RRRD(s390_irgen_LRV, ovl.fmt.RXY.r1,
13533 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13534 ovl.fmt.RXY.dl2,
13535 ovl.fmt.RXY.dh2); goto ok;
13536 case 0xe3000000001fULL: s390_format_RXY_RRRD(s390_irgen_LRVH, ovl.fmt.RXY.r1,
13537 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13538 ovl.fmt.RXY.dl2,
13539 ovl.fmt.RXY.dh2); goto ok;
13540 case 0xe30000000020ULL: s390_format_RXY_RRRD(s390_irgen_CG, ovl.fmt.RXY.r1,
13541 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13542 ovl.fmt.RXY.dl2,
13543 ovl.fmt.RXY.dh2); goto ok;
13544 case 0xe30000000021ULL: s390_format_RXY_RRRD(s390_irgen_CLG, ovl.fmt.RXY.r1,
13545 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13546 ovl.fmt.RXY.dl2,
13547 ovl.fmt.RXY.dh2); goto ok;
13548 case 0xe30000000024ULL: s390_format_RXY_RRRD(s390_irgen_STG, ovl.fmt.RXY.r1,
13549 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13550 ovl.fmt.RXY.dl2,
13551 ovl.fmt.RXY.dh2); goto ok;
13552 case 0xe30000000026ULL: s390_format_RXY_RRRD(s390_irgen_CVDY, ovl.fmt.RXY.r1,
13553 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13554 ovl.fmt.RXY.dl2,
13555 ovl.fmt.RXY.dh2); goto ok;
13556 case 0xe3000000002eULL: /* CVDG */ goto unimplemented;
13557 case 0xe3000000002fULL: s390_format_RXY_RRRD(s390_irgen_STRVG,
13558 ovl.fmt.RXY.r1, ovl.fmt.RXY.x2,
13559 ovl.fmt.RXY.b2, ovl.fmt.RXY.dl2,
13560 ovl.fmt.RXY.dh2); goto ok;
13561 case 0xe30000000030ULL: s390_format_RXY_RRRD(s390_irgen_CGF, 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 0xe30000000031ULL: s390_format_RXY_RRRD(s390_irgen_CLGF, 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 0xe30000000032ULL: s390_format_RXY_RRRD(s390_irgen_LTGF, 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 0xe30000000034ULL: s390_format_RXY_RRRD(s390_irgen_CGH, 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 0xe30000000036ULL: s390_format_RXY_URRD(s390_irgen_PFD, 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 0xe3000000003eULL: s390_format_RXY_RRRD(s390_irgen_STRV, ovl.fmt.RXY.r1,
13582 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13583 ovl.fmt.RXY.dl2,
13584 ovl.fmt.RXY.dh2); goto ok;
13585 case 0xe3000000003fULL: s390_format_RXY_RRRD(s390_irgen_STRVH,
13586 ovl.fmt.RXY.r1, ovl.fmt.RXY.x2,
13587 ovl.fmt.RXY.b2, ovl.fmt.RXY.dl2,
13588 ovl.fmt.RXY.dh2); goto ok;
13589 case 0xe30000000046ULL: s390_format_RXY_RRRD(s390_irgen_BCTG, ovl.fmt.RXY.r1,
13590 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13591 ovl.fmt.RXY.dl2,
13592 ovl.fmt.RXY.dh2); goto ok;
13593 case 0xe30000000050ULL: s390_format_RXY_RRRD(s390_irgen_STY, ovl.fmt.RXY.r1,
13594 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13595 ovl.fmt.RXY.dl2,
13596 ovl.fmt.RXY.dh2); goto ok;
13597 case 0xe30000000051ULL: s390_format_RXY_RRRD(s390_irgen_MSY, ovl.fmt.RXY.r1,
13598 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13599 ovl.fmt.RXY.dl2,
13600 ovl.fmt.RXY.dh2); goto ok;
13601 case 0xe30000000054ULL: s390_format_RXY_RRRD(s390_irgen_NY, ovl.fmt.RXY.r1,
13602 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13603 ovl.fmt.RXY.dl2,
13604 ovl.fmt.RXY.dh2); goto ok;
13605 case 0xe30000000055ULL: s390_format_RXY_RRRD(s390_irgen_CLY, ovl.fmt.RXY.r1,
13606 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13607 ovl.fmt.RXY.dl2,
13608 ovl.fmt.RXY.dh2); goto ok;
13609 case 0xe30000000056ULL: s390_format_RXY_RRRD(s390_irgen_OY, ovl.fmt.RXY.r1,
13610 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13611 ovl.fmt.RXY.dl2,
13612 ovl.fmt.RXY.dh2); goto ok;
13613 case 0xe30000000057ULL: s390_format_RXY_RRRD(s390_irgen_XY, ovl.fmt.RXY.r1,
13614 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13615 ovl.fmt.RXY.dl2,
13616 ovl.fmt.RXY.dh2); goto ok;
13617 case 0xe30000000058ULL: s390_format_RXY_RRRD(s390_irgen_LY, ovl.fmt.RXY.r1,
13618 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13619 ovl.fmt.RXY.dl2,
13620 ovl.fmt.RXY.dh2); goto ok;
13621 case 0xe30000000059ULL: s390_format_RXY_RRRD(s390_irgen_CY, ovl.fmt.RXY.r1,
13622 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13623 ovl.fmt.RXY.dl2,
13624 ovl.fmt.RXY.dh2); goto ok;
13625 case 0xe3000000005aULL: s390_format_RXY_RRRD(s390_irgen_AY, ovl.fmt.RXY.r1,
13626 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13627 ovl.fmt.RXY.dl2,
13628 ovl.fmt.RXY.dh2); goto ok;
13629 case 0xe3000000005bULL: s390_format_RXY_RRRD(s390_irgen_SY, ovl.fmt.RXY.r1,
13630 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13631 ovl.fmt.RXY.dl2,
13632 ovl.fmt.RXY.dh2); goto ok;
13633 case 0xe3000000005cULL: s390_format_RXY_RRRD(s390_irgen_MFY, ovl.fmt.RXY.r1,
13634 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13635 ovl.fmt.RXY.dl2,
13636 ovl.fmt.RXY.dh2); goto ok;
13637 case 0xe3000000005eULL: s390_format_RXY_RRRD(s390_irgen_ALY, ovl.fmt.RXY.r1,
13638 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13639 ovl.fmt.RXY.dl2,
13640 ovl.fmt.RXY.dh2); goto ok;
13641 case 0xe3000000005fULL: s390_format_RXY_RRRD(s390_irgen_SLY, ovl.fmt.RXY.r1,
13642 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13643 ovl.fmt.RXY.dl2,
13644 ovl.fmt.RXY.dh2); goto ok;
13645 case 0xe30000000070ULL: s390_format_RXY_RRRD(s390_irgen_STHY, ovl.fmt.RXY.r1,
13646 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13647 ovl.fmt.RXY.dl2,
13648 ovl.fmt.RXY.dh2); goto ok;
13649 case 0xe30000000071ULL: s390_format_RXY_RRRD(s390_irgen_LAY, ovl.fmt.RXY.r1,
13650 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13651 ovl.fmt.RXY.dl2,
13652 ovl.fmt.RXY.dh2); goto ok;
13653 case 0xe30000000072ULL: s390_format_RXY_RRRD(s390_irgen_STCY, ovl.fmt.RXY.r1,
13654 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13655 ovl.fmt.RXY.dl2,
13656 ovl.fmt.RXY.dh2); goto ok;
13657 case 0xe30000000073ULL: s390_format_RXY_RRRD(s390_irgen_ICY, ovl.fmt.RXY.r1,
13658 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13659 ovl.fmt.RXY.dl2,
13660 ovl.fmt.RXY.dh2); goto ok;
13661 case 0xe30000000075ULL: s390_format_RXY_RRRD(s390_irgen_LAEY, ovl.fmt.RXY.r1,
13662 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13663 ovl.fmt.RXY.dl2,
13664 ovl.fmt.RXY.dh2); goto ok;
13665 case 0xe30000000076ULL: s390_format_RXY_RRRD(s390_irgen_LB, ovl.fmt.RXY.r1,
13666 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13667 ovl.fmt.RXY.dl2,
13668 ovl.fmt.RXY.dh2); goto ok;
13669 case 0xe30000000077ULL: s390_format_RXY_RRRD(s390_irgen_LGB, ovl.fmt.RXY.r1,
13670 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13671 ovl.fmt.RXY.dl2,
13672 ovl.fmt.RXY.dh2); goto ok;
13673 case 0xe30000000078ULL: s390_format_RXY_RRRD(s390_irgen_LHY, ovl.fmt.RXY.r1,
13674 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13675 ovl.fmt.RXY.dl2,
13676 ovl.fmt.RXY.dh2); goto ok;
13677 case 0xe30000000079ULL: s390_format_RXY_RRRD(s390_irgen_CHY, ovl.fmt.RXY.r1,
13678 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13679 ovl.fmt.RXY.dl2,
13680 ovl.fmt.RXY.dh2); goto ok;
13681 case 0xe3000000007aULL: s390_format_RXY_RRRD(s390_irgen_AHY, ovl.fmt.RXY.r1,
13682 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13683 ovl.fmt.RXY.dl2,
13684 ovl.fmt.RXY.dh2); goto ok;
13685 case 0xe3000000007bULL: s390_format_RXY_RRRD(s390_irgen_SHY, ovl.fmt.RXY.r1,
13686 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13687 ovl.fmt.RXY.dl2,
13688 ovl.fmt.RXY.dh2); goto ok;
13689 case 0xe3000000007cULL: s390_format_RXY_RRRD(s390_irgen_MHY, ovl.fmt.RXY.r1,
13690 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13691 ovl.fmt.RXY.dl2,
13692 ovl.fmt.RXY.dh2); goto ok;
13693 case 0xe30000000080ULL: s390_format_RXY_RRRD(s390_irgen_NG, ovl.fmt.RXY.r1,
13694 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13695 ovl.fmt.RXY.dl2,
13696 ovl.fmt.RXY.dh2); goto ok;
13697 case 0xe30000000081ULL: s390_format_RXY_RRRD(s390_irgen_OG, ovl.fmt.RXY.r1,
13698 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13699 ovl.fmt.RXY.dl2,
13700 ovl.fmt.RXY.dh2); goto ok;
13701 case 0xe30000000082ULL: s390_format_RXY_RRRD(s390_irgen_XG, ovl.fmt.RXY.r1,
13702 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13703 ovl.fmt.RXY.dl2,
13704 ovl.fmt.RXY.dh2); goto ok;
13705 case 0xe30000000086ULL: s390_format_RXY_RRRD(s390_irgen_MLG, ovl.fmt.RXY.r1,
13706 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13707 ovl.fmt.RXY.dl2,
13708 ovl.fmt.RXY.dh2); goto ok;
13709 case 0xe30000000087ULL: s390_format_RXY_RRRD(s390_irgen_DLG, ovl.fmt.RXY.r1,
13710 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13711 ovl.fmt.RXY.dl2,
13712 ovl.fmt.RXY.dh2); goto ok;
13713 case 0xe30000000088ULL: s390_format_RXY_RRRD(s390_irgen_ALCG, ovl.fmt.RXY.r1,
13714 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13715 ovl.fmt.RXY.dl2,
13716 ovl.fmt.RXY.dh2); goto ok;
13717 case 0xe30000000089ULL: s390_format_RXY_RRRD(s390_irgen_SLBG, ovl.fmt.RXY.r1,
13718 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13719 ovl.fmt.RXY.dl2,
13720 ovl.fmt.RXY.dh2); goto ok;
13721 case 0xe3000000008eULL: s390_format_RXY_RRRD(s390_irgen_STPQ, ovl.fmt.RXY.r1,
13722 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13723 ovl.fmt.RXY.dl2,
13724 ovl.fmt.RXY.dh2); goto ok;
13725 case 0xe3000000008fULL: s390_format_RXY_RRRD(s390_irgen_LPQ, ovl.fmt.RXY.r1,
13726 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13727 ovl.fmt.RXY.dl2,
13728 ovl.fmt.RXY.dh2); goto ok;
13729 case 0xe30000000090ULL: s390_format_RXY_RRRD(s390_irgen_LLGC, ovl.fmt.RXY.r1,
13730 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13731 ovl.fmt.RXY.dl2,
13732 ovl.fmt.RXY.dh2); goto ok;
13733 case 0xe30000000091ULL: s390_format_RXY_RRRD(s390_irgen_LLGH, ovl.fmt.RXY.r1,
13734 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13735 ovl.fmt.RXY.dl2,
13736 ovl.fmt.RXY.dh2); goto ok;
13737 case 0xe30000000094ULL: s390_format_RXY_RRRD(s390_irgen_LLC, ovl.fmt.RXY.r1,
13738 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13739 ovl.fmt.RXY.dl2,
13740 ovl.fmt.RXY.dh2); goto ok;
13741 case 0xe30000000095ULL: s390_format_RXY_RRRD(s390_irgen_LLH, ovl.fmt.RXY.r1,
13742 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13743 ovl.fmt.RXY.dl2,
13744 ovl.fmt.RXY.dh2); goto ok;
13745 case 0xe30000000096ULL: s390_format_RXY_RRRD(s390_irgen_ML, ovl.fmt.RXY.r1,
13746 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13747 ovl.fmt.RXY.dl2,
13748 ovl.fmt.RXY.dh2); goto ok;
13749 case 0xe30000000097ULL: s390_format_RXY_RRRD(s390_irgen_DL, ovl.fmt.RXY.r1,
13750 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13751 ovl.fmt.RXY.dl2,
13752 ovl.fmt.RXY.dh2); goto ok;
13753 case 0xe30000000098ULL: s390_format_RXY_RRRD(s390_irgen_ALC, ovl.fmt.RXY.r1,
13754 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13755 ovl.fmt.RXY.dl2,
13756 ovl.fmt.RXY.dh2); goto ok;
13757 case 0xe30000000099ULL: s390_format_RXY_RRRD(s390_irgen_SLB, ovl.fmt.RXY.r1,
13758 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13759 ovl.fmt.RXY.dl2,
13760 ovl.fmt.RXY.dh2); goto ok;
13761 case 0xe300000000c0ULL: s390_format_RXY_RRRD(s390_irgen_LBH, ovl.fmt.RXY.r1,
13762 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13763 ovl.fmt.RXY.dl2,
13764 ovl.fmt.RXY.dh2); goto ok;
13765 case 0xe300000000c2ULL: s390_format_RXY_RRRD(s390_irgen_LLCH, ovl.fmt.RXY.r1,
13766 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13767 ovl.fmt.RXY.dl2,
13768 ovl.fmt.RXY.dh2); goto ok;
13769 case 0xe300000000c3ULL: s390_format_RXY_RRRD(s390_irgen_STCH, ovl.fmt.RXY.r1,
13770 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13771 ovl.fmt.RXY.dl2,
13772 ovl.fmt.RXY.dh2); goto ok;
13773 case 0xe300000000c4ULL: s390_format_RXY_RRRD(s390_irgen_LHH, ovl.fmt.RXY.r1,
13774 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13775 ovl.fmt.RXY.dl2,
13776 ovl.fmt.RXY.dh2); goto ok;
13777 case 0xe300000000c6ULL: s390_format_RXY_RRRD(s390_irgen_LLHH, ovl.fmt.RXY.r1,
13778 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13779 ovl.fmt.RXY.dl2,
13780 ovl.fmt.RXY.dh2); goto ok;
13781 case 0xe300000000c7ULL: s390_format_RXY_RRRD(s390_irgen_STHH, ovl.fmt.RXY.r1,
13782 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13783 ovl.fmt.RXY.dl2,
13784 ovl.fmt.RXY.dh2); goto ok;
13785 case 0xe300000000caULL: s390_format_RXY_RRRD(s390_irgen_LFH, ovl.fmt.RXY.r1,
13786 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13787 ovl.fmt.RXY.dl2,
13788 ovl.fmt.RXY.dh2); goto ok;
13789 case 0xe300000000cbULL: s390_format_RXY_RRRD(s390_irgen_STFH, ovl.fmt.RXY.r1,
13790 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13791 ovl.fmt.RXY.dl2,
13792 ovl.fmt.RXY.dh2); goto ok;
13793 case 0xe300000000cdULL: s390_format_RXY_RRRD(s390_irgen_CHF, ovl.fmt.RXY.r1,
13794 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13795 ovl.fmt.RXY.dl2,
13796 ovl.fmt.RXY.dh2); goto ok;
13797 case 0xe300000000cfULL: s390_format_RXY_RRRD(s390_irgen_CLHF, ovl.fmt.RXY.r1,
13798 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13799 ovl.fmt.RXY.dl2,
13800 ovl.fmt.RXY.dh2); goto ok;
13801 case 0xeb0000000004ULL: s390_format_RSY_RRRD(s390_irgen_LMG, ovl.fmt.RSY.r1,
13802 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13803 ovl.fmt.RSY.dl2,
13804 ovl.fmt.RSY.dh2); goto ok;
13805 case 0xeb000000000aULL: s390_format_RSY_RRRD(s390_irgen_SRAG, ovl.fmt.RSY.r1,
13806 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13807 ovl.fmt.RSY.dl2,
13808 ovl.fmt.RSY.dh2); goto ok;
13809 case 0xeb000000000bULL: s390_format_RSY_RRRD(s390_irgen_SLAG, ovl.fmt.RSY.r1,
13810 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13811 ovl.fmt.RSY.dl2,
13812 ovl.fmt.RSY.dh2); goto ok;
13813 case 0xeb000000000cULL: s390_format_RSY_RRRD(s390_irgen_SRLG, ovl.fmt.RSY.r1,
13814 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13815 ovl.fmt.RSY.dl2,
13816 ovl.fmt.RSY.dh2); goto ok;
13817 case 0xeb000000000dULL: s390_format_RSY_RRRD(s390_irgen_SLLG, ovl.fmt.RSY.r1,
13818 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13819 ovl.fmt.RSY.dl2,
13820 ovl.fmt.RSY.dh2); goto ok;
13821 case 0xeb000000000fULL: /* TRACG */ goto unimplemented;
13822 case 0xeb0000000014ULL: s390_format_RSY_RRRD(s390_irgen_CSY, ovl.fmt.RSY.r1,
13823 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13824 ovl.fmt.RSY.dl2,
13825 ovl.fmt.RSY.dh2); goto ok;
13826 case 0xeb000000001cULL: s390_format_RSY_RRRD(s390_irgen_RLLG, 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 0xeb000000001dULL: s390_format_RSY_RRRD(s390_irgen_RLL, 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 0xeb0000000020ULL: s390_format_RSY_RURD(s390_irgen_CLMH, 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 0xeb0000000021ULL: s390_format_RSY_RURD(s390_irgen_CLMY, 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 0xeb0000000024ULL: s390_format_RSY_RRRD(s390_irgen_STMG, 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 0xeb0000000025ULL: /* STCTG */ goto unimplemented;
13847 case 0xeb0000000026ULL: s390_format_RSY_RRRD(s390_irgen_STMH, 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 0xeb000000002cULL: s390_format_RSY_RURD(s390_irgen_STCMH,
13852 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
13853 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
13854 ovl.fmt.RSY.dh2); goto ok;
13855 case 0xeb000000002dULL: s390_format_RSY_RURD(s390_irgen_STCMY,
13856 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
13857 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
13858 ovl.fmt.RSY.dh2); goto ok;
13859 case 0xeb000000002fULL: /* LCTLG */ goto unimplemented;
13860 case 0xeb0000000030ULL: s390_format_RSY_RRRD(s390_irgen_CSG, ovl.fmt.RSY.r1,
13861 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13862 ovl.fmt.RSY.dl2,
13863 ovl.fmt.RSY.dh2); goto ok;
florian448cbba2012-06-06 02:26:01 +000013864 case 0xeb0000000031ULL: s390_format_RSY_RRRD(s390_irgen_CDSY, ovl.fmt.RSY.r1,
13865 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13866 ovl.fmt.RSY.dl2,
13867 ovl.fmt.RSY.dh2); goto ok;
13868 case 0xeb000000003eULL: s390_format_RSY_RRRD(s390_irgen_CDSG, ovl.fmt.RSY.r1,
13869 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13870 ovl.fmt.RSY.dl2,
13871 ovl.fmt.RSY.dh2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013872 case 0xeb0000000044ULL: s390_format_RSY_RRRD(s390_irgen_BXHG, 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 0xeb0000000045ULL: s390_format_RSY_RRRD(s390_irgen_BXLEG,
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;
florian8c88cb62012-08-26 18:58:13 +000013880 case 0xeb000000004cULL: s390_format_RSY_RRRD(s390_irgen_ECAG, ovl.fmt.RSY.r1,
13881 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13882 ovl.fmt.RSY.dl2,
13883 ovl.fmt.RSY.dh2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013884 case 0xeb0000000051ULL: s390_format_SIY_URD(s390_irgen_TMY, ovl.fmt.SIY.i2,
13885 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
13886 ovl.fmt.SIY.dh1); goto ok;
13887 case 0xeb0000000052ULL: s390_format_SIY_URD(s390_irgen_MVIY, ovl.fmt.SIY.i2,
13888 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
13889 ovl.fmt.SIY.dh1); goto ok;
13890 case 0xeb0000000054ULL: s390_format_SIY_URD(s390_irgen_NIY, ovl.fmt.SIY.i2,
13891 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
13892 ovl.fmt.SIY.dh1); goto ok;
13893 case 0xeb0000000055ULL: s390_format_SIY_URD(s390_irgen_CLIY, ovl.fmt.SIY.i2,
13894 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
13895 ovl.fmt.SIY.dh1); goto ok;
13896 case 0xeb0000000056ULL: s390_format_SIY_URD(s390_irgen_OIY, ovl.fmt.SIY.i2,
13897 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
13898 ovl.fmt.SIY.dh1); goto ok;
13899 case 0xeb0000000057ULL: s390_format_SIY_URD(s390_irgen_XIY, ovl.fmt.SIY.i2,
13900 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
13901 ovl.fmt.SIY.dh1); goto ok;
13902 case 0xeb000000006aULL: s390_format_SIY_IRD(s390_irgen_ASI, ovl.fmt.SIY.i2,
13903 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
13904 ovl.fmt.SIY.dh1); goto ok;
13905 case 0xeb000000006eULL: s390_format_SIY_IRD(s390_irgen_ALSI, ovl.fmt.SIY.i2,
13906 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
13907 ovl.fmt.SIY.dh1); goto ok;
13908 case 0xeb000000007aULL: s390_format_SIY_IRD(s390_irgen_AGSI, ovl.fmt.SIY.i2,
13909 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
13910 ovl.fmt.SIY.dh1); goto ok;
13911 case 0xeb000000007eULL: s390_format_SIY_IRD(s390_irgen_ALGSI, ovl.fmt.SIY.i2,
13912 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
13913 ovl.fmt.SIY.dh1); goto ok;
13914 case 0xeb0000000080ULL: s390_format_RSY_RURD(s390_irgen_ICMH, ovl.fmt.RSY.r1,
13915 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13916 ovl.fmt.RSY.dl2,
13917 ovl.fmt.RSY.dh2); goto ok;
13918 case 0xeb0000000081ULL: s390_format_RSY_RURD(s390_irgen_ICMY, ovl.fmt.RSY.r1,
13919 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13920 ovl.fmt.RSY.dl2,
13921 ovl.fmt.RSY.dh2); goto ok;
13922 case 0xeb000000008eULL: /* MVCLU */ goto unimplemented;
13923 case 0xeb000000008fULL: /* CLCLU */ goto unimplemented;
13924 case 0xeb0000000090ULL: s390_format_RSY_RRRD(s390_irgen_STMY, ovl.fmt.RSY.r1,
13925 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13926 ovl.fmt.RSY.dl2,
13927 ovl.fmt.RSY.dh2); goto ok;
13928 case 0xeb0000000096ULL: s390_format_RSY_RRRD(s390_irgen_LMH, ovl.fmt.RSY.r1,
13929 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13930 ovl.fmt.RSY.dl2,
13931 ovl.fmt.RSY.dh2); goto ok;
13932 case 0xeb0000000098ULL: s390_format_RSY_RRRD(s390_irgen_LMY, ovl.fmt.RSY.r1,
13933 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13934 ovl.fmt.RSY.dl2,
13935 ovl.fmt.RSY.dh2); goto ok;
13936 case 0xeb000000009aULL: s390_format_RSY_AARD(s390_irgen_LAMY, ovl.fmt.RSY.r1,
13937 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13938 ovl.fmt.RSY.dl2,
13939 ovl.fmt.RSY.dh2); goto ok;
13940 case 0xeb000000009bULL: s390_format_RSY_AARD(s390_irgen_STAMY,
13941 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
13942 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
13943 ovl.fmt.RSY.dh2); goto ok;
13944 case 0xeb00000000c0ULL: /* TP */ goto unimplemented;
13945 case 0xeb00000000dcULL: s390_format_RSY_RRRD(s390_irgen_SRAK, ovl.fmt.RSY.r1,
13946 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13947 ovl.fmt.RSY.dl2,
13948 ovl.fmt.RSY.dh2); goto ok;
13949 case 0xeb00000000ddULL: s390_format_RSY_RRRD(s390_irgen_SLAK, 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 0xeb00000000deULL: s390_format_RSY_RRRD(s390_irgen_SRLK, 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 0xeb00000000dfULL: s390_format_RSY_RRRD(s390_irgen_SLLK, 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;
sewardjd7bde722011-04-05 13:19:33 +000013961 case 0xeb00000000e2ULL: s390_format_RSY_RDRM(s390_irgen_LOCG, ovl.fmt.RSY.r1,
13962 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13963 ovl.fmt.RSY.dl2,
13964 ovl.fmt.RSY.dh2,
13965 S390_XMNM_LOCG); goto ok;
13966 case 0xeb00000000e3ULL: s390_format_RSY_RDRM(s390_irgen_STOCG,
13967 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
13968 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
13969 ovl.fmt.RSY.dh2,
13970 S390_XMNM_STOCG); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013971 case 0xeb00000000e4ULL: s390_format_RSY_RRRD(s390_irgen_LANG, ovl.fmt.RSY.r1,
13972 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13973 ovl.fmt.RSY.dl2,
13974 ovl.fmt.RSY.dh2); goto ok;
13975 case 0xeb00000000e6ULL: s390_format_RSY_RRRD(s390_irgen_LAOG, ovl.fmt.RSY.r1,
13976 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13977 ovl.fmt.RSY.dl2,
13978 ovl.fmt.RSY.dh2); goto ok;
13979 case 0xeb00000000e7ULL: s390_format_RSY_RRRD(s390_irgen_LAXG, ovl.fmt.RSY.r1,
13980 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13981 ovl.fmt.RSY.dl2,
13982 ovl.fmt.RSY.dh2); goto ok;
13983 case 0xeb00000000e8ULL: s390_format_RSY_RRRD(s390_irgen_LAAG, ovl.fmt.RSY.r1,
13984 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13985 ovl.fmt.RSY.dl2,
13986 ovl.fmt.RSY.dh2); goto ok;
13987 case 0xeb00000000eaULL: s390_format_RSY_RRRD(s390_irgen_LAALG,
13988 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
13989 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
13990 ovl.fmt.RSY.dh2); goto ok;
sewardjd7bde722011-04-05 13:19:33 +000013991 case 0xeb00000000f2ULL: s390_format_RSY_RDRM(s390_irgen_LOC, ovl.fmt.RSY.r1,
13992 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13993 ovl.fmt.RSY.dl2,
13994 ovl.fmt.RSY.dh2, S390_XMNM_LOC);
13995 goto ok;
13996 case 0xeb00000000f3ULL: s390_format_RSY_RDRM(s390_irgen_STOC, ovl.fmt.RSY.r1,
13997 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13998 ovl.fmt.RSY.dl2,
13999 ovl.fmt.RSY.dh2,
14000 S390_XMNM_STOC); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014001 case 0xeb00000000f4ULL: s390_format_RSY_RRRD(s390_irgen_LAN, ovl.fmt.RSY.r1,
14002 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14003 ovl.fmt.RSY.dl2,
14004 ovl.fmt.RSY.dh2); goto ok;
14005 case 0xeb00000000f6ULL: s390_format_RSY_RRRD(s390_irgen_LAO, ovl.fmt.RSY.r1,
14006 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14007 ovl.fmt.RSY.dl2,
14008 ovl.fmt.RSY.dh2); goto ok;
14009 case 0xeb00000000f7ULL: s390_format_RSY_RRRD(s390_irgen_LAX, ovl.fmt.RSY.r1,
14010 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14011 ovl.fmt.RSY.dl2,
14012 ovl.fmt.RSY.dh2); goto ok;
14013 case 0xeb00000000f8ULL: s390_format_RSY_RRRD(s390_irgen_LAA, ovl.fmt.RSY.r1,
14014 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14015 ovl.fmt.RSY.dl2,
14016 ovl.fmt.RSY.dh2); goto ok;
14017 case 0xeb00000000faULL: s390_format_RSY_RRRD(s390_irgen_LAAL, ovl.fmt.RSY.r1,
14018 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14019 ovl.fmt.RSY.dl2,
14020 ovl.fmt.RSY.dh2); goto ok;
14021 case 0xec0000000044ULL: s390_format_RIE_RRP(s390_irgen_BRXHG, ovl.fmt.RIE.r1,
14022 ovl.fmt.RIE.r3, ovl.fmt.RIE.i2);
14023 goto ok;
14024 case 0xec0000000045ULL: s390_format_RIE_RRP(s390_irgen_BRXLG, ovl.fmt.RIE.r1,
14025 ovl.fmt.RIE.r3, ovl.fmt.RIE.i2);
14026 goto ok;
14027 case 0xec0000000051ULL: /* RISBLG */ goto unimplemented;
14028 case 0xec0000000054ULL: s390_format_RIE_RRUUU(s390_irgen_RNSBG,
14029 ovl.fmt.RIE_RRUUU.r1,
14030 ovl.fmt.RIE_RRUUU.r2,
14031 ovl.fmt.RIE_RRUUU.i3,
14032 ovl.fmt.RIE_RRUUU.i4,
14033 ovl.fmt.RIE_RRUUU.i5);
14034 goto ok;
14035 case 0xec0000000055ULL: s390_format_RIE_RRUUU(s390_irgen_RISBG,
14036 ovl.fmt.RIE_RRUUU.r1,
14037 ovl.fmt.RIE_RRUUU.r2,
14038 ovl.fmt.RIE_RRUUU.i3,
14039 ovl.fmt.RIE_RRUUU.i4,
14040 ovl.fmt.RIE_RRUUU.i5);
14041 goto ok;
14042 case 0xec0000000056ULL: s390_format_RIE_RRUUU(s390_irgen_ROSBG,
14043 ovl.fmt.RIE_RRUUU.r1,
14044 ovl.fmt.RIE_RRUUU.r2,
14045 ovl.fmt.RIE_RRUUU.i3,
14046 ovl.fmt.RIE_RRUUU.i4,
14047 ovl.fmt.RIE_RRUUU.i5);
14048 goto ok;
14049 case 0xec0000000057ULL: s390_format_RIE_RRUUU(s390_irgen_RXSBG,
14050 ovl.fmt.RIE_RRUUU.r1,
14051 ovl.fmt.RIE_RRUUU.r2,
14052 ovl.fmt.RIE_RRUUU.i3,
14053 ovl.fmt.RIE_RRUUU.i4,
14054 ovl.fmt.RIE_RRUUU.i5);
14055 goto ok;
14056 case 0xec000000005dULL: /* RISBHG */ goto unimplemented;
14057 case 0xec0000000064ULL: s390_format_RIE_RRPU(s390_irgen_CGRJ,
14058 ovl.fmt.RIE_RRPU.r1,
14059 ovl.fmt.RIE_RRPU.r2,
14060 ovl.fmt.RIE_RRPU.i4,
14061 ovl.fmt.RIE_RRPU.m3); goto ok;
14062 case 0xec0000000065ULL: s390_format_RIE_RRPU(s390_irgen_CLGRJ,
14063 ovl.fmt.RIE_RRPU.r1,
14064 ovl.fmt.RIE_RRPU.r2,
14065 ovl.fmt.RIE_RRPU.i4,
14066 ovl.fmt.RIE_RRPU.m3); goto ok;
14067 case 0xec0000000070ULL: /* CGIT */ goto unimplemented;
14068 case 0xec0000000071ULL: /* CLGIT */ goto unimplemented;
14069 case 0xec0000000072ULL: /* CIT */ goto unimplemented;
14070 case 0xec0000000073ULL: /* CLFIT */ goto unimplemented;
14071 case 0xec0000000076ULL: s390_format_RIE_RRPU(s390_irgen_CRJ,
14072 ovl.fmt.RIE_RRPU.r1,
14073 ovl.fmt.RIE_RRPU.r2,
14074 ovl.fmt.RIE_RRPU.i4,
14075 ovl.fmt.RIE_RRPU.m3); goto ok;
14076 case 0xec0000000077ULL: s390_format_RIE_RRPU(s390_irgen_CLRJ,
14077 ovl.fmt.RIE_RRPU.r1,
14078 ovl.fmt.RIE_RRPU.r2,
14079 ovl.fmt.RIE_RRPU.i4,
14080 ovl.fmt.RIE_RRPU.m3); goto ok;
14081 case 0xec000000007cULL: s390_format_RIE_RUPI(s390_irgen_CGIJ,
14082 ovl.fmt.RIEv3.r1,
14083 ovl.fmt.RIEv3.m3,
14084 ovl.fmt.RIEv3.i4,
14085 ovl.fmt.RIEv3.i2); goto ok;
14086 case 0xec000000007dULL: s390_format_RIE_RUPU(s390_irgen_CLGIJ,
14087 ovl.fmt.RIEv3.r1,
14088 ovl.fmt.RIEv3.m3,
14089 ovl.fmt.RIEv3.i4,
14090 ovl.fmt.RIEv3.i2); goto ok;
14091 case 0xec000000007eULL: s390_format_RIE_RUPI(s390_irgen_CIJ,
14092 ovl.fmt.RIEv3.r1,
14093 ovl.fmt.RIEv3.m3,
14094 ovl.fmt.RIEv3.i4,
14095 ovl.fmt.RIEv3.i2); goto ok;
14096 case 0xec000000007fULL: s390_format_RIE_RUPU(s390_irgen_CLIJ,
14097 ovl.fmt.RIEv3.r1,
14098 ovl.fmt.RIEv3.m3,
14099 ovl.fmt.RIEv3.i4,
14100 ovl.fmt.RIEv3.i2); goto ok;
14101 case 0xec00000000d8ULL: s390_format_RIE_RRI0(s390_irgen_AHIK, ovl.fmt.RIE.r1,
14102 ovl.fmt.RIE.r3, ovl.fmt.RIE.i2);
14103 goto ok;
14104 case 0xec00000000d9ULL: s390_format_RIE_RRI0(s390_irgen_AGHIK,
14105 ovl.fmt.RIE.r1, ovl.fmt.RIE.r3,
14106 ovl.fmt.RIE.i2); goto ok;
14107 case 0xec00000000daULL: s390_format_RIE_RRI0(s390_irgen_ALHSIK,
14108 ovl.fmt.RIE.r1, ovl.fmt.RIE.r3,
14109 ovl.fmt.RIE.i2); goto ok;
14110 case 0xec00000000dbULL: s390_format_RIE_RRI0(s390_irgen_ALGHSIK,
14111 ovl.fmt.RIE.r1, ovl.fmt.RIE.r3,
14112 ovl.fmt.RIE.i2); goto ok;
14113 case 0xec00000000e4ULL: s390_format_RRS(s390_irgen_CGRB, ovl.fmt.RRS.r1,
14114 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
14115 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
14116 goto ok;
14117 case 0xec00000000e5ULL: s390_format_RRS(s390_irgen_CLGRB, ovl.fmt.RRS.r1,
14118 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
14119 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
14120 goto ok;
14121 case 0xec00000000f6ULL: s390_format_RRS(s390_irgen_CRB, ovl.fmt.RRS.r1,
14122 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
14123 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
14124 goto ok;
14125 case 0xec00000000f7ULL: s390_format_RRS(s390_irgen_CLRB, ovl.fmt.RRS.r1,
14126 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
14127 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
14128 goto ok;
14129 case 0xec00000000fcULL: s390_format_RIS_RURDI(s390_irgen_CGIB,
14130 ovl.fmt.RIS.r1, ovl.fmt.RIS.m3,
14131 ovl.fmt.RIS.b4, ovl.fmt.RIS.d4,
14132 ovl.fmt.RIS.i2); goto ok;
14133 case 0xec00000000fdULL: s390_format_RIS_RURDU(s390_irgen_CLGIB,
14134 ovl.fmt.RIS.r1, ovl.fmt.RIS.m3,
14135 ovl.fmt.RIS.b4, ovl.fmt.RIS.d4,
14136 ovl.fmt.RIS.i2); goto ok;
14137 case 0xec00000000feULL: s390_format_RIS_RURDI(s390_irgen_CIB, ovl.fmt.RIS.r1,
14138 ovl.fmt.RIS.m3, ovl.fmt.RIS.b4,
14139 ovl.fmt.RIS.d4,
14140 ovl.fmt.RIS.i2); goto ok;
14141 case 0xec00000000ffULL: s390_format_RIS_RURDU(s390_irgen_CLIB,
14142 ovl.fmt.RIS.r1, ovl.fmt.RIS.m3,
14143 ovl.fmt.RIS.b4, ovl.fmt.RIS.d4,
14144 ovl.fmt.RIS.i2); goto ok;
14145 case 0xed0000000004ULL: s390_format_RXE_FRRD(s390_irgen_LDEB, ovl.fmt.RXE.r1,
14146 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14147 ovl.fmt.RXE.d2); goto ok;
14148 case 0xed0000000005ULL: s390_format_RXE_FRRD(s390_irgen_LXDB, ovl.fmt.RXE.r1,
14149 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14150 ovl.fmt.RXE.d2); goto ok;
14151 case 0xed0000000006ULL: s390_format_RXE_FRRD(s390_irgen_LXEB, ovl.fmt.RXE.r1,
14152 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14153 ovl.fmt.RXE.d2); goto ok;
14154 case 0xed0000000007ULL: /* MXDB */ goto unimplemented;
14155 case 0xed0000000008ULL: /* KEB */ goto unimplemented;
14156 case 0xed0000000009ULL: s390_format_RXE_FRRD(s390_irgen_CEB, ovl.fmt.RXE.r1,
14157 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14158 ovl.fmt.RXE.d2); goto ok;
14159 case 0xed000000000aULL: s390_format_RXE_FRRD(s390_irgen_AEB, ovl.fmt.RXE.r1,
14160 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14161 ovl.fmt.RXE.d2); goto ok;
14162 case 0xed000000000bULL: s390_format_RXE_FRRD(s390_irgen_SEB, ovl.fmt.RXE.r1,
14163 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14164 ovl.fmt.RXE.d2); goto ok;
14165 case 0xed000000000cULL: /* MDEB */ goto unimplemented;
14166 case 0xed000000000dULL: s390_format_RXE_FRRD(s390_irgen_DEB, ovl.fmt.RXE.r1,
14167 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14168 ovl.fmt.RXE.d2); goto ok;
14169 case 0xed000000000eULL: s390_format_RXF_FRRDF(s390_irgen_MAEB,
14170 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
14171 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
14172 ovl.fmt.RXF.r1); goto ok;
14173 case 0xed000000000fULL: s390_format_RXF_FRRDF(s390_irgen_MSEB,
14174 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
14175 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
14176 ovl.fmt.RXF.r1); goto ok;
14177 case 0xed0000000010ULL: s390_format_RXE_FRRD(s390_irgen_TCEB, ovl.fmt.RXE.r1,
14178 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14179 ovl.fmt.RXE.d2); goto ok;
14180 case 0xed0000000011ULL: s390_format_RXE_FRRD(s390_irgen_TCDB, ovl.fmt.RXE.r1,
14181 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14182 ovl.fmt.RXE.d2); goto ok;
14183 case 0xed0000000012ULL: s390_format_RXE_FRRD(s390_irgen_TCXB, ovl.fmt.RXE.r1,
14184 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14185 ovl.fmt.RXE.d2); goto ok;
14186 case 0xed0000000014ULL: s390_format_RXE_FRRD(s390_irgen_SQEB, ovl.fmt.RXE.r1,
14187 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14188 ovl.fmt.RXE.d2); goto ok;
14189 case 0xed0000000015ULL: s390_format_RXE_FRRD(s390_irgen_SQDB, ovl.fmt.RXE.r1,
14190 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14191 ovl.fmt.RXE.d2); goto ok;
14192 case 0xed0000000017ULL: s390_format_RXE_FRRD(s390_irgen_MEEB, ovl.fmt.RXE.r1,
14193 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14194 ovl.fmt.RXE.d2); goto ok;
14195 case 0xed0000000018ULL: /* KDB */ goto unimplemented;
14196 case 0xed0000000019ULL: s390_format_RXE_FRRD(s390_irgen_CDB, ovl.fmt.RXE.r1,
14197 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14198 ovl.fmt.RXE.d2); goto ok;
14199 case 0xed000000001aULL: s390_format_RXE_FRRD(s390_irgen_ADB, ovl.fmt.RXE.r1,
14200 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14201 ovl.fmt.RXE.d2); goto ok;
14202 case 0xed000000001bULL: s390_format_RXE_FRRD(s390_irgen_SDB, ovl.fmt.RXE.r1,
14203 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14204 ovl.fmt.RXE.d2); goto ok;
14205 case 0xed000000001cULL: s390_format_RXE_FRRD(s390_irgen_MDB, ovl.fmt.RXE.r1,
14206 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14207 ovl.fmt.RXE.d2); goto ok;
14208 case 0xed000000001dULL: s390_format_RXE_FRRD(s390_irgen_DDB, ovl.fmt.RXE.r1,
14209 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14210 ovl.fmt.RXE.d2); goto ok;
14211 case 0xed000000001eULL: s390_format_RXF_FRRDF(s390_irgen_MADB,
14212 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
14213 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
14214 ovl.fmt.RXF.r1); goto ok;
14215 case 0xed000000001fULL: s390_format_RXF_FRRDF(s390_irgen_MSDB,
14216 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
14217 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
14218 ovl.fmt.RXF.r1); goto ok;
14219 case 0xed0000000024ULL: /* LDE */ goto unimplemented;
14220 case 0xed0000000025ULL: /* LXD */ goto unimplemented;
14221 case 0xed0000000026ULL: /* LXE */ goto unimplemented;
14222 case 0xed000000002eULL: /* MAE */ goto unimplemented;
14223 case 0xed000000002fULL: /* MSE */ goto unimplemented;
14224 case 0xed0000000034ULL: /* SQE */ goto unimplemented;
14225 case 0xed0000000035ULL: /* SQD */ goto unimplemented;
14226 case 0xed0000000037ULL: /* MEE */ goto unimplemented;
14227 case 0xed0000000038ULL: /* MAYL */ goto unimplemented;
14228 case 0xed0000000039ULL: /* MYL */ goto unimplemented;
14229 case 0xed000000003aULL: /* MAY */ goto unimplemented;
14230 case 0xed000000003bULL: /* MY */ goto unimplemented;
14231 case 0xed000000003cULL: /* MAYH */ goto unimplemented;
14232 case 0xed000000003dULL: /* MYH */ goto unimplemented;
14233 case 0xed000000003eULL: /* MAD */ goto unimplemented;
14234 case 0xed000000003fULL: /* MSD */ goto unimplemented;
14235 case 0xed0000000040ULL: /* SLDT */ goto unimplemented;
14236 case 0xed0000000041ULL: /* SRDT */ goto unimplemented;
14237 case 0xed0000000048ULL: /* SLXT */ goto unimplemented;
14238 case 0xed0000000049ULL: /* SRXT */ goto unimplemented;
14239 case 0xed0000000050ULL: /* TDCET */ goto unimplemented;
14240 case 0xed0000000051ULL: /* TDGET */ goto unimplemented;
14241 case 0xed0000000054ULL: /* TDCDT */ goto unimplemented;
14242 case 0xed0000000055ULL: /* TDGDT */ goto unimplemented;
14243 case 0xed0000000058ULL: /* TDCXT */ goto unimplemented;
14244 case 0xed0000000059ULL: /* TDGXT */ goto unimplemented;
14245 case 0xed0000000064ULL: s390_format_RXY_FRRD(s390_irgen_LEY, ovl.fmt.RXY.r1,
14246 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14247 ovl.fmt.RXY.dl2,
14248 ovl.fmt.RXY.dh2); goto ok;
14249 case 0xed0000000065ULL: s390_format_RXY_FRRD(s390_irgen_LDY, ovl.fmt.RXY.r1,
14250 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14251 ovl.fmt.RXY.dl2,
14252 ovl.fmt.RXY.dh2); goto ok;
14253 case 0xed0000000066ULL: s390_format_RXY_FRRD(s390_irgen_STEY, ovl.fmt.RXY.r1,
14254 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14255 ovl.fmt.RXY.dl2,
14256 ovl.fmt.RXY.dh2); goto ok;
14257 case 0xed0000000067ULL: s390_format_RXY_FRRD(s390_irgen_STDY, ovl.fmt.RXY.r1,
14258 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14259 ovl.fmt.RXY.dl2,
14260 ovl.fmt.RXY.dh2); goto ok;
14261 }
14262
14263 switch (((ovl.value >> 16) & 0xff0f00000000ULL) >> 32) {
14264 case 0xc000ULL: s390_format_RIL_RP(s390_irgen_LARL, ovl.fmt.RIL.r1,
14265 ovl.fmt.RIL.i2); goto ok;
14266 case 0xc001ULL: s390_format_RIL_RI(s390_irgen_LGFI, ovl.fmt.RIL.r1,
14267 ovl.fmt.RIL.i2); goto ok;
14268 case 0xc004ULL: s390_format_RIL(s390_irgen_BRCL, ovl.fmt.RIL.r1,
14269 ovl.fmt.RIL.i2); goto ok;
14270 case 0xc005ULL: s390_format_RIL_RP(s390_irgen_BRASL, ovl.fmt.RIL.r1,
14271 ovl.fmt.RIL.i2); goto ok;
14272 case 0xc006ULL: s390_format_RIL_RU(s390_irgen_XIHF, ovl.fmt.RIL.r1,
14273 ovl.fmt.RIL.i2); goto ok;
14274 case 0xc007ULL: s390_format_RIL_RU(s390_irgen_XILF, ovl.fmt.RIL.r1,
14275 ovl.fmt.RIL.i2); goto ok;
14276 case 0xc008ULL: s390_format_RIL_RU(s390_irgen_IIHF, ovl.fmt.RIL.r1,
14277 ovl.fmt.RIL.i2); goto ok;
14278 case 0xc009ULL: s390_format_RIL_RU(s390_irgen_IILF, ovl.fmt.RIL.r1,
14279 ovl.fmt.RIL.i2); goto ok;
14280 case 0xc00aULL: s390_format_RIL_RU(s390_irgen_NIHF, ovl.fmt.RIL.r1,
14281 ovl.fmt.RIL.i2); goto ok;
14282 case 0xc00bULL: s390_format_RIL_RU(s390_irgen_NILF, ovl.fmt.RIL.r1,
14283 ovl.fmt.RIL.i2); goto ok;
14284 case 0xc00cULL: s390_format_RIL_RU(s390_irgen_OIHF, ovl.fmt.RIL.r1,
14285 ovl.fmt.RIL.i2); goto ok;
14286 case 0xc00dULL: s390_format_RIL_RU(s390_irgen_OILF, ovl.fmt.RIL.r1,
14287 ovl.fmt.RIL.i2); goto ok;
14288 case 0xc00eULL: s390_format_RIL_RU(s390_irgen_LLIHF, ovl.fmt.RIL.r1,
14289 ovl.fmt.RIL.i2); goto ok;
14290 case 0xc00fULL: s390_format_RIL_RU(s390_irgen_LLILF, ovl.fmt.RIL.r1,
14291 ovl.fmt.RIL.i2); goto ok;
14292 case 0xc200ULL: s390_format_RIL_RI(s390_irgen_MSGFI, ovl.fmt.RIL.r1,
14293 ovl.fmt.RIL.i2); goto ok;
14294 case 0xc201ULL: s390_format_RIL_RI(s390_irgen_MSFI, ovl.fmt.RIL.r1,
14295 ovl.fmt.RIL.i2); goto ok;
14296 case 0xc204ULL: s390_format_RIL_RU(s390_irgen_SLGFI, ovl.fmt.RIL.r1,
14297 ovl.fmt.RIL.i2); goto ok;
14298 case 0xc205ULL: s390_format_RIL_RU(s390_irgen_SLFI, ovl.fmt.RIL.r1,
14299 ovl.fmt.RIL.i2); goto ok;
14300 case 0xc208ULL: s390_format_RIL_RI(s390_irgen_AGFI, ovl.fmt.RIL.r1,
14301 ovl.fmt.RIL.i2); goto ok;
14302 case 0xc209ULL: s390_format_RIL_RI(s390_irgen_AFI, ovl.fmt.RIL.r1,
14303 ovl.fmt.RIL.i2); goto ok;
14304 case 0xc20aULL: s390_format_RIL_RU(s390_irgen_ALGFI, ovl.fmt.RIL.r1,
14305 ovl.fmt.RIL.i2); goto ok;
14306 case 0xc20bULL: s390_format_RIL_RU(s390_irgen_ALFI, ovl.fmt.RIL.r1,
14307 ovl.fmt.RIL.i2); goto ok;
14308 case 0xc20cULL: s390_format_RIL_RI(s390_irgen_CGFI, ovl.fmt.RIL.r1,
14309 ovl.fmt.RIL.i2); goto ok;
14310 case 0xc20dULL: s390_format_RIL_RI(s390_irgen_CFI, ovl.fmt.RIL.r1,
14311 ovl.fmt.RIL.i2); goto ok;
14312 case 0xc20eULL: s390_format_RIL_RU(s390_irgen_CLGFI, ovl.fmt.RIL.r1,
14313 ovl.fmt.RIL.i2); goto ok;
14314 case 0xc20fULL: s390_format_RIL_RU(s390_irgen_CLFI, ovl.fmt.RIL.r1,
14315 ovl.fmt.RIL.i2); goto ok;
14316 case 0xc402ULL: s390_format_RIL_RP(s390_irgen_LLHRL, ovl.fmt.RIL.r1,
14317 ovl.fmt.RIL.i2); goto ok;
14318 case 0xc404ULL: s390_format_RIL_RP(s390_irgen_LGHRL, ovl.fmt.RIL.r1,
14319 ovl.fmt.RIL.i2); goto ok;
14320 case 0xc405ULL: s390_format_RIL_RP(s390_irgen_LHRL, ovl.fmt.RIL.r1,
14321 ovl.fmt.RIL.i2); goto ok;
14322 case 0xc406ULL: s390_format_RIL_RP(s390_irgen_LLGHRL, ovl.fmt.RIL.r1,
14323 ovl.fmt.RIL.i2); goto ok;
14324 case 0xc407ULL: s390_format_RIL_RP(s390_irgen_STHRL, ovl.fmt.RIL.r1,
14325 ovl.fmt.RIL.i2); goto ok;
14326 case 0xc408ULL: s390_format_RIL_RP(s390_irgen_LGRL, ovl.fmt.RIL.r1,
14327 ovl.fmt.RIL.i2); goto ok;
14328 case 0xc40bULL: s390_format_RIL_RP(s390_irgen_STGRL, ovl.fmt.RIL.r1,
14329 ovl.fmt.RIL.i2); goto ok;
14330 case 0xc40cULL: s390_format_RIL_RP(s390_irgen_LGFRL, ovl.fmt.RIL.r1,
14331 ovl.fmt.RIL.i2); goto ok;
14332 case 0xc40dULL: s390_format_RIL_RP(s390_irgen_LRL, ovl.fmt.RIL.r1,
14333 ovl.fmt.RIL.i2); goto ok;
14334 case 0xc40eULL: s390_format_RIL_RP(s390_irgen_LLGFRL, ovl.fmt.RIL.r1,
14335 ovl.fmt.RIL.i2); goto ok;
14336 case 0xc40fULL: s390_format_RIL_RP(s390_irgen_STRL, ovl.fmt.RIL.r1,
14337 ovl.fmt.RIL.i2); goto ok;
14338 case 0xc600ULL: s390_format_RIL_RP(s390_irgen_EXRL, ovl.fmt.RIL.r1,
14339 ovl.fmt.RIL.i2); goto ok;
14340 case 0xc602ULL: s390_format_RIL_UP(s390_irgen_PFDRL, ovl.fmt.RIL.r1,
14341 ovl.fmt.RIL.i2); goto ok;
14342 case 0xc604ULL: s390_format_RIL_RP(s390_irgen_CGHRL, ovl.fmt.RIL.r1,
14343 ovl.fmt.RIL.i2); goto ok;
14344 case 0xc605ULL: s390_format_RIL_RP(s390_irgen_CHRL, ovl.fmt.RIL.r1,
14345 ovl.fmt.RIL.i2); goto ok;
14346 case 0xc606ULL: s390_format_RIL_RP(s390_irgen_CLGHRL, ovl.fmt.RIL.r1,
14347 ovl.fmt.RIL.i2); goto ok;
14348 case 0xc607ULL: s390_format_RIL_RP(s390_irgen_CLHRL, ovl.fmt.RIL.r1,
14349 ovl.fmt.RIL.i2); goto ok;
14350 case 0xc608ULL: s390_format_RIL_RP(s390_irgen_CGRL, ovl.fmt.RIL.r1,
14351 ovl.fmt.RIL.i2); goto ok;
14352 case 0xc60aULL: s390_format_RIL_RP(s390_irgen_CLGRL, ovl.fmt.RIL.r1,
14353 ovl.fmt.RIL.i2); goto ok;
14354 case 0xc60cULL: s390_format_RIL_RP(s390_irgen_CGFRL, ovl.fmt.RIL.r1,
14355 ovl.fmt.RIL.i2); goto ok;
14356 case 0xc60dULL: s390_format_RIL_RP(s390_irgen_CRL, ovl.fmt.RIL.r1,
14357 ovl.fmt.RIL.i2); goto ok;
14358 case 0xc60eULL: s390_format_RIL_RP(s390_irgen_CLGFRL, ovl.fmt.RIL.r1,
14359 ovl.fmt.RIL.i2); goto ok;
14360 case 0xc60fULL: s390_format_RIL_RP(s390_irgen_CLRL, ovl.fmt.RIL.r1,
14361 ovl.fmt.RIL.i2); goto ok;
14362 case 0xc800ULL: /* MVCOS */ goto unimplemented;
14363 case 0xc801ULL: /* ECTG */ goto unimplemented;
14364 case 0xc802ULL: /* CSST */ goto unimplemented;
14365 case 0xc804ULL: /* LPD */ goto unimplemented;
14366 case 0xc805ULL: /* LPDG */ goto unimplemented;
14367 case 0xcc06ULL: /* BRCTH */ goto unimplemented;
14368 case 0xcc08ULL: s390_format_RIL_RI(s390_irgen_AIH, ovl.fmt.RIL.r1,
14369 ovl.fmt.RIL.i2); goto ok;
14370 case 0xcc0aULL: s390_format_RIL_RI(s390_irgen_ALSIH, ovl.fmt.RIL.r1,
14371 ovl.fmt.RIL.i2); goto ok;
14372 case 0xcc0bULL: s390_format_RIL_RI(s390_irgen_ALSIHN, ovl.fmt.RIL.r1,
14373 ovl.fmt.RIL.i2); goto ok;
14374 case 0xcc0dULL: s390_format_RIL_RI(s390_irgen_CIH, ovl.fmt.RIL.r1,
14375 ovl.fmt.RIL.i2); goto ok;
14376 case 0xcc0fULL: s390_format_RIL_RU(s390_irgen_CLIH, ovl.fmt.RIL.r1,
14377 ovl.fmt.RIL.i2); goto ok;
14378 }
14379
14380 switch (((ovl.value >> 16) & 0xff0000000000ULL) >> 40) {
14381 case 0xd0ULL: /* TRTR */ goto unimplemented;
14382 case 0xd1ULL: /* MVN */ goto unimplemented;
14383 case 0xd2ULL: s390_format_SS_L0RDRD(s390_irgen_MVC, ovl.fmt.SS.l,
14384 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
14385 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
14386 case 0xd3ULL: /* MVZ */ goto unimplemented;
14387 case 0xd4ULL: s390_format_SS_L0RDRD(s390_irgen_NC, ovl.fmt.SS.l,
14388 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
14389 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
14390 case 0xd5ULL: s390_format_SS_L0RDRD(s390_irgen_CLC, ovl.fmt.SS.l,
14391 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
14392 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
14393 case 0xd6ULL: s390_format_SS_L0RDRD(s390_irgen_OC, ovl.fmt.SS.l,
14394 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
14395 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
sewardjb63967e2011-03-24 08:50:04 +000014396 case 0xd7ULL:
14397 if (ovl.fmt.SS.b1 == ovl.fmt.SS.b2 && ovl.fmt.SS.d1 == ovl.fmt.SS.d2)
14398 s390_irgen_XC_sameloc(ovl.fmt.SS.l, ovl.fmt.SS.b1, ovl.fmt.SS.d1);
14399 else
14400 s390_format_SS_L0RDRD(s390_irgen_XC, ovl.fmt.SS.l,
14401 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
14402 ovl.fmt.SS.b2, ovl.fmt.SS.d2);
14403 goto ok;
sewardj2019a972011-03-07 16:04:07 +000014404 case 0xd9ULL: /* MVCK */ goto unimplemented;
14405 case 0xdaULL: /* MVCP */ goto unimplemented;
14406 case 0xdbULL: /* MVCS */ goto unimplemented;
florian730448f2012-02-04 17:07:07 +000014407 case 0xdcULL: s390_format_SS_L0RDRD(s390_irgen_TR, ovl.fmt.SS.l,
14408 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
14409 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014410 case 0xddULL: /* TRT */ goto unimplemented;
14411 case 0xdeULL: /* ED */ goto unimplemented;
14412 case 0xdfULL: /* EDMK */ goto unimplemented;
14413 case 0xe1ULL: /* PKU */ goto unimplemented;
14414 case 0xe2ULL: /* UNPKU */ goto unimplemented;
14415 case 0xe8ULL: /* MVCIN */ goto unimplemented;
14416 case 0xe9ULL: /* PKA */ goto unimplemented;
14417 case 0xeaULL: /* UNPKA */ goto unimplemented;
14418 case 0xeeULL: /* PLO */ goto unimplemented;
14419 case 0xefULL: /* LMD */ goto unimplemented;
14420 case 0xf0ULL: /* SRP */ goto unimplemented;
14421 case 0xf1ULL: /* MVO */ goto unimplemented;
14422 case 0xf2ULL: /* PACK */ goto unimplemented;
14423 case 0xf3ULL: /* UNPK */ goto unimplemented;
14424 case 0xf8ULL: /* ZAP */ goto unimplemented;
14425 case 0xf9ULL: /* CP */ goto unimplemented;
14426 case 0xfaULL: /* AP */ goto unimplemented;
14427 case 0xfbULL: /* SP */ goto unimplemented;
14428 case 0xfcULL: /* MP */ goto unimplemented;
14429 case 0xfdULL: /* DP */ goto unimplemented;
14430 }
14431
14432 switch (((ovl.value >> 16) & 0xffff00000000ULL) >> 32) {
14433 case 0xe500ULL: /* LASP */ goto unimplemented;
14434 case 0xe501ULL: /* TPROT */ goto unimplemented;
14435 case 0xe502ULL: /* STRAG */ goto unimplemented;
14436 case 0xe50eULL: /* MVCSK */ goto unimplemented;
14437 case 0xe50fULL: /* MVCDK */ goto unimplemented;
14438 case 0xe544ULL: s390_format_SIL_RDI(s390_irgen_MVHHI, ovl.fmt.SIL.b1,
14439 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14440 goto ok;
14441 case 0xe548ULL: s390_format_SIL_RDI(s390_irgen_MVGHI, ovl.fmt.SIL.b1,
14442 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14443 goto ok;
14444 case 0xe54cULL: s390_format_SIL_RDI(s390_irgen_MVHI, ovl.fmt.SIL.b1,
14445 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14446 goto ok;
14447 case 0xe554ULL: s390_format_SIL_RDI(s390_irgen_CHHSI, ovl.fmt.SIL.b1,
14448 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14449 goto ok;
14450 case 0xe555ULL: s390_format_SIL_RDU(s390_irgen_CLHHSI, ovl.fmt.SIL.b1,
14451 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14452 goto ok;
14453 case 0xe558ULL: s390_format_SIL_RDI(s390_irgen_CGHSI, ovl.fmt.SIL.b1,
14454 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14455 goto ok;
14456 case 0xe559ULL: s390_format_SIL_RDU(s390_irgen_CLGHSI, ovl.fmt.SIL.b1,
14457 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14458 goto ok;
14459 case 0xe55cULL: s390_format_SIL_RDI(s390_irgen_CHSI, ovl.fmt.SIL.b1,
14460 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14461 goto ok;
14462 case 0xe55dULL: s390_format_SIL_RDU(s390_irgen_CLFHSI, ovl.fmt.SIL.b1,
14463 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14464 goto ok;
14465 }
14466
14467 return S390_DECODE_UNKNOWN_INSN;
14468
14469ok:
14470 return S390_DECODE_OK;
14471
14472unimplemented:
14473 return S390_DECODE_UNIMPLEMENTED_INSN;
14474}
14475
14476/* Handle "special" instructions. */
14477static s390_decode_t
14478s390_decode_special_and_irgen(UChar *bytes)
14479{
14480 s390_decode_t status = S390_DECODE_OK;
14481
14482 /* Got a "Special" instruction preamble. Which one is it? */
14483 if (bytes[0] == 0x18 && bytes[1] == 0x22 /* lr %r2, %r2 */) {
14484 s390_irgen_client_request();
14485 } else if (bytes[0] == 0x18 && bytes[1] == 0x33 /* lr %r3, %r3 */) {
14486 s390_irgen_guest_NRADDR();
14487 } else if (bytes[0] == 0x18 && bytes[1] == 0x44 /* lr %r4, %r4 */) {
14488 s390_irgen_call_noredir();
florian2245ce92012-08-28 16:49:30 +000014489 } else if (bytes[0] == 0x18 && bytes[1] == 0x55 /* lr %r5, %r5 */) {
14490 vex_inject_ir(irsb, Iend_BE);
14491
14492 /* Invalidate the current insn. The reason is that the IRop we're
14493 injecting here can change. In which case the translation has to
14494 be redone. For ease of handling, we simply invalidate all the
14495 time. */
14496 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TISTART),
14497 mkU64(guest_IA_curr_instr)));
14498 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TILEN),
14499 mkU64(guest_IA_next_instr - guest_IA_curr_instr)));
14500 vassert(guest_IA_next_instr - guest_IA_curr_instr ==
14501 S390_SPECIAL_OP_PREAMBLE_SIZE + S390_SPECIAL_OP_SIZE);
14502
14503 put_IA(mkaddr_expr(guest_IA_next_instr));
14504 dis_res->whatNext = Dis_StopHere;
14505 dis_res->jk_StopHere = Ijk_TInval;
sewardj2019a972011-03-07 16:04:07 +000014506 } else {
14507 /* We don't know what it is. */
14508 return S390_DECODE_UNKNOWN_SPECIAL_INSN;
14509 }
14510
14511 dis_res->len = S390_SPECIAL_OP_PREAMBLE_SIZE + S390_SPECIAL_OP_SIZE;
14512
14513 return status;
14514}
14515
14516
14517/* Function returns # bytes that were decoded or 0 in case of failure */
florianb4df7682011-07-05 02:09:01 +000014518static UInt
sewardj2019a972011-03-07 16:04:07 +000014519s390_decode_and_irgen(UChar *bytes, UInt insn_length, DisResult *dres)
14520{
14521 s390_decode_t status;
14522
14523 dis_res = dres;
14524
14525 /* Spot the 8-byte preamble: 18ff lr r15,r15
14526 1811 lr r1,r1
14527 1822 lr r2,r2
14528 1833 lr r3,r3 */
14529 if (bytes[ 0] == 0x18 && bytes[ 1] == 0xff && bytes[ 2] == 0x18 &&
14530 bytes[ 3] == 0x11 && bytes[ 4] == 0x18 && bytes[ 5] == 0x22 &&
14531 bytes[ 6] == 0x18 && bytes[ 7] == 0x33) {
14532
14533 /* Handle special instruction that follows that preamble. */
14534 if (0) vex_printf("special function handling...\n");
florian2c8ed942011-08-01 22:07:51 +000014535
14536 insn_length = S390_SPECIAL_OP_PREAMBLE_SIZE + S390_SPECIAL_OP_SIZE;
14537 guest_IA_next_instr = guest_IA_curr_instr + insn_length;
14538
14539 status =
14540 s390_decode_special_and_irgen(bytes + S390_SPECIAL_OP_PREAMBLE_SIZE);
sewardj2019a972011-03-07 16:04:07 +000014541 } else {
14542 /* Handle normal instructions. */
14543 switch (insn_length) {
14544 case 2:
14545 status = s390_decode_2byte_and_irgen(bytes);
14546 break;
14547
14548 case 4:
14549 status = s390_decode_4byte_and_irgen(bytes);
14550 break;
14551
14552 case 6:
14553 status = s390_decode_6byte_and_irgen(bytes);
14554 break;
14555
14556 default:
14557 status = S390_DECODE_ERROR;
14558 break;
14559 }
14560 }
florian5fcbba22011-07-27 20:40:22 +000014561 /* If next instruction is execute, stop here */
florianf9e1ed72012-04-17 02:41:56 +000014562 if (dis_res->whatNext == Dis_Continue && bytes[insn_length] == 0x44) {
14563 put_IA(mkaddr_expr(guest_IA_next_instr));
sewardj2019a972011-03-07 16:04:07 +000014564 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +000014565 dis_res->jk_StopHere = Ijk_Boring;
sewardj2019a972011-03-07 16:04:07 +000014566 }
14567
14568 if (status == S390_DECODE_OK) return insn_length; /* OK */
14569
14570 /* Decoding failed somehow */
14571 vex_printf("vex s390->IR: ");
14572 switch (status) {
14573 case S390_DECODE_UNKNOWN_INSN:
14574 vex_printf("unknown insn: ");
14575 break;
14576
14577 case S390_DECODE_UNIMPLEMENTED_INSN:
14578 vex_printf("unimplemented insn: ");
14579 break;
14580
14581 case S390_DECODE_UNKNOWN_SPECIAL_INSN:
14582 vex_printf("unimplemented special insn: ");
14583 break;
14584
14585 default:
14586 case S390_DECODE_ERROR:
14587 vex_printf("decoding error: ");
14588 break;
14589 }
14590
14591 vex_printf("%02x%02x", bytes[0], bytes[1]);
14592 if (insn_length > 2) {
14593 vex_printf(" %02x%02x", bytes[2], bytes[3]);
14594 }
14595 if (insn_length > 4) {
14596 vex_printf(" %02x%02x", bytes[4], bytes[5]);
14597 }
14598 vex_printf("\n");
14599
14600 return 0; /* Failed */
14601}
14602
14603
sewardj2019a972011-03-07 16:04:07 +000014604/* Disassemble a single instruction INSN into IR. */
14605static DisResult
florian420c5012011-07-22 02:12:28 +000014606disInstr_S390_WRK(UChar *insn)
sewardj2019a972011-03-07 16:04:07 +000014607{
14608 UChar byte;
14609 UInt insn_length;
14610 DisResult dres;
14611
14612 /* ---------------------------------------------------- */
14613 /* --- Compute instruction length -- */
14614 /* ---------------------------------------------------- */
14615
14616 /* Get the first byte of the insn. */
14617 byte = insn[0];
14618
14619 /* The leftmost two bits (0:1) encode the length of the insn in bytes.
14620 00 -> 2 bytes, 01 -> 4 bytes, 10 -> 4 bytes, 11 -> 6 bytes. */
14621 insn_length = ((((byte >> 6) + 1) >> 1) + 1) << 1;
14622
14623 guest_IA_next_instr = guest_IA_curr_instr + insn_length;
14624
14625 /* ---------------------------------------------------- */
14626 /* --- Initialise the DisResult data -- */
14627 /* ---------------------------------------------------- */
14628 dres.whatNext = Dis_Continue;
14629 dres.len = insn_length;
14630 dres.continueAt = 0;
florian8844a632012-04-13 04:04:06 +000014631 dres.jk_StopHere = Ijk_INVALID;
sewardj2019a972011-03-07 16:04:07 +000014632
floriana99f20e2011-07-17 14:16:41 +000014633 /* fixs390: consider chasing of conditional jumps */
14634
sewardj2019a972011-03-07 16:04:07 +000014635 /* Normal and special instruction handling starts here. */
14636 if (s390_decode_and_irgen(insn, insn_length, &dres) == 0) {
14637 /* All decode failures end up here. The decoder has already issued an
14638 error message.
14639 Tell the dispatcher that this insn cannot be decoded, and so has
florian342e01a2012-07-26 02:37:49 +000014640 not been executed, and (is currently) the next to be executed.
14641 The insn address in the guest state needs to be set to
14642 guest_IA_curr_instr, otherwise the complaint will report an
14643 incorrect address. */
14644 put_IA(mkaddr_expr(guest_IA_curr_instr));
sewardj2019a972011-03-07 16:04:07 +000014645
florian8844a632012-04-13 04:04:06 +000014646 dres.whatNext = Dis_StopHere;
14647 dres.jk_StopHere = Ijk_NoDecode;
14648 dres.continueAt = 0;
14649 dres.len = 0;
14650 } else {
14651 /* Decode success */
14652 switch (dres.whatNext) {
14653 case Dis_Continue:
florian8559e412012-04-19 14:23:48 +000014654 put_IA(mkaddr_expr(guest_IA_next_instr));
florian8844a632012-04-13 04:04:06 +000014655 break;
14656 case Dis_ResteerU:
14657 case Dis_ResteerC:
14658 put_IA(mkaddr_expr(dres.continueAt));
14659 break;
14660 case Dis_StopHere:
florian4b8efad2012-09-02 18:07:08 +000014661 if (dres.jk_StopHere == Ijk_EmWarn ||
14662 dres.jk_StopHere == Ijk_EmFail) {
14663 /* We assume here, that emulation warnings are not given for
14664 insns that transfer control. There is no good way to
14665 do that. */
14666 put_IA(mkaddr_expr(guest_IA_next_instr));
14667 }
florian8844a632012-04-13 04:04:06 +000014668 break;
14669 default:
14670 vassert(0);
14671 }
sewardj2019a972011-03-07 16:04:07 +000014672 }
14673
14674 return dres;
14675}
14676
14677
14678/*------------------------------------------------------------*/
14679/*--- Top-level fn ---*/
14680/*------------------------------------------------------------*/
14681
14682/* Disassemble a single instruction into IR. The instruction
14683 is located in host memory at &guest_code[delta]. */
14684
14685DisResult
14686disInstr_S390(IRSB *irsb_IN,
sewardj2019a972011-03-07 16:04:07 +000014687 Bool (*resteerOkFn)(void *, Addr64),
14688 Bool resteerCisOk,
14689 void *callback_opaque,
14690 UChar *guest_code,
14691 Long delta,
14692 Addr64 guest_IP,
14693 VexArch guest_arch,
14694 VexArchInfo *archinfo,
14695 VexAbiInfo *abiinfo,
14696 Bool host_bigendian)
14697{
14698 vassert(guest_arch == VexArchS390X);
14699
14700 /* The instruction decoder requires a big-endian machine. */
14701 vassert(host_bigendian == True);
14702
14703 /* Set globals (see top of this file) */
14704 guest_IA_curr_instr = guest_IP;
sewardj2019a972011-03-07 16:04:07 +000014705 irsb = irsb_IN;
florian420c5012011-07-22 02:12:28 +000014706 resteer_fn = resteerOkFn;
14707 resteer_data = callback_opaque;
sewardj2019a972011-03-07 16:04:07 +000014708
florian420c5012011-07-22 02:12:28 +000014709 return disInstr_S390_WRK(guest_code + delta);
sewardj2019a972011-03-07 16:04:07 +000014710}
14711
14712/*---------------------------------------------------------------*/
14713/*--- end guest_s390_toIR.c ---*/
14714/*---------------------------------------------------------------*/