blob: 19aff59bc3d1631397e36352d9d4fdde0de98f75 [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). */
sewardj2019a972011-03-07 16:04:07 +0000433static IRRoundingMode
434encode_rounding_mode(UChar mode)
435{
436 switch (mode) {
florian847684d2012-09-05 04:19:09 +0000437 case S390_ROUND_PER_FPC: /* not supported */
438 case S390_ROUND_NEAREST_AWAY: /* not supported */
439 case S390_ROUND_PREPARE_SHORT: /* not supported */
sewardj2019a972011-03-07 16:04:07 +0000440 case S390_ROUND_NEAREST_EVEN: return Irrm_NEAREST;
441 case S390_ROUND_ZERO: return Irrm_ZERO;
442 case S390_ROUND_POSINF: return Irrm_PosINF;
443 case S390_ROUND_NEGINF: return Irrm_NegINF;
444 }
445 vpanic("encode_rounding_mode");
446}
447
448static __inline__ IRExpr *get_fpr_dw0(UInt);
449static __inline__ void put_fpr_dw0(UInt, IRExpr *);
450
451/* Read a floating point register pair and combine their contents into a
452 128-bit value */
453static IRExpr *
454get_fpr_pair(UInt archreg)
455{
456 IRExpr *high = get_fpr_dw0(archreg);
457 IRExpr *low = get_fpr_dw0(archreg + 2);
458
459 return binop(Iop_F64HLtoF128, high, low);
460}
461
462/* Write a 128-bit floating point value into a register pair. */
463static void
464put_fpr_pair(UInt archreg, IRExpr *expr)
465{
466 IRExpr *high = unop(Iop_F128HItoF64, expr);
467 IRExpr *low = unop(Iop_F128LOtoF64, expr);
468
469 put_fpr_dw0(archreg, high);
470 put_fpr_dw0(archreg + 2, low);
471}
472
floriane75dafa2012-09-01 17:54:09 +0000473/* Terminate the current IRSB with an emulation failure. */
474static void
475emulation_failure(VexEmNote fail_kind)
476{
477 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_EMNOTE), mkU32(fail_kind)));
floriane75dafa2012-09-01 17:54:09 +0000478 dis_res->whatNext = Dis_StopHere;
479 dis_res->jk_StopHere = Ijk_EmFail;
480}
sewardj2019a972011-03-07 16:04:07 +0000481
florian4b8efad2012-09-02 18:07:08 +0000482/* Terminate the current IRSB with an emulation warning. */
483static void
484emulation_warning(VexEmNote warn_kind)
485{
486 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_EMNOTE), mkU32(warn_kind)));
487 dis_res->whatNext = Dis_StopHere;
488 dis_res->jk_StopHere = Ijk_EmWarn;
489}
490
sewardj2019a972011-03-07 16:04:07 +0000491/*------------------------------------------------------------*/
florianf3410f92012-08-03 18:41:58 +0000492/*--- IR Debugging aids. ---*/
493/*------------------------------------------------------------*/
494#if 0
495
496static ULong
497s390_do_print(HChar *text, ULong value)
498{
499 vex_printf("%s %llu\n", text, value);
500 return 0;
501}
502
503static void
504s390_print(HChar *text, IRExpr *value)
505{
506 IRDirty *d;
507
508 d = unsafeIRDirty_0_N(0 /* regparms */, "s390_do_print", &s390_do_print,
509 mkIRExprVec_2(mkU64((ULong)text), value));
510 stmt(IRStmt_Dirty(d));
511}
512#endif
513
514
515/*------------------------------------------------------------*/
sewardj2019a972011-03-07 16:04:07 +0000516/*--- Build the flags thunk. ---*/
517/*------------------------------------------------------------*/
518
519/* Completely fill the flags thunk. We're always filling all fields.
520 Apparently, that is better for redundant PUT elimination. */
521static void
522s390_cc_thunk_fill(IRExpr *op, IRExpr *dep1, IRExpr *dep2, IRExpr *ndep)
523{
524 UInt op_off, dep1_off, dep2_off, ndep_off;
525
florian428dfdd2012-03-27 03:09:49 +0000526 op_off = S390X_GUEST_OFFSET(guest_CC_OP);
527 dep1_off = S390X_GUEST_OFFSET(guest_CC_DEP1);
528 dep2_off = S390X_GUEST_OFFSET(guest_CC_DEP2);
529 ndep_off = S390X_GUEST_OFFSET(guest_CC_NDEP);
sewardj2019a972011-03-07 16:04:07 +0000530
531 stmt(IRStmt_Put(op_off, op));
532 stmt(IRStmt_Put(dep1_off, dep1));
533 stmt(IRStmt_Put(dep2_off, dep2));
534 stmt(IRStmt_Put(ndep_off, ndep));
535}
536
537
538/* Create an expression for V and widen the result to 64 bit. */
539static IRExpr *
540s390_cc_widen(IRTemp v, Bool sign_extend)
541{
542 IRExpr *expr;
543
544 expr = mkexpr(v);
545
546 switch (typeOfIRTemp(irsb->tyenv, v)) {
547 case Ity_I64:
548 break;
549 case Ity_I32:
550 expr = unop(sign_extend ? Iop_32Sto64 : Iop_32Uto64, expr);
551 break;
552 case Ity_I16:
553 expr = unop(sign_extend ? Iop_16Sto64 : Iop_16Uto64, expr);
554 break;
555 case Ity_I8:
556 expr = unop(sign_extend ? Iop_8Sto64 : Iop_8Uto64, expr);
557 break;
558 default:
559 vpanic("s390_cc_widen");
560 }
561
562 return expr;
563}
564
565static void
566s390_cc_thunk_put1(UInt opc, IRTemp d1, Bool sign_extend)
567{
568 IRExpr *op, *dep1, *dep2, *ndep;
569
570 op = mkU64(opc);
571 dep1 = s390_cc_widen(d1, sign_extend);
572 dep2 = mkU64(0);
573 ndep = mkU64(0);
574
575 s390_cc_thunk_fill(op, dep1, dep2, ndep);
576}
577
578
579static void
580s390_cc_thunk_put2(UInt opc, IRTemp d1, IRTemp d2, Bool sign_extend)
581{
582 IRExpr *op, *dep1, *dep2, *ndep;
583
584 op = mkU64(opc);
585 dep1 = s390_cc_widen(d1, sign_extend);
586 dep2 = s390_cc_widen(d2, sign_extend);
587 ndep = mkU64(0);
588
589 s390_cc_thunk_fill(op, dep1, dep2, ndep);
590}
591
592
593/* memcheck believes that the NDEP field in the flags thunk is always
594 defined. But for some flag computations (e.g. add with carry) that is
595 just not true. We therefore need to convey to memcheck that the value
596 of the ndep field does matter and therefore we make the DEP2 field
597 depend on it:
598
599 DEP2 = original_DEP2 ^ NDEP
600
601 In s390_calculate_cc we exploit that (a^b)^b == a
602 I.e. we xor the DEP2 value with the NDEP value to recover the
603 original_DEP2 value. */
604static void
605s390_cc_thunk_put3(UInt opc, IRTemp d1, IRTemp d2, IRTemp nd, Bool sign_extend)
606{
607 IRExpr *op, *dep1, *dep2, *ndep, *dep2x;
608
609 op = mkU64(opc);
610 dep1 = s390_cc_widen(d1, sign_extend);
611 dep2 = s390_cc_widen(d2, sign_extend);
612 ndep = s390_cc_widen(nd, sign_extend);
613
614 dep2x = binop(Iop_Xor64, dep2, ndep);
615
616 s390_cc_thunk_fill(op, dep1, dep2x, ndep);
617}
618
619
620/* Write one floating point value into the flags thunk */
621static void
622s390_cc_thunk_put1f(UInt opc, IRTemp d1)
623{
624 IRExpr *op, *dep1, *dep2, *ndep;
625
626 op = mkU64(opc);
627 dep1 = mkexpr(d1);
628 dep2 = mkU64(0);
629 ndep = mkU64(0);
630
631 s390_cc_thunk_fill(op, dep1, dep2, ndep);
632}
633
634
635/* Write a floating point value and an integer into the flags thunk. The
636 integer value is zero-extended first. */
637static void
638s390_cc_thunk_putFZ(UInt opc, IRTemp d1, IRTemp d2)
639{
640 IRExpr *op, *dep1, *dep2, *ndep;
641
642 op = mkU64(opc);
643 dep1 = mkexpr(d1);
644 dep2 = s390_cc_widen(d2, False);
645 ndep = mkU64(0);
646
647 s390_cc_thunk_fill(op, dep1, dep2, ndep);
648}
649
650
651/* Write a 128-bit floating point value into the flags thunk. This is
652 done by splitting the value into two 64-bits values. */
653static void
654s390_cc_thunk_put1f128(UInt opc, IRTemp d1)
655{
656 IRExpr *op, *hi, *lo, *ndep;
657
658 op = mkU64(opc);
659 hi = unop(Iop_F128HItoF64, mkexpr(d1));
660 lo = unop(Iop_F128LOtoF64, mkexpr(d1));
661 ndep = mkU64(0);
662
663 s390_cc_thunk_fill(op, hi, lo, ndep);
664}
665
666
667/* Write a 128-bit floating point value and an integer into the flags thunk.
668 The integer value is zero-extended first. */
669static void
670s390_cc_thunk_put1f128Z(UInt opc, IRTemp d1, IRTemp nd)
671{
672 IRExpr *op, *hi, *lo, *lox, *ndep;
673
674 op = mkU64(opc);
675 hi = unop(Iop_F128HItoF64, mkexpr(d1));
676 lo = unop(Iop_ReinterpF64asI64, unop(Iop_F128LOtoF64, mkexpr(d1)));
677 ndep = s390_cc_widen(nd, False);
678
679 lox = binop(Iop_Xor64, lo, ndep); /* convey dependency */
680
681 s390_cc_thunk_fill(op, hi, lox, ndep);
682}
683
684
685static void
686s390_cc_set(UInt val)
687{
688 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
689 mkU64(val), mkU64(0), mkU64(0));
690}
691
692/* Build IR to calculate the condition code from flags thunk.
693 Returns an expression of type Ity_I32 */
694static IRExpr *
695s390_call_calculate_cc(void)
696{
697 IRExpr **args, *call, *op, *dep1, *dep2, *ndep;
698
florian428dfdd2012-03-27 03:09:49 +0000699 op = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_OP), Ity_I64);
700 dep1 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP1), Ity_I64);
701 dep2 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP2), Ity_I64);
702 ndep = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_NDEP), Ity_I64);
sewardj2019a972011-03-07 16:04:07 +0000703
704 args = mkIRExprVec_4(op, dep1, dep2, ndep);
705 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
706 "s390_calculate_cc", &s390_calculate_cc, args);
707
708 /* Exclude OP and NDEP from definedness checking. We're only
709 interested in DEP1 and DEP2. */
710 call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<3);
711
712 return call;
713}
714
715/* Build IR to calculate the internal condition code for a "compare and branch"
716 insn. Returns an expression of type Ity_I32 */
717static IRExpr *
florianff9613f2012-05-12 15:26:44 +0000718s390_call_calculate_icc(UInt m, UInt opc, IRTemp op1, IRTemp op2)
sewardj2019a972011-03-07 16:04:07 +0000719{
florianff9613f2012-05-12 15:26:44 +0000720 IRExpr **args, *call, *op, *dep1, *dep2, *mask;
sewardj2019a972011-03-07 16:04:07 +0000721
florianff9613f2012-05-12 15:26:44 +0000722 switch (opc) {
723 case S390_CC_OP_SIGNED_COMPARE:
724 dep1 = s390_cc_widen(op1, True);
725 dep2 = s390_cc_widen(op2, True);
726 break;
727
728 case S390_CC_OP_UNSIGNED_COMPARE:
729 dep1 = s390_cc_widen(op1, False);
730 dep2 = s390_cc_widen(op2, False);
731 break;
732
733 default:
734 vpanic("s390_call_calculate_icc");
735 }
736
737 mask = mkU64(m);
sewardj2019a972011-03-07 16:04:07 +0000738 op = mkU64(opc);
sewardj2019a972011-03-07 16:04:07 +0000739
florianff9613f2012-05-12 15:26:44 +0000740 args = mkIRExprVec_5(mask, op, dep1, dep2, mkU64(0) /* unused */);
sewardj2019a972011-03-07 16:04:07 +0000741 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
florianff9613f2012-05-12 15:26:44 +0000742 "s390_calculate_cond", &s390_calculate_cond, args);
sewardj2019a972011-03-07 16:04:07 +0000743
florianff9613f2012-05-12 15:26:44 +0000744 /* Exclude the requested condition, OP and NDEP from definedness
745 checking. We're only interested in DEP1 and DEP2. */
746 call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<1) | (1<<4);
sewardj2019a972011-03-07 16:04:07 +0000747
748 return call;
749}
750
751/* Build IR to calculate the condition code from flags thunk.
752 Returns an expression of type Ity_I32 */
753static IRExpr *
754s390_call_calculate_cond(UInt m)
755{
756 IRExpr **args, *call, *op, *dep1, *dep2, *ndep, *mask;
757
758 mask = mkU64(m);
florian428dfdd2012-03-27 03:09:49 +0000759 op = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_OP), Ity_I64);
760 dep1 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP1), Ity_I64);
761 dep2 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP2), Ity_I64);
762 ndep = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_NDEP), Ity_I64);
sewardj2019a972011-03-07 16:04:07 +0000763
764 args = mkIRExprVec_5(mask, op, dep1, dep2, ndep);
765 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
766 "s390_calculate_cond", &s390_calculate_cond, args);
767
768 /* Exclude the requested condition, OP and NDEP from definedness
769 checking. We're only interested in DEP1 and DEP2. */
770 call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<1) | (1<<4);
771
772 return call;
773}
774
775#define s390_cc_thunk_putZ(op,dep1) s390_cc_thunk_put1(op,dep1,False)
776#define s390_cc_thunk_putS(op,dep1) s390_cc_thunk_put1(op,dep1,True)
777#define s390_cc_thunk_putF(op,dep1) s390_cc_thunk_put1f(op,dep1)
778#define s390_cc_thunk_putZZ(op,dep1,dep2) s390_cc_thunk_put2(op,dep1,dep2,False)
779#define s390_cc_thunk_putSS(op,dep1,dep2) s390_cc_thunk_put2(op,dep1,dep2,True)
780#define s390_cc_thunk_putFF(op,dep1,dep2) s390_cc_thunk_put2f(op,dep1,dep2)
781#define s390_cc_thunk_putZZZ(op,dep1,dep2,ndep) \
782 s390_cc_thunk_put3(op,dep1,dep2,ndep,False)
783#define s390_cc_thunk_putSSS(op,dep1,dep2,ndep) \
784 s390_cc_thunk_put3(op,dep1,dep2,ndep,True)
sewardj2019a972011-03-07 16:04:07 +0000785
786
sewardj2019a972011-03-07 16:04:07 +0000787
788
789/*------------------------------------------------------------*/
790/*--- Guest register access ---*/
791/*------------------------------------------------------------*/
792
793
794/*------------------------------------------------------------*/
795/*--- ar registers ---*/
796/*------------------------------------------------------------*/
797
798/* Return the guest state offset of a ar register. */
799static UInt
800ar_offset(UInt archreg)
801{
802 static const UInt offset[16] = {
floriane88b3c92011-07-05 02:48:39 +0000803 S390X_GUEST_OFFSET(guest_a0),
804 S390X_GUEST_OFFSET(guest_a1),
805 S390X_GUEST_OFFSET(guest_a2),
806 S390X_GUEST_OFFSET(guest_a3),
807 S390X_GUEST_OFFSET(guest_a4),
808 S390X_GUEST_OFFSET(guest_a5),
809 S390X_GUEST_OFFSET(guest_a6),
810 S390X_GUEST_OFFSET(guest_a7),
811 S390X_GUEST_OFFSET(guest_a8),
812 S390X_GUEST_OFFSET(guest_a9),
813 S390X_GUEST_OFFSET(guest_a10),
814 S390X_GUEST_OFFSET(guest_a11),
815 S390X_GUEST_OFFSET(guest_a12),
816 S390X_GUEST_OFFSET(guest_a13),
817 S390X_GUEST_OFFSET(guest_a14),
818 S390X_GUEST_OFFSET(guest_a15),
sewardj2019a972011-03-07 16:04:07 +0000819 };
820
821 vassert(archreg < 16);
822
823 return offset[archreg];
824}
825
826
827/* Return the guest state offset of word #0 of a ar register. */
828static __inline__ UInt
829ar_w0_offset(UInt archreg)
830{
831 return ar_offset(archreg) + 0;
832}
833
834/* Write word #0 of a ar to the guest state. */
835static __inline__ void
836put_ar_w0(UInt archreg, IRExpr *expr)
837{
838 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
839
840 stmt(IRStmt_Put(ar_w0_offset(archreg), expr));
841}
842
843/* Read word #0 of a ar register. */
844static __inline__ IRExpr *
845get_ar_w0(UInt archreg)
846{
847 return IRExpr_Get(ar_w0_offset(archreg), Ity_I32);
848}
849
850
851/*------------------------------------------------------------*/
852/*--- fpr registers ---*/
853/*------------------------------------------------------------*/
854
855/* Return the guest state offset of a fpr register. */
856static UInt
857fpr_offset(UInt archreg)
858{
859 static const UInt offset[16] = {
floriane88b3c92011-07-05 02:48:39 +0000860 S390X_GUEST_OFFSET(guest_f0),
861 S390X_GUEST_OFFSET(guest_f1),
862 S390X_GUEST_OFFSET(guest_f2),
863 S390X_GUEST_OFFSET(guest_f3),
864 S390X_GUEST_OFFSET(guest_f4),
865 S390X_GUEST_OFFSET(guest_f5),
866 S390X_GUEST_OFFSET(guest_f6),
867 S390X_GUEST_OFFSET(guest_f7),
868 S390X_GUEST_OFFSET(guest_f8),
869 S390X_GUEST_OFFSET(guest_f9),
870 S390X_GUEST_OFFSET(guest_f10),
871 S390X_GUEST_OFFSET(guest_f11),
872 S390X_GUEST_OFFSET(guest_f12),
873 S390X_GUEST_OFFSET(guest_f13),
874 S390X_GUEST_OFFSET(guest_f14),
875 S390X_GUEST_OFFSET(guest_f15),
sewardj2019a972011-03-07 16:04:07 +0000876 };
877
878 vassert(archreg < 16);
879
880 return offset[archreg];
881}
882
883
884/* Return the guest state offset of word #0 of a fpr register. */
885static __inline__ UInt
886fpr_w0_offset(UInt archreg)
887{
888 return fpr_offset(archreg) + 0;
889}
890
891/* Write word #0 of a fpr to the guest state. */
892static __inline__ void
893put_fpr_w0(UInt archreg, IRExpr *expr)
894{
895 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_F32);
896
897 stmt(IRStmt_Put(fpr_w0_offset(archreg), expr));
898}
899
900/* Read word #0 of a fpr register. */
901static __inline__ IRExpr *
902get_fpr_w0(UInt archreg)
903{
904 return IRExpr_Get(fpr_w0_offset(archreg), Ity_F32);
905}
906
907/* Return the guest state offset of double word #0 of a fpr register. */
908static __inline__ UInt
909fpr_dw0_offset(UInt archreg)
910{
911 return fpr_offset(archreg) + 0;
912}
913
914/* Write double word #0 of a fpr to the guest state. */
915static __inline__ void
916put_fpr_dw0(UInt archreg, IRExpr *expr)
917{
918 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_F64);
919
920 stmt(IRStmt_Put(fpr_dw0_offset(archreg), expr));
921}
922
923/* Read double word #0 of a fpr register. */
924static __inline__ IRExpr *
925get_fpr_dw0(UInt archreg)
926{
927 return IRExpr_Get(fpr_dw0_offset(archreg), Ity_F64);
928}
929
930
931/*------------------------------------------------------------*/
932/*--- gpr registers ---*/
933/*------------------------------------------------------------*/
934
935/* Return the guest state offset of a gpr register. */
936static UInt
937gpr_offset(UInt archreg)
938{
939 static const UInt offset[16] = {
floriane88b3c92011-07-05 02:48:39 +0000940 S390X_GUEST_OFFSET(guest_r0),
941 S390X_GUEST_OFFSET(guest_r1),
942 S390X_GUEST_OFFSET(guest_r2),
943 S390X_GUEST_OFFSET(guest_r3),
944 S390X_GUEST_OFFSET(guest_r4),
945 S390X_GUEST_OFFSET(guest_r5),
946 S390X_GUEST_OFFSET(guest_r6),
947 S390X_GUEST_OFFSET(guest_r7),
948 S390X_GUEST_OFFSET(guest_r8),
949 S390X_GUEST_OFFSET(guest_r9),
950 S390X_GUEST_OFFSET(guest_r10),
951 S390X_GUEST_OFFSET(guest_r11),
952 S390X_GUEST_OFFSET(guest_r12),
953 S390X_GUEST_OFFSET(guest_r13),
954 S390X_GUEST_OFFSET(guest_r14),
955 S390X_GUEST_OFFSET(guest_r15),
sewardj2019a972011-03-07 16:04:07 +0000956 };
957
958 vassert(archreg < 16);
959
960 return offset[archreg];
961}
962
963
964/* Return the guest state offset of word #0 of a gpr register. */
965static __inline__ UInt
966gpr_w0_offset(UInt archreg)
967{
968 return gpr_offset(archreg) + 0;
969}
970
971/* Write word #0 of a gpr to the guest state. */
972static __inline__ void
973put_gpr_w0(UInt archreg, IRExpr *expr)
974{
975 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
976
977 stmt(IRStmt_Put(gpr_w0_offset(archreg), expr));
978}
979
980/* Read word #0 of a gpr register. */
981static __inline__ IRExpr *
982get_gpr_w0(UInt archreg)
983{
984 return IRExpr_Get(gpr_w0_offset(archreg), Ity_I32);
985}
986
987/* Return the guest state offset of double word #0 of a gpr register. */
988static __inline__ UInt
989gpr_dw0_offset(UInt archreg)
990{
991 return gpr_offset(archreg) + 0;
992}
993
994/* Write double word #0 of a gpr to the guest state. */
995static __inline__ void
996put_gpr_dw0(UInt archreg, IRExpr *expr)
997{
998 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I64);
999
1000 stmt(IRStmt_Put(gpr_dw0_offset(archreg), expr));
1001}
1002
1003/* Read double word #0 of a gpr register. */
1004static __inline__ IRExpr *
1005get_gpr_dw0(UInt archreg)
1006{
1007 return IRExpr_Get(gpr_dw0_offset(archreg), Ity_I64);
1008}
1009
1010/* Return the guest state offset of half word #1 of a gpr register. */
1011static __inline__ UInt
1012gpr_hw1_offset(UInt archreg)
1013{
1014 return gpr_offset(archreg) + 2;
1015}
1016
1017/* Write half word #1 of a gpr to the guest state. */
1018static __inline__ void
1019put_gpr_hw1(UInt archreg, IRExpr *expr)
1020{
1021 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1022
1023 stmt(IRStmt_Put(gpr_hw1_offset(archreg), expr));
1024}
1025
1026/* Read half word #1 of a gpr register. */
1027static __inline__ IRExpr *
1028get_gpr_hw1(UInt archreg)
1029{
1030 return IRExpr_Get(gpr_hw1_offset(archreg), Ity_I16);
1031}
1032
1033/* Return the guest state offset of byte #6 of a gpr register. */
1034static __inline__ UInt
1035gpr_b6_offset(UInt archreg)
1036{
1037 return gpr_offset(archreg) + 6;
1038}
1039
1040/* Write byte #6 of a gpr to the guest state. */
1041static __inline__ void
1042put_gpr_b6(UInt archreg, IRExpr *expr)
1043{
1044 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1045
1046 stmt(IRStmt_Put(gpr_b6_offset(archreg), expr));
1047}
1048
1049/* Read byte #6 of a gpr register. */
1050static __inline__ IRExpr *
1051get_gpr_b6(UInt archreg)
1052{
1053 return IRExpr_Get(gpr_b6_offset(archreg), Ity_I8);
1054}
1055
1056/* Return the guest state offset of byte #3 of a gpr register. */
1057static __inline__ UInt
1058gpr_b3_offset(UInt archreg)
1059{
1060 return gpr_offset(archreg) + 3;
1061}
1062
1063/* Write byte #3 of a gpr to the guest state. */
1064static __inline__ void
1065put_gpr_b3(UInt archreg, IRExpr *expr)
1066{
1067 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1068
1069 stmt(IRStmt_Put(gpr_b3_offset(archreg), expr));
1070}
1071
1072/* Read byte #3 of a gpr register. */
1073static __inline__ IRExpr *
1074get_gpr_b3(UInt archreg)
1075{
1076 return IRExpr_Get(gpr_b3_offset(archreg), Ity_I8);
1077}
1078
1079/* Return the guest state offset of byte #0 of a gpr register. */
1080static __inline__ UInt
1081gpr_b0_offset(UInt archreg)
1082{
1083 return gpr_offset(archreg) + 0;
1084}
1085
1086/* Write byte #0 of a gpr to the guest state. */
1087static __inline__ void
1088put_gpr_b0(UInt archreg, IRExpr *expr)
1089{
1090 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1091
1092 stmt(IRStmt_Put(gpr_b0_offset(archreg), expr));
1093}
1094
1095/* Read byte #0 of a gpr register. */
1096static __inline__ IRExpr *
1097get_gpr_b0(UInt archreg)
1098{
1099 return IRExpr_Get(gpr_b0_offset(archreg), Ity_I8);
1100}
1101
1102/* Return the guest state offset of word #1 of a gpr register. */
1103static __inline__ UInt
1104gpr_w1_offset(UInt archreg)
1105{
1106 return gpr_offset(archreg) + 4;
1107}
1108
1109/* Write word #1 of a gpr to the guest state. */
1110static __inline__ void
1111put_gpr_w1(UInt archreg, IRExpr *expr)
1112{
1113 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1114
1115 stmt(IRStmt_Put(gpr_w1_offset(archreg), expr));
1116}
1117
1118/* Read word #1 of a gpr register. */
1119static __inline__ IRExpr *
1120get_gpr_w1(UInt archreg)
1121{
1122 return IRExpr_Get(gpr_w1_offset(archreg), Ity_I32);
1123}
1124
1125/* Return the guest state offset of half word #3 of a gpr register. */
1126static __inline__ UInt
1127gpr_hw3_offset(UInt archreg)
1128{
1129 return gpr_offset(archreg) + 6;
1130}
1131
1132/* Write half word #3 of a gpr to the guest state. */
1133static __inline__ void
1134put_gpr_hw3(UInt archreg, IRExpr *expr)
1135{
1136 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1137
1138 stmt(IRStmt_Put(gpr_hw3_offset(archreg), expr));
1139}
1140
1141/* Read half word #3 of a gpr register. */
1142static __inline__ IRExpr *
1143get_gpr_hw3(UInt archreg)
1144{
1145 return IRExpr_Get(gpr_hw3_offset(archreg), Ity_I16);
1146}
1147
1148/* Return the guest state offset of byte #7 of a gpr register. */
1149static __inline__ UInt
1150gpr_b7_offset(UInt archreg)
1151{
1152 return gpr_offset(archreg) + 7;
1153}
1154
1155/* Write byte #7 of a gpr to the guest state. */
1156static __inline__ void
1157put_gpr_b7(UInt archreg, IRExpr *expr)
1158{
1159 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1160
1161 stmt(IRStmt_Put(gpr_b7_offset(archreg), expr));
1162}
1163
1164/* Read byte #7 of a gpr register. */
1165static __inline__ IRExpr *
1166get_gpr_b7(UInt archreg)
1167{
1168 return IRExpr_Get(gpr_b7_offset(archreg), Ity_I8);
1169}
1170
1171/* Return the guest state offset of half word #0 of a gpr register. */
1172static __inline__ UInt
1173gpr_hw0_offset(UInt archreg)
1174{
1175 return gpr_offset(archreg) + 0;
1176}
1177
1178/* Write half word #0 of a gpr to the guest state. */
1179static __inline__ void
1180put_gpr_hw0(UInt archreg, IRExpr *expr)
1181{
1182 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1183
1184 stmt(IRStmt_Put(gpr_hw0_offset(archreg), expr));
1185}
1186
1187/* Read half word #0 of a gpr register. */
1188static __inline__ IRExpr *
1189get_gpr_hw0(UInt archreg)
1190{
1191 return IRExpr_Get(gpr_hw0_offset(archreg), Ity_I16);
1192}
1193
1194/* Return the guest state offset of byte #4 of a gpr register. */
1195static __inline__ UInt
1196gpr_b4_offset(UInt archreg)
1197{
1198 return gpr_offset(archreg) + 4;
1199}
1200
1201/* Write byte #4 of a gpr to the guest state. */
1202static __inline__ void
1203put_gpr_b4(UInt archreg, IRExpr *expr)
1204{
1205 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1206
1207 stmt(IRStmt_Put(gpr_b4_offset(archreg), expr));
1208}
1209
1210/* Read byte #4 of a gpr register. */
1211static __inline__ IRExpr *
1212get_gpr_b4(UInt archreg)
1213{
1214 return IRExpr_Get(gpr_b4_offset(archreg), Ity_I8);
1215}
1216
1217/* Return the guest state offset of byte #1 of a gpr register. */
1218static __inline__ UInt
1219gpr_b1_offset(UInt archreg)
1220{
1221 return gpr_offset(archreg) + 1;
1222}
1223
1224/* Write byte #1 of a gpr to the guest state. */
1225static __inline__ void
1226put_gpr_b1(UInt archreg, IRExpr *expr)
1227{
1228 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1229
1230 stmt(IRStmt_Put(gpr_b1_offset(archreg), expr));
1231}
1232
1233/* Read byte #1 of a gpr register. */
1234static __inline__ IRExpr *
1235get_gpr_b1(UInt archreg)
1236{
1237 return IRExpr_Get(gpr_b1_offset(archreg), Ity_I8);
1238}
1239
1240/* Return the guest state offset of half word #2 of a gpr register. */
1241static __inline__ UInt
1242gpr_hw2_offset(UInt archreg)
1243{
1244 return gpr_offset(archreg) + 4;
1245}
1246
1247/* Write half word #2 of a gpr to the guest state. */
1248static __inline__ void
1249put_gpr_hw2(UInt archreg, IRExpr *expr)
1250{
1251 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1252
1253 stmt(IRStmt_Put(gpr_hw2_offset(archreg), expr));
1254}
1255
1256/* Read half word #2 of a gpr register. */
1257static __inline__ IRExpr *
1258get_gpr_hw2(UInt archreg)
1259{
1260 return IRExpr_Get(gpr_hw2_offset(archreg), Ity_I16);
1261}
1262
1263/* Return the guest state offset of byte #5 of a gpr register. */
1264static __inline__ UInt
1265gpr_b5_offset(UInt archreg)
1266{
1267 return gpr_offset(archreg) + 5;
1268}
1269
1270/* Write byte #5 of a gpr to the guest state. */
1271static __inline__ void
1272put_gpr_b5(UInt archreg, IRExpr *expr)
1273{
1274 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1275
1276 stmt(IRStmt_Put(gpr_b5_offset(archreg), expr));
1277}
1278
1279/* Read byte #5 of a gpr register. */
1280static __inline__ IRExpr *
1281get_gpr_b5(UInt archreg)
1282{
1283 return IRExpr_Get(gpr_b5_offset(archreg), Ity_I8);
1284}
1285
1286/* Return the guest state offset of byte #2 of a gpr register. */
1287static __inline__ UInt
1288gpr_b2_offset(UInt archreg)
1289{
1290 return gpr_offset(archreg) + 2;
1291}
1292
1293/* Write byte #2 of a gpr to the guest state. */
1294static __inline__ void
1295put_gpr_b2(UInt archreg, IRExpr *expr)
1296{
1297 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1298
1299 stmt(IRStmt_Put(gpr_b2_offset(archreg), expr));
1300}
1301
1302/* Read byte #2 of a gpr register. */
1303static __inline__ IRExpr *
1304get_gpr_b2(UInt archreg)
1305{
1306 return IRExpr_Get(gpr_b2_offset(archreg), Ity_I8);
1307}
1308
1309/* Return the guest state offset of the counter register. */
1310static UInt
1311counter_offset(void)
1312{
floriane88b3c92011-07-05 02:48:39 +00001313 return S390X_GUEST_OFFSET(guest_counter);
sewardj2019a972011-03-07 16:04:07 +00001314}
1315
1316/* Return the guest state offset of double word #0 of the counter register. */
1317static __inline__ UInt
1318counter_dw0_offset(void)
1319{
1320 return counter_offset() + 0;
1321}
1322
1323/* Write double word #0 of the counter to the guest state. */
1324static __inline__ void
1325put_counter_dw0(IRExpr *expr)
1326{
1327 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I64);
1328
1329 stmt(IRStmt_Put(counter_dw0_offset(), expr));
1330}
1331
1332/* Read double word #0 of the counter register. */
1333static __inline__ IRExpr *
1334get_counter_dw0(void)
1335{
1336 return IRExpr_Get(counter_dw0_offset(), Ity_I64);
1337}
1338
1339/* Return the guest state offset of word #0 of the counter register. */
1340static __inline__ UInt
1341counter_w0_offset(void)
1342{
1343 return counter_offset() + 0;
1344}
1345
1346/* Return the guest state offset of word #1 of the counter register. */
1347static __inline__ UInt
1348counter_w1_offset(void)
1349{
1350 return counter_offset() + 4;
1351}
1352
1353/* Write word #0 of the counter to the guest state. */
1354static __inline__ void
1355put_counter_w0(IRExpr *expr)
1356{
1357 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1358
1359 stmt(IRStmt_Put(counter_w0_offset(), expr));
1360}
1361
1362/* Read word #0 of the counter register. */
1363static __inline__ IRExpr *
1364get_counter_w0(void)
1365{
1366 return IRExpr_Get(counter_w0_offset(), Ity_I32);
1367}
1368
1369/* Write word #1 of the counter to the guest state. */
1370static __inline__ void
1371put_counter_w1(IRExpr *expr)
1372{
1373 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1374
1375 stmt(IRStmt_Put(counter_w1_offset(), expr));
1376}
1377
1378/* Read word #1 of the counter register. */
1379static __inline__ IRExpr *
1380get_counter_w1(void)
1381{
1382 return IRExpr_Get(counter_w1_offset(), Ity_I32);
1383}
1384
1385/* Return the guest state offset of the fpc register. */
1386static UInt
1387fpc_offset(void)
1388{
floriane88b3c92011-07-05 02:48:39 +00001389 return S390X_GUEST_OFFSET(guest_fpc);
sewardj2019a972011-03-07 16:04:07 +00001390}
1391
1392/* Return the guest state offset of word #0 of the fpc register. */
1393static __inline__ UInt
1394fpc_w0_offset(void)
1395{
1396 return fpc_offset() + 0;
1397}
1398
1399/* Write word #0 of the fpc to the guest state. */
1400static __inline__ void
1401put_fpc_w0(IRExpr *expr)
1402{
1403 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1404
1405 stmt(IRStmt_Put(fpc_w0_offset(), expr));
1406}
1407
1408/* Read word #0 of the fpc register. */
1409static __inline__ IRExpr *
1410get_fpc_w0(void)
1411{
1412 return IRExpr_Get(fpc_w0_offset(), Ity_I32);
1413}
1414
1415
1416/*------------------------------------------------------------*/
1417/*--- Build IR for formats ---*/
1418/*------------------------------------------------------------*/
1419static void
1420s390_format_I(HChar *(*irgen)(UChar i),
1421 UChar i)
1422{
1423 HChar *mnm = irgen(i);
1424
sewardj7ee97522011-05-09 21:45:04 +00001425 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001426 s390_disasm(ENC2(MNM, UINT), mnm, i);
1427}
1428
1429static void
1430s390_format_RI(HChar *(*irgen)(UChar r1, UShort i2),
1431 UChar r1, UShort i2)
1432{
1433 irgen(r1, i2);
1434}
1435
1436static void
1437s390_format_RI_RU(HChar *(*irgen)(UChar r1, UShort i2),
1438 UChar r1, UShort i2)
1439{
1440 HChar *mnm = irgen(r1, i2);
1441
sewardj7ee97522011-05-09 21:45:04 +00001442 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001443 s390_disasm(ENC3(MNM, GPR, UINT), mnm, r1, i2);
1444}
1445
1446static void
1447s390_format_RI_RI(HChar *(*irgen)(UChar r1, UShort i2),
1448 UChar r1, UShort i2)
1449{
1450 HChar *mnm = irgen(r1, i2);
1451
sewardj7ee97522011-05-09 21:45:04 +00001452 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001453 s390_disasm(ENC3(MNM, GPR, INT), mnm, r1, (Int)(Short)i2);
1454}
1455
1456static void
1457s390_format_RI_RP(HChar *(*irgen)(UChar r1, UShort i2),
1458 UChar r1, UShort i2)
1459{
1460 HChar *mnm = irgen(r1, i2);
1461
sewardj7ee97522011-05-09 21:45:04 +00001462 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001463 s390_disasm(ENC3(MNM, GPR, PCREL), mnm, r1, (Int)(Short)i2);
1464}
1465
1466static void
1467s390_format_RIE_RRP(HChar *(*irgen)(UChar r1, UChar r3, UShort i2),
1468 UChar r1, UChar r3, UShort i2)
1469{
1470 HChar *mnm = irgen(r1, r3, i2);
1471
sewardj7ee97522011-05-09 21:45:04 +00001472 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001473 s390_disasm(ENC4(MNM, GPR, GPR, PCREL), mnm, r1, r3, (Int)(Short)i2);
1474}
1475
1476static void
1477s390_format_RIE_RRI0(HChar *(*irgen)(UChar r1, UChar r3, UShort i2),
1478 UChar r1, UChar r3, UShort i2)
1479{
1480 HChar *mnm = irgen(r1, r3, i2);
1481
sewardj7ee97522011-05-09 21:45:04 +00001482 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001483 s390_disasm(ENC4(MNM, GPR, GPR, INT), mnm, r1, r3, (Int)(Short)i2);
1484}
1485
1486static void
1487s390_format_RIE_RRUUU(HChar *(*irgen)(UChar r1, UChar r2, UChar i3, UChar i4,
1488 UChar i5),
1489 UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
1490{
1491 HChar *mnm = irgen(r1, r2, i3, i4, i5);
1492
sewardj7ee97522011-05-09 21:45:04 +00001493 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001494 s390_disasm(ENC6(MNM, GPR, GPR, UINT, UINT, UINT), mnm, r1, r2, i3, i4,
1495 i5);
1496}
1497
1498static void
1499s390_format_RIE_RRPU(HChar *(*irgen)(UChar r1, UChar r2, UShort i4, UChar m3),
1500 UChar r1, UChar r2, UShort i4, UChar m3)
1501{
1502 HChar *mnm = irgen(r1, r2, i4, m3);
1503
sewardj7ee97522011-05-09 21:45:04 +00001504 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001505 s390_disasm(ENC5(XMNM, GPR, GPR, CABM, PCREL), S390_XMNM_CAB, mnm, m3, r1,
1506 r2, m3, (Int)(Short)i4);
1507}
1508
1509static void
1510s390_format_RIE_RUPU(HChar *(*irgen)(UChar r1, UChar m3, UShort i4, UChar i2),
1511 UChar r1, UChar m3, UShort i4, UChar i2)
1512{
1513 HChar *mnm = irgen(r1, m3, i4, i2);
1514
sewardj7ee97522011-05-09 21:45:04 +00001515 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001516 s390_disasm(ENC5(XMNM, GPR, UINT, CABM, PCREL), S390_XMNM_CAB, mnm, m3,
1517 r1, i2, m3, (Int)(Short)i4);
1518}
1519
1520static void
1521s390_format_RIE_RUPI(HChar *(*irgen)(UChar r1, UChar m3, UShort i4, UChar i2),
1522 UChar r1, UChar m3, UShort i4, UChar i2)
1523{
1524 HChar *mnm = irgen(r1, m3, i4, i2);
1525
sewardj7ee97522011-05-09 21:45:04 +00001526 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001527 s390_disasm(ENC5(XMNM, GPR, INT, CABM, PCREL), S390_XMNM_CAB, mnm, m3, r1,
1528 (Int)(Char)i2, m3, (Int)(Short)i4);
1529}
1530
1531static void
1532s390_format_RIL(HChar *(*irgen)(UChar r1, UInt i2),
1533 UChar r1, UInt i2)
1534{
1535 irgen(r1, i2);
1536}
1537
1538static void
1539s390_format_RIL_RU(HChar *(*irgen)(UChar r1, UInt i2),
1540 UChar r1, UInt i2)
1541{
1542 HChar *mnm = irgen(r1, i2);
1543
sewardj7ee97522011-05-09 21:45:04 +00001544 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001545 s390_disasm(ENC3(MNM, GPR, UINT), mnm, r1, i2);
1546}
1547
1548static void
1549s390_format_RIL_RI(HChar *(*irgen)(UChar r1, UInt i2),
1550 UChar r1, UInt i2)
1551{
1552 HChar *mnm = irgen(r1, i2);
1553
sewardj7ee97522011-05-09 21:45:04 +00001554 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001555 s390_disasm(ENC3(MNM, GPR, INT), mnm, r1, i2);
1556}
1557
1558static void
1559s390_format_RIL_RP(HChar *(*irgen)(UChar r1, UInt i2),
1560 UChar r1, UInt i2)
1561{
1562 HChar *mnm = irgen(r1, i2);
1563
sewardj7ee97522011-05-09 21:45:04 +00001564 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001565 s390_disasm(ENC3(MNM, GPR, PCREL), mnm, r1, i2);
1566}
1567
1568static void
1569s390_format_RIL_UP(HChar *(*irgen)(void),
1570 UChar r1, UInt i2)
1571{
1572 HChar *mnm = irgen();
1573
sewardj7ee97522011-05-09 21:45:04 +00001574 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001575 s390_disasm(ENC3(MNM, UINT, PCREL), mnm, r1, i2);
1576}
1577
1578static void
1579s390_format_RIS_RURDI(HChar *(*irgen)(UChar r1, UChar m3, UChar i2,
1580 IRTemp op4addr),
1581 UChar r1, UChar m3, UChar b4, UShort d4, UChar i2)
1582{
1583 HChar *mnm;
1584 IRTemp op4addr = newTemp(Ity_I64);
1585
1586 assign(op4addr, binop(Iop_Add64, mkU64(d4), b4 != 0 ? get_gpr_dw0(b4) :
1587 mkU64(0)));
1588
1589 mnm = irgen(r1, m3, i2, op4addr);
1590
sewardj7ee97522011-05-09 21:45:04 +00001591 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001592 s390_disasm(ENC5(XMNM, GPR, INT, CABM, UDXB), S390_XMNM_CAB, mnm, m3, r1,
1593 (Int)(Char)i2, m3, d4, 0, b4);
1594}
1595
1596static void
1597s390_format_RIS_RURDU(HChar *(*irgen)(UChar r1, UChar m3, UChar i2,
1598 IRTemp op4addr),
1599 UChar r1, UChar m3, UChar b4, UShort d4, UChar i2)
1600{
1601 HChar *mnm;
1602 IRTemp op4addr = newTemp(Ity_I64);
1603
1604 assign(op4addr, binop(Iop_Add64, mkU64(d4), b4 != 0 ? get_gpr_dw0(b4) :
1605 mkU64(0)));
1606
1607 mnm = irgen(r1, m3, i2, op4addr);
1608
sewardj7ee97522011-05-09 21:45:04 +00001609 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001610 s390_disasm(ENC5(XMNM, GPR, UINT, CABM, UDXB), S390_XMNM_CAB, mnm, m3, r1,
1611 i2, m3, d4, 0, b4);
1612}
1613
1614static void
1615s390_format_RR(HChar *(*irgen)(UChar r1, UChar r2),
1616 UChar r1, UChar r2)
1617{
1618 irgen(r1, r2);
1619}
1620
1621static void
1622s390_format_RR_RR(HChar *(*irgen)(UChar r1, UChar r2),
1623 UChar r1, UChar r2)
1624{
1625 HChar *mnm = irgen(r1, r2);
1626
sewardj7ee97522011-05-09 21:45:04 +00001627 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001628 s390_disasm(ENC3(MNM, GPR, GPR), mnm, r1, r2);
1629}
1630
1631static void
1632s390_format_RR_FF(HChar *(*irgen)(UChar r1, UChar r2),
1633 UChar r1, UChar r2)
1634{
1635 HChar *mnm = irgen(r1, r2);
1636
sewardj7ee97522011-05-09 21:45:04 +00001637 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001638 s390_disasm(ENC3(MNM, FPR, FPR), mnm, r1, r2);
1639}
1640
1641static void
1642s390_format_RRE(HChar *(*irgen)(UChar r1, UChar r2),
1643 UChar r1, UChar r2)
1644{
1645 irgen(r1, r2);
1646}
1647
1648static void
1649s390_format_RRE_RR(HChar *(*irgen)(UChar r1, UChar r2),
1650 UChar r1, UChar r2)
1651{
1652 HChar *mnm = irgen(r1, r2);
1653
sewardj7ee97522011-05-09 21:45:04 +00001654 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001655 s390_disasm(ENC3(MNM, GPR, GPR), mnm, r1, r2);
1656}
1657
1658static void
1659s390_format_RRE_FF(HChar *(*irgen)(UChar r1, UChar r2),
1660 UChar r1, UChar r2)
1661{
1662 HChar *mnm = irgen(r1, r2);
1663
sewardj7ee97522011-05-09 21:45:04 +00001664 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001665 s390_disasm(ENC3(MNM, FPR, FPR), mnm, r1, r2);
1666}
1667
1668static void
1669s390_format_RRE_RF(HChar *(*irgen)(UChar, UChar),
1670 UChar r1, UChar r2)
1671{
1672 HChar *mnm = irgen(r1, r2);
1673
sewardj7ee97522011-05-09 21:45:04 +00001674 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001675 s390_disasm(ENC3(MNM, GPR, FPR), mnm, r1, r2);
1676}
1677
1678static void
1679s390_format_RRE_FR(HChar *(*irgen)(UChar r1, UChar r2),
1680 UChar r1, UChar r2)
1681{
1682 HChar *mnm = irgen(r1, r2);
1683
sewardj7ee97522011-05-09 21:45:04 +00001684 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001685 s390_disasm(ENC3(MNM, FPR, GPR), mnm, r1, r2);
1686}
1687
1688static void
1689s390_format_RRE_R0(HChar *(*irgen)(UChar r1),
1690 UChar r1)
1691{
1692 HChar *mnm = irgen(r1);
1693
sewardj7ee97522011-05-09 21:45:04 +00001694 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001695 s390_disasm(ENC2(MNM, GPR), mnm, r1);
1696}
1697
1698static void
1699s390_format_RRE_F0(HChar *(*irgen)(UChar r1),
1700 UChar r1)
1701{
1702 HChar *mnm = irgen(r1);
1703
sewardj7ee97522011-05-09 21:45:04 +00001704 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001705 s390_disasm(ENC2(MNM, FPR), mnm, r1);
1706}
1707
1708static void
florian9af37692012-01-15 21:01:16 +00001709s390_format_RRF_M0RERE(HChar *(*irgen)(UChar m3, UChar r1, UChar r2),
1710 UChar m3, UChar r1, UChar r2)
1711{
florianfed3ea32012-07-19 14:54:03 +00001712 HChar *mnm = irgen(m3, r1, r2);
florian9af37692012-01-15 21:01:16 +00001713
1714 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
florianfed3ea32012-07-19 14:54:03 +00001715 s390_disasm(ENC4(MNM, GPR, GPR, UINT), mnm, r1, r2, m3);
florian9af37692012-01-15 21:01:16 +00001716}
1717
1718static void
sewardj2019a972011-03-07 16:04:07 +00001719s390_format_RRF_F0FF(HChar *(*irgen)(UChar, UChar, UChar),
1720 UChar r1, UChar r3, UChar r2)
1721{
1722 HChar *mnm = irgen(r1, r3, r2);
1723
sewardj7ee97522011-05-09 21:45:04 +00001724 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001725 s390_disasm(ENC4(MNM, FPR, FPR, FPR), mnm, r1, r3, r2);
1726}
1727
1728static void
florian4b8efad2012-09-02 18:07:08 +00001729s390_format_RRF_UUFF(HChar *(*irgen)(UChar m3, UChar m4, UChar r1, UChar r2),
1730 UChar m3, UChar m4, UChar r1, UChar r2)
1731{
1732 HChar *mnm = irgen(m3, m4, r1, r2);
1733
1734 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
1735 s390_disasm(ENC5(MNM, FPR, UINT, FPR, UINT), mnm, r1, m3, r2, m4);
1736}
1737
1738static void
florian1c8f7ff2012-09-01 00:12:11 +00001739s390_format_RRF_UUFR(HChar *(*irgen)(UChar m3, UChar m4, UChar r1, UChar r2),
1740 UChar m3, UChar m4, UChar r1, UChar r2)
1741{
1742 HChar *mnm = irgen(m3, m4, r1, r2);
1743
1744 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
1745 s390_disasm(ENC5(MNM, FPR, UINT, GPR, UINT), mnm, r1, m3, r2, m4);
1746}
1747
1748static void
1749s390_format_RRF_UURF(HChar *(*irgen)(UChar m3, UChar m4, UChar r1, UChar r2),
1750 UChar m3, UChar m4, UChar r1, UChar r2)
1751{
1752 HChar *mnm = irgen(m3, m4, r1, r2);
1753
1754 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
1755 s390_disasm(ENC5(MNM, GPR, UINT, FPR, UINT), mnm, r1, m3, r2, m4);
1756}
1757
1758
1759static void
sewardjd7bde722011-04-05 13:19:33 +00001760s390_format_RRF_U0RR(HChar *(*irgen)(UChar m3, UChar r1, UChar r2),
1761 UChar m3, UChar r1, UChar r2, Int xmnm_kind)
1762{
1763 irgen(m3, r1, r2);
1764
sewardj7ee97522011-05-09 21:45:04 +00001765 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardjd7bde722011-04-05 13:19:33 +00001766 s390_disasm(ENC3(XMNM, GPR, GPR), xmnm_kind, m3, r1, r2);
1767}
1768
1769static void
sewardj2019a972011-03-07 16:04:07 +00001770s390_format_RRF_F0FF2(HChar *(*irgen)(UChar, UChar, UChar),
1771 UChar r3, UChar r1, UChar r2)
1772{
1773 HChar *mnm = irgen(r3, r1, r2);
1774
sewardj7ee97522011-05-09 21:45:04 +00001775 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001776 s390_disasm(ENC4(MNM, FPR, FPR, FPR), mnm, r1, r3, r2);
1777}
1778
1779static void
1780s390_format_RRF_R0RR2(HChar *(*irgen)(UChar r3, UChar r1, UChar r2),
1781 UChar r3, UChar r1, UChar r2)
1782{
1783 HChar *mnm = irgen(r3, r1, r2);
1784
sewardj7ee97522011-05-09 21:45:04 +00001785 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001786 s390_disasm(ENC4(MNM, GPR, GPR, GPR), mnm, r1, r2, r3);
1787}
1788
1789static void
1790s390_format_RRS(HChar *(*irgen)(UChar r1, UChar r2, UChar m3, IRTemp op4addr),
1791 UChar r1, UChar r2, UChar b4, UShort d4, UChar m3)
1792{
1793 HChar *mnm;
1794 IRTemp op4addr = newTemp(Ity_I64);
1795
1796 assign(op4addr, binop(Iop_Add64, mkU64(d4), b4 != 0 ? get_gpr_dw0(b4) :
1797 mkU64(0)));
1798
1799 mnm = irgen(r1, r2, m3, op4addr);
1800
sewardj7ee97522011-05-09 21:45:04 +00001801 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001802 s390_disasm(ENC5(XMNM, GPR, GPR, CABM, UDXB), S390_XMNM_CAB, mnm, m3, r1,
1803 r2, m3, d4, 0, b4);
1804}
1805
1806static void
1807s390_format_RS_R0RD(HChar *(*irgen)(UChar r1, IRTemp op2addr),
1808 UChar r1, UChar b2, UShort d2)
1809{
1810 HChar *mnm;
1811 IRTemp op2addr = newTemp(Ity_I64);
1812
1813 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
1814 mkU64(0)));
1815
1816 mnm = irgen(r1, op2addr);
1817
sewardj7ee97522011-05-09 21:45:04 +00001818 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001819 s390_disasm(ENC3(MNM, GPR, UDXB), mnm, r1, d2, 0, b2);
1820}
1821
1822static void
1823s390_format_RS_RRRD(HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
1824 UChar r1, UChar r3, UChar b2, UShort d2)
1825{
1826 HChar *mnm;
1827 IRTemp op2addr = newTemp(Ity_I64);
1828
1829 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
1830 mkU64(0)));
1831
1832 mnm = irgen(r1, r3, op2addr);
1833
sewardj7ee97522011-05-09 21:45:04 +00001834 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001835 s390_disasm(ENC4(MNM, GPR, GPR, UDXB), mnm, r1, r3, d2, 0, b2);
1836}
1837
1838static void
1839s390_format_RS_RURD(HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
1840 UChar r1, UChar r3, UChar b2, UShort d2)
1841{
1842 HChar *mnm;
1843 IRTemp op2addr = newTemp(Ity_I64);
1844
1845 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
1846 mkU64(0)));
1847
1848 mnm = irgen(r1, r3, op2addr);
1849
sewardj7ee97522011-05-09 21:45:04 +00001850 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001851 s390_disasm(ENC4(MNM, GPR, UINT, UDXB), mnm, r1, r3, d2, 0, b2);
1852}
1853
1854static void
1855s390_format_RS_AARD(HChar *(*irgen)(UChar, UChar, IRTemp),
1856 UChar r1, UChar r3, UChar b2, UShort d2)
1857{
1858 HChar *mnm;
1859 IRTemp op2addr = newTemp(Ity_I64);
1860
1861 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
1862 mkU64(0)));
1863
1864 mnm = irgen(r1, r3, op2addr);
1865
sewardj7ee97522011-05-09 21:45:04 +00001866 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001867 s390_disasm(ENC4(MNM, AR, AR, UDXB), mnm, r1, r3, d2, 0, b2);
1868}
1869
1870static void
1871s390_format_RSI_RRP(HChar *(*irgen)(UChar r1, UChar r3, UShort i2),
1872 UChar r1, UChar r3, UShort i2)
1873{
1874 HChar *mnm = irgen(r1, r3, i2);
1875
sewardj7ee97522011-05-09 21:45:04 +00001876 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001877 s390_disasm(ENC4(MNM, GPR, GPR, PCREL), mnm, r1, r3, (Int)(Short)i2);
1878}
1879
1880static void
1881s390_format_RSY_RRRD(HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
1882 UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2)
1883{
1884 HChar *mnm;
1885 IRTemp op2addr = newTemp(Ity_I64);
1886 IRTemp d2 = newTemp(Ity_I64);
1887
1888 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
1889 assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
1890 mkU64(0)));
1891
1892 mnm = irgen(r1, r3, op2addr);
1893
sewardj7ee97522011-05-09 21:45:04 +00001894 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001895 s390_disasm(ENC4(MNM, GPR, GPR, SDXB), mnm, r1, r3, dh2, dl2, 0, b2);
1896}
1897
1898static void
1899s390_format_RSY_AARD(HChar *(*irgen)(UChar, UChar, IRTemp),
1900 UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2)
1901{
1902 HChar *mnm;
1903 IRTemp op2addr = newTemp(Ity_I64);
1904 IRTemp d2 = newTemp(Ity_I64);
1905
1906 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
1907 assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
1908 mkU64(0)));
1909
1910 mnm = irgen(r1, r3, op2addr);
1911
sewardj7ee97522011-05-09 21:45:04 +00001912 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001913 s390_disasm(ENC4(MNM, AR, AR, SDXB), mnm, r1, r3, dh2, dl2, 0, b2);
1914}
1915
1916static void
1917s390_format_RSY_RURD(HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
1918 UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2)
1919{
1920 HChar *mnm;
1921 IRTemp op2addr = newTemp(Ity_I64);
1922 IRTemp d2 = newTemp(Ity_I64);
1923
1924 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
1925 assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
1926 mkU64(0)));
1927
1928 mnm = irgen(r1, r3, op2addr);
1929
sewardj7ee97522011-05-09 21:45:04 +00001930 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001931 s390_disasm(ENC4(MNM, GPR, UINT, SDXB), mnm, r1, r3, dh2, dl2, 0, b2);
1932}
1933
1934static void
sewardjd7bde722011-04-05 13:19:33 +00001935s390_format_RSY_RDRM(HChar *(*irgen)(UChar r1, IRTemp op2addr),
1936 UChar r1, UChar m3, UChar b2, UShort dl2, UChar dh2,
1937 Int xmnm_kind)
1938{
1939 IRTemp op2addr = newTemp(Ity_I64);
1940 IRTemp d2 = newTemp(Ity_I64);
1941
florian6820ba52012-07-26 02:01:50 +00001942 next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0)));
1943
sewardjd7bde722011-04-05 13:19:33 +00001944 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
1945 assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
1946 mkU64(0)));
1947
1948 irgen(r1, op2addr);
florian6820ba52012-07-26 02:01:50 +00001949
1950 vassert(dis_res->whatNext == Dis_Continue);
sewardjd7bde722011-04-05 13:19:33 +00001951
sewardj7ee97522011-05-09 21:45:04 +00001952 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardjd7bde722011-04-05 13:19:33 +00001953 s390_disasm(ENC3(XMNM, GPR, SDXB), xmnm_kind, m3, r1, dh2, dl2, 0, b2);
1954}
1955
1956static void
sewardj2019a972011-03-07 16:04:07 +00001957s390_format_RX(HChar *(*irgen)(UChar r1, UChar x2, UChar b2, UShort d2,
1958 IRTemp op2addr),
1959 UChar r1, UChar x2, UChar b2, UShort d2)
1960{
1961 IRTemp op2addr = newTemp(Ity_I64);
1962
1963 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
1964 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
1965 mkU64(0)));
1966
1967 irgen(r1, x2, b2, d2, op2addr);
1968}
1969
1970static void
1971s390_format_RX_RRRD(HChar *(*irgen)(UChar r1, IRTemp op2addr),
1972 UChar r1, UChar x2, UChar b2, UShort d2)
1973{
1974 HChar *mnm;
1975 IRTemp op2addr = newTemp(Ity_I64);
1976
1977 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
1978 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
1979 mkU64(0)));
1980
1981 mnm = irgen(r1, op2addr);
1982
sewardj7ee97522011-05-09 21:45:04 +00001983 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001984 s390_disasm(ENC3(MNM, GPR, UDXB), mnm, r1, d2, x2, b2);
1985}
1986
1987static void
1988s390_format_RX_FRRD(HChar *(*irgen)(UChar r1, IRTemp op2addr),
1989 UChar r1, UChar x2, UChar b2, UShort d2)
1990{
1991 HChar *mnm;
1992 IRTemp op2addr = newTemp(Ity_I64);
1993
1994 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
1995 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
1996 mkU64(0)));
1997
1998 mnm = irgen(r1, op2addr);
1999
sewardj7ee97522011-05-09 21:45:04 +00002000 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002001 s390_disasm(ENC3(MNM, FPR, UDXB), mnm, r1, d2, x2, b2);
2002}
2003
2004static void
2005s390_format_RXE_FRRD(HChar *(*irgen)(UChar r1, IRTemp op2addr),
2006 UChar r1, UChar x2, UChar b2, UShort d2)
2007{
2008 HChar *mnm;
2009 IRTemp op2addr = newTemp(Ity_I64);
2010
2011 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
2012 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2013 mkU64(0)));
2014
2015 mnm = irgen(r1, op2addr);
2016
sewardj7ee97522011-05-09 21:45:04 +00002017 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002018 s390_disasm(ENC3(MNM, FPR, UDXB), mnm, r1, d2, x2, b2);
2019}
2020
2021static void
2022s390_format_RXF_FRRDF(HChar *(*irgen)(UChar, IRTemp, UChar),
2023 UChar r3, UChar x2, UChar b2, UShort d2, UChar r1)
2024{
2025 HChar *mnm;
2026 IRTemp op2addr = newTemp(Ity_I64);
2027
2028 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
2029 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2030 mkU64(0)));
2031
2032 mnm = irgen(r3, op2addr, r1);
2033
sewardj7ee97522011-05-09 21:45:04 +00002034 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002035 s390_disasm(ENC4(MNM, FPR, FPR, UDXB), mnm, r1, r3, d2, x2, b2);
2036}
2037
2038static void
2039s390_format_RXY_RRRD(HChar *(*irgen)(UChar r1, IRTemp op2addr),
2040 UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
2041{
2042 HChar *mnm;
2043 IRTemp op2addr = newTemp(Ity_I64);
2044 IRTemp d2 = newTemp(Ity_I64);
2045
2046 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2047 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkexpr(d2),
2048 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2049 mkU64(0)));
2050
2051 mnm = irgen(r1, op2addr);
2052
sewardj7ee97522011-05-09 21:45:04 +00002053 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002054 s390_disasm(ENC3(MNM, GPR, SDXB), mnm, r1, dh2, dl2, x2, b2);
2055}
2056
2057static void
2058s390_format_RXY_FRRD(HChar *(*irgen)(UChar r1, IRTemp op2addr),
2059 UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
2060{
2061 HChar *mnm;
2062 IRTemp op2addr = newTemp(Ity_I64);
2063 IRTemp d2 = newTemp(Ity_I64);
2064
2065 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2066 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkexpr(d2),
2067 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2068 mkU64(0)));
2069
2070 mnm = irgen(r1, op2addr);
2071
sewardj7ee97522011-05-09 21:45:04 +00002072 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002073 s390_disasm(ENC3(MNM, FPR, SDXB), mnm, r1, dh2, dl2, x2, b2);
2074}
2075
2076static void
2077s390_format_RXY_URRD(HChar *(*irgen)(void),
2078 UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
2079{
2080 HChar *mnm;
2081 IRTemp op2addr = newTemp(Ity_I64);
2082 IRTemp d2 = newTemp(Ity_I64);
2083
2084 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2085 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkexpr(d2),
2086 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2087 mkU64(0)));
2088
2089 mnm = irgen();
2090
sewardj7ee97522011-05-09 21:45:04 +00002091 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002092 s390_disasm(ENC3(MNM, UINT, SDXB), mnm, r1, dh2, dl2, x2, b2);
2093}
2094
2095static void
2096s390_format_S_RD(HChar *(*irgen)(IRTemp op2addr),
2097 UChar b2, UShort d2)
2098{
2099 HChar *mnm;
2100 IRTemp op2addr = newTemp(Ity_I64);
2101
2102 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2103 mkU64(0)));
2104
2105 mnm = irgen(op2addr);
2106
sewardj7ee97522011-05-09 21:45:04 +00002107 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002108 s390_disasm(ENC2(MNM, UDXB), mnm, d2, 0, b2);
2109}
2110
2111static void
2112s390_format_SI_URD(HChar *(*irgen)(UChar i2, IRTemp op1addr),
2113 UChar i2, UChar b1, UShort d1)
2114{
2115 HChar *mnm;
2116 IRTemp op1addr = newTemp(Ity_I64);
2117
2118 assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
2119 mkU64(0)));
2120
2121 mnm = irgen(i2, op1addr);
2122
sewardj7ee97522011-05-09 21:45:04 +00002123 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002124 s390_disasm(ENC3(MNM, UDXB, UINT), mnm, d1, 0, b1, i2);
2125}
2126
2127static void
2128s390_format_SIY_URD(HChar *(*irgen)(UChar i2, IRTemp op1addr),
2129 UChar i2, UChar b1, UShort dl1, UChar dh1)
2130{
2131 HChar *mnm;
2132 IRTemp op1addr = newTemp(Ity_I64);
2133 IRTemp d1 = newTemp(Ity_I64);
2134
2135 assign(d1, mkU64(((ULong)(Long)(Char)dh1 << 12) | ((ULong)dl1)));
2136 assign(op1addr, binop(Iop_Add64, mkexpr(d1), b1 != 0 ? get_gpr_dw0(b1) :
2137 mkU64(0)));
2138
2139 mnm = irgen(i2, op1addr);
2140
sewardj7ee97522011-05-09 21:45:04 +00002141 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002142 s390_disasm(ENC3(MNM, SDXB, UINT), mnm, dh1, dl1, 0, b1, i2);
2143}
2144
2145static void
2146s390_format_SIY_IRD(HChar *(*irgen)(UChar i2, IRTemp op1addr),
2147 UChar i2, UChar b1, UShort dl1, UChar dh1)
2148{
2149 HChar *mnm;
2150 IRTemp op1addr = newTemp(Ity_I64);
2151 IRTemp d1 = newTemp(Ity_I64);
2152
2153 assign(d1, mkU64(((ULong)(Long)(Char)dh1 << 12) | ((ULong)dl1)));
2154 assign(op1addr, binop(Iop_Add64, mkexpr(d1), b1 != 0 ? get_gpr_dw0(b1) :
2155 mkU64(0)));
2156
2157 mnm = irgen(i2, op1addr);
2158
sewardj7ee97522011-05-09 21:45:04 +00002159 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002160 s390_disasm(ENC3(MNM, SDXB, INT), mnm, dh1, dl1, 0, b1, (Int)(Char)i2);
2161}
2162
2163static void
2164s390_format_SS_L0RDRD(HChar *(*irgen)(UChar, IRTemp, IRTemp),
2165 UChar l, UChar b1, UShort d1, UChar b2, UShort d2)
2166{
2167 HChar *mnm;
2168 IRTemp op1addr = newTemp(Ity_I64);
2169 IRTemp op2addr = newTemp(Ity_I64);
2170
2171 assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
2172 mkU64(0)));
2173 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2174 mkU64(0)));
2175
2176 mnm = irgen(l, op1addr, op2addr);
2177
sewardj7ee97522011-05-09 21:45:04 +00002178 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002179 s390_disasm(ENC3(MNM, UDLB, UDXB), mnm, d1, l, b1, d2, 0, b2);
2180}
2181
2182static void
2183s390_format_SIL_RDI(HChar *(*irgen)(UShort i2, IRTemp op1addr),
2184 UChar b1, UShort d1, UShort i2)
2185{
2186 HChar *mnm;
2187 IRTemp op1addr = newTemp(Ity_I64);
2188
2189 assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
2190 mkU64(0)));
2191
2192 mnm = irgen(i2, op1addr);
2193
sewardj7ee97522011-05-09 21:45:04 +00002194 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002195 s390_disasm(ENC3(MNM, UDXB, INT), mnm, d1, 0, b1, (Int)(Short)i2);
2196}
2197
2198static void
2199s390_format_SIL_RDU(HChar *(*irgen)(UShort i2, IRTemp op1addr),
2200 UChar b1, UShort d1, UShort i2)
2201{
2202 HChar *mnm;
2203 IRTemp op1addr = newTemp(Ity_I64);
2204
2205 assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
2206 mkU64(0)));
2207
2208 mnm = irgen(i2, op1addr);
2209
sewardj7ee97522011-05-09 21:45:04 +00002210 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002211 s390_disasm(ENC3(MNM, UDXB, UINT), mnm, d1, 0, b1, i2);
2212}
2213
2214
2215
2216/*------------------------------------------------------------*/
2217/*--- Build IR for opcodes ---*/
2218/*------------------------------------------------------------*/
2219
2220static HChar *
2221s390_irgen_AR(UChar r1, UChar r2)
2222{
2223 IRTemp op1 = newTemp(Ity_I32);
2224 IRTemp op2 = newTemp(Ity_I32);
2225 IRTemp result = newTemp(Ity_I32);
2226
2227 assign(op1, get_gpr_w1(r1));
2228 assign(op2, get_gpr_w1(r2));
2229 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2230 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2231 put_gpr_w1(r1, mkexpr(result));
2232
2233 return "ar";
2234}
2235
2236static HChar *
2237s390_irgen_AGR(UChar r1, UChar r2)
2238{
2239 IRTemp op1 = newTemp(Ity_I64);
2240 IRTemp op2 = newTemp(Ity_I64);
2241 IRTemp result = newTemp(Ity_I64);
2242
2243 assign(op1, get_gpr_dw0(r1));
2244 assign(op2, get_gpr_dw0(r2));
2245 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2246 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
2247 put_gpr_dw0(r1, mkexpr(result));
2248
2249 return "agr";
2250}
2251
2252static HChar *
2253s390_irgen_AGFR(UChar r1, UChar r2)
2254{
2255 IRTemp op1 = newTemp(Ity_I64);
2256 IRTemp op2 = newTemp(Ity_I64);
2257 IRTemp result = newTemp(Ity_I64);
2258
2259 assign(op1, get_gpr_dw0(r1));
2260 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
2261 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2262 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
2263 put_gpr_dw0(r1, mkexpr(result));
2264
2265 return "agfr";
2266}
2267
2268static HChar *
2269s390_irgen_ARK(UChar r3, UChar r1, UChar r2)
2270{
2271 IRTemp op2 = newTemp(Ity_I32);
2272 IRTemp op3 = newTemp(Ity_I32);
2273 IRTemp result = newTemp(Ity_I32);
2274
2275 assign(op2, get_gpr_w1(r2));
2276 assign(op3, get_gpr_w1(r3));
2277 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2278 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
2279 put_gpr_w1(r1, mkexpr(result));
2280
2281 return "ark";
2282}
2283
2284static HChar *
2285s390_irgen_AGRK(UChar r3, UChar r1, UChar r2)
2286{
2287 IRTemp op2 = newTemp(Ity_I64);
2288 IRTemp op3 = newTemp(Ity_I64);
2289 IRTemp result = newTemp(Ity_I64);
2290
2291 assign(op2, get_gpr_dw0(r2));
2292 assign(op3, get_gpr_dw0(r3));
2293 assign(result, binop(Iop_Add64, mkexpr(op2), mkexpr(op3)));
2294 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op2, op3);
2295 put_gpr_dw0(r1, mkexpr(result));
2296
2297 return "agrk";
2298}
2299
2300static HChar *
2301s390_irgen_A(UChar r1, IRTemp op2addr)
2302{
2303 IRTemp op1 = newTemp(Ity_I32);
2304 IRTemp op2 = newTemp(Ity_I32);
2305 IRTemp result = newTemp(Ity_I32);
2306
2307 assign(op1, get_gpr_w1(r1));
2308 assign(op2, load(Ity_I32, mkexpr(op2addr)));
2309 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2310 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2311 put_gpr_w1(r1, mkexpr(result));
2312
2313 return "a";
2314}
2315
2316static HChar *
2317s390_irgen_AY(UChar r1, IRTemp op2addr)
2318{
2319 IRTemp op1 = newTemp(Ity_I32);
2320 IRTemp op2 = newTemp(Ity_I32);
2321 IRTemp result = newTemp(Ity_I32);
2322
2323 assign(op1, get_gpr_w1(r1));
2324 assign(op2, load(Ity_I32, mkexpr(op2addr)));
2325 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2326 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2327 put_gpr_w1(r1, mkexpr(result));
2328
2329 return "ay";
2330}
2331
2332static HChar *
2333s390_irgen_AG(UChar r1, IRTemp op2addr)
2334{
2335 IRTemp op1 = newTemp(Ity_I64);
2336 IRTemp op2 = newTemp(Ity_I64);
2337 IRTemp result = newTemp(Ity_I64);
2338
2339 assign(op1, get_gpr_dw0(r1));
2340 assign(op2, load(Ity_I64, mkexpr(op2addr)));
2341 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2342 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
2343 put_gpr_dw0(r1, mkexpr(result));
2344
2345 return "ag";
2346}
2347
2348static HChar *
2349s390_irgen_AGF(UChar r1, IRTemp op2addr)
2350{
2351 IRTemp op1 = newTemp(Ity_I64);
2352 IRTemp op2 = newTemp(Ity_I64);
2353 IRTemp result = newTemp(Ity_I64);
2354
2355 assign(op1, get_gpr_dw0(r1));
2356 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
2357 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2358 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
2359 put_gpr_dw0(r1, mkexpr(result));
2360
2361 return "agf";
2362}
2363
2364static HChar *
2365s390_irgen_AFI(UChar r1, UInt i2)
2366{
2367 IRTemp op1 = newTemp(Ity_I32);
2368 Int op2;
2369 IRTemp result = newTemp(Ity_I32);
2370
2371 assign(op1, get_gpr_w1(r1));
2372 op2 = (Int)i2;
2373 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
2374 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
2375 mkU32((UInt)op2)));
2376 put_gpr_w1(r1, mkexpr(result));
2377
2378 return "afi";
2379}
2380
2381static HChar *
2382s390_irgen_AGFI(UChar r1, UInt i2)
2383{
2384 IRTemp op1 = newTemp(Ity_I64);
2385 Long op2;
2386 IRTemp result = newTemp(Ity_I64);
2387
2388 assign(op1, get_gpr_dw0(r1));
2389 op2 = (Long)(Int)i2;
2390 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64((ULong)op2)));
2391 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, mktemp(Ity_I64,
2392 mkU64((ULong)op2)));
2393 put_gpr_dw0(r1, mkexpr(result));
2394
2395 return "agfi";
2396}
2397
2398static HChar *
2399s390_irgen_AHIK(UChar r1, UChar r3, UShort i2)
2400{
2401 Int op2;
2402 IRTemp op3 = newTemp(Ity_I32);
2403 IRTemp result = newTemp(Ity_I32);
2404
2405 op2 = (Int)(Short)i2;
2406 assign(op3, get_gpr_w1(r3));
2407 assign(result, binop(Iop_Add32, mkU32((UInt)op2), mkexpr(op3)));
2408 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, mktemp(Ity_I32, mkU32((UInt)
2409 op2)), op3);
2410 put_gpr_w1(r1, mkexpr(result));
2411
2412 return "ahik";
2413}
2414
2415static HChar *
2416s390_irgen_AGHIK(UChar r1, UChar r3, UShort i2)
2417{
2418 Long op2;
2419 IRTemp op3 = newTemp(Ity_I64);
2420 IRTemp result = newTemp(Ity_I64);
2421
2422 op2 = (Long)(Short)i2;
2423 assign(op3, get_gpr_dw0(r3));
2424 assign(result, binop(Iop_Add64, mkU64((ULong)op2), mkexpr(op3)));
2425 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, mktemp(Ity_I64, mkU64((ULong)
2426 op2)), op3);
2427 put_gpr_dw0(r1, mkexpr(result));
2428
2429 return "aghik";
2430}
2431
2432static HChar *
2433s390_irgen_ASI(UChar i2, IRTemp op1addr)
2434{
2435 IRTemp op1 = newTemp(Ity_I32);
2436 Int op2;
2437 IRTemp result = newTemp(Ity_I32);
2438
2439 assign(op1, load(Ity_I32, mkexpr(op1addr)));
2440 op2 = (Int)(Char)i2;
2441 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
2442 store(mkexpr(op1addr), mkexpr(result));
2443 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
2444 mkU32((UInt)op2)));
2445
2446 return "asi";
2447}
2448
2449static HChar *
2450s390_irgen_AGSI(UChar i2, IRTemp op1addr)
2451{
2452 IRTemp op1 = newTemp(Ity_I64);
2453 Long op2;
2454 IRTemp result = newTemp(Ity_I64);
2455
2456 assign(op1, load(Ity_I64, mkexpr(op1addr)));
2457 op2 = (Long)(Char)i2;
2458 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64((ULong)op2)));
2459 store(mkexpr(op1addr), mkexpr(result));
2460 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, mktemp(Ity_I64,
2461 mkU64((ULong)op2)));
2462
2463 return "agsi";
2464}
2465
2466static HChar *
2467s390_irgen_AH(UChar r1, IRTemp op2addr)
2468{
2469 IRTemp op1 = newTemp(Ity_I32);
2470 IRTemp op2 = newTemp(Ity_I32);
2471 IRTemp result = newTemp(Ity_I32);
2472
2473 assign(op1, get_gpr_w1(r1));
2474 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
2475 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2476 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2477 put_gpr_w1(r1, mkexpr(result));
2478
2479 return "ah";
2480}
2481
2482static HChar *
2483s390_irgen_AHY(UChar r1, IRTemp op2addr)
2484{
2485 IRTemp op1 = newTemp(Ity_I32);
2486 IRTemp op2 = newTemp(Ity_I32);
2487 IRTemp result = newTemp(Ity_I32);
2488
2489 assign(op1, get_gpr_w1(r1));
2490 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
2491 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2492 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2493 put_gpr_w1(r1, mkexpr(result));
2494
2495 return "ahy";
2496}
2497
2498static HChar *
2499s390_irgen_AHI(UChar r1, UShort i2)
2500{
2501 IRTemp op1 = newTemp(Ity_I32);
2502 Int op2;
2503 IRTemp result = newTemp(Ity_I32);
2504
2505 assign(op1, get_gpr_w1(r1));
2506 op2 = (Int)(Short)i2;
2507 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
2508 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
2509 mkU32((UInt)op2)));
2510 put_gpr_w1(r1, mkexpr(result));
2511
2512 return "ahi";
2513}
2514
2515static HChar *
2516s390_irgen_AGHI(UChar r1, UShort i2)
2517{
2518 IRTemp op1 = newTemp(Ity_I64);
2519 Long op2;
2520 IRTemp result = newTemp(Ity_I64);
2521
2522 assign(op1, get_gpr_dw0(r1));
2523 op2 = (Long)(Short)i2;
2524 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64((ULong)op2)));
2525 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, mktemp(Ity_I64,
2526 mkU64((ULong)op2)));
2527 put_gpr_dw0(r1, mkexpr(result));
2528
2529 return "aghi";
2530}
2531
2532static HChar *
2533s390_irgen_AHHHR(UChar r3, UChar r1, UChar r2)
2534{
2535 IRTemp op2 = newTemp(Ity_I32);
2536 IRTemp op3 = newTemp(Ity_I32);
2537 IRTemp result = newTemp(Ity_I32);
2538
2539 assign(op2, get_gpr_w0(r2));
2540 assign(op3, get_gpr_w0(r3));
2541 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2542 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
2543 put_gpr_w0(r1, mkexpr(result));
2544
2545 return "ahhhr";
2546}
2547
2548static HChar *
2549s390_irgen_AHHLR(UChar r3, UChar r1, UChar r2)
2550{
2551 IRTemp op2 = newTemp(Ity_I32);
2552 IRTemp op3 = newTemp(Ity_I32);
2553 IRTemp result = newTemp(Ity_I32);
2554
2555 assign(op2, get_gpr_w0(r2));
2556 assign(op3, get_gpr_w1(r3));
2557 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2558 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
2559 put_gpr_w0(r1, mkexpr(result));
2560
2561 return "ahhlr";
2562}
2563
2564static HChar *
2565s390_irgen_AIH(UChar r1, UInt i2)
2566{
2567 IRTemp op1 = newTemp(Ity_I32);
2568 Int op2;
2569 IRTemp result = newTemp(Ity_I32);
2570
2571 assign(op1, get_gpr_w0(r1));
2572 op2 = (Int)i2;
2573 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
2574 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
2575 mkU32((UInt)op2)));
2576 put_gpr_w0(r1, mkexpr(result));
2577
2578 return "aih";
2579}
2580
2581static HChar *
2582s390_irgen_ALR(UChar r1, UChar r2)
2583{
2584 IRTemp op1 = newTemp(Ity_I32);
2585 IRTemp op2 = newTemp(Ity_I32);
2586 IRTemp result = newTemp(Ity_I32);
2587
2588 assign(op1, get_gpr_w1(r1));
2589 assign(op2, get_gpr_w1(r2));
2590 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2591 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, op2);
2592 put_gpr_w1(r1, mkexpr(result));
2593
2594 return "alr";
2595}
2596
2597static HChar *
2598s390_irgen_ALGR(UChar r1, UChar r2)
2599{
2600 IRTemp op1 = newTemp(Ity_I64);
2601 IRTemp op2 = newTemp(Ity_I64);
2602 IRTemp result = newTemp(Ity_I64);
2603
2604 assign(op1, get_gpr_dw0(r1));
2605 assign(op2, get_gpr_dw0(r2));
2606 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2607 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
2608 put_gpr_dw0(r1, mkexpr(result));
2609
2610 return "algr";
2611}
2612
2613static HChar *
2614s390_irgen_ALGFR(UChar r1, UChar r2)
2615{
2616 IRTemp op1 = newTemp(Ity_I64);
2617 IRTemp op2 = newTemp(Ity_I64);
2618 IRTemp result = newTemp(Ity_I64);
2619
2620 assign(op1, get_gpr_dw0(r1));
2621 assign(op2, unop(Iop_32Uto64, get_gpr_w1(r2)));
2622 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2623 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
2624 put_gpr_dw0(r1, mkexpr(result));
2625
2626 return "algfr";
2627}
2628
2629static HChar *
2630s390_irgen_ALRK(UChar r3, UChar r1, UChar r2)
2631{
2632 IRTemp op2 = newTemp(Ity_I32);
2633 IRTemp op3 = newTemp(Ity_I32);
2634 IRTemp result = newTemp(Ity_I32);
2635
2636 assign(op2, get_gpr_w1(r2));
2637 assign(op3, get_gpr_w1(r3));
2638 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2639 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
2640 put_gpr_w1(r1, mkexpr(result));
2641
2642 return "alrk";
2643}
2644
2645static HChar *
2646s390_irgen_ALGRK(UChar r3, UChar r1, UChar r2)
2647{
2648 IRTemp op2 = newTemp(Ity_I64);
2649 IRTemp op3 = newTemp(Ity_I64);
2650 IRTemp result = newTemp(Ity_I64);
2651
2652 assign(op2, get_gpr_dw0(r2));
2653 assign(op3, get_gpr_dw0(r3));
2654 assign(result, binop(Iop_Add64, mkexpr(op2), mkexpr(op3)));
2655 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op2, op3);
2656 put_gpr_dw0(r1, mkexpr(result));
2657
2658 return "algrk";
2659}
2660
2661static HChar *
2662s390_irgen_AL(UChar r1, IRTemp op2addr)
2663{
2664 IRTemp op1 = newTemp(Ity_I32);
2665 IRTemp op2 = newTemp(Ity_I32);
2666 IRTemp result = newTemp(Ity_I32);
2667
2668 assign(op1, get_gpr_w1(r1));
2669 assign(op2, load(Ity_I32, mkexpr(op2addr)));
2670 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2671 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, op2);
2672 put_gpr_w1(r1, mkexpr(result));
2673
2674 return "al";
2675}
2676
2677static HChar *
2678s390_irgen_ALY(UChar r1, IRTemp op2addr)
2679{
2680 IRTemp op1 = newTemp(Ity_I32);
2681 IRTemp op2 = newTemp(Ity_I32);
2682 IRTemp result = newTemp(Ity_I32);
2683
2684 assign(op1, get_gpr_w1(r1));
2685 assign(op2, load(Ity_I32, mkexpr(op2addr)));
2686 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2687 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, op2);
2688 put_gpr_w1(r1, mkexpr(result));
2689
2690 return "aly";
2691}
2692
2693static HChar *
2694s390_irgen_ALG(UChar r1, IRTemp op2addr)
2695{
2696 IRTemp op1 = newTemp(Ity_I64);
2697 IRTemp op2 = newTemp(Ity_I64);
2698 IRTemp result = newTemp(Ity_I64);
2699
2700 assign(op1, get_gpr_dw0(r1));
2701 assign(op2, load(Ity_I64, mkexpr(op2addr)));
2702 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2703 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
2704 put_gpr_dw0(r1, mkexpr(result));
2705
2706 return "alg";
2707}
2708
2709static HChar *
2710s390_irgen_ALGF(UChar r1, IRTemp op2addr)
2711{
2712 IRTemp op1 = newTemp(Ity_I64);
2713 IRTemp op2 = newTemp(Ity_I64);
2714 IRTemp result = newTemp(Ity_I64);
2715
2716 assign(op1, get_gpr_dw0(r1));
2717 assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
2718 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2719 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
2720 put_gpr_dw0(r1, mkexpr(result));
2721
2722 return "algf";
2723}
2724
2725static HChar *
2726s390_irgen_ALFI(UChar r1, UInt i2)
2727{
2728 IRTemp op1 = newTemp(Ity_I32);
2729 UInt op2;
2730 IRTemp result = newTemp(Ity_I32);
2731
2732 assign(op1, get_gpr_w1(r1));
2733 op2 = i2;
2734 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
2735 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, mktemp(Ity_I32,
2736 mkU32(op2)));
2737 put_gpr_w1(r1, mkexpr(result));
2738
2739 return "alfi";
2740}
2741
2742static HChar *
2743s390_irgen_ALGFI(UChar r1, UInt i2)
2744{
2745 IRTemp op1 = newTemp(Ity_I64);
2746 ULong op2;
2747 IRTemp result = newTemp(Ity_I64);
2748
2749 assign(op1, get_gpr_dw0(r1));
2750 op2 = (ULong)i2;
2751 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64(op2)));
2752 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, mktemp(Ity_I64,
2753 mkU64(op2)));
2754 put_gpr_dw0(r1, mkexpr(result));
2755
2756 return "algfi";
2757}
2758
2759static HChar *
2760s390_irgen_ALHHHR(UChar r3, UChar r1, UChar r2)
2761{
2762 IRTemp op2 = newTemp(Ity_I32);
2763 IRTemp op3 = newTemp(Ity_I32);
2764 IRTemp result = newTemp(Ity_I32);
2765
2766 assign(op2, get_gpr_w0(r2));
2767 assign(op3, get_gpr_w0(r3));
2768 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2769 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
2770 put_gpr_w0(r1, mkexpr(result));
2771
2772 return "alhhhr";
2773}
2774
2775static HChar *
2776s390_irgen_ALHHLR(UChar r3, UChar r1, UChar r2)
2777{
2778 IRTemp op2 = newTemp(Ity_I32);
2779 IRTemp op3 = newTemp(Ity_I32);
2780 IRTemp result = newTemp(Ity_I32);
2781
2782 assign(op2, get_gpr_w0(r2));
2783 assign(op3, get_gpr_w1(r3));
2784 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2785 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
2786 put_gpr_w0(r1, mkexpr(result));
2787
2788 return "alhhlr";
2789}
2790
2791static HChar *
2792s390_irgen_ALCR(UChar r1, UChar r2)
2793{
2794 IRTemp op1 = newTemp(Ity_I32);
2795 IRTemp op2 = newTemp(Ity_I32);
2796 IRTemp result = newTemp(Ity_I32);
2797 IRTemp carry_in = newTemp(Ity_I32);
2798
2799 assign(op1, get_gpr_w1(r1));
2800 assign(op2, get_gpr_w1(r2));
2801 assign(carry_in, binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)));
2802 assign(result, binop(Iop_Add32, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)),
2803 mkexpr(carry_in)));
2804 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_32, op1, op2, carry_in);
2805 put_gpr_w1(r1, mkexpr(result));
2806
2807 return "alcr";
2808}
2809
2810static HChar *
2811s390_irgen_ALCGR(UChar r1, UChar r2)
2812{
2813 IRTemp op1 = newTemp(Ity_I64);
2814 IRTemp op2 = newTemp(Ity_I64);
2815 IRTemp result = newTemp(Ity_I64);
2816 IRTemp carry_in = newTemp(Ity_I64);
2817
2818 assign(op1, get_gpr_dw0(r1));
2819 assign(op2, get_gpr_dw0(r2));
2820 assign(carry_in, unop(Iop_32Uto64, binop(Iop_Shr32, s390_call_calculate_cc(),
2821 mkU8(1))));
2822 assign(result, binop(Iop_Add64, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)),
2823 mkexpr(carry_in)));
2824 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_64, op1, op2, carry_in);
2825 put_gpr_dw0(r1, mkexpr(result));
2826
2827 return "alcgr";
2828}
2829
2830static HChar *
2831s390_irgen_ALC(UChar r1, IRTemp op2addr)
2832{
2833 IRTemp op1 = newTemp(Ity_I32);
2834 IRTemp op2 = newTemp(Ity_I32);
2835 IRTemp result = newTemp(Ity_I32);
2836 IRTemp carry_in = newTemp(Ity_I32);
2837
2838 assign(op1, get_gpr_w1(r1));
2839 assign(op2, load(Ity_I32, mkexpr(op2addr)));
2840 assign(carry_in, binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)));
2841 assign(result, binop(Iop_Add32, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)),
2842 mkexpr(carry_in)));
2843 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_32, op1, op2, carry_in);
2844 put_gpr_w1(r1, mkexpr(result));
2845
2846 return "alc";
2847}
2848
2849static HChar *
2850s390_irgen_ALCG(UChar r1, IRTemp op2addr)
2851{
2852 IRTemp op1 = newTemp(Ity_I64);
2853 IRTemp op2 = newTemp(Ity_I64);
2854 IRTemp result = newTemp(Ity_I64);
2855 IRTemp carry_in = newTemp(Ity_I64);
2856
2857 assign(op1, get_gpr_dw0(r1));
2858 assign(op2, load(Ity_I64, mkexpr(op2addr)));
2859 assign(carry_in, unop(Iop_32Uto64, binop(Iop_Shr32, s390_call_calculate_cc(),
2860 mkU8(1))));
2861 assign(result, binop(Iop_Add64, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)),
2862 mkexpr(carry_in)));
2863 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_64, op1, op2, carry_in);
2864 put_gpr_dw0(r1, mkexpr(result));
2865
2866 return "alcg";
2867}
2868
2869static HChar *
2870s390_irgen_ALSI(UChar i2, IRTemp op1addr)
2871{
2872 IRTemp op1 = newTemp(Ity_I32);
2873 UInt op2;
2874 IRTemp result = newTemp(Ity_I32);
2875
2876 assign(op1, load(Ity_I32, mkexpr(op1addr)));
2877 op2 = (UInt)(Int)(Char)i2;
2878 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
2879 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, mktemp(Ity_I32,
2880 mkU32(op2)));
2881 store(mkexpr(op1addr), mkexpr(result));
2882
2883 return "alsi";
2884}
2885
2886static HChar *
2887s390_irgen_ALGSI(UChar i2, IRTemp op1addr)
2888{
2889 IRTemp op1 = newTemp(Ity_I64);
2890 ULong op2;
2891 IRTemp result = newTemp(Ity_I64);
2892
2893 assign(op1, load(Ity_I64, mkexpr(op1addr)));
2894 op2 = (ULong)(Long)(Char)i2;
2895 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64(op2)));
2896 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, mktemp(Ity_I64,
2897 mkU64(op2)));
2898 store(mkexpr(op1addr), mkexpr(result));
2899
2900 return "algsi";
2901}
2902
2903static HChar *
2904s390_irgen_ALHSIK(UChar r1, UChar r3, UShort i2)
2905{
2906 UInt op2;
2907 IRTemp op3 = newTemp(Ity_I32);
2908 IRTemp result = newTemp(Ity_I32);
2909
2910 op2 = (UInt)(Int)(Short)i2;
2911 assign(op3, get_gpr_w1(r3));
2912 assign(result, binop(Iop_Add32, mkU32(op2), mkexpr(op3)));
2913 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, mktemp(Ity_I32, mkU32(op2)),
2914 op3);
2915 put_gpr_w1(r1, mkexpr(result));
2916
2917 return "alhsik";
2918}
2919
2920static HChar *
2921s390_irgen_ALGHSIK(UChar r1, UChar r3, UShort i2)
2922{
2923 ULong op2;
2924 IRTemp op3 = newTemp(Ity_I64);
2925 IRTemp result = newTemp(Ity_I64);
2926
2927 op2 = (ULong)(Long)(Short)i2;
2928 assign(op3, get_gpr_dw0(r3));
2929 assign(result, binop(Iop_Add64, mkU64(op2), mkexpr(op3)));
2930 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, mktemp(Ity_I64, mkU64(op2)),
2931 op3);
2932 put_gpr_dw0(r1, mkexpr(result));
2933
2934 return "alghsik";
2935}
2936
2937static HChar *
2938s390_irgen_ALSIH(UChar r1, UInt i2)
2939{
2940 IRTemp op1 = newTemp(Ity_I32);
2941 UInt op2;
2942 IRTemp result = newTemp(Ity_I32);
2943
2944 assign(op1, get_gpr_w0(r1));
2945 op2 = i2;
2946 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
2947 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, mktemp(Ity_I32,
2948 mkU32(op2)));
2949 put_gpr_w0(r1, mkexpr(result));
2950
2951 return "alsih";
2952}
2953
2954static HChar *
2955s390_irgen_ALSIHN(UChar r1, UInt i2)
2956{
2957 IRTemp op1 = newTemp(Ity_I32);
2958 UInt op2;
2959 IRTemp result = newTemp(Ity_I32);
2960
2961 assign(op1, get_gpr_w0(r1));
2962 op2 = i2;
2963 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
2964 put_gpr_w0(r1, mkexpr(result));
2965
2966 return "alsihn";
2967}
2968
2969static HChar *
2970s390_irgen_NR(UChar r1, UChar r2)
2971{
2972 IRTemp op1 = newTemp(Ity_I32);
2973 IRTemp op2 = newTemp(Ity_I32);
2974 IRTemp result = newTemp(Ity_I32);
2975
2976 assign(op1, get_gpr_w1(r1));
2977 assign(op2, get_gpr_w1(r2));
2978 assign(result, binop(Iop_And32, mkexpr(op1), mkexpr(op2)));
2979 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
2980 put_gpr_w1(r1, mkexpr(result));
2981
2982 return "nr";
2983}
2984
2985static HChar *
2986s390_irgen_NGR(UChar r1, UChar r2)
2987{
2988 IRTemp op1 = newTemp(Ity_I64);
2989 IRTemp op2 = newTemp(Ity_I64);
2990 IRTemp result = newTemp(Ity_I64);
2991
2992 assign(op1, get_gpr_dw0(r1));
2993 assign(op2, get_gpr_dw0(r2));
2994 assign(result, binop(Iop_And64, mkexpr(op1), mkexpr(op2)));
2995 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
2996 put_gpr_dw0(r1, mkexpr(result));
2997
2998 return "ngr";
2999}
3000
3001static HChar *
3002s390_irgen_NRK(UChar r3, UChar r1, UChar r2)
3003{
3004 IRTemp op2 = newTemp(Ity_I32);
3005 IRTemp op3 = newTemp(Ity_I32);
3006 IRTemp result = newTemp(Ity_I32);
3007
3008 assign(op2, get_gpr_w1(r2));
3009 assign(op3, get_gpr_w1(r3));
3010 assign(result, binop(Iop_And32, mkexpr(op2), mkexpr(op3)));
3011 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3012 put_gpr_w1(r1, mkexpr(result));
3013
3014 return "nrk";
3015}
3016
3017static HChar *
3018s390_irgen_NGRK(UChar r3, UChar r1, UChar r2)
3019{
3020 IRTemp op2 = newTemp(Ity_I64);
3021 IRTemp op3 = newTemp(Ity_I64);
3022 IRTemp result = newTemp(Ity_I64);
3023
3024 assign(op2, get_gpr_dw0(r2));
3025 assign(op3, get_gpr_dw0(r3));
3026 assign(result, binop(Iop_And64, mkexpr(op2), mkexpr(op3)));
3027 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3028 put_gpr_dw0(r1, mkexpr(result));
3029
3030 return "ngrk";
3031}
3032
3033static HChar *
3034s390_irgen_N(UChar r1, IRTemp op2addr)
3035{
3036 IRTemp op1 = newTemp(Ity_I32);
3037 IRTemp op2 = newTemp(Ity_I32);
3038 IRTemp result = newTemp(Ity_I32);
3039
3040 assign(op1, get_gpr_w1(r1));
3041 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3042 assign(result, binop(Iop_And32, mkexpr(op1), mkexpr(op2)));
3043 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3044 put_gpr_w1(r1, mkexpr(result));
3045
3046 return "n";
3047}
3048
3049static HChar *
3050s390_irgen_NY(UChar r1, IRTemp op2addr)
3051{
3052 IRTemp op1 = newTemp(Ity_I32);
3053 IRTemp op2 = newTemp(Ity_I32);
3054 IRTemp result = newTemp(Ity_I32);
3055
3056 assign(op1, get_gpr_w1(r1));
3057 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3058 assign(result, binop(Iop_And32, mkexpr(op1), mkexpr(op2)));
3059 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3060 put_gpr_w1(r1, mkexpr(result));
3061
3062 return "ny";
3063}
3064
3065static HChar *
3066s390_irgen_NG(UChar r1, IRTemp op2addr)
3067{
3068 IRTemp op1 = newTemp(Ity_I64);
3069 IRTemp op2 = newTemp(Ity_I64);
3070 IRTemp result = newTemp(Ity_I64);
3071
3072 assign(op1, get_gpr_dw0(r1));
3073 assign(op2, load(Ity_I64, mkexpr(op2addr)));
3074 assign(result, binop(Iop_And64, mkexpr(op1), mkexpr(op2)));
3075 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3076 put_gpr_dw0(r1, mkexpr(result));
3077
3078 return "ng";
3079}
3080
3081static HChar *
3082s390_irgen_NI(UChar i2, IRTemp op1addr)
3083{
3084 IRTemp op1 = newTemp(Ity_I8);
3085 UChar op2;
3086 IRTemp result = newTemp(Ity_I8);
3087
3088 assign(op1, load(Ity_I8, mkexpr(op1addr)));
3089 op2 = i2;
3090 assign(result, binop(Iop_And8, mkexpr(op1), mkU8(op2)));
3091 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3092 store(mkexpr(op1addr), mkexpr(result));
3093
3094 return "ni";
3095}
3096
3097static HChar *
3098s390_irgen_NIY(UChar i2, IRTemp op1addr)
3099{
3100 IRTemp op1 = newTemp(Ity_I8);
3101 UChar op2;
3102 IRTemp result = newTemp(Ity_I8);
3103
3104 assign(op1, load(Ity_I8, mkexpr(op1addr)));
3105 op2 = i2;
3106 assign(result, binop(Iop_And8, mkexpr(op1), mkU8(op2)));
3107 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3108 store(mkexpr(op1addr), mkexpr(result));
3109
3110 return "niy";
3111}
3112
3113static HChar *
3114s390_irgen_NIHF(UChar r1, UInt i2)
3115{
3116 IRTemp op1 = newTemp(Ity_I32);
3117 UInt op2;
3118 IRTemp result = newTemp(Ity_I32);
3119
3120 assign(op1, get_gpr_w0(r1));
3121 op2 = i2;
3122 assign(result, binop(Iop_And32, mkexpr(op1), mkU32(op2)));
3123 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3124 put_gpr_w0(r1, mkexpr(result));
3125
3126 return "nihf";
3127}
3128
3129static HChar *
3130s390_irgen_NIHH(UChar r1, UShort i2)
3131{
3132 IRTemp op1 = newTemp(Ity_I16);
3133 UShort op2;
3134 IRTemp result = newTemp(Ity_I16);
3135
3136 assign(op1, get_gpr_hw0(r1));
3137 op2 = i2;
3138 assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
3139 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3140 put_gpr_hw0(r1, mkexpr(result));
3141
3142 return "nihh";
3143}
3144
3145static HChar *
3146s390_irgen_NIHL(UChar r1, UShort i2)
3147{
3148 IRTemp op1 = newTemp(Ity_I16);
3149 UShort op2;
3150 IRTemp result = newTemp(Ity_I16);
3151
3152 assign(op1, get_gpr_hw1(r1));
3153 op2 = i2;
3154 assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
3155 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3156 put_gpr_hw1(r1, mkexpr(result));
3157
3158 return "nihl";
3159}
3160
3161static HChar *
3162s390_irgen_NILF(UChar r1, UInt i2)
3163{
3164 IRTemp op1 = newTemp(Ity_I32);
3165 UInt op2;
3166 IRTemp result = newTemp(Ity_I32);
3167
3168 assign(op1, get_gpr_w1(r1));
3169 op2 = i2;
3170 assign(result, binop(Iop_And32, mkexpr(op1), mkU32(op2)));
3171 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3172 put_gpr_w1(r1, mkexpr(result));
3173
3174 return "nilf";
3175}
3176
3177static HChar *
3178s390_irgen_NILH(UChar r1, UShort i2)
3179{
3180 IRTemp op1 = newTemp(Ity_I16);
3181 UShort op2;
3182 IRTemp result = newTemp(Ity_I16);
3183
3184 assign(op1, get_gpr_hw2(r1));
3185 op2 = i2;
3186 assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
3187 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3188 put_gpr_hw2(r1, mkexpr(result));
3189
3190 return "nilh";
3191}
3192
3193static HChar *
3194s390_irgen_NILL(UChar r1, UShort i2)
3195{
3196 IRTemp op1 = newTemp(Ity_I16);
3197 UShort op2;
3198 IRTemp result = newTemp(Ity_I16);
3199
3200 assign(op1, get_gpr_hw3(r1));
3201 op2 = i2;
3202 assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
3203 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3204 put_gpr_hw3(r1, mkexpr(result));
3205
3206 return "nill";
3207}
3208
3209static HChar *
3210s390_irgen_BASR(UChar r1, UChar r2)
3211{
3212 IRTemp target = newTemp(Ity_I64);
3213
3214 if (r2 == 0) {
3215 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 2ULL));
3216 } else {
3217 if (r1 != r2) {
3218 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 2ULL));
3219 call_function(get_gpr_dw0(r2));
3220 } else {
3221 assign(target, get_gpr_dw0(r2));
3222 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 2ULL));
3223 call_function(mkexpr(target));
3224 }
3225 }
3226
3227 return "basr";
3228}
3229
3230static HChar *
3231s390_irgen_BAS(UChar r1, IRTemp op2addr)
3232{
3233 IRTemp target = newTemp(Ity_I64);
3234
3235 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 4ULL));
3236 assign(target, mkexpr(op2addr));
3237 call_function(mkexpr(target));
3238
3239 return "bas";
3240}
3241
3242static HChar *
3243s390_irgen_BCR(UChar r1, UChar r2)
3244{
3245 IRTemp cond = newTemp(Ity_I32);
3246
sewardja52e37e2011-04-28 18:48:06 +00003247 if (r2 == 0 && (r1 >= 14)) { /* serialization */
3248 stmt(IRStmt_MBE(Imbe_Fence));
3249 }
3250
sewardj2019a972011-03-07 16:04:07 +00003251 if ((r2 == 0) || (r1 == 0)) {
3252 } else {
3253 if (r1 == 15) {
3254 return_from_function(get_gpr_dw0(r2));
3255 } else {
3256 assign(cond, s390_call_calculate_cond(r1));
florianf321da72012-07-21 20:32:57 +00003257 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3258 get_gpr_dw0(r2));
sewardj2019a972011-03-07 16:04:07 +00003259 }
3260 }
sewardj7ee97522011-05-09 21:45:04 +00003261 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00003262 s390_disasm(ENC2(XMNM, GPR), S390_XMNM_BCR, r1, r2);
3263
3264 return "bcr";
3265}
3266
3267static HChar *
3268s390_irgen_BC(UChar r1, UChar x2, UChar b2, UShort d2, IRTemp op2addr)
3269{
3270 IRTemp cond = newTemp(Ity_I32);
3271
3272 if (r1 == 0) {
3273 } else {
3274 if (r1 == 15) {
3275 always_goto(mkexpr(op2addr));
3276 } else {
3277 assign(cond, s390_call_calculate_cond(r1));
florianf321da72012-07-21 20:32:57 +00003278 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3279 mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003280 }
3281 }
sewardj7ee97522011-05-09 21:45:04 +00003282 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00003283 s390_disasm(ENC2(XMNM, UDXB), S390_XMNM_BC, r1, d2, x2, b2);
3284
3285 return "bc";
3286}
3287
3288static HChar *
3289s390_irgen_BCTR(UChar r1, UChar r2)
3290{
3291 put_gpr_w1(r1, binop(Iop_Sub32, get_gpr_w1(r1), mkU32(1)));
3292 if (r2 != 0) {
florianf321da72012-07-21 20:32:57 +00003293 if_condition_goto_computed(binop(Iop_CmpNE32, get_gpr_w1(r1), mkU32(0)),
3294 get_gpr_dw0(r2));
sewardj2019a972011-03-07 16:04:07 +00003295 }
3296
3297 return "bctr";
3298}
3299
3300static HChar *
3301s390_irgen_BCTGR(UChar r1, UChar r2)
3302{
3303 put_gpr_dw0(r1, binop(Iop_Sub64, get_gpr_dw0(r1), mkU64(1)));
3304 if (r2 != 0) {
florianf321da72012-07-21 20:32:57 +00003305 if_condition_goto_computed(binop(Iop_CmpNE64, get_gpr_dw0(r1), mkU64(0)),
3306 get_gpr_dw0(r2));
sewardj2019a972011-03-07 16:04:07 +00003307 }
3308
3309 return "bctgr";
3310}
3311
3312static HChar *
3313s390_irgen_BCT(UChar r1, IRTemp op2addr)
3314{
3315 put_gpr_w1(r1, binop(Iop_Sub32, get_gpr_w1(r1), mkU32(1)));
florianf321da72012-07-21 20:32:57 +00003316 if_condition_goto_computed(binop(Iop_CmpNE32, get_gpr_w1(r1), mkU32(0)),
3317 mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003318
3319 return "bct";
3320}
3321
3322static HChar *
3323s390_irgen_BCTG(UChar r1, IRTemp op2addr)
3324{
3325 put_gpr_dw0(r1, binop(Iop_Sub64, get_gpr_dw0(r1), mkU64(1)));
florianf321da72012-07-21 20:32:57 +00003326 if_condition_goto_computed(binop(Iop_CmpNE64, get_gpr_dw0(r1), mkU64(0)),
3327 mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003328
3329 return "bctg";
3330}
3331
3332static HChar *
3333s390_irgen_BXH(UChar r1, UChar r3, IRTemp op2addr)
3334{
3335 IRTemp value = newTemp(Ity_I32);
3336
3337 assign(value, get_gpr_w1(r3 | 1));
3338 put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
florianf321da72012-07-21 20:32:57 +00003339 if_condition_goto_computed(binop(Iop_CmpLT32S, mkexpr(value),
3340 get_gpr_w1(r1)), mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003341
3342 return "bxh";
3343}
3344
3345static HChar *
3346s390_irgen_BXHG(UChar r1, UChar r3, IRTemp op2addr)
3347{
3348 IRTemp value = newTemp(Ity_I64);
3349
3350 assign(value, get_gpr_dw0(r3 | 1));
3351 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
florianf321da72012-07-21 20:32:57 +00003352 if_condition_goto_computed(binop(Iop_CmpLT64S, mkexpr(value),
3353 get_gpr_dw0(r1)), mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003354
3355 return "bxhg";
3356}
3357
3358static HChar *
3359s390_irgen_BXLE(UChar r1, UChar r3, IRTemp op2addr)
3360{
3361 IRTemp value = newTemp(Ity_I32);
3362
3363 assign(value, get_gpr_w1(r3 | 1));
3364 put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
florianf321da72012-07-21 20:32:57 +00003365 if_condition_goto_computed(binop(Iop_CmpLE32S, get_gpr_w1(r1),
3366 mkexpr(value)), mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003367
3368 return "bxle";
3369}
3370
3371static HChar *
3372s390_irgen_BXLEG(UChar r1, UChar r3, IRTemp op2addr)
3373{
3374 IRTemp value = newTemp(Ity_I64);
3375
3376 assign(value, get_gpr_dw0(r3 | 1));
3377 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
florianf321da72012-07-21 20:32:57 +00003378 if_condition_goto_computed(binop(Iop_CmpLE64S, get_gpr_dw0(r1),
3379 mkexpr(value)), mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003380
3381 return "bxleg";
3382}
3383
3384static HChar *
3385s390_irgen_BRAS(UChar r1, UShort i2)
3386{
3387 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 4ULL));
floriana64c2432011-07-16 02:11:50 +00003388 call_function_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
sewardj2019a972011-03-07 16:04:07 +00003389
3390 return "bras";
3391}
3392
3393static HChar *
3394s390_irgen_BRASL(UChar r1, UInt i2)
3395{
3396 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 6ULL));
floriana64c2432011-07-16 02:11:50 +00003397 call_function_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1));
sewardj2019a972011-03-07 16:04:07 +00003398
3399 return "brasl";
3400}
3401
3402static HChar *
3403s390_irgen_BRC(UChar r1, UShort i2)
3404{
3405 IRTemp cond = newTemp(Ity_I32);
3406
3407 if (r1 == 0) {
3408 } else {
3409 if (r1 == 15) {
floriana64c2432011-07-16 02:11:50 +00003410 always_goto_and_chase(
3411 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
sewardj2019a972011-03-07 16:04:07 +00003412 } else {
3413 assign(cond, s390_call_calculate_cond(r1));
3414 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3415 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3416
3417 }
3418 }
sewardj7ee97522011-05-09 21:45:04 +00003419 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00003420 s390_disasm(ENC2(XMNM, PCREL), S390_XMNM_BRC, r1, (Int)(Short)i2);
3421
3422 return "brc";
3423}
3424
3425static HChar *
3426s390_irgen_BRCL(UChar r1, UInt i2)
3427{
3428 IRTemp cond = newTemp(Ity_I32);
3429
3430 if (r1 == 0) {
3431 } else {
3432 if (r1 == 15) {
floriana64c2432011-07-16 02:11:50 +00003433 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1));
sewardj2019a972011-03-07 16:04:07 +00003434 } else {
3435 assign(cond, s390_call_calculate_cond(r1));
3436 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3437 guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1));
3438 }
3439 }
sewardj7ee97522011-05-09 21:45:04 +00003440 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00003441 s390_disasm(ENC2(XMNM, PCREL), S390_XMNM_BRCL, r1, i2);
3442
3443 return "brcl";
3444}
3445
3446static HChar *
3447s390_irgen_BRCT(UChar r1, UShort i2)
3448{
3449 put_gpr_w1(r1, binop(Iop_Sub32, get_gpr_w1(r1), mkU32(1)));
3450 if_condition_goto(binop(Iop_CmpNE32, get_gpr_w1(r1), mkU32(0)),
3451 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3452
3453 return "brct";
3454}
3455
3456static HChar *
3457s390_irgen_BRCTG(UChar r1, UShort i2)
3458{
3459 put_gpr_dw0(r1, binop(Iop_Sub64, get_gpr_dw0(r1), mkU64(1)));
3460 if_condition_goto(binop(Iop_CmpNE64, get_gpr_dw0(r1), mkU64(0)),
3461 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3462
3463 return "brctg";
3464}
3465
3466static HChar *
3467s390_irgen_BRXH(UChar r1, UChar r3, UShort i2)
3468{
3469 IRTemp value = newTemp(Ity_I32);
3470
3471 assign(value, get_gpr_w1(r3 | 1));
3472 put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
3473 if_condition_goto(binop(Iop_CmpLT32S, mkexpr(value), get_gpr_w1(r1)),
3474 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3475
3476 return "brxh";
3477}
3478
3479static HChar *
3480s390_irgen_BRXHG(UChar r1, UChar r3, UShort i2)
3481{
3482 IRTemp value = newTemp(Ity_I64);
3483
3484 assign(value, get_gpr_dw0(r3 | 1));
3485 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
3486 if_condition_goto(binop(Iop_CmpLT64S, mkexpr(value), get_gpr_dw0(r1)),
3487 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3488
3489 return "brxhg";
3490}
3491
3492static HChar *
3493s390_irgen_BRXLE(UChar r1, UChar r3, UShort i2)
3494{
3495 IRTemp value = newTemp(Ity_I32);
3496
3497 assign(value, get_gpr_w1(r3 | 1));
3498 put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
3499 if_condition_goto(binop(Iop_CmpLE32S, get_gpr_w1(r1), mkexpr(value)),
3500 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3501
3502 return "brxle";
3503}
3504
3505static HChar *
3506s390_irgen_BRXLG(UChar r1, UChar r3, UShort i2)
3507{
3508 IRTemp value = newTemp(Ity_I64);
3509
3510 assign(value, get_gpr_dw0(r3 | 1));
3511 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
3512 if_condition_goto(binop(Iop_CmpLE64S, get_gpr_dw0(r1), mkexpr(value)),
3513 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3514
3515 return "brxlg";
3516}
3517
3518static HChar *
3519s390_irgen_CR(UChar r1, UChar r2)
3520{
3521 IRTemp op1 = newTemp(Ity_I32);
3522 IRTemp op2 = newTemp(Ity_I32);
3523
3524 assign(op1, get_gpr_w1(r1));
3525 assign(op2, get_gpr_w1(r2));
3526 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3527
3528 return "cr";
3529}
3530
3531static HChar *
3532s390_irgen_CGR(UChar r1, UChar r2)
3533{
3534 IRTemp op1 = newTemp(Ity_I64);
3535 IRTemp op2 = newTemp(Ity_I64);
3536
3537 assign(op1, get_gpr_dw0(r1));
3538 assign(op2, get_gpr_dw0(r2));
3539 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3540
3541 return "cgr";
3542}
3543
3544static HChar *
3545s390_irgen_CGFR(UChar r1, UChar r2)
3546{
3547 IRTemp op1 = newTemp(Ity_I64);
3548 IRTemp op2 = newTemp(Ity_I64);
3549
3550 assign(op1, get_gpr_dw0(r1));
3551 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
3552 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3553
3554 return "cgfr";
3555}
3556
3557static HChar *
3558s390_irgen_C(UChar r1, IRTemp op2addr)
3559{
3560 IRTemp op1 = newTemp(Ity_I32);
3561 IRTemp op2 = newTemp(Ity_I32);
3562
3563 assign(op1, get_gpr_w1(r1));
3564 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3565 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3566
3567 return "c";
3568}
3569
3570static HChar *
3571s390_irgen_CY(UChar r1, IRTemp op2addr)
3572{
3573 IRTemp op1 = newTemp(Ity_I32);
3574 IRTemp op2 = newTemp(Ity_I32);
3575
3576 assign(op1, get_gpr_w1(r1));
3577 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3578 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3579
3580 return "cy";
3581}
3582
3583static HChar *
3584s390_irgen_CG(UChar r1, IRTemp op2addr)
3585{
3586 IRTemp op1 = newTemp(Ity_I64);
3587 IRTemp op2 = newTemp(Ity_I64);
3588
3589 assign(op1, get_gpr_dw0(r1));
3590 assign(op2, load(Ity_I64, mkexpr(op2addr)));
3591 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3592
3593 return "cg";
3594}
3595
3596static HChar *
3597s390_irgen_CGF(UChar r1, IRTemp op2addr)
3598{
3599 IRTemp op1 = newTemp(Ity_I64);
3600 IRTemp op2 = newTemp(Ity_I64);
3601
3602 assign(op1, get_gpr_dw0(r1));
3603 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
3604 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3605
3606 return "cgf";
3607}
3608
3609static HChar *
3610s390_irgen_CFI(UChar r1, UInt i2)
3611{
3612 IRTemp op1 = newTemp(Ity_I32);
3613 Int op2;
3614
3615 assign(op1, get_gpr_w1(r1));
3616 op2 = (Int)i2;
3617 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
3618 mkU32((UInt)op2)));
3619
3620 return "cfi";
3621}
3622
3623static HChar *
3624s390_irgen_CGFI(UChar r1, UInt i2)
3625{
3626 IRTemp op1 = newTemp(Ity_I64);
3627 Long op2;
3628
3629 assign(op1, get_gpr_dw0(r1));
3630 op2 = (Long)(Int)i2;
3631 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I64,
3632 mkU64((ULong)op2)));
3633
3634 return "cgfi";
3635}
3636
3637static HChar *
3638s390_irgen_CRL(UChar r1, UInt i2)
3639{
3640 IRTemp op1 = newTemp(Ity_I32);
3641 IRTemp op2 = newTemp(Ity_I32);
3642
3643 assign(op1, get_gpr_w1(r1));
3644 assign(op2, load(Ity_I32, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
3645 i2 << 1))));
3646 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3647
3648 return "crl";
3649}
3650
3651static HChar *
3652s390_irgen_CGRL(UChar r1, UInt i2)
3653{
3654 IRTemp op1 = newTemp(Ity_I64);
3655 IRTemp op2 = newTemp(Ity_I64);
3656
3657 assign(op1, get_gpr_dw0(r1));
3658 assign(op2, load(Ity_I64, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
3659 i2 << 1))));
3660 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3661
3662 return "cgrl";
3663}
3664
3665static HChar *
3666s390_irgen_CGFRL(UChar r1, UInt i2)
3667{
3668 IRTemp op1 = newTemp(Ity_I64);
3669 IRTemp op2 = newTemp(Ity_I64);
3670
3671 assign(op1, get_gpr_dw0(r1));
3672 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
3673 ((ULong)(Long)(Int)i2 << 1)))));
3674 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3675
3676 return "cgfrl";
3677}
3678
3679static HChar *
3680s390_irgen_CRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
3681{
3682 IRTemp op1 = newTemp(Ity_I32);
3683 IRTemp op2 = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00003684 IRTemp cond = newTemp(Ity_I32);
3685
3686 if (m3 == 0) {
3687 } else {
3688 if (m3 == 14) {
3689 always_goto(mkexpr(op4addr));
3690 } else {
3691 assign(op1, get_gpr_w1(r1));
3692 assign(op2, get_gpr_w1(r2));
florianff9613f2012-05-12 15:26:44 +00003693 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
3694 op1, op2));
florianf321da72012-07-21 20:32:57 +00003695 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond),
3696 mkU32(0)), mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00003697 }
3698 }
3699
3700 return "crb";
3701}
3702
3703static HChar *
3704s390_irgen_CGRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
3705{
3706 IRTemp op1 = newTemp(Ity_I64);
3707 IRTemp op2 = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00003708 IRTemp cond = newTemp(Ity_I32);
3709
3710 if (m3 == 0) {
3711 } else {
3712 if (m3 == 14) {
3713 always_goto(mkexpr(op4addr));
3714 } else {
3715 assign(op1, get_gpr_dw0(r1));
3716 assign(op2, get_gpr_dw0(r2));
florianff9613f2012-05-12 15:26:44 +00003717 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
3718 op1, op2));
florianf321da72012-07-21 20:32:57 +00003719 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond),
3720 mkU32(0)), mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00003721 }
3722 }
3723
3724 return "cgrb";
3725}
3726
3727static HChar *
3728s390_irgen_CRJ(UChar r1, UChar r2, UShort i4, UChar m3)
3729{
3730 IRTemp op1 = newTemp(Ity_I32);
3731 IRTemp op2 = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00003732 IRTemp cond = newTemp(Ity_I32);
3733
3734 if (m3 == 0) {
3735 } else {
3736 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00003737 always_goto_and_chase(
3738 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00003739 } else {
3740 assign(op1, get_gpr_w1(r1));
3741 assign(op2, get_gpr_w1(r2));
florianff9613f2012-05-12 15:26:44 +00003742 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
3743 op1, op2));
sewardj2019a972011-03-07 16:04:07 +00003744 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3745 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
3746
3747 }
3748 }
3749
3750 return "crj";
3751}
3752
3753static HChar *
3754s390_irgen_CGRJ(UChar r1, UChar r2, UShort i4, UChar m3)
3755{
3756 IRTemp op1 = newTemp(Ity_I64);
3757 IRTemp op2 = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00003758 IRTemp cond = newTemp(Ity_I32);
3759
3760 if (m3 == 0) {
3761 } else {
3762 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00003763 always_goto_and_chase(
3764 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00003765 } else {
3766 assign(op1, get_gpr_dw0(r1));
3767 assign(op2, get_gpr_dw0(r2));
florianff9613f2012-05-12 15:26:44 +00003768 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
3769 op1, op2));
sewardj2019a972011-03-07 16:04:07 +00003770 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3771 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
3772
3773 }
3774 }
3775
3776 return "cgrj";
3777}
3778
3779static HChar *
3780s390_irgen_CIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
3781{
3782 IRTemp op1 = newTemp(Ity_I32);
3783 Int op2;
sewardj2019a972011-03-07 16:04:07 +00003784 IRTemp cond = newTemp(Ity_I32);
3785
3786 if (m3 == 0) {
3787 } else {
3788 if (m3 == 14) {
3789 always_goto(mkexpr(op4addr));
3790 } else {
3791 assign(op1, get_gpr_w1(r1));
3792 op2 = (Int)(Char)i2;
florianff9613f2012-05-12 15:26:44 +00003793 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
3794 mktemp(Ity_I32, mkU32((UInt)op2))));
florianf321da72012-07-21 20:32:57 +00003795 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3796 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00003797 }
3798 }
3799
3800 return "cib";
3801}
3802
3803static HChar *
3804s390_irgen_CGIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
3805{
3806 IRTemp op1 = newTemp(Ity_I64);
3807 Long op2;
sewardj2019a972011-03-07 16:04:07 +00003808 IRTemp cond = newTemp(Ity_I32);
3809
3810 if (m3 == 0) {
3811 } else {
3812 if (m3 == 14) {
3813 always_goto(mkexpr(op4addr));
3814 } else {
3815 assign(op1, get_gpr_dw0(r1));
3816 op2 = (Long)(Char)i2;
florianff9613f2012-05-12 15:26:44 +00003817 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
3818 mktemp(Ity_I64, mkU64((ULong)op2))));
florianf321da72012-07-21 20:32:57 +00003819 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3820 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00003821 }
3822 }
3823
3824 return "cgib";
3825}
3826
3827static HChar *
3828s390_irgen_CIJ(UChar r1, UChar m3, UShort i4, UChar i2)
3829{
3830 IRTemp op1 = newTemp(Ity_I32);
3831 Int op2;
sewardj2019a972011-03-07 16:04:07 +00003832 IRTemp cond = newTemp(Ity_I32);
3833
3834 if (m3 == 0) {
3835 } else {
3836 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00003837 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00003838 } else {
3839 assign(op1, get_gpr_w1(r1));
3840 op2 = (Int)(Char)i2;
florianff9613f2012-05-12 15:26:44 +00003841 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
3842 mktemp(Ity_I32, mkU32((UInt)op2))));
sewardj2019a972011-03-07 16:04:07 +00003843 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3844 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
3845
3846 }
3847 }
3848
3849 return "cij";
3850}
3851
3852static HChar *
3853s390_irgen_CGIJ(UChar r1, UChar m3, UShort i4, UChar i2)
3854{
3855 IRTemp op1 = newTemp(Ity_I64);
3856 Long op2;
sewardj2019a972011-03-07 16:04:07 +00003857 IRTemp cond = newTemp(Ity_I32);
3858
3859 if (m3 == 0) {
3860 } else {
3861 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00003862 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00003863 } else {
3864 assign(op1, get_gpr_dw0(r1));
3865 op2 = (Long)(Char)i2;
florianff9613f2012-05-12 15:26:44 +00003866 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
3867 mktemp(Ity_I64, mkU64((ULong)op2))));
sewardj2019a972011-03-07 16:04:07 +00003868 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3869 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
3870
3871 }
3872 }
3873
3874 return "cgij";
3875}
3876
3877static HChar *
3878s390_irgen_CH(UChar r1, IRTemp op2addr)
3879{
3880 IRTemp op1 = newTemp(Ity_I32);
3881 IRTemp op2 = newTemp(Ity_I32);
3882
3883 assign(op1, get_gpr_w1(r1));
3884 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
3885 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3886
3887 return "ch";
3888}
3889
3890static HChar *
3891s390_irgen_CHY(UChar r1, IRTemp op2addr)
3892{
3893 IRTemp op1 = newTemp(Ity_I32);
3894 IRTemp op2 = newTemp(Ity_I32);
3895
3896 assign(op1, get_gpr_w1(r1));
3897 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
3898 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3899
3900 return "chy";
3901}
3902
3903static HChar *
3904s390_irgen_CGH(UChar r1, IRTemp op2addr)
3905{
3906 IRTemp op1 = newTemp(Ity_I64);
3907 IRTemp op2 = newTemp(Ity_I64);
3908
3909 assign(op1, get_gpr_dw0(r1));
3910 assign(op2, unop(Iop_16Sto64, load(Ity_I16, mkexpr(op2addr))));
3911 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3912
3913 return "cgh";
3914}
3915
3916static HChar *
3917s390_irgen_CHI(UChar r1, UShort i2)
3918{
3919 IRTemp op1 = newTemp(Ity_I32);
3920 Int op2;
3921
3922 assign(op1, get_gpr_w1(r1));
3923 op2 = (Int)(Short)i2;
3924 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
3925 mkU32((UInt)op2)));
3926
3927 return "chi";
3928}
3929
3930static HChar *
3931s390_irgen_CGHI(UChar r1, UShort i2)
3932{
3933 IRTemp op1 = newTemp(Ity_I64);
3934 Long op2;
3935
3936 assign(op1, get_gpr_dw0(r1));
3937 op2 = (Long)(Short)i2;
3938 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I64,
3939 mkU64((ULong)op2)));
3940
3941 return "cghi";
3942}
3943
3944static HChar *
3945s390_irgen_CHHSI(UShort i2, IRTemp op1addr)
3946{
3947 IRTemp op1 = newTemp(Ity_I16);
3948 Short op2;
3949
3950 assign(op1, load(Ity_I16, mkexpr(op1addr)));
3951 op2 = (Short)i2;
3952 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I16,
3953 mkU16((UShort)op2)));
3954
3955 return "chhsi";
3956}
3957
3958static HChar *
3959s390_irgen_CHSI(UShort i2, IRTemp op1addr)
3960{
3961 IRTemp op1 = newTemp(Ity_I32);
3962 Int op2;
3963
3964 assign(op1, load(Ity_I32, mkexpr(op1addr)));
3965 op2 = (Int)(Short)i2;
3966 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
3967 mkU32((UInt)op2)));
3968
3969 return "chsi";
3970}
3971
3972static HChar *
3973s390_irgen_CGHSI(UShort i2, IRTemp op1addr)
3974{
3975 IRTemp op1 = newTemp(Ity_I64);
3976 Long op2;
3977
3978 assign(op1, load(Ity_I64, mkexpr(op1addr)));
3979 op2 = (Long)(Short)i2;
3980 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I64,
3981 mkU64((ULong)op2)));
3982
3983 return "cghsi";
3984}
3985
3986static HChar *
3987s390_irgen_CHRL(UChar r1, UInt i2)
3988{
3989 IRTemp op1 = newTemp(Ity_I32);
3990 IRTemp op2 = newTemp(Ity_I32);
3991
3992 assign(op1, get_gpr_w1(r1));
3993 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
3994 ((ULong)(Long)(Int)i2 << 1)))));
3995 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3996
3997 return "chrl";
3998}
3999
4000static HChar *
4001s390_irgen_CGHRL(UChar r1, UInt i2)
4002{
4003 IRTemp op1 = newTemp(Ity_I64);
4004 IRTemp op2 = newTemp(Ity_I64);
4005
4006 assign(op1, get_gpr_dw0(r1));
4007 assign(op2, unop(Iop_16Sto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
4008 ((ULong)(Long)(Int)i2 << 1)))));
4009 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4010
4011 return "cghrl";
4012}
4013
4014static HChar *
4015s390_irgen_CHHR(UChar r1, UChar r2)
4016{
4017 IRTemp op1 = newTemp(Ity_I32);
4018 IRTemp op2 = newTemp(Ity_I32);
4019
4020 assign(op1, get_gpr_w0(r1));
4021 assign(op2, get_gpr_w0(r2));
4022 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4023
4024 return "chhr";
4025}
4026
4027static HChar *
4028s390_irgen_CHLR(UChar r1, UChar r2)
4029{
4030 IRTemp op1 = newTemp(Ity_I32);
4031 IRTemp op2 = newTemp(Ity_I32);
4032
4033 assign(op1, get_gpr_w0(r1));
4034 assign(op2, get_gpr_w1(r2));
4035 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4036
4037 return "chlr";
4038}
4039
4040static HChar *
4041s390_irgen_CHF(UChar r1, IRTemp op2addr)
4042{
4043 IRTemp op1 = newTemp(Ity_I32);
4044 IRTemp op2 = newTemp(Ity_I32);
4045
4046 assign(op1, get_gpr_w0(r1));
4047 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4048 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4049
4050 return "chf";
4051}
4052
4053static HChar *
4054s390_irgen_CIH(UChar r1, UInt i2)
4055{
4056 IRTemp op1 = newTemp(Ity_I32);
4057 Int op2;
4058
4059 assign(op1, get_gpr_w0(r1));
4060 op2 = (Int)i2;
4061 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
4062 mkU32((UInt)op2)));
4063
4064 return "cih";
4065}
4066
4067static HChar *
4068s390_irgen_CLR(UChar r1, UChar r2)
4069{
4070 IRTemp op1 = newTemp(Ity_I32);
4071 IRTemp op2 = newTemp(Ity_I32);
4072
4073 assign(op1, get_gpr_w1(r1));
4074 assign(op2, get_gpr_w1(r2));
4075 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4076
4077 return "clr";
4078}
4079
4080static HChar *
4081s390_irgen_CLGR(UChar r1, UChar r2)
4082{
4083 IRTemp op1 = newTemp(Ity_I64);
4084 IRTemp op2 = newTemp(Ity_I64);
4085
4086 assign(op1, get_gpr_dw0(r1));
4087 assign(op2, get_gpr_dw0(r2));
4088 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4089
4090 return "clgr";
4091}
4092
4093static HChar *
4094s390_irgen_CLGFR(UChar r1, UChar r2)
4095{
4096 IRTemp op1 = newTemp(Ity_I64);
4097 IRTemp op2 = newTemp(Ity_I64);
4098
4099 assign(op1, get_gpr_dw0(r1));
4100 assign(op2, unop(Iop_32Uto64, get_gpr_w1(r2)));
4101 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4102
4103 return "clgfr";
4104}
4105
4106static HChar *
4107s390_irgen_CL(UChar r1, IRTemp op2addr)
4108{
4109 IRTemp op1 = newTemp(Ity_I32);
4110 IRTemp op2 = newTemp(Ity_I32);
4111
4112 assign(op1, get_gpr_w1(r1));
4113 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4114 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4115
4116 return "cl";
4117}
4118
4119static HChar *
4120s390_irgen_CLY(UChar r1, IRTemp op2addr)
4121{
4122 IRTemp op1 = newTemp(Ity_I32);
4123 IRTemp op2 = newTemp(Ity_I32);
4124
4125 assign(op1, get_gpr_w1(r1));
4126 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4127 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4128
4129 return "cly";
4130}
4131
4132static HChar *
4133s390_irgen_CLG(UChar r1, IRTemp op2addr)
4134{
4135 IRTemp op1 = newTemp(Ity_I64);
4136 IRTemp op2 = newTemp(Ity_I64);
4137
4138 assign(op1, get_gpr_dw0(r1));
4139 assign(op2, load(Ity_I64, mkexpr(op2addr)));
4140 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4141
4142 return "clg";
4143}
4144
4145static HChar *
4146s390_irgen_CLGF(UChar r1, IRTemp op2addr)
4147{
4148 IRTemp op1 = newTemp(Ity_I64);
4149 IRTemp op2 = newTemp(Ity_I64);
4150
4151 assign(op1, get_gpr_dw0(r1));
4152 assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
4153 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4154
4155 return "clgf";
4156}
4157
4158static HChar *
4159s390_irgen_CLFI(UChar r1, UInt i2)
4160{
4161 IRTemp op1 = newTemp(Ity_I32);
4162 UInt op2;
4163
4164 assign(op1, get_gpr_w1(r1));
4165 op2 = i2;
4166 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I32,
4167 mkU32(op2)));
4168
4169 return "clfi";
4170}
4171
4172static HChar *
4173s390_irgen_CLGFI(UChar r1, UInt i2)
4174{
4175 IRTemp op1 = newTemp(Ity_I64);
4176 ULong op2;
4177
4178 assign(op1, get_gpr_dw0(r1));
4179 op2 = (ULong)i2;
4180 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I64,
4181 mkU64(op2)));
4182
4183 return "clgfi";
4184}
4185
4186static HChar *
4187s390_irgen_CLI(UChar i2, IRTemp op1addr)
4188{
4189 IRTemp op1 = newTemp(Ity_I8);
4190 UChar op2;
4191
4192 assign(op1, load(Ity_I8, mkexpr(op1addr)));
4193 op2 = i2;
4194 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I8,
4195 mkU8(op2)));
4196
4197 return "cli";
4198}
4199
4200static HChar *
4201s390_irgen_CLIY(UChar i2, IRTemp op1addr)
4202{
4203 IRTemp op1 = newTemp(Ity_I8);
4204 UChar op2;
4205
4206 assign(op1, load(Ity_I8, mkexpr(op1addr)));
4207 op2 = i2;
4208 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I8,
4209 mkU8(op2)));
4210
4211 return "cliy";
4212}
4213
4214static HChar *
4215s390_irgen_CLFHSI(UShort i2, IRTemp op1addr)
4216{
4217 IRTemp op1 = newTemp(Ity_I32);
4218 UInt op2;
4219
4220 assign(op1, load(Ity_I32, mkexpr(op1addr)));
4221 op2 = (UInt)i2;
4222 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I32,
4223 mkU32(op2)));
4224
4225 return "clfhsi";
4226}
4227
4228static HChar *
4229s390_irgen_CLGHSI(UShort i2, IRTemp op1addr)
4230{
4231 IRTemp op1 = newTemp(Ity_I64);
4232 ULong op2;
4233
4234 assign(op1, load(Ity_I64, mkexpr(op1addr)));
4235 op2 = (ULong)i2;
4236 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I64,
4237 mkU64(op2)));
4238
4239 return "clghsi";
4240}
4241
4242static HChar *
4243s390_irgen_CLHHSI(UShort i2, IRTemp op1addr)
4244{
4245 IRTemp op1 = newTemp(Ity_I16);
4246 UShort op2;
4247
4248 assign(op1, load(Ity_I16, mkexpr(op1addr)));
4249 op2 = i2;
4250 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I16,
4251 mkU16(op2)));
4252
4253 return "clhhsi";
4254}
4255
4256static HChar *
4257s390_irgen_CLRL(UChar r1, UInt i2)
4258{
4259 IRTemp op1 = newTemp(Ity_I32);
4260 IRTemp op2 = newTemp(Ity_I32);
4261
4262 assign(op1, get_gpr_w1(r1));
4263 assign(op2, load(Ity_I32, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
4264 i2 << 1))));
4265 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4266
4267 return "clrl";
4268}
4269
4270static HChar *
4271s390_irgen_CLGRL(UChar r1, UInt i2)
4272{
4273 IRTemp op1 = newTemp(Ity_I64);
4274 IRTemp op2 = newTemp(Ity_I64);
4275
4276 assign(op1, get_gpr_dw0(r1));
4277 assign(op2, load(Ity_I64, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
4278 i2 << 1))));
4279 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4280
4281 return "clgrl";
4282}
4283
4284static HChar *
4285s390_irgen_CLGFRL(UChar r1, UInt i2)
4286{
4287 IRTemp op1 = newTemp(Ity_I64);
4288 IRTemp op2 = newTemp(Ity_I64);
4289
4290 assign(op1, get_gpr_dw0(r1));
4291 assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
4292 ((ULong)(Long)(Int)i2 << 1)))));
4293 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4294
4295 return "clgfrl";
4296}
4297
4298static HChar *
4299s390_irgen_CLHRL(UChar r1, UInt i2)
4300{
4301 IRTemp op1 = newTemp(Ity_I32);
4302 IRTemp op2 = newTemp(Ity_I32);
4303
4304 assign(op1, get_gpr_w1(r1));
4305 assign(op2, unop(Iop_16Uto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
4306 ((ULong)(Long)(Int)i2 << 1)))));
4307 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4308
4309 return "clhrl";
4310}
4311
4312static HChar *
4313s390_irgen_CLGHRL(UChar r1, UInt i2)
4314{
4315 IRTemp op1 = newTemp(Ity_I64);
4316 IRTemp op2 = newTemp(Ity_I64);
4317
4318 assign(op1, get_gpr_dw0(r1));
4319 assign(op2, unop(Iop_16Uto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
4320 ((ULong)(Long)(Int)i2 << 1)))));
4321 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4322
4323 return "clghrl";
4324}
4325
4326static HChar *
4327s390_irgen_CLRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
4328{
4329 IRTemp op1 = newTemp(Ity_I32);
4330 IRTemp op2 = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00004331 IRTemp cond = newTemp(Ity_I32);
4332
4333 if (m3 == 0) {
4334 } else {
4335 if (m3 == 14) {
4336 always_goto(mkexpr(op4addr));
4337 } else {
4338 assign(op1, get_gpr_w1(r1));
4339 assign(op2, get_gpr_w1(r2));
florianff9613f2012-05-12 15:26:44 +00004340 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4341 op1, op2));
florianf321da72012-07-21 20:32:57 +00004342 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4343 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004344 }
4345 }
4346
4347 return "clrb";
4348}
4349
4350static HChar *
4351s390_irgen_CLGRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
4352{
4353 IRTemp op1 = newTemp(Ity_I64);
4354 IRTemp op2 = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00004355 IRTemp cond = newTemp(Ity_I32);
4356
4357 if (m3 == 0) {
4358 } else {
4359 if (m3 == 14) {
4360 always_goto(mkexpr(op4addr));
4361 } else {
4362 assign(op1, get_gpr_dw0(r1));
4363 assign(op2, get_gpr_dw0(r2));
florianff9613f2012-05-12 15:26:44 +00004364 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4365 op1, op2));
florianf321da72012-07-21 20:32:57 +00004366 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4367 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004368 }
4369 }
4370
4371 return "clgrb";
4372}
4373
4374static HChar *
4375s390_irgen_CLRJ(UChar r1, UChar r2, UShort i4, UChar m3)
4376{
4377 IRTemp op1 = newTemp(Ity_I32);
4378 IRTemp op2 = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00004379 IRTemp cond = newTemp(Ity_I32);
4380
4381 if (m3 == 0) {
4382 } else {
4383 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004384 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004385 } else {
4386 assign(op1, get_gpr_w1(r1));
4387 assign(op2, get_gpr_w1(r2));
florianff9613f2012-05-12 15:26:44 +00004388 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4389 op1, op2));
sewardj2019a972011-03-07 16:04:07 +00004390 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4391 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4392
4393 }
4394 }
4395
4396 return "clrj";
4397}
4398
4399static HChar *
4400s390_irgen_CLGRJ(UChar r1, UChar r2, UShort i4, UChar m3)
4401{
4402 IRTemp op1 = newTemp(Ity_I64);
4403 IRTemp op2 = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00004404 IRTemp cond = newTemp(Ity_I32);
4405
4406 if (m3 == 0) {
4407 } else {
4408 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004409 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004410 } else {
4411 assign(op1, get_gpr_dw0(r1));
4412 assign(op2, get_gpr_dw0(r2));
florianff9613f2012-05-12 15:26:44 +00004413 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4414 op1, op2));
sewardj2019a972011-03-07 16:04:07 +00004415 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4416 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4417
4418 }
4419 }
4420
4421 return "clgrj";
4422}
4423
4424static HChar *
4425s390_irgen_CLIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
4426{
4427 IRTemp op1 = newTemp(Ity_I32);
4428 UInt op2;
sewardj2019a972011-03-07 16:04:07 +00004429 IRTemp cond = newTemp(Ity_I32);
4430
4431 if (m3 == 0) {
4432 } else {
4433 if (m3 == 14) {
4434 always_goto(mkexpr(op4addr));
4435 } else {
4436 assign(op1, get_gpr_w1(r1));
4437 op2 = (UInt)i2;
florianff9613f2012-05-12 15:26:44 +00004438 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4439 mktemp(Ity_I32, mkU32(op2))));
florianf321da72012-07-21 20:32:57 +00004440 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4441 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004442 }
4443 }
4444
4445 return "clib";
4446}
4447
4448static HChar *
4449s390_irgen_CLGIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
4450{
4451 IRTemp op1 = newTemp(Ity_I64);
4452 ULong op2;
sewardj2019a972011-03-07 16:04:07 +00004453 IRTemp cond = newTemp(Ity_I32);
4454
4455 if (m3 == 0) {
4456 } else {
4457 if (m3 == 14) {
4458 always_goto(mkexpr(op4addr));
4459 } else {
4460 assign(op1, get_gpr_dw0(r1));
4461 op2 = (ULong)i2;
florianff9613f2012-05-12 15:26:44 +00004462 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4463 mktemp(Ity_I64, mkU64(op2))));
florianf321da72012-07-21 20:32:57 +00004464 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4465 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004466 }
4467 }
4468
4469 return "clgib";
4470}
4471
4472static HChar *
4473s390_irgen_CLIJ(UChar r1, UChar m3, UShort i4, UChar i2)
4474{
4475 IRTemp op1 = newTemp(Ity_I32);
4476 UInt op2;
sewardj2019a972011-03-07 16:04:07 +00004477 IRTemp cond = newTemp(Ity_I32);
4478
4479 if (m3 == 0) {
4480 } else {
4481 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004482 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004483 } else {
4484 assign(op1, get_gpr_w1(r1));
4485 op2 = (UInt)i2;
florianff9613f2012-05-12 15:26:44 +00004486 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4487 mktemp(Ity_I32, mkU32(op2))));
sewardj2019a972011-03-07 16:04:07 +00004488 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4489 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4490
4491 }
4492 }
4493
4494 return "clij";
4495}
4496
4497static HChar *
4498s390_irgen_CLGIJ(UChar r1, UChar m3, UShort i4, UChar i2)
4499{
4500 IRTemp op1 = newTemp(Ity_I64);
4501 ULong op2;
sewardj2019a972011-03-07 16:04:07 +00004502 IRTemp cond = newTemp(Ity_I32);
4503
4504 if (m3 == 0) {
4505 } else {
4506 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004507 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004508 } else {
4509 assign(op1, get_gpr_dw0(r1));
4510 op2 = (ULong)i2;
florianff9613f2012-05-12 15:26:44 +00004511 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4512 mktemp(Ity_I64, mkU64(op2))));
sewardj2019a972011-03-07 16:04:07 +00004513 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4514 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4515
4516 }
4517 }
4518
4519 return "clgij";
4520}
4521
4522static HChar *
4523s390_irgen_CLM(UChar r1, UChar r3, IRTemp op2addr)
4524{
4525 IRTemp op1 = newTemp(Ity_I32);
4526 IRTemp op2 = newTemp(Ity_I32);
4527 IRTemp b0 = newTemp(Ity_I32);
4528 IRTemp b1 = newTemp(Ity_I32);
4529 IRTemp b2 = newTemp(Ity_I32);
4530 IRTemp b3 = newTemp(Ity_I32);
4531 IRTemp c0 = newTemp(Ity_I32);
4532 IRTemp c1 = newTemp(Ity_I32);
4533 IRTemp c2 = newTemp(Ity_I32);
4534 IRTemp c3 = newTemp(Ity_I32);
4535 UChar n;
4536
4537 n = 0;
4538 if ((r3 & 8) != 0) {
4539 assign(b0, unop(Iop_8Uto32, get_gpr_b4(r1)));
4540 assign(c0, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
4541 n = n + 1;
4542 } else {
4543 assign(b0, mkU32(0));
4544 assign(c0, mkU32(0));
4545 }
4546 if ((r3 & 4) != 0) {
4547 assign(b1, unop(Iop_8Uto32, get_gpr_b5(r1)));
4548 assign(c1, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4549 mkU64(n)))));
4550 n = n + 1;
4551 } else {
4552 assign(b1, mkU32(0));
4553 assign(c1, mkU32(0));
4554 }
4555 if ((r3 & 2) != 0) {
4556 assign(b2, unop(Iop_8Uto32, get_gpr_b6(r1)));
4557 assign(c2, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4558 mkU64(n)))));
4559 n = n + 1;
4560 } else {
4561 assign(b2, mkU32(0));
4562 assign(c2, mkU32(0));
4563 }
4564 if ((r3 & 1) != 0) {
4565 assign(b3, unop(Iop_8Uto32, get_gpr_b7(r1)));
4566 assign(c3, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4567 mkU64(n)))));
4568 n = n + 1;
4569 } else {
4570 assign(b3, mkU32(0));
4571 assign(c3, mkU32(0));
4572 }
4573 assign(op1, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4574 mkexpr(b0), mkU8(24)), binop(Iop_Shl32, mkexpr(b1), mkU8(16))),
4575 binop(Iop_Shl32, mkexpr(b2), mkU8(8))), mkexpr(b3)));
4576 assign(op2, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4577 mkexpr(c0), mkU8(24)), binop(Iop_Shl32, mkexpr(c1), mkU8(16))),
4578 binop(Iop_Shl32, mkexpr(c2), mkU8(8))), mkexpr(c3)));
4579 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4580
4581 return "clm";
4582}
4583
4584static HChar *
4585s390_irgen_CLMY(UChar r1, UChar r3, IRTemp op2addr)
4586{
4587 IRTemp op1 = newTemp(Ity_I32);
4588 IRTemp op2 = newTemp(Ity_I32);
4589 IRTemp b0 = newTemp(Ity_I32);
4590 IRTemp b1 = newTemp(Ity_I32);
4591 IRTemp b2 = newTemp(Ity_I32);
4592 IRTemp b3 = newTemp(Ity_I32);
4593 IRTemp c0 = newTemp(Ity_I32);
4594 IRTemp c1 = newTemp(Ity_I32);
4595 IRTemp c2 = newTemp(Ity_I32);
4596 IRTemp c3 = newTemp(Ity_I32);
4597 UChar n;
4598
4599 n = 0;
4600 if ((r3 & 8) != 0) {
4601 assign(b0, unop(Iop_8Uto32, get_gpr_b4(r1)));
4602 assign(c0, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
4603 n = n + 1;
4604 } else {
4605 assign(b0, mkU32(0));
4606 assign(c0, mkU32(0));
4607 }
4608 if ((r3 & 4) != 0) {
4609 assign(b1, unop(Iop_8Uto32, get_gpr_b5(r1)));
4610 assign(c1, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4611 mkU64(n)))));
4612 n = n + 1;
4613 } else {
4614 assign(b1, mkU32(0));
4615 assign(c1, mkU32(0));
4616 }
4617 if ((r3 & 2) != 0) {
4618 assign(b2, unop(Iop_8Uto32, get_gpr_b6(r1)));
4619 assign(c2, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4620 mkU64(n)))));
4621 n = n + 1;
4622 } else {
4623 assign(b2, mkU32(0));
4624 assign(c2, mkU32(0));
4625 }
4626 if ((r3 & 1) != 0) {
4627 assign(b3, unop(Iop_8Uto32, get_gpr_b7(r1)));
4628 assign(c3, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4629 mkU64(n)))));
4630 n = n + 1;
4631 } else {
4632 assign(b3, mkU32(0));
4633 assign(c3, mkU32(0));
4634 }
4635 assign(op1, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4636 mkexpr(b0), mkU8(24)), binop(Iop_Shl32, mkexpr(b1), mkU8(16))),
4637 binop(Iop_Shl32, mkexpr(b2), mkU8(8))), mkexpr(b3)));
4638 assign(op2, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4639 mkexpr(c0), mkU8(24)), binop(Iop_Shl32, mkexpr(c1), mkU8(16))),
4640 binop(Iop_Shl32, mkexpr(c2), mkU8(8))), mkexpr(c3)));
4641 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4642
4643 return "clmy";
4644}
4645
4646static HChar *
4647s390_irgen_CLMH(UChar r1, UChar r3, IRTemp op2addr)
4648{
4649 IRTemp op1 = newTemp(Ity_I32);
4650 IRTemp op2 = newTemp(Ity_I32);
4651 IRTemp b0 = newTemp(Ity_I32);
4652 IRTemp b1 = newTemp(Ity_I32);
4653 IRTemp b2 = newTemp(Ity_I32);
4654 IRTemp b3 = newTemp(Ity_I32);
4655 IRTemp c0 = newTemp(Ity_I32);
4656 IRTemp c1 = newTemp(Ity_I32);
4657 IRTemp c2 = newTemp(Ity_I32);
4658 IRTemp c3 = newTemp(Ity_I32);
4659 UChar n;
4660
4661 n = 0;
4662 if ((r3 & 8) != 0) {
4663 assign(b0, unop(Iop_8Uto32, get_gpr_b0(r1)));
4664 assign(c0, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
4665 n = n + 1;
4666 } else {
4667 assign(b0, mkU32(0));
4668 assign(c0, mkU32(0));
4669 }
4670 if ((r3 & 4) != 0) {
4671 assign(b1, unop(Iop_8Uto32, get_gpr_b1(r1)));
4672 assign(c1, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4673 mkU64(n)))));
4674 n = n + 1;
4675 } else {
4676 assign(b1, mkU32(0));
4677 assign(c1, mkU32(0));
4678 }
4679 if ((r3 & 2) != 0) {
4680 assign(b2, unop(Iop_8Uto32, get_gpr_b2(r1)));
4681 assign(c2, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4682 mkU64(n)))));
4683 n = n + 1;
4684 } else {
4685 assign(b2, mkU32(0));
4686 assign(c2, mkU32(0));
4687 }
4688 if ((r3 & 1) != 0) {
4689 assign(b3, unop(Iop_8Uto32, get_gpr_b3(r1)));
4690 assign(c3, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4691 mkU64(n)))));
4692 n = n + 1;
4693 } else {
4694 assign(b3, mkU32(0));
4695 assign(c3, mkU32(0));
4696 }
4697 assign(op1, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4698 mkexpr(b0), mkU8(24)), binop(Iop_Shl32, mkexpr(b1), mkU8(16))),
4699 binop(Iop_Shl32, mkexpr(b2), mkU8(8))), mkexpr(b3)));
4700 assign(op2, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4701 mkexpr(c0), mkU8(24)), binop(Iop_Shl32, mkexpr(c1), mkU8(16))),
4702 binop(Iop_Shl32, mkexpr(c2), mkU8(8))), mkexpr(c3)));
4703 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4704
4705 return "clmh";
4706}
4707
4708static HChar *
4709s390_irgen_CLHHR(UChar r1, UChar r2)
4710{
4711 IRTemp op1 = newTemp(Ity_I32);
4712 IRTemp op2 = newTemp(Ity_I32);
4713
4714 assign(op1, get_gpr_w0(r1));
4715 assign(op2, get_gpr_w0(r2));
4716 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4717
4718 return "clhhr";
4719}
4720
4721static HChar *
4722s390_irgen_CLHLR(UChar r1, UChar r2)
4723{
4724 IRTemp op1 = newTemp(Ity_I32);
4725 IRTemp op2 = newTemp(Ity_I32);
4726
4727 assign(op1, get_gpr_w0(r1));
4728 assign(op2, get_gpr_w1(r2));
4729 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4730
4731 return "clhlr";
4732}
4733
4734static HChar *
4735s390_irgen_CLHF(UChar r1, IRTemp op2addr)
4736{
4737 IRTemp op1 = newTemp(Ity_I32);
4738 IRTemp op2 = newTemp(Ity_I32);
4739
4740 assign(op1, get_gpr_w0(r1));
4741 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4742 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4743
4744 return "clhf";
4745}
4746
4747static HChar *
4748s390_irgen_CLIH(UChar r1, UInt i2)
4749{
4750 IRTemp op1 = newTemp(Ity_I32);
4751 UInt op2;
4752
4753 assign(op1, get_gpr_w0(r1));
4754 op2 = i2;
4755 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I32,
4756 mkU32(op2)));
4757
4758 return "clih";
4759}
4760
4761static HChar *
4762s390_irgen_CPYA(UChar r1, UChar r2)
4763{
4764 put_ar_w0(r1, get_ar_w0(r2));
sewardj7ee97522011-05-09 21:45:04 +00004765 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00004766 s390_disasm(ENC3(MNM, AR, AR), "cpya", r1, r2);
4767
4768 return "cpya";
4769}
4770
4771static HChar *
4772s390_irgen_XR(UChar r1, UChar r2)
4773{
4774 IRTemp op1 = newTemp(Ity_I32);
4775 IRTemp op2 = newTemp(Ity_I32);
4776 IRTemp result = newTemp(Ity_I32);
4777
4778 if (r1 == r2) {
4779 assign(result, mkU32(0));
4780 } else {
4781 assign(op1, get_gpr_w1(r1));
4782 assign(op2, get_gpr_w1(r2));
4783 assign(result, binop(Iop_Xor32, mkexpr(op1), mkexpr(op2)));
4784 }
4785 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4786 put_gpr_w1(r1, mkexpr(result));
4787
4788 return "xr";
4789}
4790
4791static HChar *
4792s390_irgen_XGR(UChar r1, UChar r2)
4793{
4794 IRTemp op1 = newTemp(Ity_I64);
4795 IRTemp op2 = newTemp(Ity_I64);
4796 IRTemp result = newTemp(Ity_I64);
4797
4798 if (r1 == r2) {
4799 assign(result, mkU64(0));
4800 } else {
4801 assign(op1, get_gpr_dw0(r1));
4802 assign(op2, get_gpr_dw0(r2));
4803 assign(result, binop(Iop_Xor64, mkexpr(op1), mkexpr(op2)));
4804 }
4805 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4806 put_gpr_dw0(r1, mkexpr(result));
4807
4808 return "xgr";
4809}
4810
4811static HChar *
4812s390_irgen_XRK(UChar r3, UChar r1, UChar r2)
4813{
4814 IRTemp op2 = newTemp(Ity_I32);
4815 IRTemp op3 = newTemp(Ity_I32);
4816 IRTemp result = newTemp(Ity_I32);
4817
4818 assign(op2, get_gpr_w1(r2));
4819 assign(op3, get_gpr_w1(r3));
4820 assign(result, binop(Iop_Xor32, mkexpr(op2), mkexpr(op3)));
4821 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4822 put_gpr_w1(r1, mkexpr(result));
4823
4824 return "xrk";
4825}
4826
4827static HChar *
4828s390_irgen_XGRK(UChar r3, UChar r1, UChar r2)
4829{
4830 IRTemp op2 = newTemp(Ity_I64);
4831 IRTemp op3 = newTemp(Ity_I64);
4832 IRTemp result = newTemp(Ity_I64);
4833
4834 assign(op2, get_gpr_dw0(r2));
4835 assign(op3, get_gpr_dw0(r3));
4836 assign(result, binop(Iop_Xor64, mkexpr(op2), mkexpr(op3)));
4837 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4838 put_gpr_dw0(r1, mkexpr(result));
4839
4840 return "xgrk";
4841}
4842
4843static HChar *
4844s390_irgen_X(UChar r1, IRTemp op2addr)
4845{
4846 IRTemp op1 = newTemp(Ity_I32);
4847 IRTemp op2 = newTemp(Ity_I32);
4848 IRTemp result = newTemp(Ity_I32);
4849
4850 assign(op1, get_gpr_w1(r1));
4851 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4852 assign(result, binop(Iop_Xor32, mkexpr(op1), mkexpr(op2)));
4853 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4854 put_gpr_w1(r1, mkexpr(result));
4855
4856 return "x";
4857}
4858
4859static HChar *
4860s390_irgen_XY(UChar r1, IRTemp op2addr)
4861{
4862 IRTemp op1 = newTemp(Ity_I32);
4863 IRTemp op2 = newTemp(Ity_I32);
4864 IRTemp result = newTemp(Ity_I32);
4865
4866 assign(op1, get_gpr_w1(r1));
4867 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4868 assign(result, binop(Iop_Xor32, mkexpr(op1), mkexpr(op2)));
4869 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4870 put_gpr_w1(r1, mkexpr(result));
4871
4872 return "xy";
4873}
4874
4875static HChar *
4876s390_irgen_XG(UChar r1, IRTemp op2addr)
4877{
4878 IRTemp op1 = newTemp(Ity_I64);
4879 IRTemp op2 = newTemp(Ity_I64);
4880 IRTemp result = newTemp(Ity_I64);
4881
4882 assign(op1, get_gpr_dw0(r1));
4883 assign(op2, load(Ity_I64, mkexpr(op2addr)));
4884 assign(result, binop(Iop_Xor64, mkexpr(op1), mkexpr(op2)));
4885 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4886 put_gpr_dw0(r1, mkexpr(result));
4887
4888 return "xg";
4889}
4890
4891static HChar *
4892s390_irgen_XI(UChar i2, IRTemp op1addr)
4893{
4894 IRTemp op1 = newTemp(Ity_I8);
4895 UChar op2;
4896 IRTemp result = newTemp(Ity_I8);
4897
4898 assign(op1, load(Ity_I8, mkexpr(op1addr)));
4899 op2 = i2;
4900 assign(result, binop(Iop_Xor8, mkexpr(op1), mkU8(op2)));
4901 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4902 store(mkexpr(op1addr), mkexpr(result));
4903
4904 return "xi";
4905}
4906
4907static HChar *
4908s390_irgen_XIY(UChar i2, IRTemp op1addr)
4909{
4910 IRTemp op1 = newTemp(Ity_I8);
4911 UChar op2;
4912 IRTemp result = newTemp(Ity_I8);
4913
4914 assign(op1, load(Ity_I8, mkexpr(op1addr)));
4915 op2 = i2;
4916 assign(result, binop(Iop_Xor8, mkexpr(op1), mkU8(op2)));
4917 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4918 store(mkexpr(op1addr), mkexpr(result));
4919
4920 return "xiy";
4921}
4922
4923static HChar *
4924s390_irgen_XIHF(UChar r1, UInt i2)
4925{
4926 IRTemp op1 = newTemp(Ity_I32);
4927 UInt op2;
4928 IRTemp result = newTemp(Ity_I32);
4929
4930 assign(op1, get_gpr_w0(r1));
4931 op2 = i2;
4932 assign(result, binop(Iop_Xor32, mkexpr(op1), mkU32(op2)));
4933 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4934 put_gpr_w0(r1, mkexpr(result));
4935
4936 return "xihf";
4937}
4938
4939static HChar *
4940s390_irgen_XILF(UChar r1, UInt i2)
4941{
4942 IRTemp op1 = newTemp(Ity_I32);
4943 UInt op2;
4944 IRTemp result = newTemp(Ity_I32);
4945
4946 assign(op1, get_gpr_w1(r1));
4947 op2 = i2;
4948 assign(result, binop(Iop_Xor32, mkexpr(op1), mkU32(op2)));
4949 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4950 put_gpr_w1(r1, mkexpr(result));
4951
4952 return "xilf";
4953}
4954
4955static HChar *
4956s390_irgen_EAR(UChar r1, UChar r2)
4957{
4958 put_gpr_w1(r1, get_ar_w0(r2));
sewardj7ee97522011-05-09 21:45:04 +00004959 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00004960 s390_disasm(ENC3(MNM, GPR, AR), "ear", r1, r2);
4961
4962 return "ear";
4963}
4964
4965static HChar *
4966s390_irgen_IC(UChar r1, IRTemp op2addr)
4967{
4968 put_gpr_b7(r1, load(Ity_I8, mkexpr(op2addr)));
4969
4970 return "ic";
4971}
4972
4973static HChar *
4974s390_irgen_ICY(UChar r1, IRTemp op2addr)
4975{
4976 put_gpr_b7(r1, load(Ity_I8, mkexpr(op2addr)));
4977
4978 return "icy";
4979}
4980
4981static HChar *
4982s390_irgen_ICM(UChar r1, UChar r3, IRTemp op2addr)
4983{
4984 UChar n;
4985 IRTemp result = newTemp(Ity_I32);
4986 UInt mask;
4987
4988 n = 0;
4989 mask = (UInt)r3;
4990 if ((mask & 8) != 0) {
4991 put_gpr_b4(r1, load(Ity_I8, mkexpr(op2addr)));
4992 n = n + 1;
4993 }
4994 if ((mask & 4) != 0) {
4995 put_gpr_b5(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
4996
4997 n = n + 1;
4998 }
4999 if ((mask & 2) != 0) {
5000 put_gpr_b6(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5001
5002 n = n + 1;
5003 }
5004 if ((mask & 1) != 0) {
5005 put_gpr_b7(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5006
5007 n = n + 1;
5008 }
5009 assign(result, get_gpr_w1(r1));
5010 s390_cc_thunk_putZZ(S390_CC_OP_INSERT_CHAR_MASK_32, result, mktemp(Ity_I32,
5011 mkU32(mask)));
5012
5013 return "icm";
5014}
5015
5016static HChar *
5017s390_irgen_ICMY(UChar r1, UChar r3, IRTemp op2addr)
5018{
5019 UChar n;
5020 IRTemp result = newTemp(Ity_I32);
5021 UInt mask;
5022
5023 n = 0;
5024 mask = (UInt)r3;
5025 if ((mask & 8) != 0) {
5026 put_gpr_b4(r1, load(Ity_I8, mkexpr(op2addr)));
5027 n = n + 1;
5028 }
5029 if ((mask & 4) != 0) {
5030 put_gpr_b5(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5031
5032 n = n + 1;
5033 }
5034 if ((mask & 2) != 0) {
5035 put_gpr_b6(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5036
5037 n = n + 1;
5038 }
5039 if ((mask & 1) != 0) {
5040 put_gpr_b7(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5041
5042 n = n + 1;
5043 }
5044 assign(result, get_gpr_w1(r1));
5045 s390_cc_thunk_putZZ(S390_CC_OP_INSERT_CHAR_MASK_32, result, mktemp(Ity_I32,
5046 mkU32(mask)));
5047
5048 return "icmy";
5049}
5050
5051static HChar *
5052s390_irgen_ICMH(UChar r1, UChar r3, IRTemp op2addr)
5053{
5054 UChar n;
5055 IRTemp result = newTemp(Ity_I32);
5056 UInt mask;
5057
5058 n = 0;
5059 mask = (UInt)r3;
5060 if ((mask & 8) != 0) {
5061 put_gpr_b0(r1, load(Ity_I8, mkexpr(op2addr)));
5062 n = n + 1;
5063 }
5064 if ((mask & 4) != 0) {
5065 put_gpr_b1(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5066
5067 n = n + 1;
5068 }
5069 if ((mask & 2) != 0) {
5070 put_gpr_b2(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5071
5072 n = n + 1;
5073 }
5074 if ((mask & 1) != 0) {
5075 put_gpr_b3(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5076
5077 n = n + 1;
5078 }
5079 assign(result, get_gpr_w0(r1));
5080 s390_cc_thunk_putZZ(S390_CC_OP_INSERT_CHAR_MASK_32, result, mktemp(Ity_I32,
5081 mkU32(mask)));
5082
5083 return "icmh";
5084}
5085
5086static HChar *
5087s390_irgen_IIHF(UChar r1, UInt i2)
5088{
5089 put_gpr_w0(r1, mkU32(i2));
5090
5091 return "iihf";
5092}
5093
5094static HChar *
5095s390_irgen_IIHH(UChar r1, UShort i2)
5096{
5097 put_gpr_hw0(r1, mkU16(i2));
5098
5099 return "iihh";
5100}
5101
5102static HChar *
5103s390_irgen_IIHL(UChar r1, UShort i2)
5104{
5105 put_gpr_hw1(r1, mkU16(i2));
5106
5107 return "iihl";
5108}
5109
5110static HChar *
5111s390_irgen_IILF(UChar r1, UInt i2)
5112{
5113 put_gpr_w1(r1, mkU32(i2));
5114
5115 return "iilf";
5116}
5117
5118static HChar *
5119s390_irgen_IILH(UChar r1, UShort i2)
5120{
5121 put_gpr_hw2(r1, mkU16(i2));
5122
5123 return "iilh";
5124}
5125
5126static HChar *
5127s390_irgen_IILL(UChar r1, UShort i2)
5128{
5129 put_gpr_hw3(r1, mkU16(i2));
5130
5131 return "iill";
5132}
5133
5134static HChar *
5135s390_irgen_LR(UChar r1, UChar r2)
5136{
5137 put_gpr_w1(r1, get_gpr_w1(r2));
5138
5139 return "lr";
5140}
5141
5142static HChar *
5143s390_irgen_LGR(UChar r1, UChar r2)
5144{
5145 put_gpr_dw0(r1, get_gpr_dw0(r2));
5146
5147 return "lgr";
5148}
5149
5150static HChar *
5151s390_irgen_LGFR(UChar r1, UChar r2)
5152{
5153 put_gpr_dw0(r1, unop(Iop_32Sto64, get_gpr_w1(r2)));
5154
5155 return "lgfr";
5156}
5157
5158static HChar *
5159s390_irgen_L(UChar r1, IRTemp op2addr)
5160{
5161 put_gpr_w1(r1, load(Ity_I32, mkexpr(op2addr)));
5162
5163 return "l";
5164}
5165
5166static HChar *
5167s390_irgen_LY(UChar r1, IRTemp op2addr)
5168{
5169 put_gpr_w1(r1, load(Ity_I32, mkexpr(op2addr)));
5170
5171 return "ly";
5172}
5173
5174static HChar *
5175s390_irgen_LG(UChar r1, IRTemp op2addr)
5176{
5177 put_gpr_dw0(r1, load(Ity_I64, mkexpr(op2addr)));
5178
5179 return "lg";
5180}
5181
5182static HChar *
5183s390_irgen_LGF(UChar r1, IRTemp op2addr)
5184{
5185 put_gpr_dw0(r1, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
5186
5187 return "lgf";
5188}
5189
5190static HChar *
5191s390_irgen_LGFI(UChar r1, UInt i2)
5192{
5193 put_gpr_dw0(r1, mkU64((ULong)(Long)(Int)i2));
5194
5195 return "lgfi";
5196}
5197
5198static HChar *
5199s390_irgen_LRL(UChar r1, UInt i2)
5200{
5201 put_gpr_w1(r1, load(Ity_I32, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
5202 i2 << 1))));
5203
5204 return "lrl";
5205}
5206
5207static HChar *
5208s390_irgen_LGRL(UChar r1, UInt i2)
5209{
5210 put_gpr_dw0(r1, load(Ity_I64, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
5211 i2 << 1))));
5212
5213 return "lgrl";
5214}
5215
5216static HChar *
5217s390_irgen_LGFRL(UChar r1, UInt i2)
5218{
5219 put_gpr_dw0(r1, unop(Iop_32Sto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
5220 ((ULong)(Long)(Int)i2 << 1)))));
5221
5222 return "lgfrl";
5223}
5224
5225static HChar *
5226s390_irgen_LA(UChar r1, IRTemp op2addr)
5227{
5228 put_gpr_dw0(r1, mkexpr(op2addr));
5229
5230 return "la";
5231}
5232
5233static HChar *
5234s390_irgen_LAY(UChar r1, IRTemp op2addr)
5235{
5236 put_gpr_dw0(r1, mkexpr(op2addr));
5237
5238 return "lay";
5239}
5240
5241static HChar *
5242s390_irgen_LAE(UChar r1, IRTemp op2addr)
5243{
5244 put_gpr_dw0(r1, mkexpr(op2addr));
5245
5246 return "lae";
5247}
5248
5249static HChar *
5250s390_irgen_LAEY(UChar r1, IRTemp op2addr)
5251{
5252 put_gpr_dw0(r1, mkexpr(op2addr));
5253
5254 return "laey";
5255}
5256
5257static HChar *
5258s390_irgen_LARL(UChar r1, UInt i2)
5259{
5260 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)));
5261
5262 return "larl";
5263}
5264
5265static HChar *
5266s390_irgen_LAA(UChar r1, UChar r3, IRTemp op2addr)
5267{
5268 IRTemp op2 = newTemp(Ity_I32);
5269 IRTemp op3 = newTemp(Ity_I32);
5270 IRTemp result = newTemp(Ity_I32);
5271
5272 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5273 assign(op3, get_gpr_w1(r3));
5274 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
5275 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
5276 store(mkexpr(op2addr), mkexpr(result));
5277 put_gpr_w1(r1, mkexpr(op2));
5278
5279 return "laa";
5280}
5281
5282static HChar *
5283s390_irgen_LAAG(UChar r1, UChar r3, IRTemp op2addr)
5284{
5285 IRTemp op2 = newTemp(Ity_I64);
5286 IRTemp op3 = newTemp(Ity_I64);
5287 IRTemp result = newTemp(Ity_I64);
5288
5289 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5290 assign(op3, get_gpr_dw0(r3));
5291 assign(result, binop(Iop_Add64, mkexpr(op2), mkexpr(op3)));
5292 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op2, op3);
5293 store(mkexpr(op2addr), mkexpr(result));
5294 put_gpr_dw0(r1, mkexpr(op2));
5295
5296 return "laag";
5297}
5298
5299static HChar *
5300s390_irgen_LAAL(UChar r1, UChar r3, IRTemp op2addr)
5301{
5302 IRTemp op2 = newTemp(Ity_I32);
5303 IRTemp op3 = newTemp(Ity_I32);
5304 IRTemp result = newTemp(Ity_I32);
5305
5306 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5307 assign(op3, get_gpr_w1(r3));
5308 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
5309 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
5310 store(mkexpr(op2addr), mkexpr(result));
5311 put_gpr_w1(r1, mkexpr(op2));
5312
5313 return "laal";
5314}
5315
5316static HChar *
5317s390_irgen_LAALG(UChar r1, UChar r3, IRTemp op2addr)
5318{
5319 IRTemp op2 = newTemp(Ity_I64);
5320 IRTemp op3 = newTemp(Ity_I64);
5321 IRTemp result = newTemp(Ity_I64);
5322
5323 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5324 assign(op3, get_gpr_dw0(r3));
5325 assign(result, binop(Iop_Add64, mkexpr(op2), mkexpr(op3)));
5326 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op2, op3);
5327 store(mkexpr(op2addr), mkexpr(result));
5328 put_gpr_dw0(r1, mkexpr(op2));
5329
5330 return "laalg";
5331}
5332
5333static HChar *
5334s390_irgen_LAN(UChar r1, UChar r3, IRTemp op2addr)
5335{
5336 IRTemp op2 = newTemp(Ity_I32);
5337 IRTemp op3 = newTemp(Ity_I32);
5338 IRTemp result = newTemp(Ity_I32);
5339
5340 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5341 assign(op3, get_gpr_w1(r3));
5342 assign(result, binop(Iop_And32, mkexpr(op2), mkexpr(op3)));
5343 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5344 store(mkexpr(op2addr), mkexpr(result));
5345 put_gpr_w1(r1, mkexpr(op2));
5346
5347 return "lan";
5348}
5349
5350static HChar *
5351s390_irgen_LANG(UChar r1, UChar r3, IRTemp op2addr)
5352{
5353 IRTemp op2 = newTemp(Ity_I64);
5354 IRTemp op3 = newTemp(Ity_I64);
5355 IRTemp result = newTemp(Ity_I64);
5356
5357 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5358 assign(op3, get_gpr_dw0(r3));
5359 assign(result, binop(Iop_And64, mkexpr(op2), mkexpr(op3)));
5360 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5361 store(mkexpr(op2addr), mkexpr(result));
5362 put_gpr_dw0(r1, mkexpr(op2));
5363
5364 return "lang";
5365}
5366
5367static HChar *
5368s390_irgen_LAX(UChar r1, UChar r3, IRTemp op2addr)
5369{
5370 IRTemp op2 = newTemp(Ity_I32);
5371 IRTemp op3 = newTemp(Ity_I32);
5372 IRTemp result = newTemp(Ity_I32);
5373
5374 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5375 assign(op3, get_gpr_w1(r3));
5376 assign(result, binop(Iop_Xor32, mkexpr(op2), mkexpr(op3)));
5377 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5378 store(mkexpr(op2addr), mkexpr(result));
5379 put_gpr_w1(r1, mkexpr(op2));
5380
5381 return "lax";
5382}
5383
5384static HChar *
5385s390_irgen_LAXG(UChar r1, UChar r3, IRTemp op2addr)
5386{
5387 IRTemp op2 = newTemp(Ity_I64);
5388 IRTemp op3 = newTemp(Ity_I64);
5389 IRTemp result = newTemp(Ity_I64);
5390
5391 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5392 assign(op3, get_gpr_dw0(r3));
5393 assign(result, binop(Iop_Xor64, mkexpr(op2), mkexpr(op3)));
5394 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5395 store(mkexpr(op2addr), mkexpr(result));
5396 put_gpr_dw0(r1, mkexpr(op2));
5397
5398 return "laxg";
5399}
5400
5401static HChar *
5402s390_irgen_LAO(UChar r1, UChar r3, IRTemp op2addr)
5403{
5404 IRTemp op2 = newTemp(Ity_I32);
5405 IRTemp op3 = newTemp(Ity_I32);
5406 IRTemp result = newTemp(Ity_I32);
5407
5408 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5409 assign(op3, get_gpr_w1(r3));
5410 assign(result, binop(Iop_Or32, mkexpr(op2), mkexpr(op3)));
5411 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5412 store(mkexpr(op2addr), mkexpr(result));
5413 put_gpr_w1(r1, mkexpr(op2));
5414
5415 return "lao";
5416}
5417
5418static HChar *
5419s390_irgen_LAOG(UChar r1, UChar r3, IRTemp op2addr)
5420{
5421 IRTemp op2 = newTemp(Ity_I64);
5422 IRTemp op3 = newTemp(Ity_I64);
5423 IRTemp result = newTemp(Ity_I64);
5424
5425 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5426 assign(op3, get_gpr_dw0(r3));
5427 assign(result, binop(Iop_Or64, mkexpr(op2), mkexpr(op3)));
5428 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5429 store(mkexpr(op2addr), mkexpr(result));
5430 put_gpr_dw0(r1, mkexpr(op2));
5431
5432 return "laog";
5433}
5434
5435static HChar *
5436s390_irgen_LTR(UChar r1, UChar r2)
5437{
5438 IRTemp op2 = newTemp(Ity_I32);
5439
5440 assign(op2, get_gpr_w1(r2));
5441 put_gpr_w1(r1, mkexpr(op2));
5442 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5443
5444 return "ltr";
5445}
5446
5447static HChar *
5448s390_irgen_LTGR(UChar r1, UChar r2)
5449{
5450 IRTemp op2 = newTemp(Ity_I64);
5451
5452 assign(op2, get_gpr_dw0(r2));
5453 put_gpr_dw0(r1, mkexpr(op2));
5454 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5455
5456 return "ltgr";
5457}
5458
5459static HChar *
5460s390_irgen_LTGFR(UChar r1, UChar r2)
5461{
5462 IRTemp op2 = newTemp(Ity_I64);
5463
5464 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
5465 put_gpr_dw0(r1, mkexpr(op2));
5466 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5467
5468 return "ltgfr";
5469}
5470
5471static HChar *
5472s390_irgen_LT(UChar r1, IRTemp op2addr)
5473{
5474 IRTemp op2 = newTemp(Ity_I32);
5475
5476 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5477 put_gpr_w1(r1, mkexpr(op2));
5478 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5479
5480 return "lt";
5481}
5482
5483static HChar *
5484s390_irgen_LTG(UChar r1, IRTemp op2addr)
5485{
5486 IRTemp op2 = newTemp(Ity_I64);
5487
5488 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5489 put_gpr_dw0(r1, mkexpr(op2));
5490 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5491
5492 return "ltg";
5493}
5494
5495static HChar *
5496s390_irgen_LTGF(UChar r1, IRTemp op2addr)
5497{
5498 IRTemp op2 = newTemp(Ity_I64);
5499
5500 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
5501 put_gpr_dw0(r1, mkexpr(op2));
5502 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5503
5504 return "ltgf";
5505}
5506
5507static HChar *
5508s390_irgen_LBR(UChar r1, UChar r2)
5509{
5510 put_gpr_w1(r1, unop(Iop_8Sto32, get_gpr_b7(r2)));
5511
5512 return "lbr";
5513}
5514
5515static HChar *
5516s390_irgen_LGBR(UChar r1, UChar r2)
5517{
5518 put_gpr_dw0(r1, unop(Iop_8Sto64, get_gpr_b7(r2)));
5519
5520 return "lgbr";
5521}
5522
5523static HChar *
5524s390_irgen_LB(UChar r1, IRTemp op2addr)
5525{
5526 put_gpr_w1(r1, unop(Iop_8Sto32, load(Ity_I8, mkexpr(op2addr))));
5527
5528 return "lb";
5529}
5530
5531static HChar *
5532s390_irgen_LGB(UChar r1, IRTemp op2addr)
5533{
5534 put_gpr_dw0(r1, unop(Iop_8Sto64, load(Ity_I8, mkexpr(op2addr))));
5535
5536 return "lgb";
5537}
5538
5539static HChar *
5540s390_irgen_LBH(UChar r1, IRTemp op2addr)
5541{
5542 put_gpr_w0(r1, unop(Iop_8Sto32, load(Ity_I8, mkexpr(op2addr))));
5543
5544 return "lbh";
5545}
5546
5547static HChar *
5548s390_irgen_LCR(UChar r1, UChar r2)
5549{
5550 Int op1;
5551 IRTemp op2 = newTemp(Ity_I32);
5552 IRTemp result = newTemp(Ity_I32);
5553
5554 op1 = 0;
5555 assign(op2, get_gpr_w1(r2));
5556 assign(result, binop(Iop_Sub32, mkU32((UInt)op1), mkexpr(op2)));
5557 put_gpr_w1(r1, mkexpr(result));
5558 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, mktemp(Ity_I32, mkU32((UInt)
5559 op1)), op2);
5560
5561 return "lcr";
5562}
5563
5564static HChar *
5565s390_irgen_LCGR(UChar r1, UChar r2)
5566{
5567 Long op1;
5568 IRTemp op2 = newTemp(Ity_I64);
5569 IRTemp result = newTemp(Ity_I64);
5570
5571 op1 = 0ULL;
5572 assign(op2, get_gpr_dw0(r2));
5573 assign(result, binop(Iop_Sub64, mkU64((ULong)op1), mkexpr(op2)));
5574 put_gpr_dw0(r1, mkexpr(result));
5575 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, mktemp(Ity_I64, mkU64((ULong)
5576 op1)), op2);
5577
5578 return "lcgr";
5579}
5580
5581static HChar *
5582s390_irgen_LCGFR(UChar r1, UChar r2)
5583{
5584 Long op1;
5585 IRTemp op2 = newTemp(Ity_I64);
5586 IRTemp result = newTemp(Ity_I64);
5587
5588 op1 = 0ULL;
5589 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
5590 assign(result, binop(Iop_Sub64, mkU64((ULong)op1), mkexpr(op2)));
5591 put_gpr_dw0(r1, mkexpr(result));
5592 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, mktemp(Ity_I64, mkU64((ULong)
5593 op1)), op2);
5594
5595 return "lcgfr";
5596}
5597
5598static HChar *
5599s390_irgen_LHR(UChar r1, UChar r2)
5600{
5601 put_gpr_w1(r1, unop(Iop_16Sto32, get_gpr_hw3(r2)));
5602
5603 return "lhr";
5604}
5605
5606static HChar *
5607s390_irgen_LGHR(UChar r1, UChar r2)
5608{
5609 put_gpr_dw0(r1, unop(Iop_16Sto64, get_gpr_hw3(r2)));
5610
5611 return "lghr";
5612}
5613
5614static HChar *
5615s390_irgen_LH(UChar r1, IRTemp op2addr)
5616{
5617 put_gpr_w1(r1, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
5618
5619 return "lh";
5620}
5621
5622static HChar *
5623s390_irgen_LHY(UChar r1, IRTemp op2addr)
5624{
5625 put_gpr_w1(r1, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
5626
5627 return "lhy";
5628}
5629
5630static HChar *
5631s390_irgen_LGH(UChar r1, IRTemp op2addr)
5632{
5633 put_gpr_dw0(r1, unop(Iop_16Sto64, load(Ity_I16, mkexpr(op2addr))));
5634
5635 return "lgh";
5636}
5637
5638static HChar *
5639s390_irgen_LHI(UChar r1, UShort i2)
5640{
5641 put_gpr_w1(r1, mkU32((UInt)(Int)(Short)i2));
5642
5643 return "lhi";
5644}
5645
5646static HChar *
5647s390_irgen_LGHI(UChar r1, UShort i2)
5648{
5649 put_gpr_dw0(r1, mkU64((ULong)(Long)(Short)i2));
5650
5651 return "lghi";
5652}
5653
5654static HChar *
5655s390_irgen_LHRL(UChar r1, UInt i2)
5656{
5657 put_gpr_w1(r1, unop(Iop_16Sto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
5658 ((ULong)(Long)(Int)i2 << 1)))));
5659
5660 return "lhrl";
5661}
5662
5663static HChar *
5664s390_irgen_LGHRL(UChar r1, UInt i2)
5665{
5666 put_gpr_dw0(r1, unop(Iop_16Sto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
5667 ((ULong)(Long)(Int)i2 << 1)))));
5668
5669 return "lghrl";
5670}
5671
5672static HChar *
5673s390_irgen_LHH(UChar r1, IRTemp op2addr)
5674{
5675 put_gpr_w0(r1, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
5676
5677 return "lhh";
5678}
5679
5680static HChar *
5681s390_irgen_LFH(UChar r1, IRTemp op2addr)
5682{
5683 put_gpr_w0(r1, load(Ity_I32, mkexpr(op2addr)));
5684
5685 return "lfh";
5686}
5687
5688static HChar *
5689s390_irgen_LLGFR(UChar r1, UChar r2)
5690{
5691 put_gpr_dw0(r1, unop(Iop_32Uto64, get_gpr_w1(r2)));
5692
5693 return "llgfr";
5694}
5695
5696static HChar *
5697s390_irgen_LLGF(UChar r1, IRTemp op2addr)
5698{
5699 put_gpr_dw0(r1, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
5700
5701 return "llgf";
5702}
5703
5704static HChar *
5705s390_irgen_LLGFRL(UChar r1, UInt i2)
5706{
5707 put_gpr_dw0(r1, unop(Iop_32Uto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
5708 ((ULong)(Long)(Int)i2 << 1)))));
5709
5710 return "llgfrl";
5711}
5712
5713static HChar *
5714s390_irgen_LLCR(UChar r1, UChar r2)
5715{
5716 put_gpr_w1(r1, unop(Iop_8Uto32, get_gpr_b7(r2)));
5717
5718 return "llcr";
5719}
5720
5721static HChar *
5722s390_irgen_LLGCR(UChar r1, UChar r2)
5723{
5724 put_gpr_dw0(r1, unop(Iop_8Uto64, get_gpr_b7(r2)));
5725
5726 return "llgcr";
5727}
5728
5729static HChar *
5730s390_irgen_LLC(UChar r1, IRTemp op2addr)
5731{
5732 put_gpr_w1(r1, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
5733
5734 return "llc";
5735}
5736
5737static HChar *
5738s390_irgen_LLGC(UChar r1, IRTemp op2addr)
5739{
5740 put_gpr_dw0(r1, unop(Iop_8Uto64, load(Ity_I8, mkexpr(op2addr))));
5741
5742 return "llgc";
5743}
5744
5745static HChar *
5746s390_irgen_LLCH(UChar r1, IRTemp op2addr)
5747{
5748 put_gpr_w0(r1, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
5749
5750 return "llch";
5751}
5752
5753static HChar *
5754s390_irgen_LLHR(UChar r1, UChar r2)
5755{
5756 put_gpr_w1(r1, unop(Iop_16Uto32, get_gpr_hw3(r2)));
5757
5758 return "llhr";
5759}
5760
5761static HChar *
5762s390_irgen_LLGHR(UChar r1, UChar r2)
5763{
5764 put_gpr_dw0(r1, unop(Iop_16Uto64, get_gpr_hw3(r2)));
5765
5766 return "llghr";
5767}
5768
5769static HChar *
5770s390_irgen_LLH(UChar r1, IRTemp op2addr)
5771{
5772 put_gpr_w1(r1, unop(Iop_16Uto32, load(Ity_I16, mkexpr(op2addr))));
5773
5774 return "llh";
5775}
5776
5777static HChar *
5778s390_irgen_LLGH(UChar r1, IRTemp op2addr)
5779{
5780 put_gpr_dw0(r1, unop(Iop_16Uto64, load(Ity_I16, mkexpr(op2addr))));
5781
5782 return "llgh";
5783}
5784
5785static HChar *
5786s390_irgen_LLHRL(UChar r1, UInt i2)
5787{
5788 put_gpr_w1(r1, unop(Iop_16Uto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
5789 ((ULong)(Long)(Int)i2 << 1)))));
5790
5791 return "llhrl";
5792}
5793
5794static HChar *
5795s390_irgen_LLGHRL(UChar r1, UInt i2)
5796{
5797 put_gpr_dw0(r1, unop(Iop_16Uto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
5798 ((ULong)(Long)(Int)i2 << 1)))));
5799
5800 return "llghrl";
5801}
5802
5803static HChar *
5804s390_irgen_LLHH(UChar r1, IRTemp op2addr)
5805{
5806 put_gpr_w0(r1, unop(Iop_16Uto32, load(Ity_I16, mkexpr(op2addr))));
5807
5808 return "llhh";
5809}
5810
5811static HChar *
5812s390_irgen_LLIHF(UChar r1, UInt i2)
5813{
5814 put_gpr_dw0(r1, mkU64(((ULong)i2) << 32));
5815
5816 return "llihf";
5817}
5818
5819static HChar *
5820s390_irgen_LLIHH(UChar r1, UShort i2)
5821{
5822 put_gpr_dw0(r1, mkU64(((ULong)i2) << 48));
5823
5824 return "llihh";
5825}
5826
5827static HChar *
5828s390_irgen_LLIHL(UChar r1, UShort i2)
5829{
5830 put_gpr_dw0(r1, mkU64(((ULong)i2) << 32));
5831
5832 return "llihl";
5833}
5834
5835static HChar *
5836s390_irgen_LLILF(UChar r1, UInt i2)
5837{
5838 put_gpr_dw0(r1, mkU64(i2));
5839
5840 return "llilf";
5841}
5842
5843static HChar *
5844s390_irgen_LLILH(UChar r1, UShort i2)
5845{
5846 put_gpr_dw0(r1, mkU64(((ULong)i2) << 16));
5847
5848 return "llilh";
5849}
5850
5851static HChar *
5852s390_irgen_LLILL(UChar r1, UShort i2)
5853{
5854 put_gpr_dw0(r1, mkU64(i2));
5855
5856 return "llill";
5857}
5858
5859static HChar *
5860s390_irgen_LLGTR(UChar r1, UChar r2)
5861{
5862 put_gpr_dw0(r1, unop(Iop_32Uto64, binop(Iop_And32, get_gpr_w1(r2),
5863 mkU32(2147483647))));
5864
5865 return "llgtr";
5866}
5867
5868static HChar *
5869s390_irgen_LLGT(UChar r1, IRTemp op2addr)
5870{
5871 put_gpr_dw0(r1, unop(Iop_32Uto64, binop(Iop_And32, load(Ity_I32,
5872 mkexpr(op2addr)), mkU32(2147483647))));
5873
5874 return "llgt";
5875}
5876
5877static HChar *
5878s390_irgen_LNR(UChar r1, UChar r2)
5879{
5880 IRTemp op2 = newTemp(Ity_I32);
5881 IRTemp result = newTemp(Ity_I32);
5882
5883 assign(op2, get_gpr_w1(r2));
5884 assign(result, mkite(binop(Iop_CmpLE32S, mkexpr(op2), mkU32(0)), mkexpr(op2),
5885 binop(Iop_Sub32, mkU32(0), mkexpr(op2))));
5886 put_gpr_w1(r1, mkexpr(result));
5887 s390_cc_thunk_putS(S390_CC_OP_BITWISE, result);
5888
5889 return "lnr";
5890}
5891
5892static HChar *
5893s390_irgen_LNGR(UChar r1, UChar r2)
5894{
5895 IRTemp op2 = newTemp(Ity_I64);
5896 IRTemp result = newTemp(Ity_I64);
5897
5898 assign(op2, get_gpr_dw0(r2));
5899 assign(result, mkite(binop(Iop_CmpLE64S, mkexpr(op2), mkU64(0)), mkexpr(op2),
5900 binop(Iop_Sub64, mkU64(0), mkexpr(op2))));
5901 put_gpr_dw0(r1, mkexpr(result));
5902 s390_cc_thunk_putS(S390_CC_OP_BITWISE, result);
5903
5904 return "lngr";
5905}
5906
5907static HChar *
5908s390_irgen_LNGFR(UChar r1, UChar r2 __attribute__((unused)))
5909{
5910 IRTemp op2 = newTemp(Ity_I64);
5911 IRTemp result = newTemp(Ity_I64);
5912
5913 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r1)));
5914 assign(result, mkite(binop(Iop_CmpLE64S, mkexpr(op2), mkU64(0)), mkexpr(op2),
5915 binop(Iop_Sub64, mkU64(0), mkexpr(op2))));
5916 put_gpr_dw0(r1, mkexpr(result));
5917 s390_cc_thunk_putS(S390_CC_OP_BITWISE, result);
5918
5919 return "lngfr";
5920}
5921
5922static HChar *
sewardjd7bde722011-04-05 13:19:33 +00005923s390_irgen_LOCR(UChar m3, UChar r1, UChar r2)
5924{
florian6820ba52012-07-26 02:01:50 +00005925 next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0)));
sewardjd7bde722011-04-05 13:19:33 +00005926 put_gpr_w1(r1, get_gpr_w1(r2));
5927
5928 return "locr";
5929}
5930
5931static HChar *
5932s390_irgen_LOCGR(UChar m3, UChar r1, UChar r2)
5933{
florian6820ba52012-07-26 02:01:50 +00005934 next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0)));
sewardjd7bde722011-04-05 13:19:33 +00005935 put_gpr_dw0(r1, get_gpr_dw0(r2));
5936
5937 return "locgr";
5938}
5939
5940static HChar *
5941s390_irgen_LOC(UChar r1, IRTemp op2addr)
5942{
5943 /* condition is checked in format handler */
5944 put_gpr_w1(r1, load(Ity_I32, mkexpr(op2addr)));
5945
5946 return "loc";
5947}
5948
5949static HChar *
5950s390_irgen_LOCG(UChar r1, IRTemp op2addr)
5951{
5952 /* condition is checked in format handler */
5953 put_gpr_dw0(r1, load(Ity_I64, mkexpr(op2addr)));
5954
5955 return "locg";
5956}
5957
5958static HChar *
sewardj2019a972011-03-07 16:04:07 +00005959s390_irgen_LPQ(UChar r1, IRTemp op2addr)
5960{
5961 put_gpr_dw0(r1, load(Ity_I64, mkexpr(op2addr)));
5962 put_gpr_dw0(r1 + 1, load(Ity_I64, binop(Iop_Add64, mkexpr(op2addr), mkU64(8))
5963 ));
5964
5965 return "lpq";
5966}
5967
5968static HChar *
5969s390_irgen_LPR(UChar r1, UChar r2)
5970{
5971 IRTemp op2 = newTemp(Ity_I32);
5972 IRTemp result = newTemp(Ity_I32);
5973
5974 assign(op2, get_gpr_w1(r2));
5975 assign(result, mkite(binop(Iop_CmpLT32S, mkexpr(op2), mkU32(0)),
5976 binop(Iop_Sub32, mkU32(0), mkexpr(op2)), mkexpr(op2)));
5977 put_gpr_w1(r1, mkexpr(result));
5978 s390_cc_thunk_putS(S390_CC_OP_LOAD_POSITIVE_32, op2);
5979
5980 return "lpr";
5981}
5982
5983static HChar *
5984s390_irgen_LPGR(UChar r1, UChar r2)
5985{
5986 IRTemp op2 = newTemp(Ity_I64);
5987 IRTemp result = newTemp(Ity_I64);
5988
5989 assign(op2, get_gpr_dw0(r2));
5990 assign(result, mkite(binop(Iop_CmpLT64S, mkexpr(op2), mkU64(0)),
5991 binop(Iop_Sub64, mkU64(0), mkexpr(op2)), mkexpr(op2)));
5992 put_gpr_dw0(r1, mkexpr(result));
5993 s390_cc_thunk_putS(S390_CC_OP_LOAD_POSITIVE_64, op2);
5994
5995 return "lpgr";
5996}
5997
5998static HChar *
5999s390_irgen_LPGFR(UChar r1, UChar r2)
6000{
6001 IRTemp op2 = newTemp(Ity_I64);
6002 IRTemp result = newTemp(Ity_I64);
6003
6004 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
6005 assign(result, mkite(binop(Iop_CmpLT64S, mkexpr(op2), mkU64(0)),
6006 binop(Iop_Sub64, mkU64(0), mkexpr(op2)), mkexpr(op2)));
6007 put_gpr_dw0(r1, mkexpr(result));
6008 s390_cc_thunk_putS(S390_CC_OP_LOAD_POSITIVE_64, op2);
6009
6010 return "lpgfr";
6011}
6012
6013static HChar *
6014s390_irgen_LRVR(UChar r1, UChar r2)
6015{
6016 IRTemp b0 = newTemp(Ity_I8);
6017 IRTemp b1 = newTemp(Ity_I8);
6018 IRTemp b2 = newTemp(Ity_I8);
6019 IRTemp b3 = newTemp(Ity_I8);
6020
6021 assign(b3, get_gpr_b7(r2));
6022 assign(b2, get_gpr_b6(r2));
6023 assign(b1, get_gpr_b5(r2));
6024 assign(b0, get_gpr_b4(r2));
6025 put_gpr_b4(r1, mkexpr(b3));
6026 put_gpr_b5(r1, mkexpr(b2));
6027 put_gpr_b6(r1, mkexpr(b1));
6028 put_gpr_b7(r1, mkexpr(b0));
6029
6030 return "lrvr";
6031}
6032
6033static HChar *
6034s390_irgen_LRVGR(UChar r1, UChar r2)
6035{
6036 IRTemp b0 = newTemp(Ity_I8);
6037 IRTemp b1 = newTemp(Ity_I8);
6038 IRTemp b2 = newTemp(Ity_I8);
6039 IRTemp b3 = newTemp(Ity_I8);
6040 IRTemp b4 = newTemp(Ity_I8);
6041 IRTemp b5 = newTemp(Ity_I8);
6042 IRTemp b6 = newTemp(Ity_I8);
6043 IRTemp b7 = newTemp(Ity_I8);
6044
6045 assign(b7, get_gpr_b7(r2));
6046 assign(b6, get_gpr_b6(r2));
6047 assign(b5, get_gpr_b5(r2));
6048 assign(b4, get_gpr_b4(r2));
6049 assign(b3, get_gpr_b3(r2));
6050 assign(b2, get_gpr_b2(r2));
6051 assign(b1, get_gpr_b1(r2));
6052 assign(b0, get_gpr_b0(r2));
6053 put_gpr_b0(r1, mkexpr(b7));
6054 put_gpr_b1(r1, mkexpr(b6));
6055 put_gpr_b2(r1, mkexpr(b5));
6056 put_gpr_b3(r1, mkexpr(b4));
6057 put_gpr_b4(r1, mkexpr(b3));
6058 put_gpr_b5(r1, mkexpr(b2));
6059 put_gpr_b6(r1, mkexpr(b1));
6060 put_gpr_b7(r1, mkexpr(b0));
6061
6062 return "lrvgr";
6063}
6064
6065static HChar *
6066s390_irgen_LRVH(UChar r1, IRTemp op2addr)
6067{
6068 IRTemp op2 = newTemp(Ity_I16);
6069
6070 assign(op2, load(Ity_I16, mkexpr(op2addr)));
6071 put_gpr_b6(r1, unop(Iop_16to8, mkexpr(op2)));
6072 put_gpr_b7(r1, unop(Iop_16HIto8, mkexpr(op2)));
6073
6074 return "lrvh";
6075}
6076
6077static HChar *
6078s390_irgen_LRV(UChar r1, IRTemp op2addr)
6079{
6080 IRTemp op2 = newTemp(Ity_I32);
6081
6082 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6083 put_gpr_b4(r1, unop(Iop_32to8, binop(Iop_And32, mkexpr(op2), mkU32(255))));
6084 put_gpr_b5(r1, unop(Iop_32to8, binop(Iop_And32, binop(Iop_Shr32, mkexpr(op2),
6085 mkU8(8)), mkU32(255))));
6086 put_gpr_b6(r1, unop(Iop_32to8, binop(Iop_And32, binop(Iop_Shr32, mkexpr(op2),
6087 mkU8(16)), mkU32(255))));
6088 put_gpr_b7(r1, unop(Iop_32to8, binop(Iop_And32, binop(Iop_Shr32, mkexpr(op2),
6089 mkU8(24)), mkU32(255))));
6090
6091 return "lrv";
6092}
6093
6094static HChar *
6095s390_irgen_LRVG(UChar r1, IRTemp op2addr)
6096{
6097 IRTemp op2 = newTemp(Ity_I64);
6098
6099 assign(op2, load(Ity_I64, mkexpr(op2addr)));
6100 put_gpr_b0(r1, unop(Iop_64to8, binop(Iop_And64, mkexpr(op2), mkU64(255))));
6101 put_gpr_b1(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6102 mkU8(8)), mkU64(255))));
6103 put_gpr_b2(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6104 mkU8(16)), mkU64(255))));
6105 put_gpr_b3(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6106 mkU8(24)), mkU64(255))));
6107 put_gpr_b4(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6108 mkU8(32)), mkU64(255))));
6109 put_gpr_b5(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6110 mkU8(40)), mkU64(255))));
6111 put_gpr_b6(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6112 mkU8(48)), mkU64(255))));
6113 put_gpr_b7(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6114 mkU8(56)), mkU64(255))));
6115
6116 return "lrvg";
6117}
6118
6119static HChar *
6120s390_irgen_MVHHI(UShort i2, IRTemp op1addr)
6121{
6122 store(mkexpr(op1addr), mkU16(i2));
6123
6124 return "mvhhi";
6125}
6126
6127static HChar *
6128s390_irgen_MVHI(UShort i2, IRTemp op1addr)
6129{
6130 store(mkexpr(op1addr), mkU32((UInt)(Int)(Short)i2));
6131
6132 return "mvhi";
6133}
6134
6135static HChar *
6136s390_irgen_MVGHI(UShort i2, IRTemp op1addr)
6137{
6138 store(mkexpr(op1addr), mkU64((ULong)(Long)(Short)i2));
6139
6140 return "mvghi";
6141}
6142
6143static HChar *
6144s390_irgen_MVI(UChar i2, IRTemp op1addr)
6145{
6146 store(mkexpr(op1addr), mkU8(i2));
6147
6148 return "mvi";
6149}
6150
6151static HChar *
6152s390_irgen_MVIY(UChar i2, IRTemp op1addr)
6153{
6154 store(mkexpr(op1addr), mkU8(i2));
6155
6156 return "mviy";
6157}
6158
6159static HChar *
6160s390_irgen_MR(UChar r1, UChar r2)
6161{
6162 IRTemp op1 = newTemp(Ity_I32);
6163 IRTemp op2 = newTemp(Ity_I32);
6164 IRTemp result = newTemp(Ity_I64);
6165
6166 assign(op1, get_gpr_w1(r1 + 1));
6167 assign(op2, get_gpr_w1(r2));
6168 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6169 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6170 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6171
6172 return "mr";
6173}
6174
6175static HChar *
6176s390_irgen_M(UChar r1, IRTemp op2addr)
6177{
6178 IRTemp op1 = newTemp(Ity_I32);
6179 IRTemp op2 = newTemp(Ity_I32);
6180 IRTemp result = newTemp(Ity_I64);
6181
6182 assign(op1, get_gpr_w1(r1 + 1));
6183 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6184 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6185 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6186 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6187
6188 return "m";
6189}
6190
6191static HChar *
6192s390_irgen_MFY(UChar r1, IRTemp op2addr)
6193{
6194 IRTemp op1 = newTemp(Ity_I32);
6195 IRTemp op2 = newTemp(Ity_I32);
6196 IRTemp result = newTemp(Ity_I64);
6197
6198 assign(op1, get_gpr_w1(r1 + 1));
6199 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6200 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6201 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6202 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6203
6204 return "mfy";
6205}
6206
6207static HChar *
6208s390_irgen_MH(UChar r1, IRTemp op2addr)
6209{
6210 IRTemp op1 = newTemp(Ity_I32);
6211 IRTemp op2 = newTemp(Ity_I16);
6212 IRTemp result = newTemp(Ity_I64);
6213
6214 assign(op1, get_gpr_w1(r1));
6215 assign(op2, load(Ity_I16, mkexpr(op2addr)));
6216 assign(result, binop(Iop_MullS32, mkexpr(op1), unop(Iop_16Sto32, mkexpr(op2))
6217 ));
6218 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6219
6220 return "mh";
6221}
6222
6223static HChar *
6224s390_irgen_MHY(UChar r1, IRTemp op2addr)
6225{
6226 IRTemp op1 = newTemp(Ity_I32);
6227 IRTemp op2 = newTemp(Ity_I16);
6228 IRTemp result = newTemp(Ity_I64);
6229
6230 assign(op1, get_gpr_w1(r1));
6231 assign(op2, load(Ity_I16, mkexpr(op2addr)));
6232 assign(result, binop(Iop_MullS32, mkexpr(op1), unop(Iop_16Sto32, mkexpr(op2))
6233 ));
6234 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6235
6236 return "mhy";
6237}
6238
6239static HChar *
6240s390_irgen_MHI(UChar r1, UShort i2)
6241{
6242 IRTemp op1 = newTemp(Ity_I32);
6243 Short op2;
6244 IRTemp result = newTemp(Ity_I64);
6245
6246 assign(op1, get_gpr_w1(r1));
6247 op2 = (Short)i2;
6248 assign(result, binop(Iop_MullS32, mkexpr(op1), unop(Iop_16Sto32,
6249 mkU16((UShort)op2))));
6250 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6251
6252 return "mhi";
6253}
6254
6255static HChar *
6256s390_irgen_MGHI(UChar r1, UShort i2)
6257{
6258 IRTemp op1 = newTemp(Ity_I64);
6259 Short op2;
6260 IRTemp result = newTemp(Ity_I128);
6261
6262 assign(op1, get_gpr_dw0(r1));
6263 op2 = (Short)i2;
6264 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_16Sto64,
6265 mkU16((UShort)op2))));
6266 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6267
6268 return "mghi";
6269}
6270
6271static HChar *
6272s390_irgen_MLR(UChar r1, UChar r2)
6273{
6274 IRTemp op1 = newTemp(Ity_I32);
6275 IRTemp op2 = newTemp(Ity_I32);
6276 IRTemp result = newTemp(Ity_I64);
6277
6278 assign(op1, get_gpr_w1(r1 + 1));
6279 assign(op2, get_gpr_w1(r2));
6280 assign(result, binop(Iop_MullU32, mkexpr(op1), mkexpr(op2)));
6281 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6282 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6283
6284 return "mlr";
6285}
6286
6287static HChar *
6288s390_irgen_MLGR(UChar r1, UChar r2)
6289{
6290 IRTemp op1 = newTemp(Ity_I64);
6291 IRTemp op2 = newTemp(Ity_I64);
6292 IRTemp result = newTemp(Ity_I128);
6293
6294 assign(op1, get_gpr_dw0(r1 + 1));
6295 assign(op2, get_gpr_dw0(r2));
6296 assign(result, binop(Iop_MullU64, mkexpr(op1), mkexpr(op2)));
6297 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result)));
6298 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result)));
6299
6300 return "mlgr";
6301}
6302
6303static HChar *
6304s390_irgen_ML(UChar r1, IRTemp op2addr)
6305{
6306 IRTemp op1 = newTemp(Ity_I32);
6307 IRTemp op2 = newTemp(Ity_I32);
6308 IRTemp result = newTemp(Ity_I64);
6309
6310 assign(op1, get_gpr_w1(r1 + 1));
6311 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6312 assign(result, binop(Iop_MullU32, mkexpr(op1), mkexpr(op2)));
6313 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6314 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6315
6316 return "ml";
6317}
6318
6319static HChar *
6320s390_irgen_MLG(UChar r1, IRTemp op2addr)
6321{
6322 IRTemp op1 = newTemp(Ity_I64);
6323 IRTemp op2 = newTemp(Ity_I64);
6324 IRTemp result = newTemp(Ity_I128);
6325
6326 assign(op1, get_gpr_dw0(r1 + 1));
6327 assign(op2, load(Ity_I64, mkexpr(op2addr)));
6328 assign(result, binop(Iop_MullU64, mkexpr(op1), mkexpr(op2)));
6329 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result)));
6330 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result)));
6331
6332 return "mlg";
6333}
6334
6335static HChar *
6336s390_irgen_MSR(UChar r1, UChar r2)
6337{
6338 IRTemp op1 = newTemp(Ity_I32);
6339 IRTemp op2 = newTemp(Ity_I32);
6340 IRTemp result = newTemp(Ity_I64);
6341
6342 assign(op1, get_gpr_w1(r1));
6343 assign(op2, get_gpr_w1(r2));
6344 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6345 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6346
6347 return "msr";
6348}
6349
6350static HChar *
6351s390_irgen_MSGR(UChar r1, UChar r2)
6352{
6353 IRTemp op1 = newTemp(Ity_I64);
6354 IRTemp op2 = newTemp(Ity_I64);
6355 IRTemp result = newTemp(Ity_I128);
6356
6357 assign(op1, get_gpr_dw0(r1));
6358 assign(op2, get_gpr_dw0(r2));
6359 assign(result, binop(Iop_MullS64, mkexpr(op1), mkexpr(op2)));
6360 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6361
6362 return "msgr";
6363}
6364
6365static HChar *
6366s390_irgen_MSGFR(UChar r1, UChar r2)
6367{
6368 IRTemp op1 = newTemp(Ity_I64);
6369 IRTemp op2 = newTemp(Ity_I32);
6370 IRTemp result = newTemp(Ity_I128);
6371
6372 assign(op1, get_gpr_dw0(r1));
6373 assign(op2, get_gpr_w1(r2));
6374 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_32Sto64, mkexpr(op2))
6375 ));
6376 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6377
6378 return "msgfr";
6379}
6380
6381static HChar *
6382s390_irgen_MS(UChar r1, IRTemp op2addr)
6383{
6384 IRTemp op1 = newTemp(Ity_I32);
6385 IRTemp op2 = newTemp(Ity_I32);
6386 IRTemp result = newTemp(Ity_I64);
6387
6388 assign(op1, get_gpr_w1(r1));
6389 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6390 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6391 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6392
6393 return "ms";
6394}
6395
6396static HChar *
6397s390_irgen_MSY(UChar r1, IRTemp op2addr)
6398{
6399 IRTemp op1 = newTemp(Ity_I32);
6400 IRTemp op2 = newTemp(Ity_I32);
6401 IRTemp result = newTemp(Ity_I64);
6402
6403 assign(op1, get_gpr_w1(r1));
6404 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6405 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6406 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6407
6408 return "msy";
6409}
6410
6411static HChar *
6412s390_irgen_MSG(UChar r1, IRTemp op2addr)
6413{
6414 IRTemp op1 = newTemp(Ity_I64);
6415 IRTemp op2 = newTemp(Ity_I64);
6416 IRTemp result = newTemp(Ity_I128);
6417
6418 assign(op1, get_gpr_dw0(r1));
6419 assign(op2, load(Ity_I64, mkexpr(op2addr)));
6420 assign(result, binop(Iop_MullS64, mkexpr(op1), mkexpr(op2)));
6421 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6422
6423 return "msg";
6424}
6425
6426static HChar *
6427s390_irgen_MSGF(UChar r1, IRTemp op2addr)
6428{
6429 IRTemp op1 = newTemp(Ity_I64);
6430 IRTemp op2 = newTemp(Ity_I32);
6431 IRTemp result = newTemp(Ity_I128);
6432
6433 assign(op1, get_gpr_dw0(r1));
6434 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6435 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_32Sto64, mkexpr(op2))
6436 ));
6437 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6438
6439 return "msgf";
6440}
6441
6442static HChar *
6443s390_irgen_MSFI(UChar r1, UInt i2)
6444{
6445 IRTemp op1 = newTemp(Ity_I32);
6446 Int op2;
6447 IRTemp result = newTemp(Ity_I64);
6448
6449 assign(op1, get_gpr_w1(r1));
6450 op2 = (Int)i2;
6451 assign(result, binop(Iop_MullS32, mkexpr(op1), mkU32((UInt)op2)));
6452 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6453
6454 return "msfi";
6455}
6456
6457static HChar *
6458s390_irgen_MSGFI(UChar r1, UInt i2)
6459{
6460 IRTemp op1 = newTemp(Ity_I64);
6461 Int op2;
6462 IRTemp result = newTemp(Ity_I128);
6463
6464 assign(op1, get_gpr_dw0(r1));
6465 op2 = (Int)i2;
6466 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_32Sto64, mkU32((UInt)
6467 op2))));
6468 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6469
6470 return "msgfi";
6471}
6472
6473static HChar *
6474s390_irgen_OR(UChar r1, UChar r2)
6475{
6476 IRTemp op1 = newTemp(Ity_I32);
6477 IRTemp op2 = newTemp(Ity_I32);
6478 IRTemp result = newTemp(Ity_I32);
6479
6480 assign(op1, get_gpr_w1(r1));
6481 assign(op2, get_gpr_w1(r2));
6482 assign(result, binop(Iop_Or32, mkexpr(op1), mkexpr(op2)));
6483 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6484 put_gpr_w1(r1, mkexpr(result));
6485
6486 return "or";
6487}
6488
6489static HChar *
6490s390_irgen_OGR(UChar r1, UChar r2)
6491{
6492 IRTemp op1 = newTemp(Ity_I64);
6493 IRTemp op2 = newTemp(Ity_I64);
6494 IRTemp result = newTemp(Ity_I64);
6495
6496 assign(op1, get_gpr_dw0(r1));
6497 assign(op2, get_gpr_dw0(r2));
6498 assign(result, binop(Iop_Or64, mkexpr(op1), mkexpr(op2)));
6499 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6500 put_gpr_dw0(r1, mkexpr(result));
6501
6502 return "ogr";
6503}
6504
6505static HChar *
6506s390_irgen_ORK(UChar r3, UChar r1, UChar r2)
6507{
6508 IRTemp op2 = newTemp(Ity_I32);
6509 IRTemp op3 = newTemp(Ity_I32);
6510 IRTemp result = newTemp(Ity_I32);
6511
6512 assign(op2, get_gpr_w1(r2));
6513 assign(op3, get_gpr_w1(r3));
6514 assign(result, binop(Iop_Or32, mkexpr(op2), mkexpr(op3)));
6515 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6516 put_gpr_w1(r1, mkexpr(result));
6517
6518 return "ork";
6519}
6520
6521static HChar *
6522s390_irgen_OGRK(UChar r3, UChar r1, UChar r2)
6523{
6524 IRTemp op2 = newTemp(Ity_I64);
6525 IRTemp op3 = newTemp(Ity_I64);
6526 IRTemp result = newTemp(Ity_I64);
6527
6528 assign(op2, get_gpr_dw0(r2));
6529 assign(op3, get_gpr_dw0(r3));
6530 assign(result, binop(Iop_Or64, mkexpr(op2), mkexpr(op3)));
6531 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6532 put_gpr_dw0(r1, mkexpr(result));
6533
6534 return "ogrk";
6535}
6536
6537static HChar *
6538s390_irgen_O(UChar r1, IRTemp op2addr)
6539{
6540 IRTemp op1 = newTemp(Ity_I32);
6541 IRTemp op2 = newTemp(Ity_I32);
6542 IRTemp result = newTemp(Ity_I32);
6543
6544 assign(op1, get_gpr_w1(r1));
6545 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6546 assign(result, binop(Iop_Or32, mkexpr(op1), mkexpr(op2)));
6547 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6548 put_gpr_w1(r1, mkexpr(result));
6549
6550 return "o";
6551}
6552
6553static HChar *
6554s390_irgen_OY(UChar r1, IRTemp op2addr)
6555{
6556 IRTemp op1 = newTemp(Ity_I32);
6557 IRTemp op2 = newTemp(Ity_I32);
6558 IRTemp result = newTemp(Ity_I32);
6559
6560 assign(op1, get_gpr_w1(r1));
6561 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6562 assign(result, binop(Iop_Or32, mkexpr(op1), mkexpr(op2)));
6563 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6564 put_gpr_w1(r1, mkexpr(result));
6565
6566 return "oy";
6567}
6568
6569static HChar *
6570s390_irgen_OG(UChar r1, IRTemp op2addr)
6571{
6572 IRTemp op1 = newTemp(Ity_I64);
6573 IRTemp op2 = newTemp(Ity_I64);
6574 IRTemp result = newTemp(Ity_I64);
6575
6576 assign(op1, get_gpr_dw0(r1));
6577 assign(op2, load(Ity_I64, mkexpr(op2addr)));
6578 assign(result, binop(Iop_Or64, mkexpr(op1), mkexpr(op2)));
6579 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6580 put_gpr_dw0(r1, mkexpr(result));
6581
6582 return "og";
6583}
6584
6585static HChar *
6586s390_irgen_OI(UChar i2, IRTemp op1addr)
6587{
6588 IRTemp op1 = newTemp(Ity_I8);
6589 UChar op2;
6590 IRTemp result = newTemp(Ity_I8);
6591
6592 assign(op1, load(Ity_I8, mkexpr(op1addr)));
6593 op2 = i2;
6594 assign(result, binop(Iop_Or8, mkexpr(op1), mkU8(op2)));
6595 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6596 store(mkexpr(op1addr), mkexpr(result));
6597
6598 return "oi";
6599}
6600
6601static HChar *
6602s390_irgen_OIY(UChar i2, IRTemp op1addr)
6603{
6604 IRTemp op1 = newTemp(Ity_I8);
6605 UChar op2;
6606 IRTemp result = newTemp(Ity_I8);
6607
6608 assign(op1, load(Ity_I8, mkexpr(op1addr)));
6609 op2 = i2;
6610 assign(result, binop(Iop_Or8, mkexpr(op1), mkU8(op2)));
6611 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6612 store(mkexpr(op1addr), mkexpr(result));
6613
6614 return "oiy";
6615}
6616
6617static HChar *
6618s390_irgen_OIHF(UChar r1, UInt i2)
6619{
6620 IRTemp op1 = newTemp(Ity_I32);
6621 UInt op2;
6622 IRTemp result = newTemp(Ity_I32);
6623
6624 assign(op1, get_gpr_w0(r1));
6625 op2 = i2;
6626 assign(result, binop(Iop_Or32, mkexpr(op1), mkU32(op2)));
6627 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6628 put_gpr_w0(r1, mkexpr(result));
6629
6630 return "oihf";
6631}
6632
6633static HChar *
6634s390_irgen_OIHH(UChar r1, UShort i2)
6635{
6636 IRTemp op1 = newTemp(Ity_I16);
6637 UShort op2;
6638 IRTemp result = newTemp(Ity_I16);
6639
6640 assign(op1, get_gpr_hw0(r1));
6641 op2 = i2;
6642 assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
6643 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6644 put_gpr_hw0(r1, mkexpr(result));
6645
6646 return "oihh";
6647}
6648
6649static HChar *
6650s390_irgen_OIHL(UChar r1, UShort i2)
6651{
6652 IRTemp op1 = newTemp(Ity_I16);
6653 UShort op2;
6654 IRTemp result = newTemp(Ity_I16);
6655
6656 assign(op1, get_gpr_hw1(r1));
6657 op2 = i2;
6658 assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
6659 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6660 put_gpr_hw1(r1, mkexpr(result));
6661
6662 return "oihl";
6663}
6664
6665static HChar *
6666s390_irgen_OILF(UChar r1, UInt i2)
6667{
6668 IRTemp op1 = newTemp(Ity_I32);
6669 UInt op2;
6670 IRTemp result = newTemp(Ity_I32);
6671
6672 assign(op1, get_gpr_w1(r1));
6673 op2 = i2;
6674 assign(result, binop(Iop_Or32, mkexpr(op1), mkU32(op2)));
6675 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6676 put_gpr_w1(r1, mkexpr(result));
6677
6678 return "oilf";
6679}
6680
6681static HChar *
6682s390_irgen_OILH(UChar r1, UShort i2)
6683{
6684 IRTemp op1 = newTemp(Ity_I16);
6685 UShort op2;
6686 IRTemp result = newTemp(Ity_I16);
6687
6688 assign(op1, get_gpr_hw2(r1));
6689 op2 = i2;
6690 assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
6691 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6692 put_gpr_hw2(r1, mkexpr(result));
6693
6694 return "oilh";
6695}
6696
6697static HChar *
6698s390_irgen_OILL(UChar r1, UShort i2)
6699{
6700 IRTemp op1 = newTemp(Ity_I16);
6701 UShort op2;
6702 IRTemp result = newTemp(Ity_I16);
6703
6704 assign(op1, get_gpr_hw3(r1));
6705 op2 = i2;
6706 assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
6707 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6708 put_gpr_hw3(r1, mkexpr(result));
6709
6710 return "oill";
6711}
6712
6713static HChar *
6714s390_irgen_PFD(void)
6715{
6716
6717 return "pfd";
6718}
6719
6720static HChar *
6721s390_irgen_PFDRL(void)
6722{
6723
6724 return "pfdrl";
6725}
6726
6727static HChar *
6728s390_irgen_RLL(UChar r1, UChar r3, IRTemp op2addr)
6729{
6730 IRTemp amount = newTemp(Ity_I64);
6731 IRTemp op = newTemp(Ity_I32);
6732
6733 assign(amount, binop(Iop_And64, mkexpr(op2addr), mkU64(31)));
6734 assign(op, get_gpr_w1(r3));
6735 put_gpr_w1(r1, binop(Iop_Or32, binop(Iop_Shl32, mkexpr(op), unop(Iop_64to8,
6736 mkexpr(amount))), binop(Iop_Shr32, mkexpr(op), unop(Iop_64to8,
6737 binop(Iop_Sub64, mkU64(32), mkexpr(amount))))));
6738
6739 return "rll";
6740}
6741
6742static HChar *
6743s390_irgen_RLLG(UChar r1, UChar r3, IRTemp op2addr)
6744{
6745 IRTemp amount = newTemp(Ity_I64);
6746 IRTemp op = newTemp(Ity_I64);
6747
6748 assign(amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
6749 assign(op, get_gpr_dw0(r3));
6750 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(op), unop(Iop_64to8,
6751 mkexpr(amount))), binop(Iop_Shr64, mkexpr(op), unop(Iop_64to8,
6752 binop(Iop_Sub64, mkU64(64), mkexpr(amount))))));
6753
6754 return "rllg";
6755}
6756
6757static HChar *
6758s390_irgen_RNSBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
6759{
6760 UChar from;
6761 UChar to;
6762 UChar rot;
6763 UChar t_bit;
6764 ULong mask;
6765 ULong maskc;
6766 IRTemp result = newTemp(Ity_I64);
6767 IRTemp op2 = newTemp(Ity_I64);
6768
6769 from = i3 & 63;
6770 to = i4 & 63;
6771 rot = i5 & 63;
6772 t_bit = i3 & 128;
6773 assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
6774 get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
6775 mkU8(64 - rot))));
6776 if (from <= to) {
6777 mask = ~0ULL;
6778 mask = (mask >> from) & (mask << (63 - to));
6779 maskc = ~mask;
6780 } else {
6781 maskc = ~0ULL;
6782 maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
6783 mask = ~maskc;
6784 }
6785 assign(result, binop(Iop_And64, binop(Iop_And64, get_gpr_dw0(r1), mkexpr(op2)
6786 ), mkU64(mask)));
6787 if (t_bit == 0) {
6788 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
6789 mkU64(maskc)), mkexpr(result)));
6790 }
6791 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6792
6793 return "rnsbg";
6794}
6795
6796static HChar *
6797s390_irgen_RXSBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
6798{
6799 UChar from;
6800 UChar to;
6801 UChar rot;
6802 UChar t_bit;
6803 ULong mask;
6804 ULong maskc;
6805 IRTemp result = newTemp(Ity_I64);
6806 IRTemp op2 = newTemp(Ity_I64);
6807
6808 from = i3 & 63;
6809 to = i4 & 63;
6810 rot = i5 & 63;
6811 t_bit = i3 & 128;
6812 assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
6813 get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
6814 mkU8(64 - rot))));
6815 if (from <= to) {
6816 mask = ~0ULL;
6817 mask = (mask >> from) & (mask << (63 - to));
6818 maskc = ~mask;
6819 } else {
6820 maskc = ~0ULL;
6821 maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
6822 mask = ~maskc;
6823 }
6824 assign(result, binop(Iop_And64, binop(Iop_Xor64, get_gpr_dw0(r1), mkexpr(op2)
6825 ), mkU64(mask)));
6826 if (t_bit == 0) {
6827 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
6828 mkU64(maskc)), mkexpr(result)));
6829 }
6830 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6831
6832 return "rxsbg";
6833}
6834
6835static HChar *
6836s390_irgen_ROSBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
6837{
6838 UChar from;
6839 UChar to;
6840 UChar rot;
6841 UChar t_bit;
6842 ULong mask;
6843 ULong maskc;
6844 IRTemp result = newTemp(Ity_I64);
6845 IRTemp op2 = newTemp(Ity_I64);
6846
6847 from = i3 & 63;
6848 to = i4 & 63;
6849 rot = i5 & 63;
6850 t_bit = i3 & 128;
6851 assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
6852 get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
6853 mkU8(64 - rot))));
6854 if (from <= to) {
6855 mask = ~0ULL;
6856 mask = (mask >> from) & (mask << (63 - to));
6857 maskc = ~mask;
6858 } else {
6859 maskc = ~0ULL;
6860 maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
6861 mask = ~maskc;
6862 }
6863 assign(result, binop(Iop_And64, binop(Iop_Or64, get_gpr_dw0(r1), mkexpr(op2)
6864 ), mkU64(mask)));
6865 if (t_bit == 0) {
6866 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
6867 mkU64(maskc)), mkexpr(result)));
6868 }
6869 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6870
6871 return "rosbg";
6872}
6873
6874static HChar *
6875s390_irgen_RISBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
6876{
6877 UChar from;
6878 UChar to;
6879 UChar rot;
6880 UChar z_bit;
6881 ULong mask;
6882 ULong maskc;
6883 IRTemp op2 = newTemp(Ity_I64);
6884 IRTemp result = newTemp(Ity_I64);
6885
6886 from = i3 & 63;
6887 to = i4 & 63;
6888 rot = i5 & 63;
6889 z_bit = i4 & 128;
6890 assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
6891 get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
6892 mkU8(64 - rot))));
6893 if (from <= to) {
6894 mask = ~0ULL;
6895 mask = (mask >> from) & (mask << (63 - to));
6896 maskc = ~mask;
6897 } else {
6898 maskc = ~0ULL;
6899 maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
6900 mask = ~maskc;
6901 }
6902 if (z_bit == 0) {
6903 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
6904 mkU64(maskc)), binop(Iop_And64, mkexpr(op2), mkU64(mask))));
6905 } else {
6906 put_gpr_dw0(r1, binop(Iop_And64, mkexpr(op2), mkU64(mask)));
6907 }
6908 assign(result, get_gpr_dw0(r1));
6909 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
6910
6911 return "risbg";
6912}
6913
6914static HChar *
6915s390_irgen_SAR(UChar r1, UChar r2)
6916{
6917 put_ar_w0(r1, get_gpr_w1(r2));
sewardj7ee97522011-05-09 21:45:04 +00006918 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00006919 s390_disasm(ENC3(MNM, AR, GPR), "sar", r1, r2);
6920
6921 return "sar";
6922}
6923
6924static HChar *
6925s390_irgen_SLDA(UChar r1, IRTemp op2addr)
6926{
6927 IRTemp p1 = newTemp(Ity_I64);
6928 IRTemp p2 = newTemp(Ity_I64);
6929 IRTemp op = newTemp(Ity_I64);
6930 IRTemp result = newTemp(Ity_I64);
florian417b22d2012-07-13 13:41:41 +00006931 ULong sign_mask;
sewardj2019a972011-03-07 16:04:07 +00006932 IRTemp shift_amount = newTemp(Ity_I64);
6933
6934 assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
6935 assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
6936 assign(op, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1), mkU8(32)), mkexpr(p2)
6937 ));
6938 sign_mask = 1ULL << 63;
6939 assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
6940 assign(result, binop(Iop_Or64, binop(Iop_And64, binop(Iop_Shl64, mkexpr(op),
florian417b22d2012-07-13 13:41:41 +00006941 unop(Iop_64to8, mkexpr(shift_amount))), mkU64(~sign_mask)),
6942 binop(Iop_And64, mkexpr(op), mkU64(sign_mask))));
sewardj2019a972011-03-07 16:04:07 +00006943 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6944 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6945 s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_64, op, shift_amount);
6946
6947 return "slda";
6948}
6949
6950static HChar *
6951s390_irgen_SLDL(UChar r1, IRTemp op2addr)
6952{
6953 IRTemp p1 = newTemp(Ity_I64);
6954 IRTemp p2 = newTemp(Ity_I64);
6955 IRTemp result = newTemp(Ity_I64);
6956
6957 assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
6958 assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
6959 assign(result, binop(Iop_Shl64, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1),
6960 mkU8(32)), mkexpr(p2)), unop(Iop_64to8, binop(Iop_And64,
6961 mkexpr(op2addr), mkU64(63)))));
6962 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6963 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6964
6965 return "sldl";
6966}
6967
6968static HChar *
6969s390_irgen_SLA(UChar r1, IRTemp op2addr)
6970{
6971 IRTemp uop = newTemp(Ity_I32);
6972 IRTemp result = newTemp(Ity_I32);
6973 UInt sign_mask;
6974 IRTemp shift_amount = newTemp(Ity_I64);
6975 IRTemp op = newTemp(Ity_I32);
6976
6977 assign(op, get_gpr_w1(r1));
6978 assign(uop, get_gpr_w1(r1));
6979 sign_mask = 2147483648U;
6980 assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
6981 assign(result, binop(Iop_Or32, binop(Iop_And32, binop(Iop_Shl32, mkexpr(uop),
6982 unop(Iop_64to8, mkexpr(shift_amount))), mkU32(~sign_mask)),
6983 binop(Iop_And32, mkexpr(uop), mkU32(sign_mask))));
6984 put_gpr_w1(r1, mkexpr(result));
6985 s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_32, op, shift_amount);
6986
6987 return "sla";
6988}
6989
6990static HChar *
6991s390_irgen_SLAK(UChar r1, UChar r3, IRTemp op2addr)
6992{
6993 IRTemp uop = newTemp(Ity_I32);
6994 IRTemp result = newTemp(Ity_I32);
6995 UInt sign_mask;
6996 IRTemp shift_amount = newTemp(Ity_I64);
6997 IRTemp op = newTemp(Ity_I32);
6998
6999 assign(op, get_gpr_w1(r3));
7000 assign(uop, get_gpr_w1(r3));
7001 sign_mask = 2147483648U;
7002 assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7003 assign(result, binop(Iop_Or32, binop(Iop_And32, binop(Iop_Shl32, mkexpr(uop),
7004 unop(Iop_64to8, mkexpr(shift_amount))), mkU32(~sign_mask)),
7005 binop(Iop_And32, mkexpr(uop), mkU32(sign_mask))));
7006 put_gpr_w1(r1, mkexpr(result));
7007 s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_32, op, shift_amount);
7008
7009 return "slak";
7010}
7011
7012static HChar *
7013s390_irgen_SLAG(UChar r1, UChar r3, IRTemp op2addr)
7014{
7015 IRTemp uop = newTemp(Ity_I64);
7016 IRTemp result = newTemp(Ity_I64);
7017 ULong sign_mask;
7018 IRTemp shift_amount = newTemp(Ity_I64);
7019 IRTemp op = newTemp(Ity_I64);
7020
7021 assign(op, get_gpr_dw0(r3));
7022 assign(uop, get_gpr_dw0(r3));
7023 sign_mask = 9223372036854775808ULL;
7024 assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7025 assign(result, binop(Iop_Or64, binop(Iop_And64, binop(Iop_Shl64, mkexpr(uop),
7026 unop(Iop_64to8, mkexpr(shift_amount))), mkU64(~sign_mask)),
7027 binop(Iop_And64, mkexpr(uop), mkU64(sign_mask))));
7028 put_gpr_dw0(r1, mkexpr(result));
7029 s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_64, op, shift_amount);
7030
7031 return "slag";
7032}
7033
7034static HChar *
7035s390_irgen_SLL(UChar r1, IRTemp op2addr)
7036{
7037 put_gpr_w1(r1, binop(Iop_Shl32, get_gpr_w1(r1), unop(Iop_64to8,
7038 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
7039
7040 return "sll";
7041}
7042
7043static HChar *
7044s390_irgen_SLLK(UChar r1, UChar r3, IRTemp op2addr)
7045{
7046 put_gpr_w1(r1, binop(Iop_Shl32, get_gpr_w1(r3), unop(Iop_64to8,
7047 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
7048
7049 return "sllk";
7050}
7051
7052static HChar *
7053s390_irgen_SLLG(UChar r1, UChar r3, IRTemp op2addr)
7054{
7055 put_gpr_dw0(r1, binop(Iop_Shl64, get_gpr_dw0(r3), unop(Iop_64to8,
7056 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
7057
7058 return "sllg";
7059}
7060
7061static HChar *
7062s390_irgen_SRDA(UChar r1, IRTemp op2addr)
7063{
7064 IRTemp p1 = newTemp(Ity_I64);
7065 IRTemp p2 = newTemp(Ity_I64);
7066 IRTemp result = newTemp(Ity_I64);
7067
7068 assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
7069 assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
7070 assign(result, binop(Iop_Sar64, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1),
7071 mkU8(32)), mkexpr(p2)), unop(Iop_64to8, binop(Iop_And64,
7072 mkexpr(op2addr), mkU64(63)))));
7073 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
7074 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
7075 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7076
7077 return "srda";
7078}
7079
7080static HChar *
7081s390_irgen_SRDL(UChar r1, IRTemp op2addr)
7082{
7083 IRTemp p1 = newTemp(Ity_I64);
7084 IRTemp p2 = newTemp(Ity_I64);
7085 IRTemp result = newTemp(Ity_I64);
7086
7087 assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
7088 assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
7089 assign(result, binop(Iop_Shr64, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1),
7090 mkU8(32)), mkexpr(p2)), unop(Iop_64to8, binop(Iop_And64,
7091 mkexpr(op2addr), mkU64(63)))));
7092 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
7093 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
7094
7095 return "srdl";
7096}
7097
7098static HChar *
7099s390_irgen_SRA(UChar r1, IRTemp op2addr)
7100{
7101 IRTemp result = newTemp(Ity_I32);
7102 IRTemp op = newTemp(Ity_I32);
7103
7104 assign(op, get_gpr_w1(r1));
7105 assign(result, binop(Iop_Sar32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7106 mkexpr(op2addr), mkU64(63)))));
7107 put_gpr_w1(r1, mkexpr(result));
7108 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7109
7110 return "sra";
7111}
7112
7113static HChar *
7114s390_irgen_SRAK(UChar r1, UChar r3, IRTemp op2addr)
7115{
7116 IRTemp result = newTemp(Ity_I32);
7117 IRTemp op = newTemp(Ity_I32);
7118
7119 assign(op, get_gpr_w1(r3));
7120 assign(result, binop(Iop_Sar32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7121 mkexpr(op2addr), mkU64(63)))));
7122 put_gpr_w1(r1, mkexpr(result));
7123 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7124
7125 return "srak";
7126}
7127
7128static HChar *
7129s390_irgen_SRAG(UChar r1, UChar r3, IRTemp op2addr)
7130{
7131 IRTemp result = newTemp(Ity_I64);
7132 IRTemp op = newTemp(Ity_I64);
7133
7134 assign(op, get_gpr_dw0(r3));
7135 assign(result, binop(Iop_Sar64, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7136 mkexpr(op2addr), mkU64(63)))));
7137 put_gpr_dw0(r1, mkexpr(result));
7138 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7139
7140 return "srag";
7141}
7142
7143static HChar *
7144s390_irgen_SRL(UChar r1, IRTemp op2addr)
7145{
7146 IRTemp op = newTemp(Ity_I32);
7147
7148 assign(op, get_gpr_w1(r1));
7149 put_gpr_w1(r1, binop(Iop_Shr32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7150 mkexpr(op2addr), mkU64(63)))));
7151
7152 return "srl";
7153}
7154
7155static HChar *
7156s390_irgen_SRLK(UChar r1, UChar r3, IRTemp op2addr)
7157{
7158 IRTemp op = newTemp(Ity_I32);
7159
7160 assign(op, get_gpr_w1(r3));
7161 put_gpr_w1(r1, binop(Iop_Shr32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7162 mkexpr(op2addr), mkU64(63)))));
7163
7164 return "srlk";
7165}
7166
7167static HChar *
7168s390_irgen_SRLG(UChar r1, UChar r3, IRTemp op2addr)
7169{
7170 IRTemp op = newTemp(Ity_I64);
7171
7172 assign(op, get_gpr_dw0(r3));
7173 put_gpr_dw0(r1, binop(Iop_Shr64, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7174 mkexpr(op2addr), mkU64(63)))));
7175
7176 return "srlg";
7177}
7178
7179static HChar *
7180s390_irgen_ST(UChar r1, IRTemp op2addr)
7181{
7182 store(mkexpr(op2addr), get_gpr_w1(r1));
7183
7184 return "st";
7185}
7186
7187static HChar *
7188s390_irgen_STY(UChar r1, IRTemp op2addr)
7189{
7190 store(mkexpr(op2addr), get_gpr_w1(r1));
7191
7192 return "sty";
7193}
7194
7195static HChar *
7196s390_irgen_STG(UChar r1, IRTemp op2addr)
7197{
7198 store(mkexpr(op2addr), get_gpr_dw0(r1));
7199
7200 return "stg";
7201}
7202
7203static HChar *
7204s390_irgen_STRL(UChar r1, UInt i2)
7205{
7206 store(mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)),
7207 get_gpr_w1(r1));
7208
7209 return "strl";
7210}
7211
7212static HChar *
7213s390_irgen_STGRL(UChar r1, UInt i2)
7214{
7215 store(mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)),
7216 get_gpr_dw0(r1));
7217
7218 return "stgrl";
7219}
7220
7221static HChar *
7222s390_irgen_STC(UChar r1, IRTemp op2addr)
7223{
7224 store(mkexpr(op2addr), get_gpr_b7(r1));
7225
7226 return "stc";
7227}
7228
7229static HChar *
7230s390_irgen_STCY(UChar r1, IRTemp op2addr)
7231{
7232 store(mkexpr(op2addr), get_gpr_b7(r1));
7233
7234 return "stcy";
7235}
7236
7237static HChar *
7238s390_irgen_STCH(UChar r1, IRTemp op2addr)
7239{
7240 store(mkexpr(op2addr), get_gpr_b3(r1));
7241
7242 return "stch";
7243}
7244
7245static HChar *
7246s390_irgen_STCM(UChar r1, UChar r3, IRTemp op2addr)
7247{
7248 UChar mask;
7249 UChar n;
7250
7251 mask = (UChar)r3;
7252 n = 0;
7253 if ((mask & 8) != 0) {
7254 store(mkexpr(op2addr), get_gpr_b4(r1));
7255 n = n + 1;
7256 }
7257 if ((mask & 4) != 0) {
7258 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b5(r1));
7259 n = n + 1;
7260 }
7261 if ((mask & 2) != 0) {
7262 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b6(r1));
7263 n = n + 1;
7264 }
7265 if ((mask & 1) != 0) {
7266 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b7(r1));
7267 }
7268
7269 return "stcm";
7270}
7271
7272static HChar *
7273s390_irgen_STCMY(UChar r1, UChar r3, IRTemp op2addr)
7274{
7275 UChar mask;
7276 UChar n;
7277
7278 mask = (UChar)r3;
7279 n = 0;
7280 if ((mask & 8) != 0) {
7281 store(mkexpr(op2addr), get_gpr_b4(r1));
7282 n = n + 1;
7283 }
7284 if ((mask & 4) != 0) {
7285 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b5(r1));
7286 n = n + 1;
7287 }
7288 if ((mask & 2) != 0) {
7289 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b6(r1));
7290 n = n + 1;
7291 }
7292 if ((mask & 1) != 0) {
7293 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b7(r1));
7294 }
7295
7296 return "stcmy";
7297}
7298
7299static HChar *
7300s390_irgen_STCMH(UChar r1, UChar r3, IRTemp op2addr)
7301{
7302 UChar mask;
7303 UChar n;
7304
7305 mask = (UChar)r3;
7306 n = 0;
7307 if ((mask & 8) != 0) {
7308 store(mkexpr(op2addr), get_gpr_b0(r1));
7309 n = n + 1;
7310 }
7311 if ((mask & 4) != 0) {
7312 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b1(r1));
7313 n = n + 1;
7314 }
7315 if ((mask & 2) != 0) {
7316 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b2(r1));
7317 n = n + 1;
7318 }
7319 if ((mask & 1) != 0) {
7320 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b3(r1));
7321 }
7322
7323 return "stcmh";
7324}
7325
7326static HChar *
7327s390_irgen_STH(UChar r1, IRTemp op2addr)
7328{
7329 store(mkexpr(op2addr), get_gpr_hw3(r1));
7330
7331 return "sth";
7332}
7333
7334static HChar *
7335s390_irgen_STHY(UChar r1, IRTemp op2addr)
7336{
7337 store(mkexpr(op2addr), get_gpr_hw3(r1));
7338
7339 return "sthy";
7340}
7341
7342static HChar *
7343s390_irgen_STHRL(UChar r1, UInt i2)
7344{
7345 store(mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)),
7346 get_gpr_hw3(r1));
7347
7348 return "sthrl";
7349}
7350
7351static HChar *
7352s390_irgen_STHH(UChar r1, IRTemp op2addr)
7353{
7354 store(mkexpr(op2addr), get_gpr_hw1(r1));
7355
7356 return "sthh";
7357}
7358
7359static HChar *
7360s390_irgen_STFH(UChar r1, IRTemp op2addr)
7361{
7362 store(mkexpr(op2addr), get_gpr_w0(r1));
7363
7364 return "stfh";
7365}
7366
7367static HChar *
sewardjd7bde722011-04-05 13:19:33 +00007368s390_irgen_STOC(UChar r1, IRTemp op2addr)
7369{
7370 /* condition is checked in format handler */
7371 store(mkexpr(op2addr), get_gpr_w1(r1));
7372
7373 return "stoc";
7374}
7375
7376static HChar *
7377s390_irgen_STOCG(UChar r1, IRTemp op2addr)
7378{
7379 /* condition is checked in format handler */
7380 store(mkexpr(op2addr), get_gpr_dw0(r1));
7381
7382 return "stocg";
7383}
7384
7385static HChar *
sewardj2019a972011-03-07 16:04:07 +00007386s390_irgen_STPQ(UChar r1, IRTemp op2addr)
7387{
7388 store(mkexpr(op2addr), get_gpr_dw0(r1));
7389 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(8)), get_gpr_dw0(r1 + 1));
7390
7391 return "stpq";
7392}
7393
7394static HChar *
7395s390_irgen_STRVH(UChar r1, IRTemp op2addr)
7396{
7397 store(mkexpr(op2addr), get_gpr_b7(r1));
7398 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(1)), get_gpr_b6(r1));
7399
7400 return "strvh";
7401}
7402
7403static HChar *
7404s390_irgen_STRV(UChar r1, IRTemp op2addr)
7405{
7406 store(mkexpr(op2addr), get_gpr_b7(r1));
7407 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(1)), get_gpr_b6(r1));
7408 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(2)), get_gpr_b5(r1));
7409 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(3)), get_gpr_b4(r1));
7410
7411 return "strv";
7412}
7413
7414static HChar *
7415s390_irgen_STRVG(UChar r1, IRTemp op2addr)
7416{
7417 store(mkexpr(op2addr), get_gpr_b7(r1));
7418 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(1)), get_gpr_b6(r1));
7419 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(2)), get_gpr_b5(r1));
7420 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(3)), get_gpr_b4(r1));
7421 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(4)), get_gpr_b3(r1));
7422 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(5)), get_gpr_b2(r1));
7423 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(6)), get_gpr_b1(r1));
7424 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(7)), get_gpr_b0(r1));
7425
7426 return "strvg";
7427}
7428
7429static HChar *
7430s390_irgen_SR(UChar r1, UChar r2)
7431{
7432 IRTemp op1 = newTemp(Ity_I32);
7433 IRTemp op2 = newTemp(Ity_I32);
7434 IRTemp result = newTemp(Ity_I32);
7435
7436 assign(op1, get_gpr_w1(r1));
7437 assign(op2, get_gpr_w1(r2));
7438 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7439 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
7440 put_gpr_w1(r1, mkexpr(result));
7441
7442 return "sr";
7443}
7444
7445static HChar *
7446s390_irgen_SGR(UChar r1, UChar r2)
7447{
7448 IRTemp op1 = newTemp(Ity_I64);
7449 IRTemp op2 = newTemp(Ity_I64);
7450 IRTemp result = newTemp(Ity_I64);
7451
7452 assign(op1, get_gpr_dw0(r1));
7453 assign(op2, get_gpr_dw0(r2));
7454 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7455 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
7456 put_gpr_dw0(r1, mkexpr(result));
7457
7458 return "sgr";
7459}
7460
7461static HChar *
7462s390_irgen_SGFR(UChar r1, UChar r2)
7463{
7464 IRTemp op1 = newTemp(Ity_I64);
7465 IRTemp op2 = newTemp(Ity_I64);
7466 IRTemp result = newTemp(Ity_I64);
7467
7468 assign(op1, get_gpr_dw0(r1));
7469 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
7470 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7471 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
7472 put_gpr_dw0(r1, mkexpr(result));
7473
7474 return "sgfr";
7475}
7476
7477static HChar *
7478s390_irgen_SRK(UChar r3, UChar r1, UChar r2)
7479{
7480 IRTemp op2 = newTemp(Ity_I32);
7481 IRTemp op3 = newTemp(Ity_I32);
7482 IRTemp result = newTemp(Ity_I32);
7483
7484 assign(op2, get_gpr_w1(r2));
7485 assign(op3, get_gpr_w1(r3));
7486 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
7487 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op2, op3);
7488 put_gpr_w1(r1, mkexpr(result));
7489
7490 return "srk";
7491}
7492
7493static HChar *
7494s390_irgen_SGRK(UChar r3, UChar r1, UChar r2)
7495{
7496 IRTemp op2 = newTemp(Ity_I64);
7497 IRTemp op3 = newTemp(Ity_I64);
7498 IRTemp result = newTemp(Ity_I64);
7499
7500 assign(op2, get_gpr_dw0(r2));
7501 assign(op3, get_gpr_dw0(r3));
7502 assign(result, binop(Iop_Sub64, mkexpr(op2), mkexpr(op3)));
7503 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op2, op3);
7504 put_gpr_dw0(r1, mkexpr(result));
7505
7506 return "sgrk";
7507}
7508
7509static HChar *
7510s390_irgen_S(UChar r1, IRTemp op2addr)
7511{
7512 IRTemp op1 = newTemp(Ity_I32);
7513 IRTemp op2 = newTemp(Ity_I32);
7514 IRTemp result = newTemp(Ity_I32);
7515
7516 assign(op1, get_gpr_w1(r1));
7517 assign(op2, load(Ity_I32, mkexpr(op2addr)));
7518 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7519 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
7520 put_gpr_w1(r1, mkexpr(result));
7521
7522 return "s";
7523}
7524
7525static HChar *
7526s390_irgen_SY(UChar r1, IRTemp op2addr)
7527{
7528 IRTemp op1 = newTemp(Ity_I32);
7529 IRTemp op2 = newTemp(Ity_I32);
7530 IRTemp result = newTemp(Ity_I32);
7531
7532 assign(op1, get_gpr_w1(r1));
7533 assign(op2, load(Ity_I32, mkexpr(op2addr)));
7534 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7535 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
7536 put_gpr_w1(r1, mkexpr(result));
7537
7538 return "sy";
7539}
7540
7541static HChar *
7542s390_irgen_SG(UChar r1, IRTemp op2addr)
7543{
7544 IRTemp op1 = newTemp(Ity_I64);
7545 IRTemp op2 = newTemp(Ity_I64);
7546 IRTemp result = newTemp(Ity_I64);
7547
7548 assign(op1, get_gpr_dw0(r1));
7549 assign(op2, load(Ity_I64, mkexpr(op2addr)));
7550 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7551 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
7552 put_gpr_dw0(r1, mkexpr(result));
7553
7554 return "sg";
7555}
7556
7557static HChar *
7558s390_irgen_SGF(UChar r1, IRTemp op2addr)
7559{
7560 IRTemp op1 = newTemp(Ity_I64);
7561 IRTemp op2 = newTemp(Ity_I64);
7562 IRTemp result = newTemp(Ity_I64);
7563
7564 assign(op1, get_gpr_dw0(r1));
7565 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
7566 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7567 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
7568 put_gpr_dw0(r1, mkexpr(result));
7569
7570 return "sgf";
7571}
7572
7573static HChar *
7574s390_irgen_SH(UChar r1, IRTemp op2addr)
7575{
7576 IRTemp op1 = newTemp(Ity_I32);
7577 IRTemp op2 = newTemp(Ity_I32);
7578 IRTemp result = newTemp(Ity_I32);
7579
7580 assign(op1, get_gpr_w1(r1));
7581 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
7582 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7583 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
7584 put_gpr_w1(r1, mkexpr(result));
7585
7586 return "sh";
7587}
7588
7589static HChar *
7590s390_irgen_SHY(UChar r1, IRTemp op2addr)
7591{
7592 IRTemp op1 = newTemp(Ity_I32);
7593 IRTemp op2 = newTemp(Ity_I32);
7594 IRTemp result = newTemp(Ity_I32);
7595
7596 assign(op1, get_gpr_w1(r1));
7597 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
7598 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7599 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
7600 put_gpr_w1(r1, mkexpr(result));
7601
7602 return "shy";
7603}
7604
7605static HChar *
7606s390_irgen_SHHHR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
7607{
7608 IRTemp op2 = newTemp(Ity_I32);
7609 IRTemp op3 = newTemp(Ity_I32);
7610 IRTemp result = newTemp(Ity_I32);
7611
7612 assign(op2, get_gpr_w0(r1));
7613 assign(op3, get_gpr_w0(r2));
7614 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
7615 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op2, op3);
7616 put_gpr_w0(r1, mkexpr(result));
7617
7618 return "shhhr";
7619}
7620
7621static HChar *
7622s390_irgen_SHHLR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
7623{
7624 IRTemp op2 = newTemp(Ity_I32);
7625 IRTemp op3 = newTemp(Ity_I32);
7626 IRTemp result = newTemp(Ity_I32);
7627
7628 assign(op2, get_gpr_w0(r1));
7629 assign(op3, get_gpr_w1(r2));
7630 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
7631 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op2, op3);
7632 put_gpr_w0(r1, mkexpr(result));
7633
7634 return "shhlr";
7635}
7636
7637static HChar *
7638s390_irgen_SLR(UChar r1, UChar r2)
7639{
7640 IRTemp op1 = newTemp(Ity_I32);
7641 IRTemp op2 = newTemp(Ity_I32);
7642 IRTemp result = newTemp(Ity_I32);
7643
7644 assign(op1, get_gpr_w1(r1));
7645 assign(op2, get_gpr_w1(r2));
7646 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7647 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, op2);
7648 put_gpr_w1(r1, mkexpr(result));
7649
7650 return "slr";
7651}
7652
7653static HChar *
7654s390_irgen_SLGR(UChar r1, UChar r2)
7655{
7656 IRTemp op1 = newTemp(Ity_I64);
7657 IRTemp op2 = newTemp(Ity_I64);
7658 IRTemp result = newTemp(Ity_I64);
7659
7660 assign(op1, get_gpr_dw0(r1));
7661 assign(op2, get_gpr_dw0(r2));
7662 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7663 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
7664 put_gpr_dw0(r1, mkexpr(result));
7665
7666 return "slgr";
7667}
7668
7669static HChar *
7670s390_irgen_SLGFR(UChar r1, UChar r2)
7671{
7672 IRTemp op1 = newTemp(Ity_I64);
7673 IRTemp op2 = newTemp(Ity_I64);
7674 IRTemp result = newTemp(Ity_I64);
7675
7676 assign(op1, get_gpr_dw0(r1));
7677 assign(op2, unop(Iop_32Uto64, get_gpr_w1(r2)));
7678 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7679 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
7680 put_gpr_dw0(r1, mkexpr(result));
7681
7682 return "slgfr";
7683}
7684
7685static HChar *
7686s390_irgen_SLRK(UChar r3, UChar r1, UChar r2)
7687{
7688 IRTemp op2 = newTemp(Ity_I32);
7689 IRTemp op3 = newTemp(Ity_I32);
7690 IRTemp result = newTemp(Ity_I32);
7691
7692 assign(op2, get_gpr_w1(r2));
7693 assign(op3, get_gpr_w1(r3));
7694 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
7695 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op2, op3);
7696 put_gpr_w1(r1, mkexpr(result));
7697
7698 return "slrk";
7699}
7700
7701static HChar *
7702s390_irgen_SLGRK(UChar r3, UChar r1, UChar r2)
7703{
7704 IRTemp op2 = newTemp(Ity_I64);
7705 IRTemp op3 = newTemp(Ity_I64);
7706 IRTemp result = newTemp(Ity_I64);
7707
7708 assign(op2, get_gpr_dw0(r2));
7709 assign(op3, get_gpr_dw0(r3));
7710 assign(result, binop(Iop_Sub64, mkexpr(op2), mkexpr(op3)));
7711 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op2, op3);
7712 put_gpr_dw0(r1, mkexpr(result));
7713
7714 return "slgrk";
7715}
7716
7717static HChar *
7718s390_irgen_SL(UChar r1, IRTemp op2addr)
7719{
7720 IRTemp op1 = newTemp(Ity_I32);
7721 IRTemp op2 = newTemp(Ity_I32);
7722 IRTemp result = newTemp(Ity_I32);
7723
7724 assign(op1, get_gpr_w1(r1));
7725 assign(op2, load(Ity_I32, mkexpr(op2addr)));
7726 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7727 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, op2);
7728 put_gpr_w1(r1, mkexpr(result));
7729
7730 return "sl";
7731}
7732
7733static HChar *
7734s390_irgen_SLY(UChar r1, IRTemp op2addr)
7735{
7736 IRTemp op1 = newTemp(Ity_I32);
7737 IRTemp op2 = newTemp(Ity_I32);
7738 IRTemp result = newTemp(Ity_I32);
7739
7740 assign(op1, get_gpr_w1(r1));
7741 assign(op2, load(Ity_I32, mkexpr(op2addr)));
7742 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7743 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, op2);
7744 put_gpr_w1(r1, mkexpr(result));
7745
7746 return "sly";
7747}
7748
7749static HChar *
7750s390_irgen_SLG(UChar r1, IRTemp op2addr)
7751{
7752 IRTemp op1 = newTemp(Ity_I64);
7753 IRTemp op2 = newTemp(Ity_I64);
7754 IRTemp result = newTemp(Ity_I64);
7755
7756 assign(op1, get_gpr_dw0(r1));
7757 assign(op2, load(Ity_I64, mkexpr(op2addr)));
7758 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7759 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
7760 put_gpr_dw0(r1, mkexpr(result));
7761
7762 return "slg";
7763}
7764
7765static HChar *
7766s390_irgen_SLGF(UChar r1, IRTemp op2addr)
7767{
7768 IRTemp op1 = newTemp(Ity_I64);
7769 IRTemp op2 = newTemp(Ity_I64);
7770 IRTemp result = newTemp(Ity_I64);
7771
7772 assign(op1, get_gpr_dw0(r1));
7773 assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
7774 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7775 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
7776 put_gpr_dw0(r1, mkexpr(result));
7777
7778 return "slgf";
7779}
7780
7781static HChar *
7782s390_irgen_SLFI(UChar r1, UInt i2)
7783{
7784 IRTemp op1 = newTemp(Ity_I32);
7785 UInt op2;
7786 IRTemp result = newTemp(Ity_I32);
7787
7788 assign(op1, get_gpr_w1(r1));
7789 op2 = i2;
7790 assign(result, binop(Iop_Sub32, mkexpr(op1), mkU32(op2)));
7791 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, mktemp(Ity_I32,
7792 mkU32(op2)));
7793 put_gpr_w1(r1, mkexpr(result));
7794
7795 return "slfi";
7796}
7797
7798static HChar *
7799s390_irgen_SLGFI(UChar r1, UInt i2)
7800{
7801 IRTemp op1 = newTemp(Ity_I64);
7802 ULong op2;
7803 IRTemp result = newTemp(Ity_I64);
7804
7805 assign(op1, get_gpr_dw0(r1));
7806 op2 = (ULong)i2;
7807 assign(result, binop(Iop_Sub64, mkexpr(op1), mkU64(op2)));
7808 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, mktemp(Ity_I64,
7809 mkU64(op2)));
7810 put_gpr_dw0(r1, mkexpr(result));
7811
7812 return "slgfi";
7813}
7814
7815static HChar *
7816s390_irgen_SLHHHR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
7817{
7818 IRTemp op2 = newTemp(Ity_I32);
7819 IRTemp op3 = newTemp(Ity_I32);
7820 IRTemp result = newTemp(Ity_I32);
7821
7822 assign(op2, get_gpr_w0(r1));
7823 assign(op3, get_gpr_w0(r2));
7824 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
7825 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op2, op3);
7826 put_gpr_w0(r1, mkexpr(result));
7827
7828 return "slhhhr";
7829}
7830
7831static HChar *
7832s390_irgen_SLHHLR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
7833{
7834 IRTemp op2 = newTemp(Ity_I32);
7835 IRTemp op3 = newTemp(Ity_I32);
7836 IRTemp result = newTemp(Ity_I32);
7837
7838 assign(op2, get_gpr_w0(r1));
7839 assign(op3, get_gpr_w1(r2));
7840 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
7841 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op2, op3);
7842 put_gpr_w0(r1, mkexpr(result));
7843
7844 return "slhhlr";
7845}
7846
7847static HChar *
7848s390_irgen_SLBR(UChar r1, UChar r2)
7849{
7850 IRTemp op1 = newTemp(Ity_I32);
7851 IRTemp op2 = newTemp(Ity_I32);
7852 IRTemp result = newTemp(Ity_I32);
7853 IRTemp borrow_in = newTemp(Ity_I32);
7854
7855 assign(op1, get_gpr_w1(r1));
7856 assign(op2, get_gpr_w1(r2));
7857 assign(borrow_in, binop(Iop_Sub32, mkU32(1), binop(Iop_Shr32,
7858 s390_call_calculate_cc(), mkU8(1))));
7859 assign(result, binop(Iop_Sub32, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)),
7860 mkexpr(borrow_in)));
7861 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_32, op1, op2, borrow_in);
7862 put_gpr_w1(r1, mkexpr(result));
7863
7864 return "slbr";
7865}
7866
7867static HChar *
7868s390_irgen_SLBGR(UChar r1, UChar r2)
7869{
7870 IRTemp op1 = newTemp(Ity_I64);
7871 IRTemp op2 = newTemp(Ity_I64);
7872 IRTemp result = newTemp(Ity_I64);
7873 IRTemp borrow_in = newTemp(Ity_I64);
7874
7875 assign(op1, get_gpr_dw0(r1));
7876 assign(op2, get_gpr_dw0(r2));
7877 assign(borrow_in, unop(Iop_32Uto64, binop(Iop_Sub32, mkU32(1),
7878 binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)))));
7879 assign(result, binop(Iop_Sub64, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)),
7880 mkexpr(borrow_in)));
7881 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_64, op1, op2, borrow_in);
7882 put_gpr_dw0(r1, mkexpr(result));
7883
7884 return "slbgr";
7885}
7886
7887static HChar *
7888s390_irgen_SLB(UChar r1, IRTemp op2addr)
7889{
7890 IRTemp op1 = newTemp(Ity_I32);
7891 IRTemp op2 = newTemp(Ity_I32);
7892 IRTemp result = newTemp(Ity_I32);
7893 IRTemp borrow_in = newTemp(Ity_I32);
7894
7895 assign(op1, get_gpr_w1(r1));
7896 assign(op2, load(Ity_I32, mkexpr(op2addr)));
7897 assign(borrow_in, binop(Iop_Sub32, mkU32(1), binop(Iop_Shr32,
7898 s390_call_calculate_cc(), mkU8(1))));
7899 assign(result, binop(Iop_Sub32, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)),
7900 mkexpr(borrow_in)));
7901 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_32, op1, op2, borrow_in);
7902 put_gpr_w1(r1, mkexpr(result));
7903
7904 return "slb";
7905}
7906
7907static HChar *
7908s390_irgen_SLBG(UChar r1, IRTemp op2addr)
7909{
7910 IRTemp op1 = newTemp(Ity_I64);
7911 IRTemp op2 = newTemp(Ity_I64);
7912 IRTemp result = newTemp(Ity_I64);
7913 IRTemp borrow_in = newTemp(Ity_I64);
7914
7915 assign(op1, get_gpr_dw0(r1));
7916 assign(op2, load(Ity_I64, mkexpr(op2addr)));
7917 assign(borrow_in, unop(Iop_32Uto64, binop(Iop_Sub32, mkU32(1),
7918 binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)))));
7919 assign(result, binop(Iop_Sub64, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)),
7920 mkexpr(borrow_in)));
7921 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_64, op1, op2, borrow_in);
7922 put_gpr_dw0(r1, mkexpr(result));
7923
7924 return "slbg";
7925}
7926
7927static HChar *
7928s390_irgen_SVC(UChar i)
7929{
7930 IRTemp sysno = newTemp(Ity_I64);
7931
7932 if (i != 0) {
7933 assign(sysno, mkU64(i));
7934 } else {
7935 assign(sysno, unop(Iop_32Uto64, get_gpr_w1(1)));
7936 }
7937 system_call(mkexpr(sysno));
7938
7939 return "svc";
7940}
7941
7942static HChar *
sewardj2019a972011-03-07 16:04:07 +00007943s390_irgen_TM(UChar i2, IRTemp op1addr)
7944{
7945 UChar mask;
7946 IRTemp value = newTemp(Ity_I8);
7947
7948 mask = i2;
7949 assign(value, load(Ity_I8, mkexpr(op1addr)));
7950 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_8, value, mktemp(Ity_I8,
7951 mkU8(mask)));
7952
7953 return "tm";
7954}
7955
7956static HChar *
7957s390_irgen_TMY(UChar i2, IRTemp op1addr)
7958{
7959 UChar mask;
7960 IRTemp value = newTemp(Ity_I8);
7961
7962 mask = i2;
7963 assign(value, load(Ity_I8, mkexpr(op1addr)));
7964 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_8, value, mktemp(Ity_I8,
7965 mkU8(mask)));
7966
7967 return "tmy";
7968}
7969
7970static HChar *
7971s390_irgen_TMHH(UChar r1, UShort i2)
7972{
7973 UShort mask;
7974 IRTemp value = newTemp(Ity_I16);
7975
7976 mask = i2;
7977 assign(value, get_gpr_hw0(r1));
7978 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
7979 mkU16(mask)));
7980
7981 return "tmhh";
7982}
7983
7984static HChar *
7985s390_irgen_TMHL(UChar r1, UShort i2)
7986{
7987 UShort mask;
7988 IRTemp value = newTemp(Ity_I16);
7989
7990 mask = i2;
7991 assign(value, get_gpr_hw1(r1));
7992 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
7993 mkU16(mask)));
7994
7995 return "tmhl";
7996}
7997
7998static HChar *
7999s390_irgen_TMLH(UChar r1, UShort i2)
8000{
8001 UShort mask;
8002 IRTemp value = newTemp(Ity_I16);
8003
8004 mask = i2;
8005 assign(value, get_gpr_hw2(r1));
8006 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
8007 mkU16(mask)));
8008
8009 return "tmlh";
8010}
8011
8012static HChar *
8013s390_irgen_TMLL(UChar r1, UShort i2)
8014{
8015 UShort mask;
8016 IRTemp value = newTemp(Ity_I16);
8017
8018 mask = i2;
8019 assign(value, get_gpr_hw3(r1));
8020 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
8021 mkU16(mask)));
8022
8023 return "tmll";
8024}
8025
8026static HChar *
8027s390_irgen_EFPC(UChar r1)
8028{
8029 put_gpr_w1(r1, get_fpc_w0());
8030
8031 return "efpc";
8032}
8033
8034static HChar *
8035s390_irgen_LER(UChar r1, UChar r2)
8036{
8037 put_fpr_w0(r1, get_fpr_w0(r2));
8038
8039 return "ler";
8040}
8041
8042static HChar *
8043s390_irgen_LDR(UChar r1, UChar r2)
8044{
8045 put_fpr_dw0(r1, get_fpr_dw0(r2));
8046
8047 return "ldr";
8048}
8049
8050static HChar *
8051s390_irgen_LXR(UChar r1, UChar r2)
8052{
8053 put_fpr_dw0(r1, get_fpr_dw0(r2));
8054 put_fpr_dw0(r1 + 2, get_fpr_dw0(r2 + 2));
8055
8056 return "lxr";
8057}
8058
8059static HChar *
8060s390_irgen_LE(UChar r1, IRTemp op2addr)
8061{
8062 put_fpr_w0(r1, load(Ity_F32, mkexpr(op2addr)));
8063
8064 return "le";
8065}
8066
8067static HChar *
8068s390_irgen_LD(UChar r1, IRTemp op2addr)
8069{
8070 put_fpr_dw0(r1, load(Ity_F64, mkexpr(op2addr)));
8071
8072 return "ld";
8073}
8074
8075static HChar *
8076s390_irgen_LEY(UChar r1, IRTemp op2addr)
8077{
8078 put_fpr_w0(r1, load(Ity_F32, mkexpr(op2addr)));
8079
8080 return "ley";
8081}
8082
8083static HChar *
8084s390_irgen_LDY(UChar r1, IRTemp op2addr)
8085{
8086 put_fpr_dw0(r1, load(Ity_F64, mkexpr(op2addr)));
8087
8088 return "ldy";
8089}
8090
8091static HChar *
8092s390_irgen_LFPC(IRTemp op2addr)
8093{
8094 put_fpc_w0(load(Ity_I32, mkexpr(op2addr)));
8095
8096 return "lfpc";
8097}
8098
8099static HChar *
8100s390_irgen_LZER(UChar r1)
8101{
8102 put_fpr_w0(r1, mkF32i(0x0));
8103
8104 return "lzer";
8105}
8106
8107static HChar *
8108s390_irgen_LZDR(UChar r1)
8109{
8110 put_fpr_dw0(r1, mkF64i(0x0));
8111
8112 return "lzdr";
8113}
8114
8115static HChar *
8116s390_irgen_LZXR(UChar r1)
8117{
8118 put_fpr_dw0(r1, mkF64i(0x0));
8119 put_fpr_dw0(r1 + 2, mkF64i(0x0));
8120
8121 return "lzxr";
8122}
8123
8124static HChar *
8125s390_irgen_SRNM(IRTemp op2addr)
8126{
8127 UInt mask;
8128
8129 mask = 3;
8130 put_fpc_w0(binop(Iop_Or32, binop(Iop_And32, get_fpc_w0(), mkU32(~mask)),
8131 binop(Iop_And32, unop(Iop_64to32, mkexpr(op2addr)), mkU32(mask)))
8132 );
8133
8134 return "srnm";
8135}
8136
8137static HChar *
8138s390_irgen_SFPC(UChar r1)
8139{
8140 put_fpc_w0(get_gpr_w1(r1));
8141
8142 return "sfpc";
8143}
8144
8145static HChar *
8146s390_irgen_STE(UChar r1, IRTemp op2addr)
8147{
8148 store(mkexpr(op2addr), get_fpr_w0(r1));
8149
8150 return "ste";
8151}
8152
8153static HChar *
8154s390_irgen_STD(UChar r1, IRTemp op2addr)
8155{
8156 store(mkexpr(op2addr), get_fpr_dw0(r1));
8157
8158 return "std";
8159}
8160
8161static HChar *
8162s390_irgen_STEY(UChar r1, IRTemp op2addr)
8163{
8164 store(mkexpr(op2addr), get_fpr_w0(r1));
8165
8166 return "stey";
8167}
8168
8169static HChar *
8170s390_irgen_STDY(UChar r1, IRTemp op2addr)
8171{
8172 store(mkexpr(op2addr), get_fpr_dw0(r1));
8173
8174 return "stdy";
8175}
8176
8177static HChar *
8178s390_irgen_STFPC(IRTemp op2addr)
8179{
8180 store(mkexpr(op2addr), get_fpc_w0());
8181
8182 return "stfpc";
8183}
8184
8185static HChar *
8186s390_irgen_AEBR(UChar r1, UChar r2)
8187{
8188 IRTemp op1 = newTemp(Ity_F32);
8189 IRTemp op2 = newTemp(Ity_F32);
8190 IRTemp result = newTemp(Ity_F32);
florian847684d2012-09-05 04:19:09 +00008191 IRRoundingMode rounding_mode = encode_rounding_mode(S390_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008192
8193 assign(op1, get_fpr_w0(r1));
8194 assign(op2, get_fpr_w0(r2));
florian847684d2012-09-05 04:19:09 +00008195 assign(result, triop(Iop_AddF32, mkU32(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008196 mkexpr(op2)));
8197 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
8198 put_fpr_w0(r1, mkexpr(result));
8199
8200 return "aebr";
8201}
8202
8203static HChar *
8204s390_irgen_ADBR(UChar r1, UChar r2)
8205{
8206 IRTemp op1 = newTemp(Ity_F64);
8207 IRTemp op2 = newTemp(Ity_F64);
8208 IRTemp result = newTemp(Ity_F64);
florian847684d2012-09-05 04:19:09 +00008209 IRRoundingMode rounding_mode = encode_rounding_mode(S390_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008210
8211 assign(op1, get_fpr_dw0(r1));
8212 assign(op2, get_fpr_dw0(r2));
florian847684d2012-09-05 04:19:09 +00008213 assign(result, triop(Iop_AddF64, mkU32(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008214 mkexpr(op2)));
8215 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
8216 put_fpr_dw0(r1, mkexpr(result));
8217
8218 return "adbr";
8219}
8220
8221static HChar *
8222s390_irgen_AEB(UChar r1, IRTemp op2addr)
8223{
8224 IRTemp op1 = newTemp(Ity_F32);
8225 IRTemp op2 = newTemp(Ity_F32);
8226 IRTemp result = newTemp(Ity_F32);
florian847684d2012-09-05 04:19:09 +00008227 IRRoundingMode rounding_mode = encode_rounding_mode(S390_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008228
8229 assign(op1, get_fpr_w0(r1));
8230 assign(op2, load(Ity_F32, mkexpr(op2addr)));
florian847684d2012-09-05 04:19:09 +00008231 assign(result, triop(Iop_AddF32, mkU32(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008232 mkexpr(op2)));
8233 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
8234 put_fpr_w0(r1, mkexpr(result));
8235
8236 return "aeb";
8237}
8238
8239static HChar *
8240s390_irgen_ADB(UChar r1, IRTemp op2addr)
8241{
8242 IRTemp op1 = newTemp(Ity_F64);
8243 IRTemp op2 = newTemp(Ity_F64);
8244 IRTemp result = newTemp(Ity_F64);
florian847684d2012-09-05 04:19:09 +00008245 IRRoundingMode rounding_mode = encode_rounding_mode(S390_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008246
8247 assign(op1, get_fpr_dw0(r1));
8248 assign(op2, load(Ity_F64, mkexpr(op2addr)));
florian847684d2012-09-05 04:19:09 +00008249 assign(result, triop(Iop_AddF64, mkU32(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008250 mkexpr(op2)));
8251 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
8252 put_fpr_dw0(r1, mkexpr(result));
8253
8254 return "adb";
8255}
8256
8257static HChar *
florian4b8efad2012-09-02 18:07:08 +00008258s390_irgen_CEFBR(UChar m3, UChar m4 __attribute__((unused)),
8259 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008260{
florian847684d2012-09-05 04:19:09 +00008261 if (! s390_host_has_fpext && m3 != S390_ROUND_PER_FPC) {
florian4b8efad2012-09-02 18:07:08 +00008262 emulation_warning(EmWarn_S390X_fpext_rounding);
florian847684d2012-09-05 04:19:09 +00008263 m3 = S390_ROUND_PER_FPC;
florian4b8efad2012-09-02 18:07:08 +00008264 }
sewardj2019a972011-03-07 16:04:07 +00008265 IRTemp op2 = newTemp(Ity_I32);
8266
8267 assign(op2, get_gpr_w1(r2));
florian4b8efad2012-09-02 18:07:08 +00008268 put_fpr_w0(r1, binop(Iop_I32StoF32, mkU32(encode_rounding_mode(m3)),
8269 mkexpr(op2)));
sewardj2019a972011-03-07 16:04:07 +00008270
8271 return "cefbr";
8272}
8273
8274static HChar *
florian4b8efad2012-09-02 18:07:08 +00008275s390_irgen_CDFBR(UChar m3 __attribute__((unused)),
8276 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008277{
8278 IRTemp op2 = newTemp(Ity_I32);
8279
8280 assign(op2, get_gpr_w1(r2));
8281 put_fpr_dw0(r1, unop(Iop_I32StoF64, mkexpr(op2)));
8282
8283 return "cdfbr";
8284}
8285
8286static HChar *
florian4b8efad2012-09-02 18:07:08 +00008287s390_irgen_CEGBR(UChar m3, UChar m4 __attribute__((unused)),
8288 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008289{
florian847684d2012-09-05 04:19:09 +00008290 if (! s390_host_has_fpext && m3 != S390_ROUND_PER_FPC) {
florian4b8efad2012-09-02 18:07:08 +00008291 emulation_warning(EmWarn_S390X_fpext_rounding);
florian847684d2012-09-05 04:19:09 +00008292 m3 = S390_ROUND_PER_FPC;
florian4b8efad2012-09-02 18:07:08 +00008293 }
sewardj2019a972011-03-07 16:04:07 +00008294 IRTemp op2 = newTemp(Ity_I64);
8295
8296 assign(op2, get_gpr_dw0(r2));
florian4b8efad2012-09-02 18:07:08 +00008297 put_fpr_w0(r1, binop(Iop_I64StoF32, mkU32(encode_rounding_mode(m3)),
8298 mkexpr(op2)));
sewardj2019a972011-03-07 16:04:07 +00008299
8300 return "cegbr";
8301}
8302
8303static HChar *
florian4b8efad2012-09-02 18:07:08 +00008304s390_irgen_CDGBR(UChar m3, UChar m4 __attribute__((unused)),
8305 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008306{
florian847684d2012-09-05 04:19:09 +00008307 if (! s390_host_has_fpext && m3 != S390_ROUND_PER_FPC) {
florian4b8efad2012-09-02 18:07:08 +00008308 emulation_warning(EmWarn_S390X_fpext_rounding);
florian847684d2012-09-05 04:19:09 +00008309 m3 = S390_ROUND_PER_FPC;
florian4b8efad2012-09-02 18:07:08 +00008310 }
sewardj2019a972011-03-07 16:04:07 +00008311 IRTemp op2 = newTemp(Ity_I64);
8312
8313 assign(op2, get_gpr_dw0(r2));
florian4b8efad2012-09-02 18:07:08 +00008314 put_fpr_dw0(r1, binop(Iop_I64StoF64, mkU32(encode_rounding_mode(m3)),
8315 mkexpr(op2)));
sewardj2019a972011-03-07 16:04:07 +00008316
8317 return "cdgbr";
8318}
8319
8320static HChar *
florian1c8f7ff2012-09-01 00:12:11 +00008321s390_irgen_CELFBR(UChar m3, UChar m4 __attribute__((unused)),
8322 UChar r1, UChar r2)
8323{
floriane75dafa2012-09-01 17:54:09 +00008324 if (! s390_host_has_fpext) {
8325 emulation_failure(EmFail_S390X_fpext);
8326 } else {
8327 IRTemp op2 = newTemp(Ity_I32);
florian1c8f7ff2012-09-01 00:12:11 +00008328
floriane75dafa2012-09-01 17:54:09 +00008329 assign(op2, get_gpr_w1(r2));
8330 put_fpr_w0(r1, binop(Iop_I32UtoF32, mkU32(encode_rounding_mode(m3)),
8331 mkexpr(op2)));
8332 }
florian1c8f7ff2012-09-01 00:12:11 +00008333 return "celfbr";
8334}
8335
8336static HChar *
floriand2129202012-09-01 20:01:39 +00008337s390_irgen_CDLFBR(UChar m3 __attribute__((unused)),
8338 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
florian1c8f7ff2012-09-01 00:12:11 +00008339{
floriane75dafa2012-09-01 17:54:09 +00008340 if (! s390_host_has_fpext) {
8341 emulation_failure(EmFail_S390X_fpext);
8342 } else {
8343 IRTemp op2 = newTemp(Ity_I32);
florian1c8f7ff2012-09-01 00:12:11 +00008344
floriane75dafa2012-09-01 17:54:09 +00008345 assign(op2, get_gpr_w1(r2));
8346 put_fpr_dw0(r1, unop(Iop_I32UtoF64, mkexpr(op2)));
8347 }
florian1c8f7ff2012-09-01 00:12:11 +00008348 return "cdlfbr";
8349}
8350
8351static HChar *
8352s390_irgen_CELGBR(UChar m3, UChar m4 __attribute__((unused)),
8353 UChar r1, UChar r2)
8354{
floriane75dafa2012-09-01 17:54:09 +00008355 if (! s390_host_has_fpext) {
8356 emulation_failure(EmFail_S390X_fpext);
8357 } else {
8358 IRTemp op2 = newTemp(Ity_I64);
florian1c8f7ff2012-09-01 00:12:11 +00008359
floriane75dafa2012-09-01 17:54:09 +00008360 assign(op2, get_gpr_dw0(r2));
8361 put_fpr_w0(r1, binop(Iop_I64UtoF32, mkU32(encode_rounding_mode(m3)),
8362 mkexpr(op2)));
8363 }
florian1c8f7ff2012-09-01 00:12:11 +00008364 return "celgbr";
8365}
8366
8367static HChar *
8368s390_irgen_CDLGBR(UChar m3, UChar m4 __attribute__((unused)),
8369 UChar r1, UChar r2)
8370{
floriane75dafa2012-09-01 17:54:09 +00008371 if (! s390_host_has_fpext) {
8372 emulation_failure(EmFail_S390X_fpext);
8373 } else {
8374 IRTemp op2 = newTemp(Ity_I64);
florian1c8f7ff2012-09-01 00:12:11 +00008375
floriane75dafa2012-09-01 17:54:09 +00008376 assign(op2, get_gpr_dw0(r2));
8377 put_fpr_dw0(r1, binop(Iop_I64UtoF64, mkU32(encode_rounding_mode(m3)),
8378 mkexpr(op2)));
8379 }
florian1c8f7ff2012-09-01 00:12:11 +00008380 return "cdlgbr";
8381}
8382
8383static HChar *
8384s390_irgen_CLFEBR(UChar m3, UChar m4 __attribute__((unused)),
8385 UChar r1, UChar r2)
8386{
floriane75dafa2012-09-01 17:54:09 +00008387 if (! s390_host_has_fpext) {
8388 emulation_failure(EmFail_S390X_fpext);
8389 } else {
8390 IRTemp op = newTemp(Ity_F32);
8391 IRTemp result = newTemp(Ity_I32);
florian1c8f7ff2012-09-01 00:12:11 +00008392
floriane75dafa2012-09-01 17:54:09 +00008393 assign(op, get_fpr_w0(r2));
8394 assign(result, binop(Iop_F32toI32U, mkU32(encode_rounding_mode(m3)),
8395 mkexpr(op)));
8396 put_gpr_w1(r1, mkexpr(result));
8397 s390_cc_thunk_putF(S390_CC_OP_BFP_32_TO_UINT_32, op);
8398 }
florian1c8f7ff2012-09-01 00:12:11 +00008399 return "clfebr";
8400}
8401
8402static HChar *
8403s390_irgen_CLFDBR(UChar m3, UChar m4 __attribute__((unused)),
8404 UChar r1, UChar r2)
8405{
floriane75dafa2012-09-01 17:54:09 +00008406 if (! s390_host_has_fpext) {
8407 emulation_failure(EmFail_S390X_fpext);
8408 } else {
8409 IRTemp op = newTemp(Ity_F64);
8410 IRTemp result = newTemp(Ity_I32);
florian1c8f7ff2012-09-01 00:12:11 +00008411
floriane75dafa2012-09-01 17:54:09 +00008412 assign(op, get_fpr_dw0(r2));
8413 assign(result, binop(Iop_F64toI32U, mkU32(encode_rounding_mode(m3)),
8414 mkexpr(op)));
8415 put_gpr_w1(r1, mkexpr(result));
8416 s390_cc_thunk_putF(S390_CC_OP_BFP_64_TO_UINT_32, op);
8417 }
florian1c8f7ff2012-09-01 00:12:11 +00008418 return "clfdbr";
8419}
8420
8421static HChar *
8422s390_irgen_CLGEBR(UChar m3, UChar m4 __attribute__((unused)),
8423 UChar r1, UChar r2)
8424{
floriane75dafa2012-09-01 17:54:09 +00008425 if (! s390_host_has_fpext) {
8426 emulation_failure(EmFail_S390X_fpext);
8427 } else {
8428 IRTemp op = newTemp(Ity_F32);
8429 IRTemp result = newTemp(Ity_I64);
florian1c8f7ff2012-09-01 00:12:11 +00008430
floriane75dafa2012-09-01 17:54:09 +00008431 assign(op, get_fpr_w0(r2));
8432 assign(result, binop(Iop_F32toI64U, mkU32(encode_rounding_mode(m3)),
8433 mkexpr(op)));
8434 put_gpr_dw0(r1, mkexpr(result));
8435 s390_cc_thunk_putF(S390_CC_OP_BFP_32_TO_UINT_64, op);
8436 }
florian1c8f7ff2012-09-01 00:12:11 +00008437 return "clgebr";
8438}
8439
8440static HChar *
8441s390_irgen_CLGDBR(UChar m3, UChar m4 __attribute__((unused)),
8442 UChar r1, UChar r2)
8443{
floriane75dafa2012-09-01 17:54:09 +00008444 if (! s390_host_has_fpext) {
8445 emulation_failure(EmFail_S390X_fpext);
8446 } else {
8447 IRTemp op = newTemp(Ity_F64);
8448 IRTemp result = newTemp(Ity_I64);
florian1c8f7ff2012-09-01 00:12:11 +00008449
floriane75dafa2012-09-01 17:54:09 +00008450 assign(op, get_fpr_dw0(r2));
8451 assign(result, binop(Iop_F64toI64U, mkU32(encode_rounding_mode(m3)),
8452 mkexpr(op)));
8453 put_gpr_dw0(r1, mkexpr(result));
8454 s390_cc_thunk_putF(S390_CC_OP_BFP_64_TO_UINT_64, op);
8455 }
florian1c8f7ff2012-09-01 00:12:11 +00008456 return "clgdbr";
8457}
8458
8459static HChar *
florian4b8efad2012-09-02 18:07:08 +00008460s390_irgen_CFEBR(UChar m3, UChar m4 __attribute__((unused)),
8461 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008462{
8463 IRTemp op = newTemp(Ity_F32);
8464 IRTemp result = newTemp(Ity_I32);
8465
8466 assign(op, get_fpr_w0(r2));
florian4b8efad2012-09-02 18:07:08 +00008467 assign(result, binop(Iop_F32toI32S, mkU32(encode_rounding_mode(m3)),
sewardj2019a972011-03-07 16:04:07 +00008468 mkexpr(op)));
8469 put_gpr_w1(r1, mkexpr(result));
8470 s390_cc_thunk_putF(S390_CC_OP_BFP_32_TO_INT_32, op);
8471
8472 return "cfebr";
8473}
8474
8475static HChar *
florian4b8efad2012-09-02 18:07:08 +00008476s390_irgen_CFDBR(UChar m3, UChar m4 __attribute__((unused)),
8477 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008478{
8479 IRTemp op = newTemp(Ity_F64);
8480 IRTemp result = newTemp(Ity_I32);
8481
8482 assign(op, get_fpr_dw0(r2));
florian4b8efad2012-09-02 18:07:08 +00008483 assign(result, binop(Iop_F64toI32S, mkU32(encode_rounding_mode(m3)),
sewardj2019a972011-03-07 16:04:07 +00008484 mkexpr(op)));
8485 put_gpr_w1(r1, mkexpr(result));
8486 s390_cc_thunk_putF(S390_CC_OP_BFP_64_TO_INT_32, op);
8487
8488 return "cfdbr";
8489}
8490
8491static HChar *
florian4b8efad2012-09-02 18:07:08 +00008492s390_irgen_CGEBR(UChar m3, UChar m4 __attribute__((unused)),
8493 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008494{
8495 IRTemp op = newTemp(Ity_F32);
8496 IRTemp result = newTemp(Ity_I64);
8497
8498 assign(op, get_fpr_w0(r2));
florian4b8efad2012-09-02 18:07:08 +00008499 assign(result, binop(Iop_F32toI64S, mkU32(encode_rounding_mode(m3)),
sewardj2019a972011-03-07 16:04:07 +00008500 mkexpr(op)));
8501 put_gpr_dw0(r1, mkexpr(result));
8502 s390_cc_thunk_putF(S390_CC_OP_BFP_32_TO_INT_64, op);
8503
8504 return "cgebr";
8505}
8506
8507static HChar *
florian4b8efad2012-09-02 18:07:08 +00008508s390_irgen_CGDBR(UChar m3, UChar m4 __attribute__((unused)),
8509 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008510{
8511 IRTemp op = newTemp(Ity_F64);
8512 IRTemp result = newTemp(Ity_I64);
8513
8514 assign(op, get_fpr_dw0(r2));
florian4b8efad2012-09-02 18:07:08 +00008515 assign(result, binop(Iop_F64toI64S, mkU32(encode_rounding_mode(m3)),
sewardj2019a972011-03-07 16:04:07 +00008516 mkexpr(op)));
8517 put_gpr_dw0(r1, mkexpr(result));
8518 s390_cc_thunk_putF(S390_CC_OP_BFP_64_TO_INT_64, op);
8519
8520 return "cgdbr";
8521}
8522
8523static HChar *
8524s390_irgen_DEBR(UChar r1, UChar r2)
8525{
8526 IRTemp op1 = newTemp(Ity_F32);
8527 IRTemp op2 = newTemp(Ity_F32);
8528 IRTemp result = newTemp(Ity_F32);
florian847684d2012-09-05 04:19:09 +00008529 IRRoundingMode rounding_mode = encode_rounding_mode(S390_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008530
8531 assign(op1, get_fpr_w0(r1));
8532 assign(op2, get_fpr_w0(r2));
florian847684d2012-09-05 04:19:09 +00008533 assign(result, triop(Iop_DivF32, mkU32(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008534 mkexpr(op2)));
8535 put_fpr_w0(r1, mkexpr(result));
8536
8537 return "debr";
8538}
8539
8540static HChar *
8541s390_irgen_DDBR(UChar r1, UChar r2)
8542{
8543 IRTemp op1 = newTemp(Ity_F64);
8544 IRTemp op2 = newTemp(Ity_F64);
8545 IRTemp result = newTemp(Ity_F64);
florian847684d2012-09-05 04:19:09 +00008546 IRRoundingMode rounding_mode = encode_rounding_mode(S390_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008547
8548 assign(op1, get_fpr_dw0(r1));
8549 assign(op2, get_fpr_dw0(r2));
florian847684d2012-09-05 04:19:09 +00008550 assign(result, triop(Iop_DivF64, mkU32(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008551 mkexpr(op2)));
8552 put_fpr_dw0(r1, mkexpr(result));
8553
8554 return "ddbr";
8555}
8556
8557static HChar *
8558s390_irgen_DEB(UChar r1, IRTemp op2addr)
8559{
8560 IRTemp op1 = newTemp(Ity_F32);
8561 IRTemp op2 = newTemp(Ity_F32);
8562 IRTemp result = newTemp(Ity_F32);
florian847684d2012-09-05 04:19:09 +00008563 IRRoundingMode rounding_mode = encode_rounding_mode(S390_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008564
8565 assign(op1, get_fpr_w0(r1));
8566 assign(op2, load(Ity_F32, mkexpr(op2addr)));
florian847684d2012-09-05 04:19:09 +00008567 assign(result, triop(Iop_DivF32, mkU32(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008568 mkexpr(op2)));
8569 put_fpr_w0(r1, mkexpr(result));
8570
8571 return "deb";
8572}
8573
8574static HChar *
8575s390_irgen_DDB(UChar r1, IRTemp op2addr)
8576{
8577 IRTemp op1 = newTemp(Ity_F64);
8578 IRTemp op2 = newTemp(Ity_F64);
8579 IRTemp result = newTemp(Ity_F64);
florian847684d2012-09-05 04:19:09 +00008580 IRRoundingMode rounding_mode = encode_rounding_mode(S390_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008581
8582 assign(op1, get_fpr_dw0(r1));
8583 assign(op2, load(Ity_F64, mkexpr(op2addr)));
florian847684d2012-09-05 04:19:09 +00008584 assign(result, triop(Iop_DivF64, mkU32(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008585 mkexpr(op2)));
8586 put_fpr_dw0(r1, mkexpr(result));
8587
8588 return "ddb";
8589}
8590
8591static HChar *
8592s390_irgen_LTEBR(UChar r1, UChar r2)
8593{
8594 IRTemp result = newTemp(Ity_F32);
8595
8596 assign(result, get_fpr_w0(r2));
8597 put_fpr_w0(r1, mkexpr(result));
8598 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
8599
8600 return "ltebr";
8601}
8602
8603static HChar *
8604s390_irgen_LTDBR(UChar r1, UChar r2)
8605{
8606 IRTemp result = newTemp(Ity_F64);
8607
8608 assign(result, get_fpr_dw0(r2));
8609 put_fpr_dw0(r1, mkexpr(result));
8610 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
8611
8612 return "ltdbr";
8613}
8614
8615static HChar *
8616s390_irgen_LCEBR(UChar r1, UChar r2)
8617{
8618 IRTemp result = newTemp(Ity_F32);
8619
8620 assign(result, unop(Iop_NegF32, get_fpr_w0(r2)));
8621 put_fpr_w0(r1, mkexpr(result));
8622 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
8623
8624 return "lcebr";
8625}
8626
8627static HChar *
8628s390_irgen_LCDBR(UChar r1, UChar r2)
8629{
8630 IRTemp result = newTemp(Ity_F64);
8631
8632 assign(result, unop(Iop_NegF64, get_fpr_dw0(r2)));
8633 put_fpr_dw0(r1, mkexpr(result));
8634 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
8635
8636 return "lcdbr";
8637}
8638
8639static HChar *
8640s390_irgen_LDEBR(UChar r1, UChar r2)
8641{
8642 IRTemp op = newTemp(Ity_F32);
8643
8644 assign(op, get_fpr_w0(r2));
8645 put_fpr_dw0(r1, unop(Iop_F32toF64, mkexpr(op)));
8646
8647 return "ldebr";
8648}
8649
8650static HChar *
8651s390_irgen_LDEB(UChar r1, IRTemp op2addr)
8652{
8653 IRTemp op = newTemp(Ity_F32);
8654
8655 assign(op, load(Ity_F32, mkexpr(op2addr)));
8656 put_fpr_dw0(r1, unop(Iop_F32toF64, mkexpr(op)));
8657
8658 return "ldeb";
8659}
8660
8661static HChar *
florian4b8efad2012-09-02 18:07:08 +00008662s390_irgen_LEDBR(UChar m3, UChar m4 __attribute__((unused)),
8663 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008664{
8665 IRTemp op = newTemp(Ity_F64);
8666
8667 assign(op, get_fpr_dw0(r2));
florian4b8efad2012-09-02 18:07:08 +00008668 put_fpr_w0(r1, binop(Iop_F64toF32, mkU32(encode_rounding_mode(m3)),
8669 mkexpr(op)));
sewardj2019a972011-03-07 16:04:07 +00008670
8671 return "ledbr";
8672}
8673
8674static HChar *
8675s390_irgen_MEEBR(UChar r1, UChar r2)
8676{
8677 IRTemp op1 = newTemp(Ity_F32);
8678 IRTemp op2 = newTemp(Ity_F32);
8679 IRTemp result = newTemp(Ity_F32);
florian847684d2012-09-05 04:19:09 +00008680 IRRoundingMode rounding_mode = encode_rounding_mode(S390_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008681
8682 assign(op1, get_fpr_w0(r1));
8683 assign(op2, get_fpr_w0(r2));
florian847684d2012-09-05 04:19:09 +00008684 assign(result, triop(Iop_MulF32, mkU32(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008685 mkexpr(op2)));
8686 put_fpr_w0(r1, mkexpr(result));
8687
8688 return "meebr";
8689}
8690
8691static HChar *
8692s390_irgen_MDBR(UChar r1, UChar r2)
8693{
8694 IRTemp op1 = newTemp(Ity_F64);
8695 IRTemp op2 = newTemp(Ity_F64);
8696 IRTemp result = newTemp(Ity_F64);
florian847684d2012-09-05 04:19:09 +00008697 IRRoundingMode rounding_mode = encode_rounding_mode(S390_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008698
8699 assign(op1, get_fpr_dw0(r1));
8700 assign(op2, get_fpr_dw0(r2));
florian847684d2012-09-05 04:19:09 +00008701 assign(result, triop(Iop_MulF64, mkU32(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008702 mkexpr(op2)));
8703 put_fpr_dw0(r1, mkexpr(result));
8704
8705 return "mdbr";
8706}
8707
8708static HChar *
8709s390_irgen_MEEB(UChar r1, IRTemp op2addr)
8710{
8711 IRTemp op1 = newTemp(Ity_F32);
8712 IRTemp op2 = newTemp(Ity_F32);
8713 IRTemp result = newTemp(Ity_F32);
florian847684d2012-09-05 04:19:09 +00008714 IRRoundingMode rounding_mode = encode_rounding_mode(S390_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008715
8716 assign(op1, get_fpr_w0(r1));
8717 assign(op2, load(Ity_F32, mkexpr(op2addr)));
florian847684d2012-09-05 04:19:09 +00008718 assign(result, triop(Iop_MulF32, mkU32(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008719 mkexpr(op2)));
8720 put_fpr_w0(r1, mkexpr(result));
8721
8722 return "meeb";
8723}
8724
8725static HChar *
8726s390_irgen_MDB(UChar r1, IRTemp op2addr)
8727{
8728 IRTemp op1 = newTemp(Ity_F64);
8729 IRTemp op2 = newTemp(Ity_F64);
8730 IRTemp result = newTemp(Ity_F64);
florian847684d2012-09-05 04:19:09 +00008731 IRRoundingMode rounding_mode = encode_rounding_mode(S390_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008732
8733 assign(op1, get_fpr_dw0(r1));
8734 assign(op2, load(Ity_F64, mkexpr(op2addr)));
florian847684d2012-09-05 04:19:09 +00008735 assign(result, triop(Iop_MulF64, mkU32(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008736 mkexpr(op2)));
8737 put_fpr_dw0(r1, mkexpr(result));
8738
8739 return "mdb";
8740}
8741
8742static HChar *
8743s390_irgen_SEBR(UChar r1, UChar r2)
8744{
8745 IRTemp op1 = newTemp(Ity_F32);
8746 IRTemp op2 = newTemp(Ity_F32);
8747 IRTemp result = newTemp(Ity_F32);
florian847684d2012-09-05 04:19:09 +00008748 IRRoundingMode rounding_mode = encode_rounding_mode(S390_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008749
8750 assign(op1, get_fpr_w0(r1));
8751 assign(op2, get_fpr_w0(r2));
florian847684d2012-09-05 04:19:09 +00008752 assign(result, triop(Iop_SubF32, mkU32(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008753 mkexpr(op2)));
8754 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
8755 put_fpr_w0(r1, mkexpr(result));
8756
8757 return "sebr";
8758}
8759
8760static HChar *
8761s390_irgen_SDBR(UChar r1, UChar r2)
8762{
8763 IRTemp op1 = newTemp(Ity_F64);
8764 IRTemp op2 = newTemp(Ity_F64);
8765 IRTemp result = newTemp(Ity_F64);
florian847684d2012-09-05 04:19:09 +00008766 IRRoundingMode rounding_mode = encode_rounding_mode(S390_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008767
8768 assign(op1, get_fpr_dw0(r1));
8769 assign(op2, get_fpr_dw0(r2));
florian847684d2012-09-05 04:19:09 +00008770 assign(result, triop(Iop_SubF64, mkU32(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008771 mkexpr(op2)));
8772 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
8773 put_fpr_dw0(r1, mkexpr(result));
8774
8775 return "sdbr";
8776}
8777
8778static HChar *
8779s390_irgen_SEB(UChar r1, IRTemp op2addr)
8780{
8781 IRTemp op1 = newTemp(Ity_F32);
8782 IRTemp op2 = newTemp(Ity_F32);
8783 IRTemp result = newTemp(Ity_F32);
florian847684d2012-09-05 04:19:09 +00008784 IRRoundingMode rounding_mode = encode_rounding_mode(S390_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008785
8786 assign(op1, get_fpr_w0(r1));
8787 assign(op2, load(Ity_F32, mkexpr(op2addr)));
florian847684d2012-09-05 04:19:09 +00008788 assign(result, triop(Iop_SubF32, mkU32(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008789 mkexpr(op2)));
8790 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
8791 put_fpr_w0(r1, mkexpr(result));
8792
8793 return "seb";
8794}
8795
8796static HChar *
8797s390_irgen_SDB(UChar r1, IRTemp op2addr)
8798{
8799 IRTemp op1 = newTemp(Ity_F64);
8800 IRTemp op2 = newTemp(Ity_F64);
8801 IRTemp result = newTemp(Ity_F64);
florian847684d2012-09-05 04:19:09 +00008802 IRRoundingMode rounding_mode = encode_rounding_mode(S390_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008803
8804 assign(op1, get_fpr_dw0(r1));
8805 assign(op2, load(Ity_F64, mkexpr(op2addr)));
florian847684d2012-09-05 04:19:09 +00008806 assign(result, triop(Iop_SubF64, mkU32(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008807 mkexpr(op2)));
8808 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
8809 put_fpr_dw0(r1, mkexpr(result));
8810
8811 return "sdb";
8812}
8813
8814
8815static HChar *
8816s390_irgen_CLC(UChar length, IRTemp start1, IRTemp start2)
8817{
florian79e839e2012-05-05 02:20:30 +00008818 IRTemp len = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00008819
florian79e839e2012-05-05 02:20:30 +00008820 assign(len, mkU64(length));
8821 s390_irgen_CLC_EX(len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +00008822
8823 return "clc";
8824}
8825
8826static HChar *
florianb0c9a132011-09-08 15:37:39 +00008827s390_irgen_CLCL(UChar r1, UChar r2)
8828{
8829 IRTemp addr1 = newTemp(Ity_I64);
8830 IRTemp addr2 = newTemp(Ity_I64);
8831 IRTemp addr1_load = newTemp(Ity_I64);
8832 IRTemp addr2_load = newTemp(Ity_I64);
8833 IRTemp len1 = newTemp(Ity_I32);
8834 IRTemp len2 = newTemp(Ity_I32);
8835 IRTemp r1p1 = newTemp(Ity_I32); /* contents of r1 + 1 */
8836 IRTemp r2p1 = newTemp(Ity_I32); /* contents of r2 + 1 */
8837 IRTemp single1 = newTemp(Ity_I8);
8838 IRTemp single2 = newTemp(Ity_I8);
8839 IRTemp pad = newTemp(Ity_I8);
8840
8841 assign(addr1, get_gpr_dw0(r1));
8842 assign(r1p1, get_gpr_w1(r1 + 1));
8843 assign(len1, binop(Iop_And32, mkexpr(r1p1), mkU32(0x00ffffff)));
8844 assign(addr2, get_gpr_dw0(r2));
8845 assign(r2p1, get_gpr_w1(r2 + 1));
8846 assign(len2, binop(Iop_And32, mkexpr(r2p1), mkU32(0x00ffffff)));
8847 assign(pad, get_gpr_b4(r2 + 1));
8848
8849 /* len1 == 0 and len2 == 0? Exit */
8850 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +00008851 next_insn_if(binop(Iop_CmpEQ32, binop(Iop_Or32, mkexpr(len1),
8852 mkexpr(len2)), mkU32(0)));
florianb0c9a132011-09-08 15:37:39 +00008853
8854 /* Because mkite evaluates both the then-clause and the else-clause
8855 we cannot load directly from addr1 here. If len1 is 0, then adddr1
8856 may be NULL and loading from there would segfault. So we provide a
8857 valid dummy address in that case. Loading from there does no harm and
8858 the value will be discarded at runtime. */
8859 assign(addr1_load,
8860 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
8861 mkU64(guest_IA_curr_instr), mkexpr(addr1)));
8862 assign(single1,
8863 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
8864 mkexpr(pad), load(Ity_I8, mkexpr(addr1_load))));
8865
8866 assign(addr2_load,
8867 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
8868 mkU64(guest_IA_curr_instr), mkexpr(addr2)));
8869 assign(single2,
8870 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
8871 mkexpr(pad), load(Ity_I8, mkexpr(addr2_load))));
8872
8873 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, single1, single2, False);
8874 /* Fields differ ? */
florian6820ba52012-07-26 02:01:50 +00008875 next_insn_if(binop(Iop_CmpNE8, mkexpr(single1), mkexpr(single2)));
florianb0c9a132011-09-08 15:37:39 +00008876
8877 /* Update len1 and addr1, unless len1 == 0. */
8878 put_gpr_dw0(r1,
8879 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
8880 mkexpr(addr1),
8881 binop(Iop_Add64, mkexpr(addr1), mkU64(1))));
8882
8883 /* When updating len1 we must not modify bits (r1+1)[0:39] */
8884 put_gpr_w1(r1 + 1,
8885 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
8886 binop(Iop_And32, mkexpr(r1p1), mkU32(0xFF000000u)),
8887 binop(Iop_Sub32, mkexpr(r1p1), mkU32(1))));
8888
8889 /* Update len2 and addr2, unless len2 == 0. */
8890 put_gpr_dw0(r2,
8891 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
8892 mkexpr(addr2),
8893 binop(Iop_Add64, mkexpr(addr2), mkU64(1))));
8894
8895 /* When updating len2 we must not modify bits (r2+1)[0:39] */
8896 put_gpr_w1(r2 + 1,
8897 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
8898 binop(Iop_And32, mkexpr(r2p1), mkU32(0xFF000000u)),
8899 binop(Iop_Sub32, mkexpr(r2p1), mkU32(1))));
8900
florian6820ba52012-07-26 02:01:50 +00008901 iterate();
florianb0c9a132011-09-08 15:37:39 +00008902
8903 return "clcl";
8904}
8905
8906static HChar *
sewardj2019a972011-03-07 16:04:07 +00008907s390_irgen_CLCLE(UChar r1, UChar r3, IRTemp pad2)
8908{
8909 IRTemp addr1, addr3, addr1_load, addr3_load, len1, len3, single1, single3;
8910
8911 addr1 = newTemp(Ity_I64);
8912 addr3 = newTemp(Ity_I64);
8913 addr1_load = newTemp(Ity_I64);
8914 addr3_load = newTemp(Ity_I64);
8915 len1 = newTemp(Ity_I64);
8916 len3 = newTemp(Ity_I64);
8917 single1 = newTemp(Ity_I8);
8918 single3 = newTemp(Ity_I8);
8919
8920 assign(addr1, get_gpr_dw0(r1));
8921 assign(len1, get_gpr_dw0(r1 + 1));
8922 assign(addr3, get_gpr_dw0(r3));
8923 assign(len3, get_gpr_dw0(r3 + 1));
8924
8925 /* len1 == 0 and len3 == 0? Exit */
8926 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +00008927 next_insn_if(binop(Iop_CmpEQ64,binop(Iop_Or64, mkexpr(len1),
8928 mkexpr(len3)), mkU64(0)));
sewardj2019a972011-03-07 16:04:07 +00008929
8930 /* A mux requires both ways to be possible. This is a way to prevent clcle
8931 from reading from addr1 if it should read from the pad. Since the pad
8932 has no address, just read from the instruction, we discard that anyway */
8933 assign(addr1_load,
florian6ad49522011-09-09 02:38:55 +00008934 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
8935 mkU64(guest_IA_curr_instr), mkexpr(addr1)));
sewardj2019a972011-03-07 16:04:07 +00008936
8937 /* same for addr3 */
8938 assign(addr3_load,
florian6ad49522011-09-09 02:38:55 +00008939 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
8940 mkU64(guest_IA_curr_instr), mkexpr(addr3)));
sewardj2019a972011-03-07 16:04:07 +00008941
8942 assign(single1,
florian6ad49522011-09-09 02:38:55 +00008943 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
8944 unop(Iop_64to8, mkexpr(pad2)),
8945 load(Ity_I8, mkexpr(addr1_load))));
sewardj2019a972011-03-07 16:04:07 +00008946
8947 assign(single3,
florian6ad49522011-09-09 02:38:55 +00008948 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
8949 unop(Iop_64to8, mkexpr(pad2)),
8950 load(Ity_I8, mkexpr(addr3_load))));
sewardj2019a972011-03-07 16:04:07 +00008951
8952 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, single1, single3, False);
8953 /* Both fields differ ? */
florian6820ba52012-07-26 02:01:50 +00008954 next_insn_if(binop(Iop_CmpNE8, mkexpr(single1), mkexpr(single3)));
sewardj2019a972011-03-07 16:04:07 +00008955
8956 /* If a length in 0 we must not change this length and the address */
8957 put_gpr_dw0(r1,
florian6ad49522011-09-09 02:38:55 +00008958 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
8959 mkexpr(addr1),
8960 binop(Iop_Add64, mkexpr(addr1), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +00008961
8962 put_gpr_dw0(r1 + 1,
florian6ad49522011-09-09 02:38:55 +00008963 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
8964 mkU64(0), binop(Iop_Sub64, mkexpr(len1), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +00008965
8966 put_gpr_dw0(r3,
florian6ad49522011-09-09 02:38:55 +00008967 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
8968 mkexpr(addr3),
8969 binop(Iop_Add64, mkexpr(addr3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +00008970
8971 put_gpr_dw0(r3 + 1,
florian6ad49522011-09-09 02:38:55 +00008972 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
8973 mkU64(0), binop(Iop_Sub64, mkexpr(len3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +00008974
florian6820ba52012-07-26 02:01:50 +00008975 iterate();
sewardj2019a972011-03-07 16:04:07 +00008976
8977 return "clcle";
8978}
floriana64c2432011-07-16 02:11:50 +00008979
florianb0bf6602012-05-05 00:01:16 +00008980
sewardj2019a972011-03-07 16:04:07 +00008981static void
8982s390_irgen_XC_EX(IRTemp length, IRTemp start1, IRTemp start2)
8983{
florianb0bf6602012-05-05 00:01:16 +00008984 s390_irgen_xonc(Iop_Xor8, length, start1, start2);
8985}
sewardj2019a972011-03-07 16:04:07 +00008986
sewardj2019a972011-03-07 16:04:07 +00008987
florianb0bf6602012-05-05 00:01:16 +00008988static void
8989s390_irgen_NC_EX(IRTemp length, IRTemp start1, IRTemp start2)
8990{
8991 s390_irgen_xonc(Iop_And8, length, start1, start2);
8992}
sewardj2019a972011-03-07 16:04:07 +00008993
sewardj2019a972011-03-07 16:04:07 +00008994
florianb0bf6602012-05-05 00:01:16 +00008995static void
8996s390_irgen_OC_EX(IRTemp length, IRTemp start1, IRTemp start2)
8997{
8998 s390_irgen_xonc(Iop_Or8, length, start1, start2);
sewardj2019a972011-03-07 16:04:07 +00008999}
9000
9001
9002static void
9003s390_irgen_CLC_EX(IRTemp length, IRTemp start1, IRTemp start2)
9004{
9005 IRTemp current1 = newTemp(Ity_I8);
9006 IRTemp current2 = newTemp(Ity_I8);
9007 IRTemp counter = newTemp(Ity_I64);
9008
9009 assign(counter, get_counter_dw0());
9010 put_counter_dw0(mkU64(0));
9011
9012 assign(current1, load(Ity_I8, binop(Iop_Add64, mkexpr(start1),
9013 mkexpr(counter))));
9014 assign(current2, load(Ity_I8, binop(Iop_Add64, mkexpr(start2),
9015 mkexpr(counter))));
9016 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, current1, current2,
9017 False);
9018
9019 /* Both fields differ ? */
florian6820ba52012-07-26 02:01:50 +00009020 next_insn_if(binop(Iop_CmpNE8, mkexpr(current1), mkexpr(current2)));
sewardj2019a972011-03-07 16:04:07 +00009021
9022 /* Check for end of field */
9023 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
florian6820ba52012-07-26 02:01:50 +00009024 iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)));
sewardj2019a972011-03-07 16:04:07 +00009025 put_counter_dw0(mkU64(0));
9026}
9027
9028static void
9029s390_irgen_MVC_EX(IRTemp length, IRTemp start1, IRTemp start2)
9030{
9031 IRTemp counter = newTemp(Ity_I64);
9032
9033 assign(counter, get_counter_dw0());
9034
9035 store(binop(Iop_Add64, mkexpr(start1), mkexpr(counter)),
9036 load(Ity_I8, binop(Iop_Add64, mkexpr(start2), mkexpr(counter))));
9037
9038 /* Check for end of field */
9039 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
florian6820ba52012-07-26 02:01:50 +00009040 iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)));
sewardj2019a972011-03-07 16:04:07 +00009041 put_counter_dw0(mkU64(0));
9042}
9043
florianf87d4fb2012-05-05 02:55:24 +00009044static void
9045s390_irgen_TR_EX(IRTemp length, IRTemp start1, IRTemp start2)
9046{
9047 IRTemp op = newTemp(Ity_I8);
9048 IRTemp op1 = newTemp(Ity_I8);
9049 IRTemp result = newTemp(Ity_I64);
9050 IRTemp counter = newTemp(Ity_I64);
9051
9052 assign(counter, get_counter_dw0());
9053
9054 assign(op, load(Ity_I8, binop(Iop_Add64, mkexpr(start1), mkexpr(counter))));
9055
9056 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)), mkexpr(start2)));
9057
9058 assign(op1, load(Ity_I8, mkexpr(result)));
9059 store(binop(Iop_Add64, mkexpr(start1), mkexpr(counter)), mkexpr(op1));
9060
9061 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
florian6820ba52012-07-26 02:01:50 +00009062 iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)));
florianf87d4fb2012-05-05 02:55:24 +00009063 put_counter_dw0(mkU64(0));
9064}
sewardj2019a972011-03-07 16:04:07 +00009065
9066
9067static void
9068s390_irgen_EX_SS(UChar r, IRTemp addr2,
florian6820ba52012-07-26 02:01:50 +00009069 void (*irgen)(IRTemp length, IRTemp start1, IRTemp start2),
9070 int lensize)
sewardj2019a972011-03-07 16:04:07 +00009071{
9072 struct SS {
9073 unsigned int op : 8;
9074 unsigned int l : 8;
9075 unsigned int b1 : 4;
9076 unsigned int d1 : 12;
9077 unsigned int b2 : 4;
9078 unsigned int d2 : 12;
9079 };
9080 union {
9081 struct SS dec;
9082 unsigned long bytes;
9083 } ss;
9084 IRTemp cond;
9085 IRDirty *d;
9086 IRTemp torun;
9087
9088 IRTemp start1 = newTemp(Ity_I64);
9089 IRTemp start2 = newTemp(Ity_I64);
9090 IRTemp len = newTemp(lensize == 64 ? Ity_I64 : Ity_I32);
9091 cond = newTemp(Ity_I1);
9092 torun = newTemp(Ity_I64);
9093
9094 assign(torun, load(Ity_I64, mkexpr(addr2)));
9095 /* Start with a check that the saved code is still correct */
9096 assign(cond, binop(Iop_CmpNE64, mkexpr(torun), mkU64(last_execute_target)));
9097 /* If not, save the new value */
9098 d = unsafeIRDirty_0_N (0, "s390x_dirtyhelper_EX", &s390x_dirtyhelper_EX,
9099 mkIRExprVec_1(mkexpr(torun)));
9100 d->guard = mkexpr(cond);
9101 stmt(IRStmt_Dirty(d));
9102
9103 /* and restart */
florian428dfdd2012-03-27 03:09:49 +00009104 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TISTART),
9105 mkU64(guest_IA_curr_instr)));
9106 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TILEN), mkU64(4)));
florian6820ba52012-07-26 02:01:50 +00009107 restart_if(mkexpr(cond));
sewardj2019a972011-03-07 16:04:07 +00009108
9109 ss.bytes = last_execute_target;
9110 assign(start1, binop(Iop_Add64, mkU64(ss.dec.d1),
9111 ss.dec.b1 != 0 ? get_gpr_dw0(ss.dec.b1) : mkU64(0)));
9112 assign(start2, binop(Iop_Add64, mkU64(ss.dec.d2),
9113 ss.dec.b2 != 0 ? get_gpr_dw0(ss.dec.b2) : mkU64(0)));
9114 assign(len, unop(lensize == 64 ? Iop_8Uto64 : Iop_8Uto32, binop(Iop_Or8,
9115 r != 0 ? get_gpr_b7(r): mkU8(0), mkU8(ss.dec.l))));
9116 irgen(len, start1, start2);
florian8844a632012-04-13 04:04:06 +00009117
sewardj2019a972011-03-07 16:04:07 +00009118 last_execute_target = 0;
9119}
9120
9121static HChar *
9122s390_irgen_EX(UChar r1, IRTemp addr2)
9123{
9124 switch(last_execute_target & 0xff00000000000000ULL) {
9125 case 0:
9126 {
9127 /* no code information yet */
9128 IRDirty *d;
9129
9130 /* so safe the code... */
9131 d = unsafeIRDirty_0_N (0, "s390x_dirtyhelper_EX", &s390x_dirtyhelper_EX,
9132 mkIRExprVec_1(load(Ity_I64, mkexpr(addr2))));
9133 stmt(IRStmt_Dirty(d));
9134 /* and restart */
florian428dfdd2012-03-27 03:09:49 +00009135 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TISTART),
9136 mkU64(guest_IA_curr_instr)));
9137 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TILEN), mkU64(4)));
florian6820ba52012-07-26 02:01:50 +00009138 restart_if(IRExpr_Const(IRConst_U1(True)));
9139
sewardj2019a972011-03-07 16:04:07 +00009140 /* we know that this will be invalidated */
florianf9e1ed72012-04-17 02:41:56 +00009141 put_IA(mkaddr_expr(guest_IA_next_instr));
sewardj2019a972011-03-07 16:04:07 +00009142 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +00009143 dis_res->jk_StopHere = Ijk_TInval;
sewardj2019a972011-03-07 16:04:07 +00009144 break;
9145 }
9146
9147 case 0xd200000000000000ULL:
9148 /* special case MVC */
9149 s390_irgen_EX_SS(r1, addr2, s390_irgen_MVC_EX, 64);
9150 return "mvc via ex";
9151
9152 case 0xd500000000000000ULL:
9153 /* special case CLC */
9154 s390_irgen_EX_SS(r1, addr2, s390_irgen_CLC_EX, 64);
9155 return "clc via ex";
9156
9157 case 0xd700000000000000ULL:
9158 /* special case XC */
9159 s390_irgen_EX_SS(r1, addr2, s390_irgen_XC_EX, 32);
9160 return "xc via ex";
9161
florianb0bf6602012-05-05 00:01:16 +00009162 case 0xd600000000000000ULL:
9163 /* special case OC */
9164 s390_irgen_EX_SS(r1, addr2, s390_irgen_OC_EX, 32);
9165 return "oc via ex";
9166
9167 case 0xd400000000000000ULL:
9168 /* special case NC */
9169 s390_irgen_EX_SS(r1, addr2, s390_irgen_NC_EX, 32);
9170 return "nc via ex";
sewardj2019a972011-03-07 16:04:07 +00009171
florianf87d4fb2012-05-05 02:55:24 +00009172 case 0xdc00000000000000ULL:
9173 /* special case TR */
9174 s390_irgen_EX_SS(r1, addr2, s390_irgen_TR_EX, 64);
9175 return "tr via ex";
9176
sewardj2019a972011-03-07 16:04:07 +00009177 default:
9178 {
9179 /* everything else will get a self checking prefix that also checks the
9180 register content */
9181 IRDirty *d;
9182 UChar *bytes;
9183 IRTemp cond;
9184 IRTemp orperand;
9185 IRTemp torun;
9186
9187 cond = newTemp(Ity_I1);
9188 orperand = newTemp(Ity_I64);
9189 torun = newTemp(Ity_I64);
9190
9191 if (r1 == 0)
9192 assign(orperand, mkU64(0));
9193 else
9194 assign(orperand, unop(Iop_8Uto64,get_gpr_b7(r1)));
9195 /* This code is going to be translated */
9196 assign(torun, binop(Iop_Or64, load(Ity_I64, mkexpr(addr2)),
9197 binop(Iop_Shl64, mkexpr(orperand), mkU8(48))));
9198
9199 /* Start with a check that saved code is still correct */
9200 assign(cond, binop(Iop_CmpNE64, mkexpr(torun),
9201 mkU64(last_execute_target)));
9202 /* If not, save the new value */
9203 d = unsafeIRDirty_0_N (0, "s390x_dirtyhelper_EX", &s390x_dirtyhelper_EX,
9204 mkIRExprVec_1(mkexpr(torun)));
9205 d->guard = mkexpr(cond);
9206 stmt(IRStmt_Dirty(d));
9207
9208 /* and restart */
florian428dfdd2012-03-27 03:09:49 +00009209 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TISTART), mkU64(guest_IA_curr_instr)));
9210 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TILEN), mkU64(4)));
florian6820ba52012-07-26 02:01:50 +00009211 restart_if(mkexpr(cond));
sewardj2019a972011-03-07 16:04:07 +00009212
9213 /* Now comes the actual translation */
9214 bytes = (UChar *) &last_execute_target;
9215 s390_decode_and_irgen(bytes, ((((bytes[0] >> 6) + 1) >> 1) + 1) << 1,
9216 dis_res);
sewardj7ee97522011-05-09 21:45:04 +00009217 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00009218 vex_printf(" which was executed by\n");
9219 /* dont make useless translations in the next execute */
9220 last_execute_target = 0;
9221 }
9222 }
9223 return "ex";
9224}
9225
9226static HChar *
9227s390_irgen_EXRL(UChar r1, UInt offset)
9228{
9229 IRTemp addr = newTemp(Ity_I64);
9230 /* we might save one round trip because we know the target */
9231 if (!last_execute_target)
9232 last_execute_target = *(ULong *)(HWord)
9233 (guest_IA_curr_instr + offset * 2UL);
9234 assign(addr, mkU64(guest_IA_curr_instr + offset * 2UL));
9235 s390_irgen_EX(r1, addr);
9236 return "exrl";
9237}
9238
9239static HChar *
9240s390_irgen_IPM(UChar r1)
9241{
9242 // As long as we dont support SPM, lets just assume 0 as program mask
9243 put_gpr_b4(r1, unop(Iop_32to8, binop(Iop_Or32, mkU32(0 /* program mask */),
9244 binop(Iop_Shl32, s390_call_calculate_cc(), mkU8(4)))));
9245
9246 return "ipm";
9247}
9248
9249
9250static HChar *
9251s390_irgen_SRST(UChar r1, UChar r2)
9252{
9253 IRTemp address = newTemp(Ity_I64);
9254 IRTemp next = newTemp(Ity_I64);
9255 IRTemp delim = newTemp(Ity_I8);
9256 IRTemp counter = newTemp(Ity_I64);
9257 IRTemp byte = newTemp(Ity_I8);
9258
9259 assign(address, get_gpr_dw0(r2));
9260 assign(next, get_gpr_dw0(r1));
9261
9262 assign(counter, get_counter_dw0());
9263 put_counter_dw0(mkU64(0));
9264
9265 // start = next? CC=2 and out r1 and r2 unchanged
9266 s390_cc_set(2);
9267 put_gpr_dw0(r2, binop(Iop_Sub64, mkexpr(address), mkexpr(counter)));
florian6820ba52012-07-26 02:01:50 +00009268 next_insn_if(binop(Iop_CmpEQ64, mkexpr(address), mkexpr(next)));
sewardj2019a972011-03-07 16:04:07 +00009269
9270 assign(byte, load(Ity_I8, mkexpr(address)));
9271 assign(delim, get_gpr_b7(0));
9272
9273 // byte = delim? CC=1, R1=address
9274 s390_cc_set(1);
9275 put_gpr_dw0(r1, mkexpr(address));
florian6820ba52012-07-26 02:01:50 +00009276 next_insn_if(binop(Iop_CmpEQ8, mkexpr(delim), mkexpr(byte)));
sewardj2019a972011-03-07 16:04:07 +00009277
9278 // else: all equal, no end yet, loop
9279 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
9280 put_gpr_dw0(r1, mkexpr(next));
9281 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(address), mkU64(1)));
floriancf87c942012-07-25 00:52:21 +00009282
florian6820ba52012-07-26 02:01:50 +00009283 iterate();
sewardj2019a972011-03-07 16:04:07 +00009284
9285 return "srst";
9286}
9287
9288static HChar *
9289s390_irgen_CLST(UChar r1, UChar r2)
9290{
9291 IRTemp address1 = newTemp(Ity_I64);
9292 IRTemp address2 = newTemp(Ity_I64);
9293 IRTemp end = newTemp(Ity_I8);
9294 IRTemp counter = newTemp(Ity_I64);
9295 IRTemp byte1 = newTemp(Ity_I8);
9296 IRTemp byte2 = newTemp(Ity_I8);
9297
9298 assign(address1, get_gpr_dw0(r1));
9299 assign(address2, get_gpr_dw0(r2));
9300 assign(end, get_gpr_b7(0));
9301 assign(counter, get_counter_dw0());
9302 put_counter_dw0(mkU64(0));
9303 assign(byte1, load(Ity_I8, mkexpr(address1)));
9304 assign(byte2, load(Ity_I8, mkexpr(address2)));
9305
9306 // end in both? all equal, reset r1 and r2 to start values
9307 s390_cc_set(0);
9308 put_gpr_dw0(r1, binop(Iop_Sub64, mkexpr(address1), mkexpr(counter)));
9309 put_gpr_dw0(r2, binop(Iop_Sub64, mkexpr(address2), mkexpr(counter)));
florian6820ba52012-07-26 02:01:50 +00009310 next_insn_if(binop(Iop_CmpEQ8, mkU8(0),
9311 binop(Iop_Or8,
9312 binop(Iop_Xor8, mkexpr(byte1), mkexpr(end)),
9313 binop(Iop_Xor8, mkexpr(byte2), mkexpr(end)))));
sewardj2019a972011-03-07 16:04:07 +00009314
9315 put_gpr_dw0(r1, mkexpr(address1));
9316 put_gpr_dw0(r2, mkexpr(address2));
9317
9318 // End found in string1
9319 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +00009320 next_insn_if(binop(Iop_CmpEQ8, mkexpr(end), mkexpr(byte1)));
sewardj2019a972011-03-07 16:04:07 +00009321
9322 // End found in string2
9323 s390_cc_set(2);
florian6820ba52012-07-26 02:01:50 +00009324 next_insn_if(binop(Iop_CmpEQ8, mkexpr(end), mkexpr(byte2)));
sewardj2019a972011-03-07 16:04:07 +00009325
9326 // string1 < string2
9327 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +00009328 next_insn_if(binop(Iop_CmpLT32U, unop(Iop_8Uto32, mkexpr(byte1)),
9329 unop(Iop_8Uto32, mkexpr(byte2))));
sewardj2019a972011-03-07 16:04:07 +00009330
9331 // string2 < string1
9332 s390_cc_set(2);
florian6820ba52012-07-26 02:01:50 +00009333 next_insn_if(binop(Iop_CmpLT32U, unop(Iop_8Uto32, mkexpr(byte2)),
9334 unop(Iop_8Uto32, mkexpr(byte1))));
sewardj2019a972011-03-07 16:04:07 +00009335
9336 // else: all equal, no end yet, loop
9337 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
9338 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), mkU64(1)));
9339 put_gpr_dw0(r2, binop(Iop_Add64, get_gpr_dw0(r2), mkU64(1)));
floriancf87c942012-07-25 00:52:21 +00009340
florian6820ba52012-07-26 02:01:50 +00009341 iterate();
sewardj2019a972011-03-07 16:04:07 +00009342
9343 return "clst";
9344}
9345
9346static void
9347s390_irgen_load_multiple_32bit(UChar r1, UChar r3, IRTemp op2addr)
9348{
9349 UChar reg;
9350 IRTemp addr = newTemp(Ity_I64);
9351
9352 assign(addr, mkexpr(op2addr));
9353 reg = r1;
9354 do {
9355 IRTemp old = addr;
9356
9357 reg %= 16;
9358 put_gpr_w1(reg, load(Ity_I32, mkexpr(addr)));
9359 addr = newTemp(Ity_I64);
9360 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
9361 reg++;
9362 } while (reg != (r3 + 1));
9363}
9364
9365static HChar *
9366s390_irgen_LM(UChar r1, UChar r3, IRTemp op2addr)
9367{
9368 s390_irgen_load_multiple_32bit(r1, r3, op2addr);
9369
9370 return "lm";
9371}
9372
9373static HChar *
9374s390_irgen_LMY(UChar r1, UChar r3, IRTemp op2addr)
9375{
9376 s390_irgen_load_multiple_32bit(r1, r3, op2addr);
9377
9378 return "lmy";
9379}
9380
9381static HChar *
9382s390_irgen_LMH(UChar r1, UChar r3, IRTemp op2addr)
9383{
9384 UChar reg;
9385 IRTemp addr = newTemp(Ity_I64);
9386
9387 assign(addr, mkexpr(op2addr));
9388 reg = r1;
9389 do {
9390 IRTemp old = addr;
9391
9392 reg %= 16;
9393 put_gpr_w0(reg, load(Ity_I32, mkexpr(addr)));
9394 addr = newTemp(Ity_I64);
9395 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
9396 reg++;
9397 } while (reg != (r3 + 1));
9398
9399 return "lmh";
9400}
9401
9402static HChar *
9403s390_irgen_LMG(UChar r1, UChar r3, IRTemp op2addr)
9404{
9405 UChar reg;
9406 IRTemp addr = newTemp(Ity_I64);
9407
9408 assign(addr, mkexpr(op2addr));
9409 reg = r1;
9410 do {
9411 IRTemp old = addr;
9412
9413 reg %= 16;
9414 put_gpr_dw0(reg, load(Ity_I64, mkexpr(addr)));
9415 addr = newTemp(Ity_I64);
9416 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(8)));
9417 reg++;
9418 } while (reg != (r3 + 1));
9419
9420 return "lmg";
9421}
9422
9423static void
9424s390_irgen_store_multiple_32bit(UChar r1, UChar r3, IRTemp op2addr)
9425{
9426 UChar reg;
9427 IRTemp addr = newTemp(Ity_I64);
9428
9429 assign(addr, mkexpr(op2addr));
9430 reg = r1;
9431 do {
9432 IRTemp old = addr;
9433
9434 reg %= 16;
9435 store(mkexpr(addr), get_gpr_w1(reg));
9436 addr = newTemp(Ity_I64);
9437 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
9438 reg++;
9439 } while( reg != (r3 + 1));
9440}
9441
9442static HChar *
9443s390_irgen_STM(UChar r1, UChar r3, IRTemp op2addr)
9444{
9445 s390_irgen_store_multiple_32bit(r1, r3, op2addr);
9446
9447 return "stm";
9448}
9449
9450static HChar *
9451s390_irgen_STMY(UChar r1, UChar r3, IRTemp op2addr)
9452{
9453 s390_irgen_store_multiple_32bit(r1, r3, op2addr);
9454
9455 return "stmy";
9456}
9457
9458static HChar *
9459s390_irgen_STMH(UChar r1, UChar r3, IRTemp op2addr)
9460{
9461 UChar reg;
9462 IRTemp addr = newTemp(Ity_I64);
9463
9464 assign(addr, mkexpr(op2addr));
9465 reg = r1;
9466 do {
9467 IRTemp old = addr;
9468
9469 reg %= 16;
9470 store(mkexpr(addr), get_gpr_w0(reg));
9471 addr = newTemp(Ity_I64);
9472 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
9473 reg++;
9474 } while( reg != (r3 + 1));
9475
9476 return "stmh";
9477}
9478
9479static HChar *
9480s390_irgen_STMG(UChar r1, UChar r3, IRTemp op2addr)
9481{
9482 UChar reg;
9483 IRTemp addr = newTemp(Ity_I64);
9484
9485 assign(addr, mkexpr(op2addr));
9486 reg = r1;
9487 do {
9488 IRTemp old = addr;
9489
9490 reg %= 16;
9491 store(mkexpr(addr), get_gpr_dw0(reg));
9492 addr = newTemp(Ity_I64);
9493 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(8)));
9494 reg++;
9495 } while( reg != (r3 + 1));
9496
9497 return "stmg";
9498}
9499
9500static void
florianb0bf6602012-05-05 00:01:16 +00009501s390_irgen_xonc(IROp op, IRTemp length, IRTemp start1, IRTemp start2)
sewardj2019a972011-03-07 16:04:07 +00009502{
9503 IRTemp old1 = newTemp(Ity_I8);
9504 IRTemp old2 = newTemp(Ity_I8);
9505 IRTemp new1 = newTemp(Ity_I8);
9506 IRTemp counter = newTemp(Ity_I32);
9507 IRTemp addr1 = newTemp(Ity_I64);
9508
9509 assign(counter, get_counter_w0());
9510
9511 assign(addr1, binop(Iop_Add64, mkexpr(start1),
9512 unop(Iop_32Uto64, mkexpr(counter))));
9513
9514 assign(old1, load(Ity_I8, mkexpr(addr1)));
9515 assign(old2, load(Ity_I8, binop(Iop_Add64, mkexpr(start2),
9516 unop(Iop_32Uto64,mkexpr(counter)))));
9517 assign(new1, binop(op, mkexpr(old1), mkexpr(old2)));
9518
9519 /* Special case: xc is used to zero memory */
sewardj2019a972011-03-07 16:04:07 +00009520 if (op == Iop_Xor8) {
9521 store(mkexpr(addr1),
florian6ad49522011-09-09 02:38:55 +00009522 mkite(binop(Iop_CmpEQ64, mkexpr(start1), mkexpr(start2)),
9523 mkU8(0), mkexpr(new1)));
sewardj2019a972011-03-07 16:04:07 +00009524 } else
9525 store(mkexpr(addr1), mkexpr(new1));
9526 put_counter_w1(binop(Iop_Or32, unop(Iop_8Uto32, mkexpr(new1)),
9527 get_counter_w1()));
9528
9529 /* Check for end of field */
9530 put_counter_w0(binop(Iop_Add32, mkexpr(counter), mkU32(1)));
florian6820ba52012-07-26 02:01:50 +00009531 iterate_if(binop(Iop_CmpNE32, mkexpr(counter), mkexpr(length)));
sewardj2019a972011-03-07 16:04:07 +00009532 s390_cc_thunk_put1(S390_CC_OP_BITWISE, mktemp(Ity_I32, get_counter_w1()),
9533 False);
9534 put_counter_dw0(mkU64(0));
9535}
9536
9537static HChar *
9538s390_irgen_XC(UChar length, IRTemp start1, IRTemp start2)
9539{
florianb0bf6602012-05-05 00:01:16 +00009540 IRTemp len = newTemp(Ity_I32);
9541
9542 assign(len, mkU32(length));
9543 s390_irgen_xonc(Iop_Xor8, len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +00009544
9545 return "xc";
9546}
9547
sewardjb63967e2011-03-24 08:50:04 +00009548static void
9549s390_irgen_XC_sameloc(UChar length, UChar b, UShort d)
9550{
9551 IRTemp counter = newTemp(Ity_I32);
9552 IRTemp start = newTemp(Ity_I64);
9553 IRTemp addr = newTemp(Ity_I64);
9554
9555 assign(start,
9556 binop(Iop_Add64, mkU64(d), b != 0 ? get_gpr_dw0(b) : mkU64(0)));
9557
9558 if (length < 8) {
9559 UInt i;
9560
9561 for (i = 0; i <= length; ++i) {
9562 store(binop(Iop_Add64, mkexpr(start), mkU64(i)), mkU8(0));
9563 }
9564 } else {
9565 assign(counter, get_counter_w0());
9566
9567 assign(addr, binop(Iop_Add64, mkexpr(start),
9568 unop(Iop_32Uto64, mkexpr(counter))));
9569
9570 store(mkexpr(addr), mkU8(0));
9571
9572 /* Check for end of field */
9573 put_counter_w0(binop(Iop_Add32, mkexpr(counter), mkU32(1)));
florian6820ba52012-07-26 02:01:50 +00009574 iterate_if(binop(Iop_CmpNE32, mkexpr(counter), mkU32(length)));
sewardjb63967e2011-03-24 08:50:04 +00009575
9576 /* Reset counter */
9577 put_counter_dw0(mkU64(0));
9578 }
9579
9580 s390_cc_thunk_put1(S390_CC_OP_BITWISE, mktemp(Ity_I32, mkU32(0)), False);
9581
sewardj7ee97522011-05-09 21:45:04 +00009582 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardjb63967e2011-03-24 08:50:04 +00009583 s390_disasm(ENC3(MNM, UDLB, UDXB), "xc", d, length, b, d, 0, b);
9584}
9585
sewardj2019a972011-03-07 16:04:07 +00009586static HChar *
9587s390_irgen_NC(UChar length, IRTemp start1, IRTemp start2)
9588{
florianb0bf6602012-05-05 00:01:16 +00009589 IRTemp len = newTemp(Ity_I32);
9590
9591 assign(len, mkU32(length));
9592 s390_irgen_xonc(Iop_And8, len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +00009593
9594 return "nc";
9595}
9596
9597static HChar *
9598s390_irgen_OC(UChar length, IRTemp start1, IRTemp start2)
9599{
florianb0bf6602012-05-05 00:01:16 +00009600 IRTemp len = newTemp(Ity_I32);
9601
9602 assign(len, mkU32(length));
9603 s390_irgen_xonc(Iop_Or8, len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +00009604
9605 return "oc";
9606}
9607
9608
9609static HChar *
9610s390_irgen_MVC(UChar length, IRTemp start1, IRTemp start2)
9611{
florian79e839e2012-05-05 02:20:30 +00009612 IRTemp len = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00009613
florian79e839e2012-05-05 02:20:30 +00009614 assign(len, mkU64(length));
9615 s390_irgen_MVC_EX(len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +00009616
9617 return "mvc";
9618}
9619
9620static HChar *
florianb0c9a132011-09-08 15:37:39 +00009621s390_irgen_MVCL(UChar r1, UChar r2)
9622{
9623 IRTemp addr1 = newTemp(Ity_I64);
9624 IRTemp addr2 = newTemp(Ity_I64);
9625 IRTemp addr2_load = newTemp(Ity_I64);
9626 IRTemp r1p1 = newTemp(Ity_I32); /* contents of r1 + 1 */
9627 IRTemp r2p1 = newTemp(Ity_I32); /* contents of r2 + 1 */
9628 IRTemp len1 = newTemp(Ity_I32);
9629 IRTemp len2 = newTemp(Ity_I32);
9630 IRTemp pad = newTemp(Ity_I8);
9631 IRTemp single = newTemp(Ity_I8);
9632
9633 assign(addr1, get_gpr_dw0(r1));
9634 assign(r1p1, get_gpr_w1(r1 + 1));
9635 assign(len1, binop(Iop_And32, mkexpr(r1p1), mkU32(0x00ffffff)));
9636 assign(addr2, get_gpr_dw0(r2));
9637 assign(r2p1, get_gpr_w1(r2 + 1));
9638 assign(len2, binop(Iop_And32, mkexpr(r2p1), mkU32(0x00ffffff)));
9639 assign(pad, get_gpr_b4(r2 + 1));
9640
9641 /* len1 == 0 ? */
9642 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len2, False);
florian6820ba52012-07-26 02:01:50 +00009643 next_insn_if(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)));
florianb0c9a132011-09-08 15:37:39 +00009644
9645 /* Check for destructive overlap:
9646 addr1 > addr2 && addr2 + len1 > addr1 && (addr2 + len2) > addr1 */
9647 s390_cc_set(3);
9648 IRTemp cond1 = newTemp(Ity_I32);
9649 assign(cond1, unop(Iop_1Uto32,
9650 binop(Iop_CmpLT64U, mkexpr(addr2), mkexpr(addr1))));
9651 IRTemp cond2 = newTemp(Ity_I32);
9652 assign(cond2, unop(Iop_1Uto32,
9653 binop(Iop_CmpLT64U, mkexpr(addr1),
9654 binop(Iop_Add64, mkexpr(addr2),
9655 unop(Iop_32Uto64, mkexpr(len1))))));
9656 IRTemp cond3 = newTemp(Ity_I32);
9657 assign(cond3, unop(Iop_1Uto32,
9658 binop(Iop_CmpLT64U,
9659 mkexpr(addr1),
9660 binop(Iop_Add64, mkexpr(addr2),
9661 unop(Iop_32Uto64, mkexpr(len2))))));
9662
florian6820ba52012-07-26 02:01:50 +00009663 next_insn_if(binop(Iop_CmpEQ32,
9664 binop(Iop_And32,
9665 binop(Iop_And32, mkexpr(cond1), mkexpr(cond2)),
9666 mkexpr(cond3)),
9667 mkU32(1)));
florianb0c9a132011-09-08 15:37:39 +00009668
9669 /* See s390_irgen_CLCL for explanation why we cannot load directly
9670 and need two steps. */
9671 assign(addr2_load,
9672 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
9673 mkU64(guest_IA_curr_instr), mkexpr(addr2)));
9674 assign(single,
9675 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
9676 mkexpr(pad), load(Ity_I8, mkexpr(addr2_load))));
9677
9678 store(mkexpr(addr1), mkexpr(single));
9679
9680 /* Update addr1 and len1 */
9681 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkU64(1)));
9682 put_gpr_w1(r1 + 1, binop(Iop_Sub32, mkexpr(r1p1), mkU32(1)));
9683
9684 /* Update addr2 and len2 */
9685 put_gpr_dw0(r2,
9686 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
9687 mkexpr(addr2),
9688 binop(Iop_Add64, mkexpr(addr2), mkU64(1))));
9689
9690 /* When updating len2 we must not modify bits (r2+1)[0:39] */
9691 put_gpr_w1(r2 + 1,
9692 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
9693 binop(Iop_And32, mkexpr(r2p1), mkU32(0xFF000000u)),
9694 binop(Iop_Sub32, mkexpr(r2p1), mkU32(1))));
9695
9696 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len2, False);
florian6820ba52012-07-26 02:01:50 +00009697 iterate_if(binop(Iop_CmpNE32, mkexpr(len1), mkU32(1)));
florianb0c9a132011-09-08 15:37:39 +00009698
9699 return "mvcl";
9700}
9701
9702
9703static HChar *
sewardj2019a972011-03-07 16:04:07 +00009704s390_irgen_MVCLE(UChar r1, UChar r3, IRTemp pad2)
9705{
9706 IRTemp addr1, addr3, addr3_load, len1, len3, single;
9707
9708 addr1 = newTemp(Ity_I64);
9709 addr3 = newTemp(Ity_I64);
9710 addr3_load = newTemp(Ity_I64);
9711 len1 = newTemp(Ity_I64);
9712 len3 = newTemp(Ity_I64);
9713 single = newTemp(Ity_I8);
9714
9715 assign(addr1, get_gpr_dw0(r1));
9716 assign(len1, get_gpr_dw0(r1 + 1));
9717 assign(addr3, get_gpr_dw0(r3));
9718 assign(len3, get_gpr_dw0(r3 + 1));
9719
9720 // len1 == 0 ?
9721 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len3, False);
florian6820ba52012-07-26 02:01:50 +00009722 next_insn_if(binop(Iop_CmpEQ64,mkexpr(len1), mkU64(0)));
sewardj2019a972011-03-07 16:04:07 +00009723
9724 /* This is a hack to prevent mvcle from reading from addr3 if it
9725 should read from the pad. Since the pad has no address, just
9726 read from the instruction, we discard that anyway */
9727 assign(addr3_load,
florian6ad49522011-09-09 02:38:55 +00009728 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
9729 mkU64(guest_IA_curr_instr), mkexpr(addr3)));
sewardj2019a972011-03-07 16:04:07 +00009730
9731 assign(single,
florian6ad49522011-09-09 02:38:55 +00009732 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
9733 unop(Iop_64to8, mkexpr(pad2)),
9734 load(Ity_I8, mkexpr(addr3_load))));
sewardj2019a972011-03-07 16:04:07 +00009735 store(mkexpr(addr1), mkexpr(single));
9736
9737 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkU64(1)));
9738
9739 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkU64(1)));
9740
9741 put_gpr_dw0(r3,
florian6ad49522011-09-09 02:38:55 +00009742 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
9743 mkexpr(addr3),
9744 binop(Iop_Add64, mkexpr(addr3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +00009745
9746 put_gpr_dw0(r3 + 1,
florian6ad49522011-09-09 02:38:55 +00009747 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
9748 mkU64(0), binop(Iop_Sub64, mkexpr(len3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +00009749
sewardj2019a972011-03-07 16:04:07 +00009750 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len3, False);
florian6820ba52012-07-26 02:01:50 +00009751 iterate_if(binop(Iop_CmpNE64, mkexpr(len1), mkU64(1)));
sewardj2019a972011-03-07 16:04:07 +00009752
9753 return "mvcle";
9754}
9755
9756static HChar *
9757s390_irgen_MVST(UChar r1, UChar r2)
9758{
9759 IRTemp addr1 = newTemp(Ity_I64);
9760 IRTemp addr2 = newTemp(Ity_I64);
9761 IRTemp end = newTemp(Ity_I8);
9762 IRTemp byte = newTemp(Ity_I8);
9763 IRTemp counter = newTemp(Ity_I64);
9764
9765 assign(addr1, get_gpr_dw0(r1));
9766 assign(addr2, get_gpr_dw0(r2));
9767 assign(counter, get_counter_dw0());
9768 assign(end, get_gpr_b7(0));
9769 assign(byte, load(Ity_I8, binop(Iop_Add64, mkexpr(addr2),mkexpr(counter))));
9770 store(binop(Iop_Add64,mkexpr(addr1),mkexpr(counter)), mkexpr(byte));
9771
9772 // We use unlimited as cpu-determined number
9773 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
florian6820ba52012-07-26 02:01:50 +00009774 iterate_if(binop(Iop_CmpNE8, mkexpr(end), mkexpr(byte)));
sewardj2019a972011-03-07 16:04:07 +00009775
9776 // and always set cc=1 at the end + update r1
9777 s390_cc_set(1);
9778 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(counter)));
9779 put_counter_dw0(mkU64(0));
9780
9781 return "mvst";
9782}
9783
9784static void
9785s390_irgen_divide_64to32(IROp op, UChar r1, IRTemp op2)
9786{
9787 IRTemp op1 = newTemp(Ity_I64);
9788 IRTemp result = newTemp(Ity_I64);
9789
9790 assign(op1, binop(Iop_32HLto64,
9791 get_gpr_w1(r1), // high 32 bits
9792 get_gpr_w1(r1 + 1))); // low 32 bits
9793 assign(result, binop(op, mkexpr(op1), mkexpr(op2)));
9794 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result))); // remainder
9795 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result))); // quotient
9796}
9797
9798static void
9799s390_irgen_divide_128to64(IROp op, UChar r1, IRTemp op2)
9800{
9801 IRTemp op1 = newTemp(Ity_I128);
9802 IRTemp result = newTemp(Ity_I128);
9803
9804 assign(op1, binop(Iop_64HLto128,
9805 get_gpr_dw0(r1), // high 64 bits
9806 get_gpr_dw0(r1 + 1))); // low 64 bits
9807 assign(result, binop(op, mkexpr(op1), mkexpr(op2)));
9808 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result))); // remainder
9809 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result))); // quotient
9810}
9811
9812static void
9813s390_irgen_divide_64to64(IROp op, UChar r1, IRTemp op2)
9814{
9815 IRTemp op1 = newTemp(Ity_I64);
9816 IRTemp result = newTemp(Ity_I128);
9817
9818 assign(op1, get_gpr_dw0(r1 + 1));
9819 assign(result, binop(op, mkexpr(op1), mkexpr(op2)));
9820 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result))); // remainder
9821 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result))); // quotient
9822}
9823
9824static HChar *
9825s390_irgen_DR(UChar r1, UChar r2)
9826{
9827 IRTemp op2 = newTemp(Ity_I32);
9828
9829 assign(op2, get_gpr_w1(r2));
9830
9831 s390_irgen_divide_64to32(Iop_DivModS64to32, r1, op2);
9832
9833 return "dr";
9834}
9835
9836static HChar *
9837s390_irgen_D(UChar r1, IRTemp op2addr)
9838{
9839 IRTemp op2 = newTemp(Ity_I32);
9840
9841 assign(op2, load(Ity_I32, mkexpr(op2addr)));
9842
9843 s390_irgen_divide_64to32(Iop_DivModS64to32, r1, op2);
9844
9845 return "d";
9846}
9847
9848static HChar *
9849s390_irgen_DLR(UChar r1, UChar r2)
9850{
9851 IRTemp op2 = newTemp(Ity_I32);
9852
9853 assign(op2, get_gpr_w1(r2));
9854
9855 s390_irgen_divide_64to32(Iop_DivModU64to32, r1, op2);
9856
florian7cd1cde2012-08-16 23:57:43 +00009857 return "dlr";
sewardj2019a972011-03-07 16:04:07 +00009858}
9859
9860static HChar *
9861s390_irgen_DL(UChar r1, IRTemp op2addr)
9862{
9863 IRTemp op2 = newTemp(Ity_I32);
9864
9865 assign(op2, load(Ity_I32, mkexpr(op2addr)));
9866
9867 s390_irgen_divide_64to32(Iop_DivModU64to32, r1, op2);
9868
9869 return "dl";
9870}
9871
9872static HChar *
9873s390_irgen_DLG(UChar r1, IRTemp op2addr)
9874{
9875 IRTemp op2 = newTemp(Ity_I64);
9876
9877 assign(op2, load(Ity_I64, mkexpr(op2addr)));
9878
9879 s390_irgen_divide_128to64(Iop_DivModU128to64, r1, op2);
9880
9881 return "dlg";
9882}
9883
9884static HChar *
9885s390_irgen_DLGR(UChar r1, UChar r2)
9886{
9887 IRTemp op2 = newTemp(Ity_I64);
9888
9889 assign(op2, get_gpr_dw0(r2));
9890
9891 s390_irgen_divide_128to64(Iop_DivModU128to64, r1, op2);
9892
9893 return "dlgr";
9894}
9895
9896static HChar *
9897s390_irgen_DSGR(UChar r1, UChar r2)
9898{
9899 IRTemp op2 = newTemp(Ity_I64);
9900
9901 assign(op2, get_gpr_dw0(r2));
9902
9903 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
9904
9905 return "dsgr";
9906}
9907
9908static HChar *
9909s390_irgen_DSG(UChar r1, IRTemp op2addr)
9910{
9911 IRTemp op2 = newTemp(Ity_I64);
9912
9913 assign(op2, load(Ity_I64, mkexpr(op2addr)));
9914
9915 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
9916
9917 return "dsg";
9918}
9919
9920static HChar *
9921s390_irgen_DSGFR(UChar r1, UChar r2)
9922{
9923 IRTemp op2 = newTemp(Ity_I64);
9924
9925 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
9926
9927 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
9928
9929 return "dsgfr";
9930}
9931
9932static HChar *
9933s390_irgen_DSGF(UChar r1, IRTemp op2addr)
9934{
9935 IRTemp op2 = newTemp(Ity_I64);
9936
9937 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
9938
9939 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
9940
9941 return "dsgf";
9942}
9943
9944static void
9945s390_irgen_load_ar_multiple(UChar r1, UChar r3, IRTemp op2addr)
9946{
9947 UChar reg;
9948 IRTemp addr = newTemp(Ity_I64);
9949
9950 assign(addr, mkexpr(op2addr));
9951 reg = r1;
9952 do {
9953 IRTemp old = addr;
9954
9955 reg %= 16;
9956 put_ar_w0(reg, load(Ity_I32, mkexpr(addr)));
9957 addr = newTemp(Ity_I64);
9958 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
9959 reg++;
9960 } while (reg != (r3 + 1));
9961}
9962
9963static HChar *
9964s390_irgen_LAM(UChar r1, UChar r3, IRTemp op2addr)
9965{
9966 s390_irgen_load_ar_multiple(r1, r3, op2addr);
9967
9968 return "lam";
9969}
9970
9971static HChar *
9972s390_irgen_LAMY(UChar r1, UChar r3, IRTemp op2addr)
9973{
9974 s390_irgen_load_ar_multiple(r1, r3, op2addr);
9975
9976 return "lamy";
9977}
9978
9979static void
9980s390_irgen_store_ar_multiple(UChar r1, UChar r3, IRTemp op2addr)
9981{
9982 UChar reg;
9983 IRTemp addr = newTemp(Ity_I64);
9984
9985 assign(addr, mkexpr(op2addr));
9986 reg = r1;
9987 do {
9988 IRTemp old = addr;
9989
9990 reg %= 16;
9991 store(mkexpr(addr), get_ar_w0(reg));
9992 addr = newTemp(Ity_I64);
9993 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
9994 reg++;
9995 } while (reg != (r3 + 1));
9996}
9997
9998static HChar *
9999s390_irgen_STAM(UChar r1, UChar r3, IRTemp op2addr)
10000{
10001 s390_irgen_store_ar_multiple(r1, r3, op2addr);
10002
10003 return "stam";
10004}
10005
10006static HChar *
10007s390_irgen_STAMY(UChar r1, UChar r3, IRTemp op2addr)
10008{
10009 s390_irgen_store_ar_multiple(r1, r3, op2addr);
10010
10011 return "stamy";
10012}
10013
10014
10015/* Implementation for 32-bit compare-and-swap */
10016static void
10017s390_irgen_cas_32(UChar r1, UChar r3, IRTemp op2addr)
10018{
10019 IRCAS *cas;
10020 IRTemp op1 = newTemp(Ity_I32);
10021 IRTemp old_mem = newTemp(Ity_I32);
10022 IRTemp op3 = newTemp(Ity_I32);
10023 IRTemp result = newTemp(Ity_I32);
10024 IRTemp nequal = newTemp(Ity_I1);
10025
10026 assign(op1, get_gpr_w1(r1));
10027 assign(op3, get_gpr_w1(r3));
10028
10029 /* The first and second operands are compared. If they are equal,
10030 the third operand is stored at the second- operand location. */
10031 cas = mkIRCAS(IRTemp_INVALID, old_mem,
10032 Iend_BE, mkexpr(op2addr),
10033 NULL, mkexpr(op1), /* expected value */
10034 NULL, mkexpr(op3) /* new value */);
10035 stmt(IRStmt_CAS(cas));
10036
10037 /* Set CC. Operands compared equal -> 0, else 1. */
10038 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(old_mem)));
10039 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
10040
10041 /* If operands were equal (cc == 0) just store the old value op1 in r1.
10042 Otherwise, store the old_value from memory in r1 and yield. */
10043 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
10044 put_gpr_w1(r1, mkite(mkexpr(nequal), mkexpr(old_mem), mkexpr(op1)));
florian6820ba52012-07-26 02:01:50 +000010045 yield_if(mkexpr(nequal));
sewardj2019a972011-03-07 16:04:07 +000010046}
10047
10048static HChar *
10049s390_irgen_CS(UChar r1, UChar r3, IRTemp op2addr)
10050{
10051 s390_irgen_cas_32(r1, r3, op2addr);
10052
10053 return "cs";
10054}
10055
10056static HChar *
10057s390_irgen_CSY(UChar r1, UChar r3, IRTemp op2addr)
10058{
10059 s390_irgen_cas_32(r1, r3, op2addr);
10060
10061 return "csy";
10062}
10063
10064static HChar *
10065s390_irgen_CSG(UChar r1, UChar r3, IRTemp op2addr)
10066{
10067 IRCAS *cas;
10068 IRTemp op1 = newTemp(Ity_I64);
10069 IRTemp old_mem = newTemp(Ity_I64);
10070 IRTemp op3 = newTemp(Ity_I64);
10071 IRTemp result = newTemp(Ity_I64);
10072 IRTemp nequal = newTemp(Ity_I1);
10073
10074 assign(op1, get_gpr_dw0(r1));
10075 assign(op3, get_gpr_dw0(r3));
10076
10077 /* The first and second operands are compared. If they are equal,
10078 the third operand is stored at the second- operand location. */
10079 cas = mkIRCAS(IRTemp_INVALID, old_mem,
10080 Iend_BE, mkexpr(op2addr),
10081 NULL, mkexpr(op1), /* expected value */
10082 NULL, mkexpr(op3) /* new value */);
10083 stmt(IRStmt_CAS(cas));
10084
10085 /* Set CC. Operands compared equal -> 0, else 1. */
10086 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(old_mem)));
10087 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
10088
10089 /* If operands were equal (cc == 0) just store the old value op1 in r1.
10090 Otherwise, store the old_value from memory in r1 and yield. */
10091 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
10092 put_gpr_dw0(r1, mkite(mkexpr(nequal), mkexpr(old_mem), mkexpr(op1)));
florian6820ba52012-07-26 02:01:50 +000010093 yield_if(mkexpr(nequal));
sewardj2019a972011-03-07 16:04:07 +000010094
10095 return "csg";
10096}
10097
florian448cbba2012-06-06 02:26:01 +000010098/* Implementation for 32-bit compare-double-and-swap */
10099static void
10100s390_irgen_cdas_32(UChar r1, UChar r3, IRTemp op2addr)
10101{
10102 IRCAS *cas;
10103 IRTemp op1_high = newTemp(Ity_I32);
10104 IRTemp op1_low = newTemp(Ity_I32);
10105 IRTemp old_mem_high = newTemp(Ity_I32);
10106 IRTemp old_mem_low = newTemp(Ity_I32);
10107 IRTemp op3_high = newTemp(Ity_I32);
10108 IRTemp op3_low = newTemp(Ity_I32);
10109 IRTemp result = newTemp(Ity_I32);
10110 IRTemp nequal = newTemp(Ity_I1);
10111
10112 assign(op1_high, get_gpr_w1(r1));
10113 assign(op1_low, get_gpr_w1(r1+1));
10114 assign(op3_high, get_gpr_w1(r3));
10115 assign(op3_low, get_gpr_w1(r3+1));
10116
10117 /* The first and second operands are compared. If they are equal,
10118 the third operand is stored at the second-operand location. */
10119 cas = mkIRCAS(old_mem_high, old_mem_low,
10120 Iend_BE, mkexpr(op2addr),
10121 mkexpr(op1_high), mkexpr(op1_low), /* expected value */
10122 mkexpr(op3_high), mkexpr(op3_low) /* new value */);
10123 stmt(IRStmt_CAS(cas));
10124
10125 /* Set CC. Operands compared equal -> 0, else 1. */
10126 assign(result, unop(Iop_1Uto32,
10127 binop(Iop_CmpNE32,
10128 binop(Iop_Or32,
10129 binop(Iop_Xor32, mkexpr(op1_high), mkexpr(old_mem_high)),
10130 binop(Iop_Xor32, mkexpr(op1_low), mkexpr(old_mem_low))),
10131 mkU32(0))));
10132
10133 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
10134
10135 /* If operands were equal (cc == 0) just store the old value op1 in r1.
10136 Otherwise, store the old_value from memory in r1 and yield. */
10137 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
10138 put_gpr_w1(r1, mkite(mkexpr(nequal), mkexpr(old_mem_high), mkexpr(op1_high)));
10139 put_gpr_w1(r1+1, mkite(mkexpr(nequal), mkexpr(old_mem_low), mkexpr(op1_low)));
florian6820ba52012-07-26 02:01:50 +000010140 yield_if(mkexpr(nequal));
florian448cbba2012-06-06 02:26:01 +000010141}
10142
10143static HChar *
10144s390_irgen_CDS(UChar r1, UChar r3, IRTemp op2addr)
10145{
10146 s390_irgen_cdas_32(r1, r3, op2addr);
10147
10148 return "cds";
10149}
10150
10151static HChar *
10152s390_irgen_CDSY(UChar r1, UChar r3, IRTemp op2addr)
10153{
10154 s390_irgen_cdas_32(r1, r3, op2addr);
10155
10156 return "cdsy";
10157}
10158
10159static HChar *
10160s390_irgen_CDSG(UChar r1, UChar r3, IRTemp op2addr)
10161{
10162 IRCAS *cas;
10163 IRTemp op1_high = newTemp(Ity_I64);
10164 IRTemp op1_low = newTemp(Ity_I64);
10165 IRTemp old_mem_high = newTemp(Ity_I64);
10166 IRTemp old_mem_low = newTemp(Ity_I64);
10167 IRTemp op3_high = newTemp(Ity_I64);
10168 IRTemp op3_low = newTemp(Ity_I64);
10169 IRTemp result = newTemp(Ity_I64);
10170 IRTemp nequal = newTemp(Ity_I1);
10171
10172 assign(op1_high, get_gpr_dw0(r1));
10173 assign(op1_low, get_gpr_dw0(r1+1));
10174 assign(op3_high, get_gpr_dw0(r3));
10175 assign(op3_low, get_gpr_dw0(r3+1));
10176
10177 /* The first and second operands are compared. If they are equal,
10178 the third operand is stored at the second-operand location. */
10179 cas = mkIRCAS(old_mem_high, old_mem_low,
10180 Iend_BE, mkexpr(op2addr),
10181 mkexpr(op1_high), mkexpr(op1_low), /* expected value */
10182 mkexpr(op3_high), mkexpr(op3_low) /* new value */);
10183 stmt(IRStmt_CAS(cas));
10184
10185 /* Set CC. Operands compared equal -> 0, else 1. */
10186 assign(result, unop(Iop_1Uto64,
10187 binop(Iop_CmpNE64,
10188 binop(Iop_Or64,
10189 binop(Iop_Xor64, mkexpr(op1_high), mkexpr(old_mem_high)),
10190 binop(Iop_Xor64, mkexpr(op1_low), mkexpr(old_mem_low))),
10191 mkU64(0))));
10192
10193 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
10194
10195 /* If operands were equal (cc == 0) just store the old value op1 in r1.
10196 Otherwise, store the old_value from memory in r1 and yield. */
10197 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
10198 put_gpr_dw0(r1, mkite(mkexpr(nequal), mkexpr(old_mem_high), mkexpr(op1_high)));
10199 put_gpr_dw0(r1+1, mkite(mkexpr(nequal), mkexpr(old_mem_low), mkexpr(op1_low)));
florian6820ba52012-07-26 02:01:50 +000010200 yield_if(mkexpr(nequal));
10201
florian448cbba2012-06-06 02:26:01 +000010202 return "cdsg";
10203}
10204
sewardj2019a972011-03-07 16:04:07 +000010205
10206/* Binary floating point */
10207
10208static HChar *
10209s390_irgen_AXBR(UChar r1, UChar r2)
10210{
10211 IRTemp op1 = newTemp(Ity_F128);
10212 IRTemp op2 = newTemp(Ity_F128);
10213 IRTemp result = newTemp(Ity_F128);
florian847684d2012-09-05 04:19:09 +000010214 IRRoundingMode rounding_mode = encode_rounding_mode(S390_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000010215
10216 assign(op1, get_fpr_pair(r1));
10217 assign(op2, get_fpr_pair(r2));
florian847684d2012-09-05 04:19:09 +000010218 assign(result, triop(Iop_AddF128, mkU32(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +000010219 mkexpr(op2)));
10220 put_fpr_pair(r1, mkexpr(result));
10221
10222 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
10223
10224 return "axbr";
10225}
10226
10227/* The result of a Iop_CmdFxx operation is a condition code. It is
10228 encoded using the values defined in type IRCmpFxxResult.
10229 Before we can store the condition code into the guest state (or do
10230 anything else with it for that matter) we need to convert it to
10231 the encoding that s390 uses. This is what this function does.
10232
10233 s390 VEX b6 b2 b0 cc.1 cc.0
10234 0 0x40 EQ 1 0 0 0 0
10235 1 0x01 LT 0 0 1 0 1
10236 2 0x00 GT 0 0 0 1 0
10237 3 0x45 Unordered 1 1 1 1 1
10238
10239 The following bits from the VEX encoding are interesting:
10240 b0, b2, b6 with b0 being the LSB. We observe:
10241
10242 cc.0 = b0;
10243 cc.1 = b2 | (~b0 & ~b6)
10244
10245 with cc being the s390 condition code.
10246*/
10247static IRExpr *
10248convert_vex_fpcc_to_s390(IRTemp vex_cc)
10249{
10250 IRTemp cc0 = newTemp(Ity_I32);
10251 IRTemp cc1 = newTemp(Ity_I32);
10252 IRTemp b0 = newTemp(Ity_I32);
10253 IRTemp b2 = newTemp(Ity_I32);
10254 IRTemp b6 = newTemp(Ity_I32);
10255
10256 assign(b0, binop(Iop_And32, mkexpr(vex_cc), mkU32(1)));
10257 assign(b2, binop(Iop_And32, binop(Iop_Shr32, mkexpr(vex_cc), mkU8(2)),
10258 mkU32(1)));
10259 assign(b6, binop(Iop_And32, binop(Iop_Shr32, mkexpr(vex_cc), mkU8(6)),
10260 mkU32(1)));
10261
10262 assign(cc0, mkexpr(b0));
10263 assign(cc1, binop(Iop_Or32, mkexpr(b2),
10264 binop(Iop_And32,
10265 binop(Iop_Sub32, mkU32(1), mkexpr(b0)), /* ~b0 */
10266 binop(Iop_Sub32, mkU32(1), mkexpr(b6)) /* ~b6 */
10267 )));
10268
10269 return binop(Iop_Or32, mkexpr(cc0), binop(Iop_Shl32, mkexpr(cc1), mkU8(1)));
10270}
10271
10272static HChar *
10273s390_irgen_CEBR(UChar r1, UChar r2)
10274{
10275 IRTemp op1 = newTemp(Ity_F32);
10276 IRTemp op2 = newTemp(Ity_F32);
10277 IRTemp cc_vex = newTemp(Ity_I32);
10278 IRTemp cc_s390 = newTemp(Ity_I32);
10279
10280 assign(op1, get_fpr_w0(r1));
10281 assign(op2, get_fpr_w0(r2));
10282 assign(cc_vex, binop(Iop_CmpF32, mkexpr(op1), mkexpr(op2)));
10283
10284 assign(cc_s390, convert_vex_fpcc_to_s390(cc_vex));
10285 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
10286
10287 return "cebr";
10288}
10289
10290static HChar *
10291s390_irgen_CDBR(UChar r1, UChar r2)
10292{
10293 IRTemp op1 = newTemp(Ity_F64);
10294 IRTemp op2 = newTemp(Ity_F64);
10295 IRTemp cc_vex = newTemp(Ity_I32);
10296 IRTemp cc_s390 = newTemp(Ity_I32);
10297
10298 assign(op1, get_fpr_dw0(r1));
10299 assign(op2, get_fpr_dw0(r2));
10300 assign(cc_vex, binop(Iop_CmpF64, mkexpr(op1), mkexpr(op2)));
10301
10302 assign(cc_s390, convert_vex_fpcc_to_s390(cc_vex));
10303 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
10304
10305 return "cdbr";
10306}
10307
10308static HChar *
10309s390_irgen_CXBR(UChar r1, UChar r2)
10310{
10311 IRTemp op1 = newTemp(Ity_F128);
10312 IRTemp op2 = newTemp(Ity_F128);
10313 IRTemp cc_vex = newTemp(Ity_I32);
10314 IRTemp cc_s390 = newTemp(Ity_I32);
10315
10316 assign(op1, get_fpr_pair(r1));
10317 assign(op2, get_fpr_pair(r2));
10318 assign(cc_vex, binop(Iop_CmpF128, mkexpr(op1), mkexpr(op2)));
10319
10320 assign(cc_s390, convert_vex_fpcc_to_s390(cc_vex));
10321 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
10322
10323 return "cxbr";
10324}
10325
10326static HChar *
10327s390_irgen_CEB(UChar r1, IRTemp op2addr)
10328{
10329 IRTemp op1 = newTemp(Ity_F32);
10330 IRTemp op2 = newTemp(Ity_F32);
10331 IRTemp cc_vex = newTemp(Ity_I32);
10332 IRTemp cc_s390 = newTemp(Ity_I32);
10333
10334 assign(op1, get_fpr_w0(r1));
10335 assign(op2, load(Ity_F32, mkexpr(op2addr)));
10336 assign(cc_vex, binop(Iop_CmpF32, mkexpr(op1), mkexpr(op2)));
10337
10338 assign(cc_s390, convert_vex_fpcc_to_s390(cc_vex));
10339 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
10340
10341 return "ceb";
10342}
10343
10344static HChar *
10345s390_irgen_CDB(UChar r1, IRTemp op2addr)
10346{
10347 IRTemp op1 = newTemp(Ity_F64);
10348 IRTemp op2 = newTemp(Ity_F64);
10349 IRTemp cc_vex = newTemp(Ity_I32);
10350 IRTemp cc_s390 = newTemp(Ity_I32);
10351
10352 assign(op1, get_fpr_dw0(r1));
10353 assign(op2, load(Ity_F64, mkexpr(op2addr)));
10354 assign(cc_vex, binop(Iop_CmpF64, mkexpr(op1), mkexpr(op2)));
10355
10356 assign(cc_s390, convert_vex_fpcc_to_s390(cc_vex));
10357 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
10358
10359 return "cdb";
10360}
10361
10362static HChar *
florian4b8efad2012-09-02 18:07:08 +000010363s390_irgen_CXFBR(UChar m3 __attribute__((unused)),
10364 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000010365{
10366 IRTemp op2 = newTemp(Ity_I32);
10367
10368 assign(op2, get_gpr_w1(r2));
10369 put_fpr_pair(r1, unop(Iop_I32StoF128, mkexpr(op2)));
10370
10371 return "cxfbr";
10372}
10373
10374static HChar *
floriand2129202012-09-01 20:01:39 +000010375s390_irgen_CXLFBR(UChar m3 __attribute__((unused)),
10376 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
florian1c8f7ff2012-09-01 00:12:11 +000010377{
floriane75dafa2012-09-01 17:54:09 +000010378 if (! s390_host_has_fpext) {
10379 emulation_failure(EmFail_S390X_fpext);
10380 } else {
10381 IRTemp op2 = newTemp(Ity_I32);
florian1c8f7ff2012-09-01 00:12:11 +000010382
floriane75dafa2012-09-01 17:54:09 +000010383 assign(op2, get_gpr_w1(r2));
10384 put_fpr_pair(r1, unop(Iop_I32UtoF128, mkexpr(op2)));
10385 }
florian1c8f7ff2012-09-01 00:12:11 +000010386 return "cxlfbr";
10387}
10388
10389
10390static HChar *
florian4b8efad2012-09-02 18:07:08 +000010391s390_irgen_CXGBR(UChar m3 __attribute__((unused)),
10392 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000010393{
10394 IRTemp op2 = newTemp(Ity_I64);
10395
10396 assign(op2, get_gpr_dw0(r2));
10397 put_fpr_pair(r1, unop(Iop_I64StoF128, mkexpr(op2)));
10398
10399 return "cxgbr";
10400}
10401
10402static HChar *
floriand2129202012-09-01 20:01:39 +000010403s390_irgen_CXLGBR(UChar m3 __attribute__((unused)),
10404 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
florian1c8f7ff2012-09-01 00:12:11 +000010405{
floriane75dafa2012-09-01 17:54:09 +000010406 if (! s390_host_has_fpext) {
10407 emulation_failure(EmFail_S390X_fpext);
10408 } else {
10409 IRTemp op2 = newTemp(Ity_I64);
florian1c8f7ff2012-09-01 00:12:11 +000010410
floriane75dafa2012-09-01 17:54:09 +000010411 assign(op2, get_gpr_dw0(r2));
10412 put_fpr_pair(r1, unop(Iop_I64UtoF128, mkexpr(op2)));
10413 }
florian1c8f7ff2012-09-01 00:12:11 +000010414 return "cxlgbr";
10415}
10416
10417static HChar *
florian4b8efad2012-09-02 18:07:08 +000010418s390_irgen_CFXBR(UChar m3, UChar m4 __attribute__((unused)),
10419 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000010420{
10421 IRTemp op = newTemp(Ity_F128);
10422 IRTemp result = newTemp(Ity_I32);
10423
10424 assign(op, get_fpr_pair(r2));
florian4b8efad2012-09-02 18:07:08 +000010425 assign(result, binop(Iop_F128toI32S, mkU32(encode_rounding_mode(m3)),
sewardj2019a972011-03-07 16:04:07 +000010426 mkexpr(op)));
10427 put_gpr_w1(r1, mkexpr(result));
10428 s390_cc_thunk_put1f128(S390_CC_OP_BFP_128_TO_INT_32, op);
10429
10430 return "cfxbr";
10431}
10432
10433static HChar *
florian1c8f7ff2012-09-01 00:12:11 +000010434s390_irgen_CLFXBR(UChar m3, UChar m4 __attribute__((unused)),
10435 UChar r1, UChar r2)
10436{
floriane75dafa2012-09-01 17:54:09 +000010437 if (! s390_host_has_fpext) {
10438 emulation_failure(EmFail_S390X_fpext);
10439 } else {
10440 IRTemp op = newTemp(Ity_F128);
10441 IRTemp result = newTemp(Ity_I32);
florian1c8f7ff2012-09-01 00:12:11 +000010442
floriane75dafa2012-09-01 17:54:09 +000010443 assign(op, get_fpr_pair(r2));
10444 assign(result, binop(Iop_F128toI32U, mkU32(encode_rounding_mode(m3)),
10445 mkexpr(op)));
10446 put_gpr_w1(r1, mkexpr(result));
10447 s390_cc_thunk_put1f128(S390_CC_OP_BFP_128_TO_UINT_32, op);
10448 }
florian1c8f7ff2012-09-01 00:12:11 +000010449 return "clfxbr";
10450}
10451
10452
10453static HChar *
florian4b8efad2012-09-02 18:07:08 +000010454s390_irgen_CGXBR(UChar m3, UChar m4 __attribute__((unused)),
10455 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000010456{
10457 IRTemp op = newTemp(Ity_F128);
10458 IRTemp result = newTemp(Ity_I64);
10459
10460 assign(op, get_fpr_pair(r2));
florian4b8efad2012-09-02 18:07:08 +000010461 assign(result, binop(Iop_F128toI64S, mkU32(encode_rounding_mode(m3)),
sewardj2019a972011-03-07 16:04:07 +000010462 mkexpr(op)));
10463 put_gpr_dw0(r1, mkexpr(result));
10464 s390_cc_thunk_put1f128(S390_CC_OP_BFP_128_TO_INT_64, op);
10465
10466 return "cgxbr";
10467}
10468
10469static HChar *
florian1c8f7ff2012-09-01 00:12:11 +000010470s390_irgen_CLGXBR(UChar m3, UChar m4 __attribute__((unused)),
10471 UChar r1, UChar r2)
10472{
floriane75dafa2012-09-01 17:54:09 +000010473 if (! s390_host_has_fpext) {
10474 emulation_failure(EmFail_S390X_fpext);
10475 } else {
10476 IRTemp op = newTemp(Ity_F128);
10477 IRTemp result = newTemp(Ity_I64);
florian1c8f7ff2012-09-01 00:12:11 +000010478
floriane75dafa2012-09-01 17:54:09 +000010479 assign(op, get_fpr_pair(r2));
10480 assign(result, binop(Iop_F128toI64U, mkU32(encode_rounding_mode(m3)),
10481 mkexpr(op)));
10482 put_gpr_dw0(r1, mkexpr(result));
10483 s390_cc_thunk_put1f128(S390_CC_OP_BFP_128_TO_UINT_64, op);
10484 }
florian1c8f7ff2012-09-01 00:12:11 +000010485 return "clgxbr";
10486}
10487
10488static HChar *
sewardj2019a972011-03-07 16:04:07 +000010489s390_irgen_DXBR(UChar r1, UChar r2)
10490{
10491 IRTemp op1 = newTemp(Ity_F128);
10492 IRTemp op2 = newTemp(Ity_F128);
10493 IRTemp result = newTemp(Ity_F128);
florian847684d2012-09-05 04:19:09 +000010494 IRRoundingMode rounding_mode = encode_rounding_mode(S390_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000010495
10496 assign(op1, get_fpr_pair(r1));
10497 assign(op2, get_fpr_pair(r2));
florian847684d2012-09-05 04:19:09 +000010498 assign(result, triop(Iop_DivF128, mkU32(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +000010499 mkexpr(op2)));
10500 put_fpr_pair(r1, mkexpr(result));
10501
10502 return "dxbr";
10503}
10504
10505static HChar *
10506s390_irgen_LTXBR(UChar r1, UChar r2)
10507{
10508 IRTemp result = newTemp(Ity_F128);
10509
10510 assign(result, get_fpr_pair(r2));
10511 put_fpr_pair(r1, mkexpr(result));
10512 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
10513
10514 return "ltxbr";
10515}
10516
10517static HChar *
10518s390_irgen_LCXBR(UChar r1, UChar r2)
10519{
10520 IRTemp result = newTemp(Ity_F128);
10521
10522 assign(result, unop(Iop_NegF128, get_fpr_pair(r2)));
10523 put_fpr_pair(r1, mkexpr(result));
10524 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
10525
10526 return "lcxbr";
10527}
10528
10529static HChar *
10530s390_irgen_LXDBR(UChar r1, UChar r2)
10531{
10532 IRTemp op = newTemp(Ity_F64);
10533
10534 assign(op, get_fpr_dw0(r2));
10535 put_fpr_pair(r1, unop(Iop_F64toF128, mkexpr(op)));
10536
10537 return "lxdbr";
10538}
10539
10540static HChar *
10541s390_irgen_LXEBR(UChar r1, UChar r2)
10542{
10543 IRTemp op = newTemp(Ity_F32);
10544
10545 assign(op, get_fpr_w0(r2));
10546 put_fpr_pair(r1, unop(Iop_F32toF128, mkexpr(op)));
10547
10548 return "lxebr";
10549}
10550
10551static HChar *
10552s390_irgen_LXDB(UChar r1, IRTemp op2addr)
10553{
10554 IRTemp op = newTemp(Ity_F64);
10555
10556 assign(op, load(Ity_F64, mkexpr(op2addr)));
10557 put_fpr_pair(r1, unop(Iop_F64toF128, mkexpr(op)));
10558
10559 return "lxdb";
10560}
10561
10562static HChar *
10563s390_irgen_LXEB(UChar r1, IRTemp op2addr)
10564{
10565 IRTemp op = newTemp(Ity_F32);
10566
10567 assign(op, load(Ity_F32, mkexpr(op2addr)));
10568 put_fpr_pair(r1, unop(Iop_F32toF128, mkexpr(op)));
10569
10570 return "lxeb";
10571}
10572
10573static HChar *
10574s390_irgen_LNEBR(UChar r1, UChar r2)
10575{
10576 IRTemp result = newTemp(Ity_F32);
10577
10578 assign(result, unop(Iop_NegF32, unop(Iop_AbsF32, get_fpr_w0(r2))));
10579 put_fpr_w0(r1, mkexpr(result));
10580 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_32, result);
10581
10582 return "lnebr";
10583}
10584
10585static HChar *
10586s390_irgen_LNDBR(UChar r1, UChar r2)
10587{
10588 IRTemp result = newTemp(Ity_F64);
10589
10590 assign(result, unop(Iop_NegF64, unop(Iop_AbsF64, get_fpr_dw0(r2))));
10591 put_fpr_dw0(r1, mkexpr(result));
10592 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_64, result);
10593
10594 return "lndbr";
10595}
10596
10597static HChar *
10598s390_irgen_LNXBR(UChar r1, UChar r2)
10599{
10600 IRTemp result = newTemp(Ity_F128);
10601
10602 assign(result, unop(Iop_NegF128, unop(Iop_AbsF128, get_fpr_pair(r2))));
10603 put_fpr_pair(r1, mkexpr(result));
10604 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
10605
10606 return "lnxbr";
10607}
10608
10609static HChar *
10610s390_irgen_LPEBR(UChar r1, UChar r2)
10611{
10612 IRTemp result = newTemp(Ity_F32);
10613
10614 assign(result, unop(Iop_AbsF32, get_fpr_w0(r2)));
10615 put_fpr_w0(r1, mkexpr(result));
10616 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_32, result);
10617
10618 return "lpebr";
10619}
10620
10621static HChar *
10622s390_irgen_LPDBR(UChar r1, UChar r2)
10623{
10624 IRTemp result = newTemp(Ity_F64);
10625
10626 assign(result, unop(Iop_AbsF64, get_fpr_dw0(r2)));
10627 put_fpr_dw0(r1, mkexpr(result));
10628 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_64, result);
10629
10630 return "lpdbr";
10631}
10632
10633static HChar *
10634s390_irgen_LPXBR(UChar r1, UChar r2)
10635{
10636 IRTemp result = newTemp(Ity_F128);
10637
10638 assign(result, unop(Iop_AbsF128, get_fpr_pair(r2)));
10639 put_fpr_pair(r1, mkexpr(result));
10640 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
10641
10642 return "lpxbr";
10643}
10644
10645static HChar *
florian4b8efad2012-09-02 18:07:08 +000010646s390_irgen_LDXBR(UChar m3, UChar m4 __attribute__((unused)),
10647 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000010648{
10649 IRTemp result = newTemp(Ity_F64);
10650
florian4b8efad2012-09-02 18:07:08 +000010651 assign(result, binop(Iop_F128toF64, mkU32(encode_rounding_mode(m3)),
10652 get_fpr_pair(r2)));
sewardj2019a972011-03-07 16:04:07 +000010653 put_fpr_dw0(r1, mkexpr(result));
10654
10655 return "ldxbr";
10656}
10657
10658static HChar *
florian4b8efad2012-09-02 18:07:08 +000010659s390_irgen_LEXBR(UChar m3, UChar m4 __attribute__((unused)),
10660 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000010661{
10662 IRTemp result = newTemp(Ity_F32);
10663
florian4b8efad2012-09-02 18:07:08 +000010664 assign(result, binop(Iop_F128toF32, mkU32(encode_rounding_mode(m3)),
10665 get_fpr_pair(r2)));
sewardj2019a972011-03-07 16:04:07 +000010666 put_fpr_w0(r1, mkexpr(result));
10667
10668 return "lexbr";
10669}
10670
10671static HChar *
10672s390_irgen_MXBR(UChar r1, UChar r2)
10673{
10674 IRTemp op1 = newTemp(Ity_F128);
10675 IRTemp op2 = newTemp(Ity_F128);
10676 IRTemp result = newTemp(Ity_F128);
florian847684d2012-09-05 04:19:09 +000010677 IRRoundingMode rounding_mode = encode_rounding_mode(S390_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000010678
10679 assign(op1, get_fpr_pair(r1));
10680 assign(op2, get_fpr_pair(r2));
florian847684d2012-09-05 04:19:09 +000010681 assign(result, triop(Iop_MulF128, mkU32(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +000010682 mkexpr(op2)));
10683 put_fpr_pair(r1, mkexpr(result));
10684
10685 return "mxbr";
10686}
10687
10688static HChar *
10689s390_irgen_MAEBR(UChar r1, UChar r3, UChar r2)
10690{
florian847684d2012-09-05 04:19:09 +000010691 IRRoundingMode rounding_mode = encode_rounding_mode(S390_ROUND_PER_FPC);
10692
10693 put_fpr_w0(r1, qop(Iop_MAddF32, mkU32(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +000010694 get_fpr_w0(r1), get_fpr_w0(r2), get_fpr_w0(r3)));
10695
10696 return "maebr";
10697}
10698
10699static HChar *
10700s390_irgen_MADBR(UChar r1, UChar r3, UChar r2)
10701{
florian847684d2012-09-05 04:19:09 +000010702 IRRoundingMode rounding_mode = encode_rounding_mode(S390_ROUND_PER_FPC);
10703
10704 put_fpr_dw0(r1, qop(Iop_MAddF64, mkU32(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +000010705 get_fpr_dw0(r1), get_fpr_dw0(r2), get_fpr_dw0(r3)));
10706
10707 return "madbr";
10708}
10709
10710static HChar *
10711s390_irgen_MAEB(UChar r3, IRTemp op2addr, UChar r1)
10712{
10713 IRExpr *op2 = load(Ity_F32, mkexpr(op2addr));
florian847684d2012-09-05 04:19:09 +000010714 IRRoundingMode rounding_mode = encode_rounding_mode(S390_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000010715
florian847684d2012-09-05 04:19:09 +000010716 put_fpr_w0(r1, qop(Iop_MAddF32, mkU32(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +000010717 get_fpr_w0(r1), op2, get_fpr_w0(r3)));
10718
10719 return "maeb";
10720}
10721
10722static HChar *
10723s390_irgen_MADB(UChar r3, IRTemp op2addr, UChar r1)
10724{
10725 IRExpr *op2 = load(Ity_F64, mkexpr(op2addr));
florian847684d2012-09-05 04:19:09 +000010726 IRRoundingMode rounding_mode = encode_rounding_mode(S390_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000010727
florian847684d2012-09-05 04:19:09 +000010728 put_fpr_dw0(r1, qop(Iop_MAddF64, mkU32(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +000010729 get_fpr_dw0(r1), op2, get_fpr_dw0(r3)));
10730
10731 return "madb";
10732}
10733
10734static HChar *
10735s390_irgen_MSEBR(UChar r1, UChar r3, UChar r2)
10736{
florian847684d2012-09-05 04:19:09 +000010737 IRRoundingMode rounding_mode = encode_rounding_mode(S390_ROUND_PER_FPC);
10738
10739 put_fpr_w0(r1, qop(Iop_MSubF32, mkU32(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +000010740 get_fpr_w0(r1), get_fpr_w0(r2), get_fpr_w0(r3)));
10741
10742 return "msebr";
10743}
10744
10745static HChar *
10746s390_irgen_MSDBR(UChar r1, UChar r3, UChar r2)
10747{
florian847684d2012-09-05 04:19:09 +000010748 IRRoundingMode rounding_mode = encode_rounding_mode(S390_ROUND_PER_FPC);
10749
10750 put_fpr_dw0(r1, qop(Iop_MSubF64, mkU32(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +000010751 get_fpr_dw0(r1), get_fpr_dw0(r2), get_fpr_dw0(r3)));
10752
10753 return "msdbr";
10754}
10755
10756static HChar *
10757s390_irgen_MSEB(UChar r3, IRTemp op2addr, UChar r1)
10758{
10759 IRExpr *op2 = load(Ity_F32, mkexpr(op2addr));
florian847684d2012-09-05 04:19:09 +000010760 IRRoundingMode rounding_mode = encode_rounding_mode(S390_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000010761
florian847684d2012-09-05 04:19:09 +000010762 put_fpr_w0(r1, qop(Iop_MSubF32, mkU32(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +000010763 get_fpr_w0(r1), op2, get_fpr_w0(r3)));
10764
10765 return "mseb";
10766}
10767
10768static HChar *
10769s390_irgen_MSDB(UChar r3, IRTemp op2addr, UChar r1)
10770{
10771 IRExpr *op2 = load(Ity_F64, mkexpr(op2addr));
florian847684d2012-09-05 04:19:09 +000010772 IRRoundingMode rounding_mode = encode_rounding_mode(S390_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000010773
florian847684d2012-09-05 04:19:09 +000010774 put_fpr_dw0(r1, qop(Iop_MSubF64, mkU32(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +000010775 get_fpr_dw0(r1), op2, get_fpr_dw0(r3)));
10776
10777 return "msdb";
10778}
10779
10780static HChar *
10781s390_irgen_SQEBR(UChar r1, UChar r2)
10782{
10783 IRTemp result = newTemp(Ity_F32);
florian847684d2012-09-05 04:19:09 +000010784 IRRoundingMode rounding_mode = encode_rounding_mode(S390_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000010785
florian847684d2012-09-05 04:19:09 +000010786 assign(result, binop(Iop_SqrtF32, mkU32(rounding_mode), get_fpr_w0(r2)));
sewardj2019a972011-03-07 16:04:07 +000010787 put_fpr_w0(r1, mkexpr(result));
10788
10789 return "sqebr";
10790}
10791
10792static HChar *
10793s390_irgen_SQDBR(UChar r1, UChar r2)
10794{
10795 IRTemp result = newTemp(Ity_F64);
florian847684d2012-09-05 04:19:09 +000010796 IRRoundingMode rounding_mode = encode_rounding_mode(S390_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000010797
florian847684d2012-09-05 04:19:09 +000010798 assign(result, binop(Iop_SqrtF64, mkU32(rounding_mode), get_fpr_dw0(r2)));
sewardj2019a972011-03-07 16:04:07 +000010799 put_fpr_dw0(r1, mkexpr(result));
10800
10801 return "sqdbr";
10802}
10803
10804static HChar *
10805s390_irgen_SQXBR(UChar r1, UChar r2)
10806{
10807 IRTemp result = newTemp(Ity_F128);
florian847684d2012-09-05 04:19:09 +000010808 IRRoundingMode rounding_mode = encode_rounding_mode(S390_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000010809
florian847684d2012-09-05 04:19:09 +000010810 assign(result, binop(Iop_SqrtF128, mkU32(rounding_mode), get_fpr_pair(r2)));
sewardj2019a972011-03-07 16:04:07 +000010811 put_fpr_pair(r1, mkexpr(result));
10812
10813 return "sqxbr";
10814}
10815
10816static HChar *
10817s390_irgen_SQEB(UChar r1, IRTemp op2addr)
10818{
10819 IRTemp op = newTemp(Ity_F32);
florian847684d2012-09-05 04:19:09 +000010820 IRRoundingMode rounding_mode = encode_rounding_mode(S390_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000010821
10822 assign(op, load(Ity_F32, mkexpr(op2addr)));
florian847684d2012-09-05 04:19:09 +000010823 put_fpr_w0(r1, binop(Iop_SqrtF32, mkU32(rounding_mode), mkexpr(op)));
sewardj2019a972011-03-07 16:04:07 +000010824
10825 return "sqeb";
10826}
10827
10828static HChar *
10829s390_irgen_SQDB(UChar r1, IRTemp op2addr)
10830{
10831 IRTemp op = newTemp(Ity_F64);
florian847684d2012-09-05 04:19:09 +000010832 IRRoundingMode rounding_mode = encode_rounding_mode(S390_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000010833
10834 assign(op, load(Ity_F64, mkexpr(op2addr)));
florian847684d2012-09-05 04:19:09 +000010835 put_fpr_dw0(r1, binop(Iop_SqrtF64, mkU32(rounding_mode), mkexpr(op)));
sewardj2019a972011-03-07 16:04:07 +000010836
10837 return "sqdb";
10838}
10839
10840static HChar *
10841s390_irgen_SXBR(UChar r1, UChar r2)
10842{
10843 IRTemp op1 = newTemp(Ity_F128);
10844 IRTemp op2 = newTemp(Ity_F128);
10845 IRTemp result = newTemp(Ity_F128);
florian847684d2012-09-05 04:19:09 +000010846 IRRoundingMode rounding_mode = encode_rounding_mode(S390_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000010847
10848 assign(op1, get_fpr_pair(r1));
10849 assign(op2, get_fpr_pair(r2));
florian847684d2012-09-05 04:19:09 +000010850 assign(result, triop(Iop_SubF128, mkU32(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +000010851 mkexpr(op2)));
10852 put_fpr_pair(r1, mkexpr(result));
10853 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
10854
10855 return "sxbr";
10856}
10857
10858static HChar *
10859s390_irgen_TCEB(UChar r1, IRTemp op2addr)
10860{
10861 IRTemp value = newTemp(Ity_F32);
10862
10863 assign(value, get_fpr_w0(r1));
10864
10865 s390_cc_thunk_putFZ(S390_CC_OP_BFP_TDC_32, value, op2addr);
10866
10867 return "tceb";
10868}
10869
10870static HChar *
10871s390_irgen_TCDB(UChar r1, IRTemp op2addr)
10872{
10873 IRTemp value = newTemp(Ity_F64);
10874
10875 assign(value, get_fpr_dw0(r1));
10876
10877 s390_cc_thunk_putFZ(S390_CC_OP_BFP_TDC_64, value, op2addr);
10878
10879 return "tcdb";
10880}
10881
10882static HChar *
10883s390_irgen_TCXB(UChar r1, IRTemp op2addr)
10884{
10885 IRTemp value = newTemp(Ity_F128);
10886
10887 assign(value, get_fpr_pair(r1));
10888
10889 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_TDC_128, value, op2addr);
10890
10891 return "tcxb";
10892}
10893
10894static HChar *
10895s390_irgen_LCDFR(UChar r1, UChar r2)
10896{
10897 IRTemp result = newTemp(Ity_F64);
10898
10899 assign(result, unop(Iop_NegF64, get_fpr_dw0(r2)));
10900 put_fpr_dw0(r1, mkexpr(result));
10901
10902 return "lcdfr";
10903}
10904
10905static HChar *
10906s390_irgen_LNDFR(UChar r1, UChar r2)
10907{
10908 IRTemp result = newTemp(Ity_F64);
10909
10910 assign(result, unop(Iop_NegF64, unop(Iop_AbsF64, get_fpr_dw0(r2))));
10911 put_fpr_dw0(r1, mkexpr(result));
10912
10913 return "lndfr";
10914}
10915
10916static HChar *
10917s390_irgen_LPDFR(UChar r1, UChar r2)
10918{
10919 IRTemp result = newTemp(Ity_F64);
10920
10921 assign(result, unop(Iop_AbsF64, get_fpr_dw0(r2)));
10922 put_fpr_dw0(r1, mkexpr(result));
10923
10924 return "lpdfr";
10925}
10926
10927static HChar *
10928s390_irgen_LDGR(UChar r1, UChar r2)
10929{
10930 put_fpr_dw0(r1, unop(Iop_ReinterpI64asF64, get_gpr_dw0(r2)));
10931
10932 return "ldgr";
10933}
10934
10935static HChar *
10936s390_irgen_LGDR(UChar r1, UChar r2)
10937{
10938 put_gpr_dw0(r1, unop(Iop_ReinterpF64asI64, get_fpr_dw0(r2)));
10939
10940 return "lgdr";
10941}
10942
10943
10944static HChar *
10945s390_irgen_CPSDR(UChar r3, UChar r1, UChar r2)
10946{
10947 IRTemp sign = newTemp(Ity_I64);
10948 IRTemp value = newTemp(Ity_I64);
10949
10950 assign(sign, binop(Iop_And64, unop(Iop_ReinterpF64asI64, get_fpr_dw0(r3)),
10951 mkU64(1ULL << 63)));
10952 assign(value, binop(Iop_And64, unop(Iop_ReinterpF64asI64, get_fpr_dw0(r2)),
10953 mkU64((1ULL << 63) - 1)));
10954 put_fpr_dw0(r1, unop(Iop_ReinterpI64asF64, binop(Iop_Or64, mkexpr(value),
10955 mkexpr(sign))));
10956
10957 return "cpsdr";
10958}
10959
10960
sewardj2019a972011-03-07 16:04:07 +000010961static IRExpr *
10962s390_call_cvb(IRExpr *in)
10963{
10964 IRExpr **args, *call;
10965
10966 args = mkIRExprVec_1(in);
10967 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
10968 "s390_do_cvb", &s390_do_cvb, args);
10969
10970 /* Nothing is excluded from definedness checking. */
10971 call->Iex.CCall.cee->mcx_mask = 0;
10972
10973 return call;
10974}
10975
10976static HChar *
10977s390_irgen_CVB(UChar r1, IRTemp op2addr)
10978{
10979 put_gpr_w1(r1, s390_call_cvb(load(Ity_I64, mkexpr(op2addr))));
10980
10981 return "cvb";
10982}
10983
10984static HChar *
10985s390_irgen_CVBY(UChar r1, IRTemp op2addr)
10986{
10987 put_gpr_w1(r1, s390_call_cvb(load(Ity_I64, mkexpr(op2addr))));
10988
10989 return "cvby";
10990}
10991
10992
sewardj2019a972011-03-07 16:04:07 +000010993static IRExpr *
10994s390_call_cvd(IRExpr *in)
10995{
10996 IRExpr **args, *call;
10997
10998 args = mkIRExprVec_1(in);
10999 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
11000 "s390_do_cvd", &s390_do_cvd, args);
11001
11002 /* Nothing is excluded from definedness checking. */
11003 call->Iex.CCall.cee->mcx_mask = 0;
11004
11005 return call;
11006}
11007
11008static HChar *
11009s390_irgen_CVD(UChar r1, IRTemp op2addr)
11010{
florian11b8ee82012-08-06 13:35:33 +000011011 store(mkexpr(op2addr), s390_call_cvd(unop(Iop_32Uto64, get_gpr_w1(r1))));
sewardj2019a972011-03-07 16:04:07 +000011012
11013 return "cvd";
11014}
11015
11016static HChar *
11017s390_irgen_CVDY(UChar r1, IRTemp op2addr)
11018{
11019 store(mkexpr(op2addr), s390_call_cvd(get_gpr_w1(r1)));
11020
11021 return "cvdy";
11022}
11023
11024static HChar *
11025s390_irgen_FLOGR(UChar r1, UChar r2)
11026{
11027 IRTemp input = newTemp(Ity_I64);
11028 IRTemp not_zero = newTemp(Ity_I64);
11029 IRTemp tmpnum = newTemp(Ity_I64);
11030 IRTemp num = newTemp(Ity_I64);
11031 IRTemp shift_amount = newTemp(Ity_I8);
11032
11033 /* We use the "count leading zeroes" operator because the number of
11034 leading zeroes is identical with the bit position of the first '1' bit.
11035 However, that operator does not work when the input value is zero.
11036 Therefore, we set the LSB of the input value to 1 and use Clz64 on
11037 the modified value. If input == 0, then the result is 64. Otherwise,
11038 the result of Clz64 is what we want. */
11039
11040 assign(input, get_gpr_dw0(r2));
11041 assign(not_zero, binop(Iop_Or64, mkexpr(input), mkU64(1)));
11042 assign(tmpnum, unop(Iop_Clz64, mkexpr(not_zero)));
11043
11044 /* num = (input == 0) ? 64 : tmpnum */
11045 assign(num, mkite(binop(Iop_CmpEQ64, mkexpr(input), mkU64(0)),
11046 /* == 0 */ mkU64(64),
11047 /* != 0 */ mkexpr(tmpnum)));
11048
11049 put_gpr_dw0(r1, mkexpr(num));
11050
11051 /* Set the leftmost '1' bit of the input value to zero. The general scheme
11052 is to first shift the input value by NUM + 1 bits to the left which
11053 causes the leftmost '1' bit to disappear. Then we shift logically to
11054 the right by NUM + 1 bits. Because the semantics of Iop_Shl64 and
11055 Iop_Shr64 are undefined if the shift-amount is greater than or equal to
11056 the width of the value-to-be-shifted, we need to special case
11057 NUM + 1 >= 64. This is equivalent to INPUT != 0 && INPUT != 1.
11058 For both such INPUT values the result will be 0. */
11059
11060 assign(shift_amount, unop(Iop_64to8, binop(Iop_Add64, mkexpr(num),
11061 mkU64(1))));
11062
11063 put_gpr_dw0(r1 + 1,
florian6ad49522011-09-09 02:38:55 +000011064 mkite(binop(Iop_CmpLE64U, mkexpr(input), mkU64(1)),
11065 /* == 0 || == 1*/ mkU64(0),
11066 /* otherwise */
11067 binop(Iop_Shr64,
11068 binop(Iop_Shl64, mkexpr(input),
11069 mkexpr(shift_amount)),
11070 mkexpr(shift_amount))));
sewardj2019a972011-03-07 16:04:07 +000011071
11072 /* Compare the original value as an unsigned integer with 0. */
11073 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, input,
11074 mktemp(Ity_I64, mkU64(0)), False);
11075
11076 return "flogr";
11077}
11078
sewardj1e5fea62011-05-17 16:18:36 +000011079static HChar *
11080s390_irgen_STCK(IRTemp op2addr)
11081{
11082 IRDirty *d;
11083 IRTemp cc = newTemp(Ity_I64);
11084
11085 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STCK",
11086 &s390x_dirtyhelper_STCK,
11087 mkIRExprVec_1(mkexpr(op2addr)));
11088 d->mFx = Ifx_Write;
11089 d->mAddr = mkexpr(op2addr);
11090 d->mSize = 8;
11091 stmt(IRStmt_Dirty(d));
11092 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
11093 mkexpr(cc), mkU64(0), mkU64(0));
11094 return "stck";
11095}
11096
11097static HChar *
11098s390_irgen_STCKF(IRTemp op2addr)
11099{
florianc5c669b2012-08-26 14:32:28 +000011100 if (! s390_host_has_stckf) {
floriane75dafa2012-09-01 17:54:09 +000011101 emulation_failure(EmFail_S390X_stckf);
florianc5c669b2012-08-26 14:32:28 +000011102 } else {
11103 IRTemp cc = newTemp(Ity_I64);
sewardj1e5fea62011-05-17 16:18:36 +000011104
florianc5c669b2012-08-26 14:32:28 +000011105 IRDirty *d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STCKF",
11106 &s390x_dirtyhelper_STCKF,
11107 mkIRExprVec_1(mkexpr(op2addr)));
11108 d->mFx = Ifx_Write;
11109 d->mAddr = mkexpr(op2addr);
11110 d->mSize = 8;
11111 stmt(IRStmt_Dirty(d));
11112 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
11113 mkexpr(cc), mkU64(0), mkU64(0));
11114 }
sewardj1e5fea62011-05-17 16:18:36 +000011115 return "stckf";
11116}
11117
11118static HChar *
11119s390_irgen_STCKE(IRTemp op2addr)
11120{
11121 IRDirty *d;
11122 IRTemp cc = newTemp(Ity_I64);
11123
11124 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STCKE",
11125 &s390x_dirtyhelper_STCKE,
11126 mkIRExprVec_1(mkexpr(op2addr)));
11127 d->mFx = Ifx_Write;
11128 d->mAddr = mkexpr(op2addr);
11129 d->mSize = 16;
11130 stmt(IRStmt_Dirty(d));
11131 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
11132 mkexpr(cc), mkU64(0), mkU64(0));
11133 return "stcke";
11134}
11135
florian933065d2011-07-11 01:48:02 +000011136static HChar *
11137s390_irgen_STFLE(IRTemp op2addr)
11138{
florian4e0083e2012-08-26 03:41:56 +000011139 if (! s390_host_has_stfle) {
floriane75dafa2012-09-01 17:54:09 +000011140 emulation_failure(EmFail_S390X_stfle);
florian4e0083e2012-08-26 03:41:56 +000011141 return "stfle";
11142 }
11143
florian933065d2011-07-11 01:48:02 +000011144 IRDirty *d;
11145 IRTemp cc = newTemp(Ity_I64);
11146
11147 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STFLE",
11148 &s390x_dirtyhelper_STFLE,
11149 mkIRExprVec_1(mkexpr(op2addr)));
11150
11151 d->needsBBP = 1; /* Need to pass pointer to guest state to helper */
11152
sewardjc9069f22012-06-01 16:09:50 +000011153 d->nFxState = 1;
11154 vex_bzero(&d->fxState, sizeof(d->fxState));
11155
florian933065d2011-07-11 01:48:02 +000011156 d->fxState[0].fx = Ifx_Modify; /* read then write */
11157 d->fxState[0].offset = S390X_GUEST_OFFSET(guest_r0);
11158 d->fxState[0].size = sizeof(ULong);
florian933065d2011-07-11 01:48:02 +000011159
11160 d->mAddr = mkexpr(op2addr);
11161 /* Pretend all double words are written */
11162 d->mSize = S390_NUM_FACILITY_DW * sizeof(ULong);
11163 d->mFx = Ifx_Write;
11164
11165 stmt(IRStmt_Dirty(d));
11166
11167 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET), mkexpr(cc), mkU64(0), mkU64(0));
11168
11169 return "stfle";
11170}
11171
floriana4384a32011-08-11 16:58:45 +000011172static HChar *
11173s390_irgen_CKSM(UChar r1,UChar r2)
11174{
11175 IRTemp addr = newTemp(Ity_I64);
11176 IRTemp op = newTemp(Ity_I32);
11177 IRTemp len = newTemp(Ity_I64);
11178 IRTemp oldval = newTemp(Ity_I32);
11179 IRTemp mask = newTemp(Ity_I32);
11180 IRTemp newop = newTemp(Ity_I32);
11181 IRTemp result = newTemp(Ity_I32);
11182 IRTemp result1 = newTemp(Ity_I32);
11183 IRTemp inc = newTemp(Ity_I64);
11184
11185 assign(oldval, get_gpr_w1(r1));
11186 assign(addr, get_gpr_dw0(r2));
11187 assign(len, get_gpr_dw0(r2+1));
11188
11189 /* Condition code is always zero. */
11190 s390_cc_set(0);
11191
11192 /* If length is zero, there is no need to calculate the checksum */
florian6820ba52012-07-26 02:01:50 +000011193 next_insn_if(binop(Iop_CmpEQ64, mkexpr(len), mkU64(0)));
floriana4384a32011-08-11 16:58:45 +000011194
11195 /* Assiging the increment variable to adjust address and length
11196 later on. */
11197 assign(inc, mkite(binop(Iop_CmpLT64U, mkexpr(len), mkU64(4)),
11198 mkexpr(len), mkU64(4)));
11199
11200 /* If length < 4 the final 4-byte 2nd operand value is computed by
11201 appending the remaining bytes to the right with 0. This is done
11202 by AND'ing the 4 bytes loaded from memory with an appropriate
11203 mask. If length >= 4, that mask is simply 0xffffffff. */
11204
11205 assign(mask, mkite(binop(Iop_CmpLT64U, mkexpr(len), mkU64(4)),
11206 /* Mask computation when len < 4:
11207 0xffffffff << (32 - (len % 4)*8) */
11208 binop(Iop_Shl32, mkU32(0xffffffff),
11209 unop(Iop_32to8,
11210 binop(Iop_Sub32, mkU32(32),
11211 binop(Iop_Shl32,
11212 unop(Iop_64to32,
11213 binop(Iop_And64,
11214 mkexpr(len), mkU64(3))),
11215 mkU8(3))))),
11216 mkU32(0xffffffff)));
11217
11218 assign(op, load(Ity_I32, mkexpr(addr)));
11219 assign(newop, binop(Iop_And32, mkexpr(op), mkexpr(mask)));
11220 assign(result, binop(Iop_Add32, mkexpr(newop), mkexpr(oldval)));
11221
11222 /* Checking for carry */
11223 assign(result1, mkite(binop(Iop_CmpLT32U, mkexpr(result), mkexpr(newop)),
11224 binop(Iop_Add32, mkexpr(result), mkU32(1)),
11225 mkexpr(result)));
11226
11227 put_gpr_w1(r1, mkexpr(result1));
11228 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr), mkexpr(inc)));
11229 put_gpr_dw0(r2+1, binop(Iop_Sub64, mkexpr(len), mkexpr(inc)));
11230
florian6820ba52012-07-26 02:01:50 +000011231 iterate_if(binop(Iop_CmpNE64, mkexpr(len), mkU64(0)));
floriana4384a32011-08-11 16:58:45 +000011232
11233 return "cksm";
11234}
11235
florian9af37692012-01-15 21:01:16 +000011236static HChar *
11237s390_irgen_TROO(UChar m3, UChar r1, UChar r2)
11238{
11239 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
11240 src_addr = newTemp(Ity_I64);
11241 des_addr = newTemp(Ity_I64);
11242 tab_addr = newTemp(Ity_I64);
11243 test_byte = newTemp(Ity_I8);
11244 src_len = newTemp(Ity_I64);
11245
11246 assign(src_addr, get_gpr_dw0(r2));
11247 assign(des_addr, get_gpr_dw0(r1));
11248 assign(tab_addr, get_gpr_dw0(1));
florian53518532012-01-18 14:00:31 +000011249 assign(src_len, get_gpr_dw0(r1+1));
florian9af37692012-01-15 21:01:16 +000011250 assign(test_byte, get_gpr_b7(0));
11251
11252 IRTemp op = newTemp(Ity_I8);
11253 IRTemp op1 = newTemp(Ity_I8);
11254 IRTemp result = newTemp(Ity_I64);
11255
11256 /* End of source string? We're done; proceed to next insn */
11257 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000011258 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian9af37692012-01-15 21:01:16 +000011259
11260 /* Load character from source string, index translation table and
11261 store translated character in op1. */
11262 assign(op, load(Ity_I8, mkexpr(src_addr)));
11263
11264 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)),
11265 mkexpr(tab_addr)));
11266 assign(op1, load(Ity_I8, mkexpr(result)));
11267
11268 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
11269 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000011270 next_insn_if(binop(Iop_CmpEQ8, mkexpr(op1), mkexpr(test_byte)));
florian9af37692012-01-15 21:01:16 +000011271 }
11272 store(get_gpr_dw0(r1), mkexpr(op1));
11273
11274 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(1)));
11275 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(1)));
11276 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(1)));
11277
florian6820ba52012-07-26 02:01:50 +000011278 iterate();
florian9af37692012-01-15 21:01:16 +000011279
11280 return "troo";
11281}
11282
florian730448f2012-02-04 17:07:07 +000011283static HChar *
11284s390_irgen_TRTO(UChar m3, UChar r1, UChar r2)
11285{
11286 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
11287 src_addr = newTemp(Ity_I64);
11288 des_addr = newTemp(Ity_I64);
11289 tab_addr = newTemp(Ity_I64);
11290 test_byte = newTemp(Ity_I8);
11291 src_len = newTemp(Ity_I64);
11292
11293 assign(src_addr, get_gpr_dw0(r2));
11294 assign(des_addr, get_gpr_dw0(r1));
11295 assign(tab_addr, get_gpr_dw0(1));
11296 assign(src_len, get_gpr_dw0(r1+1));
11297 assign(test_byte, get_gpr_b7(0));
11298
11299 IRTemp op = newTemp(Ity_I16);
11300 IRTemp op1 = newTemp(Ity_I8);
11301 IRTemp result = newTemp(Ity_I64);
11302
11303 /* End of source string? We're done; proceed to next insn */
11304 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000011305 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian730448f2012-02-04 17:07:07 +000011306
11307 /* Load character from source string, index translation table and
11308 store translated character in op1. */
11309 assign(op, load(Ity_I16, mkexpr(src_addr)));
11310
11311 assign(result, binop(Iop_Add64, unop(Iop_16Uto64, mkexpr(op)),
11312 mkexpr(tab_addr)));
11313
11314 assign(op1, load(Ity_I8, mkexpr(result)));
11315
11316 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
11317 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000011318 next_insn_if(binop(Iop_CmpEQ8, mkexpr(op1), mkexpr(test_byte)));
florian730448f2012-02-04 17:07:07 +000011319 }
11320 store(get_gpr_dw0(r1), mkexpr(op1));
11321
11322 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(2)));
11323 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(1)));
11324 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(2)));
11325
florian6820ba52012-07-26 02:01:50 +000011326 iterate();
florian730448f2012-02-04 17:07:07 +000011327
11328 return "trto";
11329}
11330
11331static HChar *
11332s390_irgen_TROT(UChar m3, UChar r1, UChar r2)
11333{
11334 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
11335 src_addr = newTemp(Ity_I64);
11336 des_addr = newTemp(Ity_I64);
11337 tab_addr = newTemp(Ity_I64);
11338 test_byte = newTemp(Ity_I16);
11339 src_len = newTemp(Ity_I64);
11340
11341 assign(src_addr, get_gpr_dw0(r2));
11342 assign(des_addr, get_gpr_dw0(r1));
11343 assign(tab_addr, get_gpr_dw0(1));
11344 assign(src_len, get_gpr_dw0(r1+1));
11345 assign(test_byte, get_gpr_hw3(0));
11346
11347 IRTemp op = newTemp(Ity_I8);
11348 IRTemp op1 = newTemp(Ity_I16);
11349 IRTemp result = newTemp(Ity_I64);
11350
11351 /* End of source string? We're done; proceed to next insn */
11352 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000011353 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian730448f2012-02-04 17:07:07 +000011354
11355 /* Load character from source string, index translation table and
11356 store translated character in op1. */
11357 assign(op, binop(Iop_Shl8, load(Ity_I8, mkexpr(src_addr)), mkU8(1)));
11358
11359 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)),
11360 mkexpr(tab_addr)));
11361 assign(op1, load(Ity_I16, mkexpr(result)));
11362
11363 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
11364 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000011365 next_insn_if(binop(Iop_CmpEQ16, mkexpr(op1), mkexpr(test_byte)));
florian730448f2012-02-04 17:07:07 +000011366 }
11367 store(get_gpr_dw0(r1), mkexpr(op1));
11368
11369 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(1)));
11370 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(2)));
11371 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(1)));
11372
florian6820ba52012-07-26 02:01:50 +000011373 iterate();
florian730448f2012-02-04 17:07:07 +000011374
11375 return "trot";
11376}
11377
11378static HChar *
11379s390_irgen_TRTT(UChar m3, UChar r1, UChar r2)
11380{
11381 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
11382 src_addr = newTemp(Ity_I64);
11383 des_addr = newTemp(Ity_I64);
11384 tab_addr = newTemp(Ity_I64);
11385 test_byte = newTemp(Ity_I16);
11386 src_len = newTemp(Ity_I64);
11387
11388 assign(src_addr, get_gpr_dw0(r2));
11389 assign(des_addr, get_gpr_dw0(r1));
11390 assign(tab_addr, get_gpr_dw0(1));
11391 assign(src_len, get_gpr_dw0(r1+1));
11392 assign(test_byte, get_gpr_hw3(0));
11393
11394 IRTemp op = newTemp(Ity_I16);
11395 IRTemp op1 = newTemp(Ity_I16);
11396 IRTemp result = newTemp(Ity_I64);
11397
11398 /* End of source string? We're done; proceed to next insn */
11399 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000011400 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian730448f2012-02-04 17:07:07 +000011401
11402 /* Load character from source string, index translation table and
11403 store translated character in op1. */
11404 assign(op, binop(Iop_Shl16, load(Ity_I16, mkexpr(src_addr)), mkU8(1)));
11405
11406 assign(result, binop(Iop_Add64, unop(Iop_16Uto64, mkexpr(op)),
11407 mkexpr(tab_addr)));
11408 assign(op1, load(Ity_I16, mkexpr(result)));
11409
11410 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
11411 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000011412 next_insn_if(binop(Iop_CmpEQ16, mkexpr(op1), mkexpr(test_byte)));
florian730448f2012-02-04 17:07:07 +000011413 }
11414
11415 store(get_gpr_dw0(r1), mkexpr(op1));
11416
11417 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(2)));
11418 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(2)));
11419 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(2)));
11420
florian6820ba52012-07-26 02:01:50 +000011421 iterate();
florian730448f2012-02-04 17:07:07 +000011422
11423 return "trtt";
11424}
11425
11426static HChar *
11427s390_irgen_TR(UChar length, IRTemp start1, IRTemp start2)
11428{
florianf87d4fb2012-05-05 02:55:24 +000011429 IRTemp len = newTemp(Ity_I64);
florian730448f2012-02-04 17:07:07 +000011430
florianf87d4fb2012-05-05 02:55:24 +000011431 assign(len, mkU64(length));
11432 s390_irgen_TR_EX(len, start1, start2);
florian730448f2012-02-04 17:07:07 +000011433
11434 return "tr";
11435}
11436
11437static HChar *
11438s390_irgen_TRE(UChar r1,UChar r2)
11439{
11440 IRTemp src_addr, tab_addr, src_len, test_byte;
11441 src_addr = newTemp(Ity_I64);
11442 tab_addr = newTemp(Ity_I64);
11443 src_len = newTemp(Ity_I64);
11444 test_byte = newTemp(Ity_I8);
11445
11446 assign(src_addr, get_gpr_dw0(r1));
11447 assign(src_len, get_gpr_dw0(r1+1));
11448 assign(tab_addr, get_gpr_dw0(r2));
11449 assign(test_byte, get_gpr_b7(0));
11450
11451 IRTemp op = newTemp(Ity_I8);
11452 IRTemp op1 = newTemp(Ity_I8);
11453 IRTemp result = newTemp(Ity_I64);
11454
11455 /* End of source string? We're done; proceed to next insn */
11456 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000011457 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian730448f2012-02-04 17:07:07 +000011458
11459 /* Load character from source string and compare with test byte */
11460 assign(op, load(Ity_I8, mkexpr(src_addr)));
11461
11462 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000011463 next_insn_if(binop(Iop_CmpEQ8, mkexpr(op), mkexpr(test_byte)));
florian730448f2012-02-04 17:07:07 +000011464
11465 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)),
11466 mkexpr(tab_addr)));
11467
11468 assign(op1, load(Ity_I8, mkexpr(result)));
11469
11470 store(get_gpr_dw0(r1), mkexpr(op1));
11471 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(src_addr), mkU64(1)));
11472 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(1)));
11473
florian6820ba52012-07-26 02:01:50 +000011474 iterate();
florian730448f2012-02-04 17:07:07 +000011475
11476 return "tre";
11477}
11478
floriana0100c92012-07-20 00:06:35 +000011479static IRExpr *
11480s390_call_cu21(IRExpr *srcval, IRExpr *low_surrogate)
11481{
11482 IRExpr **args, *call;
11483 args = mkIRExprVec_2(srcval, low_surrogate);
11484 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
11485 "s390_do_cu21", &s390_do_cu21, args);
11486
11487 /* Nothing is excluded from definedness checking. */
11488 call->Iex.CCall.cee->mcx_mask = 0;
11489
11490 return call;
11491}
11492
11493static HChar *
11494s390_irgen_CU21(UChar m3, UChar r1, UChar r2)
11495{
11496 IRTemp addr1 = newTemp(Ity_I64);
11497 IRTemp addr2 = newTemp(Ity_I64);
11498 IRTemp len1 = newTemp(Ity_I64);
11499 IRTemp len2 = newTemp(Ity_I64);
11500
11501 assign(addr1, get_gpr_dw0(r1));
11502 assign(addr2, get_gpr_dw0(r2));
11503 assign(len1, get_gpr_dw0(r1 + 1));
11504 assign(len2, get_gpr_dw0(r2 + 1));
11505
11506 /* We're processing the 2nd operand 2 bytes at a time. Therefore, if
11507 there are less than 2 bytes left, then the 2nd operand is exhausted
11508 and we're done here. cc = 0 */
11509 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000011510 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(2)));
floriana0100c92012-07-20 00:06:35 +000011511
11512 /* There are at least two bytes there. Read them. */
11513 IRTemp srcval = newTemp(Ity_I32);
11514 assign(srcval, unop(Iop_16Uto32, load(Ity_I16, mkexpr(addr2))));
11515
11516 /* Find out whether this is a high surrogate. I.e. SRCVAL lies
11517 inside the interval [0xd800 - 0xdbff] */
11518 IRTemp is_high_surrogate = newTemp(Ity_I32);
11519 IRExpr *flag1 = mkite(binop(Iop_CmpLE32U, mkU32(0xd800), mkexpr(srcval)),
11520 mkU32(1), mkU32(0));
11521 IRExpr *flag2 = mkite(binop(Iop_CmpLE32U, mkexpr(srcval), mkU32(0xdbff)),
11522 mkU32(1), mkU32(0));
11523 assign(is_high_surrogate, binop(Iop_And32, flag1, flag2));
11524
11525 /* If SRCVAL is a high surrogate and there are less than 4 bytes left,
11526 then the 2nd operand is exhausted and we're done here. cc = 0 */
11527 IRExpr *not_enough_bytes =
11528 mkite(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)), mkU32(1), mkU32(0));
11529
florian6820ba52012-07-26 02:01:50 +000011530 next_insn_if(binop(Iop_CmpEQ32,
11531 binop(Iop_And32, mkexpr(is_high_surrogate),
11532 not_enough_bytes), mkU32(1)));
floriana0100c92012-07-20 00:06:35 +000011533
11534 /* The 2nd operand is not exhausted. If the first 2 bytes are a high
11535 surrogate, read the next two bytes (low surrogate). */
11536 IRTemp low_surrogate = newTemp(Ity_I32);
11537 IRExpr *low_surrogate_addr = binop(Iop_Add64, mkexpr(addr2), mkU64(2));
11538
11539 assign(low_surrogate,
11540 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
11541 unop(Iop_16Uto32, load(Ity_I16, low_surrogate_addr)),
11542 mkU32(0))); // any value is fine; it will not be used
11543
11544 /* Call the helper */
11545 IRTemp retval = newTemp(Ity_I64);
florian11b8ee82012-08-06 13:35:33 +000011546 assign(retval, s390_call_cu21(unop(Iop_32Uto64, mkexpr(srcval)),
11547 unop(Iop_32Uto64, mkexpr(low_surrogate))));
floriana0100c92012-07-20 00:06:35 +000011548
11549 /* Before we can test whether the 1st operand is exhausted we need to
11550 test for an invalid low surrogate. Because cc=2 outranks cc=1. */
11551 if (s390_host_has_etf3 && (m3 & 0x1) == 1) {
11552 IRExpr *invalid_low_surrogate =
11553 binop(Iop_And64, mkexpr(retval), mkU64(0xff));
11554
11555 s390_cc_set(2);
florian6820ba52012-07-26 02:01:50 +000011556 next_insn_if(binop(Iop_CmpEQ64, invalid_low_surrogate, mkU64(1)));
floriana0100c92012-07-20 00:06:35 +000011557 }
11558
11559 /* Now test whether the 1st operand is exhausted */
11560 IRTemp num_bytes = newTemp(Ity_I64);
11561 assign(num_bytes, binop(Iop_And64,
11562 binop(Iop_Shr64, mkexpr(retval), mkU8(8)),
11563 mkU64(0xff)));
11564 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000011565 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
floriana0100c92012-07-20 00:06:35 +000011566
11567 /* Extract the bytes to be stored at addr1 */
11568 IRTemp data = newTemp(Ity_I64);
11569 assign(data, binop(Iop_Shr64, mkexpr(retval), mkU8(16)));
11570
11571 /* To store the bytes construct 4 dirty helper calls. The helper calls
11572 are guarded (num_bytes == 1, num_bytes == 2, etc) such that only
11573 one of them will be called at runtime. */
11574 int i;
11575 for (i = 1; i <= 4; ++i) {
11576 IRDirty *d;
11577
11578 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
11579 &s390x_dirtyhelper_CUxy,
11580 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
11581 mkexpr(num_bytes)));
11582 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
11583 d->mFx = Ifx_Write;
11584 d->mAddr = mkexpr(addr1);
11585 d->mSize = i;
11586 stmt(IRStmt_Dirty(d));
11587 }
11588
11589 /* Update source address and length */
11590 IRTemp num_src_bytes = newTemp(Ity_I64);
11591 assign(num_src_bytes,
11592 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
11593 mkU64(4), mkU64(2)));
11594 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkexpr(num_src_bytes)));
11595 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkexpr(num_src_bytes)));
11596
11597 /* Update destination address and length */
11598 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
11599 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
11600
florian6820ba52012-07-26 02:01:50 +000011601 iterate();
floriana0100c92012-07-20 00:06:35 +000011602
11603 return "cu21";
11604}
11605
florian2a415a12012-07-21 17:41:36 +000011606static IRExpr *
11607s390_call_cu24(IRExpr *srcval, IRExpr *low_surrogate)
11608{
11609 IRExpr **args, *call;
11610 args = mkIRExprVec_2(srcval, low_surrogate);
11611 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
11612 "s390_do_cu24", &s390_do_cu24, args);
11613
11614 /* Nothing is excluded from definedness checking. */
11615 call->Iex.CCall.cee->mcx_mask = 0;
11616
11617 return call;
11618}
11619
11620static HChar *
11621s390_irgen_CU24(UChar m3, UChar r1, UChar r2)
11622{
11623 IRTemp addr1 = newTemp(Ity_I64);
11624 IRTemp addr2 = newTemp(Ity_I64);
11625 IRTemp len1 = newTemp(Ity_I64);
11626 IRTemp len2 = newTemp(Ity_I64);
11627
11628 assign(addr1, get_gpr_dw0(r1));
11629 assign(addr2, get_gpr_dw0(r2));
11630 assign(len1, get_gpr_dw0(r1 + 1));
11631 assign(len2, get_gpr_dw0(r2 + 1));
11632
11633 /* We're processing the 2nd operand 2 bytes at a time. Therefore, if
11634 there are less than 2 bytes left, then the 2nd operand is exhausted
11635 and we're done here. cc = 0 */
11636 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000011637 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(2)));
florian2a415a12012-07-21 17:41:36 +000011638
11639 /* There are at least two bytes there. Read them. */
11640 IRTemp srcval = newTemp(Ity_I32);
11641 assign(srcval, unop(Iop_16Uto32, load(Ity_I16, mkexpr(addr2))));
11642
11643 /* Find out whether this is a high surrogate. I.e. SRCVAL lies
11644 inside the interval [0xd800 - 0xdbff] */
11645 IRTemp is_high_surrogate = newTemp(Ity_I32);
11646 IRExpr *flag1 = mkite(binop(Iop_CmpLE32U, mkU32(0xd800), mkexpr(srcval)),
11647 mkU32(1), mkU32(0));
11648 IRExpr *flag2 = mkite(binop(Iop_CmpLE32U, mkexpr(srcval), mkU32(0xdbff)),
11649 mkU32(1), mkU32(0));
11650 assign(is_high_surrogate, binop(Iop_And32, flag1, flag2));
11651
11652 /* If SRCVAL is a high surrogate and there are less than 4 bytes left,
11653 then the 2nd operand is exhausted and we're done here. cc = 0 */
11654 IRExpr *not_enough_bytes =
11655 mkite(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)), mkU32(1), mkU32(0));
11656
florian6820ba52012-07-26 02:01:50 +000011657 next_insn_if(binop(Iop_CmpEQ32,
11658 binop(Iop_And32, mkexpr(is_high_surrogate),
11659 not_enough_bytes),
11660 mkU32(1)));
florian2a415a12012-07-21 17:41:36 +000011661
11662 /* The 2nd operand is not exhausted. If the first 2 bytes are a high
11663 surrogate, read the next two bytes (low surrogate). */
11664 IRTemp low_surrogate = newTemp(Ity_I32);
11665 IRExpr *low_surrogate_addr = binop(Iop_Add64, mkexpr(addr2), mkU64(2));
11666
11667 assign(low_surrogate,
11668 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
11669 unop(Iop_16Uto32, load(Ity_I16, low_surrogate_addr)),
11670 mkU32(0))); // any value is fine; it will not be used
11671
11672 /* Call the helper */
11673 IRTemp retval = newTemp(Ity_I64);
florian11b8ee82012-08-06 13:35:33 +000011674 assign(retval, s390_call_cu24(unop(Iop_32Uto64, mkexpr(srcval)),
11675 unop(Iop_32Uto64, mkexpr(low_surrogate))));
florian2a415a12012-07-21 17:41:36 +000011676
11677 /* Before we can test whether the 1st operand is exhausted we need to
11678 test for an invalid low surrogate. Because cc=2 outranks cc=1. */
11679 if (s390_host_has_etf3 && (m3 & 0x1) == 1) {
11680 IRExpr *invalid_low_surrogate =
11681 binop(Iop_And64, mkexpr(retval), mkU64(0xff));
11682
11683 s390_cc_set(2);
florian6820ba52012-07-26 02:01:50 +000011684 next_insn_if(binop(Iop_CmpEQ64, invalid_low_surrogate, mkU64(1)));
florian2a415a12012-07-21 17:41:36 +000011685 }
11686
11687 /* Now test whether the 1st operand is exhausted */
11688 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000011689 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkU64(4)));
florian2a415a12012-07-21 17:41:36 +000011690
11691 /* Extract the bytes to be stored at addr1 */
11692 IRExpr *data = unop(Iop_64to32, binop(Iop_Shr64, mkexpr(retval), mkU8(8)));
11693
11694 store(mkexpr(addr1), data);
11695
11696 /* Update source address and length */
11697 IRTemp num_src_bytes = newTemp(Ity_I64);
11698 assign(num_src_bytes,
11699 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
11700 mkU64(4), mkU64(2)));
11701 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkexpr(num_src_bytes)));
11702 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkexpr(num_src_bytes)));
11703
11704 /* Update destination address and length */
11705 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkU64(4)));
11706 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkU64(4)));
11707
florian6820ba52012-07-26 02:01:50 +000011708 iterate();
florian2a415a12012-07-21 17:41:36 +000011709
11710 return "cu24";
11711}
floriana4384a32011-08-11 16:58:45 +000011712
florian956194b2012-07-28 22:18:32 +000011713static IRExpr *
11714s390_call_cu42(IRExpr *srcval)
11715{
11716 IRExpr **args, *call;
11717 args = mkIRExprVec_1(srcval);
11718 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
11719 "s390_do_cu42", &s390_do_cu42, args);
11720
11721 /* Nothing is excluded from definedness checking. */
11722 call->Iex.CCall.cee->mcx_mask = 0;
11723
11724 return call;
11725}
11726
11727static HChar *
11728s390_irgen_CU42(UChar r1, UChar r2)
11729{
11730 IRTemp addr1 = newTemp(Ity_I64);
11731 IRTemp addr2 = newTemp(Ity_I64);
11732 IRTemp len1 = newTemp(Ity_I64);
11733 IRTemp len2 = newTemp(Ity_I64);
11734
11735 assign(addr1, get_gpr_dw0(r1));
11736 assign(addr2, get_gpr_dw0(r2));
11737 assign(len1, get_gpr_dw0(r1 + 1));
11738 assign(len2, get_gpr_dw0(r2 + 1));
11739
11740 /* We're processing the 2nd operand 4 bytes at a time. Therefore, if
11741 there are less than 4 bytes left, then the 2nd operand is exhausted
11742 and we're done here. cc = 0 */
11743 s390_cc_set(0);
11744 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)));
11745
11746 /* Read the 2nd operand. */
11747 IRTemp srcval = newTemp(Ity_I32);
11748 assign(srcval, load(Ity_I32, mkexpr(addr2)));
11749
11750 /* Call the helper */
11751 IRTemp retval = newTemp(Ity_I64);
florian11b8ee82012-08-06 13:35:33 +000011752 assign(retval, s390_call_cu42(unop(Iop_32Uto64, mkexpr(srcval))));
florian956194b2012-07-28 22:18:32 +000011753
11754 /* If the UTF-32 character was invalid, set cc=2 and we're done.
11755 cc=2 outranks cc=1 (1st operand exhausted) */
11756 IRExpr *invalid_character = binop(Iop_And64, mkexpr(retval), mkU64(0xff));
11757
11758 s390_cc_set(2);
11759 next_insn_if(binop(Iop_CmpEQ64, invalid_character, mkU64(1)));
11760
11761 /* Now test whether the 1st operand is exhausted */
11762 IRTemp num_bytes = newTemp(Ity_I64);
11763 assign(num_bytes, binop(Iop_And64,
11764 binop(Iop_Shr64, mkexpr(retval), mkU8(8)),
11765 mkU64(0xff)));
11766 s390_cc_set(1);
11767 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
11768
11769 /* Extract the bytes to be stored at addr1 */
11770 IRTemp data = newTemp(Ity_I64);
11771 assign(data, binop(Iop_Shr64, mkexpr(retval), mkU8(16)));
11772
11773 /* To store the bytes construct 2 dirty helper calls. The helper calls
11774 are guarded (num_bytes == 2 and num_bytes == 4, respectively) such
11775 that only one of them will be called at runtime. */
11776
11777 Int i;
11778 for (i = 2; i <= 4; ++i) {
11779 IRDirty *d;
11780
11781 if (i == 3) continue; // skip this one
11782
11783 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
11784 &s390x_dirtyhelper_CUxy,
11785 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
11786 mkexpr(num_bytes)));
11787 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
11788 d->mFx = Ifx_Write;
11789 d->mAddr = mkexpr(addr1);
11790 d->mSize = i;
11791 stmt(IRStmt_Dirty(d));
11792 }
11793
11794 /* Update source address and length */
11795 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkU64(4)));
11796 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkU64(4)));
11797
11798 /* Update destination address and length */
11799 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
11800 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
11801
11802 iterate();
11803
11804 return "cu42";
11805}
11806
florian6d9b9b22012-08-03 18:35:39 +000011807static IRExpr *
florianaf2194f2012-08-06 00:07:54 +000011808s390_call_cu41(IRExpr *srcval)
11809{
11810 IRExpr **args, *call;
11811 args = mkIRExprVec_1(srcval);
11812 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
11813 "s390_do_cu41", &s390_do_cu41, args);
11814
11815 /* Nothing is excluded from definedness checking. */
11816 call->Iex.CCall.cee->mcx_mask = 0;
11817
11818 return call;
11819}
11820
11821static HChar *
11822s390_irgen_CU41(UChar r1, UChar r2)
11823{
11824 IRTemp addr1 = newTemp(Ity_I64);
11825 IRTemp addr2 = newTemp(Ity_I64);
11826 IRTemp len1 = newTemp(Ity_I64);
11827 IRTemp len2 = newTemp(Ity_I64);
11828
11829 assign(addr1, get_gpr_dw0(r1));
11830 assign(addr2, get_gpr_dw0(r2));
11831 assign(len1, get_gpr_dw0(r1 + 1));
11832 assign(len2, get_gpr_dw0(r2 + 1));
11833
11834 /* We're processing the 2nd operand 4 bytes at a time. Therefore, if
11835 there are less than 4 bytes left, then the 2nd operand is exhausted
11836 and we're done here. cc = 0 */
11837 s390_cc_set(0);
11838 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)));
11839
11840 /* Read the 2nd operand. */
11841 IRTemp srcval = newTemp(Ity_I32);
11842 assign(srcval, load(Ity_I32, mkexpr(addr2)));
11843
11844 /* Call the helper */
11845 IRTemp retval = newTemp(Ity_I64);
florian11b8ee82012-08-06 13:35:33 +000011846 assign(retval, s390_call_cu41(unop(Iop_32Uto64, mkexpr(srcval))));
florianaf2194f2012-08-06 00:07:54 +000011847
11848 /* If the UTF-32 character was invalid, set cc=2 and we're done.
11849 cc=2 outranks cc=1 (1st operand exhausted) */
11850 IRExpr *invalid_character = binop(Iop_And64, mkexpr(retval), mkU64(0xff));
11851
11852 s390_cc_set(2);
11853 next_insn_if(binop(Iop_CmpEQ64, invalid_character, mkU64(1)));
11854
11855 /* Now test whether the 1st operand is exhausted */
11856 IRTemp num_bytes = newTemp(Ity_I64);
11857 assign(num_bytes, binop(Iop_And64,
11858 binop(Iop_Shr64, mkexpr(retval), mkU8(8)),
11859 mkU64(0xff)));
11860 s390_cc_set(1);
11861 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
11862
11863 /* Extract the bytes to be stored at addr1 */
11864 IRTemp data = newTemp(Ity_I64);
11865 assign(data, binop(Iop_Shr64, mkexpr(retval), mkU8(16)));
11866
11867 /* To store the bytes construct 4 dirty helper calls. The helper calls
11868 are guarded (num_bytes == 1, num_bytes == 2, etc) such that only
11869 one of them will be called at runtime. */
11870 int i;
11871 for (i = 1; i <= 4; ++i) {
11872 IRDirty *d;
11873
11874 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
11875 &s390x_dirtyhelper_CUxy,
11876 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
11877 mkexpr(num_bytes)));
11878 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
11879 d->mFx = Ifx_Write;
11880 d->mAddr = mkexpr(addr1);
11881 d->mSize = i;
11882 stmt(IRStmt_Dirty(d));
11883 }
11884
11885 /* Update source address and length */
11886 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkU64(4)));
11887 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkU64(4)));
11888
11889 /* Update destination address and length */
11890 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
11891 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
11892
11893 iterate();
11894
11895 return "cu41";
11896}
11897
11898static IRExpr *
florian3f8a96a2012-08-05 02:59:55 +000011899s390_call_cu12_cu14_helper1(IRExpr *byte1, IRExpr *etf3_and_m3_is_1)
florian6d9b9b22012-08-03 18:35:39 +000011900{
11901 IRExpr **args, *call;
11902 args = mkIRExprVec_2(byte1, etf3_and_m3_is_1);
florian3f8a96a2012-08-05 02:59:55 +000011903 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/, "s390_do_cu12_cu14_helper1",
11904 &s390_do_cu12_cu14_helper1, args);
florian6d9b9b22012-08-03 18:35:39 +000011905
11906 /* Nothing is excluded from definedness checking. */
11907 call->Iex.CCall.cee->mcx_mask = 0;
11908
11909 return call;
11910}
11911
11912static IRExpr *
11913s390_call_cu12_helper2(IRExpr *byte1, IRExpr *byte2, IRExpr *byte3,
11914 IRExpr *byte4, IRExpr *stuff)
11915{
11916 IRExpr **args, *call;
11917 args = mkIRExprVec_5(byte1, byte2, byte3, byte4, stuff);
11918 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
11919 "s390_do_cu12_helper2", &s390_do_cu12_helper2, args);
11920
11921 /* Nothing is excluded from definedness checking. */
11922 call->Iex.CCall.cee->mcx_mask = 0;
11923
11924 return call;
11925}
11926
florian3f8a96a2012-08-05 02:59:55 +000011927static IRExpr *
11928s390_call_cu14_helper2(IRExpr *byte1, IRExpr *byte2, IRExpr *byte3,
11929 IRExpr *byte4, IRExpr *stuff)
11930{
11931 IRExpr **args, *call;
11932 args = mkIRExprVec_5(byte1, byte2, byte3, byte4, stuff);
11933 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
11934 "s390_do_cu14_helper2", &s390_do_cu14_helper2, args);
11935
11936 /* Nothing is excluded from definedness checking. */
11937 call->Iex.CCall.cee->mcx_mask = 0;
11938
11939 return call;
11940}
11941
11942static void
11943s390_irgen_cu12_cu14(UChar m3, UChar r1, UChar r2, Bool is_cu12)
florian6d9b9b22012-08-03 18:35:39 +000011944{
11945 IRTemp addr1 = newTemp(Ity_I64);
11946 IRTemp addr2 = newTemp(Ity_I64);
11947 IRTemp len1 = newTemp(Ity_I64);
11948 IRTemp len2 = newTemp(Ity_I64);
11949
11950 assign(addr1, get_gpr_dw0(r1));
11951 assign(addr2, get_gpr_dw0(r2));
11952 assign(len1, get_gpr_dw0(r1 + 1));
11953 assign(len2, get_gpr_dw0(r2 + 1));
11954
11955 UInt extended_checking = s390_host_has_etf3 && (m3 & 0x1) == 1;
11956
11957 /* We're processing the 2nd operand 1 byte at a time. Therefore, if
11958 there is less than 1 byte left, then the 2nd operand is exhausted
11959 and we're done here. cc = 0 */
11960 s390_cc_set(0);
11961 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(1)));
11962
11963 /* There is at least one byte there. Read it. */
florian11b8ee82012-08-06 13:35:33 +000011964 IRTemp byte1 = newTemp(Ity_I64);
11965 assign(byte1, unop(Iop_8Uto64, load(Ity_I8, mkexpr(addr2))));
florian6d9b9b22012-08-03 18:35:39 +000011966
11967 /* Call the helper to get number of bytes and invalid byte indicator */
11968 IRTemp retval1 = newTemp(Ity_I64);
florian3f8a96a2012-08-05 02:59:55 +000011969 assign(retval1, s390_call_cu12_cu14_helper1(mkexpr(byte1),
florian11b8ee82012-08-06 13:35:33 +000011970 mkU64(extended_checking)));
florian6d9b9b22012-08-03 18:35:39 +000011971
11972 /* Check for invalid 1st byte */
11973 IRExpr *is_invalid = unop(Iop_64to1, mkexpr(retval1));
11974 s390_cc_set(2);
11975 next_insn_if(is_invalid);
11976
11977 /* How many bytes do we have to read? */
11978 IRTemp num_src_bytes = newTemp(Ity_I64);
11979 assign(num_src_bytes, binop(Iop_Shr64, mkexpr(retval1), mkU8(8)));
11980
11981 /* Now test whether the 2nd operand is exhausted */
11982 s390_cc_set(0);
11983 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkexpr(num_src_bytes)));
11984
11985 /* Read the remaining bytes */
11986 IRExpr *cond, *addr, *byte2, *byte3, *byte4;
11987
11988 cond = binop(Iop_CmpLE64U, mkU64(2), mkexpr(num_src_bytes));
11989 addr = binop(Iop_Add64, mkexpr(addr2), mkU64(1));
florian11b8ee82012-08-06 13:35:33 +000011990 byte2 = mkite(cond, unop(Iop_8Uto64, load(Ity_I8, addr)), mkU64(0));
florian6d9b9b22012-08-03 18:35:39 +000011991 cond = binop(Iop_CmpLE64U, mkU64(3), mkexpr(num_src_bytes));
11992 addr = binop(Iop_Add64, mkexpr(addr2), mkU64(2));
florian11b8ee82012-08-06 13:35:33 +000011993 byte3 = mkite(cond, unop(Iop_8Uto64, load(Ity_I8, addr)), mkU64(0));
florian6d9b9b22012-08-03 18:35:39 +000011994 cond = binop(Iop_CmpLE64U, mkU64(4), mkexpr(num_src_bytes));
11995 addr = binop(Iop_Add64, mkexpr(addr2), mkU64(3));
florian11b8ee82012-08-06 13:35:33 +000011996 byte4 = mkite(cond, unop(Iop_8Uto64, load(Ity_I8, addr)), mkU64(0));
florian6d9b9b22012-08-03 18:35:39 +000011997
11998 /* Call the helper to get the converted value and invalid byte indicator.
11999 We can pass at most 5 arguments; therefore some encoding is needed
12000 here */
12001 IRExpr *stuff = binop(Iop_Or64,
12002 binop(Iop_Shl64, mkexpr(num_src_bytes), mkU8(1)),
12003 mkU64(extended_checking));
12004 IRTemp retval2 = newTemp(Ity_I64);
florian3f8a96a2012-08-05 02:59:55 +000012005
12006 if (is_cu12) {
12007 assign(retval2, s390_call_cu12_helper2(mkexpr(byte1), byte2, byte3,
12008 byte4, stuff));
12009 } else {
12010 assign(retval2, s390_call_cu14_helper2(mkexpr(byte1), byte2, byte3,
12011 byte4, stuff));
12012 }
florian6d9b9b22012-08-03 18:35:39 +000012013
12014 /* Check for invalid character */
12015 s390_cc_set(2);
12016 is_invalid = unop(Iop_64to1, mkexpr(retval2));
12017 next_insn_if(is_invalid);
12018
12019 /* Now test whether the 1st operand is exhausted */
12020 IRTemp num_bytes = newTemp(Ity_I64);
12021 assign(num_bytes, binop(Iop_And64,
12022 binop(Iop_Shr64, mkexpr(retval2), mkU8(8)),
12023 mkU64(0xff)));
12024 s390_cc_set(1);
12025 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
12026
12027 /* Extract the bytes to be stored at addr1 */
12028 IRTemp data = newTemp(Ity_I64);
12029 assign(data, binop(Iop_Shr64, mkexpr(retval2), mkU8(16)));
12030
florian3f8a96a2012-08-05 02:59:55 +000012031 if (is_cu12) {
12032 /* To store the bytes construct 2 dirty helper calls. The helper calls
12033 are guarded (num_bytes == 2 and num_bytes == 4, respectively) such
12034 that only one of them will be called at runtime. */
florian6d9b9b22012-08-03 18:35:39 +000012035
florian3f8a96a2012-08-05 02:59:55 +000012036 Int i;
12037 for (i = 2; i <= 4; ++i) {
12038 IRDirty *d;
florian6d9b9b22012-08-03 18:35:39 +000012039
florian3f8a96a2012-08-05 02:59:55 +000012040 if (i == 3) continue; // skip this one
florian6d9b9b22012-08-03 18:35:39 +000012041
florian3f8a96a2012-08-05 02:59:55 +000012042 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
12043 &s390x_dirtyhelper_CUxy,
12044 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
12045 mkexpr(num_bytes)));
12046 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
12047 d->mFx = Ifx_Write;
12048 d->mAddr = mkexpr(addr1);
12049 d->mSize = i;
12050 stmt(IRStmt_Dirty(d));
12051 }
12052 } else {
12053 // cu14
12054 store(mkexpr(addr1), unop(Iop_64to32, mkexpr(data)));
florian6d9b9b22012-08-03 18:35:39 +000012055 }
12056
12057 /* Update source address and length */
12058 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkexpr(num_src_bytes)));
12059 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkexpr(num_src_bytes)));
12060
12061 /* Update destination address and length */
12062 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
12063 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
12064
12065 iterate();
florian3f8a96a2012-08-05 02:59:55 +000012066}
12067
12068static HChar *
12069s390_irgen_CU12(UChar m3, UChar r1, UChar r2)
12070{
12071 s390_irgen_cu12_cu14(m3, r1, r2, /* is_cu12 = */ 1);
florian6d9b9b22012-08-03 18:35:39 +000012072
12073 return "cu12";
12074}
12075
florian3f8a96a2012-08-05 02:59:55 +000012076static HChar *
12077s390_irgen_CU14(UChar m3, UChar r1, UChar r2)
12078{
12079 s390_irgen_cu12_cu14(m3, r1, r2, /* is_cu12 = */ 0);
12080
12081 return "cu14";
12082}
12083
florian8c88cb62012-08-26 18:58:13 +000012084static IRExpr *
12085s390_call_ecag(IRExpr *op2addr)
12086{
12087 IRExpr **args, *call;
12088
12089 args = mkIRExprVec_1(op2addr);
12090 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
12091 "s390_do_ecag", &s390_do_ecag, args);
12092
12093 /* Nothing is excluded from definedness checking. */
12094 call->Iex.CCall.cee->mcx_mask = 0;
12095
12096 return call;
12097}
12098
12099static HChar *
floriand2129202012-09-01 20:01:39 +000012100s390_irgen_ECAG(UChar r1, UChar r3 __attribute__((unused)), IRTemp op2addr)
florian8c88cb62012-08-26 18:58:13 +000012101{
12102 if (! s390_host_has_gie) {
floriane75dafa2012-09-01 17:54:09 +000012103 emulation_failure(EmFail_S390X_ecag);
florian8c88cb62012-08-26 18:58:13 +000012104 } else {
12105 put_gpr_dw0(r1, s390_call_ecag(mkexpr(op2addr)));
12106 }
12107
12108 return "ecag";
12109}
12110
12111
sewardj2019a972011-03-07 16:04:07 +000012112/*------------------------------------------------------------*/
12113/*--- Build IR for special instructions ---*/
12114/*------------------------------------------------------------*/
12115
florianb4df7682011-07-05 02:09:01 +000012116static void
sewardj2019a972011-03-07 16:04:07 +000012117s390_irgen_client_request(void)
12118{
12119 if (0)
12120 vex_printf("%%R3 = client_request ( %%R2 )\n");
12121
florianf9e1ed72012-04-17 02:41:56 +000012122 Addr64 next = guest_IA_curr_instr + S390_SPECIAL_OP_PREAMBLE_SIZE
12123 + S390_SPECIAL_OP_SIZE;
sewardj2019a972011-03-07 16:04:07 +000012124
florianf9e1ed72012-04-17 02:41:56 +000012125 dis_res->jk_StopHere = Ijk_ClientReq;
sewardj2019a972011-03-07 16:04:07 +000012126 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +000012127
12128 put_IA(mkaddr_expr(next));
sewardj2019a972011-03-07 16:04:07 +000012129}
12130
florianb4df7682011-07-05 02:09:01 +000012131static void
sewardj2019a972011-03-07 16:04:07 +000012132s390_irgen_guest_NRADDR(void)
12133{
12134 if (0)
12135 vex_printf("%%R3 = guest_NRADDR\n");
12136
floriane88b3c92011-07-05 02:48:39 +000012137 put_gpr_dw0(3, IRExpr_Get(S390X_GUEST_OFFSET(guest_NRADDR), Ity_I64));
sewardj2019a972011-03-07 16:04:07 +000012138}
12139
florianb4df7682011-07-05 02:09:01 +000012140static void
sewardj2019a972011-03-07 16:04:07 +000012141s390_irgen_call_noredir(void)
12142{
florianf9e1ed72012-04-17 02:41:56 +000012143 Addr64 next = guest_IA_curr_instr + S390_SPECIAL_OP_PREAMBLE_SIZE
12144 + S390_SPECIAL_OP_SIZE;
12145
sewardj2019a972011-03-07 16:04:07 +000012146 /* Continue after special op */
florianf9e1ed72012-04-17 02:41:56 +000012147 put_gpr_dw0(14, mkaddr_expr(next));
sewardj2019a972011-03-07 16:04:07 +000012148
12149 /* The address is in REG1, all parameters are in the right (guest) places */
florianf9e1ed72012-04-17 02:41:56 +000012150 put_IA(get_gpr_dw0(1));
sewardj2019a972011-03-07 16:04:07 +000012151
12152 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +000012153 dis_res->jk_StopHere = Ijk_NoRedir;
sewardj2019a972011-03-07 16:04:07 +000012154}
12155
12156/* Force proper alignment for the structures below. */
12157#pragma pack(1)
12158
12159
12160static s390_decode_t
12161s390_decode_2byte_and_irgen(UChar *bytes)
12162{
12163 typedef union {
12164 struct {
12165 unsigned int op : 16;
12166 } E;
12167 struct {
12168 unsigned int op : 8;
12169 unsigned int i : 8;
12170 } I;
12171 struct {
12172 unsigned int op : 8;
12173 unsigned int r1 : 4;
12174 unsigned int r2 : 4;
12175 } RR;
12176 } formats;
12177 union {
12178 formats fmt;
12179 UShort value;
12180 } ovl;
12181
12182 vassert(sizeof(formats) == 2);
12183
12184 ((char *)(&ovl.value))[0] = bytes[0];
12185 ((char *)(&ovl.value))[1] = bytes[1];
12186
12187 switch (ovl.value & 0xffff) {
12188 case 0x0101: /* PR */ goto unimplemented;
12189 case 0x0102: /* UPT */ goto unimplemented;
12190 case 0x0104: /* PTFF */ goto unimplemented;
12191 case 0x0107: /* SCKPF */ goto unimplemented;
12192 case 0x010a: /* PFPO */ goto unimplemented;
12193 case 0x010b: /* TAM */ goto unimplemented;
12194 case 0x010c: /* SAM24 */ goto unimplemented;
12195 case 0x010d: /* SAM31 */ goto unimplemented;
12196 case 0x010e: /* SAM64 */ goto unimplemented;
12197 case 0x01ff: /* TRAP2 */ goto unimplemented;
12198 }
12199
12200 switch ((ovl.value & 0xff00) >> 8) {
12201 case 0x04: /* SPM */ goto unimplemented;
12202 case 0x05: /* BALR */ goto unimplemented;
12203 case 0x06: s390_format_RR_RR(s390_irgen_BCTR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12204 goto ok;
12205 case 0x07: s390_format_RR(s390_irgen_BCR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12206 goto ok;
12207 case 0x0a: s390_format_I(s390_irgen_SVC, ovl.fmt.I.i); goto ok;
12208 case 0x0b: /* BSM */ goto unimplemented;
12209 case 0x0c: /* BASSM */ goto unimplemented;
12210 case 0x0d: s390_format_RR_RR(s390_irgen_BASR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12211 goto ok;
florianb0c9a132011-09-08 15:37:39 +000012212 case 0x0e: s390_format_RR(s390_irgen_MVCL, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12213 goto ok;
12214 case 0x0f: s390_format_RR(s390_irgen_CLCL, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12215 goto ok;
sewardj2019a972011-03-07 16:04:07 +000012216 case 0x10: s390_format_RR_RR(s390_irgen_LPR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12217 goto ok;
12218 case 0x11: s390_format_RR_RR(s390_irgen_LNR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12219 goto ok;
12220 case 0x12: s390_format_RR_RR(s390_irgen_LTR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12221 goto ok;
12222 case 0x13: s390_format_RR_RR(s390_irgen_LCR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12223 goto ok;
12224 case 0x14: s390_format_RR_RR(s390_irgen_NR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12225 goto ok;
12226 case 0x15: s390_format_RR_RR(s390_irgen_CLR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12227 goto ok;
12228 case 0x16: s390_format_RR_RR(s390_irgen_OR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12229 goto ok;
12230 case 0x17: s390_format_RR_RR(s390_irgen_XR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12231 goto ok;
12232 case 0x18: s390_format_RR_RR(s390_irgen_LR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12233 goto ok;
12234 case 0x19: s390_format_RR_RR(s390_irgen_CR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12235 goto ok;
12236 case 0x1a: s390_format_RR_RR(s390_irgen_AR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12237 goto ok;
12238 case 0x1b: s390_format_RR_RR(s390_irgen_SR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12239 goto ok;
12240 case 0x1c: s390_format_RR_RR(s390_irgen_MR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12241 goto ok;
12242 case 0x1d: s390_format_RR_RR(s390_irgen_DR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12243 goto ok;
12244 case 0x1e: s390_format_RR_RR(s390_irgen_ALR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12245 goto ok;
12246 case 0x1f: s390_format_RR_RR(s390_irgen_SLR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12247 goto ok;
12248 case 0x20: /* LPDR */ goto unimplemented;
12249 case 0x21: /* LNDR */ goto unimplemented;
12250 case 0x22: /* LTDR */ goto unimplemented;
12251 case 0x23: /* LCDR */ goto unimplemented;
12252 case 0x24: /* HDR */ goto unimplemented;
12253 case 0x25: /* LDXR */ goto unimplemented;
12254 case 0x26: /* MXR */ goto unimplemented;
12255 case 0x27: /* MXDR */ goto unimplemented;
12256 case 0x28: s390_format_RR_FF(s390_irgen_LDR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12257 goto ok;
12258 case 0x29: /* CDR */ goto unimplemented;
12259 case 0x2a: /* ADR */ goto unimplemented;
12260 case 0x2b: /* SDR */ goto unimplemented;
12261 case 0x2c: /* MDR */ goto unimplemented;
12262 case 0x2d: /* DDR */ goto unimplemented;
12263 case 0x2e: /* AWR */ goto unimplemented;
12264 case 0x2f: /* SWR */ goto unimplemented;
12265 case 0x30: /* LPER */ goto unimplemented;
12266 case 0x31: /* LNER */ goto unimplemented;
12267 case 0x32: /* LTER */ goto unimplemented;
12268 case 0x33: /* LCER */ goto unimplemented;
12269 case 0x34: /* HER */ goto unimplemented;
12270 case 0x35: /* LEDR */ goto unimplemented;
12271 case 0x36: /* AXR */ goto unimplemented;
12272 case 0x37: /* SXR */ goto unimplemented;
12273 case 0x38: s390_format_RR_FF(s390_irgen_LER, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12274 goto ok;
12275 case 0x39: /* CER */ goto unimplemented;
12276 case 0x3a: /* AER */ goto unimplemented;
12277 case 0x3b: /* SER */ goto unimplemented;
12278 case 0x3c: /* MDER */ goto unimplemented;
12279 case 0x3d: /* DER */ goto unimplemented;
12280 case 0x3e: /* AUR */ goto unimplemented;
12281 case 0x3f: /* SUR */ goto unimplemented;
12282 }
12283
12284 return S390_DECODE_UNKNOWN_INSN;
12285
12286ok:
12287 return S390_DECODE_OK;
12288
12289unimplemented:
12290 return S390_DECODE_UNIMPLEMENTED_INSN;
12291}
12292
12293static s390_decode_t
12294s390_decode_4byte_and_irgen(UChar *bytes)
12295{
12296 typedef union {
12297 struct {
12298 unsigned int op1 : 8;
12299 unsigned int r1 : 4;
12300 unsigned int op2 : 4;
12301 unsigned int i2 : 16;
12302 } RI;
12303 struct {
12304 unsigned int op : 16;
12305 unsigned int : 8;
12306 unsigned int r1 : 4;
12307 unsigned int r2 : 4;
12308 } RRE;
12309 struct {
12310 unsigned int op : 16;
12311 unsigned int r1 : 4;
12312 unsigned int : 4;
12313 unsigned int r3 : 4;
12314 unsigned int r2 : 4;
12315 } RRF;
12316 struct {
12317 unsigned int op : 16;
florian1c8f7ff2012-09-01 00:12:11 +000012318 unsigned int m3 : 4;
sewardj2019a972011-03-07 16:04:07 +000012319 unsigned int m4 : 4;
12320 unsigned int r1 : 4;
12321 unsigned int r2 : 4;
12322 } RRF2;
12323 struct {
12324 unsigned int op : 16;
12325 unsigned int r3 : 4;
12326 unsigned int : 4;
12327 unsigned int r1 : 4;
12328 unsigned int r2 : 4;
12329 } RRF3;
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 } RRR;
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 } RRF4;
12344 struct {
12345 unsigned int op : 8;
12346 unsigned int r1 : 4;
12347 unsigned int r3 : 4;
12348 unsigned int b2 : 4;
12349 unsigned int d2 : 12;
12350 } RS;
12351 struct {
12352 unsigned int op : 8;
12353 unsigned int r1 : 4;
12354 unsigned int r3 : 4;
12355 unsigned int i2 : 16;
12356 } RSI;
12357 struct {
12358 unsigned int op : 8;
12359 unsigned int r1 : 4;
12360 unsigned int x2 : 4;
12361 unsigned int b2 : 4;
12362 unsigned int d2 : 12;
12363 } RX;
12364 struct {
12365 unsigned int op : 16;
12366 unsigned int b2 : 4;
12367 unsigned int d2 : 12;
12368 } S;
12369 struct {
12370 unsigned int op : 8;
12371 unsigned int i2 : 8;
12372 unsigned int b1 : 4;
12373 unsigned int d1 : 12;
12374 } SI;
12375 } formats;
12376 union {
12377 formats fmt;
12378 UInt value;
12379 } ovl;
12380
12381 vassert(sizeof(formats) == 4);
12382
12383 ((char *)(&ovl.value))[0] = bytes[0];
12384 ((char *)(&ovl.value))[1] = bytes[1];
12385 ((char *)(&ovl.value))[2] = bytes[2];
12386 ((char *)(&ovl.value))[3] = bytes[3];
12387
12388 switch ((ovl.value & 0xff0f0000) >> 16) {
12389 case 0xa500: s390_format_RI_RU(s390_irgen_IIHH, ovl.fmt.RI.r1,
12390 ovl.fmt.RI.i2); goto ok;
12391 case 0xa501: s390_format_RI_RU(s390_irgen_IIHL, ovl.fmt.RI.r1,
12392 ovl.fmt.RI.i2); goto ok;
12393 case 0xa502: s390_format_RI_RU(s390_irgen_IILH, ovl.fmt.RI.r1,
12394 ovl.fmt.RI.i2); goto ok;
12395 case 0xa503: s390_format_RI_RU(s390_irgen_IILL, ovl.fmt.RI.r1,
12396 ovl.fmt.RI.i2); goto ok;
12397 case 0xa504: s390_format_RI_RU(s390_irgen_NIHH, ovl.fmt.RI.r1,
12398 ovl.fmt.RI.i2); goto ok;
12399 case 0xa505: s390_format_RI_RU(s390_irgen_NIHL, ovl.fmt.RI.r1,
12400 ovl.fmt.RI.i2); goto ok;
12401 case 0xa506: s390_format_RI_RU(s390_irgen_NILH, ovl.fmt.RI.r1,
12402 ovl.fmt.RI.i2); goto ok;
12403 case 0xa507: s390_format_RI_RU(s390_irgen_NILL, ovl.fmt.RI.r1,
12404 ovl.fmt.RI.i2); goto ok;
12405 case 0xa508: s390_format_RI_RU(s390_irgen_OIHH, ovl.fmt.RI.r1,
12406 ovl.fmt.RI.i2); goto ok;
12407 case 0xa509: s390_format_RI_RU(s390_irgen_OIHL, ovl.fmt.RI.r1,
12408 ovl.fmt.RI.i2); goto ok;
12409 case 0xa50a: s390_format_RI_RU(s390_irgen_OILH, ovl.fmt.RI.r1,
12410 ovl.fmt.RI.i2); goto ok;
12411 case 0xa50b: s390_format_RI_RU(s390_irgen_OILL, ovl.fmt.RI.r1,
12412 ovl.fmt.RI.i2); goto ok;
12413 case 0xa50c: s390_format_RI_RU(s390_irgen_LLIHH, ovl.fmt.RI.r1,
12414 ovl.fmt.RI.i2); goto ok;
12415 case 0xa50d: s390_format_RI_RU(s390_irgen_LLIHL, ovl.fmt.RI.r1,
12416 ovl.fmt.RI.i2); goto ok;
12417 case 0xa50e: s390_format_RI_RU(s390_irgen_LLILH, ovl.fmt.RI.r1,
12418 ovl.fmt.RI.i2); goto ok;
12419 case 0xa50f: s390_format_RI_RU(s390_irgen_LLILL, ovl.fmt.RI.r1,
12420 ovl.fmt.RI.i2); goto ok;
12421 case 0xa700: s390_format_RI_RU(s390_irgen_TMLH, ovl.fmt.RI.r1,
12422 ovl.fmt.RI.i2); goto ok;
12423 case 0xa701: s390_format_RI_RU(s390_irgen_TMLL, ovl.fmt.RI.r1,
12424 ovl.fmt.RI.i2); goto ok;
12425 case 0xa702: s390_format_RI_RU(s390_irgen_TMHH, ovl.fmt.RI.r1,
12426 ovl.fmt.RI.i2); goto ok;
12427 case 0xa703: s390_format_RI_RU(s390_irgen_TMHL, ovl.fmt.RI.r1,
12428 ovl.fmt.RI.i2); goto ok;
12429 case 0xa704: s390_format_RI(s390_irgen_BRC, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
12430 goto ok;
12431 case 0xa705: s390_format_RI_RP(s390_irgen_BRAS, ovl.fmt.RI.r1,
12432 ovl.fmt.RI.i2); goto ok;
12433 case 0xa706: s390_format_RI_RP(s390_irgen_BRCT, ovl.fmt.RI.r1,
12434 ovl.fmt.RI.i2); goto ok;
12435 case 0xa707: s390_format_RI_RP(s390_irgen_BRCTG, ovl.fmt.RI.r1,
12436 ovl.fmt.RI.i2); goto ok;
12437 case 0xa708: s390_format_RI_RI(s390_irgen_LHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
12438 goto ok;
12439 case 0xa709: s390_format_RI_RI(s390_irgen_LGHI, ovl.fmt.RI.r1,
12440 ovl.fmt.RI.i2); goto ok;
12441 case 0xa70a: s390_format_RI_RI(s390_irgen_AHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
12442 goto ok;
12443 case 0xa70b: s390_format_RI_RI(s390_irgen_AGHI, ovl.fmt.RI.r1,
12444 ovl.fmt.RI.i2); goto ok;
12445 case 0xa70c: s390_format_RI_RI(s390_irgen_MHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
12446 goto ok;
12447 case 0xa70d: s390_format_RI_RI(s390_irgen_MGHI, ovl.fmt.RI.r1,
12448 ovl.fmt.RI.i2); goto ok;
12449 case 0xa70e: s390_format_RI_RI(s390_irgen_CHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
12450 goto ok;
12451 case 0xa70f: s390_format_RI_RI(s390_irgen_CGHI, ovl.fmt.RI.r1,
12452 ovl.fmt.RI.i2); goto ok;
12453 }
12454
12455 switch ((ovl.value & 0xffff0000) >> 16) {
12456 case 0x8000: /* SSM */ goto unimplemented;
12457 case 0x8200: /* LPSW */ goto unimplemented;
florian7700fc92012-01-16 17:25:55 +000012458 case 0x9300: /* TS */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000012459 case 0xb202: /* STIDP */ goto unimplemented;
12460 case 0xb204: /* SCK */ goto unimplemented;
florian7700fc92012-01-16 17:25:55 +000012461 case 0xb205: s390_format_S_RD(s390_irgen_STCK, ovl.fmt.S.b2, ovl.fmt.S.d2);
12462 goto ok;
sewardj2019a972011-03-07 16:04:07 +000012463 case 0xb206: /* SCKC */ goto unimplemented;
12464 case 0xb207: /* STCKC */ goto unimplemented;
12465 case 0xb208: /* SPT */ goto unimplemented;
12466 case 0xb209: /* STPT */ goto unimplemented;
12467 case 0xb20a: /* SPKA */ goto unimplemented;
12468 case 0xb20b: /* IPK */ goto unimplemented;
12469 case 0xb20d: /* PTLB */ goto unimplemented;
12470 case 0xb210: /* SPX */ goto unimplemented;
12471 case 0xb211: /* STPX */ goto unimplemented;
12472 case 0xb212: /* STAP */ goto unimplemented;
12473 case 0xb214: /* SIE */ goto unimplemented;
12474 case 0xb218: /* PC */ goto unimplemented;
12475 case 0xb219: /* SAC */ goto unimplemented;
12476 case 0xb21a: /* CFC */ goto unimplemented;
12477 case 0xb221: /* IPTE */ goto unimplemented;
12478 case 0xb222: s390_format_RRE_R0(s390_irgen_IPM, ovl.fmt.RRE.r1); goto ok;
12479 case 0xb223: /* IVSK */ goto unimplemented;
12480 case 0xb224: /* IAC */ goto unimplemented;
12481 case 0xb225: /* SSAR */ goto unimplemented;
12482 case 0xb226: /* EPAR */ goto unimplemented;
12483 case 0xb227: /* ESAR */ goto unimplemented;
12484 case 0xb228: /* PT */ goto unimplemented;
12485 case 0xb229: /* ISKE */ goto unimplemented;
12486 case 0xb22a: /* RRBE */ goto unimplemented;
12487 case 0xb22b: /* SSKE */ goto unimplemented;
12488 case 0xb22c: /* TB */ goto unimplemented;
12489 case 0xb22d: /* DXR */ goto unimplemented;
12490 case 0xb22e: /* PGIN */ goto unimplemented;
12491 case 0xb22f: /* PGOUT */ goto unimplemented;
12492 case 0xb230: /* CSCH */ goto unimplemented;
12493 case 0xb231: /* HSCH */ goto unimplemented;
12494 case 0xb232: /* MSCH */ goto unimplemented;
12495 case 0xb233: /* SSCH */ goto unimplemented;
12496 case 0xb234: /* STSCH */ goto unimplemented;
12497 case 0xb235: /* TSCH */ goto unimplemented;
12498 case 0xb236: /* TPI */ goto unimplemented;
12499 case 0xb237: /* SAL */ goto unimplemented;
12500 case 0xb238: /* RSCH */ goto unimplemented;
12501 case 0xb239: /* STCRW */ goto unimplemented;
12502 case 0xb23a: /* STCPS */ goto unimplemented;
12503 case 0xb23b: /* RCHP */ goto unimplemented;
12504 case 0xb23c: /* SCHM */ goto unimplemented;
12505 case 0xb240: /* BAKR */ goto unimplemented;
floriana4384a32011-08-11 16:58:45 +000012506 case 0xb241: s390_format_RRE(s390_irgen_CKSM, ovl.fmt.RRE.r1,
12507 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000012508 case 0xb244: /* SQDR */ goto unimplemented;
12509 case 0xb245: /* SQER */ goto unimplemented;
12510 case 0xb246: /* STURA */ goto unimplemented;
12511 case 0xb247: /* MSTA */ goto unimplemented;
12512 case 0xb248: /* PALB */ goto unimplemented;
12513 case 0xb249: /* EREG */ goto unimplemented;
12514 case 0xb24a: /* ESTA */ goto unimplemented;
12515 case 0xb24b: /* LURA */ goto unimplemented;
12516 case 0xb24c: /* TAR */ goto unimplemented;
12517 case 0xb24d: s390_format_RRE(s390_irgen_CPYA, ovl.fmt.RRE.r1,
12518 ovl.fmt.RRE.r2); goto ok;
12519 case 0xb24e: s390_format_RRE(s390_irgen_SAR, ovl.fmt.RRE.r1, ovl.fmt.RRE.r2);
12520 goto ok;
12521 case 0xb24f: s390_format_RRE(s390_irgen_EAR, ovl.fmt.RRE.r1, ovl.fmt.RRE.r2);
12522 goto ok;
12523 case 0xb250: /* CSP */ goto unimplemented;
12524 case 0xb252: s390_format_RRE_RR(s390_irgen_MSR, ovl.fmt.RRE.r1,
12525 ovl.fmt.RRE.r2); goto ok;
12526 case 0xb254: /* MVPG */ goto unimplemented;
12527 case 0xb255: s390_format_RRE_RR(s390_irgen_MVST, ovl.fmt.RRE.r1,
12528 ovl.fmt.RRE.r2); goto ok;
12529 case 0xb257: /* CUSE */ goto unimplemented;
12530 case 0xb258: /* BSG */ goto unimplemented;
12531 case 0xb25a: /* BSA */ goto unimplemented;
12532 case 0xb25d: s390_format_RRE_RR(s390_irgen_CLST, ovl.fmt.RRE.r1,
12533 ovl.fmt.RRE.r2); goto ok;
12534 case 0xb25e: s390_format_RRE_RR(s390_irgen_SRST, ovl.fmt.RRE.r1,
12535 ovl.fmt.RRE.r2); goto ok;
12536 case 0xb263: /* CMPSC */ goto unimplemented;
12537 case 0xb274: /* SIGA */ goto unimplemented;
12538 case 0xb276: /* XSCH */ goto unimplemented;
12539 case 0xb277: /* RP */ goto unimplemented;
sewardj1e5fea62011-05-17 16:18:36 +000012540 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 +000012541 case 0xb279: /* SACF */ goto unimplemented;
sewardj1e5fea62011-05-17 16:18:36 +000012542 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 +000012543 case 0xb27d: /* STSI */ goto unimplemented;
12544 case 0xb299: s390_format_S_RD(s390_irgen_SRNM, ovl.fmt.S.b2, ovl.fmt.S.d2);
12545 goto ok;
12546 case 0xb29c: s390_format_S_RD(s390_irgen_STFPC, ovl.fmt.S.b2, ovl.fmt.S.d2);
12547 goto ok;
12548 case 0xb29d: s390_format_S_RD(s390_irgen_LFPC, ovl.fmt.S.b2, ovl.fmt.S.d2);
12549 goto ok;
florian730448f2012-02-04 17:07:07 +000012550 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 +000012551 case 0xb2a6: s390_format_RRF_M0RERE(s390_irgen_CU21, ovl.fmt.RRF3.r3,
12552 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
12553 goto ok;
florian6d9b9b22012-08-03 18:35:39 +000012554 case 0xb2a7: s390_format_RRF_M0RERE(s390_irgen_CU12, ovl.fmt.RRF3.r3,
12555 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
12556 goto ok;
florian933065d2011-07-11 01:48:02 +000012557 case 0xb2b0: s390_format_S_RD(s390_irgen_STFLE, ovl.fmt.S.b2, ovl.fmt.S.d2);
12558 goto ok;
sewardj2019a972011-03-07 16:04:07 +000012559 case 0xb2b1: /* STFL */ goto unimplemented;
12560 case 0xb2b2: /* LPSWE */ goto unimplemented;
12561 case 0xb2b8: /* SRNMB */ goto unimplemented;
12562 case 0xb2b9: /* SRNMT */ goto unimplemented;
12563 case 0xb2bd: /* LFAS */ goto unimplemented;
12564 case 0xb2ff: /* TRAP4 */ goto unimplemented;
12565 case 0xb300: s390_format_RRE_FF(s390_irgen_LPEBR, ovl.fmt.RRE.r1,
12566 ovl.fmt.RRE.r2); goto ok;
12567 case 0xb301: s390_format_RRE_FF(s390_irgen_LNEBR, ovl.fmt.RRE.r1,
12568 ovl.fmt.RRE.r2); goto ok;
12569 case 0xb302: s390_format_RRE_FF(s390_irgen_LTEBR, ovl.fmt.RRE.r1,
12570 ovl.fmt.RRE.r2); goto ok;
12571 case 0xb303: s390_format_RRE_FF(s390_irgen_LCEBR, ovl.fmt.RRE.r1,
12572 ovl.fmt.RRE.r2); goto ok;
12573 case 0xb304: s390_format_RRE_FF(s390_irgen_LDEBR, ovl.fmt.RRE.r1,
12574 ovl.fmt.RRE.r2); goto ok;
12575 case 0xb305: s390_format_RRE_FF(s390_irgen_LXDBR, ovl.fmt.RRE.r1,
12576 ovl.fmt.RRE.r2); goto ok;
12577 case 0xb306: s390_format_RRE_FF(s390_irgen_LXEBR, ovl.fmt.RRE.r1,
12578 ovl.fmt.RRE.r2); goto ok;
12579 case 0xb307: /* MXDBR */ goto unimplemented;
12580 case 0xb308: /* KEBR */ goto unimplemented;
12581 case 0xb309: s390_format_RRE_FF(s390_irgen_CEBR, ovl.fmt.RRE.r1,
12582 ovl.fmt.RRE.r2); goto ok;
12583 case 0xb30a: s390_format_RRE_FF(s390_irgen_AEBR, ovl.fmt.RRE.r1,
12584 ovl.fmt.RRE.r2); goto ok;
12585 case 0xb30b: s390_format_RRE_FF(s390_irgen_SEBR, ovl.fmt.RRE.r1,
12586 ovl.fmt.RRE.r2); goto ok;
12587 case 0xb30c: /* MDEBR */ goto unimplemented;
12588 case 0xb30d: s390_format_RRE_FF(s390_irgen_DEBR, ovl.fmt.RRE.r1,
12589 ovl.fmt.RRE.r2); goto ok;
12590 case 0xb30e: s390_format_RRF_F0FF(s390_irgen_MAEBR, ovl.fmt.RRF.r1,
12591 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
12592 case 0xb30f: s390_format_RRF_F0FF(s390_irgen_MSEBR, ovl.fmt.RRF.r1,
12593 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
12594 case 0xb310: s390_format_RRE_FF(s390_irgen_LPDBR, ovl.fmt.RRE.r1,
12595 ovl.fmt.RRE.r2); goto ok;
12596 case 0xb311: s390_format_RRE_FF(s390_irgen_LNDBR, ovl.fmt.RRE.r1,
12597 ovl.fmt.RRE.r2); goto ok;
12598 case 0xb312: s390_format_RRE_FF(s390_irgen_LTDBR, ovl.fmt.RRE.r1,
12599 ovl.fmt.RRE.r2); goto ok;
12600 case 0xb313: s390_format_RRE_FF(s390_irgen_LCDBR, ovl.fmt.RRE.r1,
12601 ovl.fmt.RRE.r2); goto ok;
12602 case 0xb314: s390_format_RRE_FF(s390_irgen_SQEBR, ovl.fmt.RRE.r1,
12603 ovl.fmt.RRE.r2); goto ok;
12604 case 0xb315: s390_format_RRE_FF(s390_irgen_SQDBR, ovl.fmt.RRE.r1,
12605 ovl.fmt.RRE.r2); goto ok;
12606 case 0xb316: s390_format_RRE_FF(s390_irgen_SQXBR, ovl.fmt.RRE.r1,
12607 ovl.fmt.RRE.r2); goto ok;
12608 case 0xb317: s390_format_RRE_FF(s390_irgen_MEEBR, ovl.fmt.RRE.r1,
12609 ovl.fmt.RRE.r2); goto ok;
12610 case 0xb318: /* KDBR */ goto unimplemented;
12611 case 0xb319: s390_format_RRE_FF(s390_irgen_CDBR, ovl.fmt.RRE.r1,
12612 ovl.fmt.RRE.r2); goto ok;
12613 case 0xb31a: s390_format_RRE_FF(s390_irgen_ADBR, ovl.fmt.RRE.r1,
12614 ovl.fmt.RRE.r2); goto ok;
12615 case 0xb31b: s390_format_RRE_FF(s390_irgen_SDBR, ovl.fmt.RRE.r1,
12616 ovl.fmt.RRE.r2); goto ok;
12617 case 0xb31c: s390_format_RRE_FF(s390_irgen_MDBR, ovl.fmt.RRE.r1,
12618 ovl.fmt.RRE.r2); goto ok;
12619 case 0xb31d: s390_format_RRE_FF(s390_irgen_DDBR, ovl.fmt.RRE.r1,
12620 ovl.fmt.RRE.r2); goto ok;
12621 case 0xb31e: s390_format_RRF_F0FF(s390_irgen_MADBR, ovl.fmt.RRF.r1,
12622 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
12623 case 0xb31f: s390_format_RRF_F0FF(s390_irgen_MSDBR, ovl.fmt.RRF.r1,
12624 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
12625 case 0xb324: /* LDER */ goto unimplemented;
12626 case 0xb325: /* LXDR */ goto unimplemented;
12627 case 0xb326: /* LXER */ goto unimplemented;
12628 case 0xb32e: /* MAER */ goto unimplemented;
12629 case 0xb32f: /* MSER */ goto unimplemented;
12630 case 0xb336: /* SQXR */ goto unimplemented;
12631 case 0xb337: /* MEER */ goto unimplemented;
12632 case 0xb338: /* MAYLR */ goto unimplemented;
12633 case 0xb339: /* MYLR */ goto unimplemented;
12634 case 0xb33a: /* MAYR */ goto unimplemented;
12635 case 0xb33b: /* MYR */ goto unimplemented;
12636 case 0xb33c: /* MAYHR */ goto unimplemented;
12637 case 0xb33d: /* MYHR */ goto unimplemented;
12638 case 0xb33e: /* MADR */ goto unimplemented;
12639 case 0xb33f: /* MSDR */ goto unimplemented;
12640 case 0xb340: s390_format_RRE_FF(s390_irgen_LPXBR, ovl.fmt.RRE.r1,
12641 ovl.fmt.RRE.r2); goto ok;
12642 case 0xb341: s390_format_RRE_FF(s390_irgen_LNXBR, ovl.fmt.RRE.r1,
12643 ovl.fmt.RRE.r2); goto ok;
12644 case 0xb342: s390_format_RRE_FF(s390_irgen_LTXBR, ovl.fmt.RRE.r1,
12645 ovl.fmt.RRE.r2); goto ok;
12646 case 0xb343: s390_format_RRE_FF(s390_irgen_LCXBR, ovl.fmt.RRE.r1,
12647 ovl.fmt.RRE.r2); goto ok;
florian4b8efad2012-09-02 18:07:08 +000012648 case 0xb344: s390_format_RRF_UUFF(s390_irgen_LEDBR, ovl.fmt.RRF2.m3,
12649 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12650 ovl.fmt.RRF2.r2); goto ok;
12651 case 0xb345: s390_format_RRF_UUFF(s390_irgen_LDXBR, ovl.fmt.RRF2.m3,
12652 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12653 ovl.fmt.RRF2.r2); goto ok;
12654 case 0xb346: s390_format_RRF_UUFF(s390_irgen_LEXBR, ovl.fmt.RRF2.m3,
12655 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12656 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000012657 case 0xb347: /* FIXBR */ goto unimplemented;
12658 case 0xb348: /* KXBR */ goto unimplemented;
12659 case 0xb349: s390_format_RRE_FF(s390_irgen_CXBR, ovl.fmt.RRE.r1,
12660 ovl.fmt.RRE.r2); goto ok;
12661 case 0xb34a: s390_format_RRE_FF(s390_irgen_AXBR, ovl.fmt.RRE.r1,
12662 ovl.fmt.RRE.r2); goto ok;
12663 case 0xb34b: s390_format_RRE_FF(s390_irgen_SXBR, ovl.fmt.RRE.r1,
12664 ovl.fmt.RRE.r2); goto ok;
12665 case 0xb34c: s390_format_RRE_FF(s390_irgen_MXBR, ovl.fmt.RRE.r1,
12666 ovl.fmt.RRE.r2); goto ok;
12667 case 0xb34d: s390_format_RRE_FF(s390_irgen_DXBR, ovl.fmt.RRE.r1,
12668 ovl.fmt.RRE.r2); goto ok;
12669 case 0xb350: /* TBEDR */ goto unimplemented;
12670 case 0xb351: /* TBDR */ goto unimplemented;
12671 case 0xb353: /* DIEBR */ goto unimplemented;
12672 case 0xb357: /* FIEBR */ goto unimplemented;
12673 case 0xb358: /* THDER */ goto unimplemented;
12674 case 0xb359: /* THDR */ goto unimplemented;
12675 case 0xb35b: /* DIDBR */ goto unimplemented;
12676 case 0xb35f: /* FIDBR */ goto unimplemented;
12677 case 0xb360: /* LPXR */ goto unimplemented;
12678 case 0xb361: /* LNXR */ goto unimplemented;
12679 case 0xb362: /* LTXR */ goto unimplemented;
12680 case 0xb363: /* LCXR */ goto unimplemented;
12681 case 0xb365: s390_format_RRE_FF(s390_irgen_LXR, ovl.fmt.RRE.r1,
12682 ovl.fmt.RRE.r2); goto ok;
12683 case 0xb366: /* LEXR */ goto unimplemented;
12684 case 0xb367: /* FIXR */ goto unimplemented;
12685 case 0xb369: /* CXR */ goto unimplemented;
12686 case 0xb370: s390_format_RRE_FF(s390_irgen_LPDFR, ovl.fmt.RRE.r1,
12687 ovl.fmt.RRE.r2); goto ok;
12688 case 0xb371: s390_format_RRE_FF(s390_irgen_LNDFR, ovl.fmt.RRE.r1,
12689 ovl.fmt.RRE.r2); goto ok;
12690 case 0xb372: s390_format_RRF_F0FF2(s390_irgen_CPSDR, ovl.fmt.RRF3.r3,
12691 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
12692 goto ok;
12693 case 0xb373: s390_format_RRE_FF(s390_irgen_LCDFR, ovl.fmt.RRE.r1,
12694 ovl.fmt.RRE.r2); goto ok;
12695 case 0xb374: s390_format_RRE_F0(s390_irgen_LZER, ovl.fmt.RRE.r1); goto ok;
12696 case 0xb375: s390_format_RRE_F0(s390_irgen_LZDR, ovl.fmt.RRE.r1); goto ok;
12697 case 0xb376: s390_format_RRE_F0(s390_irgen_LZXR, ovl.fmt.RRE.r1); goto ok;
12698 case 0xb377: /* FIER */ goto unimplemented;
12699 case 0xb37f: /* FIDR */ goto unimplemented;
12700 case 0xb384: s390_format_RRE_R0(s390_irgen_SFPC, ovl.fmt.RRE.r1); goto ok;
12701 case 0xb385: /* SFASR */ goto unimplemented;
12702 case 0xb38c: s390_format_RRE_R0(s390_irgen_EFPC, ovl.fmt.RRE.r1); goto ok;
florian1c8f7ff2012-09-01 00:12:11 +000012703 case 0xb390: s390_format_RRF_UUFR(s390_irgen_CELFBR, ovl.fmt.RRF2.m3,
12704 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12705 ovl.fmt.RRF2.r2); goto ok;
12706 case 0xb391: s390_format_RRF_UUFR(s390_irgen_CDLFBR, ovl.fmt.RRF2.m3,
12707 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12708 ovl.fmt.RRF2.r2); goto ok;
12709 case 0xb392: s390_format_RRF_UUFR(s390_irgen_CXLFBR, ovl.fmt.RRF2.m3,
12710 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12711 ovl.fmt.RRF2.r2); goto ok;
florian4b8efad2012-09-02 18:07:08 +000012712 case 0xb394: s390_format_RRF_UUFR(s390_irgen_CEFBR, ovl.fmt.RRF2.m3,
12713 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12714 ovl.fmt.RRF2.r2); goto ok;
12715 case 0xb395: s390_format_RRF_UUFR(s390_irgen_CDFBR, ovl.fmt.RRF2.m3,
12716 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12717 ovl.fmt.RRF2.r2); goto ok;
12718 case 0xb396: s390_format_RRF_UUFR(s390_irgen_CXFBR, ovl.fmt.RRF2.m3,
12719 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12720 ovl.fmt.RRF2.r2); goto ok;
12721 case 0xb398: s390_format_RRF_UURF(s390_irgen_CFEBR, ovl.fmt.RRF2.m3,
12722 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12723 ovl.fmt.RRF2.r2); goto ok;
12724 case 0xb399: s390_format_RRF_UURF(s390_irgen_CFDBR, ovl.fmt.RRF2.m3,
12725 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12726 ovl.fmt.RRF2.r2); goto ok;
12727 case 0xb39a: s390_format_RRF_UURF(s390_irgen_CFXBR, ovl.fmt.RRF2.m3,
12728 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12729 ovl.fmt.RRF2.r2); goto ok;
florian1c8f7ff2012-09-01 00:12:11 +000012730 case 0xb39c: s390_format_RRF_UURF(s390_irgen_CLFEBR, ovl.fmt.RRF2.m3,
12731 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12732 ovl.fmt.RRF2.r2); goto ok;
12733 case 0xb39d: s390_format_RRF_UURF(s390_irgen_CLFDBR, ovl.fmt.RRF2.m3,
12734 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12735 ovl.fmt.RRF2.r2); goto ok;
12736 case 0xb39e: s390_format_RRF_UURF(s390_irgen_CLFXBR, ovl.fmt.RRF2.m3,
12737 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12738 ovl.fmt.RRF2.r2); goto ok;
12739 case 0xb3a0: s390_format_RRF_UUFR(s390_irgen_CELGBR, ovl.fmt.RRF2.m3,
12740 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12741 ovl.fmt.RRF2.r2); goto ok;
12742 case 0xb3a1: s390_format_RRF_UUFR(s390_irgen_CDLGBR, ovl.fmt.RRF2.m3,
12743 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12744 ovl.fmt.RRF2.r2); goto ok;
12745 case 0xb3a2: s390_format_RRF_UUFR(s390_irgen_CXLGBR, ovl.fmt.RRF2.m3,
12746 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12747 ovl.fmt.RRF2.r2); goto ok;
florian4b8efad2012-09-02 18:07:08 +000012748 case 0xb3a4: s390_format_RRF_UUFR(s390_irgen_CEGBR, ovl.fmt.RRF2.m3,
12749 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12750 ovl.fmt.RRF2.r2); goto ok;
12751 case 0xb3a5: s390_format_RRF_UUFR(s390_irgen_CDGBR, ovl.fmt.RRF2.m3,
12752 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12753 ovl.fmt.RRF2.r2); goto ok;
12754 case 0xb3a6: s390_format_RRF_UUFR(s390_irgen_CXGBR, ovl.fmt.RRF2.m3,
12755 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12756 ovl.fmt.RRF2.r2); goto ok;
12757 case 0xb3a8: s390_format_RRF_UURF(s390_irgen_CGEBR, ovl.fmt.RRF2.m3,
12758 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12759 ovl.fmt.RRF2.r2); goto ok;
12760 case 0xb3a9: s390_format_RRF_UURF(s390_irgen_CGDBR, ovl.fmt.RRF2.m3,
12761 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12762 ovl.fmt.RRF2.r2); goto ok;
12763 case 0xb3aa: s390_format_RRF_UURF(s390_irgen_CGXBR, ovl.fmt.RRF2.m3,
12764 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12765 ovl.fmt.RRF2.r2); goto ok;
florian1c8f7ff2012-09-01 00:12:11 +000012766 case 0xb3ac: s390_format_RRF_UURF(s390_irgen_CLGEBR, ovl.fmt.RRF2.m3,
12767 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12768 ovl.fmt.RRF2.r2); goto ok;
12769 case 0xb3ad: s390_format_RRF_UURF(s390_irgen_CLGDBR, ovl.fmt.RRF2.m3,
12770 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12771 ovl.fmt.RRF2.r2); goto ok;
12772 case 0xb3ae: s390_format_RRF_UURF(s390_irgen_CLGXBR, ovl.fmt.RRF2.m3,
12773 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12774 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000012775 case 0xb3b4: /* CEFR */ goto unimplemented;
12776 case 0xb3b5: /* CDFR */ goto unimplemented;
12777 case 0xb3b6: /* CXFR */ goto unimplemented;
12778 case 0xb3b8: /* CFER */ goto unimplemented;
12779 case 0xb3b9: /* CFDR */ goto unimplemented;
12780 case 0xb3ba: /* CFXR */ goto unimplemented;
12781 case 0xb3c1: s390_format_RRE_FR(s390_irgen_LDGR, ovl.fmt.RRE.r1,
12782 ovl.fmt.RRE.r2); goto ok;
12783 case 0xb3c4: /* CEGR */ goto unimplemented;
12784 case 0xb3c5: /* CDGR */ goto unimplemented;
12785 case 0xb3c6: /* CXGR */ goto unimplemented;
12786 case 0xb3c8: /* CGER */ goto unimplemented;
12787 case 0xb3c9: /* CGDR */ goto unimplemented;
12788 case 0xb3ca: /* CGXR */ goto unimplemented;
12789 case 0xb3cd: s390_format_RRE_RF(s390_irgen_LGDR, ovl.fmt.RRE.r1,
12790 ovl.fmt.RRE.r2); goto ok;
12791 case 0xb3d0: /* MDTR */ goto unimplemented;
12792 case 0xb3d1: /* DDTR */ goto unimplemented;
12793 case 0xb3d2: /* ADTR */ goto unimplemented;
12794 case 0xb3d3: /* SDTR */ goto unimplemented;
12795 case 0xb3d4: /* LDETR */ goto unimplemented;
12796 case 0xb3d5: /* LEDTR */ goto unimplemented;
12797 case 0xb3d6: /* LTDTR */ goto unimplemented;
12798 case 0xb3d7: /* FIDTR */ goto unimplemented;
12799 case 0xb3d8: /* MXTR */ goto unimplemented;
12800 case 0xb3d9: /* DXTR */ goto unimplemented;
12801 case 0xb3da: /* AXTR */ goto unimplemented;
12802 case 0xb3db: /* SXTR */ goto unimplemented;
12803 case 0xb3dc: /* LXDTR */ goto unimplemented;
12804 case 0xb3dd: /* LDXTR */ goto unimplemented;
12805 case 0xb3de: /* LTXTR */ goto unimplemented;
12806 case 0xb3df: /* FIXTR */ goto unimplemented;
12807 case 0xb3e0: /* KDTR */ goto unimplemented;
12808 case 0xb3e1: /* CGDTR */ goto unimplemented;
12809 case 0xb3e2: /* CUDTR */ goto unimplemented;
12810 case 0xb3e3: /* CSDTR */ goto unimplemented;
12811 case 0xb3e4: /* CDTR */ goto unimplemented;
12812 case 0xb3e5: /* EEDTR */ goto unimplemented;
12813 case 0xb3e7: /* ESDTR */ goto unimplemented;
12814 case 0xb3e8: /* KXTR */ goto unimplemented;
12815 case 0xb3e9: /* CGXTR */ goto unimplemented;
12816 case 0xb3ea: /* CUXTR */ goto unimplemented;
12817 case 0xb3eb: /* CSXTR */ goto unimplemented;
12818 case 0xb3ec: /* CXTR */ goto unimplemented;
12819 case 0xb3ed: /* EEXTR */ goto unimplemented;
12820 case 0xb3ef: /* ESXTR */ goto unimplemented;
12821 case 0xb3f1: /* CDGTR */ goto unimplemented;
12822 case 0xb3f2: /* CDUTR */ goto unimplemented;
12823 case 0xb3f3: /* CDSTR */ goto unimplemented;
12824 case 0xb3f4: /* CEDTR */ goto unimplemented;
12825 case 0xb3f5: /* QADTR */ goto unimplemented;
12826 case 0xb3f6: /* IEDTR */ goto unimplemented;
12827 case 0xb3f7: /* RRDTR */ goto unimplemented;
12828 case 0xb3f9: /* CXGTR */ goto unimplemented;
12829 case 0xb3fa: /* CXUTR */ goto unimplemented;
12830 case 0xb3fb: /* CXSTR */ goto unimplemented;
12831 case 0xb3fc: /* CEXTR */ goto unimplemented;
12832 case 0xb3fd: /* QAXTR */ goto unimplemented;
12833 case 0xb3fe: /* IEXTR */ goto unimplemented;
12834 case 0xb3ff: /* RRXTR */ goto unimplemented;
12835 case 0xb900: s390_format_RRE_RR(s390_irgen_LPGR, ovl.fmt.RRE.r1,
12836 ovl.fmt.RRE.r2); goto ok;
12837 case 0xb901: s390_format_RRE_RR(s390_irgen_LNGR, ovl.fmt.RRE.r1,
12838 ovl.fmt.RRE.r2); goto ok;
12839 case 0xb902: s390_format_RRE_RR(s390_irgen_LTGR, ovl.fmt.RRE.r1,
12840 ovl.fmt.RRE.r2); goto ok;
12841 case 0xb903: s390_format_RRE_RR(s390_irgen_LCGR, ovl.fmt.RRE.r1,
12842 ovl.fmt.RRE.r2); goto ok;
12843 case 0xb904: s390_format_RRE_RR(s390_irgen_LGR, ovl.fmt.RRE.r1,
12844 ovl.fmt.RRE.r2); goto ok;
12845 case 0xb905: /* LURAG */ goto unimplemented;
12846 case 0xb906: s390_format_RRE_RR(s390_irgen_LGBR, ovl.fmt.RRE.r1,
12847 ovl.fmt.RRE.r2); goto ok;
12848 case 0xb907: s390_format_RRE_RR(s390_irgen_LGHR, ovl.fmt.RRE.r1,
12849 ovl.fmt.RRE.r2); goto ok;
12850 case 0xb908: s390_format_RRE_RR(s390_irgen_AGR, ovl.fmt.RRE.r1,
12851 ovl.fmt.RRE.r2); goto ok;
12852 case 0xb909: s390_format_RRE_RR(s390_irgen_SGR, ovl.fmt.RRE.r1,
12853 ovl.fmt.RRE.r2); goto ok;
12854 case 0xb90a: s390_format_RRE_RR(s390_irgen_ALGR, ovl.fmt.RRE.r1,
12855 ovl.fmt.RRE.r2); goto ok;
12856 case 0xb90b: s390_format_RRE_RR(s390_irgen_SLGR, ovl.fmt.RRE.r1,
12857 ovl.fmt.RRE.r2); goto ok;
12858 case 0xb90c: s390_format_RRE_RR(s390_irgen_MSGR, ovl.fmt.RRE.r1,
12859 ovl.fmt.RRE.r2); goto ok;
12860 case 0xb90d: s390_format_RRE_RR(s390_irgen_DSGR, ovl.fmt.RRE.r1,
12861 ovl.fmt.RRE.r2); goto ok;
12862 case 0xb90e: /* EREGG */ goto unimplemented;
12863 case 0xb90f: s390_format_RRE_RR(s390_irgen_LRVGR, ovl.fmt.RRE.r1,
12864 ovl.fmt.RRE.r2); goto ok;
12865 case 0xb910: s390_format_RRE_RR(s390_irgen_LPGFR, ovl.fmt.RRE.r1,
12866 ovl.fmt.RRE.r2); goto ok;
12867 case 0xb911: s390_format_RRE_RR(s390_irgen_LNGFR, ovl.fmt.RRE.r1,
12868 ovl.fmt.RRE.r2); goto ok;
12869 case 0xb912: s390_format_RRE_RR(s390_irgen_LTGFR, ovl.fmt.RRE.r1,
12870 ovl.fmt.RRE.r2); goto ok;
12871 case 0xb913: s390_format_RRE_RR(s390_irgen_LCGFR, ovl.fmt.RRE.r1,
12872 ovl.fmt.RRE.r2); goto ok;
12873 case 0xb914: s390_format_RRE_RR(s390_irgen_LGFR, ovl.fmt.RRE.r1,
12874 ovl.fmt.RRE.r2); goto ok;
12875 case 0xb916: s390_format_RRE_RR(s390_irgen_LLGFR, ovl.fmt.RRE.r1,
12876 ovl.fmt.RRE.r2); goto ok;
12877 case 0xb917: s390_format_RRE_RR(s390_irgen_LLGTR, ovl.fmt.RRE.r1,
12878 ovl.fmt.RRE.r2); goto ok;
12879 case 0xb918: s390_format_RRE_RR(s390_irgen_AGFR, ovl.fmt.RRE.r1,
12880 ovl.fmt.RRE.r2); goto ok;
12881 case 0xb919: s390_format_RRE_RR(s390_irgen_SGFR, ovl.fmt.RRE.r1,
12882 ovl.fmt.RRE.r2); goto ok;
12883 case 0xb91a: s390_format_RRE_RR(s390_irgen_ALGFR, ovl.fmt.RRE.r1,
12884 ovl.fmt.RRE.r2); goto ok;
12885 case 0xb91b: s390_format_RRE_RR(s390_irgen_SLGFR, ovl.fmt.RRE.r1,
12886 ovl.fmt.RRE.r2); goto ok;
12887 case 0xb91c: s390_format_RRE_RR(s390_irgen_MSGFR, ovl.fmt.RRE.r1,
12888 ovl.fmt.RRE.r2); goto ok;
12889 case 0xb91d: s390_format_RRE_RR(s390_irgen_DSGFR, ovl.fmt.RRE.r1,
12890 ovl.fmt.RRE.r2); goto ok;
12891 case 0xb91e: /* KMAC */ goto unimplemented;
12892 case 0xb91f: s390_format_RRE_RR(s390_irgen_LRVR, ovl.fmt.RRE.r1,
12893 ovl.fmt.RRE.r2); goto ok;
12894 case 0xb920: s390_format_RRE_RR(s390_irgen_CGR, ovl.fmt.RRE.r1,
12895 ovl.fmt.RRE.r2); goto ok;
12896 case 0xb921: s390_format_RRE_RR(s390_irgen_CLGR, ovl.fmt.RRE.r1,
12897 ovl.fmt.RRE.r2); goto ok;
12898 case 0xb925: /* STURG */ goto unimplemented;
12899 case 0xb926: s390_format_RRE_RR(s390_irgen_LBR, ovl.fmt.RRE.r1,
12900 ovl.fmt.RRE.r2); goto ok;
12901 case 0xb927: s390_format_RRE_RR(s390_irgen_LHR, ovl.fmt.RRE.r1,
12902 ovl.fmt.RRE.r2); goto ok;
12903 case 0xb928: /* PCKMO */ goto unimplemented;
12904 case 0xb92b: /* KMO */ goto unimplemented;
12905 case 0xb92c: /* PCC */ goto unimplemented;
12906 case 0xb92d: /* KMCTR */ goto unimplemented;
12907 case 0xb92e: /* KM */ goto unimplemented;
12908 case 0xb92f: /* KMC */ goto unimplemented;
12909 case 0xb930: s390_format_RRE_RR(s390_irgen_CGFR, ovl.fmt.RRE.r1,
12910 ovl.fmt.RRE.r2); goto ok;
12911 case 0xb931: s390_format_RRE_RR(s390_irgen_CLGFR, ovl.fmt.RRE.r1,
12912 ovl.fmt.RRE.r2); goto ok;
12913 case 0xb93e: /* KIMD */ goto unimplemented;
12914 case 0xb93f: /* KLMD */ goto unimplemented;
12915 case 0xb941: /* CFDTR */ goto unimplemented;
12916 case 0xb942: /* CLGDTR */ goto unimplemented;
12917 case 0xb943: /* CLFDTR */ goto unimplemented;
12918 case 0xb946: s390_format_RRE_RR(s390_irgen_BCTGR, ovl.fmt.RRE.r1,
12919 ovl.fmt.RRE.r2); goto ok;
12920 case 0xb949: /* CFXTR */ goto unimplemented;
12921 case 0xb94a: /* CLGXTR */ goto unimplemented;
12922 case 0xb94b: /* CLFXTR */ goto unimplemented;
12923 case 0xb951: /* CDFTR */ goto unimplemented;
12924 case 0xb952: /* CDLGTR */ goto unimplemented;
12925 case 0xb953: /* CDLFTR */ goto unimplemented;
12926 case 0xb959: /* CXFTR */ goto unimplemented;
12927 case 0xb95a: /* CXLGTR */ goto unimplemented;
12928 case 0xb95b: /* CXLFTR */ goto unimplemented;
12929 case 0xb960: /* CGRT */ goto unimplemented;
12930 case 0xb961: /* CLGRT */ goto unimplemented;
12931 case 0xb972: /* CRT */ goto unimplemented;
12932 case 0xb973: /* CLRT */ goto unimplemented;
12933 case 0xb980: s390_format_RRE_RR(s390_irgen_NGR, ovl.fmt.RRE.r1,
12934 ovl.fmt.RRE.r2); goto ok;
12935 case 0xb981: s390_format_RRE_RR(s390_irgen_OGR, ovl.fmt.RRE.r1,
12936 ovl.fmt.RRE.r2); goto ok;
12937 case 0xb982: s390_format_RRE_RR(s390_irgen_XGR, ovl.fmt.RRE.r1,
12938 ovl.fmt.RRE.r2); goto ok;
12939 case 0xb983: s390_format_RRE_RR(s390_irgen_FLOGR, ovl.fmt.RRE.r1,
12940 ovl.fmt.RRE.r2); goto ok;
12941 case 0xb984: s390_format_RRE_RR(s390_irgen_LLGCR, ovl.fmt.RRE.r1,
12942 ovl.fmt.RRE.r2); goto ok;
12943 case 0xb985: s390_format_RRE_RR(s390_irgen_LLGHR, ovl.fmt.RRE.r1,
12944 ovl.fmt.RRE.r2); goto ok;
12945 case 0xb986: s390_format_RRE_RR(s390_irgen_MLGR, ovl.fmt.RRE.r1,
12946 ovl.fmt.RRE.r2); goto ok;
12947 case 0xb987: s390_format_RRE_RR(s390_irgen_DLGR, ovl.fmt.RRE.r1,
12948 ovl.fmt.RRE.r2); goto ok;
12949 case 0xb988: s390_format_RRE_RR(s390_irgen_ALCGR, ovl.fmt.RRE.r1,
12950 ovl.fmt.RRE.r2); goto ok;
12951 case 0xb989: s390_format_RRE_RR(s390_irgen_SLBGR, ovl.fmt.RRE.r1,
12952 ovl.fmt.RRE.r2); goto ok;
12953 case 0xb98a: /* CSPG */ goto unimplemented;
12954 case 0xb98d: /* EPSW */ goto unimplemented;
12955 case 0xb98e: /* IDTE */ goto unimplemented;
florian730448f2012-02-04 17:07:07 +000012956 case 0xb990: s390_format_RRF_M0RERE(s390_irgen_TRTT, ovl.fmt.RRF3.r3,
12957 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
12958 case 0xb991: s390_format_RRF_M0RERE(s390_irgen_TRTO, ovl.fmt.RRF3.r3,
12959 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
12960 case 0xb992: s390_format_RRF_M0RERE(s390_irgen_TROT, ovl.fmt.RRF3.r3,
12961 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
florian9af37692012-01-15 21:01:16 +000012962 case 0xb993: s390_format_RRF_M0RERE(s390_irgen_TROO, ovl.fmt.RRF3.r3,
12963 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000012964 case 0xb994: s390_format_RRE_RR(s390_irgen_LLCR, ovl.fmt.RRE.r1,
12965 ovl.fmt.RRE.r2); goto ok;
12966 case 0xb995: s390_format_RRE_RR(s390_irgen_LLHR, ovl.fmt.RRE.r1,
12967 ovl.fmt.RRE.r2); goto ok;
12968 case 0xb996: s390_format_RRE_RR(s390_irgen_MLR, ovl.fmt.RRE.r1,
12969 ovl.fmt.RRE.r2); goto ok;
12970 case 0xb997: s390_format_RRE_RR(s390_irgen_DLR, ovl.fmt.RRE.r1,
12971 ovl.fmt.RRE.r2); goto ok;
12972 case 0xb998: s390_format_RRE_RR(s390_irgen_ALCR, ovl.fmt.RRE.r1,
12973 ovl.fmt.RRE.r2); goto ok;
12974 case 0xb999: s390_format_RRE_RR(s390_irgen_SLBR, ovl.fmt.RRE.r1,
12975 ovl.fmt.RRE.r2); goto ok;
12976 case 0xb99a: /* EPAIR */ goto unimplemented;
12977 case 0xb99b: /* ESAIR */ goto unimplemented;
12978 case 0xb99d: /* ESEA */ goto unimplemented;
12979 case 0xb99e: /* PTI */ goto unimplemented;
12980 case 0xb99f: /* SSAIR */ goto unimplemented;
12981 case 0xb9a2: /* PTF */ goto unimplemented;
12982 case 0xb9aa: /* LPTEA */ goto unimplemented;
12983 case 0xb9ae: /* RRBM */ goto unimplemented;
12984 case 0xb9af: /* PFMF */ goto unimplemented;
florian3f8a96a2012-08-05 02:59:55 +000012985 case 0xb9b0: s390_format_RRF_M0RERE(s390_irgen_CU14, ovl.fmt.RRF3.r3,
12986 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
12987 goto ok;
florian2a415a12012-07-21 17:41:36 +000012988 case 0xb9b1: s390_format_RRF_M0RERE(s390_irgen_CU24, ovl.fmt.RRF3.r3,
12989 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
12990 goto ok;
florianaf2194f2012-08-06 00:07:54 +000012991 case 0xb9b2: s390_format_RRE_RR(s390_irgen_CU41, ovl.fmt.RRE.r1,
12992 ovl.fmt.RRE.r2); goto ok;
florian956194b2012-07-28 22:18:32 +000012993 case 0xb9b3: s390_format_RRE_RR(s390_irgen_CU42, ovl.fmt.RRE.r1,
12994 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000012995 case 0xb9bd: /* TRTRE */ goto unimplemented;
12996 case 0xb9be: /* SRSTU */ goto unimplemented;
12997 case 0xb9bf: /* TRTE */ goto unimplemented;
12998 case 0xb9c8: s390_format_RRF_R0RR2(s390_irgen_AHHHR, ovl.fmt.RRF4.r3,
12999 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13000 goto ok;
13001 case 0xb9c9: s390_format_RRF_R0RR2(s390_irgen_SHHHR, ovl.fmt.RRF4.r3,
13002 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13003 goto ok;
13004 case 0xb9ca: s390_format_RRF_R0RR2(s390_irgen_ALHHHR, ovl.fmt.RRF4.r3,
13005 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13006 goto ok;
13007 case 0xb9cb: s390_format_RRF_R0RR2(s390_irgen_SLHHHR, ovl.fmt.RRF4.r3,
13008 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13009 goto ok;
13010 case 0xb9cd: s390_format_RRE_RR(s390_irgen_CHHR, ovl.fmt.RRE.r1,
13011 ovl.fmt.RRE.r2); goto ok;
13012 case 0xb9cf: s390_format_RRE_RR(s390_irgen_CLHHR, ovl.fmt.RRE.r1,
13013 ovl.fmt.RRE.r2); goto ok;
13014 case 0xb9d8: s390_format_RRF_R0RR2(s390_irgen_AHHLR, ovl.fmt.RRF4.r3,
13015 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13016 goto ok;
13017 case 0xb9d9: s390_format_RRF_R0RR2(s390_irgen_SHHLR, ovl.fmt.RRF4.r3,
13018 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13019 goto ok;
13020 case 0xb9da: s390_format_RRF_R0RR2(s390_irgen_ALHHLR, ovl.fmt.RRF4.r3,
13021 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13022 goto ok;
13023 case 0xb9db: s390_format_RRF_R0RR2(s390_irgen_SLHHLR, ovl.fmt.RRF4.r3,
13024 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13025 goto ok;
13026 case 0xb9dd: s390_format_RRE_RR(s390_irgen_CHLR, ovl.fmt.RRE.r1,
13027 ovl.fmt.RRE.r2); goto ok;
13028 case 0xb9df: s390_format_RRE_RR(s390_irgen_CLHLR, ovl.fmt.RRE.r1,
13029 ovl.fmt.RRE.r2); goto ok;
13030 case 0xb9e1: /* POPCNT */ goto unimplemented;
sewardjd7bde722011-04-05 13:19:33 +000013031 case 0xb9e2: s390_format_RRF_U0RR(s390_irgen_LOCGR, ovl.fmt.RRF3.r3,
13032 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2,
13033 S390_XMNM_LOCGR); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013034 case 0xb9e4: s390_format_RRF_R0RR2(s390_irgen_NGRK, ovl.fmt.RRF4.r3,
13035 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13036 goto ok;
13037 case 0xb9e6: s390_format_RRF_R0RR2(s390_irgen_OGRK, ovl.fmt.RRF4.r3,
13038 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13039 goto ok;
13040 case 0xb9e7: s390_format_RRF_R0RR2(s390_irgen_XGRK, ovl.fmt.RRF4.r3,
13041 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13042 goto ok;
13043 case 0xb9e8: s390_format_RRF_R0RR2(s390_irgen_AGRK, ovl.fmt.RRF4.r3,
13044 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13045 goto ok;
13046 case 0xb9e9: s390_format_RRF_R0RR2(s390_irgen_SGRK, ovl.fmt.RRF4.r3,
13047 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13048 goto ok;
13049 case 0xb9ea: s390_format_RRF_R0RR2(s390_irgen_ALGRK, ovl.fmt.RRF4.r3,
13050 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13051 goto ok;
13052 case 0xb9eb: s390_format_RRF_R0RR2(s390_irgen_SLGRK, ovl.fmt.RRF4.r3,
13053 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13054 goto ok;
sewardjd7bde722011-04-05 13:19:33 +000013055 case 0xb9f2: s390_format_RRF_U0RR(s390_irgen_LOCR, ovl.fmt.RRF3.r3,
13056 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2,
13057 S390_XMNM_LOCR); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013058 case 0xb9f4: s390_format_RRF_R0RR2(s390_irgen_NRK, ovl.fmt.RRF4.r3,
13059 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13060 goto ok;
13061 case 0xb9f6: s390_format_RRF_R0RR2(s390_irgen_ORK, ovl.fmt.RRF4.r3,
13062 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13063 goto ok;
13064 case 0xb9f7: s390_format_RRF_R0RR2(s390_irgen_XRK, ovl.fmt.RRF4.r3,
13065 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13066 goto ok;
13067 case 0xb9f8: s390_format_RRF_R0RR2(s390_irgen_ARK, ovl.fmt.RRF4.r3,
13068 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13069 goto ok;
13070 case 0xb9f9: s390_format_RRF_R0RR2(s390_irgen_SRK, ovl.fmt.RRF4.r3,
13071 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13072 goto ok;
13073 case 0xb9fa: s390_format_RRF_R0RR2(s390_irgen_ALRK, ovl.fmt.RRF4.r3,
13074 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13075 goto ok;
13076 case 0xb9fb: s390_format_RRF_R0RR2(s390_irgen_SLRK, ovl.fmt.RRF4.r3,
13077 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13078 goto ok;
13079 }
13080
13081 switch ((ovl.value & 0xff000000) >> 24) {
13082 case 0x40: s390_format_RX_RRRD(s390_irgen_STH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13083 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13084 case 0x41: s390_format_RX_RRRD(s390_irgen_LA, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13085 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13086 case 0x42: s390_format_RX_RRRD(s390_irgen_STC, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13087 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13088 case 0x43: s390_format_RX_RRRD(s390_irgen_IC, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13089 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13090 case 0x44: s390_format_RX_RRRD(s390_irgen_EX, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13091 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13092 case 0x45: /* BAL */ goto unimplemented;
13093 case 0x46: s390_format_RX_RRRD(s390_irgen_BCT, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13094 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13095 case 0x47: s390_format_RX(s390_irgen_BC, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13096 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13097 case 0x48: s390_format_RX_RRRD(s390_irgen_LH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13098 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13099 case 0x49: s390_format_RX_RRRD(s390_irgen_CH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13100 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13101 case 0x4a: s390_format_RX_RRRD(s390_irgen_AH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13102 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13103 case 0x4b: s390_format_RX_RRRD(s390_irgen_SH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13104 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13105 case 0x4c: s390_format_RX_RRRD(s390_irgen_MH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13106 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13107 case 0x4d: s390_format_RX_RRRD(s390_irgen_BAS, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13108 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13109 case 0x4e: s390_format_RX_RRRD(s390_irgen_CVD, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13110 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13111 case 0x4f: s390_format_RX_RRRD(s390_irgen_CVB, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13112 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13113 case 0x50: s390_format_RX_RRRD(s390_irgen_ST, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13114 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13115 case 0x51: s390_format_RX_RRRD(s390_irgen_LAE, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13116 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13117 case 0x54: s390_format_RX_RRRD(s390_irgen_N, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13118 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13119 case 0x55: s390_format_RX_RRRD(s390_irgen_CL, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13120 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13121 case 0x56: s390_format_RX_RRRD(s390_irgen_O, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13122 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13123 case 0x57: s390_format_RX_RRRD(s390_irgen_X, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13124 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13125 case 0x58: s390_format_RX_RRRD(s390_irgen_L, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13126 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13127 case 0x59: s390_format_RX_RRRD(s390_irgen_C, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13128 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13129 case 0x5a: s390_format_RX_RRRD(s390_irgen_A, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13130 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13131 case 0x5b: s390_format_RX_RRRD(s390_irgen_S, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13132 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13133 case 0x5c: s390_format_RX_RRRD(s390_irgen_M, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13134 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13135 case 0x5d: s390_format_RX_RRRD(s390_irgen_D, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13136 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13137 case 0x5e: s390_format_RX_RRRD(s390_irgen_AL, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13138 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13139 case 0x5f: s390_format_RX_RRRD(s390_irgen_SL, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13140 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13141 case 0x60: s390_format_RX_FRRD(s390_irgen_STD, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13142 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13143 case 0x67: /* MXD */ goto unimplemented;
13144 case 0x68: s390_format_RX_FRRD(s390_irgen_LD, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13145 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13146 case 0x69: /* CD */ goto unimplemented;
13147 case 0x6a: /* AD */ goto unimplemented;
13148 case 0x6b: /* SD */ goto unimplemented;
13149 case 0x6c: /* MD */ goto unimplemented;
13150 case 0x6d: /* DD */ goto unimplemented;
13151 case 0x6e: /* AW */ goto unimplemented;
13152 case 0x6f: /* SW */ goto unimplemented;
13153 case 0x70: s390_format_RX_FRRD(s390_irgen_STE, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13154 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13155 case 0x71: s390_format_RX_RRRD(s390_irgen_MS, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13156 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13157 case 0x78: s390_format_RX_FRRD(s390_irgen_LE, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13158 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13159 case 0x79: /* CE */ goto unimplemented;
13160 case 0x7a: /* AE */ goto unimplemented;
13161 case 0x7b: /* SE */ goto unimplemented;
13162 case 0x7c: /* MDE */ goto unimplemented;
13163 case 0x7d: /* DE */ goto unimplemented;
13164 case 0x7e: /* AU */ goto unimplemented;
13165 case 0x7f: /* SU */ goto unimplemented;
13166 case 0x83: /* DIAG */ goto unimplemented;
13167 case 0x84: s390_format_RSI_RRP(s390_irgen_BRXH, ovl.fmt.RSI.r1,
13168 ovl.fmt.RSI.r3, ovl.fmt.RSI.i2); goto ok;
13169 case 0x85: s390_format_RSI_RRP(s390_irgen_BRXLE, ovl.fmt.RSI.r1,
13170 ovl.fmt.RSI.r3, ovl.fmt.RSI.i2); goto ok;
13171 case 0x86: s390_format_RS_RRRD(s390_irgen_BXH, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13172 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13173 case 0x87: s390_format_RS_RRRD(s390_irgen_BXLE, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13174 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13175 case 0x88: s390_format_RS_R0RD(s390_irgen_SRL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
13176 ovl.fmt.RS.d2); goto ok;
13177 case 0x89: s390_format_RS_R0RD(s390_irgen_SLL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
13178 ovl.fmt.RS.d2); goto ok;
13179 case 0x8a: s390_format_RS_R0RD(s390_irgen_SRA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
13180 ovl.fmt.RS.d2); goto ok;
13181 case 0x8b: s390_format_RS_R0RD(s390_irgen_SLA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
13182 ovl.fmt.RS.d2); goto ok;
13183 case 0x8c: s390_format_RS_R0RD(s390_irgen_SRDL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
13184 ovl.fmt.RS.d2); goto ok;
13185 case 0x8d: s390_format_RS_R0RD(s390_irgen_SLDL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
13186 ovl.fmt.RS.d2); goto ok;
13187 case 0x8e: s390_format_RS_R0RD(s390_irgen_SRDA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
13188 ovl.fmt.RS.d2); goto ok;
13189 case 0x8f: s390_format_RS_R0RD(s390_irgen_SLDA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
13190 ovl.fmt.RS.d2); goto ok;
13191 case 0x90: s390_format_RS_RRRD(s390_irgen_STM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13192 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13193 case 0x91: s390_format_SI_URD(s390_irgen_TM, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
13194 ovl.fmt.SI.d1); goto ok;
13195 case 0x92: s390_format_SI_URD(s390_irgen_MVI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
13196 ovl.fmt.SI.d1); goto ok;
13197 case 0x94: s390_format_SI_URD(s390_irgen_NI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
13198 ovl.fmt.SI.d1); goto ok;
13199 case 0x95: s390_format_SI_URD(s390_irgen_CLI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
13200 ovl.fmt.SI.d1); goto ok;
13201 case 0x96: s390_format_SI_URD(s390_irgen_OI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
13202 ovl.fmt.SI.d1); goto ok;
13203 case 0x97: s390_format_SI_URD(s390_irgen_XI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
13204 ovl.fmt.SI.d1); goto ok;
13205 case 0x98: s390_format_RS_RRRD(s390_irgen_LM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13206 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13207 case 0x99: /* TRACE */ goto unimplemented;
13208 case 0x9a: s390_format_RS_AARD(s390_irgen_LAM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13209 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13210 case 0x9b: s390_format_RS_AARD(s390_irgen_STAM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13211 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13212 case 0xa8: s390_format_RS_RRRD(s390_irgen_MVCLE, ovl.fmt.RS.r1,
13213 ovl.fmt.RS.r3, ovl.fmt.RS.b2, ovl.fmt.RS.d2);
13214 goto ok;
13215 case 0xa9: s390_format_RS_RRRD(s390_irgen_CLCLE, ovl.fmt.RS.r1,
13216 ovl.fmt.RS.r3, ovl.fmt.RS.b2, ovl.fmt.RS.d2);
13217 goto ok;
13218 case 0xac: /* STNSM */ goto unimplemented;
13219 case 0xad: /* STOSM */ goto unimplemented;
13220 case 0xae: /* SIGP */ goto unimplemented;
13221 case 0xaf: /* MC */ goto unimplemented;
13222 case 0xb1: /* LRA */ goto unimplemented;
13223 case 0xb6: /* STCTL */ goto unimplemented;
13224 case 0xb7: /* LCTL */ goto unimplemented;
13225 case 0xba: s390_format_RS_RRRD(s390_irgen_CS, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13226 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
florian448cbba2012-06-06 02:26:01 +000013227 case 0xbb: s390_format_RS_RRRD(s390_irgen_CDS, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13228 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013229 case 0xbd: s390_format_RS_RURD(s390_irgen_CLM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13230 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13231 case 0xbe: s390_format_RS_RURD(s390_irgen_STCM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13232 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13233 case 0xbf: s390_format_RS_RURD(s390_irgen_ICM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13234 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13235 }
13236
13237 return S390_DECODE_UNKNOWN_INSN;
13238
13239ok:
13240 return S390_DECODE_OK;
13241
13242unimplemented:
13243 return S390_DECODE_UNIMPLEMENTED_INSN;
13244}
13245
13246static s390_decode_t
13247s390_decode_6byte_and_irgen(UChar *bytes)
13248{
13249 typedef union {
13250 struct {
13251 unsigned int op1 : 8;
13252 unsigned int r1 : 4;
13253 unsigned int r3 : 4;
13254 unsigned int i2 : 16;
13255 unsigned int : 8;
13256 unsigned int op2 : 8;
13257 } RIE;
13258 struct {
13259 unsigned int op1 : 8;
13260 unsigned int r1 : 4;
13261 unsigned int r2 : 4;
13262 unsigned int i3 : 8;
13263 unsigned int i4 : 8;
13264 unsigned int i5 : 8;
13265 unsigned int op2 : 8;
13266 } RIE_RRUUU;
13267 struct {
13268 unsigned int op1 : 8;
13269 unsigned int r1 : 4;
13270 unsigned int : 4;
13271 unsigned int i2 : 16;
13272 unsigned int m3 : 4;
13273 unsigned int : 4;
13274 unsigned int op2 : 8;
13275 } RIEv1;
13276 struct {
13277 unsigned int op1 : 8;
13278 unsigned int r1 : 4;
13279 unsigned int r2 : 4;
13280 unsigned int i4 : 16;
13281 unsigned int m3 : 4;
13282 unsigned int : 4;
13283 unsigned int op2 : 8;
13284 } RIE_RRPU;
13285 struct {
13286 unsigned int op1 : 8;
13287 unsigned int r1 : 4;
13288 unsigned int m3 : 4;
13289 unsigned int i4 : 16;
13290 unsigned int i2 : 8;
13291 unsigned int op2 : 8;
13292 } RIEv3;
13293 struct {
13294 unsigned int op1 : 8;
13295 unsigned int r1 : 4;
13296 unsigned int op2 : 4;
13297 unsigned int i2 : 32;
13298 } RIL;
13299 struct {
13300 unsigned int op1 : 8;
13301 unsigned int r1 : 4;
13302 unsigned int m3 : 4;
13303 unsigned int b4 : 4;
13304 unsigned int d4 : 12;
13305 unsigned int i2 : 8;
13306 unsigned int op2 : 8;
13307 } RIS;
13308 struct {
13309 unsigned int op1 : 8;
13310 unsigned int r1 : 4;
13311 unsigned int r2 : 4;
13312 unsigned int b4 : 4;
13313 unsigned int d4 : 12;
13314 unsigned int m3 : 4;
13315 unsigned int : 4;
13316 unsigned int op2 : 8;
13317 } RRS;
13318 struct {
13319 unsigned int op1 : 8;
13320 unsigned int l1 : 4;
13321 unsigned int : 4;
13322 unsigned int b1 : 4;
13323 unsigned int d1 : 12;
13324 unsigned int : 8;
13325 unsigned int op2 : 8;
13326 } RSL;
13327 struct {
13328 unsigned int op1 : 8;
13329 unsigned int r1 : 4;
13330 unsigned int r3 : 4;
13331 unsigned int b2 : 4;
13332 unsigned int dl2 : 12;
13333 unsigned int dh2 : 8;
13334 unsigned int op2 : 8;
13335 } RSY;
13336 struct {
13337 unsigned int op1 : 8;
13338 unsigned int r1 : 4;
13339 unsigned int x2 : 4;
13340 unsigned int b2 : 4;
13341 unsigned int d2 : 12;
13342 unsigned int : 8;
13343 unsigned int op2 : 8;
13344 } RXE;
13345 struct {
13346 unsigned int op1 : 8;
13347 unsigned int r3 : 4;
13348 unsigned int x2 : 4;
13349 unsigned int b2 : 4;
13350 unsigned int d2 : 12;
13351 unsigned int r1 : 4;
13352 unsigned int : 4;
13353 unsigned int op2 : 8;
13354 } RXF;
13355 struct {
13356 unsigned int op1 : 8;
13357 unsigned int r1 : 4;
13358 unsigned int x2 : 4;
13359 unsigned int b2 : 4;
13360 unsigned int dl2 : 12;
13361 unsigned int dh2 : 8;
13362 unsigned int op2 : 8;
13363 } RXY;
13364 struct {
13365 unsigned int op1 : 8;
13366 unsigned int i2 : 8;
13367 unsigned int b1 : 4;
13368 unsigned int dl1 : 12;
13369 unsigned int dh1 : 8;
13370 unsigned int op2 : 8;
13371 } SIY;
13372 struct {
13373 unsigned int op : 8;
13374 unsigned int l : 8;
13375 unsigned int b1 : 4;
13376 unsigned int d1 : 12;
13377 unsigned int b2 : 4;
13378 unsigned int d2 : 12;
13379 } SS;
13380 struct {
13381 unsigned int op : 8;
13382 unsigned int l1 : 4;
13383 unsigned int l2 : 4;
13384 unsigned int b1 : 4;
13385 unsigned int d1 : 12;
13386 unsigned int b2 : 4;
13387 unsigned int d2 : 12;
13388 } SS_LLRDRD;
13389 struct {
13390 unsigned int op : 8;
13391 unsigned int r1 : 4;
13392 unsigned int r3 : 4;
13393 unsigned int b2 : 4;
13394 unsigned int d2 : 12;
13395 unsigned int b4 : 4;
13396 unsigned int d4 : 12;
13397 } SS_RRRDRD2;
13398 struct {
13399 unsigned int op : 16;
13400 unsigned int b1 : 4;
13401 unsigned int d1 : 12;
13402 unsigned int b2 : 4;
13403 unsigned int d2 : 12;
13404 } SSE;
13405 struct {
13406 unsigned int op1 : 8;
13407 unsigned int r3 : 4;
13408 unsigned int op2 : 4;
13409 unsigned int b1 : 4;
13410 unsigned int d1 : 12;
13411 unsigned int b2 : 4;
13412 unsigned int d2 : 12;
13413 } SSF;
13414 struct {
13415 unsigned int op : 16;
13416 unsigned int b1 : 4;
13417 unsigned int d1 : 12;
13418 unsigned int i2 : 16;
13419 } SIL;
13420 } formats;
13421 union {
13422 formats fmt;
13423 ULong value;
13424 } ovl;
13425
13426 vassert(sizeof(formats) == 6);
13427
13428 ((char *)(&ovl.value))[0] = bytes[0];
13429 ((char *)(&ovl.value))[1] = bytes[1];
13430 ((char *)(&ovl.value))[2] = bytes[2];
13431 ((char *)(&ovl.value))[3] = bytes[3];
13432 ((char *)(&ovl.value))[4] = bytes[4];
13433 ((char *)(&ovl.value))[5] = bytes[5];
13434 ((char *)(&ovl.value))[6] = 0x0;
13435 ((char *)(&ovl.value))[7] = 0x0;
13436
13437 switch ((ovl.value >> 16) & 0xff00000000ffULL) {
13438 case 0xe30000000002ULL: s390_format_RXY_RRRD(s390_irgen_LTG, ovl.fmt.RXY.r1,
13439 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13440 ovl.fmt.RXY.dl2,
13441 ovl.fmt.RXY.dh2); goto ok;
13442 case 0xe30000000003ULL: /* LRAG */ goto unimplemented;
13443 case 0xe30000000004ULL: s390_format_RXY_RRRD(s390_irgen_LG, ovl.fmt.RXY.r1,
13444 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13445 ovl.fmt.RXY.dl2,
13446 ovl.fmt.RXY.dh2); goto ok;
13447 case 0xe30000000006ULL: s390_format_RXY_RRRD(s390_irgen_CVBY, ovl.fmt.RXY.r1,
13448 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13449 ovl.fmt.RXY.dl2,
13450 ovl.fmt.RXY.dh2); goto ok;
13451 case 0xe30000000008ULL: s390_format_RXY_RRRD(s390_irgen_AG, ovl.fmt.RXY.r1,
13452 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13453 ovl.fmt.RXY.dl2,
13454 ovl.fmt.RXY.dh2); goto ok;
13455 case 0xe30000000009ULL: s390_format_RXY_RRRD(s390_irgen_SG, ovl.fmt.RXY.r1,
13456 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13457 ovl.fmt.RXY.dl2,
13458 ovl.fmt.RXY.dh2); goto ok;
13459 case 0xe3000000000aULL: s390_format_RXY_RRRD(s390_irgen_ALG, ovl.fmt.RXY.r1,
13460 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13461 ovl.fmt.RXY.dl2,
13462 ovl.fmt.RXY.dh2); goto ok;
13463 case 0xe3000000000bULL: s390_format_RXY_RRRD(s390_irgen_SLG, ovl.fmt.RXY.r1,
13464 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13465 ovl.fmt.RXY.dl2,
13466 ovl.fmt.RXY.dh2); goto ok;
13467 case 0xe3000000000cULL: s390_format_RXY_RRRD(s390_irgen_MSG, ovl.fmt.RXY.r1,
13468 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13469 ovl.fmt.RXY.dl2,
13470 ovl.fmt.RXY.dh2); goto ok;
13471 case 0xe3000000000dULL: s390_format_RXY_RRRD(s390_irgen_DSG, ovl.fmt.RXY.r1,
13472 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13473 ovl.fmt.RXY.dl2,
13474 ovl.fmt.RXY.dh2); goto ok;
13475 case 0xe3000000000eULL: /* CVBG */ goto unimplemented;
13476 case 0xe3000000000fULL: s390_format_RXY_RRRD(s390_irgen_LRVG, ovl.fmt.RXY.r1,
13477 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13478 ovl.fmt.RXY.dl2,
13479 ovl.fmt.RXY.dh2); goto ok;
13480 case 0xe30000000012ULL: s390_format_RXY_RRRD(s390_irgen_LT, ovl.fmt.RXY.r1,
13481 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13482 ovl.fmt.RXY.dl2,
13483 ovl.fmt.RXY.dh2); goto ok;
13484 case 0xe30000000013ULL: /* LRAY */ goto unimplemented;
13485 case 0xe30000000014ULL: s390_format_RXY_RRRD(s390_irgen_LGF, ovl.fmt.RXY.r1,
13486 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13487 ovl.fmt.RXY.dl2,
13488 ovl.fmt.RXY.dh2); goto ok;
13489 case 0xe30000000015ULL: s390_format_RXY_RRRD(s390_irgen_LGH, ovl.fmt.RXY.r1,
13490 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13491 ovl.fmt.RXY.dl2,
13492 ovl.fmt.RXY.dh2); goto ok;
13493 case 0xe30000000016ULL: s390_format_RXY_RRRD(s390_irgen_LLGF, ovl.fmt.RXY.r1,
13494 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13495 ovl.fmt.RXY.dl2,
13496 ovl.fmt.RXY.dh2); goto ok;
13497 case 0xe30000000017ULL: s390_format_RXY_RRRD(s390_irgen_LLGT, ovl.fmt.RXY.r1,
13498 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13499 ovl.fmt.RXY.dl2,
13500 ovl.fmt.RXY.dh2); goto ok;
13501 case 0xe30000000018ULL: s390_format_RXY_RRRD(s390_irgen_AGF, ovl.fmt.RXY.r1,
13502 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13503 ovl.fmt.RXY.dl2,
13504 ovl.fmt.RXY.dh2); goto ok;
13505 case 0xe30000000019ULL: s390_format_RXY_RRRD(s390_irgen_SGF, ovl.fmt.RXY.r1,
13506 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13507 ovl.fmt.RXY.dl2,
13508 ovl.fmt.RXY.dh2); goto ok;
13509 case 0xe3000000001aULL: s390_format_RXY_RRRD(s390_irgen_ALGF, ovl.fmt.RXY.r1,
13510 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13511 ovl.fmt.RXY.dl2,
13512 ovl.fmt.RXY.dh2); goto ok;
13513 case 0xe3000000001bULL: s390_format_RXY_RRRD(s390_irgen_SLGF, ovl.fmt.RXY.r1,
13514 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13515 ovl.fmt.RXY.dl2,
13516 ovl.fmt.RXY.dh2); goto ok;
13517 case 0xe3000000001cULL: s390_format_RXY_RRRD(s390_irgen_MSGF, ovl.fmt.RXY.r1,
13518 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13519 ovl.fmt.RXY.dl2,
13520 ovl.fmt.RXY.dh2); goto ok;
13521 case 0xe3000000001dULL: s390_format_RXY_RRRD(s390_irgen_DSGF, ovl.fmt.RXY.r1,
13522 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13523 ovl.fmt.RXY.dl2,
13524 ovl.fmt.RXY.dh2); goto ok;
13525 case 0xe3000000001eULL: s390_format_RXY_RRRD(s390_irgen_LRV, ovl.fmt.RXY.r1,
13526 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13527 ovl.fmt.RXY.dl2,
13528 ovl.fmt.RXY.dh2); goto ok;
13529 case 0xe3000000001fULL: s390_format_RXY_RRRD(s390_irgen_LRVH, ovl.fmt.RXY.r1,
13530 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13531 ovl.fmt.RXY.dl2,
13532 ovl.fmt.RXY.dh2); goto ok;
13533 case 0xe30000000020ULL: s390_format_RXY_RRRD(s390_irgen_CG, ovl.fmt.RXY.r1,
13534 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13535 ovl.fmt.RXY.dl2,
13536 ovl.fmt.RXY.dh2); goto ok;
13537 case 0xe30000000021ULL: s390_format_RXY_RRRD(s390_irgen_CLG, ovl.fmt.RXY.r1,
13538 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13539 ovl.fmt.RXY.dl2,
13540 ovl.fmt.RXY.dh2); goto ok;
13541 case 0xe30000000024ULL: s390_format_RXY_RRRD(s390_irgen_STG, ovl.fmt.RXY.r1,
13542 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13543 ovl.fmt.RXY.dl2,
13544 ovl.fmt.RXY.dh2); goto ok;
13545 case 0xe30000000026ULL: s390_format_RXY_RRRD(s390_irgen_CVDY, ovl.fmt.RXY.r1,
13546 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13547 ovl.fmt.RXY.dl2,
13548 ovl.fmt.RXY.dh2); goto ok;
13549 case 0xe3000000002eULL: /* CVDG */ goto unimplemented;
13550 case 0xe3000000002fULL: s390_format_RXY_RRRD(s390_irgen_STRVG,
13551 ovl.fmt.RXY.r1, ovl.fmt.RXY.x2,
13552 ovl.fmt.RXY.b2, ovl.fmt.RXY.dl2,
13553 ovl.fmt.RXY.dh2); goto ok;
13554 case 0xe30000000030ULL: s390_format_RXY_RRRD(s390_irgen_CGF, ovl.fmt.RXY.r1,
13555 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13556 ovl.fmt.RXY.dl2,
13557 ovl.fmt.RXY.dh2); goto ok;
13558 case 0xe30000000031ULL: s390_format_RXY_RRRD(s390_irgen_CLGF, ovl.fmt.RXY.r1,
13559 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13560 ovl.fmt.RXY.dl2,
13561 ovl.fmt.RXY.dh2); goto ok;
13562 case 0xe30000000032ULL: s390_format_RXY_RRRD(s390_irgen_LTGF, ovl.fmt.RXY.r1,
13563 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13564 ovl.fmt.RXY.dl2,
13565 ovl.fmt.RXY.dh2); goto ok;
13566 case 0xe30000000034ULL: s390_format_RXY_RRRD(s390_irgen_CGH, ovl.fmt.RXY.r1,
13567 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13568 ovl.fmt.RXY.dl2,
13569 ovl.fmt.RXY.dh2); goto ok;
13570 case 0xe30000000036ULL: s390_format_RXY_URRD(s390_irgen_PFD, ovl.fmt.RXY.r1,
13571 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13572 ovl.fmt.RXY.dl2,
13573 ovl.fmt.RXY.dh2); goto ok;
13574 case 0xe3000000003eULL: s390_format_RXY_RRRD(s390_irgen_STRV, ovl.fmt.RXY.r1,
13575 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13576 ovl.fmt.RXY.dl2,
13577 ovl.fmt.RXY.dh2); goto ok;
13578 case 0xe3000000003fULL: s390_format_RXY_RRRD(s390_irgen_STRVH,
13579 ovl.fmt.RXY.r1, ovl.fmt.RXY.x2,
13580 ovl.fmt.RXY.b2, ovl.fmt.RXY.dl2,
13581 ovl.fmt.RXY.dh2); goto ok;
13582 case 0xe30000000046ULL: s390_format_RXY_RRRD(s390_irgen_BCTG, ovl.fmt.RXY.r1,
13583 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13584 ovl.fmt.RXY.dl2,
13585 ovl.fmt.RXY.dh2); goto ok;
13586 case 0xe30000000050ULL: s390_format_RXY_RRRD(s390_irgen_STY, ovl.fmt.RXY.r1,
13587 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13588 ovl.fmt.RXY.dl2,
13589 ovl.fmt.RXY.dh2); goto ok;
13590 case 0xe30000000051ULL: s390_format_RXY_RRRD(s390_irgen_MSY, ovl.fmt.RXY.r1,
13591 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13592 ovl.fmt.RXY.dl2,
13593 ovl.fmt.RXY.dh2); goto ok;
13594 case 0xe30000000054ULL: s390_format_RXY_RRRD(s390_irgen_NY, ovl.fmt.RXY.r1,
13595 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13596 ovl.fmt.RXY.dl2,
13597 ovl.fmt.RXY.dh2); goto ok;
13598 case 0xe30000000055ULL: s390_format_RXY_RRRD(s390_irgen_CLY, ovl.fmt.RXY.r1,
13599 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13600 ovl.fmt.RXY.dl2,
13601 ovl.fmt.RXY.dh2); goto ok;
13602 case 0xe30000000056ULL: s390_format_RXY_RRRD(s390_irgen_OY, ovl.fmt.RXY.r1,
13603 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13604 ovl.fmt.RXY.dl2,
13605 ovl.fmt.RXY.dh2); goto ok;
13606 case 0xe30000000057ULL: s390_format_RXY_RRRD(s390_irgen_XY, ovl.fmt.RXY.r1,
13607 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13608 ovl.fmt.RXY.dl2,
13609 ovl.fmt.RXY.dh2); goto ok;
13610 case 0xe30000000058ULL: s390_format_RXY_RRRD(s390_irgen_LY, ovl.fmt.RXY.r1,
13611 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13612 ovl.fmt.RXY.dl2,
13613 ovl.fmt.RXY.dh2); goto ok;
13614 case 0xe30000000059ULL: s390_format_RXY_RRRD(s390_irgen_CY, ovl.fmt.RXY.r1,
13615 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13616 ovl.fmt.RXY.dl2,
13617 ovl.fmt.RXY.dh2); goto ok;
13618 case 0xe3000000005aULL: s390_format_RXY_RRRD(s390_irgen_AY, ovl.fmt.RXY.r1,
13619 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13620 ovl.fmt.RXY.dl2,
13621 ovl.fmt.RXY.dh2); goto ok;
13622 case 0xe3000000005bULL: s390_format_RXY_RRRD(s390_irgen_SY, ovl.fmt.RXY.r1,
13623 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13624 ovl.fmt.RXY.dl2,
13625 ovl.fmt.RXY.dh2); goto ok;
13626 case 0xe3000000005cULL: s390_format_RXY_RRRD(s390_irgen_MFY, ovl.fmt.RXY.r1,
13627 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13628 ovl.fmt.RXY.dl2,
13629 ovl.fmt.RXY.dh2); goto ok;
13630 case 0xe3000000005eULL: s390_format_RXY_RRRD(s390_irgen_ALY, ovl.fmt.RXY.r1,
13631 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13632 ovl.fmt.RXY.dl2,
13633 ovl.fmt.RXY.dh2); goto ok;
13634 case 0xe3000000005fULL: s390_format_RXY_RRRD(s390_irgen_SLY, ovl.fmt.RXY.r1,
13635 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13636 ovl.fmt.RXY.dl2,
13637 ovl.fmt.RXY.dh2); goto ok;
13638 case 0xe30000000070ULL: s390_format_RXY_RRRD(s390_irgen_STHY, ovl.fmt.RXY.r1,
13639 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13640 ovl.fmt.RXY.dl2,
13641 ovl.fmt.RXY.dh2); goto ok;
13642 case 0xe30000000071ULL: s390_format_RXY_RRRD(s390_irgen_LAY, ovl.fmt.RXY.r1,
13643 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13644 ovl.fmt.RXY.dl2,
13645 ovl.fmt.RXY.dh2); goto ok;
13646 case 0xe30000000072ULL: s390_format_RXY_RRRD(s390_irgen_STCY, ovl.fmt.RXY.r1,
13647 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13648 ovl.fmt.RXY.dl2,
13649 ovl.fmt.RXY.dh2); goto ok;
13650 case 0xe30000000073ULL: s390_format_RXY_RRRD(s390_irgen_ICY, ovl.fmt.RXY.r1,
13651 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13652 ovl.fmt.RXY.dl2,
13653 ovl.fmt.RXY.dh2); goto ok;
13654 case 0xe30000000075ULL: s390_format_RXY_RRRD(s390_irgen_LAEY, ovl.fmt.RXY.r1,
13655 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13656 ovl.fmt.RXY.dl2,
13657 ovl.fmt.RXY.dh2); goto ok;
13658 case 0xe30000000076ULL: s390_format_RXY_RRRD(s390_irgen_LB, ovl.fmt.RXY.r1,
13659 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13660 ovl.fmt.RXY.dl2,
13661 ovl.fmt.RXY.dh2); goto ok;
13662 case 0xe30000000077ULL: s390_format_RXY_RRRD(s390_irgen_LGB, ovl.fmt.RXY.r1,
13663 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13664 ovl.fmt.RXY.dl2,
13665 ovl.fmt.RXY.dh2); goto ok;
13666 case 0xe30000000078ULL: s390_format_RXY_RRRD(s390_irgen_LHY, ovl.fmt.RXY.r1,
13667 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13668 ovl.fmt.RXY.dl2,
13669 ovl.fmt.RXY.dh2); goto ok;
13670 case 0xe30000000079ULL: s390_format_RXY_RRRD(s390_irgen_CHY, ovl.fmt.RXY.r1,
13671 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13672 ovl.fmt.RXY.dl2,
13673 ovl.fmt.RXY.dh2); goto ok;
13674 case 0xe3000000007aULL: s390_format_RXY_RRRD(s390_irgen_AHY, ovl.fmt.RXY.r1,
13675 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13676 ovl.fmt.RXY.dl2,
13677 ovl.fmt.RXY.dh2); goto ok;
13678 case 0xe3000000007bULL: s390_format_RXY_RRRD(s390_irgen_SHY, ovl.fmt.RXY.r1,
13679 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13680 ovl.fmt.RXY.dl2,
13681 ovl.fmt.RXY.dh2); goto ok;
13682 case 0xe3000000007cULL: s390_format_RXY_RRRD(s390_irgen_MHY, ovl.fmt.RXY.r1,
13683 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13684 ovl.fmt.RXY.dl2,
13685 ovl.fmt.RXY.dh2); goto ok;
13686 case 0xe30000000080ULL: s390_format_RXY_RRRD(s390_irgen_NG, ovl.fmt.RXY.r1,
13687 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13688 ovl.fmt.RXY.dl2,
13689 ovl.fmt.RXY.dh2); goto ok;
13690 case 0xe30000000081ULL: s390_format_RXY_RRRD(s390_irgen_OG, ovl.fmt.RXY.r1,
13691 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13692 ovl.fmt.RXY.dl2,
13693 ovl.fmt.RXY.dh2); goto ok;
13694 case 0xe30000000082ULL: s390_format_RXY_RRRD(s390_irgen_XG, ovl.fmt.RXY.r1,
13695 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13696 ovl.fmt.RXY.dl2,
13697 ovl.fmt.RXY.dh2); goto ok;
13698 case 0xe30000000086ULL: s390_format_RXY_RRRD(s390_irgen_MLG, ovl.fmt.RXY.r1,
13699 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13700 ovl.fmt.RXY.dl2,
13701 ovl.fmt.RXY.dh2); goto ok;
13702 case 0xe30000000087ULL: s390_format_RXY_RRRD(s390_irgen_DLG, ovl.fmt.RXY.r1,
13703 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13704 ovl.fmt.RXY.dl2,
13705 ovl.fmt.RXY.dh2); goto ok;
13706 case 0xe30000000088ULL: s390_format_RXY_RRRD(s390_irgen_ALCG, ovl.fmt.RXY.r1,
13707 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13708 ovl.fmt.RXY.dl2,
13709 ovl.fmt.RXY.dh2); goto ok;
13710 case 0xe30000000089ULL: s390_format_RXY_RRRD(s390_irgen_SLBG, ovl.fmt.RXY.r1,
13711 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13712 ovl.fmt.RXY.dl2,
13713 ovl.fmt.RXY.dh2); goto ok;
13714 case 0xe3000000008eULL: s390_format_RXY_RRRD(s390_irgen_STPQ, ovl.fmt.RXY.r1,
13715 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13716 ovl.fmt.RXY.dl2,
13717 ovl.fmt.RXY.dh2); goto ok;
13718 case 0xe3000000008fULL: s390_format_RXY_RRRD(s390_irgen_LPQ, ovl.fmt.RXY.r1,
13719 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13720 ovl.fmt.RXY.dl2,
13721 ovl.fmt.RXY.dh2); goto ok;
13722 case 0xe30000000090ULL: s390_format_RXY_RRRD(s390_irgen_LLGC, ovl.fmt.RXY.r1,
13723 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13724 ovl.fmt.RXY.dl2,
13725 ovl.fmt.RXY.dh2); goto ok;
13726 case 0xe30000000091ULL: s390_format_RXY_RRRD(s390_irgen_LLGH, ovl.fmt.RXY.r1,
13727 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13728 ovl.fmt.RXY.dl2,
13729 ovl.fmt.RXY.dh2); goto ok;
13730 case 0xe30000000094ULL: s390_format_RXY_RRRD(s390_irgen_LLC, ovl.fmt.RXY.r1,
13731 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13732 ovl.fmt.RXY.dl2,
13733 ovl.fmt.RXY.dh2); goto ok;
13734 case 0xe30000000095ULL: s390_format_RXY_RRRD(s390_irgen_LLH, ovl.fmt.RXY.r1,
13735 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13736 ovl.fmt.RXY.dl2,
13737 ovl.fmt.RXY.dh2); goto ok;
13738 case 0xe30000000096ULL: s390_format_RXY_RRRD(s390_irgen_ML, ovl.fmt.RXY.r1,
13739 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13740 ovl.fmt.RXY.dl2,
13741 ovl.fmt.RXY.dh2); goto ok;
13742 case 0xe30000000097ULL: s390_format_RXY_RRRD(s390_irgen_DL, ovl.fmt.RXY.r1,
13743 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13744 ovl.fmt.RXY.dl2,
13745 ovl.fmt.RXY.dh2); goto ok;
13746 case 0xe30000000098ULL: s390_format_RXY_RRRD(s390_irgen_ALC, ovl.fmt.RXY.r1,
13747 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13748 ovl.fmt.RXY.dl2,
13749 ovl.fmt.RXY.dh2); goto ok;
13750 case 0xe30000000099ULL: s390_format_RXY_RRRD(s390_irgen_SLB, ovl.fmt.RXY.r1,
13751 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13752 ovl.fmt.RXY.dl2,
13753 ovl.fmt.RXY.dh2); goto ok;
13754 case 0xe300000000c0ULL: s390_format_RXY_RRRD(s390_irgen_LBH, ovl.fmt.RXY.r1,
13755 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13756 ovl.fmt.RXY.dl2,
13757 ovl.fmt.RXY.dh2); goto ok;
13758 case 0xe300000000c2ULL: s390_format_RXY_RRRD(s390_irgen_LLCH, ovl.fmt.RXY.r1,
13759 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13760 ovl.fmt.RXY.dl2,
13761 ovl.fmt.RXY.dh2); goto ok;
13762 case 0xe300000000c3ULL: s390_format_RXY_RRRD(s390_irgen_STCH, ovl.fmt.RXY.r1,
13763 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13764 ovl.fmt.RXY.dl2,
13765 ovl.fmt.RXY.dh2); goto ok;
13766 case 0xe300000000c4ULL: s390_format_RXY_RRRD(s390_irgen_LHH, ovl.fmt.RXY.r1,
13767 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13768 ovl.fmt.RXY.dl2,
13769 ovl.fmt.RXY.dh2); goto ok;
13770 case 0xe300000000c6ULL: s390_format_RXY_RRRD(s390_irgen_LLHH, ovl.fmt.RXY.r1,
13771 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13772 ovl.fmt.RXY.dl2,
13773 ovl.fmt.RXY.dh2); goto ok;
13774 case 0xe300000000c7ULL: s390_format_RXY_RRRD(s390_irgen_STHH, ovl.fmt.RXY.r1,
13775 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13776 ovl.fmt.RXY.dl2,
13777 ovl.fmt.RXY.dh2); goto ok;
13778 case 0xe300000000caULL: s390_format_RXY_RRRD(s390_irgen_LFH, ovl.fmt.RXY.r1,
13779 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13780 ovl.fmt.RXY.dl2,
13781 ovl.fmt.RXY.dh2); goto ok;
13782 case 0xe300000000cbULL: s390_format_RXY_RRRD(s390_irgen_STFH, ovl.fmt.RXY.r1,
13783 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13784 ovl.fmt.RXY.dl2,
13785 ovl.fmt.RXY.dh2); goto ok;
13786 case 0xe300000000cdULL: s390_format_RXY_RRRD(s390_irgen_CHF, ovl.fmt.RXY.r1,
13787 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13788 ovl.fmt.RXY.dl2,
13789 ovl.fmt.RXY.dh2); goto ok;
13790 case 0xe300000000cfULL: s390_format_RXY_RRRD(s390_irgen_CLHF, ovl.fmt.RXY.r1,
13791 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13792 ovl.fmt.RXY.dl2,
13793 ovl.fmt.RXY.dh2); goto ok;
13794 case 0xeb0000000004ULL: s390_format_RSY_RRRD(s390_irgen_LMG, ovl.fmt.RSY.r1,
13795 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13796 ovl.fmt.RSY.dl2,
13797 ovl.fmt.RSY.dh2); goto ok;
13798 case 0xeb000000000aULL: s390_format_RSY_RRRD(s390_irgen_SRAG, ovl.fmt.RSY.r1,
13799 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13800 ovl.fmt.RSY.dl2,
13801 ovl.fmt.RSY.dh2); goto ok;
13802 case 0xeb000000000bULL: s390_format_RSY_RRRD(s390_irgen_SLAG, ovl.fmt.RSY.r1,
13803 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13804 ovl.fmt.RSY.dl2,
13805 ovl.fmt.RSY.dh2); goto ok;
13806 case 0xeb000000000cULL: s390_format_RSY_RRRD(s390_irgen_SRLG, ovl.fmt.RSY.r1,
13807 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13808 ovl.fmt.RSY.dl2,
13809 ovl.fmt.RSY.dh2); goto ok;
13810 case 0xeb000000000dULL: s390_format_RSY_RRRD(s390_irgen_SLLG, ovl.fmt.RSY.r1,
13811 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13812 ovl.fmt.RSY.dl2,
13813 ovl.fmt.RSY.dh2); goto ok;
13814 case 0xeb000000000fULL: /* TRACG */ goto unimplemented;
13815 case 0xeb0000000014ULL: s390_format_RSY_RRRD(s390_irgen_CSY, ovl.fmt.RSY.r1,
13816 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13817 ovl.fmt.RSY.dl2,
13818 ovl.fmt.RSY.dh2); goto ok;
13819 case 0xeb000000001cULL: s390_format_RSY_RRRD(s390_irgen_RLLG, ovl.fmt.RSY.r1,
13820 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13821 ovl.fmt.RSY.dl2,
13822 ovl.fmt.RSY.dh2); goto ok;
13823 case 0xeb000000001dULL: s390_format_RSY_RRRD(s390_irgen_RLL, ovl.fmt.RSY.r1,
13824 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13825 ovl.fmt.RSY.dl2,
13826 ovl.fmt.RSY.dh2); goto ok;
13827 case 0xeb0000000020ULL: s390_format_RSY_RURD(s390_irgen_CLMH, ovl.fmt.RSY.r1,
13828 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13829 ovl.fmt.RSY.dl2,
13830 ovl.fmt.RSY.dh2); goto ok;
13831 case 0xeb0000000021ULL: s390_format_RSY_RURD(s390_irgen_CLMY, ovl.fmt.RSY.r1,
13832 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13833 ovl.fmt.RSY.dl2,
13834 ovl.fmt.RSY.dh2); goto ok;
13835 case 0xeb0000000024ULL: s390_format_RSY_RRRD(s390_irgen_STMG, ovl.fmt.RSY.r1,
13836 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13837 ovl.fmt.RSY.dl2,
13838 ovl.fmt.RSY.dh2); goto ok;
13839 case 0xeb0000000025ULL: /* STCTG */ goto unimplemented;
13840 case 0xeb0000000026ULL: s390_format_RSY_RRRD(s390_irgen_STMH, ovl.fmt.RSY.r1,
13841 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13842 ovl.fmt.RSY.dl2,
13843 ovl.fmt.RSY.dh2); goto ok;
13844 case 0xeb000000002cULL: s390_format_RSY_RURD(s390_irgen_STCMH,
13845 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
13846 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
13847 ovl.fmt.RSY.dh2); goto ok;
13848 case 0xeb000000002dULL: s390_format_RSY_RURD(s390_irgen_STCMY,
13849 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
13850 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
13851 ovl.fmt.RSY.dh2); goto ok;
13852 case 0xeb000000002fULL: /* LCTLG */ goto unimplemented;
13853 case 0xeb0000000030ULL: s390_format_RSY_RRRD(s390_irgen_CSG, ovl.fmt.RSY.r1,
13854 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13855 ovl.fmt.RSY.dl2,
13856 ovl.fmt.RSY.dh2); goto ok;
florian448cbba2012-06-06 02:26:01 +000013857 case 0xeb0000000031ULL: s390_format_RSY_RRRD(s390_irgen_CDSY, ovl.fmt.RSY.r1,
13858 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13859 ovl.fmt.RSY.dl2,
13860 ovl.fmt.RSY.dh2); goto ok;
13861 case 0xeb000000003eULL: s390_format_RSY_RRRD(s390_irgen_CDSG, ovl.fmt.RSY.r1,
13862 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13863 ovl.fmt.RSY.dl2,
13864 ovl.fmt.RSY.dh2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013865 case 0xeb0000000044ULL: s390_format_RSY_RRRD(s390_irgen_BXHG, ovl.fmt.RSY.r1,
13866 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13867 ovl.fmt.RSY.dl2,
13868 ovl.fmt.RSY.dh2); goto ok;
13869 case 0xeb0000000045ULL: s390_format_RSY_RRRD(s390_irgen_BXLEG,
13870 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
13871 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
13872 ovl.fmt.RSY.dh2); goto ok;
florian8c88cb62012-08-26 18:58:13 +000013873 case 0xeb000000004cULL: s390_format_RSY_RRRD(s390_irgen_ECAG, ovl.fmt.RSY.r1,
13874 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13875 ovl.fmt.RSY.dl2,
13876 ovl.fmt.RSY.dh2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013877 case 0xeb0000000051ULL: s390_format_SIY_URD(s390_irgen_TMY, ovl.fmt.SIY.i2,
13878 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
13879 ovl.fmt.SIY.dh1); goto ok;
13880 case 0xeb0000000052ULL: s390_format_SIY_URD(s390_irgen_MVIY, ovl.fmt.SIY.i2,
13881 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
13882 ovl.fmt.SIY.dh1); goto ok;
13883 case 0xeb0000000054ULL: s390_format_SIY_URD(s390_irgen_NIY, ovl.fmt.SIY.i2,
13884 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
13885 ovl.fmt.SIY.dh1); goto ok;
13886 case 0xeb0000000055ULL: s390_format_SIY_URD(s390_irgen_CLIY, ovl.fmt.SIY.i2,
13887 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
13888 ovl.fmt.SIY.dh1); goto ok;
13889 case 0xeb0000000056ULL: s390_format_SIY_URD(s390_irgen_OIY, ovl.fmt.SIY.i2,
13890 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
13891 ovl.fmt.SIY.dh1); goto ok;
13892 case 0xeb0000000057ULL: s390_format_SIY_URD(s390_irgen_XIY, ovl.fmt.SIY.i2,
13893 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
13894 ovl.fmt.SIY.dh1); goto ok;
13895 case 0xeb000000006aULL: s390_format_SIY_IRD(s390_irgen_ASI, ovl.fmt.SIY.i2,
13896 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
13897 ovl.fmt.SIY.dh1); goto ok;
13898 case 0xeb000000006eULL: s390_format_SIY_IRD(s390_irgen_ALSI, ovl.fmt.SIY.i2,
13899 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
13900 ovl.fmt.SIY.dh1); goto ok;
13901 case 0xeb000000007aULL: s390_format_SIY_IRD(s390_irgen_AGSI, ovl.fmt.SIY.i2,
13902 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
13903 ovl.fmt.SIY.dh1); goto ok;
13904 case 0xeb000000007eULL: s390_format_SIY_IRD(s390_irgen_ALGSI, ovl.fmt.SIY.i2,
13905 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
13906 ovl.fmt.SIY.dh1); goto ok;
13907 case 0xeb0000000080ULL: s390_format_RSY_RURD(s390_irgen_ICMH, ovl.fmt.RSY.r1,
13908 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13909 ovl.fmt.RSY.dl2,
13910 ovl.fmt.RSY.dh2); goto ok;
13911 case 0xeb0000000081ULL: s390_format_RSY_RURD(s390_irgen_ICMY, ovl.fmt.RSY.r1,
13912 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13913 ovl.fmt.RSY.dl2,
13914 ovl.fmt.RSY.dh2); goto ok;
13915 case 0xeb000000008eULL: /* MVCLU */ goto unimplemented;
13916 case 0xeb000000008fULL: /* CLCLU */ goto unimplemented;
13917 case 0xeb0000000090ULL: s390_format_RSY_RRRD(s390_irgen_STMY, ovl.fmt.RSY.r1,
13918 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13919 ovl.fmt.RSY.dl2,
13920 ovl.fmt.RSY.dh2); goto ok;
13921 case 0xeb0000000096ULL: s390_format_RSY_RRRD(s390_irgen_LMH, ovl.fmt.RSY.r1,
13922 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13923 ovl.fmt.RSY.dl2,
13924 ovl.fmt.RSY.dh2); goto ok;
13925 case 0xeb0000000098ULL: s390_format_RSY_RRRD(s390_irgen_LMY, ovl.fmt.RSY.r1,
13926 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13927 ovl.fmt.RSY.dl2,
13928 ovl.fmt.RSY.dh2); goto ok;
13929 case 0xeb000000009aULL: s390_format_RSY_AARD(s390_irgen_LAMY, ovl.fmt.RSY.r1,
13930 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13931 ovl.fmt.RSY.dl2,
13932 ovl.fmt.RSY.dh2); goto ok;
13933 case 0xeb000000009bULL: s390_format_RSY_AARD(s390_irgen_STAMY,
13934 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
13935 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
13936 ovl.fmt.RSY.dh2); goto ok;
13937 case 0xeb00000000c0ULL: /* TP */ goto unimplemented;
13938 case 0xeb00000000dcULL: s390_format_RSY_RRRD(s390_irgen_SRAK, ovl.fmt.RSY.r1,
13939 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13940 ovl.fmt.RSY.dl2,
13941 ovl.fmt.RSY.dh2); goto ok;
13942 case 0xeb00000000ddULL: s390_format_RSY_RRRD(s390_irgen_SLAK, ovl.fmt.RSY.r1,
13943 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13944 ovl.fmt.RSY.dl2,
13945 ovl.fmt.RSY.dh2); goto ok;
13946 case 0xeb00000000deULL: s390_format_RSY_RRRD(s390_irgen_SRLK, ovl.fmt.RSY.r1,
13947 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13948 ovl.fmt.RSY.dl2,
13949 ovl.fmt.RSY.dh2); goto ok;
13950 case 0xeb00000000dfULL: s390_format_RSY_RRRD(s390_irgen_SLLK, ovl.fmt.RSY.r1,
13951 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13952 ovl.fmt.RSY.dl2,
13953 ovl.fmt.RSY.dh2); goto ok;
sewardjd7bde722011-04-05 13:19:33 +000013954 case 0xeb00000000e2ULL: s390_format_RSY_RDRM(s390_irgen_LOCG, ovl.fmt.RSY.r1,
13955 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13956 ovl.fmt.RSY.dl2,
13957 ovl.fmt.RSY.dh2,
13958 S390_XMNM_LOCG); goto ok;
13959 case 0xeb00000000e3ULL: s390_format_RSY_RDRM(s390_irgen_STOCG,
13960 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
13961 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
13962 ovl.fmt.RSY.dh2,
13963 S390_XMNM_STOCG); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013964 case 0xeb00000000e4ULL: s390_format_RSY_RRRD(s390_irgen_LANG, ovl.fmt.RSY.r1,
13965 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13966 ovl.fmt.RSY.dl2,
13967 ovl.fmt.RSY.dh2); goto ok;
13968 case 0xeb00000000e6ULL: s390_format_RSY_RRRD(s390_irgen_LAOG, ovl.fmt.RSY.r1,
13969 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13970 ovl.fmt.RSY.dl2,
13971 ovl.fmt.RSY.dh2); goto ok;
13972 case 0xeb00000000e7ULL: s390_format_RSY_RRRD(s390_irgen_LAXG, ovl.fmt.RSY.r1,
13973 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13974 ovl.fmt.RSY.dl2,
13975 ovl.fmt.RSY.dh2); goto ok;
13976 case 0xeb00000000e8ULL: s390_format_RSY_RRRD(s390_irgen_LAAG, ovl.fmt.RSY.r1,
13977 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13978 ovl.fmt.RSY.dl2,
13979 ovl.fmt.RSY.dh2); goto ok;
13980 case 0xeb00000000eaULL: s390_format_RSY_RRRD(s390_irgen_LAALG,
13981 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
13982 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
13983 ovl.fmt.RSY.dh2); goto ok;
sewardjd7bde722011-04-05 13:19:33 +000013984 case 0xeb00000000f2ULL: s390_format_RSY_RDRM(s390_irgen_LOC, ovl.fmt.RSY.r1,
13985 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13986 ovl.fmt.RSY.dl2,
13987 ovl.fmt.RSY.dh2, S390_XMNM_LOC);
13988 goto ok;
13989 case 0xeb00000000f3ULL: s390_format_RSY_RDRM(s390_irgen_STOC, ovl.fmt.RSY.r1,
13990 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13991 ovl.fmt.RSY.dl2,
13992 ovl.fmt.RSY.dh2,
13993 S390_XMNM_STOC); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013994 case 0xeb00000000f4ULL: s390_format_RSY_RRRD(s390_irgen_LAN, ovl.fmt.RSY.r1,
13995 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13996 ovl.fmt.RSY.dl2,
13997 ovl.fmt.RSY.dh2); goto ok;
13998 case 0xeb00000000f6ULL: s390_format_RSY_RRRD(s390_irgen_LAO, ovl.fmt.RSY.r1,
13999 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14000 ovl.fmt.RSY.dl2,
14001 ovl.fmt.RSY.dh2); goto ok;
14002 case 0xeb00000000f7ULL: s390_format_RSY_RRRD(s390_irgen_LAX, ovl.fmt.RSY.r1,
14003 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14004 ovl.fmt.RSY.dl2,
14005 ovl.fmt.RSY.dh2); goto ok;
14006 case 0xeb00000000f8ULL: s390_format_RSY_RRRD(s390_irgen_LAA, ovl.fmt.RSY.r1,
14007 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14008 ovl.fmt.RSY.dl2,
14009 ovl.fmt.RSY.dh2); goto ok;
14010 case 0xeb00000000faULL: s390_format_RSY_RRRD(s390_irgen_LAAL, ovl.fmt.RSY.r1,
14011 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14012 ovl.fmt.RSY.dl2,
14013 ovl.fmt.RSY.dh2); goto ok;
14014 case 0xec0000000044ULL: s390_format_RIE_RRP(s390_irgen_BRXHG, ovl.fmt.RIE.r1,
14015 ovl.fmt.RIE.r3, ovl.fmt.RIE.i2);
14016 goto ok;
14017 case 0xec0000000045ULL: s390_format_RIE_RRP(s390_irgen_BRXLG, ovl.fmt.RIE.r1,
14018 ovl.fmt.RIE.r3, ovl.fmt.RIE.i2);
14019 goto ok;
14020 case 0xec0000000051ULL: /* RISBLG */ goto unimplemented;
14021 case 0xec0000000054ULL: s390_format_RIE_RRUUU(s390_irgen_RNSBG,
14022 ovl.fmt.RIE_RRUUU.r1,
14023 ovl.fmt.RIE_RRUUU.r2,
14024 ovl.fmt.RIE_RRUUU.i3,
14025 ovl.fmt.RIE_RRUUU.i4,
14026 ovl.fmt.RIE_RRUUU.i5);
14027 goto ok;
14028 case 0xec0000000055ULL: s390_format_RIE_RRUUU(s390_irgen_RISBG,
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 0xec0000000056ULL: s390_format_RIE_RRUUU(s390_irgen_ROSBG,
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 0xec0000000057ULL: s390_format_RIE_RRUUU(s390_irgen_RXSBG,
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 0xec000000005dULL: /* RISBHG */ goto unimplemented;
14050 case 0xec0000000064ULL: s390_format_RIE_RRPU(s390_irgen_CGRJ,
14051 ovl.fmt.RIE_RRPU.r1,
14052 ovl.fmt.RIE_RRPU.r2,
14053 ovl.fmt.RIE_RRPU.i4,
14054 ovl.fmt.RIE_RRPU.m3); goto ok;
14055 case 0xec0000000065ULL: s390_format_RIE_RRPU(s390_irgen_CLGRJ,
14056 ovl.fmt.RIE_RRPU.r1,
14057 ovl.fmt.RIE_RRPU.r2,
14058 ovl.fmt.RIE_RRPU.i4,
14059 ovl.fmt.RIE_RRPU.m3); goto ok;
14060 case 0xec0000000070ULL: /* CGIT */ goto unimplemented;
14061 case 0xec0000000071ULL: /* CLGIT */ goto unimplemented;
14062 case 0xec0000000072ULL: /* CIT */ goto unimplemented;
14063 case 0xec0000000073ULL: /* CLFIT */ goto unimplemented;
14064 case 0xec0000000076ULL: s390_format_RIE_RRPU(s390_irgen_CRJ,
14065 ovl.fmt.RIE_RRPU.r1,
14066 ovl.fmt.RIE_RRPU.r2,
14067 ovl.fmt.RIE_RRPU.i4,
14068 ovl.fmt.RIE_RRPU.m3); goto ok;
14069 case 0xec0000000077ULL: s390_format_RIE_RRPU(s390_irgen_CLRJ,
14070 ovl.fmt.RIE_RRPU.r1,
14071 ovl.fmt.RIE_RRPU.r2,
14072 ovl.fmt.RIE_RRPU.i4,
14073 ovl.fmt.RIE_RRPU.m3); goto ok;
14074 case 0xec000000007cULL: s390_format_RIE_RUPI(s390_irgen_CGIJ,
14075 ovl.fmt.RIEv3.r1,
14076 ovl.fmt.RIEv3.m3,
14077 ovl.fmt.RIEv3.i4,
14078 ovl.fmt.RIEv3.i2); goto ok;
14079 case 0xec000000007dULL: s390_format_RIE_RUPU(s390_irgen_CLGIJ,
14080 ovl.fmt.RIEv3.r1,
14081 ovl.fmt.RIEv3.m3,
14082 ovl.fmt.RIEv3.i4,
14083 ovl.fmt.RIEv3.i2); goto ok;
14084 case 0xec000000007eULL: s390_format_RIE_RUPI(s390_irgen_CIJ,
14085 ovl.fmt.RIEv3.r1,
14086 ovl.fmt.RIEv3.m3,
14087 ovl.fmt.RIEv3.i4,
14088 ovl.fmt.RIEv3.i2); goto ok;
14089 case 0xec000000007fULL: s390_format_RIE_RUPU(s390_irgen_CLIJ,
14090 ovl.fmt.RIEv3.r1,
14091 ovl.fmt.RIEv3.m3,
14092 ovl.fmt.RIEv3.i4,
14093 ovl.fmt.RIEv3.i2); goto ok;
14094 case 0xec00000000d8ULL: s390_format_RIE_RRI0(s390_irgen_AHIK, ovl.fmt.RIE.r1,
14095 ovl.fmt.RIE.r3, ovl.fmt.RIE.i2);
14096 goto ok;
14097 case 0xec00000000d9ULL: s390_format_RIE_RRI0(s390_irgen_AGHIK,
14098 ovl.fmt.RIE.r1, ovl.fmt.RIE.r3,
14099 ovl.fmt.RIE.i2); goto ok;
14100 case 0xec00000000daULL: s390_format_RIE_RRI0(s390_irgen_ALHSIK,
14101 ovl.fmt.RIE.r1, ovl.fmt.RIE.r3,
14102 ovl.fmt.RIE.i2); goto ok;
14103 case 0xec00000000dbULL: s390_format_RIE_RRI0(s390_irgen_ALGHSIK,
14104 ovl.fmt.RIE.r1, ovl.fmt.RIE.r3,
14105 ovl.fmt.RIE.i2); goto ok;
14106 case 0xec00000000e4ULL: s390_format_RRS(s390_irgen_CGRB, ovl.fmt.RRS.r1,
14107 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
14108 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
14109 goto ok;
14110 case 0xec00000000e5ULL: s390_format_RRS(s390_irgen_CLGRB, ovl.fmt.RRS.r1,
14111 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
14112 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
14113 goto ok;
14114 case 0xec00000000f6ULL: s390_format_RRS(s390_irgen_CRB, ovl.fmt.RRS.r1,
14115 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
14116 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
14117 goto ok;
14118 case 0xec00000000f7ULL: s390_format_RRS(s390_irgen_CLRB, ovl.fmt.RRS.r1,
14119 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
14120 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
14121 goto ok;
14122 case 0xec00000000fcULL: s390_format_RIS_RURDI(s390_irgen_CGIB,
14123 ovl.fmt.RIS.r1, ovl.fmt.RIS.m3,
14124 ovl.fmt.RIS.b4, ovl.fmt.RIS.d4,
14125 ovl.fmt.RIS.i2); goto ok;
14126 case 0xec00000000fdULL: s390_format_RIS_RURDU(s390_irgen_CLGIB,
14127 ovl.fmt.RIS.r1, ovl.fmt.RIS.m3,
14128 ovl.fmt.RIS.b4, ovl.fmt.RIS.d4,
14129 ovl.fmt.RIS.i2); goto ok;
14130 case 0xec00000000feULL: s390_format_RIS_RURDI(s390_irgen_CIB, ovl.fmt.RIS.r1,
14131 ovl.fmt.RIS.m3, ovl.fmt.RIS.b4,
14132 ovl.fmt.RIS.d4,
14133 ovl.fmt.RIS.i2); goto ok;
14134 case 0xec00000000ffULL: s390_format_RIS_RURDU(s390_irgen_CLIB,
14135 ovl.fmt.RIS.r1, ovl.fmt.RIS.m3,
14136 ovl.fmt.RIS.b4, ovl.fmt.RIS.d4,
14137 ovl.fmt.RIS.i2); goto ok;
14138 case 0xed0000000004ULL: s390_format_RXE_FRRD(s390_irgen_LDEB, ovl.fmt.RXE.r1,
14139 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14140 ovl.fmt.RXE.d2); goto ok;
14141 case 0xed0000000005ULL: s390_format_RXE_FRRD(s390_irgen_LXDB, ovl.fmt.RXE.r1,
14142 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14143 ovl.fmt.RXE.d2); goto ok;
14144 case 0xed0000000006ULL: s390_format_RXE_FRRD(s390_irgen_LXEB, ovl.fmt.RXE.r1,
14145 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14146 ovl.fmt.RXE.d2); goto ok;
14147 case 0xed0000000007ULL: /* MXDB */ goto unimplemented;
14148 case 0xed0000000008ULL: /* KEB */ goto unimplemented;
14149 case 0xed0000000009ULL: s390_format_RXE_FRRD(s390_irgen_CEB, ovl.fmt.RXE.r1,
14150 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14151 ovl.fmt.RXE.d2); goto ok;
14152 case 0xed000000000aULL: s390_format_RXE_FRRD(s390_irgen_AEB, ovl.fmt.RXE.r1,
14153 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14154 ovl.fmt.RXE.d2); goto ok;
14155 case 0xed000000000bULL: s390_format_RXE_FRRD(s390_irgen_SEB, ovl.fmt.RXE.r1,
14156 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14157 ovl.fmt.RXE.d2); goto ok;
14158 case 0xed000000000cULL: /* MDEB */ goto unimplemented;
14159 case 0xed000000000dULL: s390_format_RXE_FRRD(s390_irgen_DEB, ovl.fmt.RXE.r1,
14160 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14161 ovl.fmt.RXE.d2); goto ok;
14162 case 0xed000000000eULL: s390_format_RXF_FRRDF(s390_irgen_MAEB,
14163 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
14164 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
14165 ovl.fmt.RXF.r1); goto ok;
14166 case 0xed000000000fULL: s390_format_RXF_FRRDF(s390_irgen_MSEB,
14167 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
14168 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
14169 ovl.fmt.RXF.r1); goto ok;
14170 case 0xed0000000010ULL: s390_format_RXE_FRRD(s390_irgen_TCEB, ovl.fmt.RXE.r1,
14171 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14172 ovl.fmt.RXE.d2); goto ok;
14173 case 0xed0000000011ULL: s390_format_RXE_FRRD(s390_irgen_TCDB, ovl.fmt.RXE.r1,
14174 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14175 ovl.fmt.RXE.d2); goto ok;
14176 case 0xed0000000012ULL: s390_format_RXE_FRRD(s390_irgen_TCXB, ovl.fmt.RXE.r1,
14177 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14178 ovl.fmt.RXE.d2); goto ok;
14179 case 0xed0000000014ULL: s390_format_RXE_FRRD(s390_irgen_SQEB, ovl.fmt.RXE.r1,
14180 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14181 ovl.fmt.RXE.d2); goto ok;
14182 case 0xed0000000015ULL: s390_format_RXE_FRRD(s390_irgen_SQDB, ovl.fmt.RXE.r1,
14183 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14184 ovl.fmt.RXE.d2); goto ok;
14185 case 0xed0000000017ULL: s390_format_RXE_FRRD(s390_irgen_MEEB, ovl.fmt.RXE.r1,
14186 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14187 ovl.fmt.RXE.d2); goto ok;
14188 case 0xed0000000018ULL: /* KDB */ goto unimplemented;
14189 case 0xed0000000019ULL: s390_format_RXE_FRRD(s390_irgen_CDB, ovl.fmt.RXE.r1,
14190 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14191 ovl.fmt.RXE.d2); goto ok;
14192 case 0xed000000001aULL: s390_format_RXE_FRRD(s390_irgen_ADB, ovl.fmt.RXE.r1,
14193 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14194 ovl.fmt.RXE.d2); goto ok;
14195 case 0xed000000001bULL: s390_format_RXE_FRRD(s390_irgen_SDB, ovl.fmt.RXE.r1,
14196 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14197 ovl.fmt.RXE.d2); goto ok;
14198 case 0xed000000001cULL: s390_format_RXE_FRRD(s390_irgen_MDB, ovl.fmt.RXE.r1,
14199 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14200 ovl.fmt.RXE.d2); goto ok;
14201 case 0xed000000001dULL: s390_format_RXE_FRRD(s390_irgen_DDB, ovl.fmt.RXE.r1,
14202 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14203 ovl.fmt.RXE.d2); goto ok;
14204 case 0xed000000001eULL: s390_format_RXF_FRRDF(s390_irgen_MADB,
14205 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
14206 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
14207 ovl.fmt.RXF.r1); goto ok;
14208 case 0xed000000001fULL: s390_format_RXF_FRRDF(s390_irgen_MSDB,
14209 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
14210 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
14211 ovl.fmt.RXF.r1); goto ok;
14212 case 0xed0000000024ULL: /* LDE */ goto unimplemented;
14213 case 0xed0000000025ULL: /* LXD */ goto unimplemented;
14214 case 0xed0000000026ULL: /* LXE */ goto unimplemented;
14215 case 0xed000000002eULL: /* MAE */ goto unimplemented;
14216 case 0xed000000002fULL: /* MSE */ goto unimplemented;
14217 case 0xed0000000034ULL: /* SQE */ goto unimplemented;
14218 case 0xed0000000035ULL: /* SQD */ goto unimplemented;
14219 case 0xed0000000037ULL: /* MEE */ goto unimplemented;
14220 case 0xed0000000038ULL: /* MAYL */ goto unimplemented;
14221 case 0xed0000000039ULL: /* MYL */ goto unimplemented;
14222 case 0xed000000003aULL: /* MAY */ goto unimplemented;
14223 case 0xed000000003bULL: /* MY */ goto unimplemented;
14224 case 0xed000000003cULL: /* MAYH */ goto unimplemented;
14225 case 0xed000000003dULL: /* MYH */ goto unimplemented;
14226 case 0xed000000003eULL: /* MAD */ goto unimplemented;
14227 case 0xed000000003fULL: /* MSD */ goto unimplemented;
14228 case 0xed0000000040ULL: /* SLDT */ goto unimplemented;
14229 case 0xed0000000041ULL: /* SRDT */ goto unimplemented;
14230 case 0xed0000000048ULL: /* SLXT */ goto unimplemented;
14231 case 0xed0000000049ULL: /* SRXT */ goto unimplemented;
14232 case 0xed0000000050ULL: /* TDCET */ goto unimplemented;
14233 case 0xed0000000051ULL: /* TDGET */ goto unimplemented;
14234 case 0xed0000000054ULL: /* TDCDT */ goto unimplemented;
14235 case 0xed0000000055ULL: /* TDGDT */ goto unimplemented;
14236 case 0xed0000000058ULL: /* TDCXT */ goto unimplemented;
14237 case 0xed0000000059ULL: /* TDGXT */ goto unimplemented;
14238 case 0xed0000000064ULL: s390_format_RXY_FRRD(s390_irgen_LEY, ovl.fmt.RXY.r1,
14239 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14240 ovl.fmt.RXY.dl2,
14241 ovl.fmt.RXY.dh2); goto ok;
14242 case 0xed0000000065ULL: s390_format_RXY_FRRD(s390_irgen_LDY, ovl.fmt.RXY.r1,
14243 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14244 ovl.fmt.RXY.dl2,
14245 ovl.fmt.RXY.dh2); goto ok;
14246 case 0xed0000000066ULL: s390_format_RXY_FRRD(s390_irgen_STEY, ovl.fmt.RXY.r1,
14247 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14248 ovl.fmt.RXY.dl2,
14249 ovl.fmt.RXY.dh2); goto ok;
14250 case 0xed0000000067ULL: s390_format_RXY_FRRD(s390_irgen_STDY, ovl.fmt.RXY.r1,
14251 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14252 ovl.fmt.RXY.dl2,
14253 ovl.fmt.RXY.dh2); goto ok;
14254 }
14255
14256 switch (((ovl.value >> 16) & 0xff0f00000000ULL) >> 32) {
14257 case 0xc000ULL: s390_format_RIL_RP(s390_irgen_LARL, ovl.fmt.RIL.r1,
14258 ovl.fmt.RIL.i2); goto ok;
14259 case 0xc001ULL: s390_format_RIL_RI(s390_irgen_LGFI, ovl.fmt.RIL.r1,
14260 ovl.fmt.RIL.i2); goto ok;
14261 case 0xc004ULL: s390_format_RIL(s390_irgen_BRCL, ovl.fmt.RIL.r1,
14262 ovl.fmt.RIL.i2); goto ok;
14263 case 0xc005ULL: s390_format_RIL_RP(s390_irgen_BRASL, ovl.fmt.RIL.r1,
14264 ovl.fmt.RIL.i2); goto ok;
14265 case 0xc006ULL: s390_format_RIL_RU(s390_irgen_XIHF, ovl.fmt.RIL.r1,
14266 ovl.fmt.RIL.i2); goto ok;
14267 case 0xc007ULL: s390_format_RIL_RU(s390_irgen_XILF, ovl.fmt.RIL.r1,
14268 ovl.fmt.RIL.i2); goto ok;
14269 case 0xc008ULL: s390_format_RIL_RU(s390_irgen_IIHF, ovl.fmt.RIL.r1,
14270 ovl.fmt.RIL.i2); goto ok;
14271 case 0xc009ULL: s390_format_RIL_RU(s390_irgen_IILF, ovl.fmt.RIL.r1,
14272 ovl.fmt.RIL.i2); goto ok;
14273 case 0xc00aULL: s390_format_RIL_RU(s390_irgen_NIHF, ovl.fmt.RIL.r1,
14274 ovl.fmt.RIL.i2); goto ok;
14275 case 0xc00bULL: s390_format_RIL_RU(s390_irgen_NILF, ovl.fmt.RIL.r1,
14276 ovl.fmt.RIL.i2); goto ok;
14277 case 0xc00cULL: s390_format_RIL_RU(s390_irgen_OIHF, ovl.fmt.RIL.r1,
14278 ovl.fmt.RIL.i2); goto ok;
14279 case 0xc00dULL: s390_format_RIL_RU(s390_irgen_OILF, ovl.fmt.RIL.r1,
14280 ovl.fmt.RIL.i2); goto ok;
14281 case 0xc00eULL: s390_format_RIL_RU(s390_irgen_LLIHF, ovl.fmt.RIL.r1,
14282 ovl.fmt.RIL.i2); goto ok;
14283 case 0xc00fULL: s390_format_RIL_RU(s390_irgen_LLILF, ovl.fmt.RIL.r1,
14284 ovl.fmt.RIL.i2); goto ok;
14285 case 0xc200ULL: s390_format_RIL_RI(s390_irgen_MSGFI, ovl.fmt.RIL.r1,
14286 ovl.fmt.RIL.i2); goto ok;
14287 case 0xc201ULL: s390_format_RIL_RI(s390_irgen_MSFI, ovl.fmt.RIL.r1,
14288 ovl.fmt.RIL.i2); goto ok;
14289 case 0xc204ULL: s390_format_RIL_RU(s390_irgen_SLGFI, ovl.fmt.RIL.r1,
14290 ovl.fmt.RIL.i2); goto ok;
14291 case 0xc205ULL: s390_format_RIL_RU(s390_irgen_SLFI, ovl.fmt.RIL.r1,
14292 ovl.fmt.RIL.i2); goto ok;
14293 case 0xc208ULL: s390_format_RIL_RI(s390_irgen_AGFI, ovl.fmt.RIL.r1,
14294 ovl.fmt.RIL.i2); goto ok;
14295 case 0xc209ULL: s390_format_RIL_RI(s390_irgen_AFI, ovl.fmt.RIL.r1,
14296 ovl.fmt.RIL.i2); goto ok;
14297 case 0xc20aULL: s390_format_RIL_RU(s390_irgen_ALGFI, ovl.fmt.RIL.r1,
14298 ovl.fmt.RIL.i2); goto ok;
14299 case 0xc20bULL: s390_format_RIL_RU(s390_irgen_ALFI, ovl.fmt.RIL.r1,
14300 ovl.fmt.RIL.i2); goto ok;
14301 case 0xc20cULL: s390_format_RIL_RI(s390_irgen_CGFI, ovl.fmt.RIL.r1,
14302 ovl.fmt.RIL.i2); goto ok;
14303 case 0xc20dULL: s390_format_RIL_RI(s390_irgen_CFI, ovl.fmt.RIL.r1,
14304 ovl.fmt.RIL.i2); goto ok;
14305 case 0xc20eULL: s390_format_RIL_RU(s390_irgen_CLGFI, ovl.fmt.RIL.r1,
14306 ovl.fmt.RIL.i2); goto ok;
14307 case 0xc20fULL: s390_format_RIL_RU(s390_irgen_CLFI, ovl.fmt.RIL.r1,
14308 ovl.fmt.RIL.i2); goto ok;
14309 case 0xc402ULL: s390_format_RIL_RP(s390_irgen_LLHRL, ovl.fmt.RIL.r1,
14310 ovl.fmt.RIL.i2); goto ok;
14311 case 0xc404ULL: s390_format_RIL_RP(s390_irgen_LGHRL, ovl.fmt.RIL.r1,
14312 ovl.fmt.RIL.i2); goto ok;
14313 case 0xc405ULL: s390_format_RIL_RP(s390_irgen_LHRL, ovl.fmt.RIL.r1,
14314 ovl.fmt.RIL.i2); goto ok;
14315 case 0xc406ULL: s390_format_RIL_RP(s390_irgen_LLGHRL, ovl.fmt.RIL.r1,
14316 ovl.fmt.RIL.i2); goto ok;
14317 case 0xc407ULL: s390_format_RIL_RP(s390_irgen_STHRL, ovl.fmt.RIL.r1,
14318 ovl.fmt.RIL.i2); goto ok;
14319 case 0xc408ULL: s390_format_RIL_RP(s390_irgen_LGRL, ovl.fmt.RIL.r1,
14320 ovl.fmt.RIL.i2); goto ok;
14321 case 0xc40bULL: s390_format_RIL_RP(s390_irgen_STGRL, ovl.fmt.RIL.r1,
14322 ovl.fmt.RIL.i2); goto ok;
14323 case 0xc40cULL: s390_format_RIL_RP(s390_irgen_LGFRL, ovl.fmt.RIL.r1,
14324 ovl.fmt.RIL.i2); goto ok;
14325 case 0xc40dULL: s390_format_RIL_RP(s390_irgen_LRL, ovl.fmt.RIL.r1,
14326 ovl.fmt.RIL.i2); goto ok;
14327 case 0xc40eULL: s390_format_RIL_RP(s390_irgen_LLGFRL, ovl.fmt.RIL.r1,
14328 ovl.fmt.RIL.i2); goto ok;
14329 case 0xc40fULL: s390_format_RIL_RP(s390_irgen_STRL, ovl.fmt.RIL.r1,
14330 ovl.fmt.RIL.i2); goto ok;
14331 case 0xc600ULL: s390_format_RIL_RP(s390_irgen_EXRL, ovl.fmt.RIL.r1,
14332 ovl.fmt.RIL.i2); goto ok;
14333 case 0xc602ULL: s390_format_RIL_UP(s390_irgen_PFDRL, ovl.fmt.RIL.r1,
14334 ovl.fmt.RIL.i2); goto ok;
14335 case 0xc604ULL: s390_format_RIL_RP(s390_irgen_CGHRL, ovl.fmt.RIL.r1,
14336 ovl.fmt.RIL.i2); goto ok;
14337 case 0xc605ULL: s390_format_RIL_RP(s390_irgen_CHRL, ovl.fmt.RIL.r1,
14338 ovl.fmt.RIL.i2); goto ok;
14339 case 0xc606ULL: s390_format_RIL_RP(s390_irgen_CLGHRL, ovl.fmt.RIL.r1,
14340 ovl.fmt.RIL.i2); goto ok;
14341 case 0xc607ULL: s390_format_RIL_RP(s390_irgen_CLHRL, ovl.fmt.RIL.r1,
14342 ovl.fmt.RIL.i2); goto ok;
14343 case 0xc608ULL: s390_format_RIL_RP(s390_irgen_CGRL, ovl.fmt.RIL.r1,
14344 ovl.fmt.RIL.i2); goto ok;
14345 case 0xc60aULL: s390_format_RIL_RP(s390_irgen_CLGRL, ovl.fmt.RIL.r1,
14346 ovl.fmt.RIL.i2); goto ok;
14347 case 0xc60cULL: s390_format_RIL_RP(s390_irgen_CGFRL, ovl.fmt.RIL.r1,
14348 ovl.fmt.RIL.i2); goto ok;
14349 case 0xc60dULL: s390_format_RIL_RP(s390_irgen_CRL, ovl.fmt.RIL.r1,
14350 ovl.fmt.RIL.i2); goto ok;
14351 case 0xc60eULL: s390_format_RIL_RP(s390_irgen_CLGFRL, ovl.fmt.RIL.r1,
14352 ovl.fmt.RIL.i2); goto ok;
14353 case 0xc60fULL: s390_format_RIL_RP(s390_irgen_CLRL, ovl.fmt.RIL.r1,
14354 ovl.fmt.RIL.i2); goto ok;
14355 case 0xc800ULL: /* MVCOS */ goto unimplemented;
14356 case 0xc801ULL: /* ECTG */ goto unimplemented;
14357 case 0xc802ULL: /* CSST */ goto unimplemented;
14358 case 0xc804ULL: /* LPD */ goto unimplemented;
14359 case 0xc805ULL: /* LPDG */ goto unimplemented;
14360 case 0xcc06ULL: /* BRCTH */ goto unimplemented;
14361 case 0xcc08ULL: s390_format_RIL_RI(s390_irgen_AIH, ovl.fmt.RIL.r1,
14362 ovl.fmt.RIL.i2); goto ok;
14363 case 0xcc0aULL: s390_format_RIL_RI(s390_irgen_ALSIH, ovl.fmt.RIL.r1,
14364 ovl.fmt.RIL.i2); goto ok;
14365 case 0xcc0bULL: s390_format_RIL_RI(s390_irgen_ALSIHN, ovl.fmt.RIL.r1,
14366 ovl.fmt.RIL.i2); goto ok;
14367 case 0xcc0dULL: s390_format_RIL_RI(s390_irgen_CIH, ovl.fmt.RIL.r1,
14368 ovl.fmt.RIL.i2); goto ok;
14369 case 0xcc0fULL: s390_format_RIL_RU(s390_irgen_CLIH, ovl.fmt.RIL.r1,
14370 ovl.fmt.RIL.i2); goto ok;
14371 }
14372
14373 switch (((ovl.value >> 16) & 0xff0000000000ULL) >> 40) {
14374 case 0xd0ULL: /* TRTR */ goto unimplemented;
14375 case 0xd1ULL: /* MVN */ goto unimplemented;
14376 case 0xd2ULL: s390_format_SS_L0RDRD(s390_irgen_MVC, ovl.fmt.SS.l,
14377 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
14378 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
14379 case 0xd3ULL: /* MVZ */ goto unimplemented;
14380 case 0xd4ULL: s390_format_SS_L0RDRD(s390_irgen_NC, ovl.fmt.SS.l,
14381 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
14382 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
14383 case 0xd5ULL: s390_format_SS_L0RDRD(s390_irgen_CLC, 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 0xd6ULL: s390_format_SS_L0RDRD(s390_irgen_OC, ovl.fmt.SS.l,
14387 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
14388 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
sewardjb63967e2011-03-24 08:50:04 +000014389 case 0xd7ULL:
14390 if (ovl.fmt.SS.b1 == ovl.fmt.SS.b2 && ovl.fmt.SS.d1 == ovl.fmt.SS.d2)
14391 s390_irgen_XC_sameloc(ovl.fmt.SS.l, ovl.fmt.SS.b1, ovl.fmt.SS.d1);
14392 else
14393 s390_format_SS_L0RDRD(s390_irgen_XC, ovl.fmt.SS.l,
14394 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
14395 ovl.fmt.SS.b2, ovl.fmt.SS.d2);
14396 goto ok;
sewardj2019a972011-03-07 16:04:07 +000014397 case 0xd9ULL: /* MVCK */ goto unimplemented;
14398 case 0xdaULL: /* MVCP */ goto unimplemented;
14399 case 0xdbULL: /* MVCS */ goto unimplemented;
florian730448f2012-02-04 17:07:07 +000014400 case 0xdcULL: s390_format_SS_L0RDRD(s390_irgen_TR, ovl.fmt.SS.l,
14401 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
14402 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014403 case 0xddULL: /* TRT */ goto unimplemented;
14404 case 0xdeULL: /* ED */ goto unimplemented;
14405 case 0xdfULL: /* EDMK */ goto unimplemented;
14406 case 0xe1ULL: /* PKU */ goto unimplemented;
14407 case 0xe2ULL: /* UNPKU */ goto unimplemented;
14408 case 0xe8ULL: /* MVCIN */ goto unimplemented;
14409 case 0xe9ULL: /* PKA */ goto unimplemented;
14410 case 0xeaULL: /* UNPKA */ goto unimplemented;
14411 case 0xeeULL: /* PLO */ goto unimplemented;
14412 case 0xefULL: /* LMD */ goto unimplemented;
14413 case 0xf0ULL: /* SRP */ goto unimplemented;
14414 case 0xf1ULL: /* MVO */ goto unimplemented;
14415 case 0xf2ULL: /* PACK */ goto unimplemented;
14416 case 0xf3ULL: /* UNPK */ goto unimplemented;
14417 case 0xf8ULL: /* ZAP */ goto unimplemented;
14418 case 0xf9ULL: /* CP */ goto unimplemented;
14419 case 0xfaULL: /* AP */ goto unimplemented;
14420 case 0xfbULL: /* SP */ goto unimplemented;
14421 case 0xfcULL: /* MP */ goto unimplemented;
14422 case 0xfdULL: /* DP */ goto unimplemented;
14423 }
14424
14425 switch (((ovl.value >> 16) & 0xffff00000000ULL) >> 32) {
14426 case 0xe500ULL: /* LASP */ goto unimplemented;
14427 case 0xe501ULL: /* TPROT */ goto unimplemented;
14428 case 0xe502ULL: /* STRAG */ goto unimplemented;
14429 case 0xe50eULL: /* MVCSK */ goto unimplemented;
14430 case 0xe50fULL: /* MVCDK */ goto unimplemented;
14431 case 0xe544ULL: s390_format_SIL_RDI(s390_irgen_MVHHI, ovl.fmt.SIL.b1,
14432 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14433 goto ok;
14434 case 0xe548ULL: s390_format_SIL_RDI(s390_irgen_MVGHI, ovl.fmt.SIL.b1,
14435 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14436 goto ok;
14437 case 0xe54cULL: s390_format_SIL_RDI(s390_irgen_MVHI, ovl.fmt.SIL.b1,
14438 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14439 goto ok;
14440 case 0xe554ULL: s390_format_SIL_RDI(s390_irgen_CHHSI, ovl.fmt.SIL.b1,
14441 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14442 goto ok;
14443 case 0xe555ULL: s390_format_SIL_RDU(s390_irgen_CLHHSI, ovl.fmt.SIL.b1,
14444 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14445 goto ok;
14446 case 0xe558ULL: s390_format_SIL_RDI(s390_irgen_CGHSI, ovl.fmt.SIL.b1,
14447 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14448 goto ok;
14449 case 0xe559ULL: s390_format_SIL_RDU(s390_irgen_CLGHSI, ovl.fmt.SIL.b1,
14450 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14451 goto ok;
14452 case 0xe55cULL: s390_format_SIL_RDI(s390_irgen_CHSI, ovl.fmt.SIL.b1,
14453 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14454 goto ok;
14455 case 0xe55dULL: s390_format_SIL_RDU(s390_irgen_CLFHSI, ovl.fmt.SIL.b1,
14456 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14457 goto ok;
14458 }
14459
14460 return S390_DECODE_UNKNOWN_INSN;
14461
14462ok:
14463 return S390_DECODE_OK;
14464
14465unimplemented:
14466 return S390_DECODE_UNIMPLEMENTED_INSN;
14467}
14468
14469/* Handle "special" instructions. */
14470static s390_decode_t
14471s390_decode_special_and_irgen(UChar *bytes)
14472{
14473 s390_decode_t status = S390_DECODE_OK;
14474
14475 /* Got a "Special" instruction preamble. Which one is it? */
14476 if (bytes[0] == 0x18 && bytes[1] == 0x22 /* lr %r2, %r2 */) {
14477 s390_irgen_client_request();
14478 } else if (bytes[0] == 0x18 && bytes[1] == 0x33 /* lr %r3, %r3 */) {
14479 s390_irgen_guest_NRADDR();
14480 } else if (bytes[0] == 0x18 && bytes[1] == 0x44 /* lr %r4, %r4 */) {
14481 s390_irgen_call_noredir();
florian2245ce92012-08-28 16:49:30 +000014482 } else if (bytes[0] == 0x18 && bytes[1] == 0x55 /* lr %r5, %r5 */) {
14483 vex_inject_ir(irsb, Iend_BE);
14484
14485 /* Invalidate the current insn. The reason is that the IRop we're
14486 injecting here can change. In which case the translation has to
14487 be redone. For ease of handling, we simply invalidate all the
14488 time. */
14489 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TISTART),
14490 mkU64(guest_IA_curr_instr)));
14491 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TILEN),
14492 mkU64(guest_IA_next_instr - guest_IA_curr_instr)));
14493 vassert(guest_IA_next_instr - guest_IA_curr_instr ==
14494 S390_SPECIAL_OP_PREAMBLE_SIZE + S390_SPECIAL_OP_SIZE);
14495
14496 put_IA(mkaddr_expr(guest_IA_next_instr));
14497 dis_res->whatNext = Dis_StopHere;
14498 dis_res->jk_StopHere = Ijk_TInval;
sewardj2019a972011-03-07 16:04:07 +000014499 } else {
14500 /* We don't know what it is. */
14501 return S390_DECODE_UNKNOWN_SPECIAL_INSN;
14502 }
14503
14504 dis_res->len = S390_SPECIAL_OP_PREAMBLE_SIZE + S390_SPECIAL_OP_SIZE;
14505
14506 return status;
14507}
14508
14509
14510/* Function returns # bytes that were decoded or 0 in case of failure */
florianb4df7682011-07-05 02:09:01 +000014511static UInt
sewardj2019a972011-03-07 16:04:07 +000014512s390_decode_and_irgen(UChar *bytes, UInt insn_length, DisResult *dres)
14513{
14514 s390_decode_t status;
14515
14516 dis_res = dres;
14517
14518 /* Spot the 8-byte preamble: 18ff lr r15,r15
14519 1811 lr r1,r1
14520 1822 lr r2,r2
14521 1833 lr r3,r3 */
14522 if (bytes[ 0] == 0x18 && bytes[ 1] == 0xff && bytes[ 2] == 0x18 &&
14523 bytes[ 3] == 0x11 && bytes[ 4] == 0x18 && bytes[ 5] == 0x22 &&
14524 bytes[ 6] == 0x18 && bytes[ 7] == 0x33) {
14525
14526 /* Handle special instruction that follows that preamble. */
14527 if (0) vex_printf("special function handling...\n");
florian2c8ed942011-08-01 22:07:51 +000014528
14529 insn_length = S390_SPECIAL_OP_PREAMBLE_SIZE + S390_SPECIAL_OP_SIZE;
14530 guest_IA_next_instr = guest_IA_curr_instr + insn_length;
14531
14532 status =
14533 s390_decode_special_and_irgen(bytes + S390_SPECIAL_OP_PREAMBLE_SIZE);
sewardj2019a972011-03-07 16:04:07 +000014534 } else {
14535 /* Handle normal instructions. */
14536 switch (insn_length) {
14537 case 2:
14538 status = s390_decode_2byte_and_irgen(bytes);
14539 break;
14540
14541 case 4:
14542 status = s390_decode_4byte_and_irgen(bytes);
14543 break;
14544
14545 case 6:
14546 status = s390_decode_6byte_and_irgen(bytes);
14547 break;
14548
14549 default:
14550 status = S390_DECODE_ERROR;
14551 break;
14552 }
14553 }
florian5fcbba22011-07-27 20:40:22 +000014554 /* If next instruction is execute, stop here */
florianf9e1ed72012-04-17 02:41:56 +000014555 if (dis_res->whatNext == Dis_Continue && bytes[insn_length] == 0x44) {
14556 put_IA(mkaddr_expr(guest_IA_next_instr));
sewardj2019a972011-03-07 16:04:07 +000014557 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +000014558 dis_res->jk_StopHere = Ijk_Boring;
sewardj2019a972011-03-07 16:04:07 +000014559 }
14560
14561 if (status == S390_DECODE_OK) return insn_length; /* OK */
14562
14563 /* Decoding failed somehow */
14564 vex_printf("vex s390->IR: ");
14565 switch (status) {
14566 case S390_DECODE_UNKNOWN_INSN:
14567 vex_printf("unknown insn: ");
14568 break;
14569
14570 case S390_DECODE_UNIMPLEMENTED_INSN:
14571 vex_printf("unimplemented insn: ");
14572 break;
14573
14574 case S390_DECODE_UNKNOWN_SPECIAL_INSN:
14575 vex_printf("unimplemented special insn: ");
14576 break;
14577
14578 default:
14579 case S390_DECODE_ERROR:
14580 vex_printf("decoding error: ");
14581 break;
14582 }
14583
14584 vex_printf("%02x%02x", bytes[0], bytes[1]);
14585 if (insn_length > 2) {
14586 vex_printf(" %02x%02x", bytes[2], bytes[3]);
14587 }
14588 if (insn_length > 4) {
14589 vex_printf(" %02x%02x", bytes[4], bytes[5]);
14590 }
14591 vex_printf("\n");
14592
14593 return 0; /* Failed */
14594}
14595
14596
sewardj2019a972011-03-07 16:04:07 +000014597/* Disassemble a single instruction INSN into IR. */
14598static DisResult
florian420c5012011-07-22 02:12:28 +000014599disInstr_S390_WRK(UChar *insn)
sewardj2019a972011-03-07 16:04:07 +000014600{
14601 UChar byte;
14602 UInt insn_length;
14603 DisResult dres;
14604
14605 /* ---------------------------------------------------- */
14606 /* --- Compute instruction length -- */
14607 /* ---------------------------------------------------- */
14608
14609 /* Get the first byte of the insn. */
14610 byte = insn[0];
14611
14612 /* The leftmost two bits (0:1) encode the length of the insn in bytes.
14613 00 -> 2 bytes, 01 -> 4 bytes, 10 -> 4 bytes, 11 -> 6 bytes. */
14614 insn_length = ((((byte >> 6) + 1) >> 1) + 1) << 1;
14615
14616 guest_IA_next_instr = guest_IA_curr_instr + insn_length;
14617
14618 /* ---------------------------------------------------- */
14619 /* --- Initialise the DisResult data -- */
14620 /* ---------------------------------------------------- */
14621 dres.whatNext = Dis_Continue;
14622 dres.len = insn_length;
14623 dres.continueAt = 0;
florian8844a632012-04-13 04:04:06 +000014624 dres.jk_StopHere = Ijk_INVALID;
sewardj2019a972011-03-07 16:04:07 +000014625
floriana99f20e2011-07-17 14:16:41 +000014626 /* fixs390: consider chasing of conditional jumps */
14627
sewardj2019a972011-03-07 16:04:07 +000014628 /* Normal and special instruction handling starts here. */
14629 if (s390_decode_and_irgen(insn, insn_length, &dres) == 0) {
14630 /* All decode failures end up here. The decoder has already issued an
14631 error message.
14632 Tell the dispatcher that this insn cannot be decoded, and so has
florian342e01a2012-07-26 02:37:49 +000014633 not been executed, and (is currently) the next to be executed.
14634 The insn address in the guest state needs to be set to
14635 guest_IA_curr_instr, otherwise the complaint will report an
14636 incorrect address. */
14637 put_IA(mkaddr_expr(guest_IA_curr_instr));
sewardj2019a972011-03-07 16:04:07 +000014638
florian8844a632012-04-13 04:04:06 +000014639 dres.whatNext = Dis_StopHere;
14640 dres.jk_StopHere = Ijk_NoDecode;
14641 dres.continueAt = 0;
14642 dres.len = 0;
14643 } else {
14644 /* Decode success */
14645 switch (dres.whatNext) {
14646 case Dis_Continue:
florian8559e412012-04-19 14:23:48 +000014647 put_IA(mkaddr_expr(guest_IA_next_instr));
florian8844a632012-04-13 04:04:06 +000014648 break;
14649 case Dis_ResteerU:
14650 case Dis_ResteerC:
14651 put_IA(mkaddr_expr(dres.continueAt));
14652 break;
14653 case Dis_StopHere:
florian4b8efad2012-09-02 18:07:08 +000014654 if (dres.jk_StopHere == Ijk_EmWarn ||
14655 dres.jk_StopHere == Ijk_EmFail) {
14656 /* We assume here, that emulation warnings are not given for
14657 insns that transfer control. There is no good way to
14658 do that. */
14659 put_IA(mkaddr_expr(guest_IA_next_instr));
14660 }
florian8844a632012-04-13 04:04:06 +000014661 break;
14662 default:
14663 vassert(0);
14664 }
sewardj2019a972011-03-07 16:04:07 +000014665 }
14666
14667 return dres;
14668}
14669
14670
14671/*------------------------------------------------------------*/
14672/*--- Top-level fn ---*/
14673/*------------------------------------------------------------*/
14674
14675/* Disassemble a single instruction into IR. The instruction
14676 is located in host memory at &guest_code[delta]. */
14677
14678DisResult
14679disInstr_S390(IRSB *irsb_IN,
sewardj2019a972011-03-07 16:04:07 +000014680 Bool (*resteerOkFn)(void *, Addr64),
14681 Bool resteerCisOk,
14682 void *callback_opaque,
14683 UChar *guest_code,
14684 Long delta,
14685 Addr64 guest_IP,
14686 VexArch guest_arch,
14687 VexArchInfo *archinfo,
14688 VexAbiInfo *abiinfo,
14689 Bool host_bigendian)
14690{
14691 vassert(guest_arch == VexArchS390X);
14692
14693 /* The instruction decoder requires a big-endian machine. */
14694 vassert(host_bigendian == True);
14695
14696 /* Set globals (see top of this file) */
14697 guest_IA_curr_instr = guest_IP;
sewardj2019a972011-03-07 16:04:07 +000014698 irsb = irsb_IN;
florian420c5012011-07-22 02:12:28 +000014699 resteer_fn = resteerOkFn;
14700 resteer_data = callback_opaque;
sewardj2019a972011-03-07 16:04:07 +000014701
florian420c5012011-07-22 02:12:28 +000014702 return disInstr_S390_WRK(guest_code + delta);
sewardj2019a972011-03-07 16:04:07 +000014703}
14704
14705/*---------------------------------------------------------------*/
14706/*--- end guest_s390_toIR.c ---*/
14707/*---------------------------------------------------------------*/