blob: e1c82e114372f97a831c737737f875dec43842d5 [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
sewardj2019a972011-03-07 16:04:07 +0000428/* Encode the s390 rounding mode as it appears in the m3/m4 fields of certain
429 instructions to VEX's IRRoundingMode. */
430static IRRoundingMode
431encode_rounding_mode(UChar mode)
432{
433 switch (mode) {
434 case S390_ROUND_NEAREST_EVEN: return Irrm_NEAREST;
435 case S390_ROUND_ZERO: return Irrm_ZERO;
436 case S390_ROUND_POSINF: return Irrm_PosINF;
437 case S390_ROUND_NEGINF: return Irrm_NegINF;
438 }
439 vpanic("encode_rounding_mode");
440}
441
442static __inline__ IRExpr *get_fpr_dw0(UInt);
443static __inline__ void put_fpr_dw0(UInt, IRExpr *);
444
445/* Read a floating point register pair and combine their contents into a
446 128-bit value */
447static IRExpr *
448get_fpr_pair(UInt archreg)
449{
450 IRExpr *high = get_fpr_dw0(archreg);
451 IRExpr *low = get_fpr_dw0(archreg + 2);
452
453 return binop(Iop_F64HLtoF128, high, low);
454}
455
456/* Write a 128-bit floating point value into a register pair. */
457static void
458put_fpr_pair(UInt archreg, IRExpr *expr)
459{
460 IRExpr *high = unop(Iop_F128HItoF64, expr);
461 IRExpr *low = unop(Iop_F128LOtoF64, expr);
462
463 put_fpr_dw0(archreg, high);
464 put_fpr_dw0(archreg + 2, low);
465}
466
floriane75dafa2012-09-01 17:54:09 +0000467/* Terminate the current IRSB with an emulation failure. */
468static void
469emulation_failure(VexEmNote fail_kind)
470{
471 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_EMNOTE), mkU32(fail_kind)));
472 put_IA(mkaddr_expr(guest_IA_next_instr));
473 dis_res->whatNext = Dis_StopHere;
474 dis_res->jk_StopHere = Ijk_EmFail;
475}
sewardj2019a972011-03-07 16:04:07 +0000476
sewardj2019a972011-03-07 16:04:07 +0000477/*------------------------------------------------------------*/
florianf3410f92012-08-03 18:41:58 +0000478/*--- IR Debugging aids. ---*/
479/*------------------------------------------------------------*/
480#if 0
481
482static ULong
483s390_do_print(HChar *text, ULong value)
484{
485 vex_printf("%s %llu\n", text, value);
486 return 0;
487}
488
489static void
490s390_print(HChar *text, IRExpr *value)
491{
492 IRDirty *d;
493
494 d = unsafeIRDirty_0_N(0 /* regparms */, "s390_do_print", &s390_do_print,
495 mkIRExprVec_2(mkU64((ULong)text), value));
496 stmt(IRStmt_Dirty(d));
497}
498#endif
499
500
501/*------------------------------------------------------------*/
sewardj2019a972011-03-07 16:04:07 +0000502/*--- Build the flags thunk. ---*/
503/*------------------------------------------------------------*/
504
505/* Completely fill the flags thunk. We're always filling all fields.
506 Apparently, that is better for redundant PUT elimination. */
507static void
508s390_cc_thunk_fill(IRExpr *op, IRExpr *dep1, IRExpr *dep2, IRExpr *ndep)
509{
510 UInt op_off, dep1_off, dep2_off, ndep_off;
511
florian428dfdd2012-03-27 03:09:49 +0000512 op_off = S390X_GUEST_OFFSET(guest_CC_OP);
513 dep1_off = S390X_GUEST_OFFSET(guest_CC_DEP1);
514 dep2_off = S390X_GUEST_OFFSET(guest_CC_DEP2);
515 ndep_off = S390X_GUEST_OFFSET(guest_CC_NDEP);
sewardj2019a972011-03-07 16:04:07 +0000516
517 stmt(IRStmt_Put(op_off, op));
518 stmt(IRStmt_Put(dep1_off, dep1));
519 stmt(IRStmt_Put(dep2_off, dep2));
520 stmt(IRStmt_Put(ndep_off, ndep));
521}
522
523
524/* Create an expression for V and widen the result to 64 bit. */
525static IRExpr *
526s390_cc_widen(IRTemp v, Bool sign_extend)
527{
528 IRExpr *expr;
529
530 expr = mkexpr(v);
531
532 switch (typeOfIRTemp(irsb->tyenv, v)) {
533 case Ity_I64:
534 break;
535 case Ity_I32:
536 expr = unop(sign_extend ? Iop_32Sto64 : Iop_32Uto64, expr);
537 break;
538 case Ity_I16:
539 expr = unop(sign_extend ? Iop_16Sto64 : Iop_16Uto64, expr);
540 break;
541 case Ity_I8:
542 expr = unop(sign_extend ? Iop_8Sto64 : Iop_8Uto64, expr);
543 break;
544 default:
545 vpanic("s390_cc_widen");
546 }
547
548 return expr;
549}
550
551static void
552s390_cc_thunk_put1(UInt opc, IRTemp d1, Bool sign_extend)
553{
554 IRExpr *op, *dep1, *dep2, *ndep;
555
556 op = mkU64(opc);
557 dep1 = s390_cc_widen(d1, sign_extend);
558 dep2 = mkU64(0);
559 ndep = mkU64(0);
560
561 s390_cc_thunk_fill(op, dep1, dep2, ndep);
562}
563
564
565static void
566s390_cc_thunk_put2(UInt opc, IRTemp d1, IRTemp d2, 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 = s390_cc_widen(d2, sign_extend);
573 ndep = mkU64(0);
574
575 s390_cc_thunk_fill(op, dep1, dep2, ndep);
576}
577
578
579/* memcheck believes that the NDEP field in the flags thunk is always
580 defined. But for some flag computations (e.g. add with carry) that is
581 just not true. We therefore need to convey to memcheck that the value
582 of the ndep field does matter and therefore we make the DEP2 field
583 depend on it:
584
585 DEP2 = original_DEP2 ^ NDEP
586
587 In s390_calculate_cc we exploit that (a^b)^b == a
588 I.e. we xor the DEP2 value with the NDEP value to recover the
589 original_DEP2 value. */
590static void
591s390_cc_thunk_put3(UInt opc, IRTemp d1, IRTemp d2, IRTemp nd, Bool sign_extend)
592{
593 IRExpr *op, *dep1, *dep2, *ndep, *dep2x;
594
595 op = mkU64(opc);
596 dep1 = s390_cc_widen(d1, sign_extend);
597 dep2 = s390_cc_widen(d2, sign_extend);
598 ndep = s390_cc_widen(nd, sign_extend);
599
600 dep2x = binop(Iop_Xor64, dep2, ndep);
601
602 s390_cc_thunk_fill(op, dep1, dep2x, ndep);
603}
604
605
606/* Write one floating point value into the flags thunk */
607static void
608s390_cc_thunk_put1f(UInt opc, IRTemp d1)
609{
610 IRExpr *op, *dep1, *dep2, *ndep;
611
612 op = mkU64(opc);
613 dep1 = mkexpr(d1);
614 dep2 = mkU64(0);
615 ndep = mkU64(0);
616
617 s390_cc_thunk_fill(op, dep1, dep2, ndep);
618}
619
620
621/* Write a floating point value and an integer into the flags thunk. The
622 integer value is zero-extended first. */
623static void
624s390_cc_thunk_putFZ(UInt opc, IRTemp d1, IRTemp d2)
625{
626 IRExpr *op, *dep1, *dep2, *ndep;
627
628 op = mkU64(opc);
629 dep1 = mkexpr(d1);
630 dep2 = s390_cc_widen(d2, False);
631 ndep = mkU64(0);
632
633 s390_cc_thunk_fill(op, dep1, dep2, ndep);
634}
635
636
637/* Write a 128-bit floating point value into the flags thunk. This is
638 done by splitting the value into two 64-bits values. */
639static void
640s390_cc_thunk_put1f128(UInt opc, IRTemp d1)
641{
642 IRExpr *op, *hi, *lo, *ndep;
643
644 op = mkU64(opc);
645 hi = unop(Iop_F128HItoF64, mkexpr(d1));
646 lo = unop(Iop_F128LOtoF64, mkexpr(d1));
647 ndep = mkU64(0);
648
649 s390_cc_thunk_fill(op, hi, lo, ndep);
650}
651
652
653/* Write a 128-bit floating point value and an integer into the flags thunk.
654 The integer value is zero-extended first. */
655static void
656s390_cc_thunk_put1f128Z(UInt opc, IRTemp d1, IRTemp nd)
657{
658 IRExpr *op, *hi, *lo, *lox, *ndep;
659
660 op = mkU64(opc);
661 hi = unop(Iop_F128HItoF64, mkexpr(d1));
662 lo = unop(Iop_ReinterpF64asI64, unop(Iop_F128LOtoF64, mkexpr(d1)));
663 ndep = s390_cc_widen(nd, False);
664
665 lox = binop(Iop_Xor64, lo, ndep); /* convey dependency */
666
667 s390_cc_thunk_fill(op, hi, lox, ndep);
668}
669
670
671static void
672s390_cc_set(UInt val)
673{
674 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
675 mkU64(val), mkU64(0), mkU64(0));
676}
677
678/* Build IR to calculate the condition code from flags thunk.
679 Returns an expression of type Ity_I32 */
680static IRExpr *
681s390_call_calculate_cc(void)
682{
683 IRExpr **args, *call, *op, *dep1, *dep2, *ndep;
684
florian428dfdd2012-03-27 03:09:49 +0000685 op = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_OP), Ity_I64);
686 dep1 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP1), Ity_I64);
687 dep2 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP2), Ity_I64);
688 ndep = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_NDEP), Ity_I64);
sewardj2019a972011-03-07 16:04:07 +0000689
690 args = mkIRExprVec_4(op, dep1, dep2, ndep);
691 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
692 "s390_calculate_cc", &s390_calculate_cc, args);
693
694 /* Exclude OP and NDEP from definedness checking. We're only
695 interested in DEP1 and DEP2. */
696 call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<3);
697
698 return call;
699}
700
701/* Build IR to calculate the internal condition code for a "compare and branch"
702 insn. Returns an expression of type Ity_I32 */
703static IRExpr *
florianff9613f2012-05-12 15:26:44 +0000704s390_call_calculate_icc(UInt m, UInt opc, IRTemp op1, IRTemp op2)
sewardj2019a972011-03-07 16:04:07 +0000705{
florianff9613f2012-05-12 15:26:44 +0000706 IRExpr **args, *call, *op, *dep1, *dep2, *mask;
sewardj2019a972011-03-07 16:04:07 +0000707
florianff9613f2012-05-12 15:26:44 +0000708 switch (opc) {
709 case S390_CC_OP_SIGNED_COMPARE:
710 dep1 = s390_cc_widen(op1, True);
711 dep2 = s390_cc_widen(op2, True);
712 break;
713
714 case S390_CC_OP_UNSIGNED_COMPARE:
715 dep1 = s390_cc_widen(op1, False);
716 dep2 = s390_cc_widen(op2, False);
717 break;
718
719 default:
720 vpanic("s390_call_calculate_icc");
721 }
722
723 mask = mkU64(m);
sewardj2019a972011-03-07 16:04:07 +0000724 op = mkU64(opc);
sewardj2019a972011-03-07 16:04:07 +0000725
florianff9613f2012-05-12 15:26:44 +0000726 args = mkIRExprVec_5(mask, op, dep1, dep2, mkU64(0) /* unused */);
sewardj2019a972011-03-07 16:04:07 +0000727 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
florianff9613f2012-05-12 15:26:44 +0000728 "s390_calculate_cond", &s390_calculate_cond, args);
sewardj2019a972011-03-07 16:04:07 +0000729
florianff9613f2012-05-12 15:26:44 +0000730 /* Exclude the requested condition, OP and NDEP from definedness
731 checking. We're only interested in DEP1 and DEP2. */
732 call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<1) | (1<<4);
sewardj2019a972011-03-07 16:04:07 +0000733
734 return call;
735}
736
737/* Build IR to calculate the condition code from flags thunk.
738 Returns an expression of type Ity_I32 */
739static IRExpr *
740s390_call_calculate_cond(UInt m)
741{
742 IRExpr **args, *call, *op, *dep1, *dep2, *ndep, *mask;
743
744 mask = mkU64(m);
florian428dfdd2012-03-27 03:09:49 +0000745 op = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_OP), Ity_I64);
746 dep1 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP1), Ity_I64);
747 dep2 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP2), Ity_I64);
748 ndep = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_NDEP), Ity_I64);
sewardj2019a972011-03-07 16:04:07 +0000749
750 args = mkIRExprVec_5(mask, op, dep1, dep2, ndep);
751 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
752 "s390_calculate_cond", &s390_calculate_cond, args);
753
754 /* Exclude the requested condition, OP and NDEP from definedness
755 checking. We're only interested in DEP1 and DEP2. */
756 call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<1) | (1<<4);
757
758 return call;
759}
760
761#define s390_cc_thunk_putZ(op,dep1) s390_cc_thunk_put1(op,dep1,False)
762#define s390_cc_thunk_putS(op,dep1) s390_cc_thunk_put1(op,dep1,True)
763#define s390_cc_thunk_putF(op,dep1) s390_cc_thunk_put1f(op,dep1)
764#define s390_cc_thunk_putZZ(op,dep1,dep2) s390_cc_thunk_put2(op,dep1,dep2,False)
765#define s390_cc_thunk_putSS(op,dep1,dep2) s390_cc_thunk_put2(op,dep1,dep2,True)
766#define s390_cc_thunk_putFF(op,dep1,dep2) s390_cc_thunk_put2f(op,dep1,dep2)
767#define s390_cc_thunk_putZZZ(op,dep1,dep2,ndep) \
768 s390_cc_thunk_put3(op,dep1,dep2,ndep,False)
769#define s390_cc_thunk_putSSS(op,dep1,dep2,ndep) \
770 s390_cc_thunk_put3(op,dep1,dep2,ndep,True)
sewardj2019a972011-03-07 16:04:07 +0000771
772
sewardj2019a972011-03-07 16:04:07 +0000773
774
775/*------------------------------------------------------------*/
776/*--- Guest register access ---*/
777/*------------------------------------------------------------*/
778
779
780/*------------------------------------------------------------*/
781/*--- ar registers ---*/
782/*------------------------------------------------------------*/
783
784/* Return the guest state offset of a ar register. */
785static UInt
786ar_offset(UInt archreg)
787{
788 static const UInt offset[16] = {
floriane88b3c92011-07-05 02:48:39 +0000789 S390X_GUEST_OFFSET(guest_a0),
790 S390X_GUEST_OFFSET(guest_a1),
791 S390X_GUEST_OFFSET(guest_a2),
792 S390X_GUEST_OFFSET(guest_a3),
793 S390X_GUEST_OFFSET(guest_a4),
794 S390X_GUEST_OFFSET(guest_a5),
795 S390X_GUEST_OFFSET(guest_a6),
796 S390X_GUEST_OFFSET(guest_a7),
797 S390X_GUEST_OFFSET(guest_a8),
798 S390X_GUEST_OFFSET(guest_a9),
799 S390X_GUEST_OFFSET(guest_a10),
800 S390X_GUEST_OFFSET(guest_a11),
801 S390X_GUEST_OFFSET(guest_a12),
802 S390X_GUEST_OFFSET(guest_a13),
803 S390X_GUEST_OFFSET(guest_a14),
804 S390X_GUEST_OFFSET(guest_a15),
sewardj2019a972011-03-07 16:04:07 +0000805 };
806
807 vassert(archreg < 16);
808
809 return offset[archreg];
810}
811
812
813/* Return the guest state offset of word #0 of a ar register. */
814static __inline__ UInt
815ar_w0_offset(UInt archreg)
816{
817 return ar_offset(archreg) + 0;
818}
819
820/* Write word #0 of a ar to the guest state. */
821static __inline__ void
822put_ar_w0(UInt archreg, IRExpr *expr)
823{
824 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
825
826 stmt(IRStmt_Put(ar_w0_offset(archreg), expr));
827}
828
829/* Read word #0 of a ar register. */
830static __inline__ IRExpr *
831get_ar_w0(UInt archreg)
832{
833 return IRExpr_Get(ar_w0_offset(archreg), Ity_I32);
834}
835
836
837/*------------------------------------------------------------*/
838/*--- fpr registers ---*/
839/*------------------------------------------------------------*/
840
841/* Return the guest state offset of a fpr register. */
842static UInt
843fpr_offset(UInt archreg)
844{
845 static const UInt offset[16] = {
floriane88b3c92011-07-05 02:48:39 +0000846 S390X_GUEST_OFFSET(guest_f0),
847 S390X_GUEST_OFFSET(guest_f1),
848 S390X_GUEST_OFFSET(guest_f2),
849 S390X_GUEST_OFFSET(guest_f3),
850 S390X_GUEST_OFFSET(guest_f4),
851 S390X_GUEST_OFFSET(guest_f5),
852 S390X_GUEST_OFFSET(guest_f6),
853 S390X_GUEST_OFFSET(guest_f7),
854 S390X_GUEST_OFFSET(guest_f8),
855 S390X_GUEST_OFFSET(guest_f9),
856 S390X_GUEST_OFFSET(guest_f10),
857 S390X_GUEST_OFFSET(guest_f11),
858 S390X_GUEST_OFFSET(guest_f12),
859 S390X_GUEST_OFFSET(guest_f13),
860 S390X_GUEST_OFFSET(guest_f14),
861 S390X_GUEST_OFFSET(guest_f15),
sewardj2019a972011-03-07 16:04:07 +0000862 };
863
864 vassert(archreg < 16);
865
866 return offset[archreg];
867}
868
869
870/* Return the guest state offset of word #0 of a fpr register. */
871static __inline__ UInt
872fpr_w0_offset(UInt archreg)
873{
874 return fpr_offset(archreg) + 0;
875}
876
877/* Write word #0 of a fpr to the guest state. */
878static __inline__ void
879put_fpr_w0(UInt archreg, IRExpr *expr)
880{
881 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_F32);
882
883 stmt(IRStmt_Put(fpr_w0_offset(archreg), expr));
884}
885
886/* Read word #0 of a fpr register. */
887static __inline__ IRExpr *
888get_fpr_w0(UInt archreg)
889{
890 return IRExpr_Get(fpr_w0_offset(archreg), Ity_F32);
891}
892
893/* Return the guest state offset of double word #0 of a fpr register. */
894static __inline__ UInt
895fpr_dw0_offset(UInt archreg)
896{
897 return fpr_offset(archreg) + 0;
898}
899
900/* Write double word #0 of a fpr to the guest state. */
901static __inline__ void
902put_fpr_dw0(UInt archreg, IRExpr *expr)
903{
904 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_F64);
905
906 stmt(IRStmt_Put(fpr_dw0_offset(archreg), expr));
907}
908
909/* Read double word #0 of a fpr register. */
910static __inline__ IRExpr *
911get_fpr_dw0(UInt archreg)
912{
913 return IRExpr_Get(fpr_dw0_offset(archreg), Ity_F64);
914}
915
916
917/*------------------------------------------------------------*/
918/*--- gpr registers ---*/
919/*------------------------------------------------------------*/
920
921/* Return the guest state offset of a gpr register. */
922static UInt
923gpr_offset(UInt archreg)
924{
925 static const UInt offset[16] = {
floriane88b3c92011-07-05 02:48:39 +0000926 S390X_GUEST_OFFSET(guest_r0),
927 S390X_GUEST_OFFSET(guest_r1),
928 S390X_GUEST_OFFSET(guest_r2),
929 S390X_GUEST_OFFSET(guest_r3),
930 S390X_GUEST_OFFSET(guest_r4),
931 S390X_GUEST_OFFSET(guest_r5),
932 S390X_GUEST_OFFSET(guest_r6),
933 S390X_GUEST_OFFSET(guest_r7),
934 S390X_GUEST_OFFSET(guest_r8),
935 S390X_GUEST_OFFSET(guest_r9),
936 S390X_GUEST_OFFSET(guest_r10),
937 S390X_GUEST_OFFSET(guest_r11),
938 S390X_GUEST_OFFSET(guest_r12),
939 S390X_GUEST_OFFSET(guest_r13),
940 S390X_GUEST_OFFSET(guest_r14),
941 S390X_GUEST_OFFSET(guest_r15),
sewardj2019a972011-03-07 16:04:07 +0000942 };
943
944 vassert(archreg < 16);
945
946 return offset[archreg];
947}
948
949
950/* Return the guest state offset of word #0 of a gpr register. */
951static __inline__ UInt
952gpr_w0_offset(UInt archreg)
953{
954 return gpr_offset(archreg) + 0;
955}
956
957/* Write word #0 of a gpr to the guest state. */
958static __inline__ void
959put_gpr_w0(UInt archreg, IRExpr *expr)
960{
961 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
962
963 stmt(IRStmt_Put(gpr_w0_offset(archreg), expr));
964}
965
966/* Read word #0 of a gpr register. */
967static __inline__ IRExpr *
968get_gpr_w0(UInt archreg)
969{
970 return IRExpr_Get(gpr_w0_offset(archreg), Ity_I32);
971}
972
973/* Return the guest state offset of double word #0 of a gpr register. */
974static __inline__ UInt
975gpr_dw0_offset(UInt archreg)
976{
977 return gpr_offset(archreg) + 0;
978}
979
980/* Write double word #0 of a gpr to the guest state. */
981static __inline__ void
982put_gpr_dw0(UInt archreg, IRExpr *expr)
983{
984 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I64);
985
986 stmt(IRStmt_Put(gpr_dw0_offset(archreg), expr));
987}
988
989/* Read double word #0 of a gpr register. */
990static __inline__ IRExpr *
991get_gpr_dw0(UInt archreg)
992{
993 return IRExpr_Get(gpr_dw0_offset(archreg), Ity_I64);
994}
995
996/* Return the guest state offset of half word #1 of a gpr register. */
997static __inline__ UInt
998gpr_hw1_offset(UInt archreg)
999{
1000 return gpr_offset(archreg) + 2;
1001}
1002
1003/* Write half word #1 of a gpr to the guest state. */
1004static __inline__ void
1005put_gpr_hw1(UInt archreg, IRExpr *expr)
1006{
1007 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1008
1009 stmt(IRStmt_Put(gpr_hw1_offset(archreg), expr));
1010}
1011
1012/* Read half word #1 of a gpr register. */
1013static __inline__ IRExpr *
1014get_gpr_hw1(UInt archreg)
1015{
1016 return IRExpr_Get(gpr_hw1_offset(archreg), Ity_I16);
1017}
1018
1019/* Return the guest state offset of byte #6 of a gpr register. */
1020static __inline__ UInt
1021gpr_b6_offset(UInt archreg)
1022{
1023 return gpr_offset(archreg) + 6;
1024}
1025
1026/* Write byte #6 of a gpr to the guest state. */
1027static __inline__ void
1028put_gpr_b6(UInt archreg, IRExpr *expr)
1029{
1030 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1031
1032 stmt(IRStmt_Put(gpr_b6_offset(archreg), expr));
1033}
1034
1035/* Read byte #6 of a gpr register. */
1036static __inline__ IRExpr *
1037get_gpr_b6(UInt archreg)
1038{
1039 return IRExpr_Get(gpr_b6_offset(archreg), Ity_I8);
1040}
1041
1042/* Return the guest state offset of byte #3 of a gpr register. */
1043static __inline__ UInt
1044gpr_b3_offset(UInt archreg)
1045{
1046 return gpr_offset(archreg) + 3;
1047}
1048
1049/* Write byte #3 of a gpr to the guest state. */
1050static __inline__ void
1051put_gpr_b3(UInt archreg, IRExpr *expr)
1052{
1053 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1054
1055 stmt(IRStmt_Put(gpr_b3_offset(archreg), expr));
1056}
1057
1058/* Read byte #3 of a gpr register. */
1059static __inline__ IRExpr *
1060get_gpr_b3(UInt archreg)
1061{
1062 return IRExpr_Get(gpr_b3_offset(archreg), Ity_I8);
1063}
1064
1065/* Return the guest state offset of byte #0 of a gpr register. */
1066static __inline__ UInt
1067gpr_b0_offset(UInt archreg)
1068{
1069 return gpr_offset(archreg) + 0;
1070}
1071
1072/* Write byte #0 of a gpr to the guest state. */
1073static __inline__ void
1074put_gpr_b0(UInt archreg, IRExpr *expr)
1075{
1076 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1077
1078 stmt(IRStmt_Put(gpr_b0_offset(archreg), expr));
1079}
1080
1081/* Read byte #0 of a gpr register. */
1082static __inline__ IRExpr *
1083get_gpr_b0(UInt archreg)
1084{
1085 return IRExpr_Get(gpr_b0_offset(archreg), Ity_I8);
1086}
1087
1088/* Return the guest state offset of word #1 of a gpr register. */
1089static __inline__ UInt
1090gpr_w1_offset(UInt archreg)
1091{
1092 return gpr_offset(archreg) + 4;
1093}
1094
1095/* Write word #1 of a gpr to the guest state. */
1096static __inline__ void
1097put_gpr_w1(UInt archreg, IRExpr *expr)
1098{
1099 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1100
1101 stmt(IRStmt_Put(gpr_w1_offset(archreg), expr));
1102}
1103
1104/* Read word #1 of a gpr register. */
1105static __inline__ IRExpr *
1106get_gpr_w1(UInt archreg)
1107{
1108 return IRExpr_Get(gpr_w1_offset(archreg), Ity_I32);
1109}
1110
1111/* Return the guest state offset of half word #3 of a gpr register. */
1112static __inline__ UInt
1113gpr_hw3_offset(UInt archreg)
1114{
1115 return gpr_offset(archreg) + 6;
1116}
1117
1118/* Write half word #3 of a gpr to the guest state. */
1119static __inline__ void
1120put_gpr_hw3(UInt archreg, IRExpr *expr)
1121{
1122 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1123
1124 stmt(IRStmt_Put(gpr_hw3_offset(archreg), expr));
1125}
1126
1127/* Read half word #3 of a gpr register. */
1128static __inline__ IRExpr *
1129get_gpr_hw3(UInt archreg)
1130{
1131 return IRExpr_Get(gpr_hw3_offset(archreg), Ity_I16);
1132}
1133
1134/* Return the guest state offset of byte #7 of a gpr register. */
1135static __inline__ UInt
1136gpr_b7_offset(UInt archreg)
1137{
1138 return gpr_offset(archreg) + 7;
1139}
1140
1141/* Write byte #7 of a gpr to the guest state. */
1142static __inline__ void
1143put_gpr_b7(UInt archreg, IRExpr *expr)
1144{
1145 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1146
1147 stmt(IRStmt_Put(gpr_b7_offset(archreg), expr));
1148}
1149
1150/* Read byte #7 of a gpr register. */
1151static __inline__ IRExpr *
1152get_gpr_b7(UInt archreg)
1153{
1154 return IRExpr_Get(gpr_b7_offset(archreg), Ity_I8);
1155}
1156
1157/* Return the guest state offset of half word #0 of a gpr register. */
1158static __inline__ UInt
1159gpr_hw0_offset(UInt archreg)
1160{
1161 return gpr_offset(archreg) + 0;
1162}
1163
1164/* Write half word #0 of a gpr to the guest state. */
1165static __inline__ void
1166put_gpr_hw0(UInt archreg, IRExpr *expr)
1167{
1168 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1169
1170 stmt(IRStmt_Put(gpr_hw0_offset(archreg), expr));
1171}
1172
1173/* Read half word #0 of a gpr register. */
1174static __inline__ IRExpr *
1175get_gpr_hw0(UInt archreg)
1176{
1177 return IRExpr_Get(gpr_hw0_offset(archreg), Ity_I16);
1178}
1179
1180/* Return the guest state offset of byte #4 of a gpr register. */
1181static __inline__ UInt
1182gpr_b4_offset(UInt archreg)
1183{
1184 return gpr_offset(archreg) + 4;
1185}
1186
1187/* Write byte #4 of a gpr to the guest state. */
1188static __inline__ void
1189put_gpr_b4(UInt archreg, IRExpr *expr)
1190{
1191 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1192
1193 stmt(IRStmt_Put(gpr_b4_offset(archreg), expr));
1194}
1195
1196/* Read byte #4 of a gpr register. */
1197static __inline__ IRExpr *
1198get_gpr_b4(UInt archreg)
1199{
1200 return IRExpr_Get(gpr_b4_offset(archreg), Ity_I8);
1201}
1202
1203/* Return the guest state offset of byte #1 of a gpr register. */
1204static __inline__ UInt
1205gpr_b1_offset(UInt archreg)
1206{
1207 return gpr_offset(archreg) + 1;
1208}
1209
1210/* Write byte #1 of a gpr to the guest state. */
1211static __inline__ void
1212put_gpr_b1(UInt archreg, IRExpr *expr)
1213{
1214 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1215
1216 stmt(IRStmt_Put(gpr_b1_offset(archreg), expr));
1217}
1218
1219/* Read byte #1 of a gpr register. */
1220static __inline__ IRExpr *
1221get_gpr_b1(UInt archreg)
1222{
1223 return IRExpr_Get(gpr_b1_offset(archreg), Ity_I8);
1224}
1225
1226/* Return the guest state offset of half word #2 of a gpr register. */
1227static __inline__ UInt
1228gpr_hw2_offset(UInt archreg)
1229{
1230 return gpr_offset(archreg) + 4;
1231}
1232
1233/* Write half word #2 of a gpr to the guest state. */
1234static __inline__ void
1235put_gpr_hw2(UInt archreg, IRExpr *expr)
1236{
1237 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1238
1239 stmt(IRStmt_Put(gpr_hw2_offset(archreg), expr));
1240}
1241
1242/* Read half word #2 of a gpr register. */
1243static __inline__ IRExpr *
1244get_gpr_hw2(UInt archreg)
1245{
1246 return IRExpr_Get(gpr_hw2_offset(archreg), Ity_I16);
1247}
1248
1249/* Return the guest state offset of byte #5 of a gpr register. */
1250static __inline__ UInt
1251gpr_b5_offset(UInt archreg)
1252{
1253 return gpr_offset(archreg) + 5;
1254}
1255
1256/* Write byte #5 of a gpr to the guest state. */
1257static __inline__ void
1258put_gpr_b5(UInt archreg, IRExpr *expr)
1259{
1260 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1261
1262 stmt(IRStmt_Put(gpr_b5_offset(archreg), expr));
1263}
1264
1265/* Read byte #5 of a gpr register. */
1266static __inline__ IRExpr *
1267get_gpr_b5(UInt archreg)
1268{
1269 return IRExpr_Get(gpr_b5_offset(archreg), Ity_I8);
1270}
1271
1272/* Return the guest state offset of byte #2 of a gpr register. */
1273static __inline__ UInt
1274gpr_b2_offset(UInt archreg)
1275{
1276 return gpr_offset(archreg) + 2;
1277}
1278
1279/* Write byte #2 of a gpr to the guest state. */
1280static __inline__ void
1281put_gpr_b2(UInt archreg, IRExpr *expr)
1282{
1283 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1284
1285 stmt(IRStmt_Put(gpr_b2_offset(archreg), expr));
1286}
1287
1288/* Read byte #2 of a gpr register. */
1289static __inline__ IRExpr *
1290get_gpr_b2(UInt archreg)
1291{
1292 return IRExpr_Get(gpr_b2_offset(archreg), Ity_I8);
1293}
1294
1295/* Return the guest state offset of the counter register. */
1296static UInt
1297counter_offset(void)
1298{
floriane88b3c92011-07-05 02:48:39 +00001299 return S390X_GUEST_OFFSET(guest_counter);
sewardj2019a972011-03-07 16:04:07 +00001300}
1301
1302/* Return the guest state offset of double word #0 of the counter register. */
1303static __inline__ UInt
1304counter_dw0_offset(void)
1305{
1306 return counter_offset() + 0;
1307}
1308
1309/* Write double word #0 of the counter to the guest state. */
1310static __inline__ void
1311put_counter_dw0(IRExpr *expr)
1312{
1313 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I64);
1314
1315 stmt(IRStmt_Put(counter_dw0_offset(), expr));
1316}
1317
1318/* Read double word #0 of the counter register. */
1319static __inline__ IRExpr *
1320get_counter_dw0(void)
1321{
1322 return IRExpr_Get(counter_dw0_offset(), Ity_I64);
1323}
1324
1325/* Return the guest state offset of word #0 of the counter register. */
1326static __inline__ UInt
1327counter_w0_offset(void)
1328{
1329 return counter_offset() + 0;
1330}
1331
1332/* Return the guest state offset of word #1 of the counter register. */
1333static __inline__ UInt
1334counter_w1_offset(void)
1335{
1336 return counter_offset() + 4;
1337}
1338
1339/* Write word #0 of the counter to the guest state. */
1340static __inline__ void
1341put_counter_w0(IRExpr *expr)
1342{
1343 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1344
1345 stmt(IRStmt_Put(counter_w0_offset(), expr));
1346}
1347
1348/* Read word #0 of the counter register. */
1349static __inline__ IRExpr *
1350get_counter_w0(void)
1351{
1352 return IRExpr_Get(counter_w0_offset(), Ity_I32);
1353}
1354
1355/* Write word #1 of the counter to the guest state. */
1356static __inline__ void
1357put_counter_w1(IRExpr *expr)
1358{
1359 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1360
1361 stmt(IRStmt_Put(counter_w1_offset(), expr));
1362}
1363
1364/* Read word #1 of the counter register. */
1365static __inline__ IRExpr *
1366get_counter_w1(void)
1367{
1368 return IRExpr_Get(counter_w1_offset(), Ity_I32);
1369}
1370
1371/* Return the guest state offset of the fpc register. */
1372static UInt
1373fpc_offset(void)
1374{
floriane88b3c92011-07-05 02:48:39 +00001375 return S390X_GUEST_OFFSET(guest_fpc);
sewardj2019a972011-03-07 16:04:07 +00001376}
1377
1378/* Return the guest state offset of word #0 of the fpc register. */
1379static __inline__ UInt
1380fpc_w0_offset(void)
1381{
1382 return fpc_offset() + 0;
1383}
1384
1385/* Write word #0 of the fpc to the guest state. */
1386static __inline__ void
1387put_fpc_w0(IRExpr *expr)
1388{
1389 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1390
1391 stmt(IRStmt_Put(fpc_w0_offset(), expr));
1392}
1393
1394/* Read word #0 of the fpc register. */
1395static __inline__ IRExpr *
1396get_fpc_w0(void)
1397{
1398 return IRExpr_Get(fpc_w0_offset(), Ity_I32);
1399}
1400
1401
1402/*------------------------------------------------------------*/
1403/*--- Build IR for formats ---*/
1404/*------------------------------------------------------------*/
1405static void
1406s390_format_I(HChar *(*irgen)(UChar i),
1407 UChar i)
1408{
1409 HChar *mnm = irgen(i);
1410
sewardj7ee97522011-05-09 21:45:04 +00001411 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001412 s390_disasm(ENC2(MNM, UINT), mnm, i);
1413}
1414
1415static void
1416s390_format_RI(HChar *(*irgen)(UChar r1, UShort i2),
1417 UChar r1, UShort i2)
1418{
1419 irgen(r1, i2);
1420}
1421
1422static void
1423s390_format_RI_RU(HChar *(*irgen)(UChar r1, UShort i2),
1424 UChar r1, UShort i2)
1425{
1426 HChar *mnm = irgen(r1, i2);
1427
sewardj7ee97522011-05-09 21:45:04 +00001428 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001429 s390_disasm(ENC3(MNM, GPR, UINT), mnm, r1, i2);
1430}
1431
1432static void
1433s390_format_RI_RI(HChar *(*irgen)(UChar r1, UShort i2),
1434 UChar r1, UShort i2)
1435{
1436 HChar *mnm = irgen(r1, i2);
1437
sewardj7ee97522011-05-09 21:45:04 +00001438 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001439 s390_disasm(ENC3(MNM, GPR, INT), mnm, r1, (Int)(Short)i2);
1440}
1441
1442static void
1443s390_format_RI_RP(HChar *(*irgen)(UChar r1, UShort i2),
1444 UChar r1, UShort i2)
1445{
1446 HChar *mnm = irgen(r1, i2);
1447
sewardj7ee97522011-05-09 21:45:04 +00001448 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001449 s390_disasm(ENC3(MNM, GPR, PCREL), mnm, r1, (Int)(Short)i2);
1450}
1451
1452static void
1453s390_format_RIE_RRP(HChar *(*irgen)(UChar r1, UChar r3, UShort i2),
1454 UChar r1, UChar r3, UShort i2)
1455{
1456 HChar *mnm = irgen(r1, r3, i2);
1457
sewardj7ee97522011-05-09 21:45:04 +00001458 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001459 s390_disasm(ENC4(MNM, GPR, GPR, PCREL), mnm, r1, r3, (Int)(Short)i2);
1460}
1461
1462static void
1463s390_format_RIE_RRI0(HChar *(*irgen)(UChar r1, UChar r3, UShort i2),
1464 UChar r1, UChar r3, UShort i2)
1465{
1466 HChar *mnm = irgen(r1, r3, i2);
1467
sewardj7ee97522011-05-09 21:45:04 +00001468 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001469 s390_disasm(ENC4(MNM, GPR, GPR, INT), mnm, r1, r3, (Int)(Short)i2);
1470}
1471
1472static void
1473s390_format_RIE_RRUUU(HChar *(*irgen)(UChar r1, UChar r2, UChar i3, UChar i4,
1474 UChar i5),
1475 UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
1476{
1477 HChar *mnm = irgen(r1, r2, i3, i4, i5);
1478
sewardj7ee97522011-05-09 21:45:04 +00001479 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001480 s390_disasm(ENC6(MNM, GPR, GPR, UINT, UINT, UINT), mnm, r1, r2, i3, i4,
1481 i5);
1482}
1483
1484static void
1485s390_format_RIE_RRPU(HChar *(*irgen)(UChar r1, UChar r2, UShort i4, UChar m3),
1486 UChar r1, UChar r2, UShort i4, UChar m3)
1487{
1488 HChar *mnm = irgen(r1, r2, i4, m3);
1489
sewardj7ee97522011-05-09 21:45:04 +00001490 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001491 s390_disasm(ENC5(XMNM, GPR, GPR, CABM, PCREL), S390_XMNM_CAB, mnm, m3, r1,
1492 r2, m3, (Int)(Short)i4);
1493}
1494
1495static void
1496s390_format_RIE_RUPU(HChar *(*irgen)(UChar r1, UChar m3, UShort i4, UChar i2),
1497 UChar r1, UChar m3, UShort i4, UChar i2)
1498{
1499 HChar *mnm = irgen(r1, m3, i4, i2);
1500
sewardj7ee97522011-05-09 21:45:04 +00001501 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001502 s390_disasm(ENC5(XMNM, GPR, UINT, CABM, PCREL), S390_XMNM_CAB, mnm, m3,
1503 r1, i2, m3, (Int)(Short)i4);
1504}
1505
1506static void
1507s390_format_RIE_RUPI(HChar *(*irgen)(UChar r1, UChar m3, UShort i4, UChar i2),
1508 UChar r1, UChar m3, UShort i4, UChar i2)
1509{
1510 HChar *mnm = irgen(r1, m3, i4, i2);
1511
sewardj7ee97522011-05-09 21:45:04 +00001512 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001513 s390_disasm(ENC5(XMNM, GPR, INT, CABM, PCREL), S390_XMNM_CAB, mnm, m3, r1,
1514 (Int)(Char)i2, m3, (Int)(Short)i4);
1515}
1516
1517static void
1518s390_format_RIL(HChar *(*irgen)(UChar r1, UInt i2),
1519 UChar r1, UInt i2)
1520{
1521 irgen(r1, i2);
1522}
1523
1524static void
1525s390_format_RIL_RU(HChar *(*irgen)(UChar r1, UInt i2),
1526 UChar r1, UInt i2)
1527{
1528 HChar *mnm = irgen(r1, i2);
1529
sewardj7ee97522011-05-09 21:45:04 +00001530 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001531 s390_disasm(ENC3(MNM, GPR, UINT), mnm, r1, i2);
1532}
1533
1534static void
1535s390_format_RIL_RI(HChar *(*irgen)(UChar r1, UInt i2),
1536 UChar r1, UInt i2)
1537{
1538 HChar *mnm = irgen(r1, i2);
1539
sewardj7ee97522011-05-09 21:45:04 +00001540 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001541 s390_disasm(ENC3(MNM, GPR, INT), mnm, r1, i2);
1542}
1543
1544static void
1545s390_format_RIL_RP(HChar *(*irgen)(UChar r1, UInt i2),
1546 UChar r1, UInt i2)
1547{
1548 HChar *mnm = irgen(r1, i2);
1549
sewardj7ee97522011-05-09 21:45:04 +00001550 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001551 s390_disasm(ENC3(MNM, GPR, PCREL), mnm, r1, i2);
1552}
1553
1554static void
1555s390_format_RIL_UP(HChar *(*irgen)(void),
1556 UChar r1, UInt i2)
1557{
1558 HChar *mnm = irgen();
1559
sewardj7ee97522011-05-09 21:45:04 +00001560 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001561 s390_disasm(ENC3(MNM, UINT, PCREL), mnm, r1, i2);
1562}
1563
1564static void
1565s390_format_RIS_RURDI(HChar *(*irgen)(UChar r1, UChar m3, UChar i2,
1566 IRTemp op4addr),
1567 UChar r1, UChar m3, UChar b4, UShort d4, UChar i2)
1568{
1569 HChar *mnm;
1570 IRTemp op4addr = newTemp(Ity_I64);
1571
1572 assign(op4addr, binop(Iop_Add64, mkU64(d4), b4 != 0 ? get_gpr_dw0(b4) :
1573 mkU64(0)));
1574
1575 mnm = irgen(r1, m3, i2, op4addr);
1576
sewardj7ee97522011-05-09 21:45:04 +00001577 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001578 s390_disasm(ENC5(XMNM, GPR, INT, CABM, UDXB), S390_XMNM_CAB, mnm, m3, r1,
1579 (Int)(Char)i2, m3, d4, 0, b4);
1580}
1581
1582static void
1583s390_format_RIS_RURDU(HChar *(*irgen)(UChar r1, UChar m3, UChar i2,
1584 IRTemp op4addr),
1585 UChar r1, UChar m3, UChar b4, UShort d4, UChar i2)
1586{
1587 HChar *mnm;
1588 IRTemp op4addr = newTemp(Ity_I64);
1589
1590 assign(op4addr, binop(Iop_Add64, mkU64(d4), b4 != 0 ? get_gpr_dw0(b4) :
1591 mkU64(0)));
1592
1593 mnm = irgen(r1, m3, i2, op4addr);
1594
sewardj7ee97522011-05-09 21:45:04 +00001595 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001596 s390_disasm(ENC5(XMNM, GPR, UINT, CABM, UDXB), S390_XMNM_CAB, mnm, m3, r1,
1597 i2, m3, d4, 0, b4);
1598}
1599
1600static void
1601s390_format_RR(HChar *(*irgen)(UChar r1, UChar r2),
1602 UChar r1, UChar r2)
1603{
1604 irgen(r1, r2);
1605}
1606
1607static void
1608s390_format_RR_RR(HChar *(*irgen)(UChar r1, UChar r2),
1609 UChar r1, UChar r2)
1610{
1611 HChar *mnm = irgen(r1, r2);
1612
sewardj7ee97522011-05-09 21:45:04 +00001613 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001614 s390_disasm(ENC3(MNM, GPR, GPR), mnm, r1, r2);
1615}
1616
1617static void
1618s390_format_RR_FF(HChar *(*irgen)(UChar r1, UChar r2),
1619 UChar r1, UChar r2)
1620{
1621 HChar *mnm = irgen(r1, r2);
1622
sewardj7ee97522011-05-09 21:45:04 +00001623 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001624 s390_disasm(ENC3(MNM, FPR, FPR), mnm, r1, r2);
1625}
1626
1627static void
1628s390_format_RRE(HChar *(*irgen)(UChar r1, UChar r2),
1629 UChar r1, UChar r2)
1630{
1631 irgen(r1, r2);
1632}
1633
1634static void
1635s390_format_RRE_RR(HChar *(*irgen)(UChar r1, UChar r2),
1636 UChar r1, UChar r2)
1637{
1638 HChar *mnm = irgen(r1, r2);
1639
sewardj7ee97522011-05-09 21:45:04 +00001640 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001641 s390_disasm(ENC3(MNM, GPR, GPR), mnm, r1, r2);
1642}
1643
1644static void
1645s390_format_RRE_FF(HChar *(*irgen)(UChar r1, UChar r2),
1646 UChar r1, UChar r2)
1647{
1648 HChar *mnm = irgen(r1, r2);
1649
sewardj7ee97522011-05-09 21:45:04 +00001650 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001651 s390_disasm(ENC3(MNM, FPR, FPR), mnm, r1, r2);
1652}
1653
1654static void
1655s390_format_RRE_RF(HChar *(*irgen)(UChar, UChar),
1656 UChar r1, UChar r2)
1657{
1658 HChar *mnm = irgen(r1, r2);
1659
sewardj7ee97522011-05-09 21:45:04 +00001660 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001661 s390_disasm(ENC3(MNM, GPR, FPR), mnm, r1, r2);
1662}
1663
1664static void
1665s390_format_RRE_FR(HChar *(*irgen)(UChar r1, UChar r2),
1666 UChar r1, UChar r2)
1667{
1668 HChar *mnm = irgen(r1, r2);
1669
sewardj7ee97522011-05-09 21:45:04 +00001670 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001671 s390_disasm(ENC3(MNM, FPR, GPR), mnm, r1, r2);
1672}
1673
1674static void
1675s390_format_RRE_R0(HChar *(*irgen)(UChar r1),
1676 UChar r1)
1677{
1678 HChar *mnm = irgen(r1);
1679
sewardj7ee97522011-05-09 21:45:04 +00001680 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001681 s390_disasm(ENC2(MNM, GPR), mnm, r1);
1682}
1683
1684static void
1685s390_format_RRE_F0(HChar *(*irgen)(UChar r1),
1686 UChar r1)
1687{
1688 HChar *mnm = irgen(r1);
1689
sewardj7ee97522011-05-09 21:45:04 +00001690 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001691 s390_disasm(ENC2(MNM, FPR), mnm, r1);
1692}
1693
1694static void
florian9af37692012-01-15 21:01:16 +00001695s390_format_RRF_M0RERE(HChar *(*irgen)(UChar m3, UChar r1, UChar r2),
1696 UChar m3, UChar r1, UChar r2)
1697{
florianfed3ea32012-07-19 14:54:03 +00001698 HChar *mnm = irgen(m3, r1, r2);
florian9af37692012-01-15 21:01:16 +00001699
1700 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
florianfed3ea32012-07-19 14:54:03 +00001701 s390_disasm(ENC4(MNM, GPR, GPR, UINT), mnm, r1, r2, m3);
florian9af37692012-01-15 21:01:16 +00001702}
1703
1704static void
sewardj2019a972011-03-07 16:04:07 +00001705s390_format_RRF_F0FF(HChar *(*irgen)(UChar, UChar, UChar),
1706 UChar r1, UChar r3, UChar r2)
1707{
1708 HChar *mnm = irgen(r1, r3, r2);
1709
sewardj7ee97522011-05-09 21:45:04 +00001710 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001711 s390_disasm(ENC4(MNM, FPR, FPR, FPR), mnm, r1, r3, r2);
1712}
1713
1714static void
florian1c8f7ff2012-09-01 00:12:11 +00001715s390_format_RRF_UUFR(HChar *(*irgen)(UChar m3, UChar m4, UChar r1, UChar r2),
1716 UChar m3, UChar m4, UChar r1, UChar r2)
1717{
1718 HChar *mnm = irgen(m3, m4, r1, r2);
1719
1720 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
1721 s390_disasm(ENC5(MNM, FPR, UINT, GPR, UINT), mnm, r1, m3, r2, m4);
1722}
1723
1724static void
1725s390_format_RRF_UURF(HChar *(*irgen)(UChar m3, UChar m4, UChar r1, UChar r2),
1726 UChar m3, UChar m4, UChar r1, UChar r2)
1727{
1728 HChar *mnm = irgen(m3, m4, r1, r2);
1729
1730 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
1731 s390_disasm(ENC5(MNM, GPR, UINT, FPR, UINT), mnm, r1, m3, r2, m4);
1732}
1733
1734
1735static void
sewardjd7bde722011-04-05 13:19:33 +00001736s390_format_RRF_U0RR(HChar *(*irgen)(UChar m3, UChar r1, UChar r2),
1737 UChar m3, UChar r1, UChar r2, Int xmnm_kind)
1738{
1739 irgen(m3, r1, r2);
1740
sewardj7ee97522011-05-09 21:45:04 +00001741 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardjd7bde722011-04-05 13:19:33 +00001742 s390_disasm(ENC3(XMNM, GPR, GPR), xmnm_kind, m3, r1, r2);
1743}
1744
1745static void
sewardj2019a972011-03-07 16:04:07 +00001746s390_format_RRF_U0RF(HChar *(*irgen)(UChar r3, UChar r1, UChar r2),
1747 UChar r3, UChar r1, UChar r2)
1748{
1749 HChar *mnm = irgen(r3, r1, r2);
1750
sewardj7ee97522011-05-09 21:45:04 +00001751 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001752 s390_disasm(ENC4(MNM, GPR, UINT, FPR), mnm, r1, r3, r2);
1753}
1754
1755static void
1756s390_format_RRF_F0FF2(HChar *(*irgen)(UChar, UChar, UChar),
1757 UChar r3, UChar r1, UChar r2)
1758{
1759 HChar *mnm = irgen(r3, r1, r2);
1760
sewardj7ee97522011-05-09 21:45:04 +00001761 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001762 s390_disasm(ENC4(MNM, FPR, FPR, FPR), mnm, r1, r3, r2);
1763}
1764
1765static void
1766s390_format_RRF_R0RR2(HChar *(*irgen)(UChar r3, UChar r1, UChar r2),
1767 UChar r3, UChar r1, UChar r2)
1768{
1769 HChar *mnm = irgen(r3, r1, r2);
1770
sewardj7ee97522011-05-09 21:45:04 +00001771 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001772 s390_disasm(ENC4(MNM, GPR, GPR, GPR), mnm, r1, r2, r3);
1773}
1774
1775static void
1776s390_format_RRS(HChar *(*irgen)(UChar r1, UChar r2, UChar m3, IRTemp op4addr),
1777 UChar r1, UChar r2, UChar b4, UShort d4, UChar m3)
1778{
1779 HChar *mnm;
1780 IRTemp op4addr = newTemp(Ity_I64);
1781
1782 assign(op4addr, binop(Iop_Add64, mkU64(d4), b4 != 0 ? get_gpr_dw0(b4) :
1783 mkU64(0)));
1784
1785 mnm = irgen(r1, r2, m3, op4addr);
1786
sewardj7ee97522011-05-09 21:45:04 +00001787 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001788 s390_disasm(ENC5(XMNM, GPR, GPR, CABM, UDXB), S390_XMNM_CAB, mnm, m3, r1,
1789 r2, m3, d4, 0, b4);
1790}
1791
1792static void
1793s390_format_RS_R0RD(HChar *(*irgen)(UChar r1, IRTemp op2addr),
1794 UChar r1, UChar b2, UShort d2)
1795{
1796 HChar *mnm;
1797 IRTemp op2addr = newTemp(Ity_I64);
1798
1799 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
1800 mkU64(0)));
1801
1802 mnm = irgen(r1, op2addr);
1803
sewardj7ee97522011-05-09 21:45:04 +00001804 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001805 s390_disasm(ENC3(MNM, GPR, UDXB), mnm, r1, d2, 0, b2);
1806}
1807
1808static void
1809s390_format_RS_RRRD(HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
1810 UChar r1, UChar r3, UChar b2, UShort d2)
1811{
1812 HChar *mnm;
1813 IRTemp op2addr = newTemp(Ity_I64);
1814
1815 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
1816 mkU64(0)));
1817
1818 mnm = irgen(r1, r3, op2addr);
1819
sewardj7ee97522011-05-09 21:45:04 +00001820 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001821 s390_disasm(ENC4(MNM, GPR, GPR, UDXB), mnm, r1, r3, d2, 0, b2);
1822}
1823
1824static void
1825s390_format_RS_RURD(HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
1826 UChar r1, UChar r3, UChar b2, UShort d2)
1827{
1828 HChar *mnm;
1829 IRTemp op2addr = newTemp(Ity_I64);
1830
1831 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
1832 mkU64(0)));
1833
1834 mnm = irgen(r1, r3, op2addr);
1835
sewardj7ee97522011-05-09 21:45:04 +00001836 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001837 s390_disasm(ENC4(MNM, GPR, UINT, UDXB), mnm, r1, r3, d2, 0, b2);
1838}
1839
1840static void
1841s390_format_RS_AARD(HChar *(*irgen)(UChar, UChar, IRTemp),
1842 UChar r1, UChar r3, UChar b2, UShort d2)
1843{
1844 HChar *mnm;
1845 IRTemp op2addr = newTemp(Ity_I64);
1846
1847 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
1848 mkU64(0)));
1849
1850 mnm = irgen(r1, r3, op2addr);
1851
sewardj7ee97522011-05-09 21:45:04 +00001852 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001853 s390_disasm(ENC4(MNM, AR, AR, UDXB), mnm, r1, r3, d2, 0, b2);
1854}
1855
1856static void
1857s390_format_RSI_RRP(HChar *(*irgen)(UChar r1, UChar r3, UShort i2),
1858 UChar r1, UChar r3, UShort i2)
1859{
1860 HChar *mnm = irgen(r1, r3, i2);
1861
sewardj7ee97522011-05-09 21:45:04 +00001862 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001863 s390_disasm(ENC4(MNM, GPR, GPR, PCREL), mnm, r1, r3, (Int)(Short)i2);
1864}
1865
1866static void
1867s390_format_RSY_RRRD(HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
1868 UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2)
1869{
1870 HChar *mnm;
1871 IRTemp op2addr = newTemp(Ity_I64);
1872 IRTemp d2 = newTemp(Ity_I64);
1873
1874 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
1875 assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
1876 mkU64(0)));
1877
1878 mnm = irgen(r1, r3, op2addr);
1879
sewardj7ee97522011-05-09 21:45:04 +00001880 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001881 s390_disasm(ENC4(MNM, GPR, GPR, SDXB), mnm, r1, r3, dh2, dl2, 0, b2);
1882}
1883
1884static void
1885s390_format_RSY_AARD(HChar *(*irgen)(UChar, UChar, IRTemp),
1886 UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2)
1887{
1888 HChar *mnm;
1889 IRTemp op2addr = newTemp(Ity_I64);
1890 IRTemp d2 = newTemp(Ity_I64);
1891
1892 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
1893 assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
1894 mkU64(0)));
1895
1896 mnm = irgen(r1, r3, op2addr);
1897
sewardj7ee97522011-05-09 21:45:04 +00001898 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001899 s390_disasm(ENC4(MNM, AR, AR, SDXB), mnm, r1, r3, dh2, dl2, 0, b2);
1900}
1901
1902static void
1903s390_format_RSY_RURD(HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
1904 UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2)
1905{
1906 HChar *mnm;
1907 IRTemp op2addr = newTemp(Ity_I64);
1908 IRTemp d2 = newTemp(Ity_I64);
1909
1910 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
1911 assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
1912 mkU64(0)));
1913
1914 mnm = irgen(r1, r3, op2addr);
1915
sewardj7ee97522011-05-09 21:45:04 +00001916 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001917 s390_disasm(ENC4(MNM, GPR, UINT, SDXB), mnm, r1, r3, dh2, dl2, 0, b2);
1918}
1919
1920static void
sewardjd7bde722011-04-05 13:19:33 +00001921s390_format_RSY_RDRM(HChar *(*irgen)(UChar r1, IRTemp op2addr),
1922 UChar r1, UChar m3, UChar b2, UShort dl2, UChar dh2,
1923 Int xmnm_kind)
1924{
1925 IRTemp op2addr = newTemp(Ity_I64);
1926 IRTemp d2 = newTemp(Ity_I64);
1927
florian6820ba52012-07-26 02:01:50 +00001928 next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0)));
1929
sewardjd7bde722011-04-05 13:19:33 +00001930 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
1931 assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
1932 mkU64(0)));
1933
1934 irgen(r1, op2addr);
florian6820ba52012-07-26 02:01:50 +00001935
1936 vassert(dis_res->whatNext == Dis_Continue);
sewardjd7bde722011-04-05 13:19:33 +00001937
sewardj7ee97522011-05-09 21:45:04 +00001938 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardjd7bde722011-04-05 13:19:33 +00001939 s390_disasm(ENC3(XMNM, GPR, SDXB), xmnm_kind, m3, r1, dh2, dl2, 0, b2);
1940}
1941
1942static void
sewardj2019a972011-03-07 16:04:07 +00001943s390_format_RX(HChar *(*irgen)(UChar r1, UChar x2, UChar b2, UShort d2,
1944 IRTemp op2addr),
1945 UChar r1, UChar x2, UChar b2, UShort d2)
1946{
1947 IRTemp op2addr = newTemp(Ity_I64);
1948
1949 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
1950 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
1951 mkU64(0)));
1952
1953 irgen(r1, x2, b2, d2, op2addr);
1954}
1955
1956static void
1957s390_format_RX_RRRD(HChar *(*irgen)(UChar r1, IRTemp op2addr),
1958 UChar r1, UChar x2, UChar b2, UShort d2)
1959{
1960 HChar *mnm;
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 mnm = irgen(r1, op2addr);
1968
sewardj7ee97522011-05-09 21:45:04 +00001969 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001970 s390_disasm(ENC3(MNM, GPR, UDXB), mnm, r1, d2, x2, b2);
1971}
1972
1973static void
1974s390_format_RX_FRRD(HChar *(*irgen)(UChar r1, IRTemp op2addr),
1975 UChar r1, UChar x2, UChar b2, UShort d2)
1976{
1977 HChar *mnm;
1978 IRTemp op2addr = newTemp(Ity_I64);
1979
1980 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
1981 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
1982 mkU64(0)));
1983
1984 mnm = irgen(r1, op2addr);
1985
sewardj7ee97522011-05-09 21:45:04 +00001986 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001987 s390_disasm(ENC3(MNM, FPR, UDXB), mnm, r1, d2, x2, b2);
1988}
1989
1990static void
1991s390_format_RXE_FRRD(HChar *(*irgen)(UChar r1, IRTemp op2addr),
1992 UChar r1, UChar x2, UChar b2, UShort d2)
1993{
1994 HChar *mnm;
1995 IRTemp op2addr = newTemp(Ity_I64);
1996
1997 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
1998 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
1999 mkU64(0)));
2000
2001 mnm = irgen(r1, op2addr);
2002
sewardj7ee97522011-05-09 21:45:04 +00002003 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002004 s390_disasm(ENC3(MNM, FPR, UDXB), mnm, r1, d2, x2, b2);
2005}
2006
2007static void
2008s390_format_RXF_FRRDF(HChar *(*irgen)(UChar, IRTemp, UChar),
2009 UChar r3, UChar x2, UChar b2, UShort d2, UChar r1)
2010{
2011 HChar *mnm;
2012 IRTemp op2addr = newTemp(Ity_I64);
2013
2014 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
2015 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2016 mkU64(0)));
2017
2018 mnm = irgen(r3, op2addr, r1);
2019
sewardj7ee97522011-05-09 21:45:04 +00002020 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002021 s390_disasm(ENC4(MNM, FPR, FPR, UDXB), mnm, r1, r3, d2, x2, b2);
2022}
2023
2024static void
2025s390_format_RXY_RRRD(HChar *(*irgen)(UChar r1, IRTemp op2addr),
2026 UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
2027{
2028 HChar *mnm;
2029 IRTemp op2addr = newTemp(Ity_I64);
2030 IRTemp d2 = newTemp(Ity_I64);
2031
2032 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2033 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkexpr(d2),
2034 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2035 mkU64(0)));
2036
2037 mnm = irgen(r1, op2addr);
2038
sewardj7ee97522011-05-09 21:45:04 +00002039 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002040 s390_disasm(ENC3(MNM, GPR, SDXB), mnm, r1, dh2, dl2, x2, b2);
2041}
2042
2043static void
2044s390_format_RXY_FRRD(HChar *(*irgen)(UChar r1, IRTemp op2addr),
2045 UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
2046{
2047 HChar *mnm;
2048 IRTemp op2addr = newTemp(Ity_I64);
2049 IRTemp d2 = newTemp(Ity_I64);
2050
2051 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2052 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkexpr(d2),
2053 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2054 mkU64(0)));
2055
2056 mnm = irgen(r1, op2addr);
2057
sewardj7ee97522011-05-09 21:45:04 +00002058 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002059 s390_disasm(ENC3(MNM, FPR, SDXB), mnm, r1, dh2, dl2, x2, b2);
2060}
2061
2062static void
2063s390_format_RXY_URRD(HChar *(*irgen)(void),
2064 UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
2065{
2066 HChar *mnm;
2067 IRTemp op2addr = newTemp(Ity_I64);
2068 IRTemp d2 = newTemp(Ity_I64);
2069
2070 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2071 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkexpr(d2),
2072 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2073 mkU64(0)));
2074
2075 mnm = irgen();
2076
sewardj7ee97522011-05-09 21:45:04 +00002077 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002078 s390_disasm(ENC3(MNM, UINT, SDXB), mnm, r1, dh2, dl2, x2, b2);
2079}
2080
2081static void
2082s390_format_S_RD(HChar *(*irgen)(IRTemp op2addr),
2083 UChar b2, UShort d2)
2084{
2085 HChar *mnm;
2086 IRTemp op2addr = newTemp(Ity_I64);
2087
2088 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2089 mkU64(0)));
2090
2091 mnm = irgen(op2addr);
2092
sewardj7ee97522011-05-09 21:45:04 +00002093 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002094 s390_disasm(ENC2(MNM, UDXB), mnm, d2, 0, b2);
2095}
2096
2097static void
2098s390_format_SI_URD(HChar *(*irgen)(UChar i2, IRTemp op1addr),
2099 UChar i2, UChar b1, UShort d1)
2100{
2101 HChar *mnm;
2102 IRTemp op1addr = newTemp(Ity_I64);
2103
2104 assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
2105 mkU64(0)));
2106
2107 mnm = irgen(i2, op1addr);
2108
sewardj7ee97522011-05-09 21:45:04 +00002109 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002110 s390_disasm(ENC3(MNM, UDXB, UINT), mnm, d1, 0, b1, i2);
2111}
2112
2113static void
2114s390_format_SIY_URD(HChar *(*irgen)(UChar i2, IRTemp op1addr),
2115 UChar i2, UChar b1, UShort dl1, UChar dh1)
2116{
2117 HChar *mnm;
2118 IRTemp op1addr = newTemp(Ity_I64);
2119 IRTemp d1 = newTemp(Ity_I64);
2120
2121 assign(d1, mkU64(((ULong)(Long)(Char)dh1 << 12) | ((ULong)dl1)));
2122 assign(op1addr, binop(Iop_Add64, mkexpr(d1), b1 != 0 ? get_gpr_dw0(b1) :
2123 mkU64(0)));
2124
2125 mnm = irgen(i2, op1addr);
2126
sewardj7ee97522011-05-09 21:45:04 +00002127 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002128 s390_disasm(ENC3(MNM, SDXB, UINT), mnm, dh1, dl1, 0, b1, i2);
2129}
2130
2131static void
2132s390_format_SIY_IRD(HChar *(*irgen)(UChar i2, IRTemp op1addr),
2133 UChar i2, UChar b1, UShort dl1, UChar dh1)
2134{
2135 HChar *mnm;
2136 IRTemp op1addr = newTemp(Ity_I64);
2137 IRTemp d1 = newTemp(Ity_I64);
2138
2139 assign(d1, mkU64(((ULong)(Long)(Char)dh1 << 12) | ((ULong)dl1)));
2140 assign(op1addr, binop(Iop_Add64, mkexpr(d1), b1 != 0 ? get_gpr_dw0(b1) :
2141 mkU64(0)));
2142
2143 mnm = irgen(i2, op1addr);
2144
sewardj7ee97522011-05-09 21:45:04 +00002145 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002146 s390_disasm(ENC3(MNM, SDXB, INT), mnm, dh1, dl1, 0, b1, (Int)(Char)i2);
2147}
2148
2149static void
2150s390_format_SS_L0RDRD(HChar *(*irgen)(UChar, IRTemp, IRTemp),
2151 UChar l, UChar b1, UShort d1, UChar b2, UShort d2)
2152{
2153 HChar *mnm;
2154 IRTemp op1addr = newTemp(Ity_I64);
2155 IRTemp op2addr = newTemp(Ity_I64);
2156
2157 assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
2158 mkU64(0)));
2159 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2160 mkU64(0)));
2161
2162 mnm = irgen(l, op1addr, op2addr);
2163
sewardj7ee97522011-05-09 21:45:04 +00002164 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002165 s390_disasm(ENC3(MNM, UDLB, UDXB), mnm, d1, l, b1, d2, 0, b2);
2166}
2167
2168static void
2169s390_format_SIL_RDI(HChar *(*irgen)(UShort i2, IRTemp op1addr),
2170 UChar b1, UShort d1, UShort i2)
2171{
2172 HChar *mnm;
2173 IRTemp op1addr = newTemp(Ity_I64);
2174
2175 assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
2176 mkU64(0)));
2177
2178 mnm = irgen(i2, op1addr);
2179
sewardj7ee97522011-05-09 21:45:04 +00002180 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002181 s390_disasm(ENC3(MNM, UDXB, INT), mnm, d1, 0, b1, (Int)(Short)i2);
2182}
2183
2184static void
2185s390_format_SIL_RDU(HChar *(*irgen)(UShort i2, IRTemp op1addr),
2186 UChar b1, UShort d1, UShort i2)
2187{
2188 HChar *mnm;
2189 IRTemp op1addr = newTemp(Ity_I64);
2190
2191 assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
2192 mkU64(0)));
2193
2194 mnm = irgen(i2, op1addr);
2195
sewardj7ee97522011-05-09 21:45:04 +00002196 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002197 s390_disasm(ENC3(MNM, UDXB, UINT), mnm, d1, 0, b1, i2);
2198}
2199
2200
2201
2202/*------------------------------------------------------------*/
2203/*--- Build IR for opcodes ---*/
2204/*------------------------------------------------------------*/
2205
2206static HChar *
2207s390_irgen_AR(UChar r1, UChar r2)
2208{
2209 IRTemp op1 = newTemp(Ity_I32);
2210 IRTemp op2 = newTemp(Ity_I32);
2211 IRTemp result = newTemp(Ity_I32);
2212
2213 assign(op1, get_gpr_w1(r1));
2214 assign(op2, get_gpr_w1(r2));
2215 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2216 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2217 put_gpr_w1(r1, mkexpr(result));
2218
2219 return "ar";
2220}
2221
2222static HChar *
2223s390_irgen_AGR(UChar r1, UChar r2)
2224{
2225 IRTemp op1 = newTemp(Ity_I64);
2226 IRTemp op2 = newTemp(Ity_I64);
2227 IRTemp result = newTemp(Ity_I64);
2228
2229 assign(op1, get_gpr_dw0(r1));
2230 assign(op2, get_gpr_dw0(r2));
2231 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2232 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
2233 put_gpr_dw0(r1, mkexpr(result));
2234
2235 return "agr";
2236}
2237
2238static HChar *
2239s390_irgen_AGFR(UChar r1, UChar r2)
2240{
2241 IRTemp op1 = newTemp(Ity_I64);
2242 IRTemp op2 = newTemp(Ity_I64);
2243 IRTemp result = newTemp(Ity_I64);
2244
2245 assign(op1, get_gpr_dw0(r1));
2246 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
2247 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2248 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
2249 put_gpr_dw0(r1, mkexpr(result));
2250
2251 return "agfr";
2252}
2253
2254static HChar *
2255s390_irgen_ARK(UChar r3, UChar r1, UChar r2)
2256{
2257 IRTemp op2 = newTemp(Ity_I32);
2258 IRTemp op3 = newTemp(Ity_I32);
2259 IRTemp result = newTemp(Ity_I32);
2260
2261 assign(op2, get_gpr_w1(r2));
2262 assign(op3, get_gpr_w1(r3));
2263 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2264 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
2265 put_gpr_w1(r1, mkexpr(result));
2266
2267 return "ark";
2268}
2269
2270static HChar *
2271s390_irgen_AGRK(UChar r3, UChar r1, UChar r2)
2272{
2273 IRTemp op2 = newTemp(Ity_I64);
2274 IRTemp op3 = newTemp(Ity_I64);
2275 IRTemp result = newTemp(Ity_I64);
2276
2277 assign(op2, get_gpr_dw0(r2));
2278 assign(op3, get_gpr_dw0(r3));
2279 assign(result, binop(Iop_Add64, mkexpr(op2), mkexpr(op3)));
2280 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op2, op3);
2281 put_gpr_dw0(r1, mkexpr(result));
2282
2283 return "agrk";
2284}
2285
2286static HChar *
2287s390_irgen_A(UChar r1, IRTemp op2addr)
2288{
2289 IRTemp op1 = newTemp(Ity_I32);
2290 IRTemp op2 = newTemp(Ity_I32);
2291 IRTemp result = newTemp(Ity_I32);
2292
2293 assign(op1, get_gpr_w1(r1));
2294 assign(op2, load(Ity_I32, mkexpr(op2addr)));
2295 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2296 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2297 put_gpr_w1(r1, mkexpr(result));
2298
2299 return "a";
2300}
2301
2302static HChar *
2303s390_irgen_AY(UChar r1, IRTemp op2addr)
2304{
2305 IRTemp op1 = newTemp(Ity_I32);
2306 IRTemp op2 = newTemp(Ity_I32);
2307 IRTemp result = newTemp(Ity_I32);
2308
2309 assign(op1, get_gpr_w1(r1));
2310 assign(op2, load(Ity_I32, mkexpr(op2addr)));
2311 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2312 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2313 put_gpr_w1(r1, mkexpr(result));
2314
2315 return "ay";
2316}
2317
2318static HChar *
2319s390_irgen_AG(UChar r1, IRTemp op2addr)
2320{
2321 IRTemp op1 = newTemp(Ity_I64);
2322 IRTemp op2 = newTemp(Ity_I64);
2323 IRTemp result = newTemp(Ity_I64);
2324
2325 assign(op1, get_gpr_dw0(r1));
2326 assign(op2, load(Ity_I64, mkexpr(op2addr)));
2327 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2328 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
2329 put_gpr_dw0(r1, mkexpr(result));
2330
2331 return "ag";
2332}
2333
2334static HChar *
2335s390_irgen_AGF(UChar r1, IRTemp op2addr)
2336{
2337 IRTemp op1 = newTemp(Ity_I64);
2338 IRTemp op2 = newTemp(Ity_I64);
2339 IRTemp result = newTemp(Ity_I64);
2340
2341 assign(op1, get_gpr_dw0(r1));
2342 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
2343 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2344 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
2345 put_gpr_dw0(r1, mkexpr(result));
2346
2347 return "agf";
2348}
2349
2350static HChar *
2351s390_irgen_AFI(UChar r1, UInt i2)
2352{
2353 IRTemp op1 = newTemp(Ity_I32);
2354 Int op2;
2355 IRTemp result = newTemp(Ity_I32);
2356
2357 assign(op1, get_gpr_w1(r1));
2358 op2 = (Int)i2;
2359 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
2360 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
2361 mkU32((UInt)op2)));
2362 put_gpr_w1(r1, mkexpr(result));
2363
2364 return "afi";
2365}
2366
2367static HChar *
2368s390_irgen_AGFI(UChar r1, UInt i2)
2369{
2370 IRTemp op1 = newTemp(Ity_I64);
2371 Long op2;
2372 IRTemp result = newTemp(Ity_I64);
2373
2374 assign(op1, get_gpr_dw0(r1));
2375 op2 = (Long)(Int)i2;
2376 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64((ULong)op2)));
2377 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, mktemp(Ity_I64,
2378 mkU64((ULong)op2)));
2379 put_gpr_dw0(r1, mkexpr(result));
2380
2381 return "agfi";
2382}
2383
2384static HChar *
2385s390_irgen_AHIK(UChar r1, UChar r3, UShort i2)
2386{
2387 Int op2;
2388 IRTemp op3 = newTemp(Ity_I32);
2389 IRTemp result = newTemp(Ity_I32);
2390
2391 op2 = (Int)(Short)i2;
2392 assign(op3, get_gpr_w1(r3));
2393 assign(result, binop(Iop_Add32, mkU32((UInt)op2), mkexpr(op3)));
2394 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, mktemp(Ity_I32, mkU32((UInt)
2395 op2)), op3);
2396 put_gpr_w1(r1, mkexpr(result));
2397
2398 return "ahik";
2399}
2400
2401static HChar *
2402s390_irgen_AGHIK(UChar r1, UChar r3, UShort i2)
2403{
2404 Long op2;
2405 IRTemp op3 = newTemp(Ity_I64);
2406 IRTemp result = newTemp(Ity_I64);
2407
2408 op2 = (Long)(Short)i2;
2409 assign(op3, get_gpr_dw0(r3));
2410 assign(result, binop(Iop_Add64, mkU64((ULong)op2), mkexpr(op3)));
2411 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, mktemp(Ity_I64, mkU64((ULong)
2412 op2)), op3);
2413 put_gpr_dw0(r1, mkexpr(result));
2414
2415 return "aghik";
2416}
2417
2418static HChar *
2419s390_irgen_ASI(UChar i2, IRTemp op1addr)
2420{
2421 IRTemp op1 = newTemp(Ity_I32);
2422 Int op2;
2423 IRTemp result = newTemp(Ity_I32);
2424
2425 assign(op1, load(Ity_I32, mkexpr(op1addr)));
2426 op2 = (Int)(Char)i2;
2427 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
2428 store(mkexpr(op1addr), mkexpr(result));
2429 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
2430 mkU32((UInt)op2)));
2431
2432 return "asi";
2433}
2434
2435static HChar *
2436s390_irgen_AGSI(UChar i2, IRTemp op1addr)
2437{
2438 IRTemp op1 = newTemp(Ity_I64);
2439 Long op2;
2440 IRTemp result = newTemp(Ity_I64);
2441
2442 assign(op1, load(Ity_I64, mkexpr(op1addr)));
2443 op2 = (Long)(Char)i2;
2444 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64((ULong)op2)));
2445 store(mkexpr(op1addr), mkexpr(result));
2446 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, mktemp(Ity_I64,
2447 mkU64((ULong)op2)));
2448
2449 return "agsi";
2450}
2451
2452static HChar *
2453s390_irgen_AH(UChar r1, IRTemp op2addr)
2454{
2455 IRTemp op1 = newTemp(Ity_I32);
2456 IRTemp op2 = newTemp(Ity_I32);
2457 IRTemp result = newTemp(Ity_I32);
2458
2459 assign(op1, get_gpr_w1(r1));
2460 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
2461 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2462 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2463 put_gpr_w1(r1, mkexpr(result));
2464
2465 return "ah";
2466}
2467
2468static HChar *
2469s390_irgen_AHY(UChar r1, IRTemp op2addr)
2470{
2471 IRTemp op1 = newTemp(Ity_I32);
2472 IRTemp op2 = newTemp(Ity_I32);
2473 IRTemp result = newTemp(Ity_I32);
2474
2475 assign(op1, get_gpr_w1(r1));
2476 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
2477 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2478 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2479 put_gpr_w1(r1, mkexpr(result));
2480
2481 return "ahy";
2482}
2483
2484static HChar *
2485s390_irgen_AHI(UChar r1, UShort i2)
2486{
2487 IRTemp op1 = newTemp(Ity_I32);
2488 Int op2;
2489 IRTemp result = newTemp(Ity_I32);
2490
2491 assign(op1, get_gpr_w1(r1));
2492 op2 = (Int)(Short)i2;
2493 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
2494 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
2495 mkU32((UInt)op2)));
2496 put_gpr_w1(r1, mkexpr(result));
2497
2498 return "ahi";
2499}
2500
2501static HChar *
2502s390_irgen_AGHI(UChar r1, UShort i2)
2503{
2504 IRTemp op1 = newTemp(Ity_I64);
2505 Long op2;
2506 IRTemp result = newTemp(Ity_I64);
2507
2508 assign(op1, get_gpr_dw0(r1));
2509 op2 = (Long)(Short)i2;
2510 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64((ULong)op2)));
2511 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, mktemp(Ity_I64,
2512 mkU64((ULong)op2)));
2513 put_gpr_dw0(r1, mkexpr(result));
2514
2515 return "aghi";
2516}
2517
2518static HChar *
2519s390_irgen_AHHHR(UChar r3, UChar r1, UChar r2)
2520{
2521 IRTemp op2 = newTemp(Ity_I32);
2522 IRTemp op3 = newTemp(Ity_I32);
2523 IRTemp result = newTemp(Ity_I32);
2524
2525 assign(op2, get_gpr_w0(r2));
2526 assign(op3, get_gpr_w0(r3));
2527 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2528 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
2529 put_gpr_w0(r1, mkexpr(result));
2530
2531 return "ahhhr";
2532}
2533
2534static HChar *
2535s390_irgen_AHHLR(UChar r3, UChar r1, UChar r2)
2536{
2537 IRTemp op2 = newTemp(Ity_I32);
2538 IRTemp op3 = newTemp(Ity_I32);
2539 IRTemp result = newTemp(Ity_I32);
2540
2541 assign(op2, get_gpr_w0(r2));
2542 assign(op3, get_gpr_w1(r3));
2543 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2544 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
2545 put_gpr_w0(r1, mkexpr(result));
2546
2547 return "ahhlr";
2548}
2549
2550static HChar *
2551s390_irgen_AIH(UChar r1, UInt i2)
2552{
2553 IRTemp op1 = newTemp(Ity_I32);
2554 Int op2;
2555 IRTemp result = newTemp(Ity_I32);
2556
2557 assign(op1, get_gpr_w0(r1));
2558 op2 = (Int)i2;
2559 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
2560 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
2561 mkU32((UInt)op2)));
2562 put_gpr_w0(r1, mkexpr(result));
2563
2564 return "aih";
2565}
2566
2567static HChar *
2568s390_irgen_ALR(UChar r1, UChar r2)
2569{
2570 IRTemp op1 = newTemp(Ity_I32);
2571 IRTemp op2 = newTemp(Ity_I32);
2572 IRTemp result = newTemp(Ity_I32);
2573
2574 assign(op1, get_gpr_w1(r1));
2575 assign(op2, get_gpr_w1(r2));
2576 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2577 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, op2);
2578 put_gpr_w1(r1, mkexpr(result));
2579
2580 return "alr";
2581}
2582
2583static HChar *
2584s390_irgen_ALGR(UChar r1, UChar r2)
2585{
2586 IRTemp op1 = newTemp(Ity_I64);
2587 IRTemp op2 = newTemp(Ity_I64);
2588 IRTemp result = newTemp(Ity_I64);
2589
2590 assign(op1, get_gpr_dw0(r1));
2591 assign(op2, get_gpr_dw0(r2));
2592 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2593 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
2594 put_gpr_dw0(r1, mkexpr(result));
2595
2596 return "algr";
2597}
2598
2599static HChar *
2600s390_irgen_ALGFR(UChar r1, UChar r2)
2601{
2602 IRTemp op1 = newTemp(Ity_I64);
2603 IRTemp op2 = newTemp(Ity_I64);
2604 IRTemp result = newTemp(Ity_I64);
2605
2606 assign(op1, get_gpr_dw0(r1));
2607 assign(op2, unop(Iop_32Uto64, get_gpr_w1(r2)));
2608 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2609 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
2610 put_gpr_dw0(r1, mkexpr(result));
2611
2612 return "algfr";
2613}
2614
2615static HChar *
2616s390_irgen_ALRK(UChar r3, UChar r1, UChar r2)
2617{
2618 IRTemp op2 = newTemp(Ity_I32);
2619 IRTemp op3 = newTemp(Ity_I32);
2620 IRTemp result = newTemp(Ity_I32);
2621
2622 assign(op2, get_gpr_w1(r2));
2623 assign(op3, get_gpr_w1(r3));
2624 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2625 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
2626 put_gpr_w1(r1, mkexpr(result));
2627
2628 return "alrk";
2629}
2630
2631static HChar *
2632s390_irgen_ALGRK(UChar r3, UChar r1, UChar r2)
2633{
2634 IRTemp op2 = newTemp(Ity_I64);
2635 IRTemp op3 = newTemp(Ity_I64);
2636 IRTemp result = newTemp(Ity_I64);
2637
2638 assign(op2, get_gpr_dw0(r2));
2639 assign(op3, get_gpr_dw0(r3));
2640 assign(result, binop(Iop_Add64, mkexpr(op2), mkexpr(op3)));
2641 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op2, op3);
2642 put_gpr_dw0(r1, mkexpr(result));
2643
2644 return "algrk";
2645}
2646
2647static HChar *
2648s390_irgen_AL(UChar r1, IRTemp op2addr)
2649{
2650 IRTemp op1 = newTemp(Ity_I32);
2651 IRTemp op2 = newTemp(Ity_I32);
2652 IRTemp result = newTemp(Ity_I32);
2653
2654 assign(op1, get_gpr_w1(r1));
2655 assign(op2, load(Ity_I32, mkexpr(op2addr)));
2656 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2657 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, op2);
2658 put_gpr_w1(r1, mkexpr(result));
2659
2660 return "al";
2661}
2662
2663static HChar *
2664s390_irgen_ALY(UChar r1, IRTemp op2addr)
2665{
2666 IRTemp op1 = newTemp(Ity_I32);
2667 IRTemp op2 = newTemp(Ity_I32);
2668 IRTemp result = newTemp(Ity_I32);
2669
2670 assign(op1, get_gpr_w1(r1));
2671 assign(op2, load(Ity_I32, mkexpr(op2addr)));
2672 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2673 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, op2);
2674 put_gpr_w1(r1, mkexpr(result));
2675
2676 return "aly";
2677}
2678
2679static HChar *
2680s390_irgen_ALG(UChar r1, IRTemp op2addr)
2681{
2682 IRTemp op1 = newTemp(Ity_I64);
2683 IRTemp op2 = newTemp(Ity_I64);
2684 IRTemp result = newTemp(Ity_I64);
2685
2686 assign(op1, get_gpr_dw0(r1));
2687 assign(op2, load(Ity_I64, mkexpr(op2addr)));
2688 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2689 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
2690 put_gpr_dw0(r1, mkexpr(result));
2691
2692 return "alg";
2693}
2694
2695static HChar *
2696s390_irgen_ALGF(UChar r1, IRTemp op2addr)
2697{
2698 IRTemp op1 = newTemp(Ity_I64);
2699 IRTemp op2 = newTemp(Ity_I64);
2700 IRTemp result = newTemp(Ity_I64);
2701
2702 assign(op1, get_gpr_dw0(r1));
2703 assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
2704 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2705 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
2706 put_gpr_dw0(r1, mkexpr(result));
2707
2708 return "algf";
2709}
2710
2711static HChar *
2712s390_irgen_ALFI(UChar r1, UInt i2)
2713{
2714 IRTemp op1 = newTemp(Ity_I32);
2715 UInt op2;
2716 IRTemp result = newTemp(Ity_I32);
2717
2718 assign(op1, get_gpr_w1(r1));
2719 op2 = i2;
2720 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
2721 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, mktemp(Ity_I32,
2722 mkU32(op2)));
2723 put_gpr_w1(r1, mkexpr(result));
2724
2725 return "alfi";
2726}
2727
2728static HChar *
2729s390_irgen_ALGFI(UChar r1, UInt i2)
2730{
2731 IRTemp op1 = newTemp(Ity_I64);
2732 ULong op2;
2733 IRTemp result = newTemp(Ity_I64);
2734
2735 assign(op1, get_gpr_dw0(r1));
2736 op2 = (ULong)i2;
2737 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64(op2)));
2738 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, mktemp(Ity_I64,
2739 mkU64(op2)));
2740 put_gpr_dw0(r1, mkexpr(result));
2741
2742 return "algfi";
2743}
2744
2745static HChar *
2746s390_irgen_ALHHHR(UChar r3, UChar r1, UChar r2)
2747{
2748 IRTemp op2 = newTemp(Ity_I32);
2749 IRTemp op3 = newTemp(Ity_I32);
2750 IRTemp result = newTemp(Ity_I32);
2751
2752 assign(op2, get_gpr_w0(r2));
2753 assign(op3, get_gpr_w0(r3));
2754 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2755 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
2756 put_gpr_w0(r1, mkexpr(result));
2757
2758 return "alhhhr";
2759}
2760
2761static HChar *
2762s390_irgen_ALHHLR(UChar r3, UChar r1, UChar r2)
2763{
2764 IRTemp op2 = newTemp(Ity_I32);
2765 IRTemp op3 = newTemp(Ity_I32);
2766 IRTemp result = newTemp(Ity_I32);
2767
2768 assign(op2, get_gpr_w0(r2));
2769 assign(op3, get_gpr_w1(r3));
2770 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2771 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
2772 put_gpr_w0(r1, mkexpr(result));
2773
2774 return "alhhlr";
2775}
2776
2777static HChar *
2778s390_irgen_ALCR(UChar r1, UChar r2)
2779{
2780 IRTemp op1 = newTemp(Ity_I32);
2781 IRTemp op2 = newTemp(Ity_I32);
2782 IRTemp result = newTemp(Ity_I32);
2783 IRTemp carry_in = newTemp(Ity_I32);
2784
2785 assign(op1, get_gpr_w1(r1));
2786 assign(op2, get_gpr_w1(r2));
2787 assign(carry_in, binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)));
2788 assign(result, binop(Iop_Add32, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)),
2789 mkexpr(carry_in)));
2790 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_32, op1, op2, carry_in);
2791 put_gpr_w1(r1, mkexpr(result));
2792
2793 return "alcr";
2794}
2795
2796static HChar *
2797s390_irgen_ALCGR(UChar r1, UChar r2)
2798{
2799 IRTemp op1 = newTemp(Ity_I64);
2800 IRTemp op2 = newTemp(Ity_I64);
2801 IRTemp result = newTemp(Ity_I64);
2802 IRTemp carry_in = newTemp(Ity_I64);
2803
2804 assign(op1, get_gpr_dw0(r1));
2805 assign(op2, get_gpr_dw0(r2));
2806 assign(carry_in, unop(Iop_32Uto64, binop(Iop_Shr32, s390_call_calculate_cc(),
2807 mkU8(1))));
2808 assign(result, binop(Iop_Add64, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)),
2809 mkexpr(carry_in)));
2810 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_64, op1, op2, carry_in);
2811 put_gpr_dw0(r1, mkexpr(result));
2812
2813 return "alcgr";
2814}
2815
2816static HChar *
2817s390_irgen_ALC(UChar r1, IRTemp op2addr)
2818{
2819 IRTemp op1 = newTemp(Ity_I32);
2820 IRTemp op2 = newTemp(Ity_I32);
2821 IRTemp result = newTemp(Ity_I32);
2822 IRTemp carry_in = newTemp(Ity_I32);
2823
2824 assign(op1, get_gpr_w1(r1));
2825 assign(op2, load(Ity_I32, mkexpr(op2addr)));
2826 assign(carry_in, binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)));
2827 assign(result, binop(Iop_Add32, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)),
2828 mkexpr(carry_in)));
2829 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_32, op1, op2, carry_in);
2830 put_gpr_w1(r1, mkexpr(result));
2831
2832 return "alc";
2833}
2834
2835static HChar *
2836s390_irgen_ALCG(UChar r1, IRTemp op2addr)
2837{
2838 IRTemp op1 = newTemp(Ity_I64);
2839 IRTemp op2 = newTemp(Ity_I64);
2840 IRTemp result = newTemp(Ity_I64);
2841 IRTemp carry_in = newTemp(Ity_I64);
2842
2843 assign(op1, get_gpr_dw0(r1));
2844 assign(op2, load(Ity_I64, mkexpr(op2addr)));
2845 assign(carry_in, unop(Iop_32Uto64, binop(Iop_Shr32, s390_call_calculate_cc(),
2846 mkU8(1))));
2847 assign(result, binop(Iop_Add64, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)),
2848 mkexpr(carry_in)));
2849 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_64, op1, op2, carry_in);
2850 put_gpr_dw0(r1, mkexpr(result));
2851
2852 return "alcg";
2853}
2854
2855static HChar *
2856s390_irgen_ALSI(UChar i2, IRTemp op1addr)
2857{
2858 IRTemp op1 = newTemp(Ity_I32);
2859 UInt op2;
2860 IRTemp result = newTemp(Ity_I32);
2861
2862 assign(op1, load(Ity_I32, mkexpr(op1addr)));
2863 op2 = (UInt)(Int)(Char)i2;
2864 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
2865 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, mktemp(Ity_I32,
2866 mkU32(op2)));
2867 store(mkexpr(op1addr), mkexpr(result));
2868
2869 return "alsi";
2870}
2871
2872static HChar *
2873s390_irgen_ALGSI(UChar i2, IRTemp op1addr)
2874{
2875 IRTemp op1 = newTemp(Ity_I64);
2876 ULong op2;
2877 IRTemp result = newTemp(Ity_I64);
2878
2879 assign(op1, load(Ity_I64, mkexpr(op1addr)));
2880 op2 = (ULong)(Long)(Char)i2;
2881 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64(op2)));
2882 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, mktemp(Ity_I64,
2883 mkU64(op2)));
2884 store(mkexpr(op1addr), mkexpr(result));
2885
2886 return "algsi";
2887}
2888
2889static HChar *
2890s390_irgen_ALHSIK(UChar r1, UChar r3, UShort i2)
2891{
2892 UInt op2;
2893 IRTemp op3 = newTemp(Ity_I32);
2894 IRTemp result = newTemp(Ity_I32);
2895
2896 op2 = (UInt)(Int)(Short)i2;
2897 assign(op3, get_gpr_w1(r3));
2898 assign(result, binop(Iop_Add32, mkU32(op2), mkexpr(op3)));
2899 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, mktemp(Ity_I32, mkU32(op2)),
2900 op3);
2901 put_gpr_w1(r1, mkexpr(result));
2902
2903 return "alhsik";
2904}
2905
2906static HChar *
2907s390_irgen_ALGHSIK(UChar r1, UChar r3, UShort i2)
2908{
2909 ULong op2;
2910 IRTemp op3 = newTemp(Ity_I64);
2911 IRTemp result = newTemp(Ity_I64);
2912
2913 op2 = (ULong)(Long)(Short)i2;
2914 assign(op3, get_gpr_dw0(r3));
2915 assign(result, binop(Iop_Add64, mkU64(op2), mkexpr(op3)));
2916 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, mktemp(Ity_I64, mkU64(op2)),
2917 op3);
2918 put_gpr_dw0(r1, mkexpr(result));
2919
2920 return "alghsik";
2921}
2922
2923static HChar *
2924s390_irgen_ALSIH(UChar r1, UInt i2)
2925{
2926 IRTemp op1 = newTemp(Ity_I32);
2927 UInt op2;
2928 IRTemp result = newTemp(Ity_I32);
2929
2930 assign(op1, get_gpr_w0(r1));
2931 op2 = i2;
2932 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
2933 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, mktemp(Ity_I32,
2934 mkU32(op2)));
2935 put_gpr_w0(r1, mkexpr(result));
2936
2937 return "alsih";
2938}
2939
2940static HChar *
2941s390_irgen_ALSIHN(UChar r1, UInt i2)
2942{
2943 IRTemp op1 = newTemp(Ity_I32);
2944 UInt op2;
2945 IRTemp result = newTemp(Ity_I32);
2946
2947 assign(op1, get_gpr_w0(r1));
2948 op2 = i2;
2949 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
2950 put_gpr_w0(r1, mkexpr(result));
2951
2952 return "alsihn";
2953}
2954
2955static HChar *
2956s390_irgen_NR(UChar r1, UChar r2)
2957{
2958 IRTemp op1 = newTemp(Ity_I32);
2959 IRTemp op2 = newTemp(Ity_I32);
2960 IRTemp result = newTemp(Ity_I32);
2961
2962 assign(op1, get_gpr_w1(r1));
2963 assign(op2, get_gpr_w1(r2));
2964 assign(result, binop(Iop_And32, mkexpr(op1), mkexpr(op2)));
2965 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
2966 put_gpr_w1(r1, mkexpr(result));
2967
2968 return "nr";
2969}
2970
2971static HChar *
2972s390_irgen_NGR(UChar r1, UChar r2)
2973{
2974 IRTemp op1 = newTemp(Ity_I64);
2975 IRTemp op2 = newTemp(Ity_I64);
2976 IRTemp result = newTemp(Ity_I64);
2977
2978 assign(op1, get_gpr_dw0(r1));
2979 assign(op2, get_gpr_dw0(r2));
2980 assign(result, binop(Iop_And64, mkexpr(op1), mkexpr(op2)));
2981 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
2982 put_gpr_dw0(r1, mkexpr(result));
2983
2984 return "ngr";
2985}
2986
2987static HChar *
2988s390_irgen_NRK(UChar r3, UChar r1, UChar r2)
2989{
2990 IRTemp op2 = newTemp(Ity_I32);
2991 IRTemp op3 = newTemp(Ity_I32);
2992 IRTemp result = newTemp(Ity_I32);
2993
2994 assign(op2, get_gpr_w1(r2));
2995 assign(op3, get_gpr_w1(r3));
2996 assign(result, binop(Iop_And32, mkexpr(op2), mkexpr(op3)));
2997 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
2998 put_gpr_w1(r1, mkexpr(result));
2999
3000 return "nrk";
3001}
3002
3003static HChar *
3004s390_irgen_NGRK(UChar r3, UChar r1, UChar r2)
3005{
3006 IRTemp op2 = newTemp(Ity_I64);
3007 IRTemp op3 = newTemp(Ity_I64);
3008 IRTemp result = newTemp(Ity_I64);
3009
3010 assign(op2, get_gpr_dw0(r2));
3011 assign(op3, get_gpr_dw0(r3));
3012 assign(result, binop(Iop_And64, mkexpr(op2), mkexpr(op3)));
3013 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3014 put_gpr_dw0(r1, mkexpr(result));
3015
3016 return "ngrk";
3017}
3018
3019static HChar *
3020s390_irgen_N(UChar r1, IRTemp op2addr)
3021{
3022 IRTemp op1 = newTemp(Ity_I32);
3023 IRTemp op2 = newTemp(Ity_I32);
3024 IRTemp result = newTemp(Ity_I32);
3025
3026 assign(op1, get_gpr_w1(r1));
3027 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3028 assign(result, binop(Iop_And32, mkexpr(op1), mkexpr(op2)));
3029 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3030 put_gpr_w1(r1, mkexpr(result));
3031
3032 return "n";
3033}
3034
3035static HChar *
3036s390_irgen_NY(UChar r1, IRTemp op2addr)
3037{
3038 IRTemp op1 = newTemp(Ity_I32);
3039 IRTemp op2 = newTemp(Ity_I32);
3040 IRTemp result = newTemp(Ity_I32);
3041
3042 assign(op1, get_gpr_w1(r1));
3043 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3044 assign(result, binop(Iop_And32, mkexpr(op1), mkexpr(op2)));
3045 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3046 put_gpr_w1(r1, mkexpr(result));
3047
3048 return "ny";
3049}
3050
3051static HChar *
3052s390_irgen_NG(UChar r1, IRTemp op2addr)
3053{
3054 IRTemp op1 = newTemp(Ity_I64);
3055 IRTemp op2 = newTemp(Ity_I64);
3056 IRTemp result = newTemp(Ity_I64);
3057
3058 assign(op1, get_gpr_dw0(r1));
3059 assign(op2, load(Ity_I64, mkexpr(op2addr)));
3060 assign(result, binop(Iop_And64, mkexpr(op1), mkexpr(op2)));
3061 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3062 put_gpr_dw0(r1, mkexpr(result));
3063
3064 return "ng";
3065}
3066
3067static HChar *
3068s390_irgen_NI(UChar i2, IRTemp op1addr)
3069{
3070 IRTemp op1 = newTemp(Ity_I8);
3071 UChar op2;
3072 IRTemp result = newTemp(Ity_I8);
3073
3074 assign(op1, load(Ity_I8, mkexpr(op1addr)));
3075 op2 = i2;
3076 assign(result, binop(Iop_And8, mkexpr(op1), mkU8(op2)));
3077 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3078 store(mkexpr(op1addr), mkexpr(result));
3079
3080 return "ni";
3081}
3082
3083static HChar *
3084s390_irgen_NIY(UChar i2, IRTemp op1addr)
3085{
3086 IRTemp op1 = newTemp(Ity_I8);
3087 UChar op2;
3088 IRTemp result = newTemp(Ity_I8);
3089
3090 assign(op1, load(Ity_I8, mkexpr(op1addr)));
3091 op2 = i2;
3092 assign(result, binop(Iop_And8, mkexpr(op1), mkU8(op2)));
3093 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3094 store(mkexpr(op1addr), mkexpr(result));
3095
3096 return "niy";
3097}
3098
3099static HChar *
3100s390_irgen_NIHF(UChar r1, UInt i2)
3101{
3102 IRTemp op1 = newTemp(Ity_I32);
3103 UInt op2;
3104 IRTemp result = newTemp(Ity_I32);
3105
3106 assign(op1, get_gpr_w0(r1));
3107 op2 = i2;
3108 assign(result, binop(Iop_And32, mkexpr(op1), mkU32(op2)));
3109 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3110 put_gpr_w0(r1, mkexpr(result));
3111
3112 return "nihf";
3113}
3114
3115static HChar *
3116s390_irgen_NIHH(UChar r1, UShort i2)
3117{
3118 IRTemp op1 = newTemp(Ity_I16);
3119 UShort op2;
3120 IRTemp result = newTemp(Ity_I16);
3121
3122 assign(op1, get_gpr_hw0(r1));
3123 op2 = i2;
3124 assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
3125 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3126 put_gpr_hw0(r1, mkexpr(result));
3127
3128 return "nihh";
3129}
3130
3131static HChar *
3132s390_irgen_NIHL(UChar r1, UShort i2)
3133{
3134 IRTemp op1 = newTemp(Ity_I16);
3135 UShort op2;
3136 IRTemp result = newTemp(Ity_I16);
3137
3138 assign(op1, get_gpr_hw1(r1));
3139 op2 = i2;
3140 assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
3141 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3142 put_gpr_hw1(r1, mkexpr(result));
3143
3144 return "nihl";
3145}
3146
3147static HChar *
3148s390_irgen_NILF(UChar r1, UInt i2)
3149{
3150 IRTemp op1 = newTemp(Ity_I32);
3151 UInt op2;
3152 IRTemp result = newTemp(Ity_I32);
3153
3154 assign(op1, get_gpr_w1(r1));
3155 op2 = i2;
3156 assign(result, binop(Iop_And32, mkexpr(op1), mkU32(op2)));
3157 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3158 put_gpr_w1(r1, mkexpr(result));
3159
3160 return "nilf";
3161}
3162
3163static HChar *
3164s390_irgen_NILH(UChar r1, UShort i2)
3165{
3166 IRTemp op1 = newTemp(Ity_I16);
3167 UShort op2;
3168 IRTemp result = newTemp(Ity_I16);
3169
3170 assign(op1, get_gpr_hw2(r1));
3171 op2 = i2;
3172 assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
3173 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3174 put_gpr_hw2(r1, mkexpr(result));
3175
3176 return "nilh";
3177}
3178
3179static HChar *
3180s390_irgen_NILL(UChar r1, UShort i2)
3181{
3182 IRTemp op1 = newTemp(Ity_I16);
3183 UShort op2;
3184 IRTemp result = newTemp(Ity_I16);
3185
3186 assign(op1, get_gpr_hw3(r1));
3187 op2 = i2;
3188 assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
3189 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3190 put_gpr_hw3(r1, mkexpr(result));
3191
3192 return "nill";
3193}
3194
3195static HChar *
3196s390_irgen_BASR(UChar r1, UChar r2)
3197{
3198 IRTemp target = newTemp(Ity_I64);
3199
3200 if (r2 == 0) {
3201 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 2ULL));
3202 } else {
3203 if (r1 != r2) {
3204 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 2ULL));
3205 call_function(get_gpr_dw0(r2));
3206 } else {
3207 assign(target, get_gpr_dw0(r2));
3208 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 2ULL));
3209 call_function(mkexpr(target));
3210 }
3211 }
3212
3213 return "basr";
3214}
3215
3216static HChar *
3217s390_irgen_BAS(UChar r1, IRTemp op2addr)
3218{
3219 IRTemp target = newTemp(Ity_I64);
3220
3221 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 4ULL));
3222 assign(target, mkexpr(op2addr));
3223 call_function(mkexpr(target));
3224
3225 return "bas";
3226}
3227
3228static HChar *
3229s390_irgen_BCR(UChar r1, UChar r2)
3230{
3231 IRTemp cond = newTemp(Ity_I32);
3232
sewardja52e37e2011-04-28 18:48:06 +00003233 if (r2 == 0 && (r1 >= 14)) { /* serialization */
3234 stmt(IRStmt_MBE(Imbe_Fence));
3235 }
3236
sewardj2019a972011-03-07 16:04:07 +00003237 if ((r2 == 0) || (r1 == 0)) {
3238 } else {
3239 if (r1 == 15) {
3240 return_from_function(get_gpr_dw0(r2));
3241 } else {
3242 assign(cond, s390_call_calculate_cond(r1));
florianf321da72012-07-21 20:32:57 +00003243 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3244 get_gpr_dw0(r2));
sewardj2019a972011-03-07 16:04:07 +00003245 }
3246 }
sewardj7ee97522011-05-09 21:45:04 +00003247 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00003248 s390_disasm(ENC2(XMNM, GPR), S390_XMNM_BCR, r1, r2);
3249
3250 return "bcr";
3251}
3252
3253static HChar *
3254s390_irgen_BC(UChar r1, UChar x2, UChar b2, UShort d2, IRTemp op2addr)
3255{
3256 IRTemp cond = newTemp(Ity_I32);
3257
3258 if (r1 == 0) {
3259 } else {
3260 if (r1 == 15) {
3261 always_goto(mkexpr(op2addr));
3262 } else {
3263 assign(cond, s390_call_calculate_cond(r1));
florianf321da72012-07-21 20:32:57 +00003264 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3265 mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003266 }
3267 }
sewardj7ee97522011-05-09 21:45:04 +00003268 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00003269 s390_disasm(ENC2(XMNM, UDXB), S390_XMNM_BC, r1, d2, x2, b2);
3270
3271 return "bc";
3272}
3273
3274static HChar *
3275s390_irgen_BCTR(UChar r1, UChar r2)
3276{
3277 put_gpr_w1(r1, binop(Iop_Sub32, get_gpr_w1(r1), mkU32(1)));
3278 if (r2 != 0) {
florianf321da72012-07-21 20:32:57 +00003279 if_condition_goto_computed(binop(Iop_CmpNE32, get_gpr_w1(r1), mkU32(0)),
3280 get_gpr_dw0(r2));
sewardj2019a972011-03-07 16:04:07 +00003281 }
3282
3283 return "bctr";
3284}
3285
3286static HChar *
3287s390_irgen_BCTGR(UChar r1, UChar r2)
3288{
3289 put_gpr_dw0(r1, binop(Iop_Sub64, get_gpr_dw0(r1), mkU64(1)));
3290 if (r2 != 0) {
florianf321da72012-07-21 20:32:57 +00003291 if_condition_goto_computed(binop(Iop_CmpNE64, get_gpr_dw0(r1), mkU64(0)),
3292 get_gpr_dw0(r2));
sewardj2019a972011-03-07 16:04:07 +00003293 }
3294
3295 return "bctgr";
3296}
3297
3298static HChar *
3299s390_irgen_BCT(UChar r1, IRTemp op2addr)
3300{
3301 put_gpr_w1(r1, binop(Iop_Sub32, get_gpr_w1(r1), mkU32(1)));
florianf321da72012-07-21 20:32:57 +00003302 if_condition_goto_computed(binop(Iop_CmpNE32, get_gpr_w1(r1), mkU32(0)),
3303 mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003304
3305 return "bct";
3306}
3307
3308static HChar *
3309s390_irgen_BCTG(UChar r1, IRTemp op2addr)
3310{
3311 put_gpr_dw0(r1, binop(Iop_Sub64, get_gpr_dw0(r1), mkU64(1)));
florianf321da72012-07-21 20:32:57 +00003312 if_condition_goto_computed(binop(Iop_CmpNE64, get_gpr_dw0(r1), mkU64(0)),
3313 mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003314
3315 return "bctg";
3316}
3317
3318static HChar *
3319s390_irgen_BXH(UChar r1, UChar r3, IRTemp op2addr)
3320{
3321 IRTemp value = newTemp(Ity_I32);
3322
3323 assign(value, get_gpr_w1(r3 | 1));
3324 put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
florianf321da72012-07-21 20:32:57 +00003325 if_condition_goto_computed(binop(Iop_CmpLT32S, mkexpr(value),
3326 get_gpr_w1(r1)), mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003327
3328 return "bxh";
3329}
3330
3331static HChar *
3332s390_irgen_BXHG(UChar r1, UChar r3, IRTemp op2addr)
3333{
3334 IRTemp value = newTemp(Ity_I64);
3335
3336 assign(value, get_gpr_dw0(r3 | 1));
3337 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
florianf321da72012-07-21 20:32:57 +00003338 if_condition_goto_computed(binop(Iop_CmpLT64S, mkexpr(value),
3339 get_gpr_dw0(r1)), mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003340
3341 return "bxhg";
3342}
3343
3344static HChar *
3345s390_irgen_BXLE(UChar r1, UChar r3, IRTemp op2addr)
3346{
3347 IRTemp value = newTemp(Ity_I32);
3348
3349 assign(value, get_gpr_w1(r3 | 1));
3350 put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
florianf321da72012-07-21 20:32:57 +00003351 if_condition_goto_computed(binop(Iop_CmpLE32S, get_gpr_w1(r1),
3352 mkexpr(value)), mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003353
3354 return "bxle";
3355}
3356
3357static HChar *
3358s390_irgen_BXLEG(UChar r1, UChar r3, IRTemp op2addr)
3359{
3360 IRTemp value = newTemp(Ity_I64);
3361
3362 assign(value, get_gpr_dw0(r3 | 1));
3363 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
florianf321da72012-07-21 20:32:57 +00003364 if_condition_goto_computed(binop(Iop_CmpLE64S, get_gpr_dw0(r1),
3365 mkexpr(value)), mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003366
3367 return "bxleg";
3368}
3369
3370static HChar *
3371s390_irgen_BRAS(UChar r1, UShort i2)
3372{
3373 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 4ULL));
floriana64c2432011-07-16 02:11:50 +00003374 call_function_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
sewardj2019a972011-03-07 16:04:07 +00003375
3376 return "bras";
3377}
3378
3379static HChar *
3380s390_irgen_BRASL(UChar r1, UInt i2)
3381{
3382 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 6ULL));
floriana64c2432011-07-16 02:11:50 +00003383 call_function_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1));
sewardj2019a972011-03-07 16:04:07 +00003384
3385 return "brasl";
3386}
3387
3388static HChar *
3389s390_irgen_BRC(UChar r1, UShort i2)
3390{
3391 IRTemp cond = newTemp(Ity_I32);
3392
3393 if (r1 == 0) {
3394 } else {
3395 if (r1 == 15) {
floriana64c2432011-07-16 02:11:50 +00003396 always_goto_and_chase(
3397 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
sewardj2019a972011-03-07 16:04:07 +00003398 } else {
3399 assign(cond, s390_call_calculate_cond(r1));
3400 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3401 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3402
3403 }
3404 }
sewardj7ee97522011-05-09 21:45:04 +00003405 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00003406 s390_disasm(ENC2(XMNM, PCREL), S390_XMNM_BRC, r1, (Int)(Short)i2);
3407
3408 return "brc";
3409}
3410
3411static HChar *
3412s390_irgen_BRCL(UChar r1, UInt i2)
3413{
3414 IRTemp cond = newTemp(Ity_I32);
3415
3416 if (r1 == 0) {
3417 } else {
3418 if (r1 == 15) {
floriana64c2432011-07-16 02:11:50 +00003419 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1));
sewardj2019a972011-03-07 16:04:07 +00003420 } else {
3421 assign(cond, s390_call_calculate_cond(r1));
3422 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3423 guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1));
3424 }
3425 }
sewardj7ee97522011-05-09 21:45:04 +00003426 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00003427 s390_disasm(ENC2(XMNM, PCREL), S390_XMNM_BRCL, r1, i2);
3428
3429 return "brcl";
3430}
3431
3432static HChar *
3433s390_irgen_BRCT(UChar r1, UShort i2)
3434{
3435 put_gpr_w1(r1, binop(Iop_Sub32, get_gpr_w1(r1), mkU32(1)));
3436 if_condition_goto(binop(Iop_CmpNE32, get_gpr_w1(r1), mkU32(0)),
3437 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3438
3439 return "brct";
3440}
3441
3442static HChar *
3443s390_irgen_BRCTG(UChar r1, UShort i2)
3444{
3445 put_gpr_dw0(r1, binop(Iop_Sub64, get_gpr_dw0(r1), mkU64(1)));
3446 if_condition_goto(binop(Iop_CmpNE64, get_gpr_dw0(r1), mkU64(0)),
3447 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3448
3449 return "brctg";
3450}
3451
3452static HChar *
3453s390_irgen_BRXH(UChar r1, UChar r3, UShort i2)
3454{
3455 IRTemp value = newTemp(Ity_I32);
3456
3457 assign(value, get_gpr_w1(r3 | 1));
3458 put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
3459 if_condition_goto(binop(Iop_CmpLT32S, mkexpr(value), get_gpr_w1(r1)),
3460 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3461
3462 return "brxh";
3463}
3464
3465static HChar *
3466s390_irgen_BRXHG(UChar r1, UChar r3, UShort i2)
3467{
3468 IRTemp value = newTemp(Ity_I64);
3469
3470 assign(value, get_gpr_dw0(r3 | 1));
3471 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
3472 if_condition_goto(binop(Iop_CmpLT64S, mkexpr(value), get_gpr_dw0(r1)),
3473 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3474
3475 return "brxhg";
3476}
3477
3478static HChar *
3479s390_irgen_BRXLE(UChar r1, UChar r3, UShort i2)
3480{
3481 IRTemp value = newTemp(Ity_I32);
3482
3483 assign(value, get_gpr_w1(r3 | 1));
3484 put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
3485 if_condition_goto(binop(Iop_CmpLE32S, get_gpr_w1(r1), mkexpr(value)),
3486 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3487
3488 return "brxle";
3489}
3490
3491static HChar *
3492s390_irgen_BRXLG(UChar r1, UChar r3, UShort i2)
3493{
3494 IRTemp value = newTemp(Ity_I64);
3495
3496 assign(value, get_gpr_dw0(r3 | 1));
3497 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
3498 if_condition_goto(binop(Iop_CmpLE64S, get_gpr_dw0(r1), mkexpr(value)),
3499 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3500
3501 return "brxlg";
3502}
3503
3504static HChar *
3505s390_irgen_CR(UChar r1, UChar r2)
3506{
3507 IRTemp op1 = newTemp(Ity_I32);
3508 IRTemp op2 = newTemp(Ity_I32);
3509
3510 assign(op1, get_gpr_w1(r1));
3511 assign(op2, get_gpr_w1(r2));
3512 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3513
3514 return "cr";
3515}
3516
3517static HChar *
3518s390_irgen_CGR(UChar r1, UChar r2)
3519{
3520 IRTemp op1 = newTemp(Ity_I64);
3521 IRTemp op2 = newTemp(Ity_I64);
3522
3523 assign(op1, get_gpr_dw0(r1));
3524 assign(op2, get_gpr_dw0(r2));
3525 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3526
3527 return "cgr";
3528}
3529
3530static HChar *
3531s390_irgen_CGFR(UChar r1, UChar r2)
3532{
3533 IRTemp op1 = newTemp(Ity_I64);
3534 IRTemp op2 = newTemp(Ity_I64);
3535
3536 assign(op1, get_gpr_dw0(r1));
3537 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
3538 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3539
3540 return "cgfr";
3541}
3542
3543static HChar *
3544s390_irgen_C(UChar r1, IRTemp op2addr)
3545{
3546 IRTemp op1 = newTemp(Ity_I32);
3547 IRTemp op2 = newTemp(Ity_I32);
3548
3549 assign(op1, get_gpr_w1(r1));
3550 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3551 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3552
3553 return "c";
3554}
3555
3556static HChar *
3557s390_irgen_CY(UChar r1, IRTemp op2addr)
3558{
3559 IRTemp op1 = newTemp(Ity_I32);
3560 IRTemp op2 = newTemp(Ity_I32);
3561
3562 assign(op1, get_gpr_w1(r1));
3563 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3564 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3565
3566 return "cy";
3567}
3568
3569static HChar *
3570s390_irgen_CG(UChar r1, IRTemp op2addr)
3571{
3572 IRTemp op1 = newTemp(Ity_I64);
3573 IRTemp op2 = newTemp(Ity_I64);
3574
3575 assign(op1, get_gpr_dw0(r1));
3576 assign(op2, load(Ity_I64, mkexpr(op2addr)));
3577 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3578
3579 return "cg";
3580}
3581
3582static HChar *
3583s390_irgen_CGF(UChar r1, IRTemp op2addr)
3584{
3585 IRTemp op1 = newTemp(Ity_I64);
3586 IRTemp op2 = newTemp(Ity_I64);
3587
3588 assign(op1, get_gpr_dw0(r1));
3589 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
3590 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3591
3592 return "cgf";
3593}
3594
3595static HChar *
3596s390_irgen_CFI(UChar r1, UInt i2)
3597{
3598 IRTemp op1 = newTemp(Ity_I32);
3599 Int op2;
3600
3601 assign(op1, get_gpr_w1(r1));
3602 op2 = (Int)i2;
3603 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
3604 mkU32((UInt)op2)));
3605
3606 return "cfi";
3607}
3608
3609static HChar *
3610s390_irgen_CGFI(UChar r1, UInt i2)
3611{
3612 IRTemp op1 = newTemp(Ity_I64);
3613 Long op2;
3614
3615 assign(op1, get_gpr_dw0(r1));
3616 op2 = (Long)(Int)i2;
3617 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I64,
3618 mkU64((ULong)op2)));
3619
3620 return "cgfi";
3621}
3622
3623static HChar *
3624s390_irgen_CRL(UChar r1, UInt i2)
3625{
3626 IRTemp op1 = newTemp(Ity_I32);
3627 IRTemp op2 = newTemp(Ity_I32);
3628
3629 assign(op1, get_gpr_w1(r1));
3630 assign(op2, load(Ity_I32, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
3631 i2 << 1))));
3632 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3633
3634 return "crl";
3635}
3636
3637static HChar *
3638s390_irgen_CGRL(UChar r1, UInt i2)
3639{
3640 IRTemp op1 = newTemp(Ity_I64);
3641 IRTemp op2 = newTemp(Ity_I64);
3642
3643 assign(op1, get_gpr_dw0(r1));
3644 assign(op2, load(Ity_I64, 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 "cgrl";
3649}
3650
3651static HChar *
3652s390_irgen_CGFRL(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, unop(Iop_32Sto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
3659 ((ULong)(Long)(Int)i2 << 1)))));
3660 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3661
3662 return "cgfrl";
3663}
3664
3665static HChar *
3666s390_irgen_CRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
3667{
3668 IRTemp op1 = newTemp(Ity_I32);
3669 IRTemp op2 = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00003670 IRTemp cond = newTemp(Ity_I32);
3671
3672 if (m3 == 0) {
3673 } else {
3674 if (m3 == 14) {
3675 always_goto(mkexpr(op4addr));
3676 } else {
3677 assign(op1, get_gpr_w1(r1));
3678 assign(op2, get_gpr_w1(r2));
florianff9613f2012-05-12 15:26:44 +00003679 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
3680 op1, op2));
florianf321da72012-07-21 20:32:57 +00003681 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond),
3682 mkU32(0)), mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00003683 }
3684 }
3685
3686 return "crb";
3687}
3688
3689static HChar *
3690s390_irgen_CGRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
3691{
3692 IRTemp op1 = newTemp(Ity_I64);
3693 IRTemp op2 = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00003694 IRTemp cond = newTemp(Ity_I32);
3695
3696 if (m3 == 0) {
3697 } else {
3698 if (m3 == 14) {
3699 always_goto(mkexpr(op4addr));
3700 } else {
3701 assign(op1, get_gpr_dw0(r1));
3702 assign(op2, get_gpr_dw0(r2));
florianff9613f2012-05-12 15:26:44 +00003703 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
3704 op1, op2));
florianf321da72012-07-21 20:32:57 +00003705 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond),
3706 mkU32(0)), mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00003707 }
3708 }
3709
3710 return "cgrb";
3711}
3712
3713static HChar *
3714s390_irgen_CRJ(UChar r1, UChar r2, UShort i4, UChar m3)
3715{
3716 IRTemp op1 = newTemp(Ity_I32);
3717 IRTemp op2 = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00003718 IRTemp cond = newTemp(Ity_I32);
3719
3720 if (m3 == 0) {
3721 } else {
3722 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00003723 always_goto_and_chase(
3724 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00003725 } else {
3726 assign(op1, get_gpr_w1(r1));
3727 assign(op2, get_gpr_w1(r2));
florianff9613f2012-05-12 15:26:44 +00003728 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
3729 op1, op2));
sewardj2019a972011-03-07 16:04:07 +00003730 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3731 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
3732
3733 }
3734 }
3735
3736 return "crj";
3737}
3738
3739static HChar *
3740s390_irgen_CGRJ(UChar r1, UChar r2, UShort i4, UChar m3)
3741{
3742 IRTemp op1 = newTemp(Ity_I64);
3743 IRTemp op2 = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00003744 IRTemp cond = newTemp(Ity_I32);
3745
3746 if (m3 == 0) {
3747 } else {
3748 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00003749 always_goto_and_chase(
3750 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00003751 } else {
3752 assign(op1, get_gpr_dw0(r1));
3753 assign(op2, get_gpr_dw0(r2));
florianff9613f2012-05-12 15:26:44 +00003754 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
3755 op1, op2));
sewardj2019a972011-03-07 16:04:07 +00003756 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3757 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
3758
3759 }
3760 }
3761
3762 return "cgrj";
3763}
3764
3765static HChar *
3766s390_irgen_CIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
3767{
3768 IRTemp op1 = newTemp(Ity_I32);
3769 Int op2;
sewardj2019a972011-03-07 16:04:07 +00003770 IRTemp cond = newTemp(Ity_I32);
3771
3772 if (m3 == 0) {
3773 } else {
3774 if (m3 == 14) {
3775 always_goto(mkexpr(op4addr));
3776 } else {
3777 assign(op1, get_gpr_w1(r1));
3778 op2 = (Int)(Char)i2;
florianff9613f2012-05-12 15:26:44 +00003779 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
3780 mktemp(Ity_I32, mkU32((UInt)op2))));
florianf321da72012-07-21 20:32:57 +00003781 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3782 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00003783 }
3784 }
3785
3786 return "cib";
3787}
3788
3789static HChar *
3790s390_irgen_CGIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
3791{
3792 IRTemp op1 = newTemp(Ity_I64);
3793 Long op2;
sewardj2019a972011-03-07 16:04:07 +00003794 IRTemp cond = newTemp(Ity_I32);
3795
3796 if (m3 == 0) {
3797 } else {
3798 if (m3 == 14) {
3799 always_goto(mkexpr(op4addr));
3800 } else {
3801 assign(op1, get_gpr_dw0(r1));
3802 op2 = (Long)(Char)i2;
florianff9613f2012-05-12 15:26:44 +00003803 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
3804 mktemp(Ity_I64, mkU64((ULong)op2))));
florianf321da72012-07-21 20:32:57 +00003805 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3806 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00003807 }
3808 }
3809
3810 return "cgib";
3811}
3812
3813static HChar *
3814s390_irgen_CIJ(UChar r1, UChar m3, UShort i4, UChar i2)
3815{
3816 IRTemp op1 = newTemp(Ity_I32);
3817 Int op2;
sewardj2019a972011-03-07 16:04:07 +00003818 IRTemp cond = newTemp(Ity_I32);
3819
3820 if (m3 == 0) {
3821 } else {
3822 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00003823 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00003824 } else {
3825 assign(op1, get_gpr_w1(r1));
3826 op2 = (Int)(Char)i2;
florianff9613f2012-05-12 15:26:44 +00003827 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
3828 mktemp(Ity_I32, mkU32((UInt)op2))));
sewardj2019a972011-03-07 16:04:07 +00003829 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3830 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
3831
3832 }
3833 }
3834
3835 return "cij";
3836}
3837
3838static HChar *
3839s390_irgen_CGIJ(UChar r1, UChar m3, UShort i4, UChar i2)
3840{
3841 IRTemp op1 = newTemp(Ity_I64);
3842 Long op2;
sewardj2019a972011-03-07 16:04:07 +00003843 IRTemp cond = newTemp(Ity_I32);
3844
3845 if (m3 == 0) {
3846 } else {
3847 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00003848 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00003849 } else {
3850 assign(op1, get_gpr_dw0(r1));
3851 op2 = (Long)(Char)i2;
florianff9613f2012-05-12 15:26:44 +00003852 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
3853 mktemp(Ity_I64, mkU64((ULong)op2))));
sewardj2019a972011-03-07 16:04:07 +00003854 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3855 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
3856
3857 }
3858 }
3859
3860 return "cgij";
3861}
3862
3863static HChar *
3864s390_irgen_CH(UChar r1, IRTemp op2addr)
3865{
3866 IRTemp op1 = newTemp(Ity_I32);
3867 IRTemp op2 = newTemp(Ity_I32);
3868
3869 assign(op1, get_gpr_w1(r1));
3870 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
3871 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3872
3873 return "ch";
3874}
3875
3876static HChar *
3877s390_irgen_CHY(UChar r1, IRTemp op2addr)
3878{
3879 IRTemp op1 = newTemp(Ity_I32);
3880 IRTemp op2 = newTemp(Ity_I32);
3881
3882 assign(op1, get_gpr_w1(r1));
3883 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
3884 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3885
3886 return "chy";
3887}
3888
3889static HChar *
3890s390_irgen_CGH(UChar r1, IRTemp op2addr)
3891{
3892 IRTemp op1 = newTemp(Ity_I64);
3893 IRTemp op2 = newTemp(Ity_I64);
3894
3895 assign(op1, get_gpr_dw0(r1));
3896 assign(op2, unop(Iop_16Sto64, load(Ity_I16, mkexpr(op2addr))));
3897 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3898
3899 return "cgh";
3900}
3901
3902static HChar *
3903s390_irgen_CHI(UChar r1, UShort i2)
3904{
3905 IRTemp op1 = newTemp(Ity_I32);
3906 Int op2;
3907
3908 assign(op1, get_gpr_w1(r1));
3909 op2 = (Int)(Short)i2;
3910 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
3911 mkU32((UInt)op2)));
3912
3913 return "chi";
3914}
3915
3916static HChar *
3917s390_irgen_CGHI(UChar r1, UShort i2)
3918{
3919 IRTemp op1 = newTemp(Ity_I64);
3920 Long op2;
3921
3922 assign(op1, get_gpr_dw0(r1));
3923 op2 = (Long)(Short)i2;
3924 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I64,
3925 mkU64((ULong)op2)));
3926
3927 return "cghi";
3928}
3929
3930static HChar *
3931s390_irgen_CHHSI(UShort i2, IRTemp op1addr)
3932{
3933 IRTemp op1 = newTemp(Ity_I16);
3934 Short op2;
3935
3936 assign(op1, load(Ity_I16, mkexpr(op1addr)));
3937 op2 = (Short)i2;
3938 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I16,
3939 mkU16((UShort)op2)));
3940
3941 return "chhsi";
3942}
3943
3944static HChar *
3945s390_irgen_CHSI(UShort i2, IRTemp op1addr)
3946{
3947 IRTemp op1 = newTemp(Ity_I32);
3948 Int op2;
3949
3950 assign(op1, load(Ity_I32, mkexpr(op1addr)));
3951 op2 = (Int)(Short)i2;
3952 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
3953 mkU32((UInt)op2)));
3954
3955 return "chsi";
3956}
3957
3958static HChar *
3959s390_irgen_CGHSI(UShort i2, IRTemp op1addr)
3960{
3961 IRTemp op1 = newTemp(Ity_I64);
3962 Long op2;
3963
3964 assign(op1, load(Ity_I64, mkexpr(op1addr)));
3965 op2 = (Long)(Short)i2;
3966 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I64,
3967 mkU64((ULong)op2)));
3968
3969 return "cghsi";
3970}
3971
3972static HChar *
3973s390_irgen_CHRL(UChar r1, UInt i2)
3974{
3975 IRTemp op1 = newTemp(Ity_I32);
3976 IRTemp op2 = newTemp(Ity_I32);
3977
3978 assign(op1, get_gpr_w1(r1));
3979 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
3980 ((ULong)(Long)(Int)i2 << 1)))));
3981 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3982
3983 return "chrl";
3984}
3985
3986static HChar *
3987s390_irgen_CGHRL(UChar r1, UInt i2)
3988{
3989 IRTemp op1 = newTemp(Ity_I64);
3990 IRTemp op2 = newTemp(Ity_I64);
3991
3992 assign(op1, get_gpr_dw0(r1));
3993 assign(op2, unop(Iop_16Sto64, 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 "cghrl";
3998}
3999
4000static HChar *
4001s390_irgen_CHHR(UChar r1, UChar r2)
4002{
4003 IRTemp op1 = newTemp(Ity_I32);
4004 IRTemp op2 = newTemp(Ity_I32);
4005
4006 assign(op1, get_gpr_w0(r1));
4007 assign(op2, get_gpr_w0(r2));
4008 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4009
4010 return "chhr";
4011}
4012
4013static HChar *
4014s390_irgen_CHLR(UChar r1, UChar r2)
4015{
4016 IRTemp op1 = newTemp(Ity_I32);
4017 IRTemp op2 = newTemp(Ity_I32);
4018
4019 assign(op1, get_gpr_w0(r1));
4020 assign(op2, get_gpr_w1(r2));
4021 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4022
4023 return "chlr";
4024}
4025
4026static HChar *
4027s390_irgen_CHF(UChar r1, IRTemp op2addr)
4028{
4029 IRTemp op1 = newTemp(Ity_I32);
4030 IRTemp op2 = newTemp(Ity_I32);
4031
4032 assign(op1, get_gpr_w0(r1));
4033 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4034 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4035
4036 return "chf";
4037}
4038
4039static HChar *
4040s390_irgen_CIH(UChar r1, UInt i2)
4041{
4042 IRTemp op1 = newTemp(Ity_I32);
4043 Int op2;
4044
4045 assign(op1, get_gpr_w0(r1));
4046 op2 = (Int)i2;
4047 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
4048 mkU32((UInt)op2)));
4049
4050 return "cih";
4051}
4052
4053static HChar *
4054s390_irgen_CLR(UChar r1, UChar r2)
4055{
4056 IRTemp op1 = newTemp(Ity_I32);
4057 IRTemp op2 = newTemp(Ity_I32);
4058
4059 assign(op1, get_gpr_w1(r1));
4060 assign(op2, get_gpr_w1(r2));
4061 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4062
4063 return "clr";
4064}
4065
4066static HChar *
4067s390_irgen_CLGR(UChar r1, UChar r2)
4068{
4069 IRTemp op1 = newTemp(Ity_I64);
4070 IRTemp op2 = newTemp(Ity_I64);
4071
4072 assign(op1, get_gpr_dw0(r1));
4073 assign(op2, get_gpr_dw0(r2));
4074 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4075
4076 return "clgr";
4077}
4078
4079static HChar *
4080s390_irgen_CLGFR(UChar r1, UChar r2)
4081{
4082 IRTemp op1 = newTemp(Ity_I64);
4083 IRTemp op2 = newTemp(Ity_I64);
4084
4085 assign(op1, get_gpr_dw0(r1));
4086 assign(op2, unop(Iop_32Uto64, get_gpr_w1(r2)));
4087 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4088
4089 return "clgfr";
4090}
4091
4092static HChar *
4093s390_irgen_CL(UChar r1, IRTemp op2addr)
4094{
4095 IRTemp op1 = newTemp(Ity_I32);
4096 IRTemp op2 = newTemp(Ity_I32);
4097
4098 assign(op1, get_gpr_w1(r1));
4099 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4100 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4101
4102 return "cl";
4103}
4104
4105static HChar *
4106s390_irgen_CLY(UChar r1, IRTemp op2addr)
4107{
4108 IRTemp op1 = newTemp(Ity_I32);
4109 IRTemp op2 = newTemp(Ity_I32);
4110
4111 assign(op1, get_gpr_w1(r1));
4112 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4113 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4114
4115 return "cly";
4116}
4117
4118static HChar *
4119s390_irgen_CLG(UChar r1, IRTemp op2addr)
4120{
4121 IRTemp op1 = newTemp(Ity_I64);
4122 IRTemp op2 = newTemp(Ity_I64);
4123
4124 assign(op1, get_gpr_dw0(r1));
4125 assign(op2, load(Ity_I64, mkexpr(op2addr)));
4126 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4127
4128 return "clg";
4129}
4130
4131static HChar *
4132s390_irgen_CLGF(UChar r1, IRTemp op2addr)
4133{
4134 IRTemp op1 = newTemp(Ity_I64);
4135 IRTemp op2 = newTemp(Ity_I64);
4136
4137 assign(op1, get_gpr_dw0(r1));
4138 assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
4139 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4140
4141 return "clgf";
4142}
4143
4144static HChar *
4145s390_irgen_CLFI(UChar r1, UInt i2)
4146{
4147 IRTemp op1 = newTemp(Ity_I32);
4148 UInt op2;
4149
4150 assign(op1, get_gpr_w1(r1));
4151 op2 = i2;
4152 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I32,
4153 mkU32(op2)));
4154
4155 return "clfi";
4156}
4157
4158static HChar *
4159s390_irgen_CLGFI(UChar r1, UInt i2)
4160{
4161 IRTemp op1 = newTemp(Ity_I64);
4162 ULong op2;
4163
4164 assign(op1, get_gpr_dw0(r1));
4165 op2 = (ULong)i2;
4166 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I64,
4167 mkU64(op2)));
4168
4169 return "clgfi";
4170}
4171
4172static HChar *
4173s390_irgen_CLI(UChar i2, IRTemp op1addr)
4174{
4175 IRTemp op1 = newTemp(Ity_I8);
4176 UChar op2;
4177
4178 assign(op1, load(Ity_I8, mkexpr(op1addr)));
4179 op2 = i2;
4180 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I8,
4181 mkU8(op2)));
4182
4183 return "cli";
4184}
4185
4186static HChar *
4187s390_irgen_CLIY(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 "cliy";
4198}
4199
4200static HChar *
4201s390_irgen_CLFHSI(UShort i2, IRTemp op1addr)
4202{
4203 IRTemp op1 = newTemp(Ity_I32);
4204 UInt op2;
4205
4206 assign(op1, load(Ity_I32, mkexpr(op1addr)));
4207 op2 = (UInt)i2;
4208 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I32,
4209 mkU32(op2)));
4210
4211 return "clfhsi";
4212}
4213
4214static HChar *
4215s390_irgen_CLGHSI(UShort i2, IRTemp op1addr)
4216{
4217 IRTemp op1 = newTemp(Ity_I64);
4218 ULong op2;
4219
4220 assign(op1, load(Ity_I64, mkexpr(op1addr)));
4221 op2 = (ULong)i2;
4222 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I64,
4223 mkU64(op2)));
4224
4225 return "clghsi";
4226}
4227
4228static HChar *
4229s390_irgen_CLHHSI(UShort i2, IRTemp op1addr)
4230{
4231 IRTemp op1 = newTemp(Ity_I16);
4232 UShort op2;
4233
4234 assign(op1, load(Ity_I16, mkexpr(op1addr)));
4235 op2 = i2;
4236 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I16,
4237 mkU16(op2)));
4238
4239 return "clhhsi";
4240}
4241
4242static HChar *
4243s390_irgen_CLRL(UChar r1, UInt i2)
4244{
4245 IRTemp op1 = newTemp(Ity_I32);
4246 IRTemp op2 = newTemp(Ity_I32);
4247
4248 assign(op1, get_gpr_w1(r1));
4249 assign(op2, load(Ity_I32, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
4250 i2 << 1))));
4251 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4252
4253 return "clrl";
4254}
4255
4256static HChar *
4257s390_irgen_CLGRL(UChar r1, UInt i2)
4258{
4259 IRTemp op1 = newTemp(Ity_I64);
4260 IRTemp op2 = newTemp(Ity_I64);
4261
4262 assign(op1, get_gpr_dw0(r1));
4263 assign(op2, load(Ity_I64, 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 "clgrl";
4268}
4269
4270static HChar *
4271s390_irgen_CLGFRL(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, unop(Iop_32Uto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
4278 ((ULong)(Long)(Int)i2 << 1)))));
4279 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4280
4281 return "clgfrl";
4282}
4283
4284static HChar *
4285s390_irgen_CLHRL(UChar r1, UInt i2)
4286{
4287 IRTemp op1 = newTemp(Ity_I32);
4288 IRTemp op2 = newTemp(Ity_I32);
4289
4290 assign(op1, get_gpr_w1(r1));
4291 assign(op2, unop(Iop_16Uto32, load(Ity_I16, 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 "clhrl";
4296}
4297
4298static HChar *
4299s390_irgen_CLGHRL(UChar r1, UInt i2)
4300{
4301 IRTemp op1 = newTemp(Ity_I64);
4302 IRTemp op2 = newTemp(Ity_I64);
4303
4304 assign(op1, get_gpr_dw0(r1));
4305 assign(op2, unop(Iop_16Uto64, 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 "clghrl";
4310}
4311
4312static HChar *
4313s390_irgen_CLRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
4314{
4315 IRTemp op1 = newTemp(Ity_I32);
4316 IRTemp op2 = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00004317 IRTemp cond = newTemp(Ity_I32);
4318
4319 if (m3 == 0) {
4320 } else {
4321 if (m3 == 14) {
4322 always_goto(mkexpr(op4addr));
4323 } else {
4324 assign(op1, get_gpr_w1(r1));
4325 assign(op2, get_gpr_w1(r2));
florianff9613f2012-05-12 15:26:44 +00004326 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4327 op1, op2));
florianf321da72012-07-21 20:32:57 +00004328 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4329 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004330 }
4331 }
4332
4333 return "clrb";
4334}
4335
4336static HChar *
4337s390_irgen_CLGRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
4338{
4339 IRTemp op1 = newTemp(Ity_I64);
4340 IRTemp op2 = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00004341 IRTemp cond = newTemp(Ity_I32);
4342
4343 if (m3 == 0) {
4344 } else {
4345 if (m3 == 14) {
4346 always_goto(mkexpr(op4addr));
4347 } else {
4348 assign(op1, get_gpr_dw0(r1));
4349 assign(op2, get_gpr_dw0(r2));
florianff9613f2012-05-12 15:26:44 +00004350 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4351 op1, op2));
florianf321da72012-07-21 20:32:57 +00004352 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4353 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004354 }
4355 }
4356
4357 return "clgrb";
4358}
4359
4360static HChar *
4361s390_irgen_CLRJ(UChar r1, UChar r2, UShort i4, UChar m3)
4362{
4363 IRTemp op1 = newTemp(Ity_I32);
4364 IRTemp op2 = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00004365 IRTemp cond = newTemp(Ity_I32);
4366
4367 if (m3 == 0) {
4368 } else {
4369 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004370 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004371 } else {
4372 assign(op1, get_gpr_w1(r1));
4373 assign(op2, get_gpr_w1(r2));
florianff9613f2012-05-12 15:26:44 +00004374 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4375 op1, op2));
sewardj2019a972011-03-07 16:04:07 +00004376 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4377 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4378
4379 }
4380 }
4381
4382 return "clrj";
4383}
4384
4385static HChar *
4386s390_irgen_CLGRJ(UChar r1, UChar r2, UShort i4, UChar m3)
4387{
4388 IRTemp op1 = newTemp(Ity_I64);
4389 IRTemp op2 = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00004390 IRTemp cond = newTemp(Ity_I32);
4391
4392 if (m3 == 0) {
4393 } else {
4394 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004395 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004396 } else {
4397 assign(op1, get_gpr_dw0(r1));
4398 assign(op2, get_gpr_dw0(r2));
florianff9613f2012-05-12 15:26:44 +00004399 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4400 op1, op2));
sewardj2019a972011-03-07 16:04:07 +00004401 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4402 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4403
4404 }
4405 }
4406
4407 return "clgrj";
4408}
4409
4410static HChar *
4411s390_irgen_CLIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
4412{
4413 IRTemp op1 = newTemp(Ity_I32);
4414 UInt op2;
sewardj2019a972011-03-07 16:04:07 +00004415 IRTemp cond = newTemp(Ity_I32);
4416
4417 if (m3 == 0) {
4418 } else {
4419 if (m3 == 14) {
4420 always_goto(mkexpr(op4addr));
4421 } else {
4422 assign(op1, get_gpr_w1(r1));
4423 op2 = (UInt)i2;
florianff9613f2012-05-12 15:26:44 +00004424 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4425 mktemp(Ity_I32, mkU32(op2))));
florianf321da72012-07-21 20:32:57 +00004426 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4427 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004428 }
4429 }
4430
4431 return "clib";
4432}
4433
4434static HChar *
4435s390_irgen_CLGIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
4436{
4437 IRTemp op1 = newTemp(Ity_I64);
4438 ULong op2;
sewardj2019a972011-03-07 16:04:07 +00004439 IRTemp cond = newTemp(Ity_I32);
4440
4441 if (m3 == 0) {
4442 } else {
4443 if (m3 == 14) {
4444 always_goto(mkexpr(op4addr));
4445 } else {
4446 assign(op1, get_gpr_dw0(r1));
4447 op2 = (ULong)i2;
florianff9613f2012-05-12 15:26:44 +00004448 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4449 mktemp(Ity_I64, mkU64(op2))));
florianf321da72012-07-21 20:32:57 +00004450 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4451 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004452 }
4453 }
4454
4455 return "clgib";
4456}
4457
4458static HChar *
4459s390_irgen_CLIJ(UChar r1, UChar m3, UShort i4, UChar i2)
4460{
4461 IRTemp op1 = newTemp(Ity_I32);
4462 UInt op2;
sewardj2019a972011-03-07 16:04:07 +00004463 IRTemp cond = newTemp(Ity_I32);
4464
4465 if (m3 == 0) {
4466 } else {
4467 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004468 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004469 } else {
4470 assign(op1, get_gpr_w1(r1));
4471 op2 = (UInt)i2;
florianff9613f2012-05-12 15:26:44 +00004472 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4473 mktemp(Ity_I32, mkU32(op2))));
sewardj2019a972011-03-07 16:04:07 +00004474 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4475 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4476
4477 }
4478 }
4479
4480 return "clij";
4481}
4482
4483static HChar *
4484s390_irgen_CLGIJ(UChar r1, UChar m3, UShort i4, UChar i2)
4485{
4486 IRTemp op1 = newTemp(Ity_I64);
4487 ULong op2;
sewardj2019a972011-03-07 16:04:07 +00004488 IRTemp cond = newTemp(Ity_I32);
4489
4490 if (m3 == 0) {
4491 } else {
4492 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004493 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004494 } else {
4495 assign(op1, get_gpr_dw0(r1));
4496 op2 = (ULong)i2;
florianff9613f2012-05-12 15:26:44 +00004497 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4498 mktemp(Ity_I64, mkU64(op2))));
sewardj2019a972011-03-07 16:04:07 +00004499 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4500 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4501
4502 }
4503 }
4504
4505 return "clgij";
4506}
4507
4508static HChar *
4509s390_irgen_CLM(UChar r1, UChar r3, IRTemp op2addr)
4510{
4511 IRTemp op1 = newTemp(Ity_I32);
4512 IRTemp op2 = newTemp(Ity_I32);
4513 IRTemp b0 = newTemp(Ity_I32);
4514 IRTemp b1 = newTemp(Ity_I32);
4515 IRTemp b2 = newTemp(Ity_I32);
4516 IRTemp b3 = newTemp(Ity_I32);
4517 IRTemp c0 = newTemp(Ity_I32);
4518 IRTemp c1 = newTemp(Ity_I32);
4519 IRTemp c2 = newTemp(Ity_I32);
4520 IRTemp c3 = newTemp(Ity_I32);
4521 UChar n;
4522
4523 n = 0;
4524 if ((r3 & 8) != 0) {
4525 assign(b0, unop(Iop_8Uto32, get_gpr_b4(r1)));
4526 assign(c0, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
4527 n = n + 1;
4528 } else {
4529 assign(b0, mkU32(0));
4530 assign(c0, mkU32(0));
4531 }
4532 if ((r3 & 4) != 0) {
4533 assign(b1, unop(Iop_8Uto32, get_gpr_b5(r1)));
4534 assign(c1, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4535 mkU64(n)))));
4536 n = n + 1;
4537 } else {
4538 assign(b1, mkU32(0));
4539 assign(c1, mkU32(0));
4540 }
4541 if ((r3 & 2) != 0) {
4542 assign(b2, unop(Iop_8Uto32, get_gpr_b6(r1)));
4543 assign(c2, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4544 mkU64(n)))));
4545 n = n + 1;
4546 } else {
4547 assign(b2, mkU32(0));
4548 assign(c2, mkU32(0));
4549 }
4550 if ((r3 & 1) != 0) {
4551 assign(b3, unop(Iop_8Uto32, get_gpr_b7(r1)));
4552 assign(c3, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4553 mkU64(n)))));
4554 n = n + 1;
4555 } else {
4556 assign(b3, mkU32(0));
4557 assign(c3, mkU32(0));
4558 }
4559 assign(op1, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4560 mkexpr(b0), mkU8(24)), binop(Iop_Shl32, mkexpr(b1), mkU8(16))),
4561 binop(Iop_Shl32, mkexpr(b2), mkU8(8))), mkexpr(b3)));
4562 assign(op2, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4563 mkexpr(c0), mkU8(24)), binop(Iop_Shl32, mkexpr(c1), mkU8(16))),
4564 binop(Iop_Shl32, mkexpr(c2), mkU8(8))), mkexpr(c3)));
4565 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4566
4567 return "clm";
4568}
4569
4570static HChar *
4571s390_irgen_CLMY(UChar r1, UChar r3, IRTemp op2addr)
4572{
4573 IRTemp op1 = newTemp(Ity_I32);
4574 IRTemp op2 = newTemp(Ity_I32);
4575 IRTemp b0 = newTemp(Ity_I32);
4576 IRTemp b1 = newTemp(Ity_I32);
4577 IRTemp b2 = newTemp(Ity_I32);
4578 IRTemp b3 = newTemp(Ity_I32);
4579 IRTemp c0 = newTemp(Ity_I32);
4580 IRTemp c1 = newTemp(Ity_I32);
4581 IRTemp c2 = newTemp(Ity_I32);
4582 IRTemp c3 = newTemp(Ity_I32);
4583 UChar n;
4584
4585 n = 0;
4586 if ((r3 & 8) != 0) {
4587 assign(b0, unop(Iop_8Uto32, get_gpr_b4(r1)));
4588 assign(c0, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
4589 n = n + 1;
4590 } else {
4591 assign(b0, mkU32(0));
4592 assign(c0, mkU32(0));
4593 }
4594 if ((r3 & 4) != 0) {
4595 assign(b1, unop(Iop_8Uto32, get_gpr_b5(r1)));
4596 assign(c1, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4597 mkU64(n)))));
4598 n = n + 1;
4599 } else {
4600 assign(b1, mkU32(0));
4601 assign(c1, mkU32(0));
4602 }
4603 if ((r3 & 2) != 0) {
4604 assign(b2, unop(Iop_8Uto32, get_gpr_b6(r1)));
4605 assign(c2, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4606 mkU64(n)))));
4607 n = n + 1;
4608 } else {
4609 assign(b2, mkU32(0));
4610 assign(c2, mkU32(0));
4611 }
4612 if ((r3 & 1) != 0) {
4613 assign(b3, unop(Iop_8Uto32, get_gpr_b7(r1)));
4614 assign(c3, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4615 mkU64(n)))));
4616 n = n + 1;
4617 } else {
4618 assign(b3, mkU32(0));
4619 assign(c3, mkU32(0));
4620 }
4621 assign(op1, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4622 mkexpr(b0), mkU8(24)), binop(Iop_Shl32, mkexpr(b1), mkU8(16))),
4623 binop(Iop_Shl32, mkexpr(b2), mkU8(8))), mkexpr(b3)));
4624 assign(op2, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4625 mkexpr(c0), mkU8(24)), binop(Iop_Shl32, mkexpr(c1), mkU8(16))),
4626 binop(Iop_Shl32, mkexpr(c2), mkU8(8))), mkexpr(c3)));
4627 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4628
4629 return "clmy";
4630}
4631
4632static HChar *
4633s390_irgen_CLMH(UChar r1, UChar r3, IRTemp op2addr)
4634{
4635 IRTemp op1 = newTemp(Ity_I32);
4636 IRTemp op2 = newTemp(Ity_I32);
4637 IRTemp b0 = newTemp(Ity_I32);
4638 IRTemp b1 = newTemp(Ity_I32);
4639 IRTemp b2 = newTemp(Ity_I32);
4640 IRTemp b3 = newTemp(Ity_I32);
4641 IRTemp c0 = newTemp(Ity_I32);
4642 IRTemp c1 = newTemp(Ity_I32);
4643 IRTemp c2 = newTemp(Ity_I32);
4644 IRTemp c3 = newTemp(Ity_I32);
4645 UChar n;
4646
4647 n = 0;
4648 if ((r3 & 8) != 0) {
4649 assign(b0, unop(Iop_8Uto32, get_gpr_b0(r1)));
4650 assign(c0, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
4651 n = n + 1;
4652 } else {
4653 assign(b0, mkU32(0));
4654 assign(c0, mkU32(0));
4655 }
4656 if ((r3 & 4) != 0) {
4657 assign(b1, unop(Iop_8Uto32, get_gpr_b1(r1)));
4658 assign(c1, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4659 mkU64(n)))));
4660 n = n + 1;
4661 } else {
4662 assign(b1, mkU32(0));
4663 assign(c1, mkU32(0));
4664 }
4665 if ((r3 & 2) != 0) {
4666 assign(b2, unop(Iop_8Uto32, get_gpr_b2(r1)));
4667 assign(c2, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4668 mkU64(n)))));
4669 n = n + 1;
4670 } else {
4671 assign(b2, mkU32(0));
4672 assign(c2, mkU32(0));
4673 }
4674 if ((r3 & 1) != 0) {
4675 assign(b3, unop(Iop_8Uto32, get_gpr_b3(r1)));
4676 assign(c3, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4677 mkU64(n)))));
4678 n = n + 1;
4679 } else {
4680 assign(b3, mkU32(0));
4681 assign(c3, mkU32(0));
4682 }
4683 assign(op1, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4684 mkexpr(b0), mkU8(24)), binop(Iop_Shl32, mkexpr(b1), mkU8(16))),
4685 binop(Iop_Shl32, mkexpr(b2), mkU8(8))), mkexpr(b3)));
4686 assign(op2, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4687 mkexpr(c0), mkU8(24)), binop(Iop_Shl32, mkexpr(c1), mkU8(16))),
4688 binop(Iop_Shl32, mkexpr(c2), mkU8(8))), mkexpr(c3)));
4689 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4690
4691 return "clmh";
4692}
4693
4694static HChar *
4695s390_irgen_CLHHR(UChar r1, UChar r2)
4696{
4697 IRTemp op1 = newTemp(Ity_I32);
4698 IRTemp op2 = newTemp(Ity_I32);
4699
4700 assign(op1, get_gpr_w0(r1));
4701 assign(op2, get_gpr_w0(r2));
4702 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4703
4704 return "clhhr";
4705}
4706
4707static HChar *
4708s390_irgen_CLHLR(UChar r1, UChar r2)
4709{
4710 IRTemp op1 = newTemp(Ity_I32);
4711 IRTemp op2 = newTemp(Ity_I32);
4712
4713 assign(op1, get_gpr_w0(r1));
4714 assign(op2, get_gpr_w1(r2));
4715 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4716
4717 return "clhlr";
4718}
4719
4720static HChar *
4721s390_irgen_CLHF(UChar r1, IRTemp op2addr)
4722{
4723 IRTemp op1 = newTemp(Ity_I32);
4724 IRTemp op2 = newTemp(Ity_I32);
4725
4726 assign(op1, get_gpr_w0(r1));
4727 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4728 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4729
4730 return "clhf";
4731}
4732
4733static HChar *
4734s390_irgen_CLIH(UChar r1, UInt i2)
4735{
4736 IRTemp op1 = newTemp(Ity_I32);
4737 UInt op2;
4738
4739 assign(op1, get_gpr_w0(r1));
4740 op2 = i2;
4741 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I32,
4742 mkU32(op2)));
4743
4744 return "clih";
4745}
4746
4747static HChar *
4748s390_irgen_CPYA(UChar r1, UChar r2)
4749{
4750 put_ar_w0(r1, get_ar_w0(r2));
sewardj7ee97522011-05-09 21:45:04 +00004751 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00004752 s390_disasm(ENC3(MNM, AR, AR), "cpya", r1, r2);
4753
4754 return "cpya";
4755}
4756
4757static HChar *
4758s390_irgen_XR(UChar r1, UChar r2)
4759{
4760 IRTemp op1 = newTemp(Ity_I32);
4761 IRTemp op2 = newTemp(Ity_I32);
4762 IRTemp result = newTemp(Ity_I32);
4763
4764 if (r1 == r2) {
4765 assign(result, mkU32(0));
4766 } else {
4767 assign(op1, get_gpr_w1(r1));
4768 assign(op2, get_gpr_w1(r2));
4769 assign(result, binop(Iop_Xor32, mkexpr(op1), mkexpr(op2)));
4770 }
4771 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4772 put_gpr_w1(r1, mkexpr(result));
4773
4774 return "xr";
4775}
4776
4777static HChar *
4778s390_irgen_XGR(UChar r1, UChar r2)
4779{
4780 IRTemp op1 = newTemp(Ity_I64);
4781 IRTemp op2 = newTemp(Ity_I64);
4782 IRTemp result = newTemp(Ity_I64);
4783
4784 if (r1 == r2) {
4785 assign(result, mkU64(0));
4786 } else {
4787 assign(op1, get_gpr_dw0(r1));
4788 assign(op2, get_gpr_dw0(r2));
4789 assign(result, binop(Iop_Xor64, mkexpr(op1), mkexpr(op2)));
4790 }
4791 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4792 put_gpr_dw0(r1, mkexpr(result));
4793
4794 return "xgr";
4795}
4796
4797static HChar *
4798s390_irgen_XRK(UChar r3, UChar r1, UChar r2)
4799{
4800 IRTemp op2 = newTemp(Ity_I32);
4801 IRTemp op3 = newTemp(Ity_I32);
4802 IRTemp result = newTemp(Ity_I32);
4803
4804 assign(op2, get_gpr_w1(r2));
4805 assign(op3, get_gpr_w1(r3));
4806 assign(result, binop(Iop_Xor32, mkexpr(op2), mkexpr(op3)));
4807 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4808 put_gpr_w1(r1, mkexpr(result));
4809
4810 return "xrk";
4811}
4812
4813static HChar *
4814s390_irgen_XGRK(UChar r3, UChar r1, UChar r2)
4815{
4816 IRTemp op2 = newTemp(Ity_I64);
4817 IRTemp op3 = newTemp(Ity_I64);
4818 IRTemp result = newTemp(Ity_I64);
4819
4820 assign(op2, get_gpr_dw0(r2));
4821 assign(op3, get_gpr_dw0(r3));
4822 assign(result, binop(Iop_Xor64, mkexpr(op2), mkexpr(op3)));
4823 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4824 put_gpr_dw0(r1, mkexpr(result));
4825
4826 return "xgrk";
4827}
4828
4829static HChar *
4830s390_irgen_X(UChar r1, IRTemp op2addr)
4831{
4832 IRTemp op1 = newTemp(Ity_I32);
4833 IRTemp op2 = newTemp(Ity_I32);
4834 IRTemp result = newTemp(Ity_I32);
4835
4836 assign(op1, get_gpr_w1(r1));
4837 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4838 assign(result, binop(Iop_Xor32, mkexpr(op1), mkexpr(op2)));
4839 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4840 put_gpr_w1(r1, mkexpr(result));
4841
4842 return "x";
4843}
4844
4845static HChar *
4846s390_irgen_XY(UChar r1, IRTemp op2addr)
4847{
4848 IRTemp op1 = newTemp(Ity_I32);
4849 IRTemp op2 = newTemp(Ity_I32);
4850 IRTemp result = newTemp(Ity_I32);
4851
4852 assign(op1, get_gpr_w1(r1));
4853 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4854 assign(result, binop(Iop_Xor32, mkexpr(op1), mkexpr(op2)));
4855 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4856 put_gpr_w1(r1, mkexpr(result));
4857
4858 return "xy";
4859}
4860
4861static HChar *
4862s390_irgen_XG(UChar r1, IRTemp op2addr)
4863{
4864 IRTemp op1 = newTemp(Ity_I64);
4865 IRTemp op2 = newTemp(Ity_I64);
4866 IRTemp result = newTemp(Ity_I64);
4867
4868 assign(op1, get_gpr_dw0(r1));
4869 assign(op2, load(Ity_I64, mkexpr(op2addr)));
4870 assign(result, binop(Iop_Xor64, mkexpr(op1), mkexpr(op2)));
4871 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4872 put_gpr_dw0(r1, mkexpr(result));
4873
4874 return "xg";
4875}
4876
4877static HChar *
4878s390_irgen_XI(UChar i2, IRTemp op1addr)
4879{
4880 IRTemp op1 = newTemp(Ity_I8);
4881 UChar op2;
4882 IRTemp result = newTemp(Ity_I8);
4883
4884 assign(op1, load(Ity_I8, mkexpr(op1addr)));
4885 op2 = i2;
4886 assign(result, binop(Iop_Xor8, mkexpr(op1), mkU8(op2)));
4887 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4888 store(mkexpr(op1addr), mkexpr(result));
4889
4890 return "xi";
4891}
4892
4893static HChar *
4894s390_irgen_XIY(UChar i2, IRTemp op1addr)
4895{
4896 IRTemp op1 = newTemp(Ity_I8);
4897 UChar op2;
4898 IRTemp result = newTemp(Ity_I8);
4899
4900 assign(op1, load(Ity_I8, mkexpr(op1addr)));
4901 op2 = i2;
4902 assign(result, binop(Iop_Xor8, mkexpr(op1), mkU8(op2)));
4903 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4904 store(mkexpr(op1addr), mkexpr(result));
4905
4906 return "xiy";
4907}
4908
4909static HChar *
4910s390_irgen_XIHF(UChar r1, UInt i2)
4911{
4912 IRTemp op1 = newTemp(Ity_I32);
4913 UInt op2;
4914 IRTemp result = newTemp(Ity_I32);
4915
4916 assign(op1, get_gpr_w0(r1));
4917 op2 = i2;
4918 assign(result, binop(Iop_Xor32, mkexpr(op1), mkU32(op2)));
4919 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4920 put_gpr_w0(r1, mkexpr(result));
4921
4922 return "xihf";
4923}
4924
4925static HChar *
4926s390_irgen_XILF(UChar r1, UInt i2)
4927{
4928 IRTemp op1 = newTemp(Ity_I32);
4929 UInt op2;
4930 IRTemp result = newTemp(Ity_I32);
4931
4932 assign(op1, get_gpr_w1(r1));
4933 op2 = i2;
4934 assign(result, binop(Iop_Xor32, mkexpr(op1), mkU32(op2)));
4935 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4936 put_gpr_w1(r1, mkexpr(result));
4937
4938 return "xilf";
4939}
4940
4941static HChar *
4942s390_irgen_EAR(UChar r1, UChar r2)
4943{
4944 put_gpr_w1(r1, get_ar_w0(r2));
sewardj7ee97522011-05-09 21:45:04 +00004945 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00004946 s390_disasm(ENC3(MNM, GPR, AR), "ear", r1, r2);
4947
4948 return "ear";
4949}
4950
4951static HChar *
4952s390_irgen_IC(UChar r1, IRTemp op2addr)
4953{
4954 put_gpr_b7(r1, load(Ity_I8, mkexpr(op2addr)));
4955
4956 return "ic";
4957}
4958
4959static HChar *
4960s390_irgen_ICY(UChar r1, IRTemp op2addr)
4961{
4962 put_gpr_b7(r1, load(Ity_I8, mkexpr(op2addr)));
4963
4964 return "icy";
4965}
4966
4967static HChar *
4968s390_irgen_ICM(UChar r1, UChar r3, IRTemp op2addr)
4969{
4970 UChar n;
4971 IRTemp result = newTemp(Ity_I32);
4972 UInt mask;
4973
4974 n = 0;
4975 mask = (UInt)r3;
4976 if ((mask & 8) != 0) {
4977 put_gpr_b4(r1, load(Ity_I8, mkexpr(op2addr)));
4978 n = n + 1;
4979 }
4980 if ((mask & 4) != 0) {
4981 put_gpr_b5(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
4982
4983 n = n + 1;
4984 }
4985 if ((mask & 2) != 0) {
4986 put_gpr_b6(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
4987
4988 n = n + 1;
4989 }
4990 if ((mask & 1) != 0) {
4991 put_gpr_b7(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
4992
4993 n = n + 1;
4994 }
4995 assign(result, get_gpr_w1(r1));
4996 s390_cc_thunk_putZZ(S390_CC_OP_INSERT_CHAR_MASK_32, result, mktemp(Ity_I32,
4997 mkU32(mask)));
4998
4999 return "icm";
5000}
5001
5002static HChar *
5003s390_irgen_ICMY(UChar r1, UChar r3, IRTemp op2addr)
5004{
5005 UChar n;
5006 IRTemp result = newTemp(Ity_I32);
5007 UInt mask;
5008
5009 n = 0;
5010 mask = (UInt)r3;
5011 if ((mask & 8) != 0) {
5012 put_gpr_b4(r1, load(Ity_I8, mkexpr(op2addr)));
5013 n = n + 1;
5014 }
5015 if ((mask & 4) != 0) {
5016 put_gpr_b5(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5017
5018 n = n + 1;
5019 }
5020 if ((mask & 2) != 0) {
5021 put_gpr_b6(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5022
5023 n = n + 1;
5024 }
5025 if ((mask & 1) != 0) {
5026 put_gpr_b7(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5027
5028 n = n + 1;
5029 }
5030 assign(result, get_gpr_w1(r1));
5031 s390_cc_thunk_putZZ(S390_CC_OP_INSERT_CHAR_MASK_32, result, mktemp(Ity_I32,
5032 mkU32(mask)));
5033
5034 return "icmy";
5035}
5036
5037static HChar *
5038s390_irgen_ICMH(UChar r1, UChar r3, IRTemp op2addr)
5039{
5040 UChar n;
5041 IRTemp result = newTemp(Ity_I32);
5042 UInt mask;
5043
5044 n = 0;
5045 mask = (UInt)r3;
5046 if ((mask & 8) != 0) {
5047 put_gpr_b0(r1, load(Ity_I8, mkexpr(op2addr)));
5048 n = n + 1;
5049 }
5050 if ((mask & 4) != 0) {
5051 put_gpr_b1(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5052
5053 n = n + 1;
5054 }
5055 if ((mask & 2) != 0) {
5056 put_gpr_b2(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5057
5058 n = n + 1;
5059 }
5060 if ((mask & 1) != 0) {
5061 put_gpr_b3(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5062
5063 n = n + 1;
5064 }
5065 assign(result, get_gpr_w0(r1));
5066 s390_cc_thunk_putZZ(S390_CC_OP_INSERT_CHAR_MASK_32, result, mktemp(Ity_I32,
5067 mkU32(mask)));
5068
5069 return "icmh";
5070}
5071
5072static HChar *
5073s390_irgen_IIHF(UChar r1, UInt i2)
5074{
5075 put_gpr_w0(r1, mkU32(i2));
5076
5077 return "iihf";
5078}
5079
5080static HChar *
5081s390_irgen_IIHH(UChar r1, UShort i2)
5082{
5083 put_gpr_hw0(r1, mkU16(i2));
5084
5085 return "iihh";
5086}
5087
5088static HChar *
5089s390_irgen_IIHL(UChar r1, UShort i2)
5090{
5091 put_gpr_hw1(r1, mkU16(i2));
5092
5093 return "iihl";
5094}
5095
5096static HChar *
5097s390_irgen_IILF(UChar r1, UInt i2)
5098{
5099 put_gpr_w1(r1, mkU32(i2));
5100
5101 return "iilf";
5102}
5103
5104static HChar *
5105s390_irgen_IILH(UChar r1, UShort i2)
5106{
5107 put_gpr_hw2(r1, mkU16(i2));
5108
5109 return "iilh";
5110}
5111
5112static HChar *
5113s390_irgen_IILL(UChar r1, UShort i2)
5114{
5115 put_gpr_hw3(r1, mkU16(i2));
5116
5117 return "iill";
5118}
5119
5120static HChar *
5121s390_irgen_LR(UChar r1, UChar r2)
5122{
5123 put_gpr_w1(r1, get_gpr_w1(r2));
5124
5125 return "lr";
5126}
5127
5128static HChar *
5129s390_irgen_LGR(UChar r1, UChar r2)
5130{
5131 put_gpr_dw0(r1, get_gpr_dw0(r2));
5132
5133 return "lgr";
5134}
5135
5136static HChar *
5137s390_irgen_LGFR(UChar r1, UChar r2)
5138{
5139 put_gpr_dw0(r1, unop(Iop_32Sto64, get_gpr_w1(r2)));
5140
5141 return "lgfr";
5142}
5143
5144static HChar *
5145s390_irgen_L(UChar r1, IRTemp op2addr)
5146{
5147 put_gpr_w1(r1, load(Ity_I32, mkexpr(op2addr)));
5148
5149 return "l";
5150}
5151
5152static HChar *
5153s390_irgen_LY(UChar r1, IRTemp op2addr)
5154{
5155 put_gpr_w1(r1, load(Ity_I32, mkexpr(op2addr)));
5156
5157 return "ly";
5158}
5159
5160static HChar *
5161s390_irgen_LG(UChar r1, IRTemp op2addr)
5162{
5163 put_gpr_dw0(r1, load(Ity_I64, mkexpr(op2addr)));
5164
5165 return "lg";
5166}
5167
5168static HChar *
5169s390_irgen_LGF(UChar r1, IRTemp op2addr)
5170{
5171 put_gpr_dw0(r1, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
5172
5173 return "lgf";
5174}
5175
5176static HChar *
5177s390_irgen_LGFI(UChar r1, UInt i2)
5178{
5179 put_gpr_dw0(r1, mkU64((ULong)(Long)(Int)i2));
5180
5181 return "lgfi";
5182}
5183
5184static HChar *
5185s390_irgen_LRL(UChar r1, UInt i2)
5186{
5187 put_gpr_w1(r1, load(Ity_I32, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
5188 i2 << 1))));
5189
5190 return "lrl";
5191}
5192
5193static HChar *
5194s390_irgen_LGRL(UChar r1, UInt i2)
5195{
5196 put_gpr_dw0(r1, load(Ity_I64, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
5197 i2 << 1))));
5198
5199 return "lgrl";
5200}
5201
5202static HChar *
5203s390_irgen_LGFRL(UChar r1, UInt i2)
5204{
5205 put_gpr_dw0(r1, unop(Iop_32Sto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
5206 ((ULong)(Long)(Int)i2 << 1)))));
5207
5208 return "lgfrl";
5209}
5210
5211static HChar *
5212s390_irgen_LA(UChar r1, IRTemp op2addr)
5213{
5214 put_gpr_dw0(r1, mkexpr(op2addr));
5215
5216 return "la";
5217}
5218
5219static HChar *
5220s390_irgen_LAY(UChar r1, IRTemp op2addr)
5221{
5222 put_gpr_dw0(r1, mkexpr(op2addr));
5223
5224 return "lay";
5225}
5226
5227static HChar *
5228s390_irgen_LAE(UChar r1, IRTemp op2addr)
5229{
5230 put_gpr_dw0(r1, mkexpr(op2addr));
5231
5232 return "lae";
5233}
5234
5235static HChar *
5236s390_irgen_LAEY(UChar r1, IRTemp op2addr)
5237{
5238 put_gpr_dw0(r1, mkexpr(op2addr));
5239
5240 return "laey";
5241}
5242
5243static HChar *
5244s390_irgen_LARL(UChar r1, UInt i2)
5245{
5246 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)));
5247
5248 return "larl";
5249}
5250
5251static HChar *
5252s390_irgen_LAA(UChar r1, UChar r3, IRTemp op2addr)
5253{
5254 IRTemp op2 = newTemp(Ity_I32);
5255 IRTemp op3 = newTemp(Ity_I32);
5256 IRTemp result = newTemp(Ity_I32);
5257
5258 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5259 assign(op3, get_gpr_w1(r3));
5260 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
5261 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
5262 store(mkexpr(op2addr), mkexpr(result));
5263 put_gpr_w1(r1, mkexpr(op2));
5264
5265 return "laa";
5266}
5267
5268static HChar *
5269s390_irgen_LAAG(UChar r1, UChar r3, IRTemp op2addr)
5270{
5271 IRTemp op2 = newTemp(Ity_I64);
5272 IRTemp op3 = newTemp(Ity_I64);
5273 IRTemp result = newTemp(Ity_I64);
5274
5275 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5276 assign(op3, get_gpr_dw0(r3));
5277 assign(result, binop(Iop_Add64, mkexpr(op2), mkexpr(op3)));
5278 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op2, op3);
5279 store(mkexpr(op2addr), mkexpr(result));
5280 put_gpr_dw0(r1, mkexpr(op2));
5281
5282 return "laag";
5283}
5284
5285static HChar *
5286s390_irgen_LAAL(UChar r1, UChar r3, IRTemp op2addr)
5287{
5288 IRTemp op2 = newTemp(Ity_I32);
5289 IRTemp op3 = newTemp(Ity_I32);
5290 IRTemp result = newTemp(Ity_I32);
5291
5292 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5293 assign(op3, get_gpr_w1(r3));
5294 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
5295 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
5296 store(mkexpr(op2addr), mkexpr(result));
5297 put_gpr_w1(r1, mkexpr(op2));
5298
5299 return "laal";
5300}
5301
5302static HChar *
5303s390_irgen_LAALG(UChar r1, UChar r3, IRTemp op2addr)
5304{
5305 IRTemp op2 = newTemp(Ity_I64);
5306 IRTemp op3 = newTemp(Ity_I64);
5307 IRTemp result = newTemp(Ity_I64);
5308
5309 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5310 assign(op3, get_gpr_dw0(r3));
5311 assign(result, binop(Iop_Add64, mkexpr(op2), mkexpr(op3)));
5312 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op2, op3);
5313 store(mkexpr(op2addr), mkexpr(result));
5314 put_gpr_dw0(r1, mkexpr(op2));
5315
5316 return "laalg";
5317}
5318
5319static HChar *
5320s390_irgen_LAN(UChar r1, UChar r3, IRTemp op2addr)
5321{
5322 IRTemp op2 = newTemp(Ity_I32);
5323 IRTemp op3 = newTemp(Ity_I32);
5324 IRTemp result = newTemp(Ity_I32);
5325
5326 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5327 assign(op3, get_gpr_w1(r3));
5328 assign(result, binop(Iop_And32, mkexpr(op2), mkexpr(op3)));
5329 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5330 store(mkexpr(op2addr), mkexpr(result));
5331 put_gpr_w1(r1, mkexpr(op2));
5332
5333 return "lan";
5334}
5335
5336static HChar *
5337s390_irgen_LANG(UChar r1, UChar r3, IRTemp op2addr)
5338{
5339 IRTemp op2 = newTemp(Ity_I64);
5340 IRTemp op3 = newTemp(Ity_I64);
5341 IRTemp result = newTemp(Ity_I64);
5342
5343 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5344 assign(op3, get_gpr_dw0(r3));
5345 assign(result, binop(Iop_And64, mkexpr(op2), mkexpr(op3)));
5346 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5347 store(mkexpr(op2addr), mkexpr(result));
5348 put_gpr_dw0(r1, mkexpr(op2));
5349
5350 return "lang";
5351}
5352
5353static HChar *
5354s390_irgen_LAX(UChar r1, UChar r3, IRTemp op2addr)
5355{
5356 IRTemp op2 = newTemp(Ity_I32);
5357 IRTemp op3 = newTemp(Ity_I32);
5358 IRTemp result = newTemp(Ity_I32);
5359
5360 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5361 assign(op3, get_gpr_w1(r3));
5362 assign(result, binop(Iop_Xor32, mkexpr(op2), mkexpr(op3)));
5363 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5364 store(mkexpr(op2addr), mkexpr(result));
5365 put_gpr_w1(r1, mkexpr(op2));
5366
5367 return "lax";
5368}
5369
5370static HChar *
5371s390_irgen_LAXG(UChar r1, UChar r3, IRTemp op2addr)
5372{
5373 IRTemp op2 = newTemp(Ity_I64);
5374 IRTemp op3 = newTemp(Ity_I64);
5375 IRTemp result = newTemp(Ity_I64);
5376
5377 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5378 assign(op3, get_gpr_dw0(r3));
5379 assign(result, binop(Iop_Xor64, mkexpr(op2), mkexpr(op3)));
5380 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5381 store(mkexpr(op2addr), mkexpr(result));
5382 put_gpr_dw0(r1, mkexpr(op2));
5383
5384 return "laxg";
5385}
5386
5387static HChar *
5388s390_irgen_LAO(UChar r1, UChar r3, IRTemp op2addr)
5389{
5390 IRTemp op2 = newTemp(Ity_I32);
5391 IRTemp op3 = newTemp(Ity_I32);
5392 IRTemp result = newTemp(Ity_I32);
5393
5394 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5395 assign(op3, get_gpr_w1(r3));
5396 assign(result, binop(Iop_Or32, mkexpr(op2), mkexpr(op3)));
5397 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5398 store(mkexpr(op2addr), mkexpr(result));
5399 put_gpr_w1(r1, mkexpr(op2));
5400
5401 return "lao";
5402}
5403
5404static HChar *
5405s390_irgen_LAOG(UChar r1, UChar r3, IRTemp op2addr)
5406{
5407 IRTemp op2 = newTemp(Ity_I64);
5408 IRTemp op3 = newTemp(Ity_I64);
5409 IRTemp result = newTemp(Ity_I64);
5410
5411 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5412 assign(op3, get_gpr_dw0(r3));
5413 assign(result, binop(Iop_Or64, mkexpr(op2), mkexpr(op3)));
5414 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5415 store(mkexpr(op2addr), mkexpr(result));
5416 put_gpr_dw0(r1, mkexpr(op2));
5417
5418 return "laog";
5419}
5420
5421static HChar *
5422s390_irgen_LTR(UChar r1, UChar r2)
5423{
5424 IRTemp op2 = newTemp(Ity_I32);
5425
5426 assign(op2, get_gpr_w1(r2));
5427 put_gpr_w1(r1, mkexpr(op2));
5428 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5429
5430 return "ltr";
5431}
5432
5433static HChar *
5434s390_irgen_LTGR(UChar r1, UChar r2)
5435{
5436 IRTemp op2 = newTemp(Ity_I64);
5437
5438 assign(op2, get_gpr_dw0(r2));
5439 put_gpr_dw0(r1, mkexpr(op2));
5440 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5441
5442 return "ltgr";
5443}
5444
5445static HChar *
5446s390_irgen_LTGFR(UChar r1, UChar r2)
5447{
5448 IRTemp op2 = newTemp(Ity_I64);
5449
5450 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
5451 put_gpr_dw0(r1, mkexpr(op2));
5452 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5453
5454 return "ltgfr";
5455}
5456
5457static HChar *
5458s390_irgen_LT(UChar r1, IRTemp op2addr)
5459{
5460 IRTemp op2 = newTemp(Ity_I32);
5461
5462 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5463 put_gpr_w1(r1, mkexpr(op2));
5464 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5465
5466 return "lt";
5467}
5468
5469static HChar *
5470s390_irgen_LTG(UChar r1, IRTemp op2addr)
5471{
5472 IRTemp op2 = newTemp(Ity_I64);
5473
5474 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5475 put_gpr_dw0(r1, mkexpr(op2));
5476 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5477
5478 return "ltg";
5479}
5480
5481static HChar *
5482s390_irgen_LTGF(UChar r1, IRTemp op2addr)
5483{
5484 IRTemp op2 = newTemp(Ity_I64);
5485
5486 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
5487 put_gpr_dw0(r1, mkexpr(op2));
5488 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5489
5490 return "ltgf";
5491}
5492
5493static HChar *
5494s390_irgen_LBR(UChar r1, UChar r2)
5495{
5496 put_gpr_w1(r1, unop(Iop_8Sto32, get_gpr_b7(r2)));
5497
5498 return "lbr";
5499}
5500
5501static HChar *
5502s390_irgen_LGBR(UChar r1, UChar r2)
5503{
5504 put_gpr_dw0(r1, unop(Iop_8Sto64, get_gpr_b7(r2)));
5505
5506 return "lgbr";
5507}
5508
5509static HChar *
5510s390_irgen_LB(UChar r1, IRTemp op2addr)
5511{
5512 put_gpr_w1(r1, unop(Iop_8Sto32, load(Ity_I8, mkexpr(op2addr))));
5513
5514 return "lb";
5515}
5516
5517static HChar *
5518s390_irgen_LGB(UChar r1, IRTemp op2addr)
5519{
5520 put_gpr_dw0(r1, unop(Iop_8Sto64, load(Ity_I8, mkexpr(op2addr))));
5521
5522 return "lgb";
5523}
5524
5525static HChar *
5526s390_irgen_LBH(UChar r1, IRTemp op2addr)
5527{
5528 put_gpr_w0(r1, unop(Iop_8Sto32, load(Ity_I8, mkexpr(op2addr))));
5529
5530 return "lbh";
5531}
5532
5533static HChar *
5534s390_irgen_LCR(UChar r1, UChar r2)
5535{
5536 Int op1;
5537 IRTemp op2 = newTemp(Ity_I32);
5538 IRTemp result = newTemp(Ity_I32);
5539
5540 op1 = 0;
5541 assign(op2, get_gpr_w1(r2));
5542 assign(result, binop(Iop_Sub32, mkU32((UInt)op1), mkexpr(op2)));
5543 put_gpr_w1(r1, mkexpr(result));
5544 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, mktemp(Ity_I32, mkU32((UInt)
5545 op1)), op2);
5546
5547 return "lcr";
5548}
5549
5550static HChar *
5551s390_irgen_LCGR(UChar r1, UChar r2)
5552{
5553 Long op1;
5554 IRTemp op2 = newTemp(Ity_I64);
5555 IRTemp result = newTemp(Ity_I64);
5556
5557 op1 = 0ULL;
5558 assign(op2, get_gpr_dw0(r2));
5559 assign(result, binop(Iop_Sub64, mkU64((ULong)op1), mkexpr(op2)));
5560 put_gpr_dw0(r1, mkexpr(result));
5561 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, mktemp(Ity_I64, mkU64((ULong)
5562 op1)), op2);
5563
5564 return "lcgr";
5565}
5566
5567static HChar *
5568s390_irgen_LCGFR(UChar r1, UChar r2)
5569{
5570 Long op1;
5571 IRTemp op2 = newTemp(Ity_I64);
5572 IRTemp result = newTemp(Ity_I64);
5573
5574 op1 = 0ULL;
5575 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
5576 assign(result, binop(Iop_Sub64, mkU64((ULong)op1), mkexpr(op2)));
5577 put_gpr_dw0(r1, mkexpr(result));
5578 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, mktemp(Ity_I64, mkU64((ULong)
5579 op1)), op2);
5580
5581 return "lcgfr";
5582}
5583
5584static HChar *
5585s390_irgen_LHR(UChar r1, UChar r2)
5586{
5587 put_gpr_w1(r1, unop(Iop_16Sto32, get_gpr_hw3(r2)));
5588
5589 return "lhr";
5590}
5591
5592static HChar *
5593s390_irgen_LGHR(UChar r1, UChar r2)
5594{
5595 put_gpr_dw0(r1, unop(Iop_16Sto64, get_gpr_hw3(r2)));
5596
5597 return "lghr";
5598}
5599
5600static HChar *
5601s390_irgen_LH(UChar r1, IRTemp op2addr)
5602{
5603 put_gpr_w1(r1, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
5604
5605 return "lh";
5606}
5607
5608static HChar *
5609s390_irgen_LHY(UChar r1, IRTemp op2addr)
5610{
5611 put_gpr_w1(r1, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
5612
5613 return "lhy";
5614}
5615
5616static HChar *
5617s390_irgen_LGH(UChar r1, IRTemp op2addr)
5618{
5619 put_gpr_dw0(r1, unop(Iop_16Sto64, load(Ity_I16, mkexpr(op2addr))));
5620
5621 return "lgh";
5622}
5623
5624static HChar *
5625s390_irgen_LHI(UChar r1, UShort i2)
5626{
5627 put_gpr_w1(r1, mkU32((UInt)(Int)(Short)i2));
5628
5629 return "lhi";
5630}
5631
5632static HChar *
5633s390_irgen_LGHI(UChar r1, UShort i2)
5634{
5635 put_gpr_dw0(r1, mkU64((ULong)(Long)(Short)i2));
5636
5637 return "lghi";
5638}
5639
5640static HChar *
5641s390_irgen_LHRL(UChar r1, UInt i2)
5642{
5643 put_gpr_w1(r1, unop(Iop_16Sto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
5644 ((ULong)(Long)(Int)i2 << 1)))));
5645
5646 return "lhrl";
5647}
5648
5649static HChar *
5650s390_irgen_LGHRL(UChar r1, UInt i2)
5651{
5652 put_gpr_dw0(r1, unop(Iop_16Sto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
5653 ((ULong)(Long)(Int)i2 << 1)))));
5654
5655 return "lghrl";
5656}
5657
5658static HChar *
5659s390_irgen_LHH(UChar r1, IRTemp op2addr)
5660{
5661 put_gpr_w0(r1, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
5662
5663 return "lhh";
5664}
5665
5666static HChar *
5667s390_irgen_LFH(UChar r1, IRTemp op2addr)
5668{
5669 put_gpr_w0(r1, load(Ity_I32, mkexpr(op2addr)));
5670
5671 return "lfh";
5672}
5673
5674static HChar *
5675s390_irgen_LLGFR(UChar r1, UChar r2)
5676{
5677 put_gpr_dw0(r1, unop(Iop_32Uto64, get_gpr_w1(r2)));
5678
5679 return "llgfr";
5680}
5681
5682static HChar *
5683s390_irgen_LLGF(UChar r1, IRTemp op2addr)
5684{
5685 put_gpr_dw0(r1, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
5686
5687 return "llgf";
5688}
5689
5690static HChar *
5691s390_irgen_LLGFRL(UChar r1, UInt i2)
5692{
5693 put_gpr_dw0(r1, unop(Iop_32Uto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
5694 ((ULong)(Long)(Int)i2 << 1)))));
5695
5696 return "llgfrl";
5697}
5698
5699static HChar *
5700s390_irgen_LLCR(UChar r1, UChar r2)
5701{
5702 put_gpr_w1(r1, unop(Iop_8Uto32, get_gpr_b7(r2)));
5703
5704 return "llcr";
5705}
5706
5707static HChar *
5708s390_irgen_LLGCR(UChar r1, UChar r2)
5709{
5710 put_gpr_dw0(r1, unop(Iop_8Uto64, get_gpr_b7(r2)));
5711
5712 return "llgcr";
5713}
5714
5715static HChar *
5716s390_irgen_LLC(UChar r1, IRTemp op2addr)
5717{
5718 put_gpr_w1(r1, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
5719
5720 return "llc";
5721}
5722
5723static HChar *
5724s390_irgen_LLGC(UChar r1, IRTemp op2addr)
5725{
5726 put_gpr_dw0(r1, unop(Iop_8Uto64, load(Ity_I8, mkexpr(op2addr))));
5727
5728 return "llgc";
5729}
5730
5731static HChar *
5732s390_irgen_LLCH(UChar r1, IRTemp op2addr)
5733{
5734 put_gpr_w0(r1, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
5735
5736 return "llch";
5737}
5738
5739static HChar *
5740s390_irgen_LLHR(UChar r1, UChar r2)
5741{
5742 put_gpr_w1(r1, unop(Iop_16Uto32, get_gpr_hw3(r2)));
5743
5744 return "llhr";
5745}
5746
5747static HChar *
5748s390_irgen_LLGHR(UChar r1, UChar r2)
5749{
5750 put_gpr_dw0(r1, unop(Iop_16Uto64, get_gpr_hw3(r2)));
5751
5752 return "llghr";
5753}
5754
5755static HChar *
5756s390_irgen_LLH(UChar r1, IRTemp op2addr)
5757{
5758 put_gpr_w1(r1, unop(Iop_16Uto32, load(Ity_I16, mkexpr(op2addr))));
5759
5760 return "llh";
5761}
5762
5763static HChar *
5764s390_irgen_LLGH(UChar r1, IRTemp op2addr)
5765{
5766 put_gpr_dw0(r1, unop(Iop_16Uto64, load(Ity_I16, mkexpr(op2addr))));
5767
5768 return "llgh";
5769}
5770
5771static HChar *
5772s390_irgen_LLHRL(UChar r1, UInt i2)
5773{
5774 put_gpr_w1(r1, unop(Iop_16Uto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
5775 ((ULong)(Long)(Int)i2 << 1)))));
5776
5777 return "llhrl";
5778}
5779
5780static HChar *
5781s390_irgen_LLGHRL(UChar r1, UInt i2)
5782{
5783 put_gpr_dw0(r1, unop(Iop_16Uto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
5784 ((ULong)(Long)(Int)i2 << 1)))));
5785
5786 return "llghrl";
5787}
5788
5789static HChar *
5790s390_irgen_LLHH(UChar r1, IRTemp op2addr)
5791{
5792 put_gpr_w0(r1, unop(Iop_16Uto32, load(Ity_I16, mkexpr(op2addr))));
5793
5794 return "llhh";
5795}
5796
5797static HChar *
5798s390_irgen_LLIHF(UChar r1, UInt i2)
5799{
5800 put_gpr_dw0(r1, mkU64(((ULong)i2) << 32));
5801
5802 return "llihf";
5803}
5804
5805static HChar *
5806s390_irgen_LLIHH(UChar r1, UShort i2)
5807{
5808 put_gpr_dw0(r1, mkU64(((ULong)i2) << 48));
5809
5810 return "llihh";
5811}
5812
5813static HChar *
5814s390_irgen_LLIHL(UChar r1, UShort i2)
5815{
5816 put_gpr_dw0(r1, mkU64(((ULong)i2) << 32));
5817
5818 return "llihl";
5819}
5820
5821static HChar *
5822s390_irgen_LLILF(UChar r1, UInt i2)
5823{
5824 put_gpr_dw0(r1, mkU64(i2));
5825
5826 return "llilf";
5827}
5828
5829static HChar *
5830s390_irgen_LLILH(UChar r1, UShort i2)
5831{
5832 put_gpr_dw0(r1, mkU64(((ULong)i2) << 16));
5833
5834 return "llilh";
5835}
5836
5837static HChar *
5838s390_irgen_LLILL(UChar r1, UShort i2)
5839{
5840 put_gpr_dw0(r1, mkU64(i2));
5841
5842 return "llill";
5843}
5844
5845static HChar *
5846s390_irgen_LLGTR(UChar r1, UChar r2)
5847{
5848 put_gpr_dw0(r1, unop(Iop_32Uto64, binop(Iop_And32, get_gpr_w1(r2),
5849 mkU32(2147483647))));
5850
5851 return "llgtr";
5852}
5853
5854static HChar *
5855s390_irgen_LLGT(UChar r1, IRTemp op2addr)
5856{
5857 put_gpr_dw0(r1, unop(Iop_32Uto64, binop(Iop_And32, load(Ity_I32,
5858 mkexpr(op2addr)), mkU32(2147483647))));
5859
5860 return "llgt";
5861}
5862
5863static HChar *
5864s390_irgen_LNR(UChar r1, UChar r2)
5865{
5866 IRTemp op2 = newTemp(Ity_I32);
5867 IRTemp result = newTemp(Ity_I32);
5868
5869 assign(op2, get_gpr_w1(r2));
5870 assign(result, mkite(binop(Iop_CmpLE32S, mkexpr(op2), mkU32(0)), mkexpr(op2),
5871 binop(Iop_Sub32, mkU32(0), mkexpr(op2))));
5872 put_gpr_w1(r1, mkexpr(result));
5873 s390_cc_thunk_putS(S390_CC_OP_BITWISE, result);
5874
5875 return "lnr";
5876}
5877
5878static HChar *
5879s390_irgen_LNGR(UChar r1, UChar r2)
5880{
5881 IRTemp op2 = newTemp(Ity_I64);
5882 IRTemp result = newTemp(Ity_I64);
5883
5884 assign(op2, get_gpr_dw0(r2));
5885 assign(result, mkite(binop(Iop_CmpLE64S, mkexpr(op2), mkU64(0)), mkexpr(op2),
5886 binop(Iop_Sub64, mkU64(0), mkexpr(op2))));
5887 put_gpr_dw0(r1, mkexpr(result));
5888 s390_cc_thunk_putS(S390_CC_OP_BITWISE, result);
5889
5890 return "lngr";
5891}
5892
5893static HChar *
5894s390_irgen_LNGFR(UChar r1, UChar r2 __attribute__((unused)))
5895{
5896 IRTemp op2 = newTemp(Ity_I64);
5897 IRTemp result = newTemp(Ity_I64);
5898
5899 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r1)));
5900 assign(result, mkite(binop(Iop_CmpLE64S, mkexpr(op2), mkU64(0)), mkexpr(op2),
5901 binop(Iop_Sub64, mkU64(0), mkexpr(op2))));
5902 put_gpr_dw0(r1, mkexpr(result));
5903 s390_cc_thunk_putS(S390_CC_OP_BITWISE, result);
5904
5905 return "lngfr";
5906}
5907
5908static HChar *
sewardjd7bde722011-04-05 13:19:33 +00005909s390_irgen_LOCR(UChar m3, UChar r1, UChar r2)
5910{
florian6820ba52012-07-26 02:01:50 +00005911 next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0)));
sewardjd7bde722011-04-05 13:19:33 +00005912 put_gpr_w1(r1, get_gpr_w1(r2));
5913
5914 return "locr";
5915}
5916
5917static HChar *
5918s390_irgen_LOCGR(UChar m3, UChar r1, UChar r2)
5919{
florian6820ba52012-07-26 02:01:50 +00005920 next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0)));
sewardjd7bde722011-04-05 13:19:33 +00005921 put_gpr_dw0(r1, get_gpr_dw0(r2));
5922
5923 return "locgr";
5924}
5925
5926static HChar *
5927s390_irgen_LOC(UChar r1, IRTemp op2addr)
5928{
5929 /* condition is checked in format handler */
5930 put_gpr_w1(r1, load(Ity_I32, mkexpr(op2addr)));
5931
5932 return "loc";
5933}
5934
5935static HChar *
5936s390_irgen_LOCG(UChar r1, IRTemp op2addr)
5937{
5938 /* condition is checked in format handler */
5939 put_gpr_dw0(r1, load(Ity_I64, mkexpr(op2addr)));
5940
5941 return "locg";
5942}
5943
5944static HChar *
sewardj2019a972011-03-07 16:04:07 +00005945s390_irgen_LPQ(UChar r1, IRTemp op2addr)
5946{
5947 put_gpr_dw0(r1, load(Ity_I64, mkexpr(op2addr)));
5948 put_gpr_dw0(r1 + 1, load(Ity_I64, binop(Iop_Add64, mkexpr(op2addr), mkU64(8))
5949 ));
5950
5951 return "lpq";
5952}
5953
5954static HChar *
5955s390_irgen_LPR(UChar r1, UChar r2)
5956{
5957 IRTemp op2 = newTemp(Ity_I32);
5958 IRTemp result = newTemp(Ity_I32);
5959
5960 assign(op2, get_gpr_w1(r2));
5961 assign(result, mkite(binop(Iop_CmpLT32S, mkexpr(op2), mkU32(0)),
5962 binop(Iop_Sub32, mkU32(0), mkexpr(op2)), mkexpr(op2)));
5963 put_gpr_w1(r1, mkexpr(result));
5964 s390_cc_thunk_putS(S390_CC_OP_LOAD_POSITIVE_32, op2);
5965
5966 return "lpr";
5967}
5968
5969static HChar *
5970s390_irgen_LPGR(UChar r1, UChar r2)
5971{
5972 IRTemp op2 = newTemp(Ity_I64);
5973 IRTemp result = newTemp(Ity_I64);
5974
5975 assign(op2, get_gpr_dw0(r2));
5976 assign(result, mkite(binop(Iop_CmpLT64S, mkexpr(op2), mkU64(0)),
5977 binop(Iop_Sub64, mkU64(0), mkexpr(op2)), mkexpr(op2)));
5978 put_gpr_dw0(r1, mkexpr(result));
5979 s390_cc_thunk_putS(S390_CC_OP_LOAD_POSITIVE_64, op2);
5980
5981 return "lpgr";
5982}
5983
5984static HChar *
5985s390_irgen_LPGFR(UChar r1, UChar r2)
5986{
5987 IRTemp op2 = newTemp(Ity_I64);
5988 IRTemp result = newTemp(Ity_I64);
5989
5990 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
5991 assign(result, mkite(binop(Iop_CmpLT64S, mkexpr(op2), mkU64(0)),
5992 binop(Iop_Sub64, mkU64(0), mkexpr(op2)), mkexpr(op2)));
5993 put_gpr_dw0(r1, mkexpr(result));
5994 s390_cc_thunk_putS(S390_CC_OP_LOAD_POSITIVE_64, op2);
5995
5996 return "lpgfr";
5997}
5998
5999static HChar *
6000s390_irgen_LRVR(UChar r1, UChar r2)
6001{
6002 IRTemp b0 = newTemp(Ity_I8);
6003 IRTemp b1 = newTemp(Ity_I8);
6004 IRTemp b2 = newTemp(Ity_I8);
6005 IRTemp b3 = newTemp(Ity_I8);
6006
6007 assign(b3, get_gpr_b7(r2));
6008 assign(b2, get_gpr_b6(r2));
6009 assign(b1, get_gpr_b5(r2));
6010 assign(b0, get_gpr_b4(r2));
6011 put_gpr_b4(r1, mkexpr(b3));
6012 put_gpr_b5(r1, mkexpr(b2));
6013 put_gpr_b6(r1, mkexpr(b1));
6014 put_gpr_b7(r1, mkexpr(b0));
6015
6016 return "lrvr";
6017}
6018
6019static HChar *
6020s390_irgen_LRVGR(UChar r1, UChar r2)
6021{
6022 IRTemp b0 = newTemp(Ity_I8);
6023 IRTemp b1 = newTemp(Ity_I8);
6024 IRTemp b2 = newTemp(Ity_I8);
6025 IRTemp b3 = newTemp(Ity_I8);
6026 IRTemp b4 = newTemp(Ity_I8);
6027 IRTemp b5 = newTemp(Ity_I8);
6028 IRTemp b6 = newTemp(Ity_I8);
6029 IRTemp b7 = newTemp(Ity_I8);
6030
6031 assign(b7, get_gpr_b7(r2));
6032 assign(b6, get_gpr_b6(r2));
6033 assign(b5, get_gpr_b5(r2));
6034 assign(b4, get_gpr_b4(r2));
6035 assign(b3, get_gpr_b3(r2));
6036 assign(b2, get_gpr_b2(r2));
6037 assign(b1, get_gpr_b1(r2));
6038 assign(b0, get_gpr_b0(r2));
6039 put_gpr_b0(r1, mkexpr(b7));
6040 put_gpr_b1(r1, mkexpr(b6));
6041 put_gpr_b2(r1, mkexpr(b5));
6042 put_gpr_b3(r1, mkexpr(b4));
6043 put_gpr_b4(r1, mkexpr(b3));
6044 put_gpr_b5(r1, mkexpr(b2));
6045 put_gpr_b6(r1, mkexpr(b1));
6046 put_gpr_b7(r1, mkexpr(b0));
6047
6048 return "lrvgr";
6049}
6050
6051static HChar *
6052s390_irgen_LRVH(UChar r1, IRTemp op2addr)
6053{
6054 IRTemp op2 = newTemp(Ity_I16);
6055
6056 assign(op2, load(Ity_I16, mkexpr(op2addr)));
6057 put_gpr_b6(r1, unop(Iop_16to8, mkexpr(op2)));
6058 put_gpr_b7(r1, unop(Iop_16HIto8, mkexpr(op2)));
6059
6060 return "lrvh";
6061}
6062
6063static HChar *
6064s390_irgen_LRV(UChar r1, IRTemp op2addr)
6065{
6066 IRTemp op2 = newTemp(Ity_I32);
6067
6068 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6069 put_gpr_b4(r1, unop(Iop_32to8, binop(Iop_And32, mkexpr(op2), mkU32(255))));
6070 put_gpr_b5(r1, unop(Iop_32to8, binop(Iop_And32, binop(Iop_Shr32, mkexpr(op2),
6071 mkU8(8)), mkU32(255))));
6072 put_gpr_b6(r1, unop(Iop_32to8, binop(Iop_And32, binop(Iop_Shr32, mkexpr(op2),
6073 mkU8(16)), mkU32(255))));
6074 put_gpr_b7(r1, unop(Iop_32to8, binop(Iop_And32, binop(Iop_Shr32, mkexpr(op2),
6075 mkU8(24)), mkU32(255))));
6076
6077 return "lrv";
6078}
6079
6080static HChar *
6081s390_irgen_LRVG(UChar r1, IRTemp op2addr)
6082{
6083 IRTemp op2 = newTemp(Ity_I64);
6084
6085 assign(op2, load(Ity_I64, mkexpr(op2addr)));
6086 put_gpr_b0(r1, unop(Iop_64to8, binop(Iop_And64, mkexpr(op2), mkU64(255))));
6087 put_gpr_b1(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6088 mkU8(8)), mkU64(255))));
6089 put_gpr_b2(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6090 mkU8(16)), mkU64(255))));
6091 put_gpr_b3(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6092 mkU8(24)), mkU64(255))));
6093 put_gpr_b4(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6094 mkU8(32)), mkU64(255))));
6095 put_gpr_b5(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6096 mkU8(40)), mkU64(255))));
6097 put_gpr_b6(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6098 mkU8(48)), mkU64(255))));
6099 put_gpr_b7(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6100 mkU8(56)), mkU64(255))));
6101
6102 return "lrvg";
6103}
6104
6105static HChar *
6106s390_irgen_MVHHI(UShort i2, IRTemp op1addr)
6107{
6108 store(mkexpr(op1addr), mkU16(i2));
6109
6110 return "mvhhi";
6111}
6112
6113static HChar *
6114s390_irgen_MVHI(UShort i2, IRTemp op1addr)
6115{
6116 store(mkexpr(op1addr), mkU32((UInt)(Int)(Short)i2));
6117
6118 return "mvhi";
6119}
6120
6121static HChar *
6122s390_irgen_MVGHI(UShort i2, IRTemp op1addr)
6123{
6124 store(mkexpr(op1addr), mkU64((ULong)(Long)(Short)i2));
6125
6126 return "mvghi";
6127}
6128
6129static HChar *
6130s390_irgen_MVI(UChar i2, IRTemp op1addr)
6131{
6132 store(mkexpr(op1addr), mkU8(i2));
6133
6134 return "mvi";
6135}
6136
6137static HChar *
6138s390_irgen_MVIY(UChar i2, IRTemp op1addr)
6139{
6140 store(mkexpr(op1addr), mkU8(i2));
6141
6142 return "mviy";
6143}
6144
6145static HChar *
6146s390_irgen_MR(UChar r1, UChar r2)
6147{
6148 IRTemp op1 = newTemp(Ity_I32);
6149 IRTemp op2 = newTemp(Ity_I32);
6150 IRTemp result = newTemp(Ity_I64);
6151
6152 assign(op1, get_gpr_w1(r1 + 1));
6153 assign(op2, get_gpr_w1(r2));
6154 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6155 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6156 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6157
6158 return "mr";
6159}
6160
6161static HChar *
6162s390_irgen_M(UChar r1, IRTemp op2addr)
6163{
6164 IRTemp op1 = newTemp(Ity_I32);
6165 IRTemp op2 = newTemp(Ity_I32);
6166 IRTemp result = newTemp(Ity_I64);
6167
6168 assign(op1, get_gpr_w1(r1 + 1));
6169 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6170 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6171 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6172 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6173
6174 return "m";
6175}
6176
6177static HChar *
6178s390_irgen_MFY(UChar r1, IRTemp op2addr)
6179{
6180 IRTemp op1 = newTemp(Ity_I32);
6181 IRTemp op2 = newTemp(Ity_I32);
6182 IRTemp result = newTemp(Ity_I64);
6183
6184 assign(op1, get_gpr_w1(r1 + 1));
6185 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6186 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6187 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6188 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6189
6190 return "mfy";
6191}
6192
6193static HChar *
6194s390_irgen_MH(UChar r1, IRTemp op2addr)
6195{
6196 IRTemp op1 = newTemp(Ity_I32);
6197 IRTemp op2 = newTemp(Ity_I16);
6198 IRTemp result = newTemp(Ity_I64);
6199
6200 assign(op1, get_gpr_w1(r1));
6201 assign(op2, load(Ity_I16, mkexpr(op2addr)));
6202 assign(result, binop(Iop_MullS32, mkexpr(op1), unop(Iop_16Sto32, mkexpr(op2))
6203 ));
6204 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6205
6206 return "mh";
6207}
6208
6209static HChar *
6210s390_irgen_MHY(UChar r1, IRTemp op2addr)
6211{
6212 IRTemp op1 = newTemp(Ity_I32);
6213 IRTemp op2 = newTemp(Ity_I16);
6214 IRTemp result = newTemp(Ity_I64);
6215
6216 assign(op1, get_gpr_w1(r1));
6217 assign(op2, load(Ity_I16, mkexpr(op2addr)));
6218 assign(result, binop(Iop_MullS32, mkexpr(op1), unop(Iop_16Sto32, mkexpr(op2))
6219 ));
6220 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6221
6222 return "mhy";
6223}
6224
6225static HChar *
6226s390_irgen_MHI(UChar r1, UShort i2)
6227{
6228 IRTemp op1 = newTemp(Ity_I32);
6229 Short op2;
6230 IRTemp result = newTemp(Ity_I64);
6231
6232 assign(op1, get_gpr_w1(r1));
6233 op2 = (Short)i2;
6234 assign(result, binop(Iop_MullS32, mkexpr(op1), unop(Iop_16Sto32,
6235 mkU16((UShort)op2))));
6236 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6237
6238 return "mhi";
6239}
6240
6241static HChar *
6242s390_irgen_MGHI(UChar r1, UShort i2)
6243{
6244 IRTemp op1 = newTemp(Ity_I64);
6245 Short op2;
6246 IRTemp result = newTemp(Ity_I128);
6247
6248 assign(op1, get_gpr_dw0(r1));
6249 op2 = (Short)i2;
6250 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_16Sto64,
6251 mkU16((UShort)op2))));
6252 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6253
6254 return "mghi";
6255}
6256
6257static HChar *
6258s390_irgen_MLR(UChar r1, UChar r2)
6259{
6260 IRTemp op1 = newTemp(Ity_I32);
6261 IRTemp op2 = newTemp(Ity_I32);
6262 IRTemp result = newTemp(Ity_I64);
6263
6264 assign(op1, get_gpr_w1(r1 + 1));
6265 assign(op2, get_gpr_w1(r2));
6266 assign(result, binop(Iop_MullU32, mkexpr(op1), mkexpr(op2)));
6267 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6268 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6269
6270 return "mlr";
6271}
6272
6273static HChar *
6274s390_irgen_MLGR(UChar r1, UChar r2)
6275{
6276 IRTemp op1 = newTemp(Ity_I64);
6277 IRTemp op2 = newTemp(Ity_I64);
6278 IRTemp result = newTemp(Ity_I128);
6279
6280 assign(op1, get_gpr_dw0(r1 + 1));
6281 assign(op2, get_gpr_dw0(r2));
6282 assign(result, binop(Iop_MullU64, mkexpr(op1), mkexpr(op2)));
6283 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result)));
6284 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result)));
6285
6286 return "mlgr";
6287}
6288
6289static HChar *
6290s390_irgen_ML(UChar r1, IRTemp op2addr)
6291{
6292 IRTemp op1 = newTemp(Ity_I32);
6293 IRTemp op2 = newTemp(Ity_I32);
6294 IRTemp result = newTemp(Ity_I64);
6295
6296 assign(op1, get_gpr_w1(r1 + 1));
6297 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6298 assign(result, binop(Iop_MullU32, mkexpr(op1), mkexpr(op2)));
6299 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6300 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6301
6302 return "ml";
6303}
6304
6305static HChar *
6306s390_irgen_MLG(UChar r1, IRTemp op2addr)
6307{
6308 IRTemp op1 = newTemp(Ity_I64);
6309 IRTemp op2 = newTemp(Ity_I64);
6310 IRTemp result = newTemp(Ity_I128);
6311
6312 assign(op1, get_gpr_dw0(r1 + 1));
6313 assign(op2, load(Ity_I64, mkexpr(op2addr)));
6314 assign(result, binop(Iop_MullU64, mkexpr(op1), mkexpr(op2)));
6315 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result)));
6316 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result)));
6317
6318 return "mlg";
6319}
6320
6321static HChar *
6322s390_irgen_MSR(UChar r1, UChar r2)
6323{
6324 IRTemp op1 = newTemp(Ity_I32);
6325 IRTemp op2 = newTemp(Ity_I32);
6326 IRTemp result = newTemp(Ity_I64);
6327
6328 assign(op1, get_gpr_w1(r1));
6329 assign(op2, get_gpr_w1(r2));
6330 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6331 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6332
6333 return "msr";
6334}
6335
6336static HChar *
6337s390_irgen_MSGR(UChar r1, UChar r2)
6338{
6339 IRTemp op1 = newTemp(Ity_I64);
6340 IRTemp op2 = newTemp(Ity_I64);
6341 IRTemp result = newTemp(Ity_I128);
6342
6343 assign(op1, get_gpr_dw0(r1));
6344 assign(op2, get_gpr_dw0(r2));
6345 assign(result, binop(Iop_MullS64, mkexpr(op1), mkexpr(op2)));
6346 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6347
6348 return "msgr";
6349}
6350
6351static HChar *
6352s390_irgen_MSGFR(UChar r1, UChar r2)
6353{
6354 IRTemp op1 = newTemp(Ity_I64);
6355 IRTemp op2 = newTemp(Ity_I32);
6356 IRTemp result = newTemp(Ity_I128);
6357
6358 assign(op1, get_gpr_dw0(r1));
6359 assign(op2, get_gpr_w1(r2));
6360 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_32Sto64, mkexpr(op2))
6361 ));
6362 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6363
6364 return "msgfr";
6365}
6366
6367static HChar *
6368s390_irgen_MS(UChar r1, IRTemp op2addr)
6369{
6370 IRTemp op1 = newTemp(Ity_I32);
6371 IRTemp op2 = newTemp(Ity_I32);
6372 IRTemp result = newTemp(Ity_I64);
6373
6374 assign(op1, get_gpr_w1(r1));
6375 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6376 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6377 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6378
6379 return "ms";
6380}
6381
6382static HChar *
6383s390_irgen_MSY(UChar r1, IRTemp op2addr)
6384{
6385 IRTemp op1 = newTemp(Ity_I32);
6386 IRTemp op2 = newTemp(Ity_I32);
6387 IRTemp result = newTemp(Ity_I64);
6388
6389 assign(op1, get_gpr_w1(r1));
6390 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6391 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6392 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6393
6394 return "msy";
6395}
6396
6397static HChar *
6398s390_irgen_MSG(UChar r1, IRTemp op2addr)
6399{
6400 IRTemp op1 = newTemp(Ity_I64);
6401 IRTemp op2 = newTemp(Ity_I64);
6402 IRTemp result = newTemp(Ity_I128);
6403
6404 assign(op1, get_gpr_dw0(r1));
6405 assign(op2, load(Ity_I64, mkexpr(op2addr)));
6406 assign(result, binop(Iop_MullS64, mkexpr(op1), mkexpr(op2)));
6407 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6408
6409 return "msg";
6410}
6411
6412static HChar *
6413s390_irgen_MSGF(UChar r1, IRTemp op2addr)
6414{
6415 IRTemp op1 = newTemp(Ity_I64);
6416 IRTemp op2 = newTemp(Ity_I32);
6417 IRTemp result = newTemp(Ity_I128);
6418
6419 assign(op1, get_gpr_dw0(r1));
6420 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6421 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_32Sto64, mkexpr(op2))
6422 ));
6423 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6424
6425 return "msgf";
6426}
6427
6428static HChar *
6429s390_irgen_MSFI(UChar r1, UInt i2)
6430{
6431 IRTemp op1 = newTemp(Ity_I32);
6432 Int op2;
6433 IRTemp result = newTemp(Ity_I64);
6434
6435 assign(op1, get_gpr_w1(r1));
6436 op2 = (Int)i2;
6437 assign(result, binop(Iop_MullS32, mkexpr(op1), mkU32((UInt)op2)));
6438 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6439
6440 return "msfi";
6441}
6442
6443static HChar *
6444s390_irgen_MSGFI(UChar r1, UInt i2)
6445{
6446 IRTemp op1 = newTemp(Ity_I64);
6447 Int op2;
6448 IRTemp result = newTemp(Ity_I128);
6449
6450 assign(op1, get_gpr_dw0(r1));
6451 op2 = (Int)i2;
6452 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_32Sto64, mkU32((UInt)
6453 op2))));
6454 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6455
6456 return "msgfi";
6457}
6458
6459static HChar *
6460s390_irgen_OR(UChar r1, UChar r2)
6461{
6462 IRTemp op1 = newTemp(Ity_I32);
6463 IRTemp op2 = newTemp(Ity_I32);
6464 IRTemp result = newTemp(Ity_I32);
6465
6466 assign(op1, get_gpr_w1(r1));
6467 assign(op2, get_gpr_w1(r2));
6468 assign(result, binop(Iop_Or32, mkexpr(op1), mkexpr(op2)));
6469 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6470 put_gpr_w1(r1, mkexpr(result));
6471
6472 return "or";
6473}
6474
6475static HChar *
6476s390_irgen_OGR(UChar r1, UChar r2)
6477{
6478 IRTemp op1 = newTemp(Ity_I64);
6479 IRTemp op2 = newTemp(Ity_I64);
6480 IRTemp result = newTemp(Ity_I64);
6481
6482 assign(op1, get_gpr_dw0(r1));
6483 assign(op2, get_gpr_dw0(r2));
6484 assign(result, binop(Iop_Or64, mkexpr(op1), mkexpr(op2)));
6485 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6486 put_gpr_dw0(r1, mkexpr(result));
6487
6488 return "ogr";
6489}
6490
6491static HChar *
6492s390_irgen_ORK(UChar r3, UChar r1, UChar r2)
6493{
6494 IRTemp op2 = newTemp(Ity_I32);
6495 IRTemp op3 = newTemp(Ity_I32);
6496 IRTemp result = newTemp(Ity_I32);
6497
6498 assign(op2, get_gpr_w1(r2));
6499 assign(op3, get_gpr_w1(r3));
6500 assign(result, binop(Iop_Or32, mkexpr(op2), mkexpr(op3)));
6501 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6502 put_gpr_w1(r1, mkexpr(result));
6503
6504 return "ork";
6505}
6506
6507static HChar *
6508s390_irgen_OGRK(UChar r3, UChar r1, UChar r2)
6509{
6510 IRTemp op2 = newTemp(Ity_I64);
6511 IRTemp op3 = newTemp(Ity_I64);
6512 IRTemp result = newTemp(Ity_I64);
6513
6514 assign(op2, get_gpr_dw0(r2));
6515 assign(op3, get_gpr_dw0(r3));
6516 assign(result, binop(Iop_Or64, mkexpr(op2), mkexpr(op3)));
6517 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6518 put_gpr_dw0(r1, mkexpr(result));
6519
6520 return "ogrk";
6521}
6522
6523static HChar *
6524s390_irgen_O(UChar r1, IRTemp op2addr)
6525{
6526 IRTemp op1 = newTemp(Ity_I32);
6527 IRTemp op2 = newTemp(Ity_I32);
6528 IRTemp result = newTemp(Ity_I32);
6529
6530 assign(op1, get_gpr_w1(r1));
6531 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6532 assign(result, binop(Iop_Or32, mkexpr(op1), mkexpr(op2)));
6533 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6534 put_gpr_w1(r1, mkexpr(result));
6535
6536 return "o";
6537}
6538
6539static HChar *
6540s390_irgen_OY(UChar r1, IRTemp op2addr)
6541{
6542 IRTemp op1 = newTemp(Ity_I32);
6543 IRTemp op2 = newTemp(Ity_I32);
6544 IRTemp result = newTemp(Ity_I32);
6545
6546 assign(op1, get_gpr_w1(r1));
6547 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6548 assign(result, binop(Iop_Or32, mkexpr(op1), mkexpr(op2)));
6549 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6550 put_gpr_w1(r1, mkexpr(result));
6551
6552 return "oy";
6553}
6554
6555static HChar *
6556s390_irgen_OG(UChar r1, IRTemp op2addr)
6557{
6558 IRTemp op1 = newTemp(Ity_I64);
6559 IRTemp op2 = newTemp(Ity_I64);
6560 IRTemp result = newTemp(Ity_I64);
6561
6562 assign(op1, get_gpr_dw0(r1));
6563 assign(op2, load(Ity_I64, mkexpr(op2addr)));
6564 assign(result, binop(Iop_Or64, mkexpr(op1), mkexpr(op2)));
6565 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6566 put_gpr_dw0(r1, mkexpr(result));
6567
6568 return "og";
6569}
6570
6571static HChar *
6572s390_irgen_OI(UChar i2, IRTemp op1addr)
6573{
6574 IRTemp op1 = newTemp(Ity_I8);
6575 UChar op2;
6576 IRTemp result = newTemp(Ity_I8);
6577
6578 assign(op1, load(Ity_I8, mkexpr(op1addr)));
6579 op2 = i2;
6580 assign(result, binop(Iop_Or8, mkexpr(op1), mkU8(op2)));
6581 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6582 store(mkexpr(op1addr), mkexpr(result));
6583
6584 return "oi";
6585}
6586
6587static HChar *
6588s390_irgen_OIY(UChar i2, IRTemp op1addr)
6589{
6590 IRTemp op1 = newTemp(Ity_I8);
6591 UChar op2;
6592 IRTemp result = newTemp(Ity_I8);
6593
6594 assign(op1, load(Ity_I8, mkexpr(op1addr)));
6595 op2 = i2;
6596 assign(result, binop(Iop_Or8, mkexpr(op1), mkU8(op2)));
6597 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6598 store(mkexpr(op1addr), mkexpr(result));
6599
6600 return "oiy";
6601}
6602
6603static HChar *
6604s390_irgen_OIHF(UChar r1, UInt i2)
6605{
6606 IRTemp op1 = newTemp(Ity_I32);
6607 UInt op2;
6608 IRTemp result = newTemp(Ity_I32);
6609
6610 assign(op1, get_gpr_w0(r1));
6611 op2 = i2;
6612 assign(result, binop(Iop_Or32, mkexpr(op1), mkU32(op2)));
6613 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6614 put_gpr_w0(r1, mkexpr(result));
6615
6616 return "oihf";
6617}
6618
6619static HChar *
6620s390_irgen_OIHH(UChar r1, UShort i2)
6621{
6622 IRTemp op1 = newTemp(Ity_I16);
6623 UShort op2;
6624 IRTemp result = newTemp(Ity_I16);
6625
6626 assign(op1, get_gpr_hw0(r1));
6627 op2 = i2;
6628 assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
6629 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6630 put_gpr_hw0(r1, mkexpr(result));
6631
6632 return "oihh";
6633}
6634
6635static HChar *
6636s390_irgen_OIHL(UChar r1, UShort i2)
6637{
6638 IRTemp op1 = newTemp(Ity_I16);
6639 UShort op2;
6640 IRTemp result = newTemp(Ity_I16);
6641
6642 assign(op1, get_gpr_hw1(r1));
6643 op2 = i2;
6644 assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
6645 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6646 put_gpr_hw1(r1, mkexpr(result));
6647
6648 return "oihl";
6649}
6650
6651static HChar *
6652s390_irgen_OILF(UChar r1, UInt i2)
6653{
6654 IRTemp op1 = newTemp(Ity_I32);
6655 UInt op2;
6656 IRTemp result = newTemp(Ity_I32);
6657
6658 assign(op1, get_gpr_w1(r1));
6659 op2 = i2;
6660 assign(result, binop(Iop_Or32, mkexpr(op1), mkU32(op2)));
6661 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6662 put_gpr_w1(r1, mkexpr(result));
6663
6664 return "oilf";
6665}
6666
6667static HChar *
6668s390_irgen_OILH(UChar r1, UShort i2)
6669{
6670 IRTemp op1 = newTemp(Ity_I16);
6671 UShort op2;
6672 IRTemp result = newTemp(Ity_I16);
6673
6674 assign(op1, get_gpr_hw2(r1));
6675 op2 = i2;
6676 assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
6677 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6678 put_gpr_hw2(r1, mkexpr(result));
6679
6680 return "oilh";
6681}
6682
6683static HChar *
6684s390_irgen_OILL(UChar r1, UShort i2)
6685{
6686 IRTemp op1 = newTemp(Ity_I16);
6687 UShort op2;
6688 IRTemp result = newTemp(Ity_I16);
6689
6690 assign(op1, get_gpr_hw3(r1));
6691 op2 = i2;
6692 assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
6693 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6694 put_gpr_hw3(r1, mkexpr(result));
6695
6696 return "oill";
6697}
6698
6699static HChar *
6700s390_irgen_PFD(void)
6701{
6702
6703 return "pfd";
6704}
6705
6706static HChar *
6707s390_irgen_PFDRL(void)
6708{
6709
6710 return "pfdrl";
6711}
6712
6713static HChar *
6714s390_irgen_RLL(UChar r1, UChar r3, IRTemp op2addr)
6715{
6716 IRTemp amount = newTemp(Ity_I64);
6717 IRTemp op = newTemp(Ity_I32);
6718
6719 assign(amount, binop(Iop_And64, mkexpr(op2addr), mkU64(31)));
6720 assign(op, get_gpr_w1(r3));
6721 put_gpr_w1(r1, binop(Iop_Or32, binop(Iop_Shl32, mkexpr(op), unop(Iop_64to8,
6722 mkexpr(amount))), binop(Iop_Shr32, mkexpr(op), unop(Iop_64to8,
6723 binop(Iop_Sub64, mkU64(32), mkexpr(amount))))));
6724
6725 return "rll";
6726}
6727
6728static HChar *
6729s390_irgen_RLLG(UChar r1, UChar r3, IRTemp op2addr)
6730{
6731 IRTemp amount = newTemp(Ity_I64);
6732 IRTemp op = newTemp(Ity_I64);
6733
6734 assign(amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
6735 assign(op, get_gpr_dw0(r3));
6736 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(op), unop(Iop_64to8,
6737 mkexpr(amount))), binop(Iop_Shr64, mkexpr(op), unop(Iop_64to8,
6738 binop(Iop_Sub64, mkU64(64), mkexpr(amount))))));
6739
6740 return "rllg";
6741}
6742
6743static HChar *
6744s390_irgen_RNSBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
6745{
6746 UChar from;
6747 UChar to;
6748 UChar rot;
6749 UChar t_bit;
6750 ULong mask;
6751 ULong maskc;
6752 IRTemp result = newTemp(Ity_I64);
6753 IRTemp op2 = newTemp(Ity_I64);
6754
6755 from = i3 & 63;
6756 to = i4 & 63;
6757 rot = i5 & 63;
6758 t_bit = i3 & 128;
6759 assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
6760 get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
6761 mkU8(64 - rot))));
6762 if (from <= to) {
6763 mask = ~0ULL;
6764 mask = (mask >> from) & (mask << (63 - to));
6765 maskc = ~mask;
6766 } else {
6767 maskc = ~0ULL;
6768 maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
6769 mask = ~maskc;
6770 }
6771 assign(result, binop(Iop_And64, binop(Iop_And64, get_gpr_dw0(r1), mkexpr(op2)
6772 ), mkU64(mask)));
6773 if (t_bit == 0) {
6774 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
6775 mkU64(maskc)), mkexpr(result)));
6776 }
6777 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6778
6779 return "rnsbg";
6780}
6781
6782static HChar *
6783s390_irgen_RXSBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
6784{
6785 UChar from;
6786 UChar to;
6787 UChar rot;
6788 UChar t_bit;
6789 ULong mask;
6790 ULong maskc;
6791 IRTemp result = newTemp(Ity_I64);
6792 IRTemp op2 = newTemp(Ity_I64);
6793
6794 from = i3 & 63;
6795 to = i4 & 63;
6796 rot = i5 & 63;
6797 t_bit = i3 & 128;
6798 assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
6799 get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
6800 mkU8(64 - rot))));
6801 if (from <= to) {
6802 mask = ~0ULL;
6803 mask = (mask >> from) & (mask << (63 - to));
6804 maskc = ~mask;
6805 } else {
6806 maskc = ~0ULL;
6807 maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
6808 mask = ~maskc;
6809 }
6810 assign(result, binop(Iop_And64, binop(Iop_Xor64, get_gpr_dw0(r1), mkexpr(op2)
6811 ), mkU64(mask)));
6812 if (t_bit == 0) {
6813 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
6814 mkU64(maskc)), mkexpr(result)));
6815 }
6816 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6817
6818 return "rxsbg";
6819}
6820
6821static HChar *
6822s390_irgen_ROSBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
6823{
6824 UChar from;
6825 UChar to;
6826 UChar rot;
6827 UChar t_bit;
6828 ULong mask;
6829 ULong maskc;
6830 IRTemp result = newTemp(Ity_I64);
6831 IRTemp op2 = newTemp(Ity_I64);
6832
6833 from = i3 & 63;
6834 to = i4 & 63;
6835 rot = i5 & 63;
6836 t_bit = i3 & 128;
6837 assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
6838 get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
6839 mkU8(64 - rot))));
6840 if (from <= to) {
6841 mask = ~0ULL;
6842 mask = (mask >> from) & (mask << (63 - to));
6843 maskc = ~mask;
6844 } else {
6845 maskc = ~0ULL;
6846 maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
6847 mask = ~maskc;
6848 }
6849 assign(result, binop(Iop_And64, binop(Iop_Or64, get_gpr_dw0(r1), mkexpr(op2)
6850 ), mkU64(mask)));
6851 if (t_bit == 0) {
6852 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
6853 mkU64(maskc)), mkexpr(result)));
6854 }
6855 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6856
6857 return "rosbg";
6858}
6859
6860static HChar *
6861s390_irgen_RISBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
6862{
6863 UChar from;
6864 UChar to;
6865 UChar rot;
6866 UChar z_bit;
6867 ULong mask;
6868 ULong maskc;
6869 IRTemp op2 = newTemp(Ity_I64);
6870 IRTemp result = newTemp(Ity_I64);
6871
6872 from = i3 & 63;
6873 to = i4 & 63;
6874 rot = i5 & 63;
6875 z_bit = i4 & 128;
6876 assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
6877 get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
6878 mkU8(64 - rot))));
6879 if (from <= to) {
6880 mask = ~0ULL;
6881 mask = (mask >> from) & (mask << (63 - to));
6882 maskc = ~mask;
6883 } else {
6884 maskc = ~0ULL;
6885 maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
6886 mask = ~maskc;
6887 }
6888 if (z_bit == 0) {
6889 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
6890 mkU64(maskc)), binop(Iop_And64, mkexpr(op2), mkU64(mask))));
6891 } else {
6892 put_gpr_dw0(r1, binop(Iop_And64, mkexpr(op2), mkU64(mask)));
6893 }
6894 assign(result, get_gpr_dw0(r1));
6895 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
6896
6897 return "risbg";
6898}
6899
6900static HChar *
6901s390_irgen_SAR(UChar r1, UChar r2)
6902{
6903 put_ar_w0(r1, get_gpr_w1(r2));
sewardj7ee97522011-05-09 21:45:04 +00006904 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00006905 s390_disasm(ENC3(MNM, AR, GPR), "sar", r1, r2);
6906
6907 return "sar";
6908}
6909
6910static HChar *
6911s390_irgen_SLDA(UChar r1, IRTemp op2addr)
6912{
6913 IRTemp p1 = newTemp(Ity_I64);
6914 IRTemp p2 = newTemp(Ity_I64);
6915 IRTemp op = newTemp(Ity_I64);
6916 IRTemp result = newTemp(Ity_I64);
florian417b22d2012-07-13 13:41:41 +00006917 ULong sign_mask;
sewardj2019a972011-03-07 16:04:07 +00006918 IRTemp shift_amount = newTemp(Ity_I64);
6919
6920 assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
6921 assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
6922 assign(op, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1), mkU8(32)), mkexpr(p2)
6923 ));
6924 sign_mask = 1ULL << 63;
6925 assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
6926 assign(result, binop(Iop_Or64, binop(Iop_And64, binop(Iop_Shl64, mkexpr(op),
florian417b22d2012-07-13 13:41:41 +00006927 unop(Iop_64to8, mkexpr(shift_amount))), mkU64(~sign_mask)),
6928 binop(Iop_And64, mkexpr(op), mkU64(sign_mask))));
sewardj2019a972011-03-07 16:04:07 +00006929 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6930 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6931 s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_64, op, shift_amount);
6932
6933 return "slda";
6934}
6935
6936static HChar *
6937s390_irgen_SLDL(UChar r1, IRTemp op2addr)
6938{
6939 IRTemp p1 = newTemp(Ity_I64);
6940 IRTemp p2 = newTemp(Ity_I64);
6941 IRTemp result = newTemp(Ity_I64);
6942
6943 assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
6944 assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
6945 assign(result, binop(Iop_Shl64, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1),
6946 mkU8(32)), mkexpr(p2)), unop(Iop_64to8, binop(Iop_And64,
6947 mkexpr(op2addr), mkU64(63)))));
6948 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6949 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6950
6951 return "sldl";
6952}
6953
6954static HChar *
6955s390_irgen_SLA(UChar r1, IRTemp op2addr)
6956{
6957 IRTemp uop = newTemp(Ity_I32);
6958 IRTemp result = newTemp(Ity_I32);
6959 UInt sign_mask;
6960 IRTemp shift_amount = newTemp(Ity_I64);
6961 IRTemp op = newTemp(Ity_I32);
6962
6963 assign(op, get_gpr_w1(r1));
6964 assign(uop, get_gpr_w1(r1));
6965 sign_mask = 2147483648U;
6966 assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
6967 assign(result, binop(Iop_Or32, binop(Iop_And32, binop(Iop_Shl32, mkexpr(uop),
6968 unop(Iop_64to8, mkexpr(shift_amount))), mkU32(~sign_mask)),
6969 binop(Iop_And32, mkexpr(uop), mkU32(sign_mask))));
6970 put_gpr_w1(r1, mkexpr(result));
6971 s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_32, op, shift_amount);
6972
6973 return "sla";
6974}
6975
6976static HChar *
6977s390_irgen_SLAK(UChar r1, UChar r3, IRTemp op2addr)
6978{
6979 IRTemp uop = newTemp(Ity_I32);
6980 IRTemp result = newTemp(Ity_I32);
6981 UInt sign_mask;
6982 IRTemp shift_amount = newTemp(Ity_I64);
6983 IRTemp op = newTemp(Ity_I32);
6984
6985 assign(op, get_gpr_w1(r3));
6986 assign(uop, get_gpr_w1(r3));
6987 sign_mask = 2147483648U;
6988 assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
6989 assign(result, binop(Iop_Or32, binop(Iop_And32, binop(Iop_Shl32, mkexpr(uop),
6990 unop(Iop_64to8, mkexpr(shift_amount))), mkU32(~sign_mask)),
6991 binop(Iop_And32, mkexpr(uop), mkU32(sign_mask))));
6992 put_gpr_w1(r1, mkexpr(result));
6993 s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_32, op, shift_amount);
6994
6995 return "slak";
6996}
6997
6998static HChar *
6999s390_irgen_SLAG(UChar r1, UChar r3, IRTemp op2addr)
7000{
7001 IRTemp uop = newTemp(Ity_I64);
7002 IRTemp result = newTemp(Ity_I64);
7003 ULong sign_mask;
7004 IRTemp shift_amount = newTemp(Ity_I64);
7005 IRTemp op = newTemp(Ity_I64);
7006
7007 assign(op, get_gpr_dw0(r3));
7008 assign(uop, get_gpr_dw0(r3));
7009 sign_mask = 9223372036854775808ULL;
7010 assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7011 assign(result, binop(Iop_Or64, binop(Iop_And64, binop(Iop_Shl64, mkexpr(uop),
7012 unop(Iop_64to8, mkexpr(shift_amount))), mkU64(~sign_mask)),
7013 binop(Iop_And64, mkexpr(uop), mkU64(sign_mask))));
7014 put_gpr_dw0(r1, mkexpr(result));
7015 s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_64, op, shift_amount);
7016
7017 return "slag";
7018}
7019
7020static HChar *
7021s390_irgen_SLL(UChar r1, IRTemp op2addr)
7022{
7023 put_gpr_w1(r1, binop(Iop_Shl32, get_gpr_w1(r1), unop(Iop_64to8,
7024 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
7025
7026 return "sll";
7027}
7028
7029static HChar *
7030s390_irgen_SLLK(UChar r1, UChar r3, IRTemp op2addr)
7031{
7032 put_gpr_w1(r1, binop(Iop_Shl32, get_gpr_w1(r3), unop(Iop_64to8,
7033 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
7034
7035 return "sllk";
7036}
7037
7038static HChar *
7039s390_irgen_SLLG(UChar r1, UChar r3, IRTemp op2addr)
7040{
7041 put_gpr_dw0(r1, binop(Iop_Shl64, get_gpr_dw0(r3), unop(Iop_64to8,
7042 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
7043
7044 return "sllg";
7045}
7046
7047static HChar *
7048s390_irgen_SRDA(UChar r1, IRTemp op2addr)
7049{
7050 IRTemp p1 = newTemp(Ity_I64);
7051 IRTemp p2 = newTemp(Ity_I64);
7052 IRTemp result = newTemp(Ity_I64);
7053
7054 assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
7055 assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
7056 assign(result, binop(Iop_Sar64, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1),
7057 mkU8(32)), mkexpr(p2)), unop(Iop_64to8, binop(Iop_And64,
7058 mkexpr(op2addr), mkU64(63)))));
7059 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
7060 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
7061 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7062
7063 return "srda";
7064}
7065
7066static HChar *
7067s390_irgen_SRDL(UChar r1, IRTemp op2addr)
7068{
7069 IRTemp p1 = newTemp(Ity_I64);
7070 IRTemp p2 = newTemp(Ity_I64);
7071 IRTemp result = newTemp(Ity_I64);
7072
7073 assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
7074 assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
7075 assign(result, binop(Iop_Shr64, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1),
7076 mkU8(32)), mkexpr(p2)), unop(Iop_64to8, binop(Iop_And64,
7077 mkexpr(op2addr), mkU64(63)))));
7078 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
7079 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
7080
7081 return "srdl";
7082}
7083
7084static HChar *
7085s390_irgen_SRA(UChar r1, IRTemp op2addr)
7086{
7087 IRTemp result = newTemp(Ity_I32);
7088 IRTemp op = newTemp(Ity_I32);
7089
7090 assign(op, get_gpr_w1(r1));
7091 assign(result, binop(Iop_Sar32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7092 mkexpr(op2addr), mkU64(63)))));
7093 put_gpr_w1(r1, mkexpr(result));
7094 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7095
7096 return "sra";
7097}
7098
7099static HChar *
7100s390_irgen_SRAK(UChar r1, UChar r3, IRTemp op2addr)
7101{
7102 IRTemp result = newTemp(Ity_I32);
7103 IRTemp op = newTemp(Ity_I32);
7104
7105 assign(op, get_gpr_w1(r3));
7106 assign(result, binop(Iop_Sar32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7107 mkexpr(op2addr), mkU64(63)))));
7108 put_gpr_w1(r1, mkexpr(result));
7109 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7110
7111 return "srak";
7112}
7113
7114static HChar *
7115s390_irgen_SRAG(UChar r1, UChar r3, IRTemp op2addr)
7116{
7117 IRTemp result = newTemp(Ity_I64);
7118 IRTemp op = newTemp(Ity_I64);
7119
7120 assign(op, get_gpr_dw0(r3));
7121 assign(result, binop(Iop_Sar64, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7122 mkexpr(op2addr), mkU64(63)))));
7123 put_gpr_dw0(r1, mkexpr(result));
7124 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7125
7126 return "srag";
7127}
7128
7129static HChar *
7130s390_irgen_SRL(UChar r1, IRTemp op2addr)
7131{
7132 IRTemp op = newTemp(Ity_I32);
7133
7134 assign(op, get_gpr_w1(r1));
7135 put_gpr_w1(r1, binop(Iop_Shr32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7136 mkexpr(op2addr), mkU64(63)))));
7137
7138 return "srl";
7139}
7140
7141static HChar *
7142s390_irgen_SRLK(UChar r1, UChar r3, IRTemp op2addr)
7143{
7144 IRTemp op = newTemp(Ity_I32);
7145
7146 assign(op, get_gpr_w1(r3));
7147 put_gpr_w1(r1, binop(Iop_Shr32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7148 mkexpr(op2addr), mkU64(63)))));
7149
7150 return "srlk";
7151}
7152
7153static HChar *
7154s390_irgen_SRLG(UChar r1, UChar r3, IRTemp op2addr)
7155{
7156 IRTemp op = newTemp(Ity_I64);
7157
7158 assign(op, get_gpr_dw0(r3));
7159 put_gpr_dw0(r1, binop(Iop_Shr64, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7160 mkexpr(op2addr), mkU64(63)))));
7161
7162 return "srlg";
7163}
7164
7165static HChar *
7166s390_irgen_ST(UChar r1, IRTemp op2addr)
7167{
7168 store(mkexpr(op2addr), get_gpr_w1(r1));
7169
7170 return "st";
7171}
7172
7173static HChar *
7174s390_irgen_STY(UChar r1, IRTemp op2addr)
7175{
7176 store(mkexpr(op2addr), get_gpr_w1(r1));
7177
7178 return "sty";
7179}
7180
7181static HChar *
7182s390_irgen_STG(UChar r1, IRTemp op2addr)
7183{
7184 store(mkexpr(op2addr), get_gpr_dw0(r1));
7185
7186 return "stg";
7187}
7188
7189static HChar *
7190s390_irgen_STRL(UChar r1, UInt i2)
7191{
7192 store(mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)),
7193 get_gpr_w1(r1));
7194
7195 return "strl";
7196}
7197
7198static HChar *
7199s390_irgen_STGRL(UChar r1, UInt i2)
7200{
7201 store(mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)),
7202 get_gpr_dw0(r1));
7203
7204 return "stgrl";
7205}
7206
7207static HChar *
7208s390_irgen_STC(UChar r1, IRTemp op2addr)
7209{
7210 store(mkexpr(op2addr), get_gpr_b7(r1));
7211
7212 return "stc";
7213}
7214
7215static HChar *
7216s390_irgen_STCY(UChar r1, IRTemp op2addr)
7217{
7218 store(mkexpr(op2addr), get_gpr_b7(r1));
7219
7220 return "stcy";
7221}
7222
7223static HChar *
7224s390_irgen_STCH(UChar r1, IRTemp op2addr)
7225{
7226 store(mkexpr(op2addr), get_gpr_b3(r1));
7227
7228 return "stch";
7229}
7230
7231static HChar *
7232s390_irgen_STCM(UChar r1, UChar r3, IRTemp op2addr)
7233{
7234 UChar mask;
7235 UChar n;
7236
7237 mask = (UChar)r3;
7238 n = 0;
7239 if ((mask & 8) != 0) {
7240 store(mkexpr(op2addr), get_gpr_b4(r1));
7241 n = n + 1;
7242 }
7243 if ((mask & 4) != 0) {
7244 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b5(r1));
7245 n = n + 1;
7246 }
7247 if ((mask & 2) != 0) {
7248 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b6(r1));
7249 n = n + 1;
7250 }
7251 if ((mask & 1) != 0) {
7252 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b7(r1));
7253 }
7254
7255 return "stcm";
7256}
7257
7258static HChar *
7259s390_irgen_STCMY(UChar r1, UChar r3, IRTemp op2addr)
7260{
7261 UChar mask;
7262 UChar n;
7263
7264 mask = (UChar)r3;
7265 n = 0;
7266 if ((mask & 8) != 0) {
7267 store(mkexpr(op2addr), get_gpr_b4(r1));
7268 n = n + 1;
7269 }
7270 if ((mask & 4) != 0) {
7271 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b5(r1));
7272 n = n + 1;
7273 }
7274 if ((mask & 2) != 0) {
7275 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b6(r1));
7276 n = n + 1;
7277 }
7278 if ((mask & 1) != 0) {
7279 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b7(r1));
7280 }
7281
7282 return "stcmy";
7283}
7284
7285static HChar *
7286s390_irgen_STCMH(UChar r1, UChar r3, IRTemp op2addr)
7287{
7288 UChar mask;
7289 UChar n;
7290
7291 mask = (UChar)r3;
7292 n = 0;
7293 if ((mask & 8) != 0) {
7294 store(mkexpr(op2addr), get_gpr_b0(r1));
7295 n = n + 1;
7296 }
7297 if ((mask & 4) != 0) {
7298 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b1(r1));
7299 n = n + 1;
7300 }
7301 if ((mask & 2) != 0) {
7302 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b2(r1));
7303 n = n + 1;
7304 }
7305 if ((mask & 1) != 0) {
7306 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b3(r1));
7307 }
7308
7309 return "stcmh";
7310}
7311
7312static HChar *
7313s390_irgen_STH(UChar r1, IRTemp op2addr)
7314{
7315 store(mkexpr(op2addr), get_gpr_hw3(r1));
7316
7317 return "sth";
7318}
7319
7320static HChar *
7321s390_irgen_STHY(UChar r1, IRTemp op2addr)
7322{
7323 store(mkexpr(op2addr), get_gpr_hw3(r1));
7324
7325 return "sthy";
7326}
7327
7328static HChar *
7329s390_irgen_STHRL(UChar r1, UInt i2)
7330{
7331 store(mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)),
7332 get_gpr_hw3(r1));
7333
7334 return "sthrl";
7335}
7336
7337static HChar *
7338s390_irgen_STHH(UChar r1, IRTemp op2addr)
7339{
7340 store(mkexpr(op2addr), get_gpr_hw1(r1));
7341
7342 return "sthh";
7343}
7344
7345static HChar *
7346s390_irgen_STFH(UChar r1, IRTemp op2addr)
7347{
7348 store(mkexpr(op2addr), get_gpr_w0(r1));
7349
7350 return "stfh";
7351}
7352
7353static HChar *
sewardjd7bde722011-04-05 13:19:33 +00007354s390_irgen_STOC(UChar r1, IRTemp op2addr)
7355{
7356 /* condition is checked in format handler */
7357 store(mkexpr(op2addr), get_gpr_w1(r1));
7358
7359 return "stoc";
7360}
7361
7362static HChar *
7363s390_irgen_STOCG(UChar r1, IRTemp op2addr)
7364{
7365 /* condition is checked in format handler */
7366 store(mkexpr(op2addr), get_gpr_dw0(r1));
7367
7368 return "stocg";
7369}
7370
7371static HChar *
sewardj2019a972011-03-07 16:04:07 +00007372s390_irgen_STPQ(UChar r1, IRTemp op2addr)
7373{
7374 store(mkexpr(op2addr), get_gpr_dw0(r1));
7375 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(8)), get_gpr_dw0(r1 + 1));
7376
7377 return "stpq";
7378}
7379
7380static HChar *
7381s390_irgen_STRVH(UChar r1, IRTemp op2addr)
7382{
7383 store(mkexpr(op2addr), get_gpr_b7(r1));
7384 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(1)), get_gpr_b6(r1));
7385
7386 return "strvh";
7387}
7388
7389static HChar *
7390s390_irgen_STRV(UChar r1, IRTemp op2addr)
7391{
7392 store(mkexpr(op2addr), get_gpr_b7(r1));
7393 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(1)), get_gpr_b6(r1));
7394 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(2)), get_gpr_b5(r1));
7395 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(3)), get_gpr_b4(r1));
7396
7397 return "strv";
7398}
7399
7400static HChar *
7401s390_irgen_STRVG(UChar r1, IRTemp op2addr)
7402{
7403 store(mkexpr(op2addr), get_gpr_b7(r1));
7404 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(1)), get_gpr_b6(r1));
7405 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(2)), get_gpr_b5(r1));
7406 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(3)), get_gpr_b4(r1));
7407 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(4)), get_gpr_b3(r1));
7408 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(5)), get_gpr_b2(r1));
7409 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(6)), get_gpr_b1(r1));
7410 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(7)), get_gpr_b0(r1));
7411
7412 return "strvg";
7413}
7414
7415static HChar *
7416s390_irgen_SR(UChar r1, UChar r2)
7417{
7418 IRTemp op1 = newTemp(Ity_I32);
7419 IRTemp op2 = newTemp(Ity_I32);
7420 IRTemp result = newTemp(Ity_I32);
7421
7422 assign(op1, get_gpr_w1(r1));
7423 assign(op2, get_gpr_w1(r2));
7424 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7425 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
7426 put_gpr_w1(r1, mkexpr(result));
7427
7428 return "sr";
7429}
7430
7431static HChar *
7432s390_irgen_SGR(UChar r1, UChar r2)
7433{
7434 IRTemp op1 = newTemp(Ity_I64);
7435 IRTemp op2 = newTemp(Ity_I64);
7436 IRTemp result = newTemp(Ity_I64);
7437
7438 assign(op1, get_gpr_dw0(r1));
7439 assign(op2, get_gpr_dw0(r2));
7440 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7441 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
7442 put_gpr_dw0(r1, mkexpr(result));
7443
7444 return "sgr";
7445}
7446
7447static HChar *
7448s390_irgen_SGFR(UChar r1, UChar r2)
7449{
7450 IRTemp op1 = newTemp(Ity_I64);
7451 IRTemp op2 = newTemp(Ity_I64);
7452 IRTemp result = newTemp(Ity_I64);
7453
7454 assign(op1, get_gpr_dw0(r1));
7455 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
7456 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7457 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
7458 put_gpr_dw0(r1, mkexpr(result));
7459
7460 return "sgfr";
7461}
7462
7463static HChar *
7464s390_irgen_SRK(UChar r3, UChar r1, UChar r2)
7465{
7466 IRTemp op2 = newTemp(Ity_I32);
7467 IRTemp op3 = newTemp(Ity_I32);
7468 IRTemp result = newTemp(Ity_I32);
7469
7470 assign(op2, get_gpr_w1(r2));
7471 assign(op3, get_gpr_w1(r3));
7472 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
7473 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op2, op3);
7474 put_gpr_w1(r1, mkexpr(result));
7475
7476 return "srk";
7477}
7478
7479static HChar *
7480s390_irgen_SGRK(UChar r3, UChar r1, UChar r2)
7481{
7482 IRTemp op2 = newTemp(Ity_I64);
7483 IRTemp op3 = newTemp(Ity_I64);
7484 IRTemp result = newTemp(Ity_I64);
7485
7486 assign(op2, get_gpr_dw0(r2));
7487 assign(op3, get_gpr_dw0(r3));
7488 assign(result, binop(Iop_Sub64, mkexpr(op2), mkexpr(op3)));
7489 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op2, op3);
7490 put_gpr_dw0(r1, mkexpr(result));
7491
7492 return "sgrk";
7493}
7494
7495static HChar *
7496s390_irgen_S(UChar r1, IRTemp op2addr)
7497{
7498 IRTemp op1 = newTemp(Ity_I32);
7499 IRTemp op2 = newTemp(Ity_I32);
7500 IRTemp result = newTemp(Ity_I32);
7501
7502 assign(op1, get_gpr_w1(r1));
7503 assign(op2, load(Ity_I32, mkexpr(op2addr)));
7504 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7505 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
7506 put_gpr_w1(r1, mkexpr(result));
7507
7508 return "s";
7509}
7510
7511static HChar *
7512s390_irgen_SY(UChar r1, IRTemp op2addr)
7513{
7514 IRTemp op1 = newTemp(Ity_I32);
7515 IRTemp op2 = newTemp(Ity_I32);
7516 IRTemp result = newTemp(Ity_I32);
7517
7518 assign(op1, get_gpr_w1(r1));
7519 assign(op2, load(Ity_I32, mkexpr(op2addr)));
7520 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7521 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
7522 put_gpr_w1(r1, mkexpr(result));
7523
7524 return "sy";
7525}
7526
7527static HChar *
7528s390_irgen_SG(UChar r1, IRTemp op2addr)
7529{
7530 IRTemp op1 = newTemp(Ity_I64);
7531 IRTemp op2 = newTemp(Ity_I64);
7532 IRTemp result = newTemp(Ity_I64);
7533
7534 assign(op1, get_gpr_dw0(r1));
7535 assign(op2, load(Ity_I64, mkexpr(op2addr)));
7536 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7537 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
7538 put_gpr_dw0(r1, mkexpr(result));
7539
7540 return "sg";
7541}
7542
7543static HChar *
7544s390_irgen_SGF(UChar r1, IRTemp op2addr)
7545{
7546 IRTemp op1 = newTemp(Ity_I64);
7547 IRTemp op2 = newTemp(Ity_I64);
7548 IRTemp result = newTemp(Ity_I64);
7549
7550 assign(op1, get_gpr_dw0(r1));
7551 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
7552 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7553 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
7554 put_gpr_dw0(r1, mkexpr(result));
7555
7556 return "sgf";
7557}
7558
7559static HChar *
7560s390_irgen_SH(UChar r1, IRTemp op2addr)
7561{
7562 IRTemp op1 = newTemp(Ity_I32);
7563 IRTemp op2 = newTemp(Ity_I32);
7564 IRTemp result = newTemp(Ity_I32);
7565
7566 assign(op1, get_gpr_w1(r1));
7567 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
7568 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7569 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
7570 put_gpr_w1(r1, mkexpr(result));
7571
7572 return "sh";
7573}
7574
7575static HChar *
7576s390_irgen_SHY(UChar r1, IRTemp op2addr)
7577{
7578 IRTemp op1 = newTemp(Ity_I32);
7579 IRTemp op2 = newTemp(Ity_I32);
7580 IRTemp result = newTemp(Ity_I32);
7581
7582 assign(op1, get_gpr_w1(r1));
7583 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
7584 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7585 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
7586 put_gpr_w1(r1, mkexpr(result));
7587
7588 return "shy";
7589}
7590
7591static HChar *
7592s390_irgen_SHHHR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
7593{
7594 IRTemp op2 = newTemp(Ity_I32);
7595 IRTemp op3 = newTemp(Ity_I32);
7596 IRTemp result = newTemp(Ity_I32);
7597
7598 assign(op2, get_gpr_w0(r1));
7599 assign(op3, get_gpr_w0(r2));
7600 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
7601 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op2, op3);
7602 put_gpr_w0(r1, mkexpr(result));
7603
7604 return "shhhr";
7605}
7606
7607static HChar *
7608s390_irgen_SHHLR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
7609{
7610 IRTemp op2 = newTemp(Ity_I32);
7611 IRTemp op3 = newTemp(Ity_I32);
7612 IRTemp result = newTemp(Ity_I32);
7613
7614 assign(op2, get_gpr_w0(r1));
7615 assign(op3, get_gpr_w1(r2));
7616 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
7617 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op2, op3);
7618 put_gpr_w0(r1, mkexpr(result));
7619
7620 return "shhlr";
7621}
7622
7623static HChar *
7624s390_irgen_SLR(UChar r1, UChar r2)
7625{
7626 IRTemp op1 = newTemp(Ity_I32);
7627 IRTemp op2 = newTemp(Ity_I32);
7628 IRTemp result = newTemp(Ity_I32);
7629
7630 assign(op1, get_gpr_w1(r1));
7631 assign(op2, get_gpr_w1(r2));
7632 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7633 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, op2);
7634 put_gpr_w1(r1, mkexpr(result));
7635
7636 return "slr";
7637}
7638
7639static HChar *
7640s390_irgen_SLGR(UChar r1, UChar r2)
7641{
7642 IRTemp op1 = newTemp(Ity_I64);
7643 IRTemp op2 = newTemp(Ity_I64);
7644 IRTemp result = newTemp(Ity_I64);
7645
7646 assign(op1, get_gpr_dw0(r1));
7647 assign(op2, get_gpr_dw0(r2));
7648 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7649 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
7650 put_gpr_dw0(r1, mkexpr(result));
7651
7652 return "slgr";
7653}
7654
7655static HChar *
7656s390_irgen_SLGFR(UChar r1, UChar r2)
7657{
7658 IRTemp op1 = newTemp(Ity_I64);
7659 IRTemp op2 = newTemp(Ity_I64);
7660 IRTemp result = newTemp(Ity_I64);
7661
7662 assign(op1, get_gpr_dw0(r1));
7663 assign(op2, unop(Iop_32Uto64, get_gpr_w1(r2)));
7664 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7665 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
7666 put_gpr_dw0(r1, mkexpr(result));
7667
7668 return "slgfr";
7669}
7670
7671static HChar *
7672s390_irgen_SLRK(UChar r3, UChar r1, UChar r2)
7673{
7674 IRTemp op2 = newTemp(Ity_I32);
7675 IRTemp op3 = newTemp(Ity_I32);
7676 IRTemp result = newTemp(Ity_I32);
7677
7678 assign(op2, get_gpr_w1(r2));
7679 assign(op3, get_gpr_w1(r3));
7680 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
7681 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op2, op3);
7682 put_gpr_w1(r1, mkexpr(result));
7683
7684 return "slrk";
7685}
7686
7687static HChar *
7688s390_irgen_SLGRK(UChar r3, UChar r1, UChar r2)
7689{
7690 IRTemp op2 = newTemp(Ity_I64);
7691 IRTemp op3 = newTemp(Ity_I64);
7692 IRTemp result = newTemp(Ity_I64);
7693
7694 assign(op2, get_gpr_dw0(r2));
7695 assign(op3, get_gpr_dw0(r3));
7696 assign(result, binop(Iop_Sub64, mkexpr(op2), mkexpr(op3)));
7697 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op2, op3);
7698 put_gpr_dw0(r1, mkexpr(result));
7699
7700 return "slgrk";
7701}
7702
7703static HChar *
7704s390_irgen_SL(UChar r1, IRTemp op2addr)
7705{
7706 IRTemp op1 = newTemp(Ity_I32);
7707 IRTemp op2 = newTemp(Ity_I32);
7708 IRTemp result = newTemp(Ity_I32);
7709
7710 assign(op1, get_gpr_w1(r1));
7711 assign(op2, load(Ity_I32, mkexpr(op2addr)));
7712 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7713 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, op2);
7714 put_gpr_w1(r1, mkexpr(result));
7715
7716 return "sl";
7717}
7718
7719static HChar *
7720s390_irgen_SLY(UChar r1, IRTemp op2addr)
7721{
7722 IRTemp op1 = newTemp(Ity_I32);
7723 IRTemp op2 = newTemp(Ity_I32);
7724 IRTemp result = newTemp(Ity_I32);
7725
7726 assign(op1, get_gpr_w1(r1));
7727 assign(op2, load(Ity_I32, mkexpr(op2addr)));
7728 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7729 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, op2);
7730 put_gpr_w1(r1, mkexpr(result));
7731
7732 return "sly";
7733}
7734
7735static HChar *
7736s390_irgen_SLG(UChar r1, IRTemp op2addr)
7737{
7738 IRTemp op1 = newTemp(Ity_I64);
7739 IRTemp op2 = newTemp(Ity_I64);
7740 IRTemp result = newTemp(Ity_I64);
7741
7742 assign(op1, get_gpr_dw0(r1));
7743 assign(op2, load(Ity_I64, mkexpr(op2addr)));
7744 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7745 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
7746 put_gpr_dw0(r1, mkexpr(result));
7747
7748 return "slg";
7749}
7750
7751static HChar *
7752s390_irgen_SLGF(UChar r1, IRTemp op2addr)
7753{
7754 IRTemp op1 = newTemp(Ity_I64);
7755 IRTemp op2 = newTemp(Ity_I64);
7756 IRTemp result = newTemp(Ity_I64);
7757
7758 assign(op1, get_gpr_dw0(r1));
7759 assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
7760 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7761 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
7762 put_gpr_dw0(r1, mkexpr(result));
7763
7764 return "slgf";
7765}
7766
7767static HChar *
7768s390_irgen_SLFI(UChar r1, UInt i2)
7769{
7770 IRTemp op1 = newTemp(Ity_I32);
7771 UInt op2;
7772 IRTemp result = newTemp(Ity_I32);
7773
7774 assign(op1, get_gpr_w1(r1));
7775 op2 = i2;
7776 assign(result, binop(Iop_Sub32, mkexpr(op1), mkU32(op2)));
7777 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, mktemp(Ity_I32,
7778 mkU32(op2)));
7779 put_gpr_w1(r1, mkexpr(result));
7780
7781 return "slfi";
7782}
7783
7784static HChar *
7785s390_irgen_SLGFI(UChar r1, UInt i2)
7786{
7787 IRTemp op1 = newTemp(Ity_I64);
7788 ULong op2;
7789 IRTemp result = newTemp(Ity_I64);
7790
7791 assign(op1, get_gpr_dw0(r1));
7792 op2 = (ULong)i2;
7793 assign(result, binop(Iop_Sub64, mkexpr(op1), mkU64(op2)));
7794 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, mktemp(Ity_I64,
7795 mkU64(op2)));
7796 put_gpr_dw0(r1, mkexpr(result));
7797
7798 return "slgfi";
7799}
7800
7801static HChar *
7802s390_irgen_SLHHHR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
7803{
7804 IRTemp op2 = newTemp(Ity_I32);
7805 IRTemp op3 = newTemp(Ity_I32);
7806 IRTemp result = newTemp(Ity_I32);
7807
7808 assign(op2, get_gpr_w0(r1));
7809 assign(op3, get_gpr_w0(r2));
7810 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
7811 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op2, op3);
7812 put_gpr_w0(r1, mkexpr(result));
7813
7814 return "slhhhr";
7815}
7816
7817static HChar *
7818s390_irgen_SLHHLR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
7819{
7820 IRTemp op2 = newTemp(Ity_I32);
7821 IRTemp op3 = newTemp(Ity_I32);
7822 IRTemp result = newTemp(Ity_I32);
7823
7824 assign(op2, get_gpr_w0(r1));
7825 assign(op3, get_gpr_w1(r2));
7826 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
7827 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op2, op3);
7828 put_gpr_w0(r1, mkexpr(result));
7829
7830 return "slhhlr";
7831}
7832
7833static HChar *
7834s390_irgen_SLBR(UChar r1, UChar r2)
7835{
7836 IRTemp op1 = newTemp(Ity_I32);
7837 IRTemp op2 = newTemp(Ity_I32);
7838 IRTemp result = newTemp(Ity_I32);
7839 IRTemp borrow_in = newTemp(Ity_I32);
7840
7841 assign(op1, get_gpr_w1(r1));
7842 assign(op2, get_gpr_w1(r2));
7843 assign(borrow_in, binop(Iop_Sub32, mkU32(1), binop(Iop_Shr32,
7844 s390_call_calculate_cc(), mkU8(1))));
7845 assign(result, binop(Iop_Sub32, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)),
7846 mkexpr(borrow_in)));
7847 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_32, op1, op2, borrow_in);
7848 put_gpr_w1(r1, mkexpr(result));
7849
7850 return "slbr";
7851}
7852
7853static HChar *
7854s390_irgen_SLBGR(UChar r1, UChar r2)
7855{
7856 IRTemp op1 = newTemp(Ity_I64);
7857 IRTemp op2 = newTemp(Ity_I64);
7858 IRTemp result = newTemp(Ity_I64);
7859 IRTemp borrow_in = newTemp(Ity_I64);
7860
7861 assign(op1, get_gpr_dw0(r1));
7862 assign(op2, get_gpr_dw0(r2));
7863 assign(borrow_in, unop(Iop_32Uto64, binop(Iop_Sub32, mkU32(1),
7864 binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)))));
7865 assign(result, binop(Iop_Sub64, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)),
7866 mkexpr(borrow_in)));
7867 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_64, op1, op2, borrow_in);
7868 put_gpr_dw0(r1, mkexpr(result));
7869
7870 return "slbgr";
7871}
7872
7873static HChar *
7874s390_irgen_SLB(UChar r1, IRTemp op2addr)
7875{
7876 IRTemp op1 = newTemp(Ity_I32);
7877 IRTemp op2 = newTemp(Ity_I32);
7878 IRTemp result = newTemp(Ity_I32);
7879 IRTemp borrow_in = newTemp(Ity_I32);
7880
7881 assign(op1, get_gpr_w1(r1));
7882 assign(op2, load(Ity_I32, mkexpr(op2addr)));
7883 assign(borrow_in, binop(Iop_Sub32, mkU32(1), binop(Iop_Shr32,
7884 s390_call_calculate_cc(), mkU8(1))));
7885 assign(result, binop(Iop_Sub32, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)),
7886 mkexpr(borrow_in)));
7887 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_32, op1, op2, borrow_in);
7888 put_gpr_w1(r1, mkexpr(result));
7889
7890 return "slb";
7891}
7892
7893static HChar *
7894s390_irgen_SLBG(UChar r1, IRTemp op2addr)
7895{
7896 IRTemp op1 = newTemp(Ity_I64);
7897 IRTemp op2 = newTemp(Ity_I64);
7898 IRTemp result = newTemp(Ity_I64);
7899 IRTemp borrow_in = newTemp(Ity_I64);
7900
7901 assign(op1, get_gpr_dw0(r1));
7902 assign(op2, load(Ity_I64, mkexpr(op2addr)));
7903 assign(borrow_in, unop(Iop_32Uto64, binop(Iop_Sub32, mkU32(1),
7904 binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)))));
7905 assign(result, binop(Iop_Sub64, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)),
7906 mkexpr(borrow_in)));
7907 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_64, op1, op2, borrow_in);
7908 put_gpr_dw0(r1, mkexpr(result));
7909
7910 return "slbg";
7911}
7912
7913static HChar *
7914s390_irgen_SVC(UChar i)
7915{
7916 IRTemp sysno = newTemp(Ity_I64);
7917
7918 if (i != 0) {
7919 assign(sysno, mkU64(i));
7920 } else {
7921 assign(sysno, unop(Iop_32Uto64, get_gpr_w1(1)));
7922 }
7923 system_call(mkexpr(sysno));
7924
7925 return "svc";
7926}
7927
7928static HChar *
sewardj2019a972011-03-07 16:04:07 +00007929s390_irgen_TM(UChar i2, IRTemp op1addr)
7930{
7931 UChar mask;
7932 IRTemp value = newTemp(Ity_I8);
7933
7934 mask = i2;
7935 assign(value, load(Ity_I8, mkexpr(op1addr)));
7936 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_8, value, mktemp(Ity_I8,
7937 mkU8(mask)));
7938
7939 return "tm";
7940}
7941
7942static HChar *
7943s390_irgen_TMY(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 "tmy";
7954}
7955
7956static HChar *
7957s390_irgen_TMHH(UChar r1, UShort i2)
7958{
7959 UShort mask;
7960 IRTemp value = newTemp(Ity_I16);
7961
7962 mask = i2;
7963 assign(value, get_gpr_hw0(r1));
7964 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
7965 mkU16(mask)));
7966
7967 return "tmhh";
7968}
7969
7970static HChar *
7971s390_irgen_TMHL(UChar r1, UShort i2)
7972{
7973 UShort mask;
7974 IRTemp value = newTemp(Ity_I16);
7975
7976 mask = i2;
7977 assign(value, get_gpr_hw1(r1));
7978 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
7979 mkU16(mask)));
7980
7981 return "tmhl";
7982}
7983
7984static HChar *
7985s390_irgen_TMLH(UChar r1, UShort i2)
7986{
7987 UShort mask;
7988 IRTemp value = newTemp(Ity_I16);
7989
7990 mask = i2;
7991 assign(value, get_gpr_hw2(r1));
7992 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
7993 mkU16(mask)));
7994
7995 return "tmlh";
7996}
7997
7998static HChar *
7999s390_irgen_TMLL(UChar r1, UShort i2)
8000{
8001 UShort mask;
8002 IRTemp value = newTemp(Ity_I16);
8003
8004 mask = i2;
8005 assign(value, get_gpr_hw3(r1));
8006 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
8007 mkU16(mask)));
8008
8009 return "tmll";
8010}
8011
8012static HChar *
8013s390_irgen_EFPC(UChar r1)
8014{
8015 put_gpr_w1(r1, get_fpc_w0());
8016
8017 return "efpc";
8018}
8019
8020static HChar *
8021s390_irgen_LER(UChar r1, UChar r2)
8022{
8023 put_fpr_w0(r1, get_fpr_w0(r2));
8024
8025 return "ler";
8026}
8027
8028static HChar *
8029s390_irgen_LDR(UChar r1, UChar r2)
8030{
8031 put_fpr_dw0(r1, get_fpr_dw0(r2));
8032
8033 return "ldr";
8034}
8035
8036static HChar *
8037s390_irgen_LXR(UChar r1, UChar r2)
8038{
8039 put_fpr_dw0(r1, get_fpr_dw0(r2));
8040 put_fpr_dw0(r1 + 2, get_fpr_dw0(r2 + 2));
8041
8042 return "lxr";
8043}
8044
8045static HChar *
8046s390_irgen_LE(UChar r1, IRTemp op2addr)
8047{
8048 put_fpr_w0(r1, load(Ity_F32, mkexpr(op2addr)));
8049
8050 return "le";
8051}
8052
8053static HChar *
8054s390_irgen_LD(UChar r1, IRTemp op2addr)
8055{
8056 put_fpr_dw0(r1, load(Ity_F64, mkexpr(op2addr)));
8057
8058 return "ld";
8059}
8060
8061static HChar *
8062s390_irgen_LEY(UChar r1, IRTemp op2addr)
8063{
8064 put_fpr_w0(r1, load(Ity_F32, mkexpr(op2addr)));
8065
8066 return "ley";
8067}
8068
8069static HChar *
8070s390_irgen_LDY(UChar r1, IRTemp op2addr)
8071{
8072 put_fpr_dw0(r1, load(Ity_F64, mkexpr(op2addr)));
8073
8074 return "ldy";
8075}
8076
8077static HChar *
8078s390_irgen_LFPC(IRTemp op2addr)
8079{
8080 put_fpc_w0(load(Ity_I32, mkexpr(op2addr)));
8081
8082 return "lfpc";
8083}
8084
8085static HChar *
8086s390_irgen_LZER(UChar r1)
8087{
8088 put_fpr_w0(r1, mkF32i(0x0));
8089
8090 return "lzer";
8091}
8092
8093static HChar *
8094s390_irgen_LZDR(UChar r1)
8095{
8096 put_fpr_dw0(r1, mkF64i(0x0));
8097
8098 return "lzdr";
8099}
8100
8101static HChar *
8102s390_irgen_LZXR(UChar r1)
8103{
8104 put_fpr_dw0(r1, mkF64i(0x0));
8105 put_fpr_dw0(r1 + 2, mkF64i(0x0));
8106
8107 return "lzxr";
8108}
8109
8110static HChar *
8111s390_irgen_SRNM(IRTemp op2addr)
8112{
8113 UInt mask;
8114
8115 mask = 3;
8116 put_fpc_w0(binop(Iop_Or32, binop(Iop_And32, get_fpc_w0(), mkU32(~mask)),
8117 binop(Iop_And32, unop(Iop_64to32, mkexpr(op2addr)), mkU32(mask)))
8118 );
8119
8120 return "srnm";
8121}
8122
8123static HChar *
8124s390_irgen_SFPC(UChar r1)
8125{
8126 put_fpc_w0(get_gpr_w1(r1));
8127
8128 return "sfpc";
8129}
8130
8131static HChar *
8132s390_irgen_STE(UChar r1, IRTemp op2addr)
8133{
8134 store(mkexpr(op2addr), get_fpr_w0(r1));
8135
8136 return "ste";
8137}
8138
8139static HChar *
8140s390_irgen_STD(UChar r1, IRTemp op2addr)
8141{
8142 store(mkexpr(op2addr), get_fpr_dw0(r1));
8143
8144 return "std";
8145}
8146
8147static HChar *
8148s390_irgen_STEY(UChar r1, IRTemp op2addr)
8149{
8150 store(mkexpr(op2addr), get_fpr_w0(r1));
8151
8152 return "stey";
8153}
8154
8155static HChar *
8156s390_irgen_STDY(UChar r1, IRTemp op2addr)
8157{
8158 store(mkexpr(op2addr), get_fpr_dw0(r1));
8159
8160 return "stdy";
8161}
8162
8163static HChar *
8164s390_irgen_STFPC(IRTemp op2addr)
8165{
8166 store(mkexpr(op2addr), get_fpc_w0());
8167
8168 return "stfpc";
8169}
8170
8171static HChar *
8172s390_irgen_AEBR(UChar r1, UChar r2)
8173{
8174 IRTemp op1 = newTemp(Ity_F32);
8175 IRTemp op2 = newTemp(Ity_F32);
8176 IRTemp result = newTemp(Ity_F32);
8177
8178 assign(op1, get_fpr_w0(r1));
8179 assign(op2, get_fpr_w0(r2));
8180 assign(result, triop(Iop_AddF32, mkU32(Irrm_NEAREST), mkexpr(op1),
8181 mkexpr(op2)));
8182 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
8183 put_fpr_w0(r1, mkexpr(result));
8184
8185 return "aebr";
8186}
8187
8188static HChar *
8189s390_irgen_ADBR(UChar r1, UChar r2)
8190{
8191 IRTemp op1 = newTemp(Ity_F64);
8192 IRTemp op2 = newTemp(Ity_F64);
8193 IRTemp result = newTemp(Ity_F64);
8194
8195 assign(op1, get_fpr_dw0(r1));
8196 assign(op2, get_fpr_dw0(r2));
8197 assign(result, triop(Iop_AddF64, mkU32(Irrm_NEAREST), mkexpr(op1),
8198 mkexpr(op2)));
8199 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
8200 put_fpr_dw0(r1, mkexpr(result));
8201
8202 return "adbr";
8203}
8204
8205static HChar *
8206s390_irgen_AEB(UChar r1, IRTemp op2addr)
8207{
8208 IRTemp op1 = newTemp(Ity_F32);
8209 IRTemp op2 = newTemp(Ity_F32);
8210 IRTemp result = newTemp(Ity_F32);
8211
8212 assign(op1, get_fpr_w0(r1));
8213 assign(op2, load(Ity_F32, mkexpr(op2addr)));
8214 assign(result, triop(Iop_AddF32, mkU32(Irrm_NEAREST), mkexpr(op1),
8215 mkexpr(op2)));
8216 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
8217 put_fpr_w0(r1, mkexpr(result));
8218
8219 return "aeb";
8220}
8221
8222static HChar *
8223s390_irgen_ADB(UChar r1, IRTemp op2addr)
8224{
8225 IRTemp op1 = newTemp(Ity_F64);
8226 IRTemp op2 = newTemp(Ity_F64);
8227 IRTemp result = newTemp(Ity_F64);
8228
8229 assign(op1, get_fpr_dw0(r1));
8230 assign(op2, load(Ity_F64, mkexpr(op2addr)));
8231 assign(result, triop(Iop_AddF64, mkU32(Irrm_NEAREST), mkexpr(op1),
8232 mkexpr(op2)));
8233 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
8234 put_fpr_dw0(r1, mkexpr(result));
8235
8236 return "adb";
8237}
8238
8239static HChar *
8240s390_irgen_CEFBR(UChar r1, UChar r2)
8241{
8242 IRTemp op2 = newTemp(Ity_I32);
8243
8244 assign(op2, get_gpr_w1(r2));
8245 put_fpr_w0(r1, binop(Iop_I32StoF32, mkU32(Irrm_NEAREST), mkexpr(op2)));
8246
8247 return "cefbr";
8248}
8249
8250static HChar *
8251s390_irgen_CDFBR(UChar r1, UChar r2)
8252{
8253 IRTemp op2 = newTemp(Ity_I32);
8254
8255 assign(op2, get_gpr_w1(r2));
8256 put_fpr_dw0(r1, unop(Iop_I32StoF64, mkexpr(op2)));
8257
8258 return "cdfbr";
8259}
8260
8261static HChar *
8262s390_irgen_CEGBR(UChar r1, UChar r2)
8263{
8264 IRTemp op2 = newTemp(Ity_I64);
8265
8266 assign(op2, get_gpr_dw0(r2));
8267 put_fpr_w0(r1, binop(Iop_I64StoF32, mkU32(Irrm_NEAREST), mkexpr(op2)));
8268
8269 return "cegbr";
8270}
8271
8272static HChar *
8273s390_irgen_CDGBR(UChar r1, UChar r2)
8274{
8275 IRTemp op2 = newTemp(Ity_I64);
8276
8277 assign(op2, get_gpr_dw0(r2));
8278 put_fpr_dw0(r1, binop(Iop_I64StoF64, mkU32(Irrm_NEAREST), mkexpr(op2)));
8279
8280 return "cdgbr";
8281}
8282
8283static HChar *
florian1c8f7ff2012-09-01 00:12:11 +00008284s390_irgen_CELFBR(UChar m3, UChar m4 __attribute__((unused)),
8285 UChar r1, UChar r2)
8286{
floriane75dafa2012-09-01 17:54:09 +00008287 if (! s390_host_has_fpext) {
8288 emulation_failure(EmFail_S390X_fpext);
8289 } else {
8290 IRTemp op2 = newTemp(Ity_I32);
florian1c8f7ff2012-09-01 00:12:11 +00008291
floriane75dafa2012-09-01 17:54:09 +00008292 assign(op2, get_gpr_w1(r2));
8293 put_fpr_w0(r1, binop(Iop_I32UtoF32, mkU32(encode_rounding_mode(m3)),
8294 mkexpr(op2)));
8295 }
florian1c8f7ff2012-09-01 00:12:11 +00008296 return "celfbr";
8297}
8298
8299static HChar *
8300s390_irgen_CDLFBR(UChar m3, UChar m4 __attribute__((unused)),
8301 UChar r1, UChar r2)
8302{
floriane75dafa2012-09-01 17:54:09 +00008303 if (! s390_host_has_fpext) {
8304 emulation_failure(EmFail_S390X_fpext);
8305 } else {
8306 IRTemp op2 = newTemp(Ity_I32);
florian1c8f7ff2012-09-01 00:12:11 +00008307
floriane75dafa2012-09-01 17:54:09 +00008308 assign(op2, get_gpr_w1(r2));
8309 put_fpr_dw0(r1, unop(Iop_I32UtoF64, mkexpr(op2)));
8310 }
florian1c8f7ff2012-09-01 00:12:11 +00008311 return "cdlfbr";
8312}
8313
8314static HChar *
8315s390_irgen_CELGBR(UChar m3, UChar m4 __attribute__((unused)),
8316 UChar r1, UChar r2)
8317{
floriane75dafa2012-09-01 17:54:09 +00008318 if (! s390_host_has_fpext) {
8319 emulation_failure(EmFail_S390X_fpext);
8320 } else {
8321 IRTemp op2 = newTemp(Ity_I64);
florian1c8f7ff2012-09-01 00:12:11 +00008322
floriane75dafa2012-09-01 17:54:09 +00008323 assign(op2, get_gpr_dw0(r2));
8324 put_fpr_w0(r1, binop(Iop_I64UtoF32, mkU32(encode_rounding_mode(m3)),
8325 mkexpr(op2)));
8326 }
florian1c8f7ff2012-09-01 00:12:11 +00008327 return "celgbr";
8328}
8329
8330static HChar *
8331s390_irgen_CDLGBR(UChar m3, UChar m4 __attribute__((unused)),
8332 UChar r1, UChar r2)
8333{
floriane75dafa2012-09-01 17:54:09 +00008334 if (! s390_host_has_fpext) {
8335 emulation_failure(EmFail_S390X_fpext);
8336 } else {
8337 IRTemp op2 = newTemp(Ity_I64);
florian1c8f7ff2012-09-01 00:12:11 +00008338
floriane75dafa2012-09-01 17:54:09 +00008339 assign(op2, get_gpr_dw0(r2));
8340 put_fpr_dw0(r1, binop(Iop_I64UtoF64, mkU32(encode_rounding_mode(m3)),
8341 mkexpr(op2)));
8342 }
florian1c8f7ff2012-09-01 00:12:11 +00008343 return "cdlgbr";
8344}
8345
8346static HChar *
8347s390_irgen_CLFEBR(UChar m3, UChar m4 __attribute__((unused)),
8348 UChar r1, UChar r2)
8349{
floriane75dafa2012-09-01 17:54:09 +00008350 if (! s390_host_has_fpext) {
8351 emulation_failure(EmFail_S390X_fpext);
8352 } else {
8353 IRTemp op = newTemp(Ity_F32);
8354 IRTemp result = newTemp(Ity_I32);
florian1c8f7ff2012-09-01 00:12:11 +00008355
floriane75dafa2012-09-01 17:54:09 +00008356 assign(op, get_fpr_w0(r2));
8357 assign(result, binop(Iop_F32toI32U, mkU32(encode_rounding_mode(m3)),
8358 mkexpr(op)));
8359 put_gpr_w1(r1, mkexpr(result));
8360 s390_cc_thunk_putF(S390_CC_OP_BFP_32_TO_UINT_32, op);
8361 }
florian1c8f7ff2012-09-01 00:12:11 +00008362 return "clfebr";
8363}
8364
8365static HChar *
8366s390_irgen_CLFDBR(UChar m3, UChar m4 __attribute__((unused)),
8367 UChar r1, UChar r2)
8368{
floriane75dafa2012-09-01 17:54:09 +00008369 if (! s390_host_has_fpext) {
8370 emulation_failure(EmFail_S390X_fpext);
8371 } else {
8372 IRTemp op = newTemp(Ity_F64);
8373 IRTemp result = newTemp(Ity_I32);
florian1c8f7ff2012-09-01 00:12:11 +00008374
floriane75dafa2012-09-01 17:54:09 +00008375 assign(op, get_fpr_dw0(r2));
8376 assign(result, binop(Iop_F64toI32U, mkU32(encode_rounding_mode(m3)),
8377 mkexpr(op)));
8378 put_gpr_w1(r1, mkexpr(result));
8379 s390_cc_thunk_putF(S390_CC_OP_BFP_64_TO_UINT_32, op);
8380 }
florian1c8f7ff2012-09-01 00:12:11 +00008381 return "clfdbr";
8382}
8383
8384static HChar *
8385s390_irgen_CLGEBR(UChar m3, UChar m4 __attribute__((unused)),
8386 UChar r1, UChar r2)
8387{
floriane75dafa2012-09-01 17:54:09 +00008388 if (! s390_host_has_fpext) {
8389 emulation_failure(EmFail_S390X_fpext);
8390 } else {
8391 IRTemp op = newTemp(Ity_F32);
8392 IRTemp result = newTemp(Ity_I64);
florian1c8f7ff2012-09-01 00:12:11 +00008393
floriane75dafa2012-09-01 17:54:09 +00008394 assign(op, get_fpr_w0(r2));
8395 assign(result, binop(Iop_F32toI64U, mkU32(encode_rounding_mode(m3)),
8396 mkexpr(op)));
8397 put_gpr_dw0(r1, mkexpr(result));
8398 s390_cc_thunk_putF(S390_CC_OP_BFP_32_TO_UINT_64, op);
8399 }
florian1c8f7ff2012-09-01 00:12:11 +00008400 return "clgebr";
8401}
8402
8403static HChar *
8404s390_irgen_CLGDBR(UChar m3, UChar m4 __attribute__((unused)),
8405 UChar r1, UChar r2)
8406{
floriane75dafa2012-09-01 17:54:09 +00008407 if (! s390_host_has_fpext) {
8408 emulation_failure(EmFail_S390X_fpext);
8409 } else {
8410 IRTemp op = newTemp(Ity_F64);
8411 IRTemp result = newTemp(Ity_I64);
florian1c8f7ff2012-09-01 00:12:11 +00008412
floriane75dafa2012-09-01 17:54:09 +00008413 assign(op, get_fpr_dw0(r2));
8414 assign(result, binop(Iop_F64toI64U, mkU32(encode_rounding_mode(m3)),
8415 mkexpr(op)));
8416 put_gpr_dw0(r1, mkexpr(result));
8417 s390_cc_thunk_putF(S390_CC_OP_BFP_64_TO_UINT_64, op);
8418 }
florian1c8f7ff2012-09-01 00:12:11 +00008419 return "clgdbr";
8420}
8421
8422static HChar *
sewardj2019a972011-03-07 16:04:07 +00008423s390_irgen_CFEBR(UChar r3, UChar r1, UChar r2)
8424{
8425 IRTemp op = newTemp(Ity_F32);
8426 IRTemp result = newTemp(Ity_I32);
8427
8428 assign(op, get_fpr_w0(r2));
8429 assign(result, binop(Iop_F32toI32S, mkU32(encode_rounding_mode(r3)),
8430 mkexpr(op)));
8431 put_gpr_w1(r1, mkexpr(result));
8432 s390_cc_thunk_putF(S390_CC_OP_BFP_32_TO_INT_32, op);
8433
8434 return "cfebr";
8435}
8436
8437static HChar *
8438s390_irgen_CFDBR(UChar r3, UChar r1, UChar r2)
8439{
8440 IRTemp op = newTemp(Ity_F64);
8441 IRTemp result = newTemp(Ity_I32);
8442
8443 assign(op, get_fpr_dw0(r2));
8444 assign(result, binop(Iop_F64toI32S, mkU32(encode_rounding_mode(r3)),
8445 mkexpr(op)));
8446 put_gpr_w1(r1, mkexpr(result));
8447 s390_cc_thunk_putF(S390_CC_OP_BFP_64_TO_INT_32, op);
8448
8449 return "cfdbr";
8450}
8451
8452static HChar *
8453s390_irgen_CGEBR(UChar r3, UChar r1, UChar r2)
8454{
8455 IRTemp op = newTemp(Ity_F32);
8456 IRTemp result = newTemp(Ity_I64);
8457
8458 assign(op, get_fpr_w0(r2));
8459 assign(result, binop(Iop_F32toI64S, mkU32(encode_rounding_mode(r3)),
8460 mkexpr(op)));
8461 put_gpr_dw0(r1, mkexpr(result));
8462 s390_cc_thunk_putF(S390_CC_OP_BFP_32_TO_INT_64, op);
8463
8464 return "cgebr";
8465}
8466
8467static HChar *
8468s390_irgen_CGDBR(UChar r3, UChar r1, UChar r2)
8469{
8470 IRTemp op = newTemp(Ity_F64);
8471 IRTemp result = newTemp(Ity_I64);
8472
8473 assign(op, get_fpr_dw0(r2));
8474 assign(result, binop(Iop_F64toI64S, mkU32(encode_rounding_mode(r3)),
8475 mkexpr(op)));
8476 put_gpr_dw0(r1, mkexpr(result));
8477 s390_cc_thunk_putF(S390_CC_OP_BFP_64_TO_INT_64, op);
8478
8479 return "cgdbr";
8480}
8481
8482static HChar *
8483s390_irgen_DEBR(UChar r1, UChar r2)
8484{
8485 IRTemp op1 = newTemp(Ity_F32);
8486 IRTemp op2 = newTemp(Ity_F32);
8487 IRTemp result = newTemp(Ity_F32);
8488
8489 assign(op1, get_fpr_w0(r1));
8490 assign(op2, get_fpr_w0(r2));
8491 assign(result, triop(Iop_DivF32, mkU32(Irrm_NEAREST), mkexpr(op1),
8492 mkexpr(op2)));
8493 put_fpr_w0(r1, mkexpr(result));
8494
8495 return "debr";
8496}
8497
8498static HChar *
8499s390_irgen_DDBR(UChar r1, UChar r2)
8500{
8501 IRTemp op1 = newTemp(Ity_F64);
8502 IRTemp op2 = newTemp(Ity_F64);
8503 IRTemp result = newTemp(Ity_F64);
8504
8505 assign(op1, get_fpr_dw0(r1));
8506 assign(op2, get_fpr_dw0(r2));
8507 assign(result, triop(Iop_DivF64, mkU32(Irrm_NEAREST), mkexpr(op1),
8508 mkexpr(op2)));
8509 put_fpr_dw0(r1, mkexpr(result));
8510
8511 return "ddbr";
8512}
8513
8514static HChar *
8515s390_irgen_DEB(UChar r1, IRTemp op2addr)
8516{
8517 IRTemp op1 = newTemp(Ity_F32);
8518 IRTemp op2 = newTemp(Ity_F32);
8519 IRTemp result = newTemp(Ity_F32);
8520
8521 assign(op1, get_fpr_w0(r1));
8522 assign(op2, load(Ity_F32, mkexpr(op2addr)));
8523 assign(result, triop(Iop_DivF32, mkU32(Irrm_NEAREST), mkexpr(op1),
8524 mkexpr(op2)));
8525 put_fpr_w0(r1, mkexpr(result));
8526
8527 return "deb";
8528}
8529
8530static HChar *
8531s390_irgen_DDB(UChar r1, IRTemp op2addr)
8532{
8533 IRTemp op1 = newTemp(Ity_F64);
8534 IRTemp op2 = newTemp(Ity_F64);
8535 IRTemp result = newTemp(Ity_F64);
8536
8537 assign(op1, get_fpr_dw0(r1));
8538 assign(op2, load(Ity_F64, mkexpr(op2addr)));
8539 assign(result, triop(Iop_DivF64, mkU32(Irrm_NEAREST), mkexpr(op1),
8540 mkexpr(op2)));
8541 put_fpr_dw0(r1, mkexpr(result));
8542
8543 return "ddb";
8544}
8545
8546static HChar *
8547s390_irgen_LTEBR(UChar r1, UChar r2)
8548{
8549 IRTemp result = newTemp(Ity_F32);
8550
8551 assign(result, get_fpr_w0(r2));
8552 put_fpr_w0(r1, mkexpr(result));
8553 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
8554
8555 return "ltebr";
8556}
8557
8558static HChar *
8559s390_irgen_LTDBR(UChar r1, UChar r2)
8560{
8561 IRTemp result = newTemp(Ity_F64);
8562
8563 assign(result, get_fpr_dw0(r2));
8564 put_fpr_dw0(r1, mkexpr(result));
8565 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
8566
8567 return "ltdbr";
8568}
8569
8570static HChar *
8571s390_irgen_LCEBR(UChar r1, UChar r2)
8572{
8573 IRTemp result = newTemp(Ity_F32);
8574
8575 assign(result, unop(Iop_NegF32, get_fpr_w0(r2)));
8576 put_fpr_w0(r1, mkexpr(result));
8577 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
8578
8579 return "lcebr";
8580}
8581
8582static HChar *
8583s390_irgen_LCDBR(UChar r1, UChar r2)
8584{
8585 IRTemp result = newTemp(Ity_F64);
8586
8587 assign(result, unop(Iop_NegF64, get_fpr_dw0(r2)));
8588 put_fpr_dw0(r1, mkexpr(result));
8589 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
8590
8591 return "lcdbr";
8592}
8593
8594static HChar *
8595s390_irgen_LDEBR(UChar r1, UChar r2)
8596{
8597 IRTemp op = newTemp(Ity_F32);
8598
8599 assign(op, get_fpr_w0(r2));
8600 put_fpr_dw0(r1, unop(Iop_F32toF64, mkexpr(op)));
8601
8602 return "ldebr";
8603}
8604
8605static HChar *
8606s390_irgen_LDEB(UChar r1, IRTemp op2addr)
8607{
8608 IRTemp op = newTemp(Ity_F32);
8609
8610 assign(op, load(Ity_F32, mkexpr(op2addr)));
8611 put_fpr_dw0(r1, unop(Iop_F32toF64, mkexpr(op)));
8612
8613 return "ldeb";
8614}
8615
8616static HChar *
8617s390_irgen_LEDBR(UChar r1, UChar r2)
8618{
8619 IRTemp op = newTemp(Ity_F64);
8620
8621 assign(op, get_fpr_dw0(r2));
8622 put_fpr_w0(r1, binop(Iop_F64toF32, mkU32(Irrm_NEAREST), mkexpr(op)));
8623
8624 return "ledbr";
8625}
8626
8627static HChar *
8628s390_irgen_MEEBR(UChar r1, UChar r2)
8629{
8630 IRTemp op1 = newTemp(Ity_F32);
8631 IRTemp op2 = newTemp(Ity_F32);
8632 IRTemp result = newTemp(Ity_F32);
8633
8634 assign(op1, get_fpr_w0(r1));
8635 assign(op2, get_fpr_w0(r2));
8636 assign(result, triop(Iop_MulF32, mkU32(Irrm_NEAREST), mkexpr(op1),
8637 mkexpr(op2)));
8638 put_fpr_w0(r1, mkexpr(result));
8639
8640 return "meebr";
8641}
8642
8643static HChar *
8644s390_irgen_MDBR(UChar r1, UChar r2)
8645{
8646 IRTemp op1 = newTemp(Ity_F64);
8647 IRTemp op2 = newTemp(Ity_F64);
8648 IRTemp result = newTemp(Ity_F64);
8649
8650 assign(op1, get_fpr_dw0(r1));
8651 assign(op2, get_fpr_dw0(r2));
8652 assign(result, triop(Iop_MulF64, mkU32(Irrm_NEAREST), mkexpr(op1),
8653 mkexpr(op2)));
8654 put_fpr_dw0(r1, mkexpr(result));
8655
8656 return "mdbr";
8657}
8658
8659static HChar *
8660s390_irgen_MEEB(UChar r1, IRTemp op2addr)
8661{
8662 IRTemp op1 = newTemp(Ity_F32);
8663 IRTemp op2 = newTemp(Ity_F32);
8664 IRTemp result = newTemp(Ity_F32);
8665
8666 assign(op1, get_fpr_w0(r1));
8667 assign(op2, load(Ity_F32, mkexpr(op2addr)));
8668 assign(result, triop(Iop_MulF32, mkU32(Irrm_NEAREST), mkexpr(op1),
8669 mkexpr(op2)));
8670 put_fpr_w0(r1, mkexpr(result));
8671
8672 return "meeb";
8673}
8674
8675static HChar *
8676s390_irgen_MDB(UChar r1, IRTemp op2addr)
8677{
8678 IRTemp op1 = newTemp(Ity_F64);
8679 IRTemp op2 = newTemp(Ity_F64);
8680 IRTemp result = newTemp(Ity_F64);
8681
8682 assign(op1, get_fpr_dw0(r1));
8683 assign(op2, load(Ity_F64, mkexpr(op2addr)));
8684 assign(result, triop(Iop_MulF64, mkU32(Irrm_NEAREST), mkexpr(op1),
8685 mkexpr(op2)));
8686 put_fpr_dw0(r1, mkexpr(result));
8687
8688 return "mdb";
8689}
8690
8691static HChar *
8692s390_irgen_SEBR(UChar r1, UChar r2)
8693{
8694 IRTemp op1 = newTemp(Ity_F32);
8695 IRTemp op2 = newTemp(Ity_F32);
8696 IRTemp result = newTemp(Ity_F32);
8697
8698 assign(op1, get_fpr_w0(r1));
8699 assign(op2, get_fpr_w0(r2));
8700 assign(result, triop(Iop_SubF32, mkU32(Irrm_NEAREST), mkexpr(op1),
8701 mkexpr(op2)));
8702 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
8703 put_fpr_w0(r1, mkexpr(result));
8704
8705 return "sebr";
8706}
8707
8708static HChar *
8709s390_irgen_SDBR(UChar r1, UChar r2)
8710{
8711 IRTemp op1 = newTemp(Ity_F64);
8712 IRTemp op2 = newTemp(Ity_F64);
8713 IRTemp result = newTemp(Ity_F64);
8714
8715 assign(op1, get_fpr_dw0(r1));
8716 assign(op2, get_fpr_dw0(r2));
8717 assign(result, triop(Iop_SubF64, mkU32(Irrm_NEAREST), mkexpr(op1),
8718 mkexpr(op2)));
8719 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
8720 put_fpr_dw0(r1, mkexpr(result));
8721
8722 return "sdbr";
8723}
8724
8725static HChar *
8726s390_irgen_SEB(UChar r1, IRTemp op2addr)
8727{
8728 IRTemp op1 = newTemp(Ity_F32);
8729 IRTemp op2 = newTemp(Ity_F32);
8730 IRTemp result = newTemp(Ity_F32);
8731
8732 assign(op1, get_fpr_w0(r1));
8733 assign(op2, load(Ity_F32, mkexpr(op2addr)));
8734 assign(result, triop(Iop_SubF32, mkU32(Irrm_NEAREST), mkexpr(op1),
8735 mkexpr(op2)));
8736 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
8737 put_fpr_w0(r1, mkexpr(result));
8738
8739 return "seb";
8740}
8741
8742static HChar *
8743s390_irgen_SDB(UChar r1, IRTemp op2addr)
8744{
8745 IRTemp op1 = newTemp(Ity_F64);
8746 IRTemp op2 = newTemp(Ity_F64);
8747 IRTemp result = newTemp(Ity_F64);
8748
8749 assign(op1, get_fpr_dw0(r1));
8750 assign(op2, load(Ity_F64, mkexpr(op2addr)));
8751 assign(result, triop(Iop_SubF64, mkU32(Irrm_NEAREST), mkexpr(op1),
8752 mkexpr(op2)));
8753 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
8754 put_fpr_dw0(r1, mkexpr(result));
8755
8756 return "sdb";
8757}
8758
8759
8760static HChar *
8761s390_irgen_CLC(UChar length, IRTemp start1, IRTemp start2)
8762{
florian79e839e2012-05-05 02:20:30 +00008763 IRTemp len = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00008764
florian79e839e2012-05-05 02:20:30 +00008765 assign(len, mkU64(length));
8766 s390_irgen_CLC_EX(len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +00008767
8768 return "clc";
8769}
8770
8771static HChar *
florianb0c9a132011-09-08 15:37:39 +00008772s390_irgen_CLCL(UChar r1, UChar r2)
8773{
8774 IRTemp addr1 = newTemp(Ity_I64);
8775 IRTemp addr2 = newTemp(Ity_I64);
8776 IRTemp addr1_load = newTemp(Ity_I64);
8777 IRTemp addr2_load = newTemp(Ity_I64);
8778 IRTemp len1 = newTemp(Ity_I32);
8779 IRTemp len2 = newTemp(Ity_I32);
8780 IRTemp r1p1 = newTemp(Ity_I32); /* contents of r1 + 1 */
8781 IRTemp r2p1 = newTemp(Ity_I32); /* contents of r2 + 1 */
8782 IRTemp single1 = newTemp(Ity_I8);
8783 IRTemp single2 = newTemp(Ity_I8);
8784 IRTemp pad = newTemp(Ity_I8);
8785
8786 assign(addr1, get_gpr_dw0(r1));
8787 assign(r1p1, get_gpr_w1(r1 + 1));
8788 assign(len1, binop(Iop_And32, mkexpr(r1p1), mkU32(0x00ffffff)));
8789 assign(addr2, get_gpr_dw0(r2));
8790 assign(r2p1, get_gpr_w1(r2 + 1));
8791 assign(len2, binop(Iop_And32, mkexpr(r2p1), mkU32(0x00ffffff)));
8792 assign(pad, get_gpr_b4(r2 + 1));
8793
8794 /* len1 == 0 and len2 == 0? Exit */
8795 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +00008796 next_insn_if(binop(Iop_CmpEQ32, binop(Iop_Or32, mkexpr(len1),
8797 mkexpr(len2)), mkU32(0)));
florianb0c9a132011-09-08 15:37:39 +00008798
8799 /* Because mkite evaluates both the then-clause and the else-clause
8800 we cannot load directly from addr1 here. If len1 is 0, then adddr1
8801 may be NULL and loading from there would segfault. So we provide a
8802 valid dummy address in that case. Loading from there does no harm and
8803 the value will be discarded at runtime. */
8804 assign(addr1_load,
8805 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
8806 mkU64(guest_IA_curr_instr), mkexpr(addr1)));
8807 assign(single1,
8808 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
8809 mkexpr(pad), load(Ity_I8, mkexpr(addr1_load))));
8810
8811 assign(addr2_load,
8812 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
8813 mkU64(guest_IA_curr_instr), mkexpr(addr2)));
8814 assign(single2,
8815 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
8816 mkexpr(pad), load(Ity_I8, mkexpr(addr2_load))));
8817
8818 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, single1, single2, False);
8819 /* Fields differ ? */
florian6820ba52012-07-26 02:01:50 +00008820 next_insn_if(binop(Iop_CmpNE8, mkexpr(single1), mkexpr(single2)));
florianb0c9a132011-09-08 15:37:39 +00008821
8822 /* Update len1 and addr1, unless len1 == 0. */
8823 put_gpr_dw0(r1,
8824 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
8825 mkexpr(addr1),
8826 binop(Iop_Add64, mkexpr(addr1), mkU64(1))));
8827
8828 /* When updating len1 we must not modify bits (r1+1)[0:39] */
8829 put_gpr_w1(r1 + 1,
8830 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
8831 binop(Iop_And32, mkexpr(r1p1), mkU32(0xFF000000u)),
8832 binop(Iop_Sub32, mkexpr(r1p1), mkU32(1))));
8833
8834 /* Update len2 and addr2, unless len2 == 0. */
8835 put_gpr_dw0(r2,
8836 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
8837 mkexpr(addr2),
8838 binop(Iop_Add64, mkexpr(addr2), mkU64(1))));
8839
8840 /* When updating len2 we must not modify bits (r2+1)[0:39] */
8841 put_gpr_w1(r2 + 1,
8842 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
8843 binop(Iop_And32, mkexpr(r2p1), mkU32(0xFF000000u)),
8844 binop(Iop_Sub32, mkexpr(r2p1), mkU32(1))));
8845
florian6820ba52012-07-26 02:01:50 +00008846 iterate();
florianb0c9a132011-09-08 15:37:39 +00008847
8848 return "clcl";
8849}
8850
8851static HChar *
sewardj2019a972011-03-07 16:04:07 +00008852s390_irgen_CLCLE(UChar r1, UChar r3, IRTemp pad2)
8853{
8854 IRTemp addr1, addr3, addr1_load, addr3_load, len1, len3, single1, single3;
8855
8856 addr1 = newTemp(Ity_I64);
8857 addr3 = newTemp(Ity_I64);
8858 addr1_load = newTemp(Ity_I64);
8859 addr3_load = newTemp(Ity_I64);
8860 len1 = newTemp(Ity_I64);
8861 len3 = newTemp(Ity_I64);
8862 single1 = newTemp(Ity_I8);
8863 single3 = newTemp(Ity_I8);
8864
8865 assign(addr1, get_gpr_dw0(r1));
8866 assign(len1, get_gpr_dw0(r1 + 1));
8867 assign(addr3, get_gpr_dw0(r3));
8868 assign(len3, get_gpr_dw0(r3 + 1));
8869
8870 /* len1 == 0 and len3 == 0? Exit */
8871 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +00008872 next_insn_if(binop(Iop_CmpEQ64,binop(Iop_Or64, mkexpr(len1),
8873 mkexpr(len3)), mkU64(0)));
sewardj2019a972011-03-07 16:04:07 +00008874
8875 /* A mux requires both ways to be possible. This is a way to prevent clcle
8876 from reading from addr1 if it should read from the pad. Since the pad
8877 has no address, just read from the instruction, we discard that anyway */
8878 assign(addr1_load,
florian6ad49522011-09-09 02:38:55 +00008879 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
8880 mkU64(guest_IA_curr_instr), mkexpr(addr1)));
sewardj2019a972011-03-07 16:04:07 +00008881
8882 /* same for addr3 */
8883 assign(addr3_load,
florian6ad49522011-09-09 02:38:55 +00008884 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
8885 mkU64(guest_IA_curr_instr), mkexpr(addr3)));
sewardj2019a972011-03-07 16:04:07 +00008886
8887 assign(single1,
florian6ad49522011-09-09 02:38:55 +00008888 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
8889 unop(Iop_64to8, mkexpr(pad2)),
8890 load(Ity_I8, mkexpr(addr1_load))));
sewardj2019a972011-03-07 16:04:07 +00008891
8892 assign(single3,
florian6ad49522011-09-09 02:38:55 +00008893 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
8894 unop(Iop_64to8, mkexpr(pad2)),
8895 load(Ity_I8, mkexpr(addr3_load))));
sewardj2019a972011-03-07 16:04:07 +00008896
8897 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, single1, single3, False);
8898 /* Both fields differ ? */
florian6820ba52012-07-26 02:01:50 +00008899 next_insn_if(binop(Iop_CmpNE8, mkexpr(single1), mkexpr(single3)));
sewardj2019a972011-03-07 16:04:07 +00008900
8901 /* If a length in 0 we must not change this length and the address */
8902 put_gpr_dw0(r1,
florian6ad49522011-09-09 02:38:55 +00008903 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
8904 mkexpr(addr1),
8905 binop(Iop_Add64, mkexpr(addr1), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +00008906
8907 put_gpr_dw0(r1 + 1,
florian6ad49522011-09-09 02:38:55 +00008908 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
8909 mkU64(0), binop(Iop_Sub64, mkexpr(len1), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +00008910
8911 put_gpr_dw0(r3,
florian6ad49522011-09-09 02:38:55 +00008912 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
8913 mkexpr(addr3),
8914 binop(Iop_Add64, mkexpr(addr3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +00008915
8916 put_gpr_dw0(r3 + 1,
florian6ad49522011-09-09 02:38:55 +00008917 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
8918 mkU64(0), binop(Iop_Sub64, mkexpr(len3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +00008919
florian6820ba52012-07-26 02:01:50 +00008920 iterate();
sewardj2019a972011-03-07 16:04:07 +00008921
8922 return "clcle";
8923}
floriana64c2432011-07-16 02:11:50 +00008924
florianb0bf6602012-05-05 00:01:16 +00008925
sewardj2019a972011-03-07 16:04:07 +00008926static void
8927s390_irgen_XC_EX(IRTemp length, IRTemp start1, IRTemp start2)
8928{
florianb0bf6602012-05-05 00:01:16 +00008929 s390_irgen_xonc(Iop_Xor8, length, start1, start2);
8930}
sewardj2019a972011-03-07 16:04:07 +00008931
sewardj2019a972011-03-07 16:04:07 +00008932
florianb0bf6602012-05-05 00:01:16 +00008933static void
8934s390_irgen_NC_EX(IRTemp length, IRTemp start1, IRTemp start2)
8935{
8936 s390_irgen_xonc(Iop_And8, length, start1, start2);
8937}
sewardj2019a972011-03-07 16:04:07 +00008938
sewardj2019a972011-03-07 16:04:07 +00008939
florianb0bf6602012-05-05 00:01:16 +00008940static void
8941s390_irgen_OC_EX(IRTemp length, IRTemp start1, IRTemp start2)
8942{
8943 s390_irgen_xonc(Iop_Or8, length, start1, start2);
sewardj2019a972011-03-07 16:04:07 +00008944}
8945
8946
8947static void
8948s390_irgen_CLC_EX(IRTemp length, IRTemp start1, IRTemp start2)
8949{
8950 IRTemp current1 = newTemp(Ity_I8);
8951 IRTemp current2 = newTemp(Ity_I8);
8952 IRTemp counter = newTemp(Ity_I64);
8953
8954 assign(counter, get_counter_dw0());
8955 put_counter_dw0(mkU64(0));
8956
8957 assign(current1, load(Ity_I8, binop(Iop_Add64, mkexpr(start1),
8958 mkexpr(counter))));
8959 assign(current2, load(Ity_I8, binop(Iop_Add64, mkexpr(start2),
8960 mkexpr(counter))));
8961 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, current1, current2,
8962 False);
8963
8964 /* Both fields differ ? */
florian6820ba52012-07-26 02:01:50 +00008965 next_insn_if(binop(Iop_CmpNE8, mkexpr(current1), mkexpr(current2)));
sewardj2019a972011-03-07 16:04:07 +00008966
8967 /* Check for end of field */
8968 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
florian6820ba52012-07-26 02:01:50 +00008969 iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)));
sewardj2019a972011-03-07 16:04:07 +00008970 put_counter_dw0(mkU64(0));
8971}
8972
8973static void
8974s390_irgen_MVC_EX(IRTemp length, IRTemp start1, IRTemp start2)
8975{
8976 IRTemp counter = newTemp(Ity_I64);
8977
8978 assign(counter, get_counter_dw0());
8979
8980 store(binop(Iop_Add64, mkexpr(start1), mkexpr(counter)),
8981 load(Ity_I8, binop(Iop_Add64, mkexpr(start2), mkexpr(counter))));
8982
8983 /* Check for end of field */
8984 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
florian6820ba52012-07-26 02:01:50 +00008985 iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)));
sewardj2019a972011-03-07 16:04:07 +00008986 put_counter_dw0(mkU64(0));
8987}
8988
florianf87d4fb2012-05-05 02:55:24 +00008989static void
8990s390_irgen_TR_EX(IRTemp length, IRTemp start1, IRTemp start2)
8991{
8992 IRTemp op = newTemp(Ity_I8);
8993 IRTemp op1 = newTemp(Ity_I8);
8994 IRTemp result = newTemp(Ity_I64);
8995 IRTemp counter = newTemp(Ity_I64);
8996
8997 assign(counter, get_counter_dw0());
8998
8999 assign(op, load(Ity_I8, binop(Iop_Add64, mkexpr(start1), mkexpr(counter))));
9000
9001 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)), mkexpr(start2)));
9002
9003 assign(op1, load(Ity_I8, mkexpr(result)));
9004 store(binop(Iop_Add64, mkexpr(start1), mkexpr(counter)), mkexpr(op1));
9005
9006 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
florian6820ba52012-07-26 02:01:50 +00009007 iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)));
florianf87d4fb2012-05-05 02:55:24 +00009008 put_counter_dw0(mkU64(0));
9009}
sewardj2019a972011-03-07 16:04:07 +00009010
9011
9012static void
9013s390_irgen_EX_SS(UChar r, IRTemp addr2,
florian6820ba52012-07-26 02:01:50 +00009014 void (*irgen)(IRTemp length, IRTemp start1, IRTemp start2),
9015 int lensize)
sewardj2019a972011-03-07 16:04:07 +00009016{
9017 struct SS {
9018 unsigned int op : 8;
9019 unsigned int l : 8;
9020 unsigned int b1 : 4;
9021 unsigned int d1 : 12;
9022 unsigned int b2 : 4;
9023 unsigned int d2 : 12;
9024 };
9025 union {
9026 struct SS dec;
9027 unsigned long bytes;
9028 } ss;
9029 IRTemp cond;
9030 IRDirty *d;
9031 IRTemp torun;
9032
9033 IRTemp start1 = newTemp(Ity_I64);
9034 IRTemp start2 = newTemp(Ity_I64);
9035 IRTemp len = newTemp(lensize == 64 ? Ity_I64 : Ity_I32);
9036 cond = newTemp(Ity_I1);
9037 torun = newTemp(Ity_I64);
9038
9039 assign(torun, load(Ity_I64, mkexpr(addr2)));
9040 /* Start with a check that the saved code is still correct */
9041 assign(cond, binop(Iop_CmpNE64, mkexpr(torun), mkU64(last_execute_target)));
9042 /* If not, save the new value */
9043 d = unsafeIRDirty_0_N (0, "s390x_dirtyhelper_EX", &s390x_dirtyhelper_EX,
9044 mkIRExprVec_1(mkexpr(torun)));
9045 d->guard = mkexpr(cond);
9046 stmt(IRStmt_Dirty(d));
9047
9048 /* and restart */
florian428dfdd2012-03-27 03:09:49 +00009049 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TISTART),
9050 mkU64(guest_IA_curr_instr)));
9051 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TILEN), mkU64(4)));
florian6820ba52012-07-26 02:01:50 +00009052 restart_if(mkexpr(cond));
sewardj2019a972011-03-07 16:04:07 +00009053
9054 ss.bytes = last_execute_target;
9055 assign(start1, binop(Iop_Add64, mkU64(ss.dec.d1),
9056 ss.dec.b1 != 0 ? get_gpr_dw0(ss.dec.b1) : mkU64(0)));
9057 assign(start2, binop(Iop_Add64, mkU64(ss.dec.d2),
9058 ss.dec.b2 != 0 ? get_gpr_dw0(ss.dec.b2) : mkU64(0)));
9059 assign(len, unop(lensize == 64 ? Iop_8Uto64 : Iop_8Uto32, binop(Iop_Or8,
9060 r != 0 ? get_gpr_b7(r): mkU8(0), mkU8(ss.dec.l))));
9061 irgen(len, start1, start2);
florian8844a632012-04-13 04:04:06 +00009062
sewardj2019a972011-03-07 16:04:07 +00009063 last_execute_target = 0;
9064}
9065
9066static HChar *
9067s390_irgen_EX(UChar r1, IRTemp addr2)
9068{
9069 switch(last_execute_target & 0xff00000000000000ULL) {
9070 case 0:
9071 {
9072 /* no code information yet */
9073 IRDirty *d;
9074
9075 /* so safe the code... */
9076 d = unsafeIRDirty_0_N (0, "s390x_dirtyhelper_EX", &s390x_dirtyhelper_EX,
9077 mkIRExprVec_1(load(Ity_I64, mkexpr(addr2))));
9078 stmt(IRStmt_Dirty(d));
9079 /* and restart */
florian428dfdd2012-03-27 03:09:49 +00009080 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TISTART),
9081 mkU64(guest_IA_curr_instr)));
9082 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TILEN), mkU64(4)));
florian6820ba52012-07-26 02:01:50 +00009083 restart_if(IRExpr_Const(IRConst_U1(True)));
9084
sewardj2019a972011-03-07 16:04:07 +00009085 /* we know that this will be invalidated */
florianf9e1ed72012-04-17 02:41:56 +00009086 put_IA(mkaddr_expr(guest_IA_next_instr));
sewardj2019a972011-03-07 16:04:07 +00009087 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +00009088 dis_res->jk_StopHere = Ijk_TInval;
sewardj2019a972011-03-07 16:04:07 +00009089 break;
9090 }
9091
9092 case 0xd200000000000000ULL:
9093 /* special case MVC */
9094 s390_irgen_EX_SS(r1, addr2, s390_irgen_MVC_EX, 64);
9095 return "mvc via ex";
9096
9097 case 0xd500000000000000ULL:
9098 /* special case CLC */
9099 s390_irgen_EX_SS(r1, addr2, s390_irgen_CLC_EX, 64);
9100 return "clc via ex";
9101
9102 case 0xd700000000000000ULL:
9103 /* special case XC */
9104 s390_irgen_EX_SS(r1, addr2, s390_irgen_XC_EX, 32);
9105 return "xc via ex";
9106
florianb0bf6602012-05-05 00:01:16 +00009107 case 0xd600000000000000ULL:
9108 /* special case OC */
9109 s390_irgen_EX_SS(r1, addr2, s390_irgen_OC_EX, 32);
9110 return "oc via ex";
9111
9112 case 0xd400000000000000ULL:
9113 /* special case NC */
9114 s390_irgen_EX_SS(r1, addr2, s390_irgen_NC_EX, 32);
9115 return "nc via ex";
sewardj2019a972011-03-07 16:04:07 +00009116
florianf87d4fb2012-05-05 02:55:24 +00009117 case 0xdc00000000000000ULL:
9118 /* special case TR */
9119 s390_irgen_EX_SS(r1, addr2, s390_irgen_TR_EX, 64);
9120 return "tr via ex";
9121
sewardj2019a972011-03-07 16:04:07 +00009122 default:
9123 {
9124 /* everything else will get a self checking prefix that also checks the
9125 register content */
9126 IRDirty *d;
9127 UChar *bytes;
9128 IRTemp cond;
9129 IRTemp orperand;
9130 IRTemp torun;
9131
9132 cond = newTemp(Ity_I1);
9133 orperand = newTemp(Ity_I64);
9134 torun = newTemp(Ity_I64);
9135
9136 if (r1 == 0)
9137 assign(orperand, mkU64(0));
9138 else
9139 assign(orperand, unop(Iop_8Uto64,get_gpr_b7(r1)));
9140 /* This code is going to be translated */
9141 assign(torun, binop(Iop_Or64, load(Ity_I64, mkexpr(addr2)),
9142 binop(Iop_Shl64, mkexpr(orperand), mkU8(48))));
9143
9144 /* Start with a check that saved code is still correct */
9145 assign(cond, binop(Iop_CmpNE64, mkexpr(torun),
9146 mkU64(last_execute_target)));
9147 /* If not, save the new value */
9148 d = unsafeIRDirty_0_N (0, "s390x_dirtyhelper_EX", &s390x_dirtyhelper_EX,
9149 mkIRExprVec_1(mkexpr(torun)));
9150 d->guard = mkexpr(cond);
9151 stmt(IRStmt_Dirty(d));
9152
9153 /* and restart */
florian428dfdd2012-03-27 03:09:49 +00009154 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TISTART), mkU64(guest_IA_curr_instr)));
9155 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TILEN), mkU64(4)));
florian6820ba52012-07-26 02:01:50 +00009156 restart_if(mkexpr(cond));
sewardj2019a972011-03-07 16:04:07 +00009157
9158 /* Now comes the actual translation */
9159 bytes = (UChar *) &last_execute_target;
9160 s390_decode_and_irgen(bytes, ((((bytes[0] >> 6) + 1) >> 1) + 1) << 1,
9161 dis_res);
sewardj7ee97522011-05-09 21:45:04 +00009162 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00009163 vex_printf(" which was executed by\n");
9164 /* dont make useless translations in the next execute */
9165 last_execute_target = 0;
9166 }
9167 }
9168 return "ex";
9169}
9170
9171static HChar *
9172s390_irgen_EXRL(UChar r1, UInt offset)
9173{
9174 IRTemp addr = newTemp(Ity_I64);
9175 /* we might save one round trip because we know the target */
9176 if (!last_execute_target)
9177 last_execute_target = *(ULong *)(HWord)
9178 (guest_IA_curr_instr + offset * 2UL);
9179 assign(addr, mkU64(guest_IA_curr_instr + offset * 2UL));
9180 s390_irgen_EX(r1, addr);
9181 return "exrl";
9182}
9183
9184static HChar *
9185s390_irgen_IPM(UChar r1)
9186{
9187 // As long as we dont support SPM, lets just assume 0 as program mask
9188 put_gpr_b4(r1, unop(Iop_32to8, binop(Iop_Or32, mkU32(0 /* program mask */),
9189 binop(Iop_Shl32, s390_call_calculate_cc(), mkU8(4)))));
9190
9191 return "ipm";
9192}
9193
9194
9195static HChar *
9196s390_irgen_SRST(UChar r1, UChar r2)
9197{
9198 IRTemp address = newTemp(Ity_I64);
9199 IRTemp next = newTemp(Ity_I64);
9200 IRTemp delim = newTemp(Ity_I8);
9201 IRTemp counter = newTemp(Ity_I64);
9202 IRTemp byte = newTemp(Ity_I8);
9203
9204 assign(address, get_gpr_dw0(r2));
9205 assign(next, get_gpr_dw0(r1));
9206
9207 assign(counter, get_counter_dw0());
9208 put_counter_dw0(mkU64(0));
9209
9210 // start = next? CC=2 and out r1 and r2 unchanged
9211 s390_cc_set(2);
9212 put_gpr_dw0(r2, binop(Iop_Sub64, mkexpr(address), mkexpr(counter)));
florian6820ba52012-07-26 02:01:50 +00009213 next_insn_if(binop(Iop_CmpEQ64, mkexpr(address), mkexpr(next)));
sewardj2019a972011-03-07 16:04:07 +00009214
9215 assign(byte, load(Ity_I8, mkexpr(address)));
9216 assign(delim, get_gpr_b7(0));
9217
9218 // byte = delim? CC=1, R1=address
9219 s390_cc_set(1);
9220 put_gpr_dw0(r1, mkexpr(address));
florian6820ba52012-07-26 02:01:50 +00009221 next_insn_if(binop(Iop_CmpEQ8, mkexpr(delim), mkexpr(byte)));
sewardj2019a972011-03-07 16:04:07 +00009222
9223 // else: all equal, no end yet, loop
9224 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
9225 put_gpr_dw0(r1, mkexpr(next));
9226 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(address), mkU64(1)));
floriancf87c942012-07-25 00:52:21 +00009227
florian6820ba52012-07-26 02:01:50 +00009228 iterate();
sewardj2019a972011-03-07 16:04:07 +00009229
9230 return "srst";
9231}
9232
9233static HChar *
9234s390_irgen_CLST(UChar r1, UChar r2)
9235{
9236 IRTemp address1 = newTemp(Ity_I64);
9237 IRTemp address2 = newTemp(Ity_I64);
9238 IRTemp end = newTemp(Ity_I8);
9239 IRTemp counter = newTemp(Ity_I64);
9240 IRTemp byte1 = newTemp(Ity_I8);
9241 IRTemp byte2 = newTemp(Ity_I8);
9242
9243 assign(address1, get_gpr_dw0(r1));
9244 assign(address2, get_gpr_dw0(r2));
9245 assign(end, get_gpr_b7(0));
9246 assign(counter, get_counter_dw0());
9247 put_counter_dw0(mkU64(0));
9248 assign(byte1, load(Ity_I8, mkexpr(address1)));
9249 assign(byte2, load(Ity_I8, mkexpr(address2)));
9250
9251 // end in both? all equal, reset r1 and r2 to start values
9252 s390_cc_set(0);
9253 put_gpr_dw0(r1, binop(Iop_Sub64, mkexpr(address1), mkexpr(counter)));
9254 put_gpr_dw0(r2, binop(Iop_Sub64, mkexpr(address2), mkexpr(counter)));
florian6820ba52012-07-26 02:01:50 +00009255 next_insn_if(binop(Iop_CmpEQ8, mkU8(0),
9256 binop(Iop_Or8,
9257 binop(Iop_Xor8, mkexpr(byte1), mkexpr(end)),
9258 binop(Iop_Xor8, mkexpr(byte2), mkexpr(end)))));
sewardj2019a972011-03-07 16:04:07 +00009259
9260 put_gpr_dw0(r1, mkexpr(address1));
9261 put_gpr_dw0(r2, mkexpr(address2));
9262
9263 // End found in string1
9264 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +00009265 next_insn_if(binop(Iop_CmpEQ8, mkexpr(end), mkexpr(byte1)));
sewardj2019a972011-03-07 16:04:07 +00009266
9267 // End found in string2
9268 s390_cc_set(2);
florian6820ba52012-07-26 02:01:50 +00009269 next_insn_if(binop(Iop_CmpEQ8, mkexpr(end), mkexpr(byte2)));
sewardj2019a972011-03-07 16:04:07 +00009270
9271 // string1 < string2
9272 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +00009273 next_insn_if(binop(Iop_CmpLT32U, unop(Iop_8Uto32, mkexpr(byte1)),
9274 unop(Iop_8Uto32, mkexpr(byte2))));
sewardj2019a972011-03-07 16:04:07 +00009275
9276 // string2 < string1
9277 s390_cc_set(2);
florian6820ba52012-07-26 02:01:50 +00009278 next_insn_if(binop(Iop_CmpLT32U, unop(Iop_8Uto32, mkexpr(byte2)),
9279 unop(Iop_8Uto32, mkexpr(byte1))));
sewardj2019a972011-03-07 16:04:07 +00009280
9281 // else: all equal, no end yet, loop
9282 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
9283 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), mkU64(1)));
9284 put_gpr_dw0(r2, binop(Iop_Add64, get_gpr_dw0(r2), mkU64(1)));
floriancf87c942012-07-25 00:52:21 +00009285
florian6820ba52012-07-26 02:01:50 +00009286 iterate();
sewardj2019a972011-03-07 16:04:07 +00009287
9288 return "clst";
9289}
9290
9291static void
9292s390_irgen_load_multiple_32bit(UChar r1, UChar r3, IRTemp op2addr)
9293{
9294 UChar reg;
9295 IRTemp addr = newTemp(Ity_I64);
9296
9297 assign(addr, mkexpr(op2addr));
9298 reg = r1;
9299 do {
9300 IRTemp old = addr;
9301
9302 reg %= 16;
9303 put_gpr_w1(reg, load(Ity_I32, mkexpr(addr)));
9304 addr = newTemp(Ity_I64);
9305 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
9306 reg++;
9307 } while (reg != (r3 + 1));
9308}
9309
9310static HChar *
9311s390_irgen_LM(UChar r1, UChar r3, IRTemp op2addr)
9312{
9313 s390_irgen_load_multiple_32bit(r1, r3, op2addr);
9314
9315 return "lm";
9316}
9317
9318static HChar *
9319s390_irgen_LMY(UChar r1, UChar r3, IRTemp op2addr)
9320{
9321 s390_irgen_load_multiple_32bit(r1, r3, op2addr);
9322
9323 return "lmy";
9324}
9325
9326static HChar *
9327s390_irgen_LMH(UChar r1, UChar r3, IRTemp op2addr)
9328{
9329 UChar reg;
9330 IRTemp addr = newTemp(Ity_I64);
9331
9332 assign(addr, mkexpr(op2addr));
9333 reg = r1;
9334 do {
9335 IRTemp old = addr;
9336
9337 reg %= 16;
9338 put_gpr_w0(reg, load(Ity_I32, mkexpr(addr)));
9339 addr = newTemp(Ity_I64);
9340 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
9341 reg++;
9342 } while (reg != (r3 + 1));
9343
9344 return "lmh";
9345}
9346
9347static HChar *
9348s390_irgen_LMG(UChar r1, UChar r3, IRTemp op2addr)
9349{
9350 UChar reg;
9351 IRTemp addr = newTemp(Ity_I64);
9352
9353 assign(addr, mkexpr(op2addr));
9354 reg = r1;
9355 do {
9356 IRTemp old = addr;
9357
9358 reg %= 16;
9359 put_gpr_dw0(reg, load(Ity_I64, mkexpr(addr)));
9360 addr = newTemp(Ity_I64);
9361 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(8)));
9362 reg++;
9363 } while (reg != (r3 + 1));
9364
9365 return "lmg";
9366}
9367
9368static void
9369s390_irgen_store_multiple_32bit(UChar r1, UChar r3, IRTemp op2addr)
9370{
9371 UChar reg;
9372 IRTemp addr = newTemp(Ity_I64);
9373
9374 assign(addr, mkexpr(op2addr));
9375 reg = r1;
9376 do {
9377 IRTemp old = addr;
9378
9379 reg %= 16;
9380 store(mkexpr(addr), get_gpr_w1(reg));
9381 addr = newTemp(Ity_I64);
9382 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
9383 reg++;
9384 } while( reg != (r3 + 1));
9385}
9386
9387static HChar *
9388s390_irgen_STM(UChar r1, UChar r3, IRTemp op2addr)
9389{
9390 s390_irgen_store_multiple_32bit(r1, r3, op2addr);
9391
9392 return "stm";
9393}
9394
9395static HChar *
9396s390_irgen_STMY(UChar r1, UChar r3, IRTemp op2addr)
9397{
9398 s390_irgen_store_multiple_32bit(r1, r3, op2addr);
9399
9400 return "stmy";
9401}
9402
9403static HChar *
9404s390_irgen_STMH(UChar r1, UChar r3, IRTemp op2addr)
9405{
9406 UChar reg;
9407 IRTemp addr = newTemp(Ity_I64);
9408
9409 assign(addr, mkexpr(op2addr));
9410 reg = r1;
9411 do {
9412 IRTemp old = addr;
9413
9414 reg %= 16;
9415 store(mkexpr(addr), get_gpr_w0(reg));
9416 addr = newTemp(Ity_I64);
9417 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
9418 reg++;
9419 } while( reg != (r3 + 1));
9420
9421 return "stmh";
9422}
9423
9424static HChar *
9425s390_irgen_STMG(UChar r1, UChar r3, IRTemp op2addr)
9426{
9427 UChar reg;
9428 IRTemp addr = newTemp(Ity_I64);
9429
9430 assign(addr, mkexpr(op2addr));
9431 reg = r1;
9432 do {
9433 IRTemp old = addr;
9434
9435 reg %= 16;
9436 store(mkexpr(addr), get_gpr_dw0(reg));
9437 addr = newTemp(Ity_I64);
9438 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(8)));
9439 reg++;
9440 } while( reg != (r3 + 1));
9441
9442 return "stmg";
9443}
9444
9445static void
florianb0bf6602012-05-05 00:01:16 +00009446s390_irgen_xonc(IROp op, IRTemp length, IRTemp start1, IRTemp start2)
sewardj2019a972011-03-07 16:04:07 +00009447{
9448 IRTemp old1 = newTemp(Ity_I8);
9449 IRTemp old2 = newTemp(Ity_I8);
9450 IRTemp new1 = newTemp(Ity_I8);
9451 IRTemp counter = newTemp(Ity_I32);
9452 IRTemp addr1 = newTemp(Ity_I64);
9453
9454 assign(counter, get_counter_w0());
9455
9456 assign(addr1, binop(Iop_Add64, mkexpr(start1),
9457 unop(Iop_32Uto64, mkexpr(counter))));
9458
9459 assign(old1, load(Ity_I8, mkexpr(addr1)));
9460 assign(old2, load(Ity_I8, binop(Iop_Add64, mkexpr(start2),
9461 unop(Iop_32Uto64,mkexpr(counter)))));
9462 assign(new1, binop(op, mkexpr(old1), mkexpr(old2)));
9463
9464 /* Special case: xc is used to zero memory */
sewardj2019a972011-03-07 16:04:07 +00009465 if (op == Iop_Xor8) {
9466 store(mkexpr(addr1),
florian6ad49522011-09-09 02:38:55 +00009467 mkite(binop(Iop_CmpEQ64, mkexpr(start1), mkexpr(start2)),
9468 mkU8(0), mkexpr(new1)));
sewardj2019a972011-03-07 16:04:07 +00009469 } else
9470 store(mkexpr(addr1), mkexpr(new1));
9471 put_counter_w1(binop(Iop_Or32, unop(Iop_8Uto32, mkexpr(new1)),
9472 get_counter_w1()));
9473
9474 /* Check for end of field */
9475 put_counter_w0(binop(Iop_Add32, mkexpr(counter), mkU32(1)));
florian6820ba52012-07-26 02:01:50 +00009476 iterate_if(binop(Iop_CmpNE32, mkexpr(counter), mkexpr(length)));
sewardj2019a972011-03-07 16:04:07 +00009477 s390_cc_thunk_put1(S390_CC_OP_BITWISE, mktemp(Ity_I32, get_counter_w1()),
9478 False);
9479 put_counter_dw0(mkU64(0));
9480}
9481
9482static HChar *
9483s390_irgen_XC(UChar length, IRTemp start1, IRTemp start2)
9484{
florianb0bf6602012-05-05 00:01:16 +00009485 IRTemp len = newTemp(Ity_I32);
9486
9487 assign(len, mkU32(length));
9488 s390_irgen_xonc(Iop_Xor8, len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +00009489
9490 return "xc";
9491}
9492
sewardjb63967e2011-03-24 08:50:04 +00009493static void
9494s390_irgen_XC_sameloc(UChar length, UChar b, UShort d)
9495{
9496 IRTemp counter = newTemp(Ity_I32);
9497 IRTemp start = newTemp(Ity_I64);
9498 IRTemp addr = newTemp(Ity_I64);
9499
9500 assign(start,
9501 binop(Iop_Add64, mkU64(d), b != 0 ? get_gpr_dw0(b) : mkU64(0)));
9502
9503 if (length < 8) {
9504 UInt i;
9505
9506 for (i = 0; i <= length; ++i) {
9507 store(binop(Iop_Add64, mkexpr(start), mkU64(i)), mkU8(0));
9508 }
9509 } else {
9510 assign(counter, get_counter_w0());
9511
9512 assign(addr, binop(Iop_Add64, mkexpr(start),
9513 unop(Iop_32Uto64, mkexpr(counter))));
9514
9515 store(mkexpr(addr), mkU8(0));
9516
9517 /* Check for end of field */
9518 put_counter_w0(binop(Iop_Add32, mkexpr(counter), mkU32(1)));
florian6820ba52012-07-26 02:01:50 +00009519 iterate_if(binop(Iop_CmpNE32, mkexpr(counter), mkU32(length)));
sewardjb63967e2011-03-24 08:50:04 +00009520
9521 /* Reset counter */
9522 put_counter_dw0(mkU64(0));
9523 }
9524
9525 s390_cc_thunk_put1(S390_CC_OP_BITWISE, mktemp(Ity_I32, mkU32(0)), False);
9526
sewardj7ee97522011-05-09 21:45:04 +00009527 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardjb63967e2011-03-24 08:50:04 +00009528 s390_disasm(ENC3(MNM, UDLB, UDXB), "xc", d, length, b, d, 0, b);
9529}
9530
sewardj2019a972011-03-07 16:04:07 +00009531static HChar *
9532s390_irgen_NC(UChar length, IRTemp start1, IRTemp start2)
9533{
florianb0bf6602012-05-05 00:01:16 +00009534 IRTemp len = newTemp(Ity_I32);
9535
9536 assign(len, mkU32(length));
9537 s390_irgen_xonc(Iop_And8, len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +00009538
9539 return "nc";
9540}
9541
9542static HChar *
9543s390_irgen_OC(UChar length, IRTemp start1, IRTemp start2)
9544{
florianb0bf6602012-05-05 00:01:16 +00009545 IRTemp len = newTemp(Ity_I32);
9546
9547 assign(len, mkU32(length));
9548 s390_irgen_xonc(Iop_Or8, len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +00009549
9550 return "oc";
9551}
9552
9553
9554static HChar *
9555s390_irgen_MVC(UChar length, IRTemp start1, IRTemp start2)
9556{
florian79e839e2012-05-05 02:20:30 +00009557 IRTemp len = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00009558
florian79e839e2012-05-05 02:20:30 +00009559 assign(len, mkU64(length));
9560 s390_irgen_MVC_EX(len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +00009561
9562 return "mvc";
9563}
9564
9565static HChar *
florianb0c9a132011-09-08 15:37:39 +00009566s390_irgen_MVCL(UChar r1, UChar r2)
9567{
9568 IRTemp addr1 = newTemp(Ity_I64);
9569 IRTemp addr2 = newTemp(Ity_I64);
9570 IRTemp addr2_load = newTemp(Ity_I64);
9571 IRTemp r1p1 = newTemp(Ity_I32); /* contents of r1 + 1 */
9572 IRTemp r2p1 = newTemp(Ity_I32); /* contents of r2 + 1 */
9573 IRTemp len1 = newTemp(Ity_I32);
9574 IRTemp len2 = newTemp(Ity_I32);
9575 IRTemp pad = newTemp(Ity_I8);
9576 IRTemp single = newTemp(Ity_I8);
9577
9578 assign(addr1, get_gpr_dw0(r1));
9579 assign(r1p1, get_gpr_w1(r1 + 1));
9580 assign(len1, binop(Iop_And32, mkexpr(r1p1), mkU32(0x00ffffff)));
9581 assign(addr2, get_gpr_dw0(r2));
9582 assign(r2p1, get_gpr_w1(r2 + 1));
9583 assign(len2, binop(Iop_And32, mkexpr(r2p1), mkU32(0x00ffffff)));
9584 assign(pad, get_gpr_b4(r2 + 1));
9585
9586 /* len1 == 0 ? */
9587 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len2, False);
florian6820ba52012-07-26 02:01:50 +00009588 next_insn_if(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)));
florianb0c9a132011-09-08 15:37:39 +00009589
9590 /* Check for destructive overlap:
9591 addr1 > addr2 && addr2 + len1 > addr1 && (addr2 + len2) > addr1 */
9592 s390_cc_set(3);
9593 IRTemp cond1 = newTemp(Ity_I32);
9594 assign(cond1, unop(Iop_1Uto32,
9595 binop(Iop_CmpLT64U, mkexpr(addr2), mkexpr(addr1))));
9596 IRTemp cond2 = newTemp(Ity_I32);
9597 assign(cond2, unop(Iop_1Uto32,
9598 binop(Iop_CmpLT64U, mkexpr(addr1),
9599 binop(Iop_Add64, mkexpr(addr2),
9600 unop(Iop_32Uto64, mkexpr(len1))))));
9601 IRTemp cond3 = newTemp(Ity_I32);
9602 assign(cond3, unop(Iop_1Uto32,
9603 binop(Iop_CmpLT64U,
9604 mkexpr(addr1),
9605 binop(Iop_Add64, mkexpr(addr2),
9606 unop(Iop_32Uto64, mkexpr(len2))))));
9607
florian6820ba52012-07-26 02:01:50 +00009608 next_insn_if(binop(Iop_CmpEQ32,
9609 binop(Iop_And32,
9610 binop(Iop_And32, mkexpr(cond1), mkexpr(cond2)),
9611 mkexpr(cond3)),
9612 mkU32(1)));
florianb0c9a132011-09-08 15:37:39 +00009613
9614 /* See s390_irgen_CLCL for explanation why we cannot load directly
9615 and need two steps. */
9616 assign(addr2_load,
9617 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
9618 mkU64(guest_IA_curr_instr), mkexpr(addr2)));
9619 assign(single,
9620 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
9621 mkexpr(pad), load(Ity_I8, mkexpr(addr2_load))));
9622
9623 store(mkexpr(addr1), mkexpr(single));
9624
9625 /* Update addr1 and len1 */
9626 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkU64(1)));
9627 put_gpr_w1(r1 + 1, binop(Iop_Sub32, mkexpr(r1p1), mkU32(1)));
9628
9629 /* Update addr2 and len2 */
9630 put_gpr_dw0(r2,
9631 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
9632 mkexpr(addr2),
9633 binop(Iop_Add64, mkexpr(addr2), mkU64(1))));
9634
9635 /* When updating len2 we must not modify bits (r2+1)[0:39] */
9636 put_gpr_w1(r2 + 1,
9637 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
9638 binop(Iop_And32, mkexpr(r2p1), mkU32(0xFF000000u)),
9639 binop(Iop_Sub32, mkexpr(r2p1), mkU32(1))));
9640
9641 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len2, False);
florian6820ba52012-07-26 02:01:50 +00009642 iterate_if(binop(Iop_CmpNE32, mkexpr(len1), mkU32(1)));
florianb0c9a132011-09-08 15:37:39 +00009643
9644 return "mvcl";
9645}
9646
9647
9648static HChar *
sewardj2019a972011-03-07 16:04:07 +00009649s390_irgen_MVCLE(UChar r1, UChar r3, IRTemp pad2)
9650{
9651 IRTemp addr1, addr3, addr3_load, len1, len3, single;
9652
9653 addr1 = newTemp(Ity_I64);
9654 addr3 = newTemp(Ity_I64);
9655 addr3_load = newTemp(Ity_I64);
9656 len1 = newTemp(Ity_I64);
9657 len3 = newTemp(Ity_I64);
9658 single = newTemp(Ity_I8);
9659
9660 assign(addr1, get_gpr_dw0(r1));
9661 assign(len1, get_gpr_dw0(r1 + 1));
9662 assign(addr3, get_gpr_dw0(r3));
9663 assign(len3, get_gpr_dw0(r3 + 1));
9664
9665 // len1 == 0 ?
9666 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len3, False);
florian6820ba52012-07-26 02:01:50 +00009667 next_insn_if(binop(Iop_CmpEQ64,mkexpr(len1), mkU64(0)));
sewardj2019a972011-03-07 16:04:07 +00009668
9669 /* This is a hack to prevent mvcle from reading from addr3 if it
9670 should read from the pad. Since the pad has no address, just
9671 read from the instruction, we discard that anyway */
9672 assign(addr3_load,
florian6ad49522011-09-09 02:38:55 +00009673 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
9674 mkU64(guest_IA_curr_instr), mkexpr(addr3)));
sewardj2019a972011-03-07 16:04:07 +00009675
9676 assign(single,
florian6ad49522011-09-09 02:38:55 +00009677 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
9678 unop(Iop_64to8, mkexpr(pad2)),
9679 load(Ity_I8, mkexpr(addr3_load))));
sewardj2019a972011-03-07 16:04:07 +00009680 store(mkexpr(addr1), mkexpr(single));
9681
9682 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkU64(1)));
9683
9684 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkU64(1)));
9685
9686 put_gpr_dw0(r3,
florian6ad49522011-09-09 02:38:55 +00009687 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
9688 mkexpr(addr3),
9689 binop(Iop_Add64, mkexpr(addr3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +00009690
9691 put_gpr_dw0(r3 + 1,
florian6ad49522011-09-09 02:38:55 +00009692 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
9693 mkU64(0), binop(Iop_Sub64, mkexpr(len3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +00009694
sewardj2019a972011-03-07 16:04:07 +00009695 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len3, False);
florian6820ba52012-07-26 02:01:50 +00009696 iterate_if(binop(Iop_CmpNE64, mkexpr(len1), mkU64(1)));
sewardj2019a972011-03-07 16:04:07 +00009697
9698 return "mvcle";
9699}
9700
9701static HChar *
9702s390_irgen_MVST(UChar r1, UChar r2)
9703{
9704 IRTemp addr1 = newTemp(Ity_I64);
9705 IRTemp addr2 = newTemp(Ity_I64);
9706 IRTemp end = newTemp(Ity_I8);
9707 IRTemp byte = newTemp(Ity_I8);
9708 IRTemp counter = newTemp(Ity_I64);
9709
9710 assign(addr1, get_gpr_dw0(r1));
9711 assign(addr2, get_gpr_dw0(r2));
9712 assign(counter, get_counter_dw0());
9713 assign(end, get_gpr_b7(0));
9714 assign(byte, load(Ity_I8, binop(Iop_Add64, mkexpr(addr2),mkexpr(counter))));
9715 store(binop(Iop_Add64,mkexpr(addr1),mkexpr(counter)), mkexpr(byte));
9716
9717 // We use unlimited as cpu-determined number
9718 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
florian6820ba52012-07-26 02:01:50 +00009719 iterate_if(binop(Iop_CmpNE8, mkexpr(end), mkexpr(byte)));
sewardj2019a972011-03-07 16:04:07 +00009720
9721 // and always set cc=1 at the end + update r1
9722 s390_cc_set(1);
9723 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(counter)));
9724 put_counter_dw0(mkU64(0));
9725
9726 return "mvst";
9727}
9728
9729static void
9730s390_irgen_divide_64to32(IROp op, UChar r1, IRTemp op2)
9731{
9732 IRTemp op1 = newTemp(Ity_I64);
9733 IRTemp result = newTemp(Ity_I64);
9734
9735 assign(op1, binop(Iop_32HLto64,
9736 get_gpr_w1(r1), // high 32 bits
9737 get_gpr_w1(r1 + 1))); // low 32 bits
9738 assign(result, binop(op, mkexpr(op1), mkexpr(op2)));
9739 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result))); // remainder
9740 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result))); // quotient
9741}
9742
9743static void
9744s390_irgen_divide_128to64(IROp op, UChar r1, IRTemp op2)
9745{
9746 IRTemp op1 = newTemp(Ity_I128);
9747 IRTemp result = newTemp(Ity_I128);
9748
9749 assign(op1, binop(Iop_64HLto128,
9750 get_gpr_dw0(r1), // high 64 bits
9751 get_gpr_dw0(r1 + 1))); // low 64 bits
9752 assign(result, binop(op, mkexpr(op1), mkexpr(op2)));
9753 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result))); // remainder
9754 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result))); // quotient
9755}
9756
9757static void
9758s390_irgen_divide_64to64(IROp op, UChar r1, IRTemp op2)
9759{
9760 IRTemp op1 = newTemp(Ity_I64);
9761 IRTemp result = newTemp(Ity_I128);
9762
9763 assign(op1, get_gpr_dw0(r1 + 1));
9764 assign(result, binop(op, mkexpr(op1), mkexpr(op2)));
9765 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result))); // remainder
9766 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result))); // quotient
9767}
9768
9769static HChar *
9770s390_irgen_DR(UChar r1, UChar r2)
9771{
9772 IRTemp op2 = newTemp(Ity_I32);
9773
9774 assign(op2, get_gpr_w1(r2));
9775
9776 s390_irgen_divide_64to32(Iop_DivModS64to32, r1, op2);
9777
9778 return "dr";
9779}
9780
9781static HChar *
9782s390_irgen_D(UChar r1, IRTemp op2addr)
9783{
9784 IRTemp op2 = newTemp(Ity_I32);
9785
9786 assign(op2, load(Ity_I32, mkexpr(op2addr)));
9787
9788 s390_irgen_divide_64to32(Iop_DivModS64to32, r1, op2);
9789
9790 return "d";
9791}
9792
9793static HChar *
9794s390_irgen_DLR(UChar r1, UChar r2)
9795{
9796 IRTemp op2 = newTemp(Ity_I32);
9797
9798 assign(op2, get_gpr_w1(r2));
9799
9800 s390_irgen_divide_64to32(Iop_DivModU64to32, r1, op2);
9801
florian7cd1cde2012-08-16 23:57:43 +00009802 return "dlr";
sewardj2019a972011-03-07 16:04:07 +00009803}
9804
9805static HChar *
9806s390_irgen_DL(UChar r1, IRTemp op2addr)
9807{
9808 IRTemp op2 = newTemp(Ity_I32);
9809
9810 assign(op2, load(Ity_I32, mkexpr(op2addr)));
9811
9812 s390_irgen_divide_64to32(Iop_DivModU64to32, r1, op2);
9813
9814 return "dl";
9815}
9816
9817static HChar *
9818s390_irgen_DLG(UChar r1, IRTemp op2addr)
9819{
9820 IRTemp op2 = newTemp(Ity_I64);
9821
9822 assign(op2, load(Ity_I64, mkexpr(op2addr)));
9823
9824 s390_irgen_divide_128to64(Iop_DivModU128to64, r1, op2);
9825
9826 return "dlg";
9827}
9828
9829static HChar *
9830s390_irgen_DLGR(UChar r1, UChar r2)
9831{
9832 IRTemp op2 = newTemp(Ity_I64);
9833
9834 assign(op2, get_gpr_dw0(r2));
9835
9836 s390_irgen_divide_128to64(Iop_DivModU128to64, r1, op2);
9837
9838 return "dlgr";
9839}
9840
9841static HChar *
9842s390_irgen_DSGR(UChar r1, UChar r2)
9843{
9844 IRTemp op2 = newTemp(Ity_I64);
9845
9846 assign(op2, get_gpr_dw0(r2));
9847
9848 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
9849
9850 return "dsgr";
9851}
9852
9853static HChar *
9854s390_irgen_DSG(UChar r1, IRTemp op2addr)
9855{
9856 IRTemp op2 = newTemp(Ity_I64);
9857
9858 assign(op2, load(Ity_I64, mkexpr(op2addr)));
9859
9860 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
9861
9862 return "dsg";
9863}
9864
9865static HChar *
9866s390_irgen_DSGFR(UChar r1, UChar r2)
9867{
9868 IRTemp op2 = newTemp(Ity_I64);
9869
9870 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
9871
9872 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
9873
9874 return "dsgfr";
9875}
9876
9877static HChar *
9878s390_irgen_DSGF(UChar r1, IRTemp op2addr)
9879{
9880 IRTemp op2 = newTemp(Ity_I64);
9881
9882 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
9883
9884 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
9885
9886 return "dsgf";
9887}
9888
9889static void
9890s390_irgen_load_ar_multiple(UChar r1, UChar r3, IRTemp op2addr)
9891{
9892 UChar reg;
9893 IRTemp addr = newTemp(Ity_I64);
9894
9895 assign(addr, mkexpr(op2addr));
9896 reg = r1;
9897 do {
9898 IRTemp old = addr;
9899
9900 reg %= 16;
9901 put_ar_w0(reg, load(Ity_I32, mkexpr(addr)));
9902 addr = newTemp(Ity_I64);
9903 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
9904 reg++;
9905 } while (reg != (r3 + 1));
9906}
9907
9908static HChar *
9909s390_irgen_LAM(UChar r1, UChar r3, IRTemp op2addr)
9910{
9911 s390_irgen_load_ar_multiple(r1, r3, op2addr);
9912
9913 return "lam";
9914}
9915
9916static HChar *
9917s390_irgen_LAMY(UChar r1, UChar r3, IRTemp op2addr)
9918{
9919 s390_irgen_load_ar_multiple(r1, r3, op2addr);
9920
9921 return "lamy";
9922}
9923
9924static void
9925s390_irgen_store_ar_multiple(UChar r1, UChar r3, IRTemp op2addr)
9926{
9927 UChar reg;
9928 IRTemp addr = newTemp(Ity_I64);
9929
9930 assign(addr, mkexpr(op2addr));
9931 reg = r1;
9932 do {
9933 IRTemp old = addr;
9934
9935 reg %= 16;
9936 store(mkexpr(addr), get_ar_w0(reg));
9937 addr = newTemp(Ity_I64);
9938 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
9939 reg++;
9940 } while (reg != (r3 + 1));
9941}
9942
9943static HChar *
9944s390_irgen_STAM(UChar r1, UChar r3, IRTemp op2addr)
9945{
9946 s390_irgen_store_ar_multiple(r1, r3, op2addr);
9947
9948 return "stam";
9949}
9950
9951static HChar *
9952s390_irgen_STAMY(UChar r1, UChar r3, IRTemp op2addr)
9953{
9954 s390_irgen_store_ar_multiple(r1, r3, op2addr);
9955
9956 return "stamy";
9957}
9958
9959
9960/* Implementation for 32-bit compare-and-swap */
9961static void
9962s390_irgen_cas_32(UChar r1, UChar r3, IRTemp op2addr)
9963{
9964 IRCAS *cas;
9965 IRTemp op1 = newTemp(Ity_I32);
9966 IRTemp old_mem = newTemp(Ity_I32);
9967 IRTemp op3 = newTemp(Ity_I32);
9968 IRTemp result = newTemp(Ity_I32);
9969 IRTemp nequal = newTemp(Ity_I1);
9970
9971 assign(op1, get_gpr_w1(r1));
9972 assign(op3, get_gpr_w1(r3));
9973
9974 /* The first and second operands are compared. If they are equal,
9975 the third operand is stored at the second- operand location. */
9976 cas = mkIRCAS(IRTemp_INVALID, old_mem,
9977 Iend_BE, mkexpr(op2addr),
9978 NULL, mkexpr(op1), /* expected value */
9979 NULL, mkexpr(op3) /* new value */);
9980 stmt(IRStmt_CAS(cas));
9981
9982 /* Set CC. Operands compared equal -> 0, else 1. */
9983 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(old_mem)));
9984 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
9985
9986 /* If operands were equal (cc == 0) just store the old value op1 in r1.
9987 Otherwise, store the old_value from memory in r1 and yield. */
9988 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
9989 put_gpr_w1(r1, mkite(mkexpr(nequal), mkexpr(old_mem), mkexpr(op1)));
florian6820ba52012-07-26 02:01:50 +00009990 yield_if(mkexpr(nequal));
sewardj2019a972011-03-07 16:04:07 +00009991}
9992
9993static HChar *
9994s390_irgen_CS(UChar r1, UChar r3, IRTemp op2addr)
9995{
9996 s390_irgen_cas_32(r1, r3, op2addr);
9997
9998 return "cs";
9999}
10000
10001static HChar *
10002s390_irgen_CSY(UChar r1, UChar r3, IRTemp op2addr)
10003{
10004 s390_irgen_cas_32(r1, r3, op2addr);
10005
10006 return "csy";
10007}
10008
10009static HChar *
10010s390_irgen_CSG(UChar r1, UChar r3, IRTemp op2addr)
10011{
10012 IRCAS *cas;
10013 IRTemp op1 = newTemp(Ity_I64);
10014 IRTemp old_mem = newTemp(Ity_I64);
10015 IRTemp op3 = newTemp(Ity_I64);
10016 IRTemp result = newTemp(Ity_I64);
10017 IRTemp nequal = newTemp(Ity_I1);
10018
10019 assign(op1, get_gpr_dw0(r1));
10020 assign(op3, get_gpr_dw0(r3));
10021
10022 /* The first and second operands are compared. If they are equal,
10023 the third operand is stored at the second- operand location. */
10024 cas = mkIRCAS(IRTemp_INVALID, old_mem,
10025 Iend_BE, mkexpr(op2addr),
10026 NULL, mkexpr(op1), /* expected value */
10027 NULL, mkexpr(op3) /* new value */);
10028 stmt(IRStmt_CAS(cas));
10029
10030 /* Set CC. Operands compared equal -> 0, else 1. */
10031 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(old_mem)));
10032 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
10033
10034 /* If operands were equal (cc == 0) just store the old value op1 in r1.
10035 Otherwise, store the old_value from memory in r1 and yield. */
10036 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
10037 put_gpr_dw0(r1, mkite(mkexpr(nequal), mkexpr(old_mem), mkexpr(op1)));
florian6820ba52012-07-26 02:01:50 +000010038 yield_if(mkexpr(nequal));
sewardj2019a972011-03-07 16:04:07 +000010039
10040 return "csg";
10041}
10042
florian448cbba2012-06-06 02:26:01 +000010043/* Implementation for 32-bit compare-double-and-swap */
10044static void
10045s390_irgen_cdas_32(UChar r1, UChar r3, IRTemp op2addr)
10046{
10047 IRCAS *cas;
10048 IRTemp op1_high = newTemp(Ity_I32);
10049 IRTemp op1_low = newTemp(Ity_I32);
10050 IRTemp old_mem_high = newTemp(Ity_I32);
10051 IRTemp old_mem_low = newTemp(Ity_I32);
10052 IRTemp op3_high = newTemp(Ity_I32);
10053 IRTemp op3_low = newTemp(Ity_I32);
10054 IRTemp result = newTemp(Ity_I32);
10055 IRTemp nequal = newTemp(Ity_I1);
10056
10057 assign(op1_high, get_gpr_w1(r1));
10058 assign(op1_low, get_gpr_w1(r1+1));
10059 assign(op3_high, get_gpr_w1(r3));
10060 assign(op3_low, get_gpr_w1(r3+1));
10061
10062 /* The first and second operands are compared. If they are equal,
10063 the third operand is stored at the second-operand location. */
10064 cas = mkIRCAS(old_mem_high, old_mem_low,
10065 Iend_BE, mkexpr(op2addr),
10066 mkexpr(op1_high), mkexpr(op1_low), /* expected value */
10067 mkexpr(op3_high), mkexpr(op3_low) /* new value */);
10068 stmt(IRStmt_CAS(cas));
10069
10070 /* Set CC. Operands compared equal -> 0, else 1. */
10071 assign(result, unop(Iop_1Uto32,
10072 binop(Iop_CmpNE32,
10073 binop(Iop_Or32,
10074 binop(Iop_Xor32, mkexpr(op1_high), mkexpr(old_mem_high)),
10075 binop(Iop_Xor32, mkexpr(op1_low), mkexpr(old_mem_low))),
10076 mkU32(0))));
10077
10078 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
10079
10080 /* If operands were equal (cc == 0) just store the old value op1 in r1.
10081 Otherwise, store the old_value from memory in r1 and yield. */
10082 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
10083 put_gpr_w1(r1, mkite(mkexpr(nequal), mkexpr(old_mem_high), mkexpr(op1_high)));
10084 put_gpr_w1(r1+1, mkite(mkexpr(nequal), mkexpr(old_mem_low), mkexpr(op1_low)));
florian6820ba52012-07-26 02:01:50 +000010085 yield_if(mkexpr(nequal));
florian448cbba2012-06-06 02:26:01 +000010086}
10087
10088static HChar *
10089s390_irgen_CDS(UChar r1, UChar r3, IRTemp op2addr)
10090{
10091 s390_irgen_cdas_32(r1, r3, op2addr);
10092
10093 return "cds";
10094}
10095
10096static HChar *
10097s390_irgen_CDSY(UChar r1, UChar r3, IRTemp op2addr)
10098{
10099 s390_irgen_cdas_32(r1, r3, op2addr);
10100
10101 return "cdsy";
10102}
10103
10104static HChar *
10105s390_irgen_CDSG(UChar r1, UChar r3, IRTemp op2addr)
10106{
10107 IRCAS *cas;
10108 IRTemp op1_high = newTemp(Ity_I64);
10109 IRTemp op1_low = newTemp(Ity_I64);
10110 IRTemp old_mem_high = newTemp(Ity_I64);
10111 IRTemp old_mem_low = newTemp(Ity_I64);
10112 IRTemp op3_high = newTemp(Ity_I64);
10113 IRTemp op3_low = newTemp(Ity_I64);
10114 IRTemp result = newTemp(Ity_I64);
10115 IRTemp nequal = newTemp(Ity_I1);
10116
10117 assign(op1_high, get_gpr_dw0(r1));
10118 assign(op1_low, get_gpr_dw0(r1+1));
10119 assign(op3_high, get_gpr_dw0(r3));
10120 assign(op3_low, get_gpr_dw0(r3+1));
10121
10122 /* The first and second operands are compared. If they are equal,
10123 the third operand is stored at the second-operand location. */
10124 cas = mkIRCAS(old_mem_high, old_mem_low,
10125 Iend_BE, mkexpr(op2addr),
10126 mkexpr(op1_high), mkexpr(op1_low), /* expected value */
10127 mkexpr(op3_high), mkexpr(op3_low) /* new value */);
10128 stmt(IRStmt_CAS(cas));
10129
10130 /* Set CC. Operands compared equal -> 0, else 1. */
10131 assign(result, unop(Iop_1Uto64,
10132 binop(Iop_CmpNE64,
10133 binop(Iop_Or64,
10134 binop(Iop_Xor64, mkexpr(op1_high), mkexpr(old_mem_high)),
10135 binop(Iop_Xor64, mkexpr(op1_low), mkexpr(old_mem_low))),
10136 mkU64(0))));
10137
10138 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
10139
10140 /* If operands were equal (cc == 0) just store the old value op1 in r1.
10141 Otherwise, store the old_value from memory in r1 and yield. */
10142 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
10143 put_gpr_dw0(r1, mkite(mkexpr(nequal), mkexpr(old_mem_high), mkexpr(op1_high)));
10144 put_gpr_dw0(r1+1, mkite(mkexpr(nequal), mkexpr(old_mem_low), mkexpr(op1_low)));
florian6820ba52012-07-26 02:01:50 +000010145 yield_if(mkexpr(nequal));
10146
florian448cbba2012-06-06 02:26:01 +000010147 return "cdsg";
10148}
10149
sewardj2019a972011-03-07 16:04:07 +000010150
10151/* Binary floating point */
10152
10153static HChar *
10154s390_irgen_AXBR(UChar r1, UChar r2)
10155{
10156 IRTemp op1 = newTemp(Ity_F128);
10157 IRTemp op2 = newTemp(Ity_F128);
10158 IRTemp result = newTemp(Ity_F128);
10159
10160 assign(op1, get_fpr_pair(r1));
10161 assign(op2, get_fpr_pair(r2));
10162 assign(result, triop(Iop_AddF128, mkU32(Irrm_NEAREST), mkexpr(op1),
10163 mkexpr(op2)));
10164 put_fpr_pair(r1, mkexpr(result));
10165
10166 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
10167
10168 return "axbr";
10169}
10170
10171/* The result of a Iop_CmdFxx operation is a condition code. It is
10172 encoded using the values defined in type IRCmpFxxResult.
10173 Before we can store the condition code into the guest state (or do
10174 anything else with it for that matter) we need to convert it to
10175 the encoding that s390 uses. This is what this function does.
10176
10177 s390 VEX b6 b2 b0 cc.1 cc.0
10178 0 0x40 EQ 1 0 0 0 0
10179 1 0x01 LT 0 0 1 0 1
10180 2 0x00 GT 0 0 0 1 0
10181 3 0x45 Unordered 1 1 1 1 1
10182
10183 The following bits from the VEX encoding are interesting:
10184 b0, b2, b6 with b0 being the LSB. We observe:
10185
10186 cc.0 = b0;
10187 cc.1 = b2 | (~b0 & ~b6)
10188
10189 with cc being the s390 condition code.
10190*/
10191static IRExpr *
10192convert_vex_fpcc_to_s390(IRTemp vex_cc)
10193{
10194 IRTemp cc0 = newTemp(Ity_I32);
10195 IRTemp cc1 = newTemp(Ity_I32);
10196 IRTemp b0 = newTemp(Ity_I32);
10197 IRTemp b2 = newTemp(Ity_I32);
10198 IRTemp b6 = newTemp(Ity_I32);
10199
10200 assign(b0, binop(Iop_And32, mkexpr(vex_cc), mkU32(1)));
10201 assign(b2, binop(Iop_And32, binop(Iop_Shr32, mkexpr(vex_cc), mkU8(2)),
10202 mkU32(1)));
10203 assign(b6, binop(Iop_And32, binop(Iop_Shr32, mkexpr(vex_cc), mkU8(6)),
10204 mkU32(1)));
10205
10206 assign(cc0, mkexpr(b0));
10207 assign(cc1, binop(Iop_Or32, mkexpr(b2),
10208 binop(Iop_And32,
10209 binop(Iop_Sub32, mkU32(1), mkexpr(b0)), /* ~b0 */
10210 binop(Iop_Sub32, mkU32(1), mkexpr(b6)) /* ~b6 */
10211 )));
10212
10213 return binop(Iop_Or32, mkexpr(cc0), binop(Iop_Shl32, mkexpr(cc1), mkU8(1)));
10214}
10215
10216static HChar *
10217s390_irgen_CEBR(UChar r1, UChar r2)
10218{
10219 IRTemp op1 = newTemp(Ity_F32);
10220 IRTemp op2 = newTemp(Ity_F32);
10221 IRTemp cc_vex = newTemp(Ity_I32);
10222 IRTemp cc_s390 = newTemp(Ity_I32);
10223
10224 assign(op1, get_fpr_w0(r1));
10225 assign(op2, get_fpr_w0(r2));
10226 assign(cc_vex, binop(Iop_CmpF32, mkexpr(op1), mkexpr(op2)));
10227
10228 assign(cc_s390, convert_vex_fpcc_to_s390(cc_vex));
10229 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
10230
10231 return "cebr";
10232}
10233
10234static HChar *
10235s390_irgen_CDBR(UChar r1, UChar r2)
10236{
10237 IRTemp op1 = newTemp(Ity_F64);
10238 IRTemp op2 = newTemp(Ity_F64);
10239 IRTemp cc_vex = newTemp(Ity_I32);
10240 IRTemp cc_s390 = newTemp(Ity_I32);
10241
10242 assign(op1, get_fpr_dw0(r1));
10243 assign(op2, get_fpr_dw0(r2));
10244 assign(cc_vex, binop(Iop_CmpF64, mkexpr(op1), mkexpr(op2)));
10245
10246 assign(cc_s390, convert_vex_fpcc_to_s390(cc_vex));
10247 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
10248
10249 return "cdbr";
10250}
10251
10252static HChar *
10253s390_irgen_CXBR(UChar r1, UChar r2)
10254{
10255 IRTemp op1 = newTemp(Ity_F128);
10256 IRTemp op2 = newTemp(Ity_F128);
10257 IRTemp cc_vex = newTemp(Ity_I32);
10258 IRTemp cc_s390 = newTemp(Ity_I32);
10259
10260 assign(op1, get_fpr_pair(r1));
10261 assign(op2, get_fpr_pair(r2));
10262 assign(cc_vex, binop(Iop_CmpF128, mkexpr(op1), mkexpr(op2)));
10263
10264 assign(cc_s390, convert_vex_fpcc_to_s390(cc_vex));
10265 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
10266
10267 return "cxbr";
10268}
10269
10270static HChar *
10271s390_irgen_CEB(UChar r1, IRTemp op2addr)
10272{
10273 IRTemp op1 = newTemp(Ity_F32);
10274 IRTemp op2 = newTemp(Ity_F32);
10275 IRTemp cc_vex = newTemp(Ity_I32);
10276 IRTemp cc_s390 = newTemp(Ity_I32);
10277
10278 assign(op1, get_fpr_w0(r1));
10279 assign(op2, load(Ity_F32, mkexpr(op2addr)));
10280 assign(cc_vex, binop(Iop_CmpF32, mkexpr(op1), mkexpr(op2)));
10281
10282 assign(cc_s390, convert_vex_fpcc_to_s390(cc_vex));
10283 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
10284
10285 return "ceb";
10286}
10287
10288static HChar *
10289s390_irgen_CDB(UChar r1, IRTemp op2addr)
10290{
10291 IRTemp op1 = newTemp(Ity_F64);
10292 IRTemp op2 = newTemp(Ity_F64);
10293 IRTemp cc_vex = newTemp(Ity_I32);
10294 IRTemp cc_s390 = newTemp(Ity_I32);
10295
10296 assign(op1, get_fpr_dw0(r1));
10297 assign(op2, load(Ity_F64, mkexpr(op2addr)));
10298 assign(cc_vex, binop(Iop_CmpF64, mkexpr(op1), mkexpr(op2)));
10299
10300 assign(cc_s390, convert_vex_fpcc_to_s390(cc_vex));
10301 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
10302
10303 return "cdb";
10304}
10305
10306static HChar *
10307s390_irgen_CXFBR(UChar r1, UChar r2)
10308{
10309 IRTemp op2 = newTemp(Ity_I32);
10310
10311 assign(op2, get_gpr_w1(r2));
10312 put_fpr_pair(r1, unop(Iop_I32StoF128, mkexpr(op2)));
10313
10314 return "cxfbr";
10315}
10316
10317static HChar *
florian1c8f7ff2012-09-01 00:12:11 +000010318s390_irgen_CXLFBR(UChar m3, UChar m4 __attribute__((unused)),
10319 UChar r1, UChar r2)
10320{
floriane75dafa2012-09-01 17:54:09 +000010321 if (! s390_host_has_fpext) {
10322 emulation_failure(EmFail_S390X_fpext);
10323 } else {
10324 IRTemp op2 = newTemp(Ity_I32);
florian1c8f7ff2012-09-01 00:12:11 +000010325
floriane75dafa2012-09-01 17:54:09 +000010326 assign(op2, get_gpr_w1(r2));
10327 put_fpr_pair(r1, unop(Iop_I32UtoF128, mkexpr(op2)));
10328 }
florian1c8f7ff2012-09-01 00:12:11 +000010329 return "cxlfbr";
10330}
10331
10332
10333static HChar *
sewardj2019a972011-03-07 16:04:07 +000010334s390_irgen_CXGBR(UChar r1, UChar r2)
10335{
10336 IRTemp op2 = newTemp(Ity_I64);
10337
10338 assign(op2, get_gpr_dw0(r2));
10339 put_fpr_pair(r1, unop(Iop_I64StoF128, mkexpr(op2)));
10340
10341 return "cxgbr";
10342}
10343
10344static HChar *
florian1c8f7ff2012-09-01 00:12:11 +000010345s390_irgen_CXLGBR(UChar m3, UChar m4 __attribute__((unused)),
10346 UChar r1, UChar r2)
10347{
floriane75dafa2012-09-01 17:54:09 +000010348 if (! s390_host_has_fpext) {
10349 emulation_failure(EmFail_S390X_fpext);
10350 } else {
10351 IRTemp op2 = newTemp(Ity_I64);
florian1c8f7ff2012-09-01 00:12:11 +000010352
floriane75dafa2012-09-01 17:54:09 +000010353 assign(op2, get_gpr_dw0(r2));
10354 put_fpr_pair(r1, unop(Iop_I64UtoF128, mkexpr(op2)));
10355 }
florian1c8f7ff2012-09-01 00:12:11 +000010356 return "cxlgbr";
10357}
10358
10359static HChar *
sewardj2019a972011-03-07 16:04:07 +000010360s390_irgen_CFXBR(UChar r3, UChar r1, UChar r2)
10361{
10362 IRTemp op = newTemp(Ity_F128);
10363 IRTemp result = newTemp(Ity_I32);
10364
10365 assign(op, get_fpr_pair(r2));
10366 assign(result, binop(Iop_F128toI32S, mkU32(encode_rounding_mode(r3)),
10367 mkexpr(op)));
10368 put_gpr_w1(r1, mkexpr(result));
10369 s390_cc_thunk_put1f128(S390_CC_OP_BFP_128_TO_INT_32, op);
10370
10371 return "cfxbr";
10372}
10373
10374static HChar *
florian1c8f7ff2012-09-01 00:12:11 +000010375s390_irgen_CLFXBR(UChar m3, UChar m4 __attribute__((unused)),
10376 UChar r1, UChar r2)
10377{
floriane75dafa2012-09-01 17:54:09 +000010378 if (! s390_host_has_fpext) {
10379 emulation_failure(EmFail_S390X_fpext);
10380 } else {
10381 IRTemp op = newTemp(Ity_F128);
10382 IRTemp result = newTemp(Ity_I32);
florian1c8f7ff2012-09-01 00:12:11 +000010383
floriane75dafa2012-09-01 17:54:09 +000010384 assign(op, get_fpr_pair(r2));
10385 assign(result, binop(Iop_F128toI32U, mkU32(encode_rounding_mode(m3)),
10386 mkexpr(op)));
10387 put_gpr_w1(r1, mkexpr(result));
10388 s390_cc_thunk_put1f128(S390_CC_OP_BFP_128_TO_UINT_32, op);
10389 }
florian1c8f7ff2012-09-01 00:12:11 +000010390 return "clfxbr";
10391}
10392
10393
10394static HChar *
sewardj2019a972011-03-07 16:04:07 +000010395s390_irgen_CGXBR(UChar r3, UChar r1, UChar r2)
10396{
10397 IRTemp op = newTemp(Ity_F128);
10398 IRTemp result = newTemp(Ity_I64);
10399
10400 assign(op, get_fpr_pair(r2));
10401 assign(result, binop(Iop_F128toI64S, mkU32(encode_rounding_mode(r3)),
10402 mkexpr(op)));
10403 put_gpr_dw0(r1, mkexpr(result));
10404 s390_cc_thunk_put1f128(S390_CC_OP_BFP_128_TO_INT_64, op);
10405
10406 return "cgxbr";
10407}
10408
10409static HChar *
florian1c8f7ff2012-09-01 00:12:11 +000010410s390_irgen_CLGXBR(UChar m3, UChar m4 __attribute__((unused)),
10411 UChar r1, UChar r2)
10412{
floriane75dafa2012-09-01 17:54:09 +000010413 if (! s390_host_has_fpext) {
10414 emulation_failure(EmFail_S390X_fpext);
10415 } else {
10416 IRTemp op = newTemp(Ity_F128);
10417 IRTemp result = newTemp(Ity_I64);
florian1c8f7ff2012-09-01 00:12:11 +000010418
floriane75dafa2012-09-01 17:54:09 +000010419 assign(op, get_fpr_pair(r2));
10420 assign(result, binop(Iop_F128toI64U, mkU32(encode_rounding_mode(m3)),
10421 mkexpr(op)));
10422 put_gpr_dw0(r1, mkexpr(result));
10423 s390_cc_thunk_put1f128(S390_CC_OP_BFP_128_TO_UINT_64, op);
10424 }
florian1c8f7ff2012-09-01 00:12:11 +000010425 return "clgxbr";
10426}
10427
10428static HChar *
sewardj2019a972011-03-07 16:04:07 +000010429s390_irgen_DXBR(UChar r1, UChar r2)
10430{
10431 IRTemp op1 = newTemp(Ity_F128);
10432 IRTemp op2 = newTemp(Ity_F128);
10433 IRTemp result = newTemp(Ity_F128);
10434
10435 assign(op1, get_fpr_pair(r1));
10436 assign(op2, get_fpr_pair(r2));
10437 assign(result, triop(Iop_DivF128, mkU32(Irrm_NEAREST), mkexpr(op1),
10438 mkexpr(op2)));
10439 put_fpr_pair(r1, mkexpr(result));
10440
10441 return "dxbr";
10442}
10443
10444static HChar *
10445s390_irgen_LTXBR(UChar r1, UChar r2)
10446{
10447 IRTemp result = newTemp(Ity_F128);
10448
10449 assign(result, get_fpr_pair(r2));
10450 put_fpr_pair(r1, mkexpr(result));
10451 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
10452
10453 return "ltxbr";
10454}
10455
10456static HChar *
10457s390_irgen_LCXBR(UChar r1, UChar r2)
10458{
10459 IRTemp result = newTemp(Ity_F128);
10460
10461 assign(result, unop(Iop_NegF128, get_fpr_pair(r2)));
10462 put_fpr_pair(r1, mkexpr(result));
10463 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
10464
10465 return "lcxbr";
10466}
10467
10468static HChar *
10469s390_irgen_LXDBR(UChar r1, UChar r2)
10470{
10471 IRTemp op = newTemp(Ity_F64);
10472
10473 assign(op, get_fpr_dw0(r2));
10474 put_fpr_pair(r1, unop(Iop_F64toF128, mkexpr(op)));
10475
10476 return "lxdbr";
10477}
10478
10479static HChar *
10480s390_irgen_LXEBR(UChar r1, UChar r2)
10481{
10482 IRTemp op = newTemp(Ity_F32);
10483
10484 assign(op, get_fpr_w0(r2));
10485 put_fpr_pair(r1, unop(Iop_F32toF128, mkexpr(op)));
10486
10487 return "lxebr";
10488}
10489
10490static HChar *
10491s390_irgen_LXDB(UChar r1, IRTemp op2addr)
10492{
10493 IRTemp op = newTemp(Ity_F64);
10494
10495 assign(op, load(Ity_F64, mkexpr(op2addr)));
10496 put_fpr_pair(r1, unop(Iop_F64toF128, mkexpr(op)));
10497
10498 return "lxdb";
10499}
10500
10501static HChar *
10502s390_irgen_LXEB(UChar r1, IRTemp op2addr)
10503{
10504 IRTemp op = newTemp(Ity_F32);
10505
10506 assign(op, load(Ity_F32, mkexpr(op2addr)));
10507 put_fpr_pair(r1, unop(Iop_F32toF128, mkexpr(op)));
10508
10509 return "lxeb";
10510}
10511
10512static HChar *
10513s390_irgen_LNEBR(UChar r1, UChar r2)
10514{
10515 IRTemp result = newTemp(Ity_F32);
10516
10517 assign(result, unop(Iop_NegF32, unop(Iop_AbsF32, get_fpr_w0(r2))));
10518 put_fpr_w0(r1, mkexpr(result));
10519 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_32, result);
10520
10521 return "lnebr";
10522}
10523
10524static HChar *
10525s390_irgen_LNDBR(UChar r1, UChar r2)
10526{
10527 IRTemp result = newTemp(Ity_F64);
10528
10529 assign(result, unop(Iop_NegF64, unop(Iop_AbsF64, get_fpr_dw0(r2))));
10530 put_fpr_dw0(r1, mkexpr(result));
10531 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_64, result);
10532
10533 return "lndbr";
10534}
10535
10536static HChar *
10537s390_irgen_LNXBR(UChar r1, UChar r2)
10538{
10539 IRTemp result = newTemp(Ity_F128);
10540
10541 assign(result, unop(Iop_NegF128, unop(Iop_AbsF128, get_fpr_pair(r2))));
10542 put_fpr_pair(r1, mkexpr(result));
10543 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
10544
10545 return "lnxbr";
10546}
10547
10548static HChar *
10549s390_irgen_LPEBR(UChar r1, UChar r2)
10550{
10551 IRTemp result = newTemp(Ity_F32);
10552
10553 assign(result, unop(Iop_AbsF32, get_fpr_w0(r2)));
10554 put_fpr_w0(r1, mkexpr(result));
10555 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_32, result);
10556
10557 return "lpebr";
10558}
10559
10560static HChar *
10561s390_irgen_LPDBR(UChar r1, UChar r2)
10562{
10563 IRTemp result = newTemp(Ity_F64);
10564
10565 assign(result, unop(Iop_AbsF64, get_fpr_dw0(r2)));
10566 put_fpr_dw0(r1, mkexpr(result));
10567 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_64, result);
10568
10569 return "lpdbr";
10570}
10571
10572static HChar *
10573s390_irgen_LPXBR(UChar r1, UChar r2)
10574{
10575 IRTemp result = newTemp(Ity_F128);
10576
10577 assign(result, unop(Iop_AbsF128, get_fpr_pair(r2)));
10578 put_fpr_pair(r1, mkexpr(result));
10579 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
10580
10581 return "lpxbr";
10582}
10583
10584static HChar *
10585s390_irgen_LDXBR(UChar r1, UChar r2)
10586{
10587 IRTemp result = newTemp(Ity_F64);
10588
10589 assign(result, binop(Iop_F128toF64, mkU32(Irrm_NEAREST), get_fpr_pair(r2)));
10590 put_fpr_dw0(r1, mkexpr(result));
10591
10592 return "ldxbr";
10593}
10594
10595static HChar *
10596s390_irgen_LEXBR(UChar r1, UChar r2)
10597{
10598 IRTemp result = newTemp(Ity_F32);
10599
10600 assign(result, binop(Iop_F128toF32, mkU32(Irrm_NEAREST), get_fpr_pair(r2)));
10601 put_fpr_w0(r1, mkexpr(result));
10602
10603 return "lexbr";
10604}
10605
10606static HChar *
10607s390_irgen_MXBR(UChar r1, UChar r2)
10608{
10609 IRTemp op1 = newTemp(Ity_F128);
10610 IRTemp op2 = newTemp(Ity_F128);
10611 IRTemp result = newTemp(Ity_F128);
10612
10613 assign(op1, get_fpr_pair(r1));
10614 assign(op2, get_fpr_pair(r2));
10615 assign(result, triop(Iop_MulF128, mkU32(Irrm_NEAREST), mkexpr(op1),
10616 mkexpr(op2)));
10617 put_fpr_pair(r1, mkexpr(result));
10618
10619 return "mxbr";
10620}
10621
10622static HChar *
10623s390_irgen_MAEBR(UChar r1, UChar r3, UChar r2)
10624{
10625 put_fpr_w0(r1, qop(Iop_MAddF32, mkU32(Irrm_NEAREST),
10626 get_fpr_w0(r1), get_fpr_w0(r2), get_fpr_w0(r3)));
10627
10628 return "maebr";
10629}
10630
10631static HChar *
10632s390_irgen_MADBR(UChar r1, UChar r3, UChar r2)
10633{
10634 put_fpr_dw0(r1, qop(Iop_MAddF64, mkU32(Irrm_NEAREST),
10635 get_fpr_dw0(r1), get_fpr_dw0(r2), get_fpr_dw0(r3)));
10636
10637 return "madbr";
10638}
10639
10640static HChar *
10641s390_irgen_MAEB(UChar r3, IRTemp op2addr, UChar r1)
10642{
10643 IRExpr *op2 = load(Ity_F32, mkexpr(op2addr));
10644
10645 put_fpr_w0(r1, qop(Iop_MAddF32, mkU32(Irrm_NEAREST),
10646 get_fpr_w0(r1), op2, get_fpr_w0(r3)));
10647
10648 return "maeb";
10649}
10650
10651static HChar *
10652s390_irgen_MADB(UChar r3, IRTemp op2addr, UChar r1)
10653{
10654 IRExpr *op2 = load(Ity_F64, mkexpr(op2addr));
10655
10656 put_fpr_dw0(r1, qop(Iop_MAddF64, mkU32(Irrm_NEAREST),
10657 get_fpr_dw0(r1), op2, get_fpr_dw0(r3)));
10658
10659 return "madb";
10660}
10661
10662static HChar *
10663s390_irgen_MSEBR(UChar r1, UChar r3, UChar r2)
10664{
10665 put_fpr_w0(r1, qop(Iop_MSubF32, mkU32(Irrm_NEAREST),
10666 get_fpr_w0(r1), get_fpr_w0(r2), get_fpr_w0(r3)));
10667
10668 return "msebr";
10669}
10670
10671static HChar *
10672s390_irgen_MSDBR(UChar r1, UChar r3, UChar r2)
10673{
10674 put_fpr_dw0(r1, qop(Iop_MSubF64, mkU32(Irrm_NEAREST),
10675 get_fpr_dw0(r1), get_fpr_dw0(r2), get_fpr_dw0(r3)));
10676
10677 return "msdbr";
10678}
10679
10680static HChar *
10681s390_irgen_MSEB(UChar r3, IRTemp op2addr, UChar r1)
10682{
10683 IRExpr *op2 = load(Ity_F32, mkexpr(op2addr));
10684
10685 put_fpr_w0(r1, qop(Iop_MSubF32, mkU32(Irrm_NEAREST),
10686 get_fpr_w0(r1), op2, get_fpr_w0(r3)));
10687
10688 return "mseb";
10689}
10690
10691static HChar *
10692s390_irgen_MSDB(UChar r3, IRTemp op2addr, UChar r1)
10693{
10694 IRExpr *op2 = load(Ity_F64, mkexpr(op2addr));
10695
10696 put_fpr_dw0(r1, qop(Iop_MSubF64, mkU32(Irrm_NEAREST),
10697 get_fpr_dw0(r1), op2, get_fpr_dw0(r3)));
10698
10699 return "msdb";
10700}
10701
10702static HChar *
10703s390_irgen_SQEBR(UChar r1, UChar r2)
10704{
10705 IRTemp result = newTemp(Ity_F32);
10706
10707 assign(result, binop(Iop_SqrtF32, mkU32(Irrm_NEAREST), get_fpr_w0(r2)));
10708 put_fpr_w0(r1, mkexpr(result));
10709
10710 return "sqebr";
10711}
10712
10713static HChar *
10714s390_irgen_SQDBR(UChar r1, UChar r2)
10715{
10716 IRTemp result = newTemp(Ity_F64);
10717
10718 assign(result, binop(Iop_SqrtF64, mkU32(Irrm_NEAREST), get_fpr_dw0(r2)));
10719 put_fpr_dw0(r1, mkexpr(result));
10720
10721 return "sqdbr";
10722}
10723
10724static HChar *
10725s390_irgen_SQXBR(UChar r1, UChar r2)
10726{
10727 IRTemp result = newTemp(Ity_F128);
10728
10729 assign(result, binop(Iop_SqrtF128, mkU32(Irrm_NEAREST), get_fpr_pair(r2)));
10730 put_fpr_pair(r1, mkexpr(result));
10731
10732 return "sqxbr";
10733}
10734
10735static HChar *
10736s390_irgen_SQEB(UChar r1, IRTemp op2addr)
10737{
10738 IRTemp op = newTemp(Ity_F32);
10739
10740 assign(op, load(Ity_F32, mkexpr(op2addr)));
10741 put_fpr_w0(r1, binop(Iop_SqrtF32, mkU32(Irrm_NEAREST), mkexpr(op)));
10742
10743 return "sqeb";
10744}
10745
10746static HChar *
10747s390_irgen_SQDB(UChar r1, IRTemp op2addr)
10748{
10749 IRTemp op = newTemp(Ity_F64);
10750
10751 assign(op, load(Ity_F64, mkexpr(op2addr)));
10752 put_fpr_dw0(r1, binop(Iop_SqrtF64, mkU32(Irrm_NEAREST), mkexpr(op)));
10753
10754 return "sqdb";
10755}
10756
10757static HChar *
10758s390_irgen_SXBR(UChar r1, UChar r2)
10759{
10760 IRTemp op1 = newTemp(Ity_F128);
10761 IRTemp op2 = newTemp(Ity_F128);
10762 IRTemp result = newTemp(Ity_F128);
10763
10764 assign(op1, get_fpr_pair(r1));
10765 assign(op2, get_fpr_pair(r2));
10766 assign(result, triop(Iop_SubF128, mkU32(Irrm_NEAREST), mkexpr(op1),
10767 mkexpr(op2)));
10768 put_fpr_pair(r1, mkexpr(result));
10769 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
10770
10771 return "sxbr";
10772}
10773
10774static HChar *
10775s390_irgen_TCEB(UChar r1, IRTemp op2addr)
10776{
10777 IRTemp value = newTemp(Ity_F32);
10778
10779 assign(value, get_fpr_w0(r1));
10780
10781 s390_cc_thunk_putFZ(S390_CC_OP_BFP_TDC_32, value, op2addr);
10782
10783 return "tceb";
10784}
10785
10786static HChar *
10787s390_irgen_TCDB(UChar r1, IRTemp op2addr)
10788{
10789 IRTemp value = newTemp(Ity_F64);
10790
10791 assign(value, get_fpr_dw0(r1));
10792
10793 s390_cc_thunk_putFZ(S390_CC_OP_BFP_TDC_64, value, op2addr);
10794
10795 return "tcdb";
10796}
10797
10798static HChar *
10799s390_irgen_TCXB(UChar r1, IRTemp op2addr)
10800{
10801 IRTemp value = newTemp(Ity_F128);
10802
10803 assign(value, get_fpr_pair(r1));
10804
10805 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_TDC_128, value, op2addr);
10806
10807 return "tcxb";
10808}
10809
10810static HChar *
10811s390_irgen_LCDFR(UChar r1, UChar r2)
10812{
10813 IRTemp result = newTemp(Ity_F64);
10814
10815 assign(result, unop(Iop_NegF64, get_fpr_dw0(r2)));
10816 put_fpr_dw0(r1, mkexpr(result));
10817
10818 return "lcdfr";
10819}
10820
10821static HChar *
10822s390_irgen_LNDFR(UChar r1, UChar r2)
10823{
10824 IRTemp result = newTemp(Ity_F64);
10825
10826 assign(result, unop(Iop_NegF64, unop(Iop_AbsF64, get_fpr_dw0(r2))));
10827 put_fpr_dw0(r1, mkexpr(result));
10828
10829 return "lndfr";
10830}
10831
10832static HChar *
10833s390_irgen_LPDFR(UChar r1, UChar r2)
10834{
10835 IRTemp result = newTemp(Ity_F64);
10836
10837 assign(result, unop(Iop_AbsF64, get_fpr_dw0(r2)));
10838 put_fpr_dw0(r1, mkexpr(result));
10839
10840 return "lpdfr";
10841}
10842
10843static HChar *
10844s390_irgen_LDGR(UChar r1, UChar r2)
10845{
10846 put_fpr_dw0(r1, unop(Iop_ReinterpI64asF64, get_gpr_dw0(r2)));
10847
10848 return "ldgr";
10849}
10850
10851static HChar *
10852s390_irgen_LGDR(UChar r1, UChar r2)
10853{
10854 put_gpr_dw0(r1, unop(Iop_ReinterpF64asI64, get_fpr_dw0(r2)));
10855
10856 return "lgdr";
10857}
10858
10859
10860static HChar *
10861s390_irgen_CPSDR(UChar r3, UChar r1, UChar r2)
10862{
10863 IRTemp sign = newTemp(Ity_I64);
10864 IRTemp value = newTemp(Ity_I64);
10865
10866 assign(sign, binop(Iop_And64, unop(Iop_ReinterpF64asI64, get_fpr_dw0(r3)),
10867 mkU64(1ULL << 63)));
10868 assign(value, binop(Iop_And64, unop(Iop_ReinterpF64asI64, get_fpr_dw0(r2)),
10869 mkU64((1ULL << 63) - 1)));
10870 put_fpr_dw0(r1, unop(Iop_ReinterpI64asF64, binop(Iop_Or64, mkexpr(value),
10871 mkexpr(sign))));
10872
10873 return "cpsdr";
10874}
10875
10876
sewardj2019a972011-03-07 16:04:07 +000010877static IRExpr *
10878s390_call_cvb(IRExpr *in)
10879{
10880 IRExpr **args, *call;
10881
10882 args = mkIRExprVec_1(in);
10883 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
10884 "s390_do_cvb", &s390_do_cvb, args);
10885
10886 /* Nothing is excluded from definedness checking. */
10887 call->Iex.CCall.cee->mcx_mask = 0;
10888
10889 return call;
10890}
10891
10892static HChar *
10893s390_irgen_CVB(UChar r1, IRTemp op2addr)
10894{
10895 put_gpr_w1(r1, s390_call_cvb(load(Ity_I64, mkexpr(op2addr))));
10896
10897 return "cvb";
10898}
10899
10900static HChar *
10901s390_irgen_CVBY(UChar r1, IRTemp op2addr)
10902{
10903 put_gpr_w1(r1, s390_call_cvb(load(Ity_I64, mkexpr(op2addr))));
10904
10905 return "cvby";
10906}
10907
10908
sewardj2019a972011-03-07 16:04:07 +000010909static IRExpr *
10910s390_call_cvd(IRExpr *in)
10911{
10912 IRExpr **args, *call;
10913
10914 args = mkIRExprVec_1(in);
10915 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
10916 "s390_do_cvd", &s390_do_cvd, args);
10917
10918 /* Nothing is excluded from definedness checking. */
10919 call->Iex.CCall.cee->mcx_mask = 0;
10920
10921 return call;
10922}
10923
10924static HChar *
10925s390_irgen_CVD(UChar r1, IRTemp op2addr)
10926{
florian11b8ee82012-08-06 13:35:33 +000010927 store(mkexpr(op2addr), s390_call_cvd(unop(Iop_32Uto64, get_gpr_w1(r1))));
sewardj2019a972011-03-07 16:04:07 +000010928
10929 return "cvd";
10930}
10931
10932static HChar *
10933s390_irgen_CVDY(UChar r1, IRTemp op2addr)
10934{
10935 store(mkexpr(op2addr), s390_call_cvd(get_gpr_w1(r1)));
10936
10937 return "cvdy";
10938}
10939
10940static HChar *
10941s390_irgen_FLOGR(UChar r1, UChar r2)
10942{
10943 IRTemp input = newTemp(Ity_I64);
10944 IRTemp not_zero = newTemp(Ity_I64);
10945 IRTemp tmpnum = newTemp(Ity_I64);
10946 IRTemp num = newTemp(Ity_I64);
10947 IRTemp shift_amount = newTemp(Ity_I8);
10948
10949 /* We use the "count leading zeroes" operator because the number of
10950 leading zeroes is identical with the bit position of the first '1' bit.
10951 However, that operator does not work when the input value is zero.
10952 Therefore, we set the LSB of the input value to 1 and use Clz64 on
10953 the modified value. If input == 0, then the result is 64. Otherwise,
10954 the result of Clz64 is what we want. */
10955
10956 assign(input, get_gpr_dw0(r2));
10957 assign(not_zero, binop(Iop_Or64, mkexpr(input), mkU64(1)));
10958 assign(tmpnum, unop(Iop_Clz64, mkexpr(not_zero)));
10959
10960 /* num = (input == 0) ? 64 : tmpnum */
10961 assign(num, mkite(binop(Iop_CmpEQ64, mkexpr(input), mkU64(0)),
10962 /* == 0 */ mkU64(64),
10963 /* != 0 */ mkexpr(tmpnum)));
10964
10965 put_gpr_dw0(r1, mkexpr(num));
10966
10967 /* Set the leftmost '1' bit of the input value to zero. The general scheme
10968 is to first shift the input value by NUM + 1 bits to the left which
10969 causes the leftmost '1' bit to disappear. Then we shift logically to
10970 the right by NUM + 1 bits. Because the semantics of Iop_Shl64 and
10971 Iop_Shr64 are undefined if the shift-amount is greater than or equal to
10972 the width of the value-to-be-shifted, we need to special case
10973 NUM + 1 >= 64. This is equivalent to INPUT != 0 && INPUT != 1.
10974 For both such INPUT values the result will be 0. */
10975
10976 assign(shift_amount, unop(Iop_64to8, binop(Iop_Add64, mkexpr(num),
10977 mkU64(1))));
10978
10979 put_gpr_dw0(r1 + 1,
florian6ad49522011-09-09 02:38:55 +000010980 mkite(binop(Iop_CmpLE64U, mkexpr(input), mkU64(1)),
10981 /* == 0 || == 1*/ mkU64(0),
10982 /* otherwise */
10983 binop(Iop_Shr64,
10984 binop(Iop_Shl64, mkexpr(input),
10985 mkexpr(shift_amount)),
10986 mkexpr(shift_amount))));
sewardj2019a972011-03-07 16:04:07 +000010987
10988 /* Compare the original value as an unsigned integer with 0. */
10989 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, input,
10990 mktemp(Ity_I64, mkU64(0)), False);
10991
10992 return "flogr";
10993}
10994
sewardj1e5fea62011-05-17 16:18:36 +000010995static HChar *
10996s390_irgen_STCK(IRTemp op2addr)
10997{
10998 IRDirty *d;
10999 IRTemp cc = newTemp(Ity_I64);
11000
11001 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STCK",
11002 &s390x_dirtyhelper_STCK,
11003 mkIRExprVec_1(mkexpr(op2addr)));
11004 d->mFx = Ifx_Write;
11005 d->mAddr = mkexpr(op2addr);
11006 d->mSize = 8;
11007 stmt(IRStmt_Dirty(d));
11008 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
11009 mkexpr(cc), mkU64(0), mkU64(0));
11010 return "stck";
11011}
11012
11013static HChar *
11014s390_irgen_STCKF(IRTemp op2addr)
11015{
florianc5c669b2012-08-26 14:32:28 +000011016 if (! s390_host_has_stckf) {
floriane75dafa2012-09-01 17:54:09 +000011017 emulation_failure(EmFail_S390X_stckf);
florianc5c669b2012-08-26 14:32:28 +000011018 } else {
11019 IRTemp cc = newTemp(Ity_I64);
sewardj1e5fea62011-05-17 16:18:36 +000011020
florianc5c669b2012-08-26 14:32:28 +000011021 IRDirty *d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STCKF",
11022 &s390x_dirtyhelper_STCKF,
11023 mkIRExprVec_1(mkexpr(op2addr)));
11024 d->mFx = Ifx_Write;
11025 d->mAddr = mkexpr(op2addr);
11026 d->mSize = 8;
11027 stmt(IRStmt_Dirty(d));
11028 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
11029 mkexpr(cc), mkU64(0), mkU64(0));
11030 }
sewardj1e5fea62011-05-17 16:18:36 +000011031 return "stckf";
11032}
11033
11034static HChar *
11035s390_irgen_STCKE(IRTemp op2addr)
11036{
11037 IRDirty *d;
11038 IRTemp cc = newTemp(Ity_I64);
11039
11040 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STCKE",
11041 &s390x_dirtyhelper_STCKE,
11042 mkIRExprVec_1(mkexpr(op2addr)));
11043 d->mFx = Ifx_Write;
11044 d->mAddr = mkexpr(op2addr);
11045 d->mSize = 16;
11046 stmt(IRStmt_Dirty(d));
11047 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
11048 mkexpr(cc), mkU64(0), mkU64(0));
11049 return "stcke";
11050}
11051
florian933065d2011-07-11 01:48:02 +000011052static HChar *
11053s390_irgen_STFLE(IRTemp op2addr)
11054{
florian4e0083e2012-08-26 03:41:56 +000011055 if (! s390_host_has_stfle) {
floriane75dafa2012-09-01 17:54:09 +000011056 emulation_failure(EmFail_S390X_stfle);
florian4e0083e2012-08-26 03:41:56 +000011057 return "stfle";
11058 }
11059
florian933065d2011-07-11 01:48:02 +000011060 IRDirty *d;
11061 IRTemp cc = newTemp(Ity_I64);
11062
11063 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STFLE",
11064 &s390x_dirtyhelper_STFLE,
11065 mkIRExprVec_1(mkexpr(op2addr)));
11066
11067 d->needsBBP = 1; /* Need to pass pointer to guest state to helper */
11068
sewardjc9069f22012-06-01 16:09:50 +000011069 d->nFxState = 1;
11070 vex_bzero(&d->fxState, sizeof(d->fxState));
11071
florian933065d2011-07-11 01:48:02 +000011072 d->fxState[0].fx = Ifx_Modify; /* read then write */
11073 d->fxState[0].offset = S390X_GUEST_OFFSET(guest_r0);
11074 d->fxState[0].size = sizeof(ULong);
florian933065d2011-07-11 01:48:02 +000011075
11076 d->mAddr = mkexpr(op2addr);
11077 /* Pretend all double words are written */
11078 d->mSize = S390_NUM_FACILITY_DW * sizeof(ULong);
11079 d->mFx = Ifx_Write;
11080
11081 stmt(IRStmt_Dirty(d));
11082
11083 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET), mkexpr(cc), mkU64(0), mkU64(0));
11084
11085 return "stfle";
11086}
11087
floriana4384a32011-08-11 16:58:45 +000011088static HChar *
11089s390_irgen_CKSM(UChar r1,UChar r2)
11090{
11091 IRTemp addr = newTemp(Ity_I64);
11092 IRTemp op = newTemp(Ity_I32);
11093 IRTemp len = newTemp(Ity_I64);
11094 IRTemp oldval = newTemp(Ity_I32);
11095 IRTemp mask = newTemp(Ity_I32);
11096 IRTemp newop = newTemp(Ity_I32);
11097 IRTemp result = newTemp(Ity_I32);
11098 IRTemp result1 = newTemp(Ity_I32);
11099 IRTemp inc = newTemp(Ity_I64);
11100
11101 assign(oldval, get_gpr_w1(r1));
11102 assign(addr, get_gpr_dw0(r2));
11103 assign(len, get_gpr_dw0(r2+1));
11104
11105 /* Condition code is always zero. */
11106 s390_cc_set(0);
11107
11108 /* If length is zero, there is no need to calculate the checksum */
florian6820ba52012-07-26 02:01:50 +000011109 next_insn_if(binop(Iop_CmpEQ64, mkexpr(len), mkU64(0)));
floriana4384a32011-08-11 16:58:45 +000011110
11111 /* Assiging the increment variable to adjust address and length
11112 later on. */
11113 assign(inc, mkite(binop(Iop_CmpLT64U, mkexpr(len), mkU64(4)),
11114 mkexpr(len), mkU64(4)));
11115
11116 /* If length < 4 the final 4-byte 2nd operand value is computed by
11117 appending the remaining bytes to the right with 0. This is done
11118 by AND'ing the 4 bytes loaded from memory with an appropriate
11119 mask. If length >= 4, that mask is simply 0xffffffff. */
11120
11121 assign(mask, mkite(binop(Iop_CmpLT64U, mkexpr(len), mkU64(4)),
11122 /* Mask computation when len < 4:
11123 0xffffffff << (32 - (len % 4)*8) */
11124 binop(Iop_Shl32, mkU32(0xffffffff),
11125 unop(Iop_32to8,
11126 binop(Iop_Sub32, mkU32(32),
11127 binop(Iop_Shl32,
11128 unop(Iop_64to32,
11129 binop(Iop_And64,
11130 mkexpr(len), mkU64(3))),
11131 mkU8(3))))),
11132 mkU32(0xffffffff)));
11133
11134 assign(op, load(Ity_I32, mkexpr(addr)));
11135 assign(newop, binop(Iop_And32, mkexpr(op), mkexpr(mask)));
11136 assign(result, binop(Iop_Add32, mkexpr(newop), mkexpr(oldval)));
11137
11138 /* Checking for carry */
11139 assign(result1, mkite(binop(Iop_CmpLT32U, mkexpr(result), mkexpr(newop)),
11140 binop(Iop_Add32, mkexpr(result), mkU32(1)),
11141 mkexpr(result)));
11142
11143 put_gpr_w1(r1, mkexpr(result1));
11144 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr), mkexpr(inc)));
11145 put_gpr_dw0(r2+1, binop(Iop_Sub64, mkexpr(len), mkexpr(inc)));
11146
florian6820ba52012-07-26 02:01:50 +000011147 iterate_if(binop(Iop_CmpNE64, mkexpr(len), mkU64(0)));
floriana4384a32011-08-11 16:58:45 +000011148
11149 return "cksm";
11150}
11151
florian9af37692012-01-15 21:01:16 +000011152static HChar *
11153s390_irgen_TROO(UChar m3, UChar r1, UChar r2)
11154{
11155 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
11156 src_addr = newTemp(Ity_I64);
11157 des_addr = newTemp(Ity_I64);
11158 tab_addr = newTemp(Ity_I64);
11159 test_byte = newTemp(Ity_I8);
11160 src_len = newTemp(Ity_I64);
11161
11162 assign(src_addr, get_gpr_dw0(r2));
11163 assign(des_addr, get_gpr_dw0(r1));
11164 assign(tab_addr, get_gpr_dw0(1));
florian53518532012-01-18 14:00:31 +000011165 assign(src_len, get_gpr_dw0(r1+1));
florian9af37692012-01-15 21:01:16 +000011166 assign(test_byte, get_gpr_b7(0));
11167
11168 IRTemp op = newTemp(Ity_I8);
11169 IRTemp op1 = newTemp(Ity_I8);
11170 IRTemp result = newTemp(Ity_I64);
11171
11172 /* End of source string? We're done; proceed to next insn */
11173 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000011174 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian9af37692012-01-15 21:01:16 +000011175
11176 /* Load character from source string, index translation table and
11177 store translated character in op1. */
11178 assign(op, load(Ity_I8, mkexpr(src_addr)));
11179
11180 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)),
11181 mkexpr(tab_addr)));
11182 assign(op1, load(Ity_I8, mkexpr(result)));
11183
11184 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
11185 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000011186 next_insn_if(binop(Iop_CmpEQ8, mkexpr(op1), mkexpr(test_byte)));
florian9af37692012-01-15 21:01:16 +000011187 }
11188 store(get_gpr_dw0(r1), mkexpr(op1));
11189
11190 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(1)));
11191 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(1)));
11192 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(1)));
11193
florian6820ba52012-07-26 02:01:50 +000011194 iterate();
florian9af37692012-01-15 21:01:16 +000011195
11196 return "troo";
11197}
11198
florian730448f2012-02-04 17:07:07 +000011199static HChar *
11200s390_irgen_TRTO(UChar m3, UChar r1, UChar r2)
11201{
11202 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
11203 src_addr = newTemp(Ity_I64);
11204 des_addr = newTemp(Ity_I64);
11205 tab_addr = newTemp(Ity_I64);
11206 test_byte = newTemp(Ity_I8);
11207 src_len = newTemp(Ity_I64);
11208
11209 assign(src_addr, get_gpr_dw0(r2));
11210 assign(des_addr, get_gpr_dw0(r1));
11211 assign(tab_addr, get_gpr_dw0(1));
11212 assign(src_len, get_gpr_dw0(r1+1));
11213 assign(test_byte, get_gpr_b7(0));
11214
11215 IRTemp op = newTemp(Ity_I16);
11216 IRTemp op1 = newTemp(Ity_I8);
11217 IRTemp result = newTemp(Ity_I64);
11218
11219 /* End of source string? We're done; proceed to next insn */
11220 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000011221 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian730448f2012-02-04 17:07:07 +000011222
11223 /* Load character from source string, index translation table and
11224 store translated character in op1. */
11225 assign(op, load(Ity_I16, mkexpr(src_addr)));
11226
11227 assign(result, binop(Iop_Add64, unop(Iop_16Uto64, mkexpr(op)),
11228 mkexpr(tab_addr)));
11229
11230 assign(op1, load(Ity_I8, mkexpr(result)));
11231
11232 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
11233 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000011234 next_insn_if(binop(Iop_CmpEQ8, mkexpr(op1), mkexpr(test_byte)));
florian730448f2012-02-04 17:07:07 +000011235 }
11236 store(get_gpr_dw0(r1), mkexpr(op1));
11237
11238 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(2)));
11239 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(1)));
11240 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(2)));
11241
florian6820ba52012-07-26 02:01:50 +000011242 iterate();
florian730448f2012-02-04 17:07:07 +000011243
11244 return "trto";
11245}
11246
11247static HChar *
11248s390_irgen_TROT(UChar m3, UChar r1, UChar r2)
11249{
11250 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
11251 src_addr = newTemp(Ity_I64);
11252 des_addr = newTemp(Ity_I64);
11253 tab_addr = newTemp(Ity_I64);
11254 test_byte = newTemp(Ity_I16);
11255 src_len = newTemp(Ity_I64);
11256
11257 assign(src_addr, get_gpr_dw0(r2));
11258 assign(des_addr, get_gpr_dw0(r1));
11259 assign(tab_addr, get_gpr_dw0(1));
11260 assign(src_len, get_gpr_dw0(r1+1));
11261 assign(test_byte, get_gpr_hw3(0));
11262
11263 IRTemp op = newTemp(Ity_I8);
11264 IRTemp op1 = newTemp(Ity_I16);
11265 IRTemp result = newTemp(Ity_I64);
11266
11267 /* End of source string? We're done; proceed to next insn */
11268 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000011269 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian730448f2012-02-04 17:07:07 +000011270
11271 /* Load character from source string, index translation table and
11272 store translated character in op1. */
11273 assign(op, binop(Iop_Shl8, load(Ity_I8, mkexpr(src_addr)), mkU8(1)));
11274
11275 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)),
11276 mkexpr(tab_addr)));
11277 assign(op1, load(Ity_I16, mkexpr(result)));
11278
11279 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
11280 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000011281 next_insn_if(binop(Iop_CmpEQ16, mkexpr(op1), mkexpr(test_byte)));
florian730448f2012-02-04 17:07:07 +000011282 }
11283 store(get_gpr_dw0(r1), mkexpr(op1));
11284
11285 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(1)));
11286 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(2)));
11287 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(1)));
11288
florian6820ba52012-07-26 02:01:50 +000011289 iterate();
florian730448f2012-02-04 17:07:07 +000011290
11291 return "trot";
11292}
11293
11294static HChar *
11295s390_irgen_TRTT(UChar m3, UChar r1, UChar r2)
11296{
11297 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
11298 src_addr = newTemp(Ity_I64);
11299 des_addr = newTemp(Ity_I64);
11300 tab_addr = newTemp(Ity_I64);
11301 test_byte = newTemp(Ity_I16);
11302 src_len = newTemp(Ity_I64);
11303
11304 assign(src_addr, get_gpr_dw0(r2));
11305 assign(des_addr, get_gpr_dw0(r1));
11306 assign(tab_addr, get_gpr_dw0(1));
11307 assign(src_len, get_gpr_dw0(r1+1));
11308 assign(test_byte, get_gpr_hw3(0));
11309
11310 IRTemp op = newTemp(Ity_I16);
11311 IRTemp op1 = newTemp(Ity_I16);
11312 IRTemp result = newTemp(Ity_I64);
11313
11314 /* End of source string? We're done; proceed to next insn */
11315 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000011316 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian730448f2012-02-04 17:07:07 +000011317
11318 /* Load character from source string, index translation table and
11319 store translated character in op1. */
11320 assign(op, binop(Iop_Shl16, load(Ity_I16, mkexpr(src_addr)), mkU8(1)));
11321
11322 assign(result, binop(Iop_Add64, unop(Iop_16Uto64, mkexpr(op)),
11323 mkexpr(tab_addr)));
11324 assign(op1, load(Ity_I16, mkexpr(result)));
11325
11326 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
11327 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000011328 next_insn_if(binop(Iop_CmpEQ16, mkexpr(op1), mkexpr(test_byte)));
florian730448f2012-02-04 17:07:07 +000011329 }
11330
11331 store(get_gpr_dw0(r1), mkexpr(op1));
11332
11333 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(2)));
11334 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(2)));
11335 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(2)));
11336
florian6820ba52012-07-26 02:01:50 +000011337 iterate();
florian730448f2012-02-04 17:07:07 +000011338
11339 return "trtt";
11340}
11341
11342static HChar *
11343s390_irgen_TR(UChar length, IRTemp start1, IRTemp start2)
11344{
florianf87d4fb2012-05-05 02:55:24 +000011345 IRTemp len = newTemp(Ity_I64);
florian730448f2012-02-04 17:07:07 +000011346
florianf87d4fb2012-05-05 02:55:24 +000011347 assign(len, mkU64(length));
11348 s390_irgen_TR_EX(len, start1, start2);
florian730448f2012-02-04 17:07:07 +000011349
11350 return "tr";
11351}
11352
11353static HChar *
11354s390_irgen_TRE(UChar r1,UChar r2)
11355{
11356 IRTemp src_addr, tab_addr, src_len, test_byte;
11357 src_addr = newTemp(Ity_I64);
11358 tab_addr = newTemp(Ity_I64);
11359 src_len = newTemp(Ity_I64);
11360 test_byte = newTemp(Ity_I8);
11361
11362 assign(src_addr, get_gpr_dw0(r1));
11363 assign(src_len, get_gpr_dw0(r1+1));
11364 assign(tab_addr, get_gpr_dw0(r2));
11365 assign(test_byte, get_gpr_b7(0));
11366
11367 IRTemp op = newTemp(Ity_I8);
11368 IRTemp op1 = newTemp(Ity_I8);
11369 IRTemp result = newTemp(Ity_I64);
11370
11371 /* End of source string? We're done; proceed to next insn */
11372 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000011373 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian730448f2012-02-04 17:07:07 +000011374
11375 /* Load character from source string and compare with test byte */
11376 assign(op, load(Ity_I8, mkexpr(src_addr)));
11377
11378 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000011379 next_insn_if(binop(Iop_CmpEQ8, mkexpr(op), mkexpr(test_byte)));
florian730448f2012-02-04 17:07:07 +000011380
11381 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)),
11382 mkexpr(tab_addr)));
11383
11384 assign(op1, load(Ity_I8, mkexpr(result)));
11385
11386 store(get_gpr_dw0(r1), mkexpr(op1));
11387 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(src_addr), mkU64(1)));
11388 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(1)));
11389
florian6820ba52012-07-26 02:01:50 +000011390 iterate();
florian730448f2012-02-04 17:07:07 +000011391
11392 return "tre";
11393}
11394
floriana0100c92012-07-20 00:06:35 +000011395static IRExpr *
11396s390_call_cu21(IRExpr *srcval, IRExpr *low_surrogate)
11397{
11398 IRExpr **args, *call;
11399 args = mkIRExprVec_2(srcval, low_surrogate);
11400 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
11401 "s390_do_cu21", &s390_do_cu21, args);
11402
11403 /* Nothing is excluded from definedness checking. */
11404 call->Iex.CCall.cee->mcx_mask = 0;
11405
11406 return call;
11407}
11408
11409static HChar *
11410s390_irgen_CU21(UChar m3, UChar r1, UChar r2)
11411{
11412 IRTemp addr1 = newTemp(Ity_I64);
11413 IRTemp addr2 = newTemp(Ity_I64);
11414 IRTemp len1 = newTemp(Ity_I64);
11415 IRTemp len2 = newTemp(Ity_I64);
11416
11417 assign(addr1, get_gpr_dw0(r1));
11418 assign(addr2, get_gpr_dw0(r2));
11419 assign(len1, get_gpr_dw0(r1 + 1));
11420 assign(len2, get_gpr_dw0(r2 + 1));
11421
11422 /* We're processing the 2nd operand 2 bytes at a time. Therefore, if
11423 there are less than 2 bytes left, then the 2nd operand is exhausted
11424 and we're done here. cc = 0 */
11425 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000011426 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(2)));
floriana0100c92012-07-20 00:06:35 +000011427
11428 /* There are at least two bytes there. Read them. */
11429 IRTemp srcval = newTemp(Ity_I32);
11430 assign(srcval, unop(Iop_16Uto32, load(Ity_I16, mkexpr(addr2))));
11431
11432 /* Find out whether this is a high surrogate. I.e. SRCVAL lies
11433 inside the interval [0xd800 - 0xdbff] */
11434 IRTemp is_high_surrogate = newTemp(Ity_I32);
11435 IRExpr *flag1 = mkite(binop(Iop_CmpLE32U, mkU32(0xd800), mkexpr(srcval)),
11436 mkU32(1), mkU32(0));
11437 IRExpr *flag2 = mkite(binop(Iop_CmpLE32U, mkexpr(srcval), mkU32(0xdbff)),
11438 mkU32(1), mkU32(0));
11439 assign(is_high_surrogate, binop(Iop_And32, flag1, flag2));
11440
11441 /* If SRCVAL is a high surrogate and there are less than 4 bytes left,
11442 then the 2nd operand is exhausted and we're done here. cc = 0 */
11443 IRExpr *not_enough_bytes =
11444 mkite(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)), mkU32(1), mkU32(0));
11445
florian6820ba52012-07-26 02:01:50 +000011446 next_insn_if(binop(Iop_CmpEQ32,
11447 binop(Iop_And32, mkexpr(is_high_surrogate),
11448 not_enough_bytes), mkU32(1)));
floriana0100c92012-07-20 00:06:35 +000011449
11450 /* The 2nd operand is not exhausted. If the first 2 bytes are a high
11451 surrogate, read the next two bytes (low surrogate). */
11452 IRTemp low_surrogate = newTemp(Ity_I32);
11453 IRExpr *low_surrogate_addr = binop(Iop_Add64, mkexpr(addr2), mkU64(2));
11454
11455 assign(low_surrogate,
11456 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
11457 unop(Iop_16Uto32, load(Ity_I16, low_surrogate_addr)),
11458 mkU32(0))); // any value is fine; it will not be used
11459
11460 /* Call the helper */
11461 IRTemp retval = newTemp(Ity_I64);
florian11b8ee82012-08-06 13:35:33 +000011462 assign(retval, s390_call_cu21(unop(Iop_32Uto64, mkexpr(srcval)),
11463 unop(Iop_32Uto64, mkexpr(low_surrogate))));
floriana0100c92012-07-20 00:06:35 +000011464
11465 /* Before we can test whether the 1st operand is exhausted we need to
11466 test for an invalid low surrogate. Because cc=2 outranks cc=1. */
11467 if (s390_host_has_etf3 && (m3 & 0x1) == 1) {
11468 IRExpr *invalid_low_surrogate =
11469 binop(Iop_And64, mkexpr(retval), mkU64(0xff));
11470
11471 s390_cc_set(2);
florian6820ba52012-07-26 02:01:50 +000011472 next_insn_if(binop(Iop_CmpEQ64, invalid_low_surrogate, mkU64(1)));
floriana0100c92012-07-20 00:06:35 +000011473 }
11474
11475 /* Now test whether the 1st operand is exhausted */
11476 IRTemp num_bytes = newTemp(Ity_I64);
11477 assign(num_bytes, binop(Iop_And64,
11478 binop(Iop_Shr64, mkexpr(retval), mkU8(8)),
11479 mkU64(0xff)));
11480 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000011481 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
floriana0100c92012-07-20 00:06:35 +000011482
11483 /* Extract the bytes to be stored at addr1 */
11484 IRTemp data = newTemp(Ity_I64);
11485 assign(data, binop(Iop_Shr64, mkexpr(retval), mkU8(16)));
11486
11487 /* To store the bytes construct 4 dirty helper calls. The helper calls
11488 are guarded (num_bytes == 1, num_bytes == 2, etc) such that only
11489 one of them will be called at runtime. */
11490 int i;
11491 for (i = 1; i <= 4; ++i) {
11492 IRDirty *d;
11493
11494 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
11495 &s390x_dirtyhelper_CUxy,
11496 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
11497 mkexpr(num_bytes)));
11498 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
11499 d->mFx = Ifx_Write;
11500 d->mAddr = mkexpr(addr1);
11501 d->mSize = i;
11502 stmt(IRStmt_Dirty(d));
11503 }
11504
11505 /* Update source address and length */
11506 IRTemp num_src_bytes = newTemp(Ity_I64);
11507 assign(num_src_bytes,
11508 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
11509 mkU64(4), mkU64(2)));
11510 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkexpr(num_src_bytes)));
11511 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkexpr(num_src_bytes)));
11512
11513 /* Update destination address and length */
11514 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
11515 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
11516
florian6820ba52012-07-26 02:01:50 +000011517 iterate();
floriana0100c92012-07-20 00:06:35 +000011518
11519 return "cu21";
11520}
11521
florian2a415a12012-07-21 17:41:36 +000011522static IRExpr *
11523s390_call_cu24(IRExpr *srcval, IRExpr *low_surrogate)
11524{
11525 IRExpr **args, *call;
11526 args = mkIRExprVec_2(srcval, low_surrogate);
11527 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
11528 "s390_do_cu24", &s390_do_cu24, args);
11529
11530 /* Nothing is excluded from definedness checking. */
11531 call->Iex.CCall.cee->mcx_mask = 0;
11532
11533 return call;
11534}
11535
11536static HChar *
11537s390_irgen_CU24(UChar m3, UChar r1, UChar r2)
11538{
11539 IRTemp addr1 = newTemp(Ity_I64);
11540 IRTemp addr2 = newTemp(Ity_I64);
11541 IRTemp len1 = newTemp(Ity_I64);
11542 IRTemp len2 = newTemp(Ity_I64);
11543
11544 assign(addr1, get_gpr_dw0(r1));
11545 assign(addr2, get_gpr_dw0(r2));
11546 assign(len1, get_gpr_dw0(r1 + 1));
11547 assign(len2, get_gpr_dw0(r2 + 1));
11548
11549 /* We're processing the 2nd operand 2 bytes at a time. Therefore, if
11550 there are less than 2 bytes left, then the 2nd operand is exhausted
11551 and we're done here. cc = 0 */
11552 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000011553 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(2)));
florian2a415a12012-07-21 17:41:36 +000011554
11555 /* There are at least two bytes there. Read them. */
11556 IRTemp srcval = newTemp(Ity_I32);
11557 assign(srcval, unop(Iop_16Uto32, load(Ity_I16, mkexpr(addr2))));
11558
11559 /* Find out whether this is a high surrogate. I.e. SRCVAL lies
11560 inside the interval [0xd800 - 0xdbff] */
11561 IRTemp is_high_surrogate = newTemp(Ity_I32);
11562 IRExpr *flag1 = mkite(binop(Iop_CmpLE32U, mkU32(0xd800), mkexpr(srcval)),
11563 mkU32(1), mkU32(0));
11564 IRExpr *flag2 = mkite(binop(Iop_CmpLE32U, mkexpr(srcval), mkU32(0xdbff)),
11565 mkU32(1), mkU32(0));
11566 assign(is_high_surrogate, binop(Iop_And32, flag1, flag2));
11567
11568 /* If SRCVAL is a high surrogate and there are less than 4 bytes left,
11569 then the 2nd operand is exhausted and we're done here. cc = 0 */
11570 IRExpr *not_enough_bytes =
11571 mkite(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)), mkU32(1), mkU32(0));
11572
florian6820ba52012-07-26 02:01:50 +000011573 next_insn_if(binop(Iop_CmpEQ32,
11574 binop(Iop_And32, mkexpr(is_high_surrogate),
11575 not_enough_bytes),
11576 mkU32(1)));
florian2a415a12012-07-21 17:41:36 +000011577
11578 /* The 2nd operand is not exhausted. If the first 2 bytes are a high
11579 surrogate, read the next two bytes (low surrogate). */
11580 IRTemp low_surrogate = newTemp(Ity_I32);
11581 IRExpr *low_surrogate_addr = binop(Iop_Add64, mkexpr(addr2), mkU64(2));
11582
11583 assign(low_surrogate,
11584 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
11585 unop(Iop_16Uto32, load(Ity_I16, low_surrogate_addr)),
11586 mkU32(0))); // any value is fine; it will not be used
11587
11588 /* Call the helper */
11589 IRTemp retval = newTemp(Ity_I64);
florian11b8ee82012-08-06 13:35:33 +000011590 assign(retval, s390_call_cu24(unop(Iop_32Uto64, mkexpr(srcval)),
11591 unop(Iop_32Uto64, mkexpr(low_surrogate))));
florian2a415a12012-07-21 17:41:36 +000011592
11593 /* Before we can test whether the 1st operand is exhausted we need to
11594 test for an invalid low surrogate. Because cc=2 outranks cc=1. */
11595 if (s390_host_has_etf3 && (m3 & 0x1) == 1) {
11596 IRExpr *invalid_low_surrogate =
11597 binop(Iop_And64, mkexpr(retval), mkU64(0xff));
11598
11599 s390_cc_set(2);
florian6820ba52012-07-26 02:01:50 +000011600 next_insn_if(binop(Iop_CmpEQ64, invalid_low_surrogate, mkU64(1)));
florian2a415a12012-07-21 17:41:36 +000011601 }
11602
11603 /* Now test whether the 1st operand is exhausted */
11604 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000011605 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkU64(4)));
florian2a415a12012-07-21 17:41:36 +000011606
11607 /* Extract the bytes to be stored at addr1 */
11608 IRExpr *data = unop(Iop_64to32, binop(Iop_Shr64, mkexpr(retval), mkU8(8)));
11609
11610 store(mkexpr(addr1), data);
11611
11612 /* Update source address and length */
11613 IRTemp num_src_bytes = newTemp(Ity_I64);
11614 assign(num_src_bytes,
11615 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
11616 mkU64(4), mkU64(2)));
11617 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkexpr(num_src_bytes)));
11618 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkexpr(num_src_bytes)));
11619
11620 /* Update destination address and length */
11621 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkU64(4)));
11622 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkU64(4)));
11623
florian6820ba52012-07-26 02:01:50 +000011624 iterate();
florian2a415a12012-07-21 17:41:36 +000011625
11626 return "cu24";
11627}
floriana4384a32011-08-11 16:58:45 +000011628
florian956194b2012-07-28 22:18:32 +000011629static IRExpr *
11630s390_call_cu42(IRExpr *srcval)
11631{
11632 IRExpr **args, *call;
11633 args = mkIRExprVec_1(srcval);
11634 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
11635 "s390_do_cu42", &s390_do_cu42, args);
11636
11637 /* Nothing is excluded from definedness checking. */
11638 call->Iex.CCall.cee->mcx_mask = 0;
11639
11640 return call;
11641}
11642
11643static HChar *
11644s390_irgen_CU42(UChar r1, UChar r2)
11645{
11646 IRTemp addr1 = newTemp(Ity_I64);
11647 IRTemp addr2 = newTemp(Ity_I64);
11648 IRTemp len1 = newTemp(Ity_I64);
11649 IRTemp len2 = newTemp(Ity_I64);
11650
11651 assign(addr1, get_gpr_dw0(r1));
11652 assign(addr2, get_gpr_dw0(r2));
11653 assign(len1, get_gpr_dw0(r1 + 1));
11654 assign(len2, get_gpr_dw0(r2 + 1));
11655
11656 /* We're processing the 2nd operand 4 bytes at a time. Therefore, if
11657 there are less than 4 bytes left, then the 2nd operand is exhausted
11658 and we're done here. cc = 0 */
11659 s390_cc_set(0);
11660 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)));
11661
11662 /* Read the 2nd operand. */
11663 IRTemp srcval = newTemp(Ity_I32);
11664 assign(srcval, load(Ity_I32, mkexpr(addr2)));
11665
11666 /* Call the helper */
11667 IRTemp retval = newTemp(Ity_I64);
florian11b8ee82012-08-06 13:35:33 +000011668 assign(retval, s390_call_cu42(unop(Iop_32Uto64, mkexpr(srcval))));
florian956194b2012-07-28 22:18:32 +000011669
11670 /* If the UTF-32 character was invalid, set cc=2 and we're done.
11671 cc=2 outranks cc=1 (1st operand exhausted) */
11672 IRExpr *invalid_character = binop(Iop_And64, mkexpr(retval), mkU64(0xff));
11673
11674 s390_cc_set(2);
11675 next_insn_if(binop(Iop_CmpEQ64, invalid_character, mkU64(1)));
11676
11677 /* Now test whether the 1st operand is exhausted */
11678 IRTemp num_bytes = newTemp(Ity_I64);
11679 assign(num_bytes, binop(Iop_And64,
11680 binop(Iop_Shr64, mkexpr(retval), mkU8(8)),
11681 mkU64(0xff)));
11682 s390_cc_set(1);
11683 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
11684
11685 /* Extract the bytes to be stored at addr1 */
11686 IRTemp data = newTemp(Ity_I64);
11687 assign(data, binop(Iop_Shr64, mkexpr(retval), mkU8(16)));
11688
11689 /* To store the bytes construct 2 dirty helper calls. The helper calls
11690 are guarded (num_bytes == 2 and num_bytes == 4, respectively) such
11691 that only one of them will be called at runtime. */
11692
11693 Int i;
11694 for (i = 2; i <= 4; ++i) {
11695 IRDirty *d;
11696
11697 if (i == 3) continue; // skip this one
11698
11699 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
11700 &s390x_dirtyhelper_CUxy,
11701 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
11702 mkexpr(num_bytes)));
11703 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
11704 d->mFx = Ifx_Write;
11705 d->mAddr = mkexpr(addr1);
11706 d->mSize = i;
11707 stmt(IRStmt_Dirty(d));
11708 }
11709
11710 /* Update source address and length */
11711 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkU64(4)));
11712 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkU64(4)));
11713
11714 /* Update destination address and length */
11715 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
11716 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
11717
11718 iterate();
11719
11720 return "cu42";
11721}
11722
florian6d9b9b22012-08-03 18:35:39 +000011723static IRExpr *
florianaf2194f2012-08-06 00:07:54 +000011724s390_call_cu41(IRExpr *srcval)
11725{
11726 IRExpr **args, *call;
11727 args = mkIRExprVec_1(srcval);
11728 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
11729 "s390_do_cu41", &s390_do_cu41, args);
11730
11731 /* Nothing is excluded from definedness checking. */
11732 call->Iex.CCall.cee->mcx_mask = 0;
11733
11734 return call;
11735}
11736
11737static HChar *
11738s390_irgen_CU41(UChar r1, UChar r2)
11739{
11740 IRTemp addr1 = newTemp(Ity_I64);
11741 IRTemp addr2 = newTemp(Ity_I64);
11742 IRTemp len1 = newTemp(Ity_I64);
11743 IRTemp len2 = newTemp(Ity_I64);
11744
11745 assign(addr1, get_gpr_dw0(r1));
11746 assign(addr2, get_gpr_dw0(r2));
11747 assign(len1, get_gpr_dw0(r1 + 1));
11748 assign(len2, get_gpr_dw0(r2 + 1));
11749
11750 /* We're processing the 2nd operand 4 bytes at a time. Therefore, if
11751 there are less than 4 bytes left, then the 2nd operand is exhausted
11752 and we're done here. cc = 0 */
11753 s390_cc_set(0);
11754 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)));
11755
11756 /* Read the 2nd operand. */
11757 IRTemp srcval = newTemp(Ity_I32);
11758 assign(srcval, load(Ity_I32, mkexpr(addr2)));
11759
11760 /* Call the helper */
11761 IRTemp retval = newTemp(Ity_I64);
florian11b8ee82012-08-06 13:35:33 +000011762 assign(retval, s390_call_cu41(unop(Iop_32Uto64, mkexpr(srcval))));
florianaf2194f2012-08-06 00:07:54 +000011763
11764 /* If the UTF-32 character was invalid, set cc=2 and we're done.
11765 cc=2 outranks cc=1 (1st operand exhausted) */
11766 IRExpr *invalid_character = binop(Iop_And64, mkexpr(retval), mkU64(0xff));
11767
11768 s390_cc_set(2);
11769 next_insn_if(binop(Iop_CmpEQ64, invalid_character, mkU64(1)));
11770
11771 /* Now test whether the 1st operand is exhausted */
11772 IRTemp num_bytes = newTemp(Ity_I64);
11773 assign(num_bytes, binop(Iop_And64,
11774 binop(Iop_Shr64, mkexpr(retval), mkU8(8)),
11775 mkU64(0xff)));
11776 s390_cc_set(1);
11777 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
11778
11779 /* Extract the bytes to be stored at addr1 */
11780 IRTemp data = newTemp(Ity_I64);
11781 assign(data, binop(Iop_Shr64, mkexpr(retval), mkU8(16)));
11782
11783 /* To store the bytes construct 4 dirty helper calls. The helper calls
11784 are guarded (num_bytes == 1, num_bytes == 2, etc) such that only
11785 one of them will be called at runtime. */
11786 int i;
11787 for (i = 1; i <= 4; ++i) {
11788 IRDirty *d;
11789
11790 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
11791 &s390x_dirtyhelper_CUxy,
11792 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
11793 mkexpr(num_bytes)));
11794 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
11795 d->mFx = Ifx_Write;
11796 d->mAddr = mkexpr(addr1);
11797 d->mSize = i;
11798 stmt(IRStmt_Dirty(d));
11799 }
11800
11801 /* Update source address and length */
11802 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkU64(4)));
11803 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkU64(4)));
11804
11805 /* Update destination address and length */
11806 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
11807 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
11808
11809 iterate();
11810
11811 return "cu41";
11812}
11813
11814static IRExpr *
florian3f8a96a2012-08-05 02:59:55 +000011815s390_call_cu12_cu14_helper1(IRExpr *byte1, IRExpr *etf3_and_m3_is_1)
florian6d9b9b22012-08-03 18:35:39 +000011816{
11817 IRExpr **args, *call;
11818 args = mkIRExprVec_2(byte1, etf3_and_m3_is_1);
florian3f8a96a2012-08-05 02:59:55 +000011819 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/, "s390_do_cu12_cu14_helper1",
11820 &s390_do_cu12_cu14_helper1, args);
florian6d9b9b22012-08-03 18:35:39 +000011821
11822 /* Nothing is excluded from definedness checking. */
11823 call->Iex.CCall.cee->mcx_mask = 0;
11824
11825 return call;
11826}
11827
11828static IRExpr *
11829s390_call_cu12_helper2(IRExpr *byte1, IRExpr *byte2, IRExpr *byte3,
11830 IRExpr *byte4, IRExpr *stuff)
11831{
11832 IRExpr **args, *call;
11833 args = mkIRExprVec_5(byte1, byte2, byte3, byte4, stuff);
11834 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
11835 "s390_do_cu12_helper2", &s390_do_cu12_helper2, args);
11836
11837 /* Nothing is excluded from definedness checking. */
11838 call->Iex.CCall.cee->mcx_mask = 0;
11839
11840 return call;
11841}
11842
florian3f8a96a2012-08-05 02:59:55 +000011843static IRExpr *
11844s390_call_cu14_helper2(IRExpr *byte1, IRExpr *byte2, IRExpr *byte3,
11845 IRExpr *byte4, IRExpr *stuff)
11846{
11847 IRExpr **args, *call;
11848 args = mkIRExprVec_5(byte1, byte2, byte3, byte4, stuff);
11849 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
11850 "s390_do_cu14_helper2", &s390_do_cu14_helper2, args);
11851
11852 /* Nothing is excluded from definedness checking. */
11853 call->Iex.CCall.cee->mcx_mask = 0;
11854
11855 return call;
11856}
11857
11858static void
11859s390_irgen_cu12_cu14(UChar m3, UChar r1, UChar r2, Bool is_cu12)
florian6d9b9b22012-08-03 18:35:39 +000011860{
11861 IRTemp addr1 = newTemp(Ity_I64);
11862 IRTemp addr2 = newTemp(Ity_I64);
11863 IRTemp len1 = newTemp(Ity_I64);
11864 IRTemp len2 = newTemp(Ity_I64);
11865
11866 assign(addr1, get_gpr_dw0(r1));
11867 assign(addr2, get_gpr_dw0(r2));
11868 assign(len1, get_gpr_dw0(r1 + 1));
11869 assign(len2, get_gpr_dw0(r2 + 1));
11870
11871 UInt extended_checking = s390_host_has_etf3 && (m3 & 0x1) == 1;
11872
11873 /* We're processing the 2nd operand 1 byte at a time. Therefore, if
11874 there is less than 1 byte left, then the 2nd operand is exhausted
11875 and we're done here. cc = 0 */
11876 s390_cc_set(0);
11877 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(1)));
11878
11879 /* There is at least one byte there. Read it. */
florian11b8ee82012-08-06 13:35:33 +000011880 IRTemp byte1 = newTemp(Ity_I64);
11881 assign(byte1, unop(Iop_8Uto64, load(Ity_I8, mkexpr(addr2))));
florian6d9b9b22012-08-03 18:35:39 +000011882
11883 /* Call the helper to get number of bytes and invalid byte indicator */
11884 IRTemp retval1 = newTemp(Ity_I64);
florian3f8a96a2012-08-05 02:59:55 +000011885 assign(retval1, s390_call_cu12_cu14_helper1(mkexpr(byte1),
florian11b8ee82012-08-06 13:35:33 +000011886 mkU64(extended_checking)));
florian6d9b9b22012-08-03 18:35:39 +000011887
11888 /* Check for invalid 1st byte */
11889 IRExpr *is_invalid = unop(Iop_64to1, mkexpr(retval1));
11890 s390_cc_set(2);
11891 next_insn_if(is_invalid);
11892
11893 /* How many bytes do we have to read? */
11894 IRTemp num_src_bytes = newTemp(Ity_I64);
11895 assign(num_src_bytes, binop(Iop_Shr64, mkexpr(retval1), mkU8(8)));
11896
11897 /* Now test whether the 2nd operand is exhausted */
11898 s390_cc_set(0);
11899 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkexpr(num_src_bytes)));
11900
11901 /* Read the remaining bytes */
11902 IRExpr *cond, *addr, *byte2, *byte3, *byte4;
11903
11904 cond = binop(Iop_CmpLE64U, mkU64(2), mkexpr(num_src_bytes));
11905 addr = binop(Iop_Add64, mkexpr(addr2), mkU64(1));
florian11b8ee82012-08-06 13:35:33 +000011906 byte2 = mkite(cond, unop(Iop_8Uto64, load(Ity_I8, addr)), mkU64(0));
florian6d9b9b22012-08-03 18:35:39 +000011907 cond = binop(Iop_CmpLE64U, mkU64(3), mkexpr(num_src_bytes));
11908 addr = binop(Iop_Add64, mkexpr(addr2), mkU64(2));
florian11b8ee82012-08-06 13:35:33 +000011909 byte3 = mkite(cond, unop(Iop_8Uto64, load(Ity_I8, addr)), mkU64(0));
florian6d9b9b22012-08-03 18:35:39 +000011910 cond = binop(Iop_CmpLE64U, mkU64(4), mkexpr(num_src_bytes));
11911 addr = binop(Iop_Add64, mkexpr(addr2), mkU64(3));
florian11b8ee82012-08-06 13:35:33 +000011912 byte4 = mkite(cond, unop(Iop_8Uto64, load(Ity_I8, addr)), mkU64(0));
florian6d9b9b22012-08-03 18:35:39 +000011913
11914 /* Call the helper to get the converted value and invalid byte indicator.
11915 We can pass at most 5 arguments; therefore some encoding is needed
11916 here */
11917 IRExpr *stuff = binop(Iop_Or64,
11918 binop(Iop_Shl64, mkexpr(num_src_bytes), mkU8(1)),
11919 mkU64(extended_checking));
11920 IRTemp retval2 = newTemp(Ity_I64);
florian3f8a96a2012-08-05 02:59:55 +000011921
11922 if (is_cu12) {
11923 assign(retval2, s390_call_cu12_helper2(mkexpr(byte1), byte2, byte3,
11924 byte4, stuff));
11925 } else {
11926 assign(retval2, s390_call_cu14_helper2(mkexpr(byte1), byte2, byte3,
11927 byte4, stuff));
11928 }
florian6d9b9b22012-08-03 18:35:39 +000011929
11930 /* Check for invalid character */
11931 s390_cc_set(2);
11932 is_invalid = unop(Iop_64to1, mkexpr(retval2));
11933 next_insn_if(is_invalid);
11934
11935 /* Now test whether the 1st operand is exhausted */
11936 IRTemp num_bytes = newTemp(Ity_I64);
11937 assign(num_bytes, binop(Iop_And64,
11938 binop(Iop_Shr64, mkexpr(retval2), mkU8(8)),
11939 mkU64(0xff)));
11940 s390_cc_set(1);
11941 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
11942
11943 /* Extract the bytes to be stored at addr1 */
11944 IRTemp data = newTemp(Ity_I64);
11945 assign(data, binop(Iop_Shr64, mkexpr(retval2), mkU8(16)));
11946
florian3f8a96a2012-08-05 02:59:55 +000011947 if (is_cu12) {
11948 /* To store the bytes construct 2 dirty helper calls. The helper calls
11949 are guarded (num_bytes == 2 and num_bytes == 4, respectively) such
11950 that only one of them will be called at runtime. */
florian6d9b9b22012-08-03 18:35:39 +000011951
florian3f8a96a2012-08-05 02:59:55 +000011952 Int i;
11953 for (i = 2; i <= 4; ++i) {
11954 IRDirty *d;
florian6d9b9b22012-08-03 18:35:39 +000011955
florian3f8a96a2012-08-05 02:59:55 +000011956 if (i == 3) continue; // skip this one
florian6d9b9b22012-08-03 18:35:39 +000011957
florian3f8a96a2012-08-05 02:59:55 +000011958 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
11959 &s390x_dirtyhelper_CUxy,
11960 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
11961 mkexpr(num_bytes)));
11962 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
11963 d->mFx = Ifx_Write;
11964 d->mAddr = mkexpr(addr1);
11965 d->mSize = i;
11966 stmt(IRStmt_Dirty(d));
11967 }
11968 } else {
11969 // cu14
11970 store(mkexpr(addr1), unop(Iop_64to32, mkexpr(data)));
florian6d9b9b22012-08-03 18:35:39 +000011971 }
11972
11973 /* Update source address and length */
11974 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkexpr(num_src_bytes)));
11975 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkexpr(num_src_bytes)));
11976
11977 /* Update destination address and length */
11978 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
11979 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
11980
11981 iterate();
florian3f8a96a2012-08-05 02:59:55 +000011982}
11983
11984static HChar *
11985s390_irgen_CU12(UChar m3, UChar r1, UChar r2)
11986{
11987 s390_irgen_cu12_cu14(m3, r1, r2, /* is_cu12 = */ 1);
florian6d9b9b22012-08-03 18:35:39 +000011988
11989 return "cu12";
11990}
11991
florian3f8a96a2012-08-05 02:59:55 +000011992static HChar *
11993s390_irgen_CU14(UChar m3, UChar r1, UChar r2)
11994{
11995 s390_irgen_cu12_cu14(m3, r1, r2, /* is_cu12 = */ 0);
11996
11997 return "cu14";
11998}
11999
florian8c88cb62012-08-26 18:58:13 +000012000static IRExpr *
12001s390_call_ecag(IRExpr *op2addr)
12002{
12003 IRExpr **args, *call;
12004
12005 args = mkIRExprVec_1(op2addr);
12006 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
12007 "s390_do_ecag", &s390_do_ecag, args);
12008
12009 /* Nothing is excluded from definedness checking. */
12010 call->Iex.CCall.cee->mcx_mask = 0;
12011
12012 return call;
12013}
12014
12015static HChar *
12016s390_irgen_ECAG(UChar r1, UChar r3, IRTemp op2addr)
12017{
12018 if (! s390_host_has_gie) {
floriane75dafa2012-09-01 17:54:09 +000012019 emulation_failure(EmFail_S390X_ecag);
florian8c88cb62012-08-26 18:58:13 +000012020 } else {
12021 put_gpr_dw0(r1, s390_call_ecag(mkexpr(op2addr)));
12022 }
12023
12024 return "ecag";
12025}
12026
12027
sewardj2019a972011-03-07 16:04:07 +000012028/*------------------------------------------------------------*/
12029/*--- Build IR for special instructions ---*/
12030/*------------------------------------------------------------*/
12031
florianb4df7682011-07-05 02:09:01 +000012032static void
sewardj2019a972011-03-07 16:04:07 +000012033s390_irgen_client_request(void)
12034{
12035 if (0)
12036 vex_printf("%%R3 = client_request ( %%R2 )\n");
12037
florianf9e1ed72012-04-17 02:41:56 +000012038 Addr64 next = guest_IA_curr_instr + S390_SPECIAL_OP_PREAMBLE_SIZE
12039 + S390_SPECIAL_OP_SIZE;
sewardj2019a972011-03-07 16:04:07 +000012040
florianf9e1ed72012-04-17 02:41:56 +000012041 dis_res->jk_StopHere = Ijk_ClientReq;
sewardj2019a972011-03-07 16:04:07 +000012042 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +000012043
12044 put_IA(mkaddr_expr(next));
sewardj2019a972011-03-07 16:04:07 +000012045}
12046
florianb4df7682011-07-05 02:09:01 +000012047static void
sewardj2019a972011-03-07 16:04:07 +000012048s390_irgen_guest_NRADDR(void)
12049{
12050 if (0)
12051 vex_printf("%%R3 = guest_NRADDR\n");
12052
floriane88b3c92011-07-05 02:48:39 +000012053 put_gpr_dw0(3, IRExpr_Get(S390X_GUEST_OFFSET(guest_NRADDR), Ity_I64));
sewardj2019a972011-03-07 16:04:07 +000012054}
12055
florianb4df7682011-07-05 02:09:01 +000012056static void
sewardj2019a972011-03-07 16:04:07 +000012057s390_irgen_call_noredir(void)
12058{
florianf9e1ed72012-04-17 02:41:56 +000012059 Addr64 next = guest_IA_curr_instr + S390_SPECIAL_OP_PREAMBLE_SIZE
12060 + S390_SPECIAL_OP_SIZE;
12061
sewardj2019a972011-03-07 16:04:07 +000012062 /* Continue after special op */
florianf9e1ed72012-04-17 02:41:56 +000012063 put_gpr_dw0(14, mkaddr_expr(next));
sewardj2019a972011-03-07 16:04:07 +000012064
12065 /* The address is in REG1, all parameters are in the right (guest) places */
florianf9e1ed72012-04-17 02:41:56 +000012066 put_IA(get_gpr_dw0(1));
sewardj2019a972011-03-07 16:04:07 +000012067
12068 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +000012069 dis_res->jk_StopHere = Ijk_NoRedir;
sewardj2019a972011-03-07 16:04:07 +000012070}
12071
12072/* Force proper alignment for the structures below. */
12073#pragma pack(1)
12074
12075
12076static s390_decode_t
12077s390_decode_2byte_and_irgen(UChar *bytes)
12078{
12079 typedef union {
12080 struct {
12081 unsigned int op : 16;
12082 } E;
12083 struct {
12084 unsigned int op : 8;
12085 unsigned int i : 8;
12086 } I;
12087 struct {
12088 unsigned int op : 8;
12089 unsigned int r1 : 4;
12090 unsigned int r2 : 4;
12091 } RR;
12092 } formats;
12093 union {
12094 formats fmt;
12095 UShort value;
12096 } ovl;
12097
12098 vassert(sizeof(formats) == 2);
12099
12100 ((char *)(&ovl.value))[0] = bytes[0];
12101 ((char *)(&ovl.value))[1] = bytes[1];
12102
12103 switch (ovl.value & 0xffff) {
12104 case 0x0101: /* PR */ goto unimplemented;
12105 case 0x0102: /* UPT */ goto unimplemented;
12106 case 0x0104: /* PTFF */ goto unimplemented;
12107 case 0x0107: /* SCKPF */ goto unimplemented;
12108 case 0x010a: /* PFPO */ goto unimplemented;
12109 case 0x010b: /* TAM */ goto unimplemented;
12110 case 0x010c: /* SAM24 */ goto unimplemented;
12111 case 0x010d: /* SAM31 */ goto unimplemented;
12112 case 0x010e: /* SAM64 */ goto unimplemented;
12113 case 0x01ff: /* TRAP2 */ goto unimplemented;
12114 }
12115
12116 switch ((ovl.value & 0xff00) >> 8) {
12117 case 0x04: /* SPM */ goto unimplemented;
12118 case 0x05: /* BALR */ goto unimplemented;
12119 case 0x06: s390_format_RR_RR(s390_irgen_BCTR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12120 goto ok;
12121 case 0x07: s390_format_RR(s390_irgen_BCR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12122 goto ok;
12123 case 0x0a: s390_format_I(s390_irgen_SVC, ovl.fmt.I.i); goto ok;
12124 case 0x0b: /* BSM */ goto unimplemented;
12125 case 0x0c: /* BASSM */ goto unimplemented;
12126 case 0x0d: s390_format_RR_RR(s390_irgen_BASR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12127 goto ok;
florianb0c9a132011-09-08 15:37:39 +000012128 case 0x0e: s390_format_RR(s390_irgen_MVCL, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12129 goto ok;
12130 case 0x0f: s390_format_RR(s390_irgen_CLCL, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12131 goto ok;
sewardj2019a972011-03-07 16:04:07 +000012132 case 0x10: s390_format_RR_RR(s390_irgen_LPR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12133 goto ok;
12134 case 0x11: s390_format_RR_RR(s390_irgen_LNR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12135 goto ok;
12136 case 0x12: s390_format_RR_RR(s390_irgen_LTR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12137 goto ok;
12138 case 0x13: s390_format_RR_RR(s390_irgen_LCR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12139 goto ok;
12140 case 0x14: s390_format_RR_RR(s390_irgen_NR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12141 goto ok;
12142 case 0x15: s390_format_RR_RR(s390_irgen_CLR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12143 goto ok;
12144 case 0x16: s390_format_RR_RR(s390_irgen_OR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12145 goto ok;
12146 case 0x17: s390_format_RR_RR(s390_irgen_XR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12147 goto ok;
12148 case 0x18: s390_format_RR_RR(s390_irgen_LR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12149 goto ok;
12150 case 0x19: s390_format_RR_RR(s390_irgen_CR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12151 goto ok;
12152 case 0x1a: s390_format_RR_RR(s390_irgen_AR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12153 goto ok;
12154 case 0x1b: s390_format_RR_RR(s390_irgen_SR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12155 goto ok;
12156 case 0x1c: s390_format_RR_RR(s390_irgen_MR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12157 goto ok;
12158 case 0x1d: s390_format_RR_RR(s390_irgen_DR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12159 goto ok;
12160 case 0x1e: s390_format_RR_RR(s390_irgen_ALR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12161 goto ok;
12162 case 0x1f: s390_format_RR_RR(s390_irgen_SLR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12163 goto ok;
12164 case 0x20: /* LPDR */ goto unimplemented;
12165 case 0x21: /* LNDR */ goto unimplemented;
12166 case 0x22: /* LTDR */ goto unimplemented;
12167 case 0x23: /* LCDR */ goto unimplemented;
12168 case 0x24: /* HDR */ goto unimplemented;
12169 case 0x25: /* LDXR */ goto unimplemented;
12170 case 0x26: /* MXR */ goto unimplemented;
12171 case 0x27: /* MXDR */ goto unimplemented;
12172 case 0x28: s390_format_RR_FF(s390_irgen_LDR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12173 goto ok;
12174 case 0x29: /* CDR */ goto unimplemented;
12175 case 0x2a: /* ADR */ goto unimplemented;
12176 case 0x2b: /* SDR */ goto unimplemented;
12177 case 0x2c: /* MDR */ goto unimplemented;
12178 case 0x2d: /* DDR */ goto unimplemented;
12179 case 0x2e: /* AWR */ goto unimplemented;
12180 case 0x2f: /* SWR */ goto unimplemented;
12181 case 0x30: /* LPER */ goto unimplemented;
12182 case 0x31: /* LNER */ goto unimplemented;
12183 case 0x32: /* LTER */ goto unimplemented;
12184 case 0x33: /* LCER */ goto unimplemented;
12185 case 0x34: /* HER */ goto unimplemented;
12186 case 0x35: /* LEDR */ goto unimplemented;
12187 case 0x36: /* AXR */ goto unimplemented;
12188 case 0x37: /* SXR */ goto unimplemented;
12189 case 0x38: s390_format_RR_FF(s390_irgen_LER, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12190 goto ok;
12191 case 0x39: /* CER */ goto unimplemented;
12192 case 0x3a: /* AER */ goto unimplemented;
12193 case 0x3b: /* SER */ goto unimplemented;
12194 case 0x3c: /* MDER */ goto unimplemented;
12195 case 0x3d: /* DER */ goto unimplemented;
12196 case 0x3e: /* AUR */ goto unimplemented;
12197 case 0x3f: /* SUR */ goto unimplemented;
12198 }
12199
12200 return S390_DECODE_UNKNOWN_INSN;
12201
12202ok:
12203 return S390_DECODE_OK;
12204
12205unimplemented:
12206 return S390_DECODE_UNIMPLEMENTED_INSN;
12207}
12208
12209static s390_decode_t
12210s390_decode_4byte_and_irgen(UChar *bytes)
12211{
12212 typedef union {
12213 struct {
12214 unsigned int op1 : 8;
12215 unsigned int r1 : 4;
12216 unsigned int op2 : 4;
12217 unsigned int i2 : 16;
12218 } RI;
12219 struct {
12220 unsigned int op : 16;
12221 unsigned int : 8;
12222 unsigned int r1 : 4;
12223 unsigned int r2 : 4;
12224 } RRE;
12225 struct {
12226 unsigned int op : 16;
12227 unsigned int r1 : 4;
12228 unsigned int : 4;
12229 unsigned int r3 : 4;
12230 unsigned int r2 : 4;
12231 } RRF;
12232 struct {
12233 unsigned int op : 16;
florian1c8f7ff2012-09-01 00:12:11 +000012234 unsigned int m3 : 4;
sewardj2019a972011-03-07 16:04:07 +000012235 unsigned int m4 : 4;
12236 unsigned int r1 : 4;
12237 unsigned int r2 : 4;
12238 } RRF2;
12239 struct {
12240 unsigned int op : 16;
12241 unsigned int r3 : 4;
12242 unsigned int : 4;
12243 unsigned int r1 : 4;
12244 unsigned int r2 : 4;
12245 } RRF3;
12246 struct {
12247 unsigned int op : 16;
12248 unsigned int r3 : 4;
12249 unsigned int : 4;
12250 unsigned int r1 : 4;
12251 unsigned int r2 : 4;
12252 } RRR;
12253 struct {
12254 unsigned int op : 16;
12255 unsigned int r3 : 4;
12256 unsigned int : 4;
12257 unsigned int r1 : 4;
12258 unsigned int r2 : 4;
12259 } RRF4;
12260 struct {
12261 unsigned int op : 8;
12262 unsigned int r1 : 4;
12263 unsigned int r3 : 4;
12264 unsigned int b2 : 4;
12265 unsigned int d2 : 12;
12266 } RS;
12267 struct {
12268 unsigned int op : 8;
12269 unsigned int r1 : 4;
12270 unsigned int r3 : 4;
12271 unsigned int i2 : 16;
12272 } RSI;
12273 struct {
12274 unsigned int op : 8;
12275 unsigned int r1 : 4;
12276 unsigned int x2 : 4;
12277 unsigned int b2 : 4;
12278 unsigned int d2 : 12;
12279 } RX;
12280 struct {
12281 unsigned int op : 16;
12282 unsigned int b2 : 4;
12283 unsigned int d2 : 12;
12284 } S;
12285 struct {
12286 unsigned int op : 8;
12287 unsigned int i2 : 8;
12288 unsigned int b1 : 4;
12289 unsigned int d1 : 12;
12290 } SI;
12291 } formats;
12292 union {
12293 formats fmt;
12294 UInt value;
12295 } ovl;
12296
12297 vassert(sizeof(formats) == 4);
12298
12299 ((char *)(&ovl.value))[0] = bytes[0];
12300 ((char *)(&ovl.value))[1] = bytes[1];
12301 ((char *)(&ovl.value))[2] = bytes[2];
12302 ((char *)(&ovl.value))[3] = bytes[3];
12303
12304 switch ((ovl.value & 0xff0f0000) >> 16) {
12305 case 0xa500: s390_format_RI_RU(s390_irgen_IIHH, ovl.fmt.RI.r1,
12306 ovl.fmt.RI.i2); goto ok;
12307 case 0xa501: s390_format_RI_RU(s390_irgen_IIHL, ovl.fmt.RI.r1,
12308 ovl.fmt.RI.i2); goto ok;
12309 case 0xa502: s390_format_RI_RU(s390_irgen_IILH, ovl.fmt.RI.r1,
12310 ovl.fmt.RI.i2); goto ok;
12311 case 0xa503: s390_format_RI_RU(s390_irgen_IILL, ovl.fmt.RI.r1,
12312 ovl.fmt.RI.i2); goto ok;
12313 case 0xa504: s390_format_RI_RU(s390_irgen_NIHH, ovl.fmt.RI.r1,
12314 ovl.fmt.RI.i2); goto ok;
12315 case 0xa505: s390_format_RI_RU(s390_irgen_NIHL, ovl.fmt.RI.r1,
12316 ovl.fmt.RI.i2); goto ok;
12317 case 0xa506: s390_format_RI_RU(s390_irgen_NILH, ovl.fmt.RI.r1,
12318 ovl.fmt.RI.i2); goto ok;
12319 case 0xa507: s390_format_RI_RU(s390_irgen_NILL, ovl.fmt.RI.r1,
12320 ovl.fmt.RI.i2); goto ok;
12321 case 0xa508: s390_format_RI_RU(s390_irgen_OIHH, ovl.fmt.RI.r1,
12322 ovl.fmt.RI.i2); goto ok;
12323 case 0xa509: s390_format_RI_RU(s390_irgen_OIHL, ovl.fmt.RI.r1,
12324 ovl.fmt.RI.i2); goto ok;
12325 case 0xa50a: s390_format_RI_RU(s390_irgen_OILH, ovl.fmt.RI.r1,
12326 ovl.fmt.RI.i2); goto ok;
12327 case 0xa50b: s390_format_RI_RU(s390_irgen_OILL, ovl.fmt.RI.r1,
12328 ovl.fmt.RI.i2); goto ok;
12329 case 0xa50c: s390_format_RI_RU(s390_irgen_LLIHH, ovl.fmt.RI.r1,
12330 ovl.fmt.RI.i2); goto ok;
12331 case 0xa50d: s390_format_RI_RU(s390_irgen_LLIHL, ovl.fmt.RI.r1,
12332 ovl.fmt.RI.i2); goto ok;
12333 case 0xa50e: s390_format_RI_RU(s390_irgen_LLILH, ovl.fmt.RI.r1,
12334 ovl.fmt.RI.i2); goto ok;
12335 case 0xa50f: s390_format_RI_RU(s390_irgen_LLILL, ovl.fmt.RI.r1,
12336 ovl.fmt.RI.i2); goto ok;
12337 case 0xa700: s390_format_RI_RU(s390_irgen_TMLH, ovl.fmt.RI.r1,
12338 ovl.fmt.RI.i2); goto ok;
12339 case 0xa701: s390_format_RI_RU(s390_irgen_TMLL, ovl.fmt.RI.r1,
12340 ovl.fmt.RI.i2); goto ok;
12341 case 0xa702: s390_format_RI_RU(s390_irgen_TMHH, ovl.fmt.RI.r1,
12342 ovl.fmt.RI.i2); goto ok;
12343 case 0xa703: s390_format_RI_RU(s390_irgen_TMHL, ovl.fmt.RI.r1,
12344 ovl.fmt.RI.i2); goto ok;
12345 case 0xa704: s390_format_RI(s390_irgen_BRC, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
12346 goto ok;
12347 case 0xa705: s390_format_RI_RP(s390_irgen_BRAS, ovl.fmt.RI.r1,
12348 ovl.fmt.RI.i2); goto ok;
12349 case 0xa706: s390_format_RI_RP(s390_irgen_BRCT, ovl.fmt.RI.r1,
12350 ovl.fmt.RI.i2); goto ok;
12351 case 0xa707: s390_format_RI_RP(s390_irgen_BRCTG, ovl.fmt.RI.r1,
12352 ovl.fmt.RI.i2); goto ok;
12353 case 0xa708: s390_format_RI_RI(s390_irgen_LHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
12354 goto ok;
12355 case 0xa709: s390_format_RI_RI(s390_irgen_LGHI, ovl.fmt.RI.r1,
12356 ovl.fmt.RI.i2); goto ok;
12357 case 0xa70a: s390_format_RI_RI(s390_irgen_AHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
12358 goto ok;
12359 case 0xa70b: s390_format_RI_RI(s390_irgen_AGHI, ovl.fmt.RI.r1,
12360 ovl.fmt.RI.i2); goto ok;
12361 case 0xa70c: s390_format_RI_RI(s390_irgen_MHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
12362 goto ok;
12363 case 0xa70d: s390_format_RI_RI(s390_irgen_MGHI, ovl.fmt.RI.r1,
12364 ovl.fmt.RI.i2); goto ok;
12365 case 0xa70e: s390_format_RI_RI(s390_irgen_CHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
12366 goto ok;
12367 case 0xa70f: s390_format_RI_RI(s390_irgen_CGHI, ovl.fmt.RI.r1,
12368 ovl.fmt.RI.i2); goto ok;
12369 }
12370
12371 switch ((ovl.value & 0xffff0000) >> 16) {
12372 case 0x8000: /* SSM */ goto unimplemented;
12373 case 0x8200: /* LPSW */ goto unimplemented;
florian7700fc92012-01-16 17:25:55 +000012374 case 0x9300: /* TS */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000012375 case 0xb202: /* STIDP */ goto unimplemented;
12376 case 0xb204: /* SCK */ goto unimplemented;
florian7700fc92012-01-16 17:25:55 +000012377 case 0xb205: s390_format_S_RD(s390_irgen_STCK, ovl.fmt.S.b2, ovl.fmt.S.d2);
12378 goto ok;
sewardj2019a972011-03-07 16:04:07 +000012379 case 0xb206: /* SCKC */ goto unimplemented;
12380 case 0xb207: /* STCKC */ goto unimplemented;
12381 case 0xb208: /* SPT */ goto unimplemented;
12382 case 0xb209: /* STPT */ goto unimplemented;
12383 case 0xb20a: /* SPKA */ goto unimplemented;
12384 case 0xb20b: /* IPK */ goto unimplemented;
12385 case 0xb20d: /* PTLB */ goto unimplemented;
12386 case 0xb210: /* SPX */ goto unimplemented;
12387 case 0xb211: /* STPX */ goto unimplemented;
12388 case 0xb212: /* STAP */ goto unimplemented;
12389 case 0xb214: /* SIE */ goto unimplemented;
12390 case 0xb218: /* PC */ goto unimplemented;
12391 case 0xb219: /* SAC */ goto unimplemented;
12392 case 0xb21a: /* CFC */ goto unimplemented;
12393 case 0xb221: /* IPTE */ goto unimplemented;
12394 case 0xb222: s390_format_RRE_R0(s390_irgen_IPM, ovl.fmt.RRE.r1); goto ok;
12395 case 0xb223: /* IVSK */ goto unimplemented;
12396 case 0xb224: /* IAC */ goto unimplemented;
12397 case 0xb225: /* SSAR */ goto unimplemented;
12398 case 0xb226: /* EPAR */ goto unimplemented;
12399 case 0xb227: /* ESAR */ goto unimplemented;
12400 case 0xb228: /* PT */ goto unimplemented;
12401 case 0xb229: /* ISKE */ goto unimplemented;
12402 case 0xb22a: /* RRBE */ goto unimplemented;
12403 case 0xb22b: /* SSKE */ goto unimplemented;
12404 case 0xb22c: /* TB */ goto unimplemented;
12405 case 0xb22d: /* DXR */ goto unimplemented;
12406 case 0xb22e: /* PGIN */ goto unimplemented;
12407 case 0xb22f: /* PGOUT */ goto unimplemented;
12408 case 0xb230: /* CSCH */ goto unimplemented;
12409 case 0xb231: /* HSCH */ goto unimplemented;
12410 case 0xb232: /* MSCH */ goto unimplemented;
12411 case 0xb233: /* SSCH */ goto unimplemented;
12412 case 0xb234: /* STSCH */ goto unimplemented;
12413 case 0xb235: /* TSCH */ goto unimplemented;
12414 case 0xb236: /* TPI */ goto unimplemented;
12415 case 0xb237: /* SAL */ goto unimplemented;
12416 case 0xb238: /* RSCH */ goto unimplemented;
12417 case 0xb239: /* STCRW */ goto unimplemented;
12418 case 0xb23a: /* STCPS */ goto unimplemented;
12419 case 0xb23b: /* RCHP */ goto unimplemented;
12420 case 0xb23c: /* SCHM */ goto unimplemented;
12421 case 0xb240: /* BAKR */ goto unimplemented;
floriana4384a32011-08-11 16:58:45 +000012422 case 0xb241: s390_format_RRE(s390_irgen_CKSM, ovl.fmt.RRE.r1,
12423 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000012424 case 0xb244: /* SQDR */ goto unimplemented;
12425 case 0xb245: /* SQER */ goto unimplemented;
12426 case 0xb246: /* STURA */ goto unimplemented;
12427 case 0xb247: /* MSTA */ goto unimplemented;
12428 case 0xb248: /* PALB */ goto unimplemented;
12429 case 0xb249: /* EREG */ goto unimplemented;
12430 case 0xb24a: /* ESTA */ goto unimplemented;
12431 case 0xb24b: /* LURA */ goto unimplemented;
12432 case 0xb24c: /* TAR */ goto unimplemented;
12433 case 0xb24d: s390_format_RRE(s390_irgen_CPYA, ovl.fmt.RRE.r1,
12434 ovl.fmt.RRE.r2); goto ok;
12435 case 0xb24e: s390_format_RRE(s390_irgen_SAR, ovl.fmt.RRE.r1, ovl.fmt.RRE.r2);
12436 goto ok;
12437 case 0xb24f: s390_format_RRE(s390_irgen_EAR, ovl.fmt.RRE.r1, ovl.fmt.RRE.r2);
12438 goto ok;
12439 case 0xb250: /* CSP */ goto unimplemented;
12440 case 0xb252: s390_format_RRE_RR(s390_irgen_MSR, ovl.fmt.RRE.r1,
12441 ovl.fmt.RRE.r2); goto ok;
12442 case 0xb254: /* MVPG */ goto unimplemented;
12443 case 0xb255: s390_format_RRE_RR(s390_irgen_MVST, ovl.fmt.RRE.r1,
12444 ovl.fmt.RRE.r2); goto ok;
12445 case 0xb257: /* CUSE */ goto unimplemented;
12446 case 0xb258: /* BSG */ goto unimplemented;
12447 case 0xb25a: /* BSA */ goto unimplemented;
12448 case 0xb25d: s390_format_RRE_RR(s390_irgen_CLST, ovl.fmt.RRE.r1,
12449 ovl.fmt.RRE.r2); goto ok;
12450 case 0xb25e: s390_format_RRE_RR(s390_irgen_SRST, ovl.fmt.RRE.r1,
12451 ovl.fmt.RRE.r2); goto ok;
12452 case 0xb263: /* CMPSC */ goto unimplemented;
12453 case 0xb274: /* SIGA */ goto unimplemented;
12454 case 0xb276: /* XSCH */ goto unimplemented;
12455 case 0xb277: /* RP */ goto unimplemented;
sewardj1e5fea62011-05-17 16:18:36 +000012456 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 +000012457 case 0xb279: /* SACF */ goto unimplemented;
sewardj1e5fea62011-05-17 16:18:36 +000012458 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 +000012459 case 0xb27d: /* STSI */ goto unimplemented;
12460 case 0xb299: s390_format_S_RD(s390_irgen_SRNM, ovl.fmt.S.b2, ovl.fmt.S.d2);
12461 goto ok;
12462 case 0xb29c: s390_format_S_RD(s390_irgen_STFPC, ovl.fmt.S.b2, ovl.fmt.S.d2);
12463 goto ok;
12464 case 0xb29d: s390_format_S_RD(s390_irgen_LFPC, ovl.fmt.S.b2, ovl.fmt.S.d2);
12465 goto ok;
florian730448f2012-02-04 17:07:07 +000012466 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 +000012467 case 0xb2a6: s390_format_RRF_M0RERE(s390_irgen_CU21, ovl.fmt.RRF3.r3,
12468 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
12469 goto ok;
florian6d9b9b22012-08-03 18:35:39 +000012470 case 0xb2a7: s390_format_RRF_M0RERE(s390_irgen_CU12, ovl.fmt.RRF3.r3,
12471 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
12472 goto ok;
florian933065d2011-07-11 01:48:02 +000012473 case 0xb2b0: s390_format_S_RD(s390_irgen_STFLE, ovl.fmt.S.b2, ovl.fmt.S.d2);
12474 goto ok;
sewardj2019a972011-03-07 16:04:07 +000012475 case 0xb2b1: /* STFL */ goto unimplemented;
12476 case 0xb2b2: /* LPSWE */ goto unimplemented;
12477 case 0xb2b8: /* SRNMB */ goto unimplemented;
12478 case 0xb2b9: /* SRNMT */ goto unimplemented;
12479 case 0xb2bd: /* LFAS */ goto unimplemented;
12480 case 0xb2ff: /* TRAP4 */ goto unimplemented;
12481 case 0xb300: s390_format_RRE_FF(s390_irgen_LPEBR, ovl.fmt.RRE.r1,
12482 ovl.fmt.RRE.r2); goto ok;
12483 case 0xb301: s390_format_RRE_FF(s390_irgen_LNEBR, ovl.fmt.RRE.r1,
12484 ovl.fmt.RRE.r2); goto ok;
12485 case 0xb302: s390_format_RRE_FF(s390_irgen_LTEBR, ovl.fmt.RRE.r1,
12486 ovl.fmt.RRE.r2); goto ok;
12487 case 0xb303: s390_format_RRE_FF(s390_irgen_LCEBR, ovl.fmt.RRE.r1,
12488 ovl.fmt.RRE.r2); goto ok;
12489 case 0xb304: s390_format_RRE_FF(s390_irgen_LDEBR, ovl.fmt.RRE.r1,
12490 ovl.fmt.RRE.r2); goto ok;
12491 case 0xb305: s390_format_RRE_FF(s390_irgen_LXDBR, ovl.fmt.RRE.r1,
12492 ovl.fmt.RRE.r2); goto ok;
12493 case 0xb306: s390_format_RRE_FF(s390_irgen_LXEBR, ovl.fmt.RRE.r1,
12494 ovl.fmt.RRE.r2); goto ok;
12495 case 0xb307: /* MXDBR */ goto unimplemented;
12496 case 0xb308: /* KEBR */ goto unimplemented;
12497 case 0xb309: s390_format_RRE_FF(s390_irgen_CEBR, ovl.fmt.RRE.r1,
12498 ovl.fmt.RRE.r2); goto ok;
12499 case 0xb30a: s390_format_RRE_FF(s390_irgen_AEBR, ovl.fmt.RRE.r1,
12500 ovl.fmt.RRE.r2); goto ok;
12501 case 0xb30b: s390_format_RRE_FF(s390_irgen_SEBR, ovl.fmt.RRE.r1,
12502 ovl.fmt.RRE.r2); goto ok;
12503 case 0xb30c: /* MDEBR */ goto unimplemented;
12504 case 0xb30d: s390_format_RRE_FF(s390_irgen_DEBR, ovl.fmt.RRE.r1,
12505 ovl.fmt.RRE.r2); goto ok;
12506 case 0xb30e: s390_format_RRF_F0FF(s390_irgen_MAEBR, ovl.fmt.RRF.r1,
12507 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
12508 case 0xb30f: s390_format_RRF_F0FF(s390_irgen_MSEBR, ovl.fmt.RRF.r1,
12509 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
12510 case 0xb310: s390_format_RRE_FF(s390_irgen_LPDBR, ovl.fmt.RRE.r1,
12511 ovl.fmt.RRE.r2); goto ok;
12512 case 0xb311: s390_format_RRE_FF(s390_irgen_LNDBR, ovl.fmt.RRE.r1,
12513 ovl.fmt.RRE.r2); goto ok;
12514 case 0xb312: s390_format_RRE_FF(s390_irgen_LTDBR, ovl.fmt.RRE.r1,
12515 ovl.fmt.RRE.r2); goto ok;
12516 case 0xb313: s390_format_RRE_FF(s390_irgen_LCDBR, ovl.fmt.RRE.r1,
12517 ovl.fmt.RRE.r2); goto ok;
12518 case 0xb314: s390_format_RRE_FF(s390_irgen_SQEBR, ovl.fmt.RRE.r1,
12519 ovl.fmt.RRE.r2); goto ok;
12520 case 0xb315: s390_format_RRE_FF(s390_irgen_SQDBR, ovl.fmt.RRE.r1,
12521 ovl.fmt.RRE.r2); goto ok;
12522 case 0xb316: s390_format_RRE_FF(s390_irgen_SQXBR, ovl.fmt.RRE.r1,
12523 ovl.fmt.RRE.r2); goto ok;
12524 case 0xb317: s390_format_RRE_FF(s390_irgen_MEEBR, ovl.fmt.RRE.r1,
12525 ovl.fmt.RRE.r2); goto ok;
12526 case 0xb318: /* KDBR */ goto unimplemented;
12527 case 0xb319: s390_format_RRE_FF(s390_irgen_CDBR, ovl.fmt.RRE.r1,
12528 ovl.fmt.RRE.r2); goto ok;
12529 case 0xb31a: s390_format_RRE_FF(s390_irgen_ADBR, ovl.fmt.RRE.r1,
12530 ovl.fmt.RRE.r2); goto ok;
12531 case 0xb31b: s390_format_RRE_FF(s390_irgen_SDBR, ovl.fmt.RRE.r1,
12532 ovl.fmt.RRE.r2); goto ok;
12533 case 0xb31c: s390_format_RRE_FF(s390_irgen_MDBR, ovl.fmt.RRE.r1,
12534 ovl.fmt.RRE.r2); goto ok;
12535 case 0xb31d: s390_format_RRE_FF(s390_irgen_DDBR, ovl.fmt.RRE.r1,
12536 ovl.fmt.RRE.r2); goto ok;
12537 case 0xb31e: s390_format_RRF_F0FF(s390_irgen_MADBR, ovl.fmt.RRF.r1,
12538 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
12539 case 0xb31f: s390_format_RRF_F0FF(s390_irgen_MSDBR, ovl.fmt.RRF.r1,
12540 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
12541 case 0xb324: /* LDER */ goto unimplemented;
12542 case 0xb325: /* LXDR */ goto unimplemented;
12543 case 0xb326: /* LXER */ goto unimplemented;
12544 case 0xb32e: /* MAER */ goto unimplemented;
12545 case 0xb32f: /* MSER */ goto unimplemented;
12546 case 0xb336: /* SQXR */ goto unimplemented;
12547 case 0xb337: /* MEER */ goto unimplemented;
12548 case 0xb338: /* MAYLR */ goto unimplemented;
12549 case 0xb339: /* MYLR */ goto unimplemented;
12550 case 0xb33a: /* MAYR */ goto unimplemented;
12551 case 0xb33b: /* MYR */ goto unimplemented;
12552 case 0xb33c: /* MAYHR */ goto unimplemented;
12553 case 0xb33d: /* MYHR */ goto unimplemented;
12554 case 0xb33e: /* MADR */ goto unimplemented;
12555 case 0xb33f: /* MSDR */ goto unimplemented;
12556 case 0xb340: s390_format_RRE_FF(s390_irgen_LPXBR, ovl.fmt.RRE.r1,
12557 ovl.fmt.RRE.r2); goto ok;
12558 case 0xb341: s390_format_RRE_FF(s390_irgen_LNXBR, ovl.fmt.RRE.r1,
12559 ovl.fmt.RRE.r2); goto ok;
12560 case 0xb342: s390_format_RRE_FF(s390_irgen_LTXBR, ovl.fmt.RRE.r1,
12561 ovl.fmt.RRE.r2); goto ok;
12562 case 0xb343: s390_format_RRE_FF(s390_irgen_LCXBR, ovl.fmt.RRE.r1,
12563 ovl.fmt.RRE.r2); goto ok;
12564 case 0xb344: s390_format_RRE_FF(s390_irgen_LEDBR, ovl.fmt.RRE.r1,
12565 ovl.fmt.RRE.r2); goto ok;
12566 case 0xb345: s390_format_RRE_FF(s390_irgen_LDXBR, ovl.fmt.RRE.r1,
12567 ovl.fmt.RRE.r2); goto ok;
12568 case 0xb346: s390_format_RRE_FF(s390_irgen_LEXBR, ovl.fmt.RRE.r1,
12569 ovl.fmt.RRE.r2); goto ok;
12570 case 0xb347: /* FIXBR */ goto unimplemented;
12571 case 0xb348: /* KXBR */ goto unimplemented;
12572 case 0xb349: s390_format_RRE_FF(s390_irgen_CXBR, ovl.fmt.RRE.r1,
12573 ovl.fmt.RRE.r2); goto ok;
12574 case 0xb34a: s390_format_RRE_FF(s390_irgen_AXBR, ovl.fmt.RRE.r1,
12575 ovl.fmt.RRE.r2); goto ok;
12576 case 0xb34b: s390_format_RRE_FF(s390_irgen_SXBR, ovl.fmt.RRE.r1,
12577 ovl.fmt.RRE.r2); goto ok;
12578 case 0xb34c: s390_format_RRE_FF(s390_irgen_MXBR, ovl.fmt.RRE.r1,
12579 ovl.fmt.RRE.r2); goto ok;
12580 case 0xb34d: s390_format_RRE_FF(s390_irgen_DXBR, ovl.fmt.RRE.r1,
12581 ovl.fmt.RRE.r2); goto ok;
12582 case 0xb350: /* TBEDR */ goto unimplemented;
12583 case 0xb351: /* TBDR */ goto unimplemented;
12584 case 0xb353: /* DIEBR */ goto unimplemented;
12585 case 0xb357: /* FIEBR */ goto unimplemented;
12586 case 0xb358: /* THDER */ goto unimplemented;
12587 case 0xb359: /* THDR */ goto unimplemented;
12588 case 0xb35b: /* DIDBR */ goto unimplemented;
12589 case 0xb35f: /* FIDBR */ goto unimplemented;
12590 case 0xb360: /* LPXR */ goto unimplemented;
12591 case 0xb361: /* LNXR */ goto unimplemented;
12592 case 0xb362: /* LTXR */ goto unimplemented;
12593 case 0xb363: /* LCXR */ goto unimplemented;
12594 case 0xb365: s390_format_RRE_FF(s390_irgen_LXR, ovl.fmt.RRE.r1,
12595 ovl.fmt.RRE.r2); goto ok;
12596 case 0xb366: /* LEXR */ goto unimplemented;
12597 case 0xb367: /* FIXR */ goto unimplemented;
12598 case 0xb369: /* CXR */ goto unimplemented;
12599 case 0xb370: s390_format_RRE_FF(s390_irgen_LPDFR, ovl.fmt.RRE.r1,
12600 ovl.fmt.RRE.r2); goto ok;
12601 case 0xb371: s390_format_RRE_FF(s390_irgen_LNDFR, ovl.fmt.RRE.r1,
12602 ovl.fmt.RRE.r2); goto ok;
12603 case 0xb372: s390_format_RRF_F0FF2(s390_irgen_CPSDR, ovl.fmt.RRF3.r3,
12604 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
12605 goto ok;
12606 case 0xb373: s390_format_RRE_FF(s390_irgen_LCDFR, ovl.fmt.RRE.r1,
12607 ovl.fmt.RRE.r2); goto ok;
12608 case 0xb374: s390_format_RRE_F0(s390_irgen_LZER, ovl.fmt.RRE.r1); goto ok;
12609 case 0xb375: s390_format_RRE_F0(s390_irgen_LZDR, ovl.fmt.RRE.r1); goto ok;
12610 case 0xb376: s390_format_RRE_F0(s390_irgen_LZXR, ovl.fmt.RRE.r1); goto ok;
12611 case 0xb377: /* FIER */ goto unimplemented;
12612 case 0xb37f: /* FIDR */ goto unimplemented;
12613 case 0xb384: s390_format_RRE_R0(s390_irgen_SFPC, ovl.fmt.RRE.r1); goto ok;
12614 case 0xb385: /* SFASR */ goto unimplemented;
12615 case 0xb38c: s390_format_RRE_R0(s390_irgen_EFPC, ovl.fmt.RRE.r1); goto ok;
florian1c8f7ff2012-09-01 00:12:11 +000012616 case 0xb390: s390_format_RRF_UUFR(s390_irgen_CELFBR, ovl.fmt.RRF2.m3,
12617 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12618 ovl.fmt.RRF2.r2); goto ok;
12619 case 0xb391: s390_format_RRF_UUFR(s390_irgen_CDLFBR, ovl.fmt.RRF2.m3,
12620 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12621 ovl.fmt.RRF2.r2); goto ok;
12622 case 0xb392: s390_format_RRF_UUFR(s390_irgen_CXLFBR, ovl.fmt.RRF2.m3,
12623 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12624 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000012625 case 0xb394: s390_format_RRE_FR(s390_irgen_CEFBR, ovl.fmt.RRE.r1,
12626 ovl.fmt.RRE.r2); goto ok;
12627 case 0xb395: s390_format_RRE_FR(s390_irgen_CDFBR, ovl.fmt.RRE.r1,
12628 ovl.fmt.RRE.r2); goto ok;
12629 case 0xb396: s390_format_RRE_FR(s390_irgen_CXFBR, ovl.fmt.RRE.r1,
12630 ovl.fmt.RRE.r2); goto ok;
12631 case 0xb398: s390_format_RRF_U0RF(s390_irgen_CFEBR, ovl.fmt.RRF3.r3,
12632 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
12633 goto ok;
12634 case 0xb399: s390_format_RRF_U0RF(s390_irgen_CFDBR, ovl.fmt.RRF3.r3,
12635 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
12636 goto ok;
12637 case 0xb39a: s390_format_RRF_U0RF(s390_irgen_CFXBR, ovl.fmt.RRF3.r3,
12638 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
12639 goto ok;
florian1c8f7ff2012-09-01 00:12:11 +000012640 case 0xb39c: s390_format_RRF_UURF(s390_irgen_CLFEBR, ovl.fmt.RRF2.m3,
12641 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12642 ovl.fmt.RRF2.r2); goto ok;
12643 case 0xb39d: s390_format_RRF_UURF(s390_irgen_CLFDBR, ovl.fmt.RRF2.m3,
12644 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12645 ovl.fmt.RRF2.r2); goto ok;
12646 case 0xb39e: s390_format_RRF_UURF(s390_irgen_CLFXBR, ovl.fmt.RRF2.m3,
12647 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12648 ovl.fmt.RRF2.r2); goto ok;
12649 case 0xb3a0: s390_format_RRF_UUFR(s390_irgen_CELGBR, ovl.fmt.RRF2.m3,
12650 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12651 ovl.fmt.RRF2.r2); goto ok;
12652 case 0xb3a1: s390_format_RRF_UUFR(s390_irgen_CDLGBR, ovl.fmt.RRF2.m3,
12653 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12654 ovl.fmt.RRF2.r2); goto ok;
12655 case 0xb3a2: s390_format_RRF_UUFR(s390_irgen_CXLGBR, ovl.fmt.RRF2.m3,
12656 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12657 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000012658 case 0xb3a4: s390_format_RRE_FR(s390_irgen_CEGBR, ovl.fmt.RRE.r1,
12659 ovl.fmt.RRE.r2); goto ok;
12660 case 0xb3a5: s390_format_RRE_FR(s390_irgen_CDGBR, ovl.fmt.RRE.r1,
12661 ovl.fmt.RRE.r2); goto ok;
12662 case 0xb3a6: s390_format_RRE_FR(s390_irgen_CXGBR, ovl.fmt.RRE.r1,
12663 ovl.fmt.RRE.r2); goto ok;
12664 case 0xb3a8: s390_format_RRF_U0RF(s390_irgen_CGEBR, ovl.fmt.RRF3.r3,
12665 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
12666 goto ok;
12667 case 0xb3a9: s390_format_RRF_U0RF(s390_irgen_CGDBR, ovl.fmt.RRF3.r3,
12668 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
12669 goto ok;
12670 case 0xb3aa: s390_format_RRF_U0RF(s390_irgen_CGXBR, ovl.fmt.RRF3.r3,
12671 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
12672 goto ok;
florian1c8f7ff2012-09-01 00:12:11 +000012673 case 0xb3ac: s390_format_RRF_UURF(s390_irgen_CLGEBR, ovl.fmt.RRF2.m3,
12674 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12675 ovl.fmt.RRF2.r2); goto ok;
12676 case 0xb3ad: s390_format_RRF_UURF(s390_irgen_CLGDBR, ovl.fmt.RRF2.m3,
12677 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12678 ovl.fmt.RRF2.r2); goto ok;
12679 case 0xb3ae: s390_format_RRF_UURF(s390_irgen_CLGXBR, ovl.fmt.RRF2.m3,
12680 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12681 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000012682 case 0xb3b4: /* CEFR */ goto unimplemented;
12683 case 0xb3b5: /* CDFR */ goto unimplemented;
12684 case 0xb3b6: /* CXFR */ goto unimplemented;
12685 case 0xb3b8: /* CFER */ goto unimplemented;
12686 case 0xb3b9: /* CFDR */ goto unimplemented;
12687 case 0xb3ba: /* CFXR */ goto unimplemented;
12688 case 0xb3c1: s390_format_RRE_FR(s390_irgen_LDGR, ovl.fmt.RRE.r1,
12689 ovl.fmt.RRE.r2); goto ok;
12690 case 0xb3c4: /* CEGR */ goto unimplemented;
12691 case 0xb3c5: /* CDGR */ goto unimplemented;
12692 case 0xb3c6: /* CXGR */ goto unimplemented;
12693 case 0xb3c8: /* CGER */ goto unimplemented;
12694 case 0xb3c9: /* CGDR */ goto unimplemented;
12695 case 0xb3ca: /* CGXR */ goto unimplemented;
12696 case 0xb3cd: s390_format_RRE_RF(s390_irgen_LGDR, ovl.fmt.RRE.r1,
12697 ovl.fmt.RRE.r2); goto ok;
12698 case 0xb3d0: /* MDTR */ goto unimplemented;
12699 case 0xb3d1: /* DDTR */ goto unimplemented;
12700 case 0xb3d2: /* ADTR */ goto unimplemented;
12701 case 0xb3d3: /* SDTR */ goto unimplemented;
12702 case 0xb3d4: /* LDETR */ goto unimplemented;
12703 case 0xb3d5: /* LEDTR */ goto unimplemented;
12704 case 0xb3d6: /* LTDTR */ goto unimplemented;
12705 case 0xb3d7: /* FIDTR */ goto unimplemented;
12706 case 0xb3d8: /* MXTR */ goto unimplemented;
12707 case 0xb3d9: /* DXTR */ goto unimplemented;
12708 case 0xb3da: /* AXTR */ goto unimplemented;
12709 case 0xb3db: /* SXTR */ goto unimplemented;
12710 case 0xb3dc: /* LXDTR */ goto unimplemented;
12711 case 0xb3dd: /* LDXTR */ goto unimplemented;
12712 case 0xb3de: /* LTXTR */ goto unimplemented;
12713 case 0xb3df: /* FIXTR */ goto unimplemented;
12714 case 0xb3e0: /* KDTR */ goto unimplemented;
12715 case 0xb3e1: /* CGDTR */ goto unimplemented;
12716 case 0xb3e2: /* CUDTR */ goto unimplemented;
12717 case 0xb3e3: /* CSDTR */ goto unimplemented;
12718 case 0xb3e4: /* CDTR */ goto unimplemented;
12719 case 0xb3e5: /* EEDTR */ goto unimplemented;
12720 case 0xb3e7: /* ESDTR */ goto unimplemented;
12721 case 0xb3e8: /* KXTR */ goto unimplemented;
12722 case 0xb3e9: /* CGXTR */ goto unimplemented;
12723 case 0xb3ea: /* CUXTR */ goto unimplemented;
12724 case 0xb3eb: /* CSXTR */ goto unimplemented;
12725 case 0xb3ec: /* CXTR */ goto unimplemented;
12726 case 0xb3ed: /* EEXTR */ goto unimplemented;
12727 case 0xb3ef: /* ESXTR */ goto unimplemented;
12728 case 0xb3f1: /* CDGTR */ goto unimplemented;
12729 case 0xb3f2: /* CDUTR */ goto unimplemented;
12730 case 0xb3f3: /* CDSTR */ goto unimplemented;
12731 case 0xb3f4: /* CEDTR */ goto unimplemented;
12732 case 0xb3f5: /* QADTR */ goto unimplemented;
12733 case 0xb3f6: /* IEDTR */ goto unimplemented;
12734 case 0xb3f7: /* RRDTR */ goto unimplemented;
12735 case 0xb3f9: /* CXGTR */ goto unimplemented;
12736 case 0xb3fa: /* CXUTR */ goto unimplemented;
12737 case 0xb3fb: /* CXSTR */ goto unimplemented;
12738 case 0xb3fc: /* CEXTR */ goto unimplemented;
12739 case 0xb3fd: /* QAXTR */ goto unimplemented;
12740 case 0xb3fe: /* IEXTR */ goto unimplemented;
12741 case 0xb3ff: /* RRXTR */ goto unimplemented;
12742 case 0xb900: s390_format_RRE_RR(s390_irgen_LPGR, ovl.fmt.RRE.r1,
12743 ovl.fmt.RRE.r2); goto ok;
12744 case 0xb901: s390_format_RRE_RR(s390_irgen_LNGR, ovl.fmt.RRE.r1,
12745 ovl.fmt.RRE.r2); goto ok;
12746 case 0xb902: s390_format_RRE_RR(s390_irgen_LTGR, ovl.fmt.RRE.r1,
12747 ovl.fmt.RRE.r2); goto ok;
12748 case 0xb903: s390_format_RRE_RR(s390_irgen_LCGR, ovl.fmt.RRE.r1,
12749 ovl.fmt.RRE.r2); goto ok;
12750 case 0xb904: s390_format_RRE_RR(s390_irgen_LGR, ovl.fmt.RRE.r1,
12751 ovl.fmt.RRE.r2); goto ok;
12752 case 0xb905: /* LURAG */ goto unimplemented;
12753 case 0xb906: s390_format_RRE_RR(s390_irgen_LGBR, ovl.fmt.RRE.r1,
12754 ovl.fmt.RRE.r2); goto ok;
12755 case 0xb907: s390_format_RRE_RR(s390_irgen_LGHR, ovl.fmt.RRE.r1,
12756 ovl.fmt.RRE.r2); goto ok;
12757 case 0xb908: s390_format_RRE_RR(s390_irgen_AGR, ovl.fmt.RRE.r1,
12758 ovl.fmt.RRE.r2); goto ok;
12759 case 0xb909: s390_format_RRE_RR(s390_irgen_SGR, ovl.fmt.RRE.r1,
12760 ovl.fmt.RRE.r2); goto ok;
12761 case 0xb90a: s390_format_RRE_RR(s390_irgen_ALGR, ovl.fmt.RRE.r1,
12762 ovl.fmt.RRE.r2); goto ok;
12763 case 0xb90b: s390_format_RRE_RR(s390_irgen_SLGR, ovl.fmt.RRE.r1,
12764 ovl.fmt.RRE.r2); goto ok;
12765 case 0xb90c: s390_format_RRE_RR(s390_irgen_MSGR, ovl.fmt.RRE.r1,
12766 ovl.fmt.RRE.r2); goto ok;
12767 case 0xb90d: s390_format_RRE_RR(s390_irgen_DSGR, ovl.fmt.RRE.r1,
12768 ovl.fmt.RRE.r2); goto ok;
12769 case 0xb90e: /* EREGG */ goto unimplemented;
12770 case 0xb90f: s390_format_RRE_RR(s390_irgen_LRVGR, ovl.fmt.RRE.r1,
12771 ovl.fmt.RRE.r2); goto ok;
12772 case 0xb910: s390_format_RRE_RR(s390_irgen_LPGFR, ovl.fmt.RRE.r1,
12773 ovl.fmt.RRE.r2); goto ok;
12774 case 0xb911: s390_format_RRE_RR(s390_irgen_LNGFR, ovl.fmt.RRE.r1,
12775 ovl.fmt.RRE.r2); goto ok;
12776 case 0xb912: s390_format_RRE_RR(s390_irgen_LTGFR, ovl.fmt.RRE.r1,
12777 ovl.fmt.RRE.r2); goto ok;
12778 case 0xb913: s390_format_RRE_RR(s390_irgen_LCGFR, ovl.fmt.RRE.r1,
12779 ovl.fmt.RRE.r2); goto ok;
12780 case 0xb914: s390_format_RRE_RR(s390_irgen_LGFR, ovl.fmt.RRE.r1,
12781 ovl.fmt.RRE.r2); goto ok;
12782 case 0xb916: s390_format_RRE_RR(s390_irgen_LLGFR, ovl.fmt.RRE.r1,
12783 ovl.fmt.RRE.r2); goto ok;
12784 case 0xb917: s390_format_RRE_RR(s390_irgen_LLGTR, ovl.fmt.RRE.r1,
12785 ovl.fmt.RRE.r2); goto ok;
12786 case 0xb918: s390_format_RRE_RR(s390_irgen_AGFR, ovl.fmt.RRE.r1,
12787 ovl.fmt.RRE.r2); goto ok;
12788 case 0xb919: s390_format_RRE_RR(s390_irgen_SGFR, ovl.fmt.RRE.r1,
12789 ovl.fmt.RRE.r2); goto ok;
12790 case 0xb91a: s390_format_RRE_RR(s390_irgen_ALGFR, ovl.fmt.RRE.r1,
12791 ovl.fmt.RRE.r2); goto ok;
12792 case 0xb91b: s390_format_RRE_RR(s390_irgen_SLGFR, ovl.fmt.RRE.r1,
12793 ovl.fmt.RRE.r2); goto ok;
12794 case 0xb91c: s390_format_RRE_RR(s390_irgen_MSGFR, ovl.fmt.RRE.r1,
12795 ovl.fmt.RRE.r2); goto ok;
12796 case 0xb91d: s390_format_RRE_RR(s390_irgen_DSGFR, ovl.fmt.RRE.r1,
12797 ovl.fmt.RRE.r2); goto ok;
12798 case 0xb91e: /* KMAC */ goto unimplemented;
12799 case 0xb91f: s390_format_RRE_RR(s390_irgen_LRVR, ovl.fmt.RRE.r1,
12800 ovl.fmt.RRE.r2); goto ok;
12801 case 0xb920: s390_format_RRE_RR(s390_irgen_CGR, ovl.fmt.RRE.r1,
12802 ovl.fmt.RRE.r2); goto ok;
12803 case 0xb921: s390_format_RRE_RR(s390_irgen_CLGR, ovl.fmt.RRE.r1,
12804 ovl.fmt.RRE.r2); goto ok;
12805 case 0xb925: /* STURG */ goto unimplemented;
12806 case 0xb926: s390_format_RRE_RR(s390_irgen_LBR, ovl.fmt.RRE.r1,
12807 ovl.fmt.RRE.r2); goto ok;
12808 case 0xb927: s390_format_RRE_RR(s390_irgen_LHR, ovl.fmt.RRE.r1,
12809 ovl.fmt.RRE.r2); goto ok;
12810 case 0xb928: /* PCKMO */ goto unimplemented;
12811 case 0xb92b: /* KMO */ goto unimplemented;
12812 case 0xb92c: /* PCC */ goto unimplemented;
12813 case 0xb92d: /* KMCTR */ goto unimplemented;
12814 case 0xb92e: /* KM */ goto unimplemented;
12815 case 0xb92f: /* KMC */ goto unimplemented;
12816 case 0xb930: s390_format_RRE_RR(s390_irgen_CGFR, ovl.fmt.RRE.r1,
12817 ovl.fmt.RRE.r2); goto ok;
12818 case 0xb931: s390_format_RRE_RR(s390_irgen_CLGFR, ovl.fmt.RRE.r1,
12819 ovl.fmt.RRE.r2); goto ok;
12820 case 0xb93e: /* KIMD */ goto unimplemented;
12821 case 0xb93f: /* KLMD */ goto unimplemented;
12822 case 0xb941: /* CFDTR */ goto unimplemented;
12823 case 0xb942: /* CLGDTR */ goto unimplemented;
12824 case 0xb943: /* CLFDTR */ goto unimplemented;
12825 case 0xb946: s390_format_RRE_RR(s390_irgen_BCTGR, ovl.fmt.RRE.r1,
12826 ovl.fmt.RRE.r2); goto ok;
12827 case 0xb949: /* CFXTR */ goto unimplemented;
12828 case 0xb94a: /* CLGXTR */ goto unimplemented;
12829 case 0xb94b: /* CLFXTR */ goto unimplemented;
12830 case 0xb951: /* CDFTR */ goto unimplemented;
12831 case 0xb952: /* CDLGTR */ goto unimplemented;
12832 case 0xb953: /* CDLFTR */ goto unimplemented;
12833 case 0xb959: /* CXFTR */ goto unimplemented;
12834 case 0xb95a: /* CXLGTR */ goto unimplemented;
12835 case 0xb95b: /* CXLFTR */ goto unimplemented;
12836 case 0xb960: /* CGRT */ goto unimplemented;
12837 case 0xb961: /* CLGRT */ goto unimplemented;
12838 case 0xb972: /* CRT */ goto unimplemented;
12839 case 0xb973: /* CLRT */ goto unimplemented;
12840 case 0xb980: s390_format_RRE_RR(s390_irgen_NGR, ovl.fmt.RRE.r1,
12841 ovl.fmt.RRE.r2); goto ok;
12842 case 0xb981: s390_format_RRE_RR(s390_irgen_OGR, ovl.fmt.RRE.r1,
12843 ovl.fmt.RRE.r2); goto ok;
12844 case 0xb982: s390_format_RRE_RR(s390_irgen_XGR, ovl.fmt.RRE.r1,
12845 ovl.fmt.RRE.r2); goto ok;
12846 case 0xb983: s390_format_RRE_RR(s390_irgen_FLOGR, ovl.fmt.RRE.r1,
12847 ovl.fmt.RRE.r2); goto ok;
12848 case 0xb984: s390_format_RRE_RR(s390_irgen_LLGCR, ovl.fmt.RRE.r1,
12849 ovl.fmt.RRE.r2); goto ok;
12850 case 0xb985: s390_format_RRE_RR(s390_irgen_LLGHR, ovl.fmt.RRE.r1,
12851 ovl.fmt.RRE.r2); goto ok;
12852 case 0xb986: s390_format_RRE_RR(s390_irgen_MLGR, ovl.fmt.RRE.r1,
12853 ovl.fmt.RRE.r2); goto ok;
12854 case 0xb987: s390_format_RRE_RR(s390_irgen_DLGR, ovl.fmt.RRE.r1,
12855 ovl.fmt.RRE.r2); goto ok;
12856 case 0xb988: s390_format_RRE_RR(s390_irgen_ALCGR, ovl.fmt.RRE.r1,
12857 ovl.fmt.RRE.r2); goto ok;
12858 case 0xb989: s390_format_RRE_RR(s390_irgen_SLBGR, ovl.fmt.RRE.r1,
12859 ovl.fmt.RRE.r2); goto ok;
12860 case 0xb98a: /* CSPG */ goto unimplemented;
12861 case 0xb98d: /* EPSW */ goto unimplemented;
12862 case 0xb98e: /* IDTE */ goto unimplemented;
florian730448f2012-02-04 17:07:07 +000012863 case 0xb990: s390_format_RRF_M0RERE(s390_irgen_TRTT, ovl.fmt.RRF3.r3,
12864 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
12865 case 0xb991: s390_format_RRF_M0RERE(s390_irgen_TRTO, ovl.fmt.RRF3.r3,
12866 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
12867 case 0xb992: s390_format_RRF_M0RERE(s390_irgen_TROT, ovl.fmt.RRF3.r3,
12868 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
florian9af37692012-01-15 21:01:16 +000012869 case 0xb993: s390_format_RRF_M0RERE(s390_irgen_TROO, ovl.fmt.RRF3.r3,
12870 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000012871 case 0xb994: s390_format_RRE_RR(s390_irgen_LLCR, ovl.fmt.RRE.r1,
12872 ovl.fmt.RRE.r2); goto ok;
12873 case 0xb995: s390_format_RRE_RR(s390_irgen_LLHR, ovl.fmt.RRE.r1,
12874 ovl.fmt.RRE.r2); goto ok;
12875 case 0xb996: s390_format_RRE_RR(s390_irgen_MLR, ovl.fmt.RRE.r1,
12876 ovl.fmt.RRE.r2); goto ok;
12877 case 0xb997: s390_format_RRE_RR(s390_irgen_DLR, ovl.fmt.RRE.r1,
12878 ovl.fmt.RRE.r2); goto ok;
12879 case 0xb998: s390_format_RRE_RR(s390_irgen_ALCR, ovl.fmt.RRE.r1,
12880 ovl.fmt.RRE.r2); goto ok;
12881 case 0xb999: s390_format_RRE_RR(s390_irgen_SLBR, ovl.fmt.RRE.r1,
12882 ovl.fmt.RRE.r2); goto ok;
12883 case 0xb99a: /* EPAIR */ goto unimplemented;
12884 case 0xb99b: /* ESAIR */ goto unimplemented;
12885 case 0xb99d: /* ESEA */ goto unimplemented;
12886 case 0xb99e: /* PTI */ goto unimplemented;
12887 case 0xb99f: /* SSAIR */ goto unimplemented;
12888 case 0xb9a2: /* PTF */ goto unimplemented;
12889 case 0xb9aa: /* LPTEA */ goto unimplemented;
12890 case 0xb9ae: /* RRBM */ goto unimplemented;
12891 case 0xb9af: /* PFMF */ goto unimplemented;
florian3f8a96a2012-08-05 02:59:55 +000012892 case 0xb9b0: s390_format_RRF_M0RERE(s390_irgen_CU14, ovl.fmt.RRF3.r3,
12893 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
12894 goto ok;
florian2a415a12012-07-21 17:41:36 +000012895 case 0xb9b1: s390_format_RRF_M0RERE(s390_irgen_CU24, ovl.fmt.RRF3.r3,
12896 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
12897 goto ok;
florianaf2194f2012-08-06 00:07:54 +000012898 case 0xb9b2: s390_format_RRE_RR(s390_irgen_CU41, ovl.fmt.RRE.r1,
12899 ovl.fmt.RRE.r2); goto ok;
florian956194b2012-07-28 22:18:32 +000012900 case 0xb9b3: s390_format_RRE_RR(s390_irgen_CU42, ovl.fmt.RRE.r1,
12901 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000012902 case 0xb9bd: /* TRTRE */ goto unimplemented;
12903 case 0xb9be: /* SRSTU */ goto unimplemented;
12904 case 0xb9bf: /* TRTE */ goto unimplemented;
12905 case 0xb9c8: s390_format_RRF_R0RR2(s390_irgen_AHHHR, ovl.fmt.RRF4.r3,
12906 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12907 goto ok;
12908 case 0xb9c9: s390_format_RRF_R0RR2(s390_irgen_SHHHR, ovl.fmt.RRF4.r3,
12909 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12910 goto ok;
12911 case 0xb9ca: s390_format_RRF_R0RR2(s390_irgen_ALHHHR, ovl.fmt.RRF4.r3,
12912 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12913 goto ok;
12914 case 0xb9cb: s390_format_RRF_R0RR2(s390_irgen_SLHHHR, ovl.fmt.RRF4.r3,
12915 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12916 goto ok;
12917 case 0xb9cd: s390_format_RRE_RR(s390_irgen_CHHR, ovl.fmt.RRE.r1,
12918 ovl.fmt.RRE.r2); goto ok;
12919 case 0xb9cf: s390_format_RRE_RR(s390_irgen_CLHHR, ovl.fmt.RRE.r1,
12920 ovl.fmt.RRE.r2); goto ok;
12921 case 0xb9d8: s390_format_RRF_R0RR2(s390_irgen_AHHLR, ovl.fmt.RRF4.r3,
12922 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12923 goto ok;
12924 case 0xb9d9: s390_format_RRF_R0RR2(s390_irgen_SHHLR, ovl.fmt.RRF4.r3,
12925 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12926 goto ok;
12927 case 0xb9da: s390_format_RRF_R0RR2(s390_irgen_ALHHLR, ovl.fmt.RRF4.r3,
12928 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12929 goto ok;
12930 case 0xb9db: s390_format_RRF_R0RR2(s390_irgen_SLHHLR, ovl.fmt.RRF4.r3,
12931 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12932 goto ok;
12933 case 0xb9dd: s390_format_RRE_RR(s390_irgen_CHLR, ovl.fmt.RRE.r1,
12934 ovl.fmt.RRE.r2); goto ok;
12935 case 0xb9df: s390_format_RRE_RR(s390_irgen_CLHLR, ovl.fmt.RRE.r1,
12936 ovl.fmt.RRE.r2); goto ok;
12937 case 0xb9e1: /* POPCNT */ goto unimplemented;
sewardjd7bde722011-04-05 13:19:33 +000012938 case 0xb9e2: s390_format_RRF_U0RR(s390_irgen_LOCGR, ovl.fmt.RRF3.r3,
12939 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2,
12940 S390_XMNM_LOCGR); goto ok;
sewardj2019a972011-03-07 16:04:07 +000012941 case 0xb9e4: s390_format_RRF_R0RR2(s390_irgen_NGRK, ovl.fmt.RRF4.r3,
12942 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12943 goto ok;
12944 case 0xb9e6: s390_format_RRF_R0RR2(s390_irgen_OGRK, ovl.fmt.RRF4.r3,
12945 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12946 goto ok;
12947 case 0xb9e7: s390_format_RRF_R0RR2(s390_irgen_XGRK, ovl.fmt.RRF4.r3,
12948 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12949 goto ok;
12950 case 0xb9e8: s390_format_RRF_R0RR2(s390_irgen_AGRK, ovl.fmt.RRF4.r3,
12951 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12952 goto ok;
12953 case 0xb9e9: s390_format_RRF_R0RR2(s390_irgen_SGRK, ovl.fmt.RRF4.r3,
12954 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12955 goto ok;
12956 case 0xb9ea: s390_format_RRF_R0RR2(s390_irgen_ALGRK, ovl.fmt.RRF4.r3,
12957 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12958 goto ok;
12959 case 0xb9eb: s390_format_RRF_R0RR2(s390_irgen_SLGRK, ovl.fmt.RRF4.r3,
12960 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12961 goto ok;
sewardjd7bde722011-04-05 13:19:33 +000012962 case 0xb9f2: s390_format_RRF_U0RR(s390_irgen_LOCR, ovl.fmt.RRF3.r3,
12963 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2,
12964 S390_XMNM_LOCR); goto ok;
sewardj2019a972011-03-07 16:04:07 +000012965 case 0xb9f4: s390_format_RRF_R0RR2(s390_irgen_NRK, ovl.fmt.RRF4.r3,
12966 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12967 goto ok;
12968 case 0xb9f6: s390_format_RRF_R0RR2(s390_irgen_ORK, ovl.fmt.RRF4.r3,
12969 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12970 goto ok;
12971 case 0xb9f7: s390_format_RRF_R0RR2(s390_irgen_XRK, ovl.fmt.RRF4.r3,
12972 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12973 goto ok;
12974 case 0xb9f8: s390_format_RRF_R0RR2(s390_irgen_ARK, ovl.fmt.RRF4.r3,
12975 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12976 goto ok;
12977 case 0xb9f9: s390_format_RRF_R0RR2(s390_irgen_SRK, ovl.fmt.RRF4.r3,
12978 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12979 goto ok;
12980 case 0xb9fa: s390_format_RRF_R0RR2(s390_irgen_ALRK, ovl.fmt.RRF4.r3,
12981 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12982 goto ok;
12983 case 0xb9fb: s390_format_RRF_R0RR2(s390_irgen_SLRK, ovl.fmt.RRF4.r3,
12984 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12985 goto ok;
12986 }
12987
12988 switch ((ovl.value & 0xff000000) >> 24) {
12989 case 0x40: s390_format_RX_RRRD(s390_irgen_STH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12990 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12991 case 0x41: s390_format_RX_RRRD(s390_irgen_LA, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12992 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12993 case 0x42: s390_format_RX_RRRD(s390_irgen_STC, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12994 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12995 case 0x43: s390_format_RX_RRRD(s390_irgen_IC, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12996 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12997 case 0x44: s390_format_RX_RRRD(s390_irgen_EX, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12998 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12999 case 0x45: /* BAL */ goto unimplemented;
13000 case 0x46: s390_format_RX_RRRD(s390_irgen_BCT, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13001 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13002 case 0x47: s390_format_RX(s390_irgen_BC, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13003 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13004 case 0x48: s390_format_RX_RRRD(s390_irgen_LH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13005 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13006 case 0x49: s390_format_RX_RRRD(s390_irgen_CH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13007 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13008 case 0x4a: s390_format_RX_RRRD(s390_irgen_AH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13009 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13010 case 0x4b: s390_format_RX_RRRD(s390_irgen_SH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13011 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13012 case 0x4c: s390_format_RX_RRRD(s390_irgen_MH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13013 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13014 case 0x4d: s390_format_RX_RRRD(s390_irgen_BAS, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13015 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13016 case 0x4e: s390_format_RX_RRRD(s390_irgen_CVD, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13017 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13018 case 0x4f: s390_format_RX_RRRD(s390_irgen_CVB, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13019 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13020 case 0x50: s390_format_RX_RRRD(s390_irgen_ST, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13021 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13022 case 0x51: s390_format_RX_RRRD(s390_irgen_LAE, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13023 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13024 case 0x54: s390_format_RX_RRRD(s390_irgen_N, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13025 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13026 case 0x55: s390_format_RX_RRRD(s390_irgen_CL, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13027 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13028 case 0x56: s390_format_RX_RRRD(s390_irgen_O, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13029 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13030 case 0x57: s390_format_RX_RRRD(s390_irgen_X, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13031 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13032 case 0x58: s390_format_RX_RRRD(s390_irgen_L, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13033 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13034 case 0x59: s390_format_RX_RRRD(s390_irgen_C, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13035 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13036 case 0x5a: s390_format_RX_RRRD(s390_irgen_A, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13037 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13038 case 0x5b: s390_format_RX_RRRD(s390_irgen_S, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13039 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13040 case 0x5c: s390_format_RX_RRRD(s390_irgen_M, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13041 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13042 case 0x5d: s390_format_RX_RRRD(s390_irgen_D, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13043 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13044 case 0x5e: s390_format_RX_RRRD(s390_irgen_AL, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13045 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13046 case 0x5f: s390_format_RX_RRRD(s390_irgen_SL, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13047 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13048 case 0x60: s390_format_RX_FRRD(s390_irgen_STD, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13049 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13050 case 0x67: /* MXD */ goto unimplemented;
13051 case 0x68: s390_format_RX_FRRD(s390_irgen_LD, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13052 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13053 case 0x69: /* CD */ goto unimplemented;
13054 case 0x6a: /* AD */ goto unimplemented;
13055 case 0x6b: /* SD */ goto unimplemented;
13056 case 0x6c: /* MD */ goto unimplemented;
13057 case 0x6d: /* DD */ goto unimplemented;
13058 case 0x6e: /* AW */ goto unimplemented;
13059 case 0x6f: /* SW */ goto unimplemented;
13060 case 0x70: s390_format_RX_FRRD(s390_irgen_STE, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13061 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13062 case 0x71: s390_format_RX_RRRD(s390_irgen_MS, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13063 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13064 case 0x78: s390_format_RX_FRRD(s390_irgen_LE, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13065 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13066 case 0x79: /* CE */ goto unimplemented;
13067 case 0x7a: /* AE */ goto unimplemented;
13068 case 0x7b: /* SE */ goto unimplemented;
13069 case 0x7c: /* MDE */ goto unimplemented;
13070 case 0x7d: /* DE */ goto unimplemented;
13071 case 0x7e: /* AU */ goto unimplemented;
13072 case 0x7f: /* SU */ goto unimplemented;
13073 case 0x83: /* DIAG */ goto unimplemented;
13074 case 0x84: s390_format_RSI_RRP(s390_irgen_BRXH, ovl.fmt.RSI.r1,
13075 ovl.fmt.RSI.r3, ovl.fmt.RSI.i2); goto ok;
13076 case 0x85: s390_format_RSI_RRP(s390_irgen_BRXLE, ovl.fmt.RSI.r1,
13077 ovl.fmt.RSI.r3, ovl.fmt.RSI.i2); goto ok;
13078 case 0x86: s390_format_RS_RRRD(s390_irgen_BXH, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13079 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13080 case 0x87: s390_format_RS_RRRD(s390_irgen_BXLE, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13081 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13082 case 0x88: s390_format_RS_R0RD(s390_irgen_SRL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
13083 ovl.fmt.RS.d2); goto ok;
13084 case 0x89: s390_format_RS_R0RD(s390_irgen_SLL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
13085 ovl.fmt.RS.d2); goto ok;
13086 case 0x8a: s390_format_RS_R0RD(s390_irgen_SRA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
13087 ovl.fmt.RS.d2); goto ok;
13088 case 0x8b: s390_format_RS_R0RD(s390_irgen_SLA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
13089 ovl.fmt.RS.d2); goto ok;
13090 case 0x8c: s390_format_RS_R0RD(s390_irgen_SRDL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
13091 ovl.fmt.RS.d2); goto ok;
13092 case 0x8d: s390_format_RS_R0RD(s390_irgen_SLDL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
13093 ovl.fmt.RS.d2); goto ok;
13094 case 0x8e: s390_format_RS_R0RD(s390_irgen_SRDA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
13095 ovl.fmt.RS.d2); goto ok;
13096 case 0x8f: s390_format_RS_R0RD(s390_irgen_SLDA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
13097 ovl.fmt.RS.d2); goto ok;
13098 case 0x90: s390_format_RS_RRRD(s390_irgen_STM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13099 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13100 case 0x91: s390_format_SI_URD(s390_irgen_TM, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
13101 ovl.fmt.SI.d1); goto ok;
13102 case 0x92: s390_format_SI_URD(s390_irgen_MVI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
13103 ovl.fmt.SI.d1); goto ok;
13104 case 0x94: s390_format_SI_URD(s390_irgen_NI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
13105 ovl.fmt.SI.d1); goto ok;
13106 case 0x95: s390_format_SI_URD(s390_irgen_CLI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
13107 ovl.fmt.SI.d1); goto ok;
13108 case 0x96: s390_format_SI_URD(s390_irgen_OI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
13109 ovl.fmt.SI.d1); goto ok;
13110 case 0x97: s390_format_SI_URD(s390_irgen_XI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
13111 ovl.fmt.SI.d1); goto ok;
13112 case 0x98: s390_format_RS_RRRD(s390_irgen_LM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13113 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13114 case 0x99: /* TRACE */ goto unimplemented;
13115 case 0x9a: s390_format_RS_AARD(s390_irgen_LAM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13116 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13117 case 0x9b: s390_format_RS_AARD(s390_irgen_STAM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13118 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13119 case 0xa8: s390_format_RS_RRRD(s390_irgen_MVCLE, ovl.fmt.RS.r1,
13120 ovl.fmt.RS.r3, ovl.fmt.RS.b2, ovl.fmt.RS.d2);
13121 goto ok;
13122 case 0xa9: s390_format_RS_RRRD(s390_irgen_CLCLE, ovl.fmt.RS.r1,
13123 ovl.fmt.RS.r3, ovl.fmt.RS.b2, ovl.fmt.RS.d2);
13124 goto ok;
13125 case 0xac: /* STNSM */ goto unimplemented;
13126 case 0xad: /* STOSM */ goto unimplemented;
13127 case 0xae: /* SIGP */ goto unimplemented;
13128 case 0xaf: /* MC */ goto unimplemented;
13129 case 0xb1: /* LRA */ goto unimplemented;
13130 case 0xb6: /* STCTL */ goto unimplemented;
13131 case 0xb7: /* LCTL */ goto unimplemented;
13132 case 0xba: s390_format_RS_RRRD(s390_irgen_CS, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13133 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
florian448cbba2012-06-06 02:26:01 +000013134 case 0xbb: s390_format_RS_RRRD(s390_irgen_CDS, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13135 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013136 case 0xbd: s390_format_RS_RURD(s390_irgen_CLM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13137 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13138 case 0xbe: s390_format_RS_RURD(s390_irgen_STCM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13139 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13140 case 0xbf: s390_format_RS_RURD(s390_irgen_ICM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13141 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13142 }
13143
13144 return S390_DECODE_UNKNOWN_INSN;
13145
13146ok:
13147 return S390_DECODE_OK;
13148
13149unimplemented:
13150 return S390_DECODE_UNIMPLEMENTED_INSN;
13151}
13152
13153static s390_decode_t
13154s390_decode_6byte_and_irgen(UChar *bytes)
13155{
13156 typedef union {
13157 struct {
13158 unsigned int op1 : 8;
13159 unsigned int r1 : 4;
13160 unsigned int r3 : 4;
13161 unsigned int i2 : 16;
13162 unsigned int : 8;
13163 unsigned int op2 : 8;
13164 } RIE;
13165 struct {
13166 unsigned int op1 : 8;
13167 unsigned int r1 : 4;
13168 unsigned int r2 : 4;
13169 unsigned int i3 : 8;
13170 unsigned int i4 : 8;
13171 unsigned int i5 : 8;
13172 unsigned int op2 : 8;
13173 } RIE_RRUUU;
13174 struct {
13175 unsigned int op1 : 8;
13176 unsigned int r1 : 4;
13177 unsigned int : 4;
13178 unsigned int i2 : 16;
13179 unsigned int m3 : 4;
13180 unsigned int : 4;
13181 unsigned int op2 : 8;
13182 } RIEv1;
13183 struct {
13184 unsigned int op1 : 8;
13185 unsigned int r1 : 4;
13186 unsigned int r2 : 4;
13187 unsigned int i4 : 16;
13188 unsigned int m3 : 4;
13189 unsigned int : 4;
13190 unsigned int op2 : 8;
13191 } RIE_RRPU;
13192 struct {
13193 unsigned int op1 : 8;
13194 unsigned int r1 : 4;
13195 unsigned int m3 : 4;
13196 unsigned int i4 : 16;
13197 unsigned int i2 : 8;
13198 unsigned int op2 : 8;
13199 } RIEv3;
13200 struct {
13201 unsigned int op1 : 8;
13202 unsigned int r1 : 4;
13203 unsigned int op2 : 4;
13204 unsigned int i2 : 32;
13205 } RIL;
13206 struct {
13207 unsigned int op1 : 8;
13208 unsigned int r1 : 4;
13209 unsigned int m3 : 4;
13210 unsigned int b4 : 4;
13211 unsigned int d4 : 12;
13212 unsigned int i2 : 8;
13213 unsigned int op2 : 8;
13214 } RIS;
13215 struct {
13216 unsigned int op1 : 8;
13217 unsigned int r1 : 4;
13218 unsigned int r2 : 4;
13219 unsigned int b4 : 4;
13220 unsigned int d4 : 12;
13221 unsigned int m3 : 4;
13222 unsigned int : 4;
13223 unsigned int op2 : 8;
13224 } RRS;
13225 struct {
13226 unsigned int op1 : 8;
13227 unsigned int l1 : 4;
13228 unsigned int : 4;
13229 unsigned int b1 : 4;
13230 unsigned int d1 : 12;
13231 unsigned int : 8;
13232 unsigned int op2 : 8;
13233 } RSL;
13234 struct {
13235 unsigned int op1 : 8;
13236 unsigned int r1 : 4;
13237 unsigned int r3 : 4;
13238 unsigned int b2 : 4;
13239 unsigned int dl2 : 12;
13240 unsigned int dh2 : 8;
13241 unsigned int op2 : 8;
13242 } RSY;
13243 struct {
13244 unsigned int op1 : 8;
13245 unsigned int r1 : 4;
13246 unsigned int x2 : 4;
13247 unsigned int b2 : 4;
13248 unsigned int d2 : 12;
13249 unsigned int : 8;
13250 unsigned int op2 : 8;
13251 } RXE;
13252 struct {
13253 unsigned int op1 : 8;
13254 unsigned int r3 : 4;
13255 unsigned int x2 : 4;
13256 unsigned int b2 : 4;
13257 unsigned int d2 : 12;
13258 unsigned int r1 : 4;
13259 unsigned int : 4;
13260 unsigned int op2 : 8;
13261 } RXF;
13262 struct {
13263 unsigned int op1 : 8;
13264 unsigned int r1 : 4;
13265 unsigned int x2 : 4;
13266 unsigned int b2 : 4;
13267 unsigned int dl2 : 12;
13268 unsigned int dh2 : 8;
13269 unsigned int op2 : 8;
13270 } RXY;
13271 struct {
13272 unsigned int op1 : 8;
13273 unsigned int i2 : 8;
13274 unsigned int b1 : 4;
13275 unsigned int dl1 : 12;
13276 unsigned int dh1 : 8;
13277 unsigned int op2 : 8;
13278 } SIY;
13279 struct {
13280 unsigned int op : 8;
13281 unsigned int l : 8;
13282 unsigned int b1 : 4;
13283 unsigned int d1 : 12;
13284 unsigned int b2 : 4;
13285 unsigned int d2 : 12;
13286 } SS;
13287 struct {
13288 unsigned int op : 8;
13289 unsigned int l1 : 4;
13290 unsigned int l2 : 4;
13291 unsigned int b1 : 4;
13292 unsigned int d1 : 12;
13293 unsigned int b2 : 4;
13294 unsigned int d2 : 12;
13295 } SS_LLRDRD;
13296 struct {
13297 unsigned int op : 8;
13298 unsigned int r1 : 4;
13299 unsigned int r3 : 4;
13300 unsigned int b2 : 4;
13301 unsigned int d2 : 12;
13302 unsigned int b4 : 4;
13303 unsigned int d4 : 12;
13304 } SS_RRRDRD2;
13305 struct {
13306 unsigned int op : 16;
13307 unsigned int b1 : 4;
13308 unsigned int d1 : 12;
13309 unsigned int b2 : 4;
13310 unsigned int d2 : 12;
13311 } SSE;
13312 struct {
13313 unsigned int op1 : 8;
13314 unsigned int r3 : 4;
13315 unsigned int op2 : 4;
13316 unsigned int b1 : 4;
13317 unsigned int d1 : 12;
13318 unsigned int b2 : 4;
13319 unsigned int d2 : 12;
13320 } SSF;
13321 struct {
13322 unsigned int op : 16;
13323 unsigned int b1 : 4;
13324 unsigned int d1 : 12;
13325 unsigned int i2 : 16;
13326 } SIL;
13327 } formats;
13328 union {
13329 formats fmt;
13330 ULong value;
13331 } ovl;
13332
13333 vassert(sizeof(formats) == 6);
13334
13335 ((char *)(&ovl.value))[0] = bytes[0];
13336 ((char *)(&ovl.value))[1] = bytes[1];
13337 ((char *)(&ovl.value))[2] = bytes[2];
13338 ((char *)(&ovl.value))[3] = bytes[3];
13339 ((char *)(&ovl.value))[4] = bytes[4];
13340 ((char *)(&ovl.value))[5] = bytes[5];
13341 ((char *)(&ovl.value))[6] = 0x0;
13342 ((char *)(&ovl.value))[7] = 0x0;
13343
13344 switch ((ovl.value >> 16) & 0xff00000000ffULL) {
13345 case 0xe30000000002ULL: s390_format_RXY_RRRD(s390_irgen_LTG, ovl.fmt.RXY.r1,
13346 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13347 ovl.fmt.RXY.dl2,
13348 ovl.fmt.RXY.dh2); goto ok;
13349 case 0xe30000000003ULL: /* LRAG */ goto unimplemented;
13350 case 0xe30000000004ULL: s390_format_RXY_RRRD(s390_irgen_LG, ovl.fmt.RXY.r1,
13351 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13352 ovl.fmt.RXY.dl2,
13353 ovl.fmt.RXY.dh2); goto ok;
13354 case 0xe30000000006ULL: s390_format_RXY_RRRD(s390_irgen_CVBY, ovl.fmt.RXY.r1,
13355 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13356 ovl.fmt.RXY.dl2,
13357 ovl.fmt.RXY.dh2); goto ok;
13358 case 0xe30000000008ULL: s390_format_RXY_RRRD(s390_irgen_AG, ovl.fmt.RXY.r1,
13359 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13360 ovl.fmt.RXY.dl2,
13361 ovl.fmt.RXY.dh2); goto ok;
13362 case 0xe30000000009ULL: s390_format_RXY_RRRD(s390_irgen_SG, ovl.fmt.RXY.r1,
13363 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13364 ovl.fmt.RXY.dl2,
13365 ovl.fmt.RXY.dh2); goto ok;
13366 case 0xe3000000000aULL: s390_format_RXY_RRRD(s390_irgen_ALG, ovl.fmt.RXY.r1,
13367 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13368 ovl.fmt.RXY.dl2,
13369 ovl.fmt.RXY.dh2); goto ok;
13370 case 0xe3000000000bULL: s390_format_RXY_RRRD(s390_irgen_SLG, ovl.fmt.RXY.r1,
13371 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13372 ovl.fmt.RXY.dl2,
13373 ovl.fmt.RXY.dh2); goto ok;
13374 case 0xe3000000000cULL: s390_format_RXY_RRRD(s390_irgen_MSG, ovl.fmt.RXY.r1,
13375 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13376 ovl.fmt.RXY.dl2,
13377 ovl.fmt.RXY.dh2); goto ok;
13378 case 0xe3000000000dULL: s390_format_RXY_RRRD(s390_irgen_DSG, ovl.fmt.RXY.r1,
13379 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13380 ovl.fmt.RXY.dl2,
13381 ovl.fmt.RXY.dh2); goto ok;
13382 case 0xe3000000000eULL: /* CVBG */ goto unimplemented;
13383 case 0xe3000000000fULL: s390_format_RXY_RRRD(s390_irgen_LRVG, ovl.fmt.RXY.r1,
13384 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13385 ovl.fmt.RXY.dl2,
13386 ovl.fmt.RXY.dh2); goto ok;
13387 case 0xe30000000012ULL: s390_format_RXY_RRRD(s390_irgen_LT, ovl.fmt.RXY.r1,
13388 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13389 ovl.fmt.RXY.dl2,
13390 ovl.fmt.RXY.dh2); goto ok;
13391 case 0xe30000000013ULL: /* LRAY */ goto unimplemented;
13392 case 0xe30000000014ULL: s390_format_RXY_RRRD(s390_irgen_LGF, ovl.fmt.RXY.r1,
13393 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13394 ovl.fmt.RXY.dl2,
13395 ovl.fmt.RXY.dh2); goto ok;
13396 case 0xe30000000015ULL: s390_format_RXY_RRRD(s390_irgen_LGH, ovl.fmt.RXY.r1,
13397 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13398 ovl.fmt.RXY.dl2,
13399 ovl.fmt.RXY.dh2); goto ok;
13400 case 0xe30000000016ULL: s390_format_RXY_RRRD(s390_irgen_LLGF, ovl.fmt.RXY.r1,
13401 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13402 ovl.fmt.RXY.dl2,
13403 ovl.fmt.RXY.dh2); goto ok;
13404 case 0xe30000000017ULL: s390_format_RXY_RRRD(s390_irgen_LLGT, ovl.fmt.RXY.r1,
13405 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13406 ovl.fmt.RXY.dl2,
13407 ovl.fmt.RXY.dh2); goto ok;
13408 case 0xe30000000018ULL: s390_format_RXY_RRRD(s390_irgen_AGF, ovl.fmt.RXY.r1,
13409 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13410 ovl.fmt.RXY.dl2,
13411 ovl.fmt.RXY.dh2); goto ok;
13412 case 0xe30000000019ULL: s390_format_RXY_RRRD(s390_irgen_SGF, ovl.fmt.RXY.r1,
13413 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13414 ovl.fmt.RXY.dl2,
13415 ovl.fmt.RXY.dh2); goto ok;
13416 case 0xe3000000001aULL: s390_format_RXY_RRRD(s390_irgen_ALGF, ovl.fmt.RXY.r1,
13417 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13418 ovl.fmt.RXY.dl2,
13419 ovl.fmt.RXY.dh2); goto ok;
13420 case 0xe3000000001bULL: s390_format_RXY_RRRD(s390_irgen_SLGF, ovl.fmt.RXY.r1,
13421 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13422 ovl.fmt.RXY.dl2,
13423 ovl.fmt.RXY.dh2); goto ok;
13424 case 0xe3000000001cULL: s390_format_RXY_RRRD(s390_irgen_MSGF, ovl.fmt.RXY.r1,
13425 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13426 ovl.fmt.RXY.dl2,
13427 ovl.fmt.RXY.dh2); goto ok;
13428 case 0xe3000000001dULL: s390_format_RXY_RRRD(s390_irgen_DSGF, ovl.fmt.RXY.r1,
13429 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13430 ovl.fmt.RXY.dl2,
13431 ovl.fmt.RXY.dh2); goto ok;
13432 case 0xe3000000001eULL: s390_format_RXY_RRRD(s390_irgen_LRV, ovl.fmt.RXY.r1,
13433 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13434 ovl.fmt.RXY.dl2,
13435 ovl.fmt.RXY.dh2); goto ok;
13436 case 0xe3000000001fULL: s390_format_RXY_RRRD(s390_irgen_LRVH, ovl.fmt.RXY.r1,
13437 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13438 ovl.fmt.RXY.dl2,
13439 ovl.fmt.RXY.dh2); goto ok;
13440 case 0xe30000000020ULL: s390_format_RXY_RRRD(s390_irgen_CG, ovl.fmt.RXY.r1,
13441 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13442 ovl.fmt.RXY.dl2,
13443 ovl.fmt.RXY.dh2); goto ok;
13444 case 0xe30000000021ULL: s390_format_RXY_RRRD(s390_irgen_CLG, ovl.fmt.RXY.r1,
13445 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13446 ovl.fmt.RXY.dl2,
13447 ovl.fmt.RXY.dh2); goto ok;
13448 case 0xe30000000024ULL: s390_format_RXY_RRRD(s390_irgen_STG, ovl.fmt.RXY.r1,
13449 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13450 ovl.fmt.RXY.dl2,
13451 ovl.fmt.RXY.dh2); goto ok;
13452 case 0xe30000000026ULL: s390_format_RXY_RRRD(s390_irgen_CVDY, ovl.fmt.RXY.r1,
13453 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13454 ovl.fmt.RXY.dl2,
13455 ovl.fmt.RXY.dh2); goto ok;
13456 case 0xe3000000002eULL: /* CVDG */ goto unimplemented;
13457 case 0xe3000000002fULL: s390_format_RXY_RRRD(s390_irgen_STRVG,
13458 ovl.fmt.RXY.r1, ovl.fmt.RXY.x2,
13459 ovl.fmt.RXY.b2, ovl.fmt.RXY.dl2,
13460 ovl.fmt.RXY.dh2); goto ok;
13461 case 0xe30000000030ULL: s390_format_RXY_RRRD(s390_irgen_CGF, ovl.fmt.RXY.r1,
13462 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13463 ovl.fmt.RXY.dl2,
13464 ovl.fmt.RXY.dh2); goto ok;
13465 case 0xe30000000031ULL: s390_format_RXY_RRRD(s390_irgen_CLGF, ovl.fmt.RXY.r1,
13466 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13467 ovl.fmt.RXY.dl2,
13468 ovl.fmt.RXY.dh2); goto ok;
13469 case 0xe30000000032ULL: s390_format_RXY_RRRD(s390_irgen_LTGF, ovl.fmt.RXY.r1,
13470 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13471 ovl.fmt.RXY.dl2,
13472 ovl.fmt.RXY.dh2); goto ok;
13473 case 0xe30000000034ULL: s390_format_RXY_RRRD(s390_irgen_CGH, ovl.fmt.RXY.r1,
13474 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13475 ovl.fmt.RXY.dl2,
13476 ovl.fmt.RXY.dh2); goto ok;
13477 case 0xe30000000036ULL: s390_format_RXY_URRD(s390_irgen_PFD, ovl.fmt.RXY.r1,
13478 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13479 ovl.fmt.RXY.dl2,
13480 ovl.fmt.RXY.dh2); goto ok;
13481 case 0xe3000000003eULL: s390_format_RXY_RRRD(s390_irgen_STRV, ovl.fmt.RXY.r1,
13482 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13483 ovl.fmt.RXY.dl2,
13484 ovl.fmt.RXY.dh2); goto ok;
13485 case 0xe3000000003fULL: s390_format_RXY_RRRD(s390_irgen_STRVH,
13486 ovl.fmt.RXY.r1, ovl.fmt.RXY.x2,
13487 ovl.fmt.RXY.b2, ovl.fmt.RXY.dl2,
13488 ovl.fmt.RXY.dh2); goto ok;
13489 case 0xe30000000046ULL: s390_format_RXY_RRRD(s390_irgen_BCTG, 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 0xe30000000050ULL: s390_format_RXY_RRRD(s390_irgen_STY, 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 0xe30000000051ULL: s390_format_RXY_RRRD(s390_irgen_MSY, 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 0xe30000000054ULL: s390_format_RXY_RRRD(s390_irgen_NY, 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 0xe30000000055ULL: s390_format_RXY_RRRD(s390_irgen_CLY, 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 0xe30000000056ULL: s390_format_RXY_RRRD(s390_irgen_OY, 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 0xe30000000057ULL: s390_format_RXY_RRRD(s390_irgen_XY, 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 0xe30000000058ULL: s390_format_RXY_RRRD(s390_irgen_LY, 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 0xe30000000059ULL: s390_format_RXY_RRRD(s390_irgen_CY, 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 0xe3000000005aULL: s390_format_RXY_RRRD(s390_irgen_AY, 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 0xe3000000005bULL: s390_format_RXY_RRRD(s390_irgen_SY, 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 0xe3000000005cULL: s390_format_RXY_RRRD(s390_irgen_MFY, 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 0xe3000000005eULL: s390_format_RXY_RRRD(s390_irgen_ALY, 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 0xe3000000005fULL: s390_format_RXY_RRRD(s390_irgen_SLY, 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 0xe30000000070ULL: s390_format_RXY_RRRD(s390_irgen_STHY, 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 0xe30000000071ULL: s390_format_RXY_RRRD(s390_irgen_LAY, ovl.fmt.RXY.r1,
13550 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13551 ovl.fmt.RXY.dl2,
13552 ovl.fmt.RXY.dh2); goto ok;
13553 case 0xe30000000072ULL: s390_format_RXY_RRRD(s390_irgen_STCY, ovl.fmt.RXY.r1,
13554 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13555 ovl.fmt.RXY.dl2,
13556 ovl.fmt.RXY.dh2); goto ok;
13557 case 0xe30000000073ULL: s390_format_RXY_RRRD(s390_irgen_ICY, ovl.fmt.RXY.r1,
13558 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13559 ovl.fmt.RXY.dl2,
13560 ovl.fmt.RXY.dh2); goto ok;
13561 case 0xe30000000075ULL: s390_format_RXY_RRRD(s390_irgen_LAEY, ovl.fmt.RXY.r1,
13562 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13563 ovl.fmt.RXY.dl2,
13564 ovl.fmt.RXY.dh2); goto ok;
13565 case 0xe30000000076ULL: s390_format_RXY_RRRD(s390_irgen_LB, ovl.fmt.RXY.r1,
13566 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13567 ovl.fmt.RXY.dl2,
13568 ovl.fmt.RXY.dh2); goto ok;
13569 case 0xe30000000077ULL: s390_format_RXY_RRRD(s390_irgen_LGB, ovl.fmt.RXY.r1,
13570 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13571 ovl.fmt.RXY.dl2,
13572 ovl.fmt.RXY.dh2); goto ok;
13573 case 0xe30000000078ULL: s390_format_RXY_RRRD(s390_irgen_LHY, ovl.fmt.RXY.r1,
13574 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13575 ovl.fmt.RXY.dl2,
13576 ovl.fmt.RXY.dh2); goto ok;
13577 case 0xe30000000079ULL: s390_format_RXY_RRRD(s390_irgen_CHY, ovl.fmt.RXY.r1,
13578 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13579 ovl.fmt.RXY.dl2,
13580 ovl.fmt.RXY.dh2); goto ok;
13581 case 0xe3000000007aULL: s390_format_RXY_RRRD(s390_irgen_AHY, ovl.fmt.RXY.r1,
13582 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13583 ovl.fmt.RXY.dl2,
13584 ovl.fmt.RXY.dh2); goto ok;
13585 case 0xe3000000007bULL: s390_format_RXY_RRRD(s390_irgen_SHY, ovl.fmt.RXY.r1,
13586 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13587 ovl.fmt.RXY.dl2,
13588 ovl.fmt.RXY.dh2); goto ok;
13589 case 0xe3000000007cULL: s390_format_RXY_RRRD(s390_irgen_MHY, ovl.fmt.RXY.r1,
13590 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13591 ovl.fmt.RXY.dl2,
13592 ovl.fmt.RXY.dh2); goto ok;
13593 case 0xe30000000080ULL: s390_format_RXY_RRRD(s390_irgen_NG, ovl.fmt.RXY.r1,
13594 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13595 ovl.fmt.RXY.dl2,
13596 ovl.fmt.RXY.dh2); goto ok;
13597 case 0xe30000000081ULL: s390_format_RXY_RRRD(s390_irgen_OG, ovl.fmt.RXY.r1,
13598 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13599 ovl.fmt.RXY.dl2,
13600 ovl.fmt.RXY.dh2); goto ok;
13601 case 0xe30000000082ULL: s390_format_RXY_RRRD(s390_irgen_XG, ovl.fmt.RXY.r1,
13602 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13603 ovl.fmt.RXY.dl2,
13604 ovl.fmt.RXY.dh2); goto ok;
13605 case 0xe30000000086ULL: s390_format_RXY_RRRD(s390_irgen_MLG, ovl.fmt.RXY.r1,
13606 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13607 ovl.fmt.RXY.dl2,
13608 ovl.fmt.RXY.dh2); goto ok;
13609 case 0xe30000000087ULL: s390_format_RXY_RRRD(s390_irgen_DLG, ovl.fmt.RXY.r1,
13610 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13611 ovl.fmt.RXY.dl2,
13612 ovl.fmt.RXY.dh2); goto ok;
13613 case 0xe30000000088ULL: s390_format_RXY_RRRD(s390_irgen_ALCG, ovl.fmt.RXY.r1,
13614 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13615 ovl.fmt.RXY.dl2,
13616 ovl.fmt.RXY.dh2); goto ok;
13617 case 0xe30000000089ULL: s390_format_RXY_RRRD(s390_irgen_SLBG, ovl.fmt.RXY.r1,
13618 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13619 ovl.fmt.RXY.dl2,
13620 ovl.fmt.RXY.dh2); goto ok;
13621 case 0xe3000000008eULL: s390_format_RXY_RRRD(s390_irgen_STPQ, ovl.fmt.RXY.r1,
13622 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13623 ovl.fmt.RXY.dl2,
13624 ovl.fmt.RXY.dh2); goto ok;
13625 case 0xe3000000008fULL: s390_format_RXY_RRRD(s390_irgen_LPQ, ovl.fmt.RXY.r1,
13626 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13627 ovl.fmt.RXY.dl2,
13628 ovl.fmt.RXY.dh2); goto ok;
13629 case 0xe30000000090ULL: s390_format_RXY_RRRD(s390_irgen_LLGC, ovl.fmt.RXY.r1,
13630 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13631 ovl.fmt.RXY.dl2,
13632 ovl.fmt.RXY.dh2); goto ok;
13633 case 0xe30000000091ULL: s390_format_RXY_RRRD(s390_irgen_LLGH, ovl.fmt.RXY.r1,
13634 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13635 ovl.fmt.RXY.dl2,
13636 ovl.fmt.RXY.dh2); goto ok;
13637 case 0xe30000000094ULL: s390_format_RXY_RRRD(s390_irgen_LLC, ovl.fmt.RXY.r1,
13638 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13639 ovl.fmt.RXY.dl2,
13640 ovl.fmt.RXY.dh2); goto ok;
13641 case 0xe30000000095ULL: s390_format_RXY_RRRD(s390_irgen_LLH, ovl.fmt.RXY.r1,
13642 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13643 ovl.fmt.RXY.dl2,
13644 ovl.fmt.RXY.dh2); goto ok;
13645 case 0xe30000000096ULL: s390_format_RXY_RRRD(s390_irgen_ML, ovl.fmt.RXY.r1,
13646 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13647 ovl.fmt.RXY.dl2,
13648 ovl.fmt.RXY.dh2); goto ok;
13649 case 0xe30000000097ULL: s390_format_RXY_RRRD(s390_irgen_DL, ovl.fmt.RXY.r1,
13650 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13651 ovl.fmt.RXY.dl2,
13652 ovl.fmt.RXY.dh2); goto ok;
13653 case 0xe30000000098ULL: s390_format_RXY_RRRD(s390_irgen_ALC, ovl.fmt.RXY.r1,
13654 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13655 ovl.fmt.RXY.dl2,
13656 ovl.fmt.RXY.dh2); goto ok;
13657 case 0xe30000000099ULL: s390_format_RXY_RRRD(s390_irgen_SLB, ovl.fmt.RXY.r1,
13658 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13659 ovl.fmt.RXY.dl2,
13660 ovl.fmt.RXY.dh2); goto ok;
13661 case 0xe300000000c0ULL: s390_format_RXY_RRRD(s390_irgen_LBH, ovl.fmt.RXY.r1,
13662 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13663 ovl.fmt.RXY.dl2,
13664 ovl.fmt.RXY.dh2); goto ok;
13665 case 0xe300000000c2ULL: s390_format_RXY_RRRD(s390_irgen_LLCH, ovl.fmt.RXY.r1,
13666 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13667 ovl.fmt.RXY.dl2,
13668 ovl.fmt.RXY.dh2); goto ok;
13669 case 0xe300000000c3ULL: s390_format_RXY_RRRD(s390_irgen_STCH, ovl.fmt.RXY.r1,
13670 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13671 ovl.fmt.RXY.dl2,
13672 ovl.fmt.RXY.dh2); goto ok;
13673 case 0xe300000000c4ULL: s390_format_RXY_RRRD(s390_irgen_LHH, ovl.fmt.RXY.r1,
13674 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13675 ovl.fmt.RXY.dl2,
13676 ovl.fmt.RXY.dh2); goto ok;
13677 case 0xe300000000c6ULL: s390_format_RXY_RRRD(s390_irgen_LLHH, ovl.fmt.RXY.r1,
13678 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13679 ovl.fmt.RXY.dl2,
13680 ovl.fmt.RXY.dh2); goto ok;
13681 case 0xe300000000c7ULL: s390_format_RXY_RRRD(s390_irgen_STHH, ovl.fmt.RXY.r1,
13682 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13683 ovl.fmt.RXY.dl2,
13684 ovl.fmt.RXY.dh2); goto ok;
13685 case 0xe300000000caULL: s390_format_RXY_RRRD(s390_irgen_LFH, ovl.fmt.RXY.r1,
13686 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13687 ovl.fmt.RXY.dl2,
13688 ovl.fmt.RXY.dh2); goto ok;
13689 case 0xe300000000cbULL: s390_format_RXY_RRRD(s390_irgen_STFH, ovl.fmt.RXY.r1,
13690 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13691 ovl.fmt.RXY.dl2,
13692 ovl.fmt.RXY.dh2); goto ok;
13693 case 0xe300000000cdULL: s390_format_RXY_RRRD(s390_irgen_CHF, ovl.fmt.RXY.r1,
13694 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13695 ovl.fmt.RXY.dl2,
13696 ovl.fmt.RXY.dh2); goto ok;
13697 case 0xe300000000cfULL: s390_format_RXY_RRRD(s390_irgen_CLHF, ovl.fmt.RXY.r1,
13698 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13699 ovl.fmt.RXY.dl2,
13700 ovl.fmt.RXY.dh2); goto ok;
13701 case 0xeb0000000004ULL: s390_format_RSY_RRRD(s390_irgen_LMG, ovl.fmt.RSY.r1,
13702 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13703 ovl.fmt.RSY.dl2,
13704 ovl.fmt.RSY.dh2); goto ok;
13705 case 0xeb000000000aULL: s390_format_RSY_RRRD(s390_irgen_SRAG, ovl.fmt.RSY.r1,
13706 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13707 ovl.fmt.RSY.dl2,
13708 ovl.fmt.RSY.dh2); goto ok;
13709 case 0xeb000000000bULL: s390_format_RSY_RRRD(s390_irgen_SLAG, ovl.fmt.RSY.r1,
13710 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13711 ovl.fmt.RSY.dl2,
13712 ovl.fmt.RSY.dh2); goto ok;
13713 case 0xeb000000000cULL: s390_format_RSY_RRRD(s390_irgen_SRLG, ovl.fmt.RSY.r1,
13714 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13715 ovl.fmt.RSY.dl2,
13716 ovl.fmt.RSY.dh2); goto ok;
13717 case 0xeb000000000dULL: s390_format_RSY_RRRD(s390_irgen_SLLG, ovl.fmt.RSY.r1,
13718 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13719 ovl.fmt.RSY.dl2,
13720 ovl.fmt.RSY.dh2); goto ok;
13721 case 0xeb000000000fULL: /* TRACG */ goto unimplemented;
13722 case 0xeb0000000014ULL: s390_format_RSY_RRRD(s390_irgen_CSY, ovl.fmt.RSY.r1,
13723 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13724 ovl.fmt.RSY.dl2,
13725 ovl.fmt.RSY.dh2); goto ok;
13726 case 0xeb000000001cULL: s390_format_RSY_RRRD(s390_irgen_RLLG, ovl.fmt.RSY.r1,
13727 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13728 ovl.fmt.RSY.dl2,
13729 ovl.fmt.RSY.dh2); goto ok;
13730 case 0xeb000000001dULL: s390_format_RSY_RRRD(s390_irgen_RLL, ovl.fmt.RSY.r1,
13731 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13732 ovl.fmt.RSY.dl2,
13733 ovl.fmt.RSY.dh2); goto ok;
13734 case 0xeb0000000020ULL: s390_format_RSY_RURD(s390_irgen_CLMH, ovl.fmt.RSY.r1,
13735 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13736 ovl.fmt.RSY.dl2,
13737 ovl.fmt.RSY.dh2); goto ok;
13738 case 0xeb0000000021ULL: s390_format_RSY_RURD(s390_irgen_CLMY, ovl.fmt.RSY.r1,
13739 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13740 ovl.fmt.RSY.dl2,
13741 ovl.fmt.RSY.dh2); goto ok;
13742 case 0xeb0000000024ULL: s390_format_RSY_RRRD(s390_irgen_STMG, ovl.fmt.RSY.r1,
13743 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13744 ovl.fmt.RSY.dl2,
13745 ovl.fmt.RSY.dh2); goto ok;
13746 case 0xeb0000000025ULL: /* STCTG */ goto unimplemented;
13747 case 0xeb0000000026ULL: s390_format_RSY_RRRD(s390_irgen_STMH, ovl.fmt.RSY.r1,
13748 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13749 ovl.fmt.RSY.dl2,
13750 ovl.fmt.RSY.dh2); goto ok;
13751 case 0xeb000000002cULL: s390_format_RSY_RURD(s390_irgen_STCMH,
13752 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
13753 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
13754 ovl.fmt.RSY.dh2); goto ok;
13755 case 0xeb000000002dULL: s390_format_RSY_RURD(s390_irgen_STCMY,
13756 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
13757 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
13758 ovl.fmt.RSY.dh2); goto ok;
13759 case 0xeb000000002fULL: /* LCTLG */ goto unimplemented;
13760 case 0xeb0000000030ULL: s390_format_RSY_RRRD(s390_irgen_CSG, ovl.fmt.RSY.r1,
13761 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13762 ovl.fmt.RSY.dl2,
13763 ovl.fmt.RSY.dh2); goto ok;
florian448cbba2012-06-06 02:26:01 +000013764 case 0xeb0000000031ULL: s390_format_RSY_RRRD(s390_irgen_CDSY, ovl.fmt.RSY.r1,
13765 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13766 ovl.fmt.RSY.dl2,
13767 ovl.fmt.RSY.dh2); goto ok;
13768 case 0xeb000000003eULL: s390_format_RSY_RRRD(s390_irgen_CDSG, ovl.fmt.RSY.r1,
13769 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13770 ovl.fmt.RSY.dl2,
13771 ovl.fmt.RSY.dh2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013772 case 0xeb0000000044ULL: s390_format_RSY_RRRD(s390_irgen_BXHG, ovl.fmt.RSY.r1,
13773 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13774 ovl.fmt.RSY.dl2,
13775 ovl.fmt.RSY.dh2); goto ok;
13776 case 0xeb0000000045ULL: s390_format_RSY_RRRD(s390_irgen_BXLEG,
13777 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
13778 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
13779 ovl.fmt.RSY.dh2); goto ok;
florian8c88cb62012-08-26 18:58:13 +000013780 case 0xeb000000004cULL: s390_format_RSY_RRRD(s390_irgen_ECAG, ovl.fmt.RSY.r1,
13781 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13782 ovl.fmt.RSY.dl2,
13783 ovl.fmt.RSY.dh2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013784 case 0xeb0000000051ULL: s390_format_SIY_URD(s390_irgen_TMY, ovl.fmt.SIY.i2,
13785 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
13786 ovl.fmt.SIY.dh1); goto ok;
13787 case 0xeb0000000052ULL: s390_format_SIY_URD(s390_irgen_MVIY, ovl.fmt.SIY.i2,
13788 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
13789 ovl.fmt.SIY.dh1); goto ok;
13790 case 0xeb0000000054ULL: s390_format_SIY_URD(s390_irgen_NIY, ovl.fmt.SIY.i2,
13791 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
13792 ovl.fmt.SIY.dh1); goto ok;
13793 case 0xeb0000000055ULL: s390_format_SIY_URD(s390_irgen_CLIY, ovl.fmt.SIY.i2,
13794 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
13795 ovl.fmt.SIY.dh1); goto ok;
13796 case 0xeb0000000056ULL: s390_format_SIY_URD(s390_irgen_OIY, ovl.fmt.SIY.i2,
13797 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
13798 ovl.fmt.SIY.dh1); goto ok;
13799 case 0xeb0000000057ULL: s390_format_SIY_URD(s390_irgen_XIY, ovl.fmt.SIY.i2,
13800 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
13801 ovl.fmt.SIY.dh1); goto ok;
13802 case 0xeb000000006aULL: s390_format_SIY_IRD(s390_irgen_ASI, ovl.fmt.SIY.i2,
13803 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
13804 ovl.fmt.SIY.dh1); goto ok;
13805 case 0xeb000000006eULL: s390_format_SIY_IRD(s390_irgen_ALSI, ovl.fmt.SIY.i2,
13806 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
13807 ovl.fmt.SIY.dh1); goto ok;
13808 case 0xeb000000007aULL: s390_format_SIY_IRD(s390_irgen_AGSI, ovl.fmt.SIY.i2,
13809 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
13810 ovl.fmt.SIY.dh1); goto ok;
13811 case 0xeb000000007eULL: s390_format_SIY_IRD(s390_irgen_ALGSI, ovl.fmt.SIY.i2,
13812 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
13813 ovl.fmt.SIY.dh1); goto ok;
13814 case 0xeb0000000080ULL: s390_format_RSY_RURD(s390_irgen_ICMH, ovl.fmt.RSY.r1,
13815 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13816 ovl.fmt.RSY.dl2,
13817 ovl.fmt.RSY.dh2); goto ok;
13818 case 0xeb0000000081ULL: s390_format_RSY_RURD(s390_irgen_ICMY, ovl.fmt.RSY.r1,
13819 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13820 ovl.fmt.RSY.dl2,
13821 ovl.fmt.RSY.dh2); goto ok;
13822 case 0xeb000000008eULL: /* MVCLU */ goto unimplemented;
13823 case 0xeb000000008fULL: /* CLCLU */ goto unimplemented;
13824 case 0xeb0000000090ULL: s390_format_RSY_RRRD(s390_irgen_STMY, ovl.fmt.RSY.r1,
13825 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13826 ovl.fmt.RSY.dl2,
13827 ovl.fmt.RSY.dh2); goto ok;
13828 case 0xeb0000000096ULL: s390_format_RSY_RRRD(s390_irgen_LMH, ovl.fmt.RSY.r1,
13829 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13830 ovl.fmt.RSY.dl2,
13831 ovl.fmt.RSY.dh2); goto ok;
13832 case 0xeb0000000098ULL: s390_format_RSY_RRRD(s390_irgen_LMY, ovl.fmt.RSY.r1,
13833 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13834 ovl.fmt.RSY.dl2,
13835 ovl.fmt.RSY.dh2); goto ok;
13836 case 0xeb000000009aULL: s390_format_RSY_AARD(s390_irgen_LAMY, ovl.fmt.RSY.r1,
13837 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13838 ovl.fmt.RSY.dl2,
13839 ovl.fmt.RSY.dh2); goto ok;
13840 case 0xeb000000009bULL: s390_format_RSY_AARD(s390_irgen_STAMY,
13841 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
13842 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
13843 ovl.fmt.RSY.dh2); goto ok;
13844 case 0xeb00000000c0ULL: /* TP */ goto unimplemented;
13845 case 0xeb00000000dcULL: s390_format_RSY_RRRD(s390_irgen_SRAK, ovl.fmt.RSY.r1,
13846 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13847 ovl.fmt.RSY.dl2,
13848 ovl.fmt.RSY.dh2); goto ok;
13849 case 0xeb00000000ddULL: s390_format_RSY_RRRD(s390_irgen_SLAK, ovl.fmt.RSY.r1,
13850 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13851 ovl.fmt.RSY.dl2,
13852 ovl.fmt.RSY.dh2); goto ok;
13853 case 0xeb00000000deULL: s390_format_RSY_RRRD(s390_irgen_SRLK, 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;
13857 case 0xeb00000000dfULL: s390_format_RSY_RRRD(s390_irgen_SLLK, 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;
sewardjd7bde722011-04-05 13:19:33 +000013861 case 0xeb00000000e2ULL: s390_format_RSY_RDRM(s390_irgen_LOCG, ovl.fmt.RSY.r1,
13862 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13863 ovl.fmt.RSY.dl2,
13864 ovl.fmt.RSY.dh2,
13865 S390_XMNM_LOCG); goto ok;
13866 case 0xeb00000000e3ULL: s390_format_RSY_RDRM(s390_irgen_STOCG,
13867 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
13868 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
13869 ovl.fmt.RSY.dh2,
13870 S390_XMNM_STOCG); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013871 case 0xeb00000000e4ULL: s390_format_RSY_RRRD(s390_irgen_LANG, ovl.fmt.RSY.r1,
13872 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13873 ovl.fmt.RSY.dl2,
13874 ovl.fmt.RSY.dh2); goto ok;
13875 case 0xeb00000000e6ULL: s390_format_RSY_RRRD(s390_irgen_LAOG, ovl.fmt.RSY.r1,
13876 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13877 ovl.fmt.RSY.dl2,
13878 ovl.fmt.RSY.dh2); goto ok;
13879 case 0xeb00000000e7ULL: s390_format_RSY_RRRD(s390_irgen_LAXG, ovl.fmt.RSY.r1,
13880 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13881 ovl.fmt.RSY.dl2,
13882 ovl.fmt.RSY.dh2); goto ok;
13883 case 0xeb00000000e8ULL: s390_format_RSY_RRRD(s390_irgen_LAAG, ovl.fmt.RSY.r1,
13884 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13885 ovl.fmt.RSY.dl2,
13886 ovl.fmt.RSY.dh2); goto ok;
13887 case 0xeb00000000eaULL: s390_format_RSY_RRRD(s390_irgen_LAALG,
13888 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
13889 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
13890 ovl.fmt.RSY.dh2); goto ok;
sewardjd7bde722011-04-05 13:19:33 +000013891 case 0xeb00000000f2ULL: s390_format_RSY_RDRM(s390_irgen_LOC, ovl.fmt.RSY.r1,
13892 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13893 ovl.fmt.RSY.dl2,
13894 ovl.fmt.RSY.dh2, S390_XMNM_LOC);
13895 goto ok;
13896 case 0xeb00000000f3ULL: s390_format_RSY_RDRM(s390_irgen_STOC, ovl.fmt.RSY.r1,
13897 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13898 ovl.fmt.RSY.dl2,
13899 ovl.fmt.RSY.dh2,
13900 S390_XMNM_STOC); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013901 case 0xeb00000000f4ULL: s390_format_RSY_RRRD(s390_irgen_LAN, ovl.fmt.RSY.r1,
13902 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13903 ovl.fmt.RSY.dl2,
13904 ovl.fmt.RSY.dh2); goto ok;
13905 case 0xeb00000000f6ULL: s390_format_RSY_RRRD(s390_irgen_LAO, ovl.fmt.RSY.r1,
13906 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13907 ovl.fmt.RSY.dl2,
13908 ovl.fmt.RSY.dh2); goto ok;
13909 case 0xeb00000000f7ULL: s390_format_RSY_RRRD(s390_irgen_LAX, ovl.fmt.RSY.r1,
13910 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13911 ovl.fmt.RSY.dl2,
13912 ovl.fmt.RSY.dh2); goto ok;
13913 case 0xeb00000000f8ULL: s390_format_RSY_RRRD(s390_irgen_LAA, ovl.fmt.RSY.r1,
13914 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13915 ovl.fmt.RSY.dl2,
13916 ovl.fmt.RSY.dh2); goto ok;
13917 case 0xeb00000000faULL: s390_format_RSY_RRRD(s390_irgen_LAAL, 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 0xec0000000044ULL: s390_format_RIE_RRP(s390_irgen_BRXHG, ovl.fmt.RIE.r1,
13922 ovl.fmt.RIE.r3, ovl.fmt.RIE.i2);
13923 goto ok;
13924 case 0xec0000000045ULL: s390_format_RIE_RRP(s390_irgen_BRXLG, ovl.fmt.RIE.r1,
13925 ovl.fmt.RIE.r3, ovl.fmt.RIE.i2);
13926 goto ok;
13927 case 0xec0000000051ULL: /* RISBLG */ goto unimplemented;
13928 case 0xec0000000054ULL: s390_format_RIE_RRUUU(s390_irgen_RNSBG,
13929 ovl.fmt.RIE_RRUUU.r1,
13930 ovl.fmt.RIE_RRUUU.r2,
13931 ovl.fmt.RIE_RRUUU.i3,
13932 ovl.fmt.RIE_RRUUU.i4,
13933 ovl.fmt.RIE_RRUUU.i5);
13934 goto ok;
13935 case 0xec0000000055ULL: s390_format_RIE_RRUUU(s390_irgen_RISBG,
13936 ovl.fmt.RIE_RRUUU.r1,
13937 ovl.fmt.RIE_RRUUU.r2,
13938 ovl.fmt.RIE_RRUUU.i3,
13939 ovl.fmt.RIE_RRUUU.i4,
13940 ovl.fmt.RIE_RRUUU.i5);
13941 goto ok;
13942 case 0xec0000000056ULL: s390_format_RIE_RRUUU(s390_irgen_ROSBG,
13943 ovl.fmt.RIE_RRUUU.r1,
13944 ovl.fmt.RIE_RRUUU.r2,
13945 ovl.fmt.RIE_RRUUU.i3,
13946 ovl.fmt.RIE_RRUUU.i4,
13947 ovl.fmt.RIE_RRUUU.i5);
13948 goto ok;
13949 case 0xec0000000057ULL: s390_format_RIE_RRUUU(s390_irgen_RXSBG,
13950 ovl.fmt.RIE_RRUUU.r1,
13951 ovl.fmt.RIE_RRUUU.r2,
13952 ovl.fmt.RIE_RRUUU.i3,
13953 ovl.fmt.RIE_RRUUU.i4,
13954 ovl.fmt.RIE_RRUUU.i5);
13955 goto ok;
13956 case 0xec000000005dULL: /* RISBHG */ goto unimplemented;
13957 case 0xec0000000064ULL: s390_format_RIE_RRPU(s390_irgen_CGRJ,
13958 ovl.fmt.RIE_RRPU.r1,
13959 ovl.fmt.RIE_RRPU.r2,
13960 ovl.fmt.RIE_RRPU.i4,
13961 ovl.fmt.RIE_RRPU.m3); goto ok;
13962 case 0xec0000000065ULL: s390_format_RIE_RRPU(s390_irgen_CLGRJ,
13963 ovl.fmt.RIE_RRPU.r1,
13964 ovl.fmt.RIE_RRPU.r2,
13965 ovl.fmt.RIE_RRPU.i4,
13966 ovl.fmt.RIE_RRPU.m3); goto ok;
13967 case 0xec0000000070ULL: /* CGIT */ goto unimplemented;
13968 case 0xec0000000071ULL: /* CLGIT */ goto unimplemented;
13969 case 0xec0000000072ULL: /* CIT */ goto unimplemented;
13970 case 0xec0000000073ULL: /* CLFIT */ goto unimplemented;
13971 case 0xec0000000076ULL: s390_format_RIE_RRPU(s390_irgen_CRJ,
13972 ovl.fmt.RIE_RRPU.r1,
13973 ovl.fmt.RIE_RRPU.r2,
13974 ovl.fmt.RIE_RRPU.i4,
13975 ovl.fmt.RIE_RRPU.m3); goto ok;
13976 case 0xec0000000077ULL: s390_format_RIE_RRPU(s390_irgen_CLRJ,
13977 ovl.fmt.RIE_RRPU.r1,
13978 ovl.fmt.RIE_RRPU.r2,
13979 ovl.fmt.RIE_RRPU.i4,
13980 ovl.fmt.RIE_RRPU.m3); goto ok;
13981 case 0xec000000007cULL: s390_format_RIE_RUPI(s390_irgen_CGIJ,
13982 ovl.fmt.RIEv3.r1,
13983 ovl.fmt.RIEv3.m3,
13984 ovl.fmt.RIEv3.i4,
13985 ovl.fmt.RIEv3.i2); goto ok;
13986 case 0xec000000007dULL: s390_format_RIE_RUPU(s390_irgen_CLGIJ,
13987 ovl.fmt.RIEv3.r1,
13988 ovl.fmt.RIEv3.m3,
13989 ovl.fmt.RIEv3.i4,
13990 ovl.fmt.RIEv3.i2); goto ok;
13991 case 0xec000000007eULL: s390_format_RIE_RUPI(s390_irgen_CIJ,
13992 ovl.fmt.RIEv3.r1,
13993 ovl.fmt.RIEv3.m3,
13994 ovl.fmt.RIEv3.i4,
13995 ovl.fmt.RIEv3.i2); goto ok;
13996 case 0xec000000007fULL: s390_format_RIE_RUPU(s390_irgen_CLIJ,
13997 ovl.fmt.RIEv3.r1,
13998 ovl.fmt.RIEv3.m3,
13999 ovl.fmt.RIEv3.i4,
14000 ovl.fmt.RIEv3.i2); goto ok;
14001 case 0xec00000000d8ULL: s390_format_RIE_RRI0(s390_irgen_AHIK, ovl.fmt.RIE.r1,
14002 ovl.fmt.RIE.r3, ovl.fmt.RIE.i2);
14003 goto ok;
14004 case 0xec00000000d9ULL: s390_format_RIE_RRI0(s390_irgen_AGHIK,
14005 ovl.fmt.RIE.r1, ovl.fmt.RIE.r3,
14006 ovl.fmt.RIE.i2); goto ok;
14007 case 0xec00000000daULL: s390_format_RIE_RRI0(s390_irgen_ALHSIK,
14008 ovl.fmt.RIE.r1, ovl.fmt.RIE.r3,
14009 ovl.fmt.RIE.i2); goto ok;
14010 case 0xec00000000dbULL: s390_format_RIE_RRI0(s390_irgen_ALGHSIK,
14011 ovl.fmt.RIE.r1, ovl.fmt.RIE.r3,
14012 ovl.fmt.RIE.i2); goto ok;
14013 case 0xec00000000e4ULL: s390_format_RRS(s390_irgen_CGRB, ovl.fmt.RRS.r1,
14014 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
14015 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
14016 goto ok;
14017 case 0xec00000000e5ULL: s390_format_RRS(s390_irgen_CLGRB, ovl.fmt.RRS.r1,
14018 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
14019 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
14020 goto ok;
14021 case 0xec00000000f6ULL: s390_format_RRS(s390_irgen_CRB, ovl.fmt.RRS.r1,
14022 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
14023 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
14024 goto ok;
14025 case 0xec00000000f7ULL: s390_format_RRS(s390_irgen_CLRB, ovl.fmt.RRS.r1,
14026 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
14027 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
14028 goto ok;
14029 case 0xec00000000fcULL: s390_format_RIS_RURDI(s390_irgen_CGIB,
14030 ovl.fmt.RIS.r1, ovl.fmt.RIS.m3,
14031 ovl.fmt.RIS.b4, ovl.fmt.RIS.d4,
14032 ovl.fmt.RIS.i2); goto ok;
14033 case 0xec00000000fdULL: s390_format_RIS_RURDU(s390_irgen_CLGIB,
14034 ovl.fmt.RIS.r1, ovl.fmt.RIS.m3,
14035 ovl.fmt.RIS.b4, ovl.fmt.RIS.d4,
14036 ovl.fmt.RIS.i2); goto ok;
14037 case 0xec00000000feULL: s390_format_RIS_RURDI(s390_irgen_CIB, ovl.fmt.RIS.r1,
14038 ovl.fmt.RIS.m3, ovl.fmt.RIS.b4,
14039 ovl.fmt.RIS.d4,
14040 ovl.fmt.RIS.i2); goto ok;
14041 case 0xec00000000ffULL: s390_format_RIS_RURDU(s390_irgen_CLIB,
14042 ovl.fmt.RIS.r1, ovl.fmt.RIS.m3,
14043 ovl.fmt.RIS.b4, ovl.fmt.RIS.d4,
14044 ovl.fmt.RIS.i2); goto ok;
14045 case 0xed0000000004ULL: s390_format_RXE_FRRD(s390_irgen_LDEB, ovl.fmt.RXE.r1,
14046 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14047 ovl.fmt.RXE.d2); goto ok;
14048 case 0xed0000000005ULL: s390_format_RXE_FRRD(s390_irgen_LXDB, ovl.fmt.RXE.r1,
14049 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14050 ovl.fmt.RXE.d2); goto ok;
14051 case 0xed0000000006ULL: s390_format_RXE_FRRD(s390_irgen_LXEB, ovl.fmt.RXE.r1,
14052 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14053 ovl.fmt.RXE.d2); goto ok;
14054 case 0xed0000000007ULL: /* MXDB */ goto unimplemented;
14055 case 0xed0000000008ULL: /* KEB */ goto unimplemented;
14056 case 0xed0000000009ULL: s390_format_RXE_FRRD(s390_irgen_CEB, ovl.fmt.RXE.r1,
14057 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14058 ovl.fmt.RXE.d2); goto ok;
14059 case 0xed000000000aULL: s390_format_RXE_FRRD(s390_irgen_AEB, ovl.fmt.RXE.r1,
14060 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14061 ovl.fmt.RXE.d2); goto ok;
14062 case 0xed000000000bULL: s390_format_RXE_FRRD(s390_irgen_SEB, ovl.fmt.RXE.r1,
14063 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14064 ovl.fmt.RXE.d2); goto ok;
14065 case 0xed000000000cULL: /* MDEB */ goto unimplemented;
14066 case 0xed000000000dULL: s390_format_RXE_FRRD(s390_irgen_DEB, ovl.fmt.RXE.r1,
14067 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14068 ovl.fmt.RXE.d2); goto ok;
14069 case 0xed000000000eULL: s390_format_RXF_FRRDF(s390_irgen_MAEB,
14070 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
14071 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
14072 ovl.fmt.RXF.r1); goto ok;
14073 case 0xed000000000fULL: s390_format_RXF_FRRDF(s390_irgen_MSEB,
14074 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
14075 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
14076 ovl.fmt.RXF.r1); goto ok;
14077 case 0xed0000000010ULL: s390_format_RXE_FRRD(s390_irgen_TCEB, ovl.fmt.RXE.r1,
14078 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14079 ovl.fmt.RXE.d2); goto ok;
14080 case 0xed0000000011ULL: s390_format_RXE_FRRD(s390_irgen_TCDB, ovl.fmt.RXE.r1,
14081 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14082 ovl.fmt.RXE.d2); goto ok;
14083 case 0xed0000000012ULL: s390_format_RXE_FRRD(s390_irgen_TCXB, ovl.fmt.RXE.r1,
14084 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14085 ovl.fmt.RXE.d2); goto ok;
14086 case 0xed0000000014ULL: s390_format_RXE_FRRD(s390_irgen_SQEB, ovl.fmt.RXE.r1,
14087 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14088 ovl.fmt.RXE.d2); goto ok;
14089 case 0xed0000000015ULL: s390_format_RXE_FRRD(s390_irgen_SQDB, ovl.fmt.RXE.r1,
14090 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14091 ovl.fmt.RXE.d2); goto ok;
14092 case 0xed0000000017ULL: s390_format_RXE_FRRD(s390_irgen_MEEB, ovl.fmt.RXE.r1,
14093 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14094 ovl.fmt.RXE.d2); goto ok;
14095 case 0xed0000000018ULL: /* KDB */ goto unimplemented;
14096 case 0xed0000000019ULL: s390_format_RXE_FRRD(s390_irgen_CDB, ovl.fmt.RXE.r1,
14097 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14098 ovl.fmt.RXE.d2); goto ok;
14099 case 0xed000000001aULL: s390_format_RXE_FRRD(s390_irgen_ADB, ovl.fmt.RXE.r1,
14100 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14101 ovl.fmt.RXE.d2); goto ok;
14102 case 0xed000000001bULL: s390_format_RXE_FRRD(s390_irgen_SDB, ovl.fmt.RXE.r1,
14103 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14104 ovl.fmt.RXE.d2); goto ok;
14105 case 0xed000000001cULL: s390_format_RXE_FRRD(s390_irgen_MDB, ovl.fmt.RXE.r1,
14106 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14107 ovl.fmt.RXE.d2); goto ok;
14108 case 0xed000000001dULL: s390_format_RXE_FRRD(s390_irgen_DDB, ovl.fmt.RXE.r1,
14109 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14110 ovl.fmt.RXE.d2); goto ok;
14111 case 0xed000000001eULL: s390_format_RXF_FRRDF(s390_irgen_MADB,
14112 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
14113 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
14114 ovl.fmt.RXF.r1); goto ok;
14115 case 0xed000000001fULL: s390_format_RXF_FRRDF(s390_irgen_MSDB,
14116 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
14117 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
14118 ovl.fmt.RXF.r1); goto ok;
14119 case 0xed0000000024ULL: /* LDE */ goto unimplemented;
14120 case 0xed0000000025ULL: /* LXD */ goto unimplemented;
14121 case 0xed0000000026ULL: /* LXE */ goto unimplemented;
14122 case 0xed000000002eULL: /* MAE */ goto unimplemented;
14123 case 0xed000000002fULL: /* MSE */ goto unimplemented;
14124 case 0xed0000000034ULL: /* SQE */ goto unimplemented;
14125 case 0xed0000000035ULL: /* SQD */ goto unimplemented;
14126 case 0xed0000000037ULL: /* MEE */ goto unimplemented;
14127 case 0xed0000000038ULL: /* MAYL */ goto unimplemented;
14128 case 0xed0000000039ULL: /* MYL */ goto unimplemented;
14129 case 0xed000000003aULL: /* MAY */ goto unimplemented;
14130 case 0xed000000003bULL: /* MY */ goto unimplemented;
14131 case 0xed000000003cULL: /* MAYH */ goto unimplemented;
14132 case 0xed000000003dULL: /* MYH */ goto unimplemented;
14133 case 0xed000000003eULL: /* MAD */ goto unimplemented;
14134 case 0xed000000003fULL: /* MSD */ goto unimplemented;
14135 case 0xed0000000040ULL: /* SLDT */ goto unimplemented;
14136 case 0xed0000000041ULL: /* SRDT */ goto unimplemented;
14137 case 0xed0000000048ULL: /* SLXT */ goto unimplemented;
14138 case 0xed0000000049ULL: /* SRXT */ goto unimplemented;
14139 case 0xed0000000050ULL: /* TDCET */ goto unimplemented;
14140 case 0xed0000000051ULL: /* TDGET */ goto unimplemented;
14141 case 0xed0000000054ULL: /* TDCDT */ goto unimplemented;
14142 case 0xed0000000055ULL: /* TDGDT */ goto unimplemented;
14143 case 0xed0000000058ULL: /* TDCXT */ goto unimplemented;
14144 case 0xed0000000059ULL: /* TDGXT */ goto unimplemented;
14145 case 0xed0000000064ULL: s390_format_RXY_FRRD(s390_irgen_LEY, ovl.fmt.RXY.r1,
14146 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14147 ovl.fmt.RXY.dl2,
14148 ovl.fmt.RXY.dh2); goto ok;
14149 case 0xed0000000065ULL: s390_format_RXY_FRRD(s390_irgen_LDY, ovl.fmt.RXY.r1,
14150 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14151 ovl.fmt.RXY.dl2,
14152 ovl.fmt.RXY.dh2); goto ok;
14153 case 0xed0000000066ULL: s390_format_RXY_FRRD(s390_irgen_STEY, ovl.fmt.RXY.r1,
14154 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14155 ovl.fmt.RXY.dl2,
14156 ovl.fmt.RXY.dh2); goto ok;
14157 case 0xed0000000067ULL: s390_format_RXY_FRRD(s390_irgen_STDY, ovl.fmt.RXY.r1,
14158 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14159 ovl.fmt.RXY.dl2,
14160 ovl.fmt.RXY.dh2); goto ok;
14161 }
14162
14163 switch (((ovl.value >> 16) & 0xff0f00000000ULL) >> 32) {
14164 case 0xc000ULL: s390_format_RIL_RP(s390_irgen_LARL, ovl.fmt.RIL.r1,
14165 ovl.fmt.RIL.i2); goto ok;
14166 case 0xc001ULL: s390_format_RIL_RI(s390_irgen_LGFI, ovl.fmt.RIL.r1,
14167 ovl.fmt.RIL.i2); goto ok;
14168 case 0xc004ULL: s390_format_RIL(s390_irgen_BRCL, ovl.fmt.RIL.r1,
14169 ovl.fmt.RIL.i2); goto ok;
14170 case 0xc005ULL: s390_format_RIL_RP(s390_irgen_BRASL, ovl.fmt.RIL.r1,
14171 ovl.fmt.RIL.i2); goto ok;
14172 case 0xc006ULL: s390_format_RIL_RU(s390_irgen_XIHF, ovl.fmt.RIL.r1,
14173 ovl.fmt.RIL.i2); goto ok;
14174 case 0xc007ULL: s390_format_RIL_RU(s390_irgen_XILF, ovl.fmt.RIL.r1,
14175 ovl.fmt.RIL.i2); goto ok;
14176 case 0xc008ULL: s390_format_RIL_RU(s390_irgen_IIHF, ovl.fmt.RIL.r1,
14177 ovl.fmt.RIL.i2); goto ok;
14178 case 0xc009ULL: s390_format_RIL_RU(s390_irgen_IILF, ovl.fmt.RIL.r1,
14179 ovl.fmt.RIL.i2); goto ok;
14180 case 0xc00aULL: s390_format_RIL_RU(s390_irgen_NIHF, ovl.fmt.RIL.r1,
14181 ovl.fmt.RIL.i2); goto ok;
14182 case 0xc00bULL: s390_format_RIL_RU(s390_irgen_NILF, ovl.fmt.RIL.r1,
14183 ovl.fmt.RIL.i2); goto ok;
14184 case 0xc00cULL: s390_format_RIL_RU(s390_irgen_OIHF, ovl.fmt.RIL.r1,
14185 ovl.fmt.RIL.i2); goto ok;
14186 case 0xc00dULL: s390_format_RIL_RU(s390_irgen_OILF, ovl.fmt.RIL.r1,
14187 ovl.fmt.RIL.i2); goto ok;
14188 case 0xc00eULL: s390_format_RIL_RU(s390_irgen_LLIHF, ovl.fmt.RIL.r1,
14189 ovl.fmt.RIL.i2); goto ok;
14190 case 0xc00fULL: s390_format_RIL_RU(s390_irgen_LLILF, ovl.fmt.RIL.r1,
14191 ovl.fmt.RIL.i2); goto ok;
14192 case 0xc200ULL: s390_format_RIL_RI(s390_irgen_MSGFI, ovl.fmt.RIL.r1,
14193 ovl.fmt.RIL.i2); goto ok;
14194 case 0xc201ULL: s390_format_RIL_RI(s390_irgen_MSFI, ovl.fmt.RIL.r1,
14195 ovl.fmt.RIL.i2); goto ok;
14196 case 0xc204ULL: s390_format_RIL_RU(s390_irgen_SLGFI, ovl.fmt.RIL.r1,
14197 ovl.fmt.RIL.i2); goto ok;
14198 case 0xc205ULL: s390_format_RIL_RU(s390_irgen_SLFI, ovl.fmt.RIL.r1,
14199 ovl.fmt.RIL.i2); goto ok;
14200 case 0xc208ULL: s390_format_RIL_RI(s390_irgen_AGFI, ovl.fmt.RIL.r1,
14201 ovl.fmt.RIL.i2); goto ok;
14202 case 0xc209ULL: s390_format_RIL_RI(s390_irgen_AFI, ovl.fmt.RIL.r1,
14203 ovl.fmt.RIL.i2); goto ok;
14204 case 0xc20aULL: s390_format_RIL_RU(s390_irgen_ALGFI, ovl.fmt.RIL.r1,
14205 ovl.fmt.RIL.i2); goto ok;
14206 case 0xc20bULL: s390_format_RIL_RU(s390_irgen_ALFI, ovl.fmt.RIL.r1,
14207 ovl.fmt.RIL.i2); goto ok;
14208 case 0xc20cULL: s390_format_RIL_RI(s390_irgen_CGFI, ovl.fmt.RIL.r1,
14209 ovl.fmt.RIL.i2); goto ok;
14210 case 0xc20dULL: s390_format_RIL_RI(s390_irgen_CFI, ovl.fmt.RIL.r1,
14211 ovl.fmt.RIL.i2); goto ok;
14212 case 0xc20eULL: s390_format_RIL_RU(s390_irgen_CLGFI, ovl.fmt.RIL.r1,
14213 ovl.fmt.RIL.i2); goto ok;
14214 case 0xc20fULL: s390_format_RIL_RU(s390_irgen_CLFI, ovl.fmt.RIL.r1,
14215 ovl.fmt.RIL.i2); goto ok;
14216 case 0xc402ULL: s390_format_RIL_RP(s390_irgen_LLHRL, ovl.fmt.RIL.r1,
14217 ovl.fmt.RIL.i2); goto ok;
14218 case 0xc404ULL: s390_format_RIL_RP(s390_irgen_LGHRL, ovl.fmt.RIL.r1,
14219 ovl.fmt.RIL.i2); goto ok;
14220 case 0xc405ULL: s390_format_RIL_RP(s390_irgen_LHRL, ovl.fmt.RIL.r1,
14221 ovl.fmt.RIL.i2); goto ok;
14222 case 0xc406ULL: s390_format_RIL_RP(s390_irgen_LLGHRL, ovl.fmt.RIL.r1,
14223 ovl.fmt.RIL.i2); goto ok;
14224 case 0xc407ULL: s390_format_RIL_RP(s390_irgen_STHRL, ovl.fmt.RIL.r1,
14225 ovl.fmt.RIL.i2); goto ok;
14226 case 0xc408ULL: s390_format_RIL_RP(s390_irgen_LGRL, ovl.fmt.RIL.r1,
14227 ovl.fmt.RIL.i2); goto ok;
14228 case 0xc40bULL: s390_format_RIL_RP(s390_irgen_STGRL, ovl.fmt.RIL.r1,
14229 ovl.fmt.RIL.i2); goto ok;
14230 case 0xc40cULL: s390_format_RIL_RP(s390_irgen_LGFRL, ovl.fmt.RIL.r1,
14231 ovl.fmt.RIL.i2); goto ok;
14232 case 0xc40dULL: s390_format_RIL_RP(s390_irgen_LRL, ovl.fmt.RIL.r1,
14233 ovl.fmt.RIL.i2); goto ok;
14234 case 0xc40eULL: s390_format_RIL_RP(s390_irgen_LLGFRL, ovl.fmt.RIL.r1,
14235 ovl.fmt.RIL.i2); goto ok;
14236 case 0xc40fULL: s390_format_RIL_RP(s390_irgen_STRL, ovl.fmt.RIL.r1,
14237 ovl.fmt.RIL.i2); goto ok;
14238 case 0xc600ULL: s390_format_RIL_RP(s390_irgen_EXRL, ovl.fmt.RIL.r1,
14239 ovl.fmt.RIL.i2); goto ok;
14240 case 0xc602ULL: s390_format_RIL_UP(s390_irgen_PFDRL, ovl.fmt.RIL.r1,
14241 ovl.fmt.RIL.i2); goto ok;
14242 case 0xc604ULL: s390_format_RIL_RP(s390_irgen_CGHRL, ovl.fmt.RIL.r1,
14243 ovl.fmt.RIL.i2); goto ok;
14244 case 0xc605ULL: s390_format_RIL_RP(s390_irgen_CHRL, ovl.fmt.RIL.r1,
14245 ovl.fmt.RIL.i2); goto ok;
14246 case 0xc606ULL: s390_format_RIL_RP(s390_irgen_CLGHRL, ovl.fmt.RIL.r1,
14247 ovl.fmt.RIL.i2); goto ok;
14248 case 0xc607ULL: s390_format_RIL_RP(s390_irgen_CLHRL, ovl.fmt.RIL.r1,
14249 ovl.fmt.RIL.i2); goto ok;
14250 case 0xc608ULL: s390_format_RIL_RP(s390_irgen_CGRL, ovl.fmt.RIL.r1,
14251 ovl.fmt.RIL.i2); goto ok;
14252 case 0xc60aULL: s390_format_RIL_RP(s390_irgen_CLGRL, ovl.fmt.RIL.r1,
14253 ovl.fmt.RIL.i2); goto ok;
14254 case 0xc60cULL: s390_format_RIL_RP(s390_irgen_CGFRL, ovl.fmt.RIL.r1,
14255 ovl.fmt.RIL.i2); goto ok;
14256 case 0xc60dULL: s390_format_RIL_RP(s390_irgen_CRL, ovl.fmt.RIL.r1,
14257 ovl.fmt.RIL.i2); goto ok;
14258 case 0xc60eULL: s390_format_RIL_RP(s390_irgen_CLGFRL, ovl.fmt.RIL.r1,
14259 ovl.fmt.RIL.i2); goto ok;
14260 case 0xc60fULL: s390_format_RIL_RP(s390_irgen_CLRL, ovl.fmt.RIL.r1,
14261 ovl.fmt.RIL.i2); goto ok;
14262 case 0xc800ULL: /* MVCOS */ goto unimplemented;
14263 case 0xc801ULL: /* ECTG */ goto unimplemented;
14264 case 0xc802ULL: /* CSST */ goto unimplemented;
14265 case 0xc804ULL: /* LPD */ goto unimplemented;
14266 case 0xc805ULL: /* LPDG */ goto unimplemented;
14267 case 0xcc06ULL: /* BRCTH */ goto unimplemented;
14268 case 0xcc08ULL: s390_format_RIL_RI(s390_irgen_AIH, ovl.fmt.RIL.r1,
14269 ovl.fmt.RIL.i2); goto ok;
14270 case 0xcc0aULL: s390_format_RIL_RI(s390_irgen_ALSIH, ovl.fmt.RIL.r1,
14271 ovl.fmt.RIL.i2); goto ok;
14272 case 0xcc0bULL: s390_format_RIL_RI(s390_irgen_ALSIHN, ovl.fmt.RIL.r1,
14273 ovl.fmt.RIL.i2); goto ok;
14274 case 0xcc0dULL: s390_format_RIL_RI(s390_irgen_CIH, ovl.fmt.RIL.r1,
14275 ovl.fmt.RIL.i2); goto ok;
14276 case 0xcc0fULL: s390_format_RIL_RU(s390_irgen_CLIH, ovl.fmt.RIL.r1,
14277 ovl.fmt.RIL.i2); goto ok;
14278 }
14279
14280 switch (((ovl.value >> 16) & 0xff0000000000ULL) >> 40) {
14281 case 0xd0ULL: /* TRTR */ goto unimplemented;
14282 case 0xd1ULL: /* MVN */ goto unimplemented;
14283 case 0xd2ULL: s390_format_SS_L0RDRD(s390_irgen_MVC, ovl.fmt.SS.l,
14284 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
14285 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
14286 case 0xd3ULL: /* MVZ */ goto unimplemented;
14287 case 0xd4ULL: s390_format_SS_L0RDRD(s390_irgen_NC, ovl.fmt.SS.l,
14288 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
14289 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
14290 case 0xd5ULL: s390_format_SS_L0RDRD(s390_irgen_CLC, ovl.fmt.SS.l,
14291 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
14292 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
14293 case 0xd6ULL: s390_format_SS_L0RDRD(s390_irgen_OC, ovl.fmt.SS.l,
14294 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
14295 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
sewardjb63967e2011-03-24 08:50:04 +000014296 case 0xd7ULL:
14297 if (ovl.fmt.SS.b1 == ovl.fmt.SS.b2 && ovl.fmt.SS.d1 == ovl.fmt.SS.d2)
14298 s390_irgen_XC_sameloc(ovl.fmt.SS.l, ovl.fmt.SS.b1, ovl.fmt.SS.d1);
14299 else
14300 s390_format_SS_L0RDRD(s390_irgen_XC, ovl.fmt.SS.l,
14301 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
14302 ovl.fmt.SS.b2, ovl.fmt.SS.d2);
14303 goto ok;
sewardj2019a972011-03-07 16:04:07 +000014304 case 0xd9ULL: /* MVCK */ goto unimplemented;
14305 case 0xdaULL: /* MVCP */ goto unimplemented;
14306 case 0xdbULL: /* MVCS */ goto unimplemented;
florian730448f2012-02-04 17:07:07 +000014307 case 0xdcULL: s390_format_SS_L0RDRD(s390_irgen_TR, ovl.fmt.SS.l,
14308 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
14309 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014310 case 0xddULL: /* TRT */ goto unimplemented;
14311 case 0xdeULL: /* ED */ goto unimplemented;
14312 case 0xdfULL: /* EDMK */ goto unimplemented;
14313 case 0xe1ULL: /* PKU */ goto unimplemented;
14314 case 0xe2ULL: /* UNPKU */ goto unimplemented;
14315 case 0xe8ULL: /* MVCIN */ goto unimplemented;
14316 case 0xe9ULL: /* PKA */ goto unimplemented;
14317 case 0xeaULL: /* UNPKA */ goto unimplemented;
14318 case 0xeeULL: /* PLO */ goto unimplemented;
14319 case 0xefULL: /* LMD */ goto unimplemented;
14320 case 0xf0ULL: /* SRP */ goto unimplemented;
14321 case 0xf1ULL: /* MVO */ goto unimplemented;
14322 case 0xf2ULL: /* PACK */ goto unimplemented;
14323 case 0xf3ULL: /* UNPK */ goto unimplemented;
14324 case 0xf8ULL: /* ZAP */ goto unimplemented;
14325 case 0xf9ULL: /* CP */ goto unimplemented;
14326 case 0xfaULL: /* AP */ goto unimplemented;
14327 case 0xfbULL: /* SP */ goto unimplemented;
14328 case 0xfcULL: /* MP */ goto unimplemented;
14329 case 0xfdULL: /* DP */ goto unimplemented;
14330 }
14331
14332 switch (((ovl.value >> 16) & 0xffff00000000ULL) >> 32) {
14333 case 0xe500ULL: /* LASP */ goto unimplemented;
14334 case 0xe501ULL: /* TPROT */ goto unimplemented;
14335 case 0xe502ULL: /* STRAG */ goto unimplemented;
14336 case 0xe50eULL: /* MVCSK */ goto unimplemented;
14337 case 0xe50fULL: /* MVCDK */ goto unimplemented;
14338 case 0xe544ULL: s390_format_SIL_RDI(s390_irgen_MVHHI, ovl.fmt.SIL.b1,
14339 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14340 goto ok;
14341 case 0xe548ULL: s390_format_SIL_RDI(s390_irgen_MVGHI, ovl.fmt.SIL.b1,
14342 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14343 goto ok;
14344 case 0xe54cULL: s390_format_SIL_RDI(s390_irgen_MVHI, ovl.fmt.SIL.b1,
14345 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14346 goto ok;
14347 case 0xe554ULL: s390_format_SIL_RDI(s390_irgen_CHHSI, ovl.fmt.SIL.b1,
14348 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14349 goto ok;
14350 case 0xe555ULL: s390_format_SIL_RDU(s390_irgen_CLHHSI, ovl.fmt.SIL.b1,
14351 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14352 goto ok;
14353 case 0xe558ULL: s390_format_SIL_RDI(s390_irgen_CGHSI, ovl.fmt.SIL.b1,
14354 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14355 goto ok;
14356 case 0xe559ULL: s390_format_SIL_RDU(s390_irgen_CLGHSI, ovl.fmt.SIL.b1,
14357 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14358 goto ok;
14359 case 0xe55cULL: s390_format_SIL_RDI(s390_irgen_CHSI, ovl.fmt.SIL.b1,
14360 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14361 goto ok;
14362 case 0xe55dULL: s390_format_SIL_RDU(s390_irgen_CLFHSI, ovl.fmt.SIL.b1,
14363 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14364 goto ok;
14365 }
14366
14367 return S390_DECODE_UNKNOWN_INSN;
14368
14369ok:
14370 return S390_DECODE_OK;
14371
14372unimplemented:
14373 return S390_DECODE_UNIMPLEMENTED_INSN;
14374}
14375
14376/* Handle "special" instructions. */
14377static s390_decode_t
14378s390_decode_special_and_irgen(UChar *bytes)
14379{
14380 s390_decode_t status = S390_DECODE_OK;
14381
14382 /* Got a "Special" instruction preamble. Which one is it? */
14383 if (bytes[0] == 0x18 && bytes[1] == 0x22 /* lr %r2, %r2 */) {
14384 s390_irgen_client_request();
14385 } else if (bytes[0] == 0x18 && bytes[1] == 0x33 /* lr %r3, %r3 */) {
14386 s390_irgen_guest_NRADDR();
14387 } else if (bytes[0] == 0x18 && bytes[1] == 0x44 /* lr %r4, %r4 */) {
14388 s390_irgen_call_noredir();
florian2245ce92012-08-28 16:49:30 +000014389 } else if (bytes[0] == 0x18 && bytes[1] == 0x55 /* lr %r5, %r5 */) {
14390 vex_inject_ir(irsb, Iend_BE);
14391
14392 /* Invalidate the current insn. The reason is that the IRop we're
14393 injecting here can change. In which case the translation has to
14394 be redone. For ease of handling, we simply invalidate all the
14395 time. */
14396 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TISTART),
14397 mkU64(guest_IA_curr_instr)));
14398 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TILEN),
14399 mkU64(guest_IA_next_instr - guest_IA_curr_instr)));
14400 vassert(guest_IA_next_instr - guest_IA_curr_instr ==
14401 S390_SPECIAL_OP_PREAMBLE_SIZE + S390_SPECIAL_OP_SIZE);
14402
14403 put_IA(mkaddr_expr(guest_IA_next_instr));
14404 dis_res->whatNext = Dis_StopHere;
14405 dis_res->jk_StopHere = Ijk_TInval;
sewardj2019a972011-03-07 16:04:07 +000014406 } else {
14407 /* We don't know what it is. */
14408 return S390_DECODE_UNKNOWN_SPECIAL_INSN;
14409 }
14410
14411 dis_res->len = S390_SPECIAL_OP_PREAMBLE_SIZE + S390_SPECIAL_OP_SIZE;
14412
14413 return status;
14414}
14415
14416
14417/* Function returns # bytes that were decoded or 0 in case of failure */
florianb4df7682011-07-05 02:09:01 +000014418static UInt
sewardj2019a972011-03-07 16:04:07 +000014419s390_decode_and_irgen(UChar *bytes, UInt insn_length, DisResult *dres)
14420{
14421 s390_decode_t status;
14422
14423 dis_res = dres;
14424
14425 /* Spot the 8-byte preamble: 18ff lr r15,r15
14426 1811 lr r1,r1
14427 1822 lr r2,r2
14428 1833 lr r3,r3 */
14429 if (bytes[ 0] == 0x18 && bytes[ 1] == 0xff && bytes[ 2] == 0x18 &&
14430 bytes[ 3] == 0x11 && bytes[ 4] == 0x18 && bytes[ 5] == 0x22 &&
14431 bytes[ 6] == 0x18 && bytes[ 7] == 0x33) {
14432
14433 /* Handle special instruction that follows that preamble. */
14434 if (0) vex_printf("special function handling...\n");
florian2c8ed942011-08-01 22:07:51 +000014435
14436 insn_length = S390_SPECIAL_OP_PREAMBLE_SIZE + S390_SPECIAL_OP_SIZE;
14437 guest_IA_next_instr = guest_IA_curr_instr + insn_length;
14438
14439 status =
14440 s390_decode_special_and_irgen(bytes + S390_SPECIAL_OP_PREAMBLE_SIZE);
sewardj2019a972011-03-07 16:04:07 +000014441 } else {
14442 /* Handle normal instructions. */
14443 switch (insn_length) {
14444 case 2:
14445 status = s390_decode_2byte_and_irgen(bytes);
14446 break;
14447
14448 case 4:
14449 status = s390_decode_4byte_and_irgen(bytes);
14450 break;
14451
14452 case 6:
14453 status = s390_decode_6byte_and_irgen(bytes);
14454 break;
14455
14456 default:
14457 status = S390_DECODE_ERROR;
14458 break;
14459 }
14460 }
florian5fcbba22011-07-27 20:40:22 +000014461 /* If next instruction is execute, stop here */
florianf9e1ed72012-04-17 02:41:56 +000014462 if (dis_res->whatNext == Dis_Continue && bytes[insn_length] == 0x44) {
14463 put_IA(mkaddr_expr(guest_IA_next_instr));
sewardj2019a972011-03-07 16:04:07 +000014464 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +000014465 dis_res->jk_StopHere = Ijk_Boring;
sewardj2019a972011-03-07 16:04:07 +000014466 }
14467
14468 if (status == S390_DECODE_OK) return insn_length; /* OK */
14469
14470 /* Decoding failed somehow */
14471 vex_printf("vex s390->IR: ");
14472 switch (status) {
14473 case S390_DECODE_UNKNOWN_INSN:
14474 vex_printf("unknown insn: ");
14475 break;
14476
14477 case S390_DECODE_UNIMPLEMENTED_INSN:
14478 vex_printf("unimplemented insn: ");
14479 break;
14480
14481 case S390_DECODE_UNKNOWN_SPECIAL_INSN:
14482 vex_printf("unimplemented special insn: ");
14483 break;
14484
14485 default:
14486 case S390_DECODE_ERROR:
14487 vex_printf("decoding error: ");
14488 break;
14489 }
14490
14491 vex_printf("%02x%02x", bytes[0], bytes[1]);
14492 if (insn_length > 2) {
14493 vex_printf(" %02x%02x", bytes[2], bytes[3]);
14494 }
14495 if (insn_length > 4) {
14496 vex_printf(" %02x%02x", bytes[4], bytes[5]);
14497 }
14498 vex_printf("\n");
14499
14500 return 0; /* Failed */
14501}
14502
14503
sewardj2019a972011-03-07 16:04:07 +000014504/* Disassemble a single instruction INSN into IR. */
14505static DisResult
florian420c5012011-07-22 02:12:28 +000014506disInstr_S390_WRK(UChar *insn)
sewardj2019a972011-03-07 16:04:07 +000014507{
14508 UChar byte;
14509 UInt insn_length;
14510 DisResult dres;
14511
14512 /* ---------------------------------------------------- */
14513 /* --- Compute instruction length -- */
14514 /* ---------------------------------------------------- */
14515
14516 /* Get the first byte of the insn. */
14517 byte = insn[0];
14518
14519 /* The leftmost two bits (0:1) encode the length of the insn in bytes.
14520 00 -> 2 bytes, 01 -> 4 bytes, 10 -> 4 bytes, 11 -> 6 bytes. */
14521 insn_length = ((((byte >> 6) + 1) >> 1) + 1) << 1;
14522
14523 guest_IA_next_instr = guest_IA_curr_instr + insn_length;
14524
14525 /* ---------------------------------------------------- */
14526 /* --- Initialise the DisResult data -- */
14527 /* ---------------------------------------------------- */
14528 dres.whatNext = Dis_Continue;
14529 dres.len = insn_length;
14530 dres.continueAt = 0;
florian8844a632012-04-13 04:04:06 +000014531 dres.jk_StopHere = Ijk_INVALID;
sewardj2019a972011-03-07 16:04:07 +000014532
floriana99f20e2011-07-17 14:16:41 +000014533 /* fixs390: consider chasing of conditional jumps */
14534
sewardj2019a972011-03-07 16:04:07 +000014535 /* Normal and special instruction handling starts here. */
14536 if (s390_decode_and_irgen(insn, insn_length, &dres) == 0) {
14537 /* All decode failures end up here. The decoder has already issued an
14538 error message.
14539 Tell the dispatcher that this insn cannot be decoded, and so has
florian342e01a2012-07-26 02:37:49 +000014540 not been executed, and (is currently) the next to be executed.
14541 The insn address in the guest state needs to be set to
14542 guest_IA_curr_instr, otherwise the complaint will report an
14543 incorrect address. */
14544 put_IA(mkaddr_expr(guest_IA_curr_instr));
sewardj2019a972011-03-07 16:04:07 +000014545
florian8844a632012-04-13 04:04:06 +000014546 dres.whatNext = Dis_StopHere;
14547 dres.jk_StopHere = Ijk_NoDecode;
14548 dres.continueAt = 0;
14549 dres.len = 0;
14550 } else {
14551 /* Decode success */
14552 switch (dres.whatNext) {
14553 case Dis_Continue:
florian8559e412012-04-19 14:23:48 +000014554 put_IA(mkaddr_expr(guest_IA_next_instr));
florian8844a632012-04-13 04:04:06 +000014555 break;
14556 case Dis_ResteerU:
14557 case Dis_ResteerC:
14558 put_IA(mkaddr_expr(dres.continueAt));
14559 break;
14560 case Dis_StopHere:
14561 break;
14562 default:
14563 vassert(0);
14564 }
sewardj2019a972011-03-07 16:04:07 +000014565 }
14566
14567 return dres;
14568}
14569
14570
14571/*------------------------------------------------------------*/
14572/*--- Top-level fn ---*/
14573/*------------------------------------------------------------*/
14574
14575/* Disassemble a single instruction into IR. The instruction
14576 is located in host memory at &guest_code[delta]. */
14577
14578DisResult
14579disInstr_S390(IRSB *irsb_IN,
sewardj2019a972011-03-07 16:04:07 +000014580 Bool (*resteerOkFn)(void *, Addr64),
14581 Bool resteerCisOk,
14582 void *callback_opaque,
14583 UChar *guest_code,
14584 Long delta,
14585 Addr64 guest_IP,
14586 VexArch guest_arch,
14587 VexArchInfo *archinfo,
14588 VexAbiInfo *abiinfo,
14589 Bool host_bigendian)
14590{
14591 vassert(guest_arch == VexArchS390X);
14592
14593 /* The instruction decoder requires a big-endian machine. */
14594 vassert(host_bigendian == True);
14595
14596 /* Set globals (see top of this file) */
14597 guest_IA_curr_instr = guest_IP;
sewardj2019a972011-03-07 16:04:07 +000014598 irsb = irsb_IN;
florian420c5012011-07-22 02:12:28 +000014599 resteer_fn = resteerOkFn;
14600 resteer_data = callback_opaque;
sewardj2019a972011-03-07 16:04:07 +000014601
florian420c5012011-07-22 02:12:28 +000014602 return disInstr_S390_WRK(guest_code + delta);
sewardj2019a972011-03-07 16:04:07 +000014603}
14604
14605/*---------------------------------------------------------------*/
14606/*--- end guest_s390_toIR.c ---*/
14607/*---------------------------------------------------------------*/