blob: 3bc34a781ac0cc4f47cdb81059238933931a6d73 [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
11 Copyright IBM Corp. 2010-2011
12
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
467
sewardj2019a972011-03-07 16:04:07 +0000468/*------------------------------------------------------------*/
florianf3410f92012-08-03 18:41:58 +0000469/*--- IR Debugging aids. ---*/
470/*------------------------------------------------------------*/
471#if 0
472
473static ULong
474s390_do_print(HChar *text, ULong value)
475{
476 vex_printf("%s %llu\n", text, value);
477 return 0;
478}
479
480static void
481s390_print(HChar *text, IRExpr *value)
482{
483 IRDirty *d;
484
485 d = unsafeIRDirty_0_N(0 /* regparms */, "s390_do_print", &s390_do_print,
486 mkIRExprVec_2(mkU64((ULong)text), value));
487 stmt(IRStmt_Dirty(d));
488}
489#endif
490
491
492/*------------------------------------------------------------*/
sewardj2019a972011-03-07 16:04:07 +0000493/*--- Build the flags thunk. ---*/
494/*------------------------------------------------------------*/
495
496/* Completely fill the flags thunk. We're always filling all fields.
497 Apparently, that is better for redundant PUT elimination. */
498static void
499s390_cc_thunk_fill(IRExpr *op, IRExpr *dep1, IRExpr *dep2, IRExpr *ndep)
500{
501 UInt op_off, dep1_off, dep2_off, ndep_off;
502
florian428dfdd2012-03-27 03:09:49 +0000503 op_off = S390X_GUEST_OFFSET(guest_CC_OP);
504 dep1_off = S390X_GUEST_OFFSET(guest_CC_DEP1);
505 dep2_off = S390X_GUEST_OFFSET(guest_CC_DEP2);
506 ndep_off = S390X_GUEST_OFFSET(guest_CC_NDEP);
sewardj2019a972011-03-07 16:04:07 +0000507
508 stmt(IRStmt_Put(op_off, op));
509 stmt(IRStmt_Put(dep1_off, dep1));
510 stmt(IRStmt_Put(dep2_off, dep2));
511 stmt(IRStmt_Put(ndep_off, ndep));
512}
513
514
515/* Create an expression for V and widen the result to 64 bit. */
516static IRExpr *
517s390_cc_widen(IRTemp v, Bool sign_extend)
518{
519 IRExpr *expr;
520
521 expr = mkexpr(v);
522
523 switch (typeOfIRTemp(irsb->tyenv, v)) {
524 case Ity_I64:
525 break;
526 case Ity_I32:
527 expr = unop(sign_extend ? Iop_32Sto64 : Iop_32Uto64, expr);
528 break;
529 case Ity_I16:
530 expr = unop(sign_extend ? Iop_16Sto64 : Iop_16Uto64, expr);
531 break;
532 case Ity_I8:
533 expr = unop(sign_extend ? Iop_8Sto64 : Iop_8Uto64, expr);
534 break;
535 default:
536 vpanic("s390_cc_widen");
537 }
538
539 return expr;
540}
541
542static void
543s390_cc_thunk_put1(UInt opc, IRTemp d1, Bool sign_extend)
544{
545 IRExpr *op, *dep1, *dep2, *ndep;
546
547 op = mkU64(opc);
548 dep1 = s390_cc_widen(d1, sign_extend);
549 dep2 = mkU64(0);
550 ndep = mkU64(0);
551
552 s390_cc_thunk_fill(op, dep1, dep2, ndep);
553}
554
555
556static void
557s390_cc_thunk_put2(UInt opc, IRTemp d1, IRTemp d2, Bool sign_extend)
558{
559 IRExpr *op, *dep1, *dep2, *ndep;
560
561 op = mkU64(opc);
562 dep1 = s390_cc_widen(d1, sign_extend);
563 dep2 = s390_cc_widen(d2, sign_extend);
564 ndep = mkU64(0);
565
566 s390_cc_thunk_fill(op, dep1, dep2, ndep);
567}
568
569
570/* memcheck believes that the NDEP field in the flags thunk is always
571 defined. But for some flag computations (e.g. add with carry) that is
572 just not true. We therefore need to convey to memcheck that the value
573 of the ndep field does matter and therefore we make the DEP2 field
574 depend on it:
575
576 DEP2 = original_DEP2 ^ NDEP
577
578 In s390_calculate_cc we exploit that (a^b)^b == a
579 I.e. we xor the DEP2 value with the NDEP value to recover the
580 original_DEP2 value. */
581static void
582s390_cc_thunk_put3(UInt opc, IRTemp d1, IRTemp d2, IRTemp nd, Bool sign_extend)
583{
584 IRExpr *op, *dep1, *dep2, *ndep, *dep2x;
585
586 op = mkU64(opc);
587 dep1 = s390_cc_widen(d1, sign_extend);
588 dep2 = s390_cc_widen(d2, sign_extend);
589 ndep = s390_cc_widen(nd, sign_extend);
590
591 dep2x = binop(Iop_Xor64, dep2, ndep);
592
593 s390_cc_thunk_fill(op, dep1, dep2x, ndep);
594}
595
596
597/* Write one floating point value into the flags thunk */
598static void
599s390_cc_thunk_put1f(UInt opc, IRTemp d1)
600{
601 IRExpr *op, *dep1, *dep2, *ndep;
602
603 op = mkU64(opc);
604 dep1 = mkexpr(d1);
605 dep2 = mkU64(0);
606 ndep = mkU64(0);
607
608 s390_cc_thunk_fill(op, dep1, dep2, ndep);
609}
610
611
612/* Write a floating point value and an integer into the flags thunk. The
613 integer value is zero-extended first. */
614static void
615s390_cc_thunk_putFZ(UInt opc, IRTemp d1, IRTemp d2)
616{
617 IRExpr *op, *dep1, *dep2, *ndep;
618
619 op = mkU64(opc);
620 dep1 = mkexpr(d1);
621 dep2 = s390_cc_widen(d2, False);
622 ndep = mkU64(0);
623
624 s390_cc_thunk_fill(op, dep1, dep2, ndep);
625}
626
627
628/* Write a 128-bit floating point value into the flags thunk. This is
629 done by splitting the value into two 64-bits values. */
630static void
631s390_cc_thunk_put1f128(UInt opc, IRTemp d1)
632{
633 IRExpr *op, *hi, *lo, *ndep;
634
635 op = mkU64(opc);
636 hi = unop(Iop_F128HItoF64, mkexpr(d1));
637 lo = unop(Iop_F128LOtoF64, mkexpr(d1));
638 ndep = mkU64(0);
639
640 s390_cc_thunk_fill(op, hi, lo, ndep);
641}
642
643
644/* Write a 128-bit floating point value and an integer into the flags thunk.
645 The integer value is zero-extended first. */
646static void
647s390_cc_thunk_put1f128Z(UInt opc, IRTemp d1, IRTemp nd)
648{
649 IRExpr *op, *hi, *lo, *lox, *ndep;
650
651 op = mkU64(opc);
652 hi = unop(Iop_F128HItoF64, mkexpr(d1));
653 lo = unop(Iop_ReinterpF64asI64, unop(Iop_F128LOtoF64, mkexpr(d1)));
654 ndep = s390_cc_widen(nd, False);
655
656 lox = binop(Iop_Xor64, lo, ndep); /* convey dependency */
657
658 s390_cc_thunk_fill(op, hi, lox, ndep);
659}
660
661
662static void
663s390_cc_set(UInt val)
664{
665 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
666 mkU64(val), mkU64(0), mkU64(0));
667}
668
669/* Build IR to calculate the condition code from flags thunk.
670 Returns an expression of type Ity_I32 */
671static IRExpr *
672s390_call_calculate_cc(void)
673{
674 IRExpr **args, *call, *op, *dep1, *dep2, *ndep;
675
florian428dfdd2012-03-27 03:09:49 +0000676 op = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_OP), Ity_I64);
677 dep1 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP1), Ity_I64);
678 dep2 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP2), Ity_I64);
679 ndep = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_NDEP), Ity_I64);
sewardj2019a972011-03-07 16:04:07 +0000680
681 args = mkIRExprVec_4(op, dep1, dep2, ndep);
682 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
683 "s390_calculate_cc", &s390_calculate_cc, args);
684
685 /* Exclude OP and NDEP from definedness checking. We're only
686 interested in DEP1 and DEP2. */
687 call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<3);
688
689 return call;
690}
691
692/* Build IR to calculate the internal condition code for a "compare and branch"
693 insn. Returns an expression of type Ity_I32 */
694static IRExpr *
florianff9613f2012-05-12 15:26:44 +0000695s390_call_calculate_icc(UInt m, UInt opc, IRTemp op1, IRTemp op2)
sewardj2019a972011-03-07 16:04:07 +0000696{
florianff9613f2012-05-12 15:26:44 +0000697 IRExpr **args, *call, *op, *dep1, *dep2, *mask;
sewardj2019a972011-03-07 16:04:07 +0000698
florianff9613f2012-05-12 15:26:44 +0000699 switch (opc) {
700 case S390_CC_OP_SIGNED_COMPARE:
701 dep1 = s390_cc_widen(op1, True);
702 dep2 = s390_cc_widen(op2, True);
703 break;
704
705 case S390_CC_OP_UNSIGNED_COMPARE:
706 dep1 = s390_cc_widen(op1, False);
707 dep2 = s390_cc_widen(op2, False);
708 break;
709
710 default:
711 vpanic("s390_call_calculate_icc");
712 }
713
714 mask = mkU64(m);
sewardj2019a972011-03-07 16:04:07 +0000715 op = mkU64(opc);
sewardj2019a972011-03-07 16:04:07 +0000716
florianff9613f2012-05-12 15:26:44 +0000717 args = mkIRExprVec_5(mask, op, dep1, dep2, mkU64(0) /* unused */);
sewardj2019a972011-03-07 16:04:07 +0000718 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
florianff9613f2012-05-12 15:26:44 +0000719 "s390_calculate_cond", &s390_calculate_cond, args);
sewardj2019a972011-03-07 16:04:07 +0000720
florianff9613f2012-05-12 15:26:44 +0000721 /* Exclude the requested condition, OP and NDEP from definedness
722 checking. We're only interested in DEP1 and DEP2. */
723 call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<1) | (1<<4);
sewardj2019a972011-03-07 16:04:07 +0000724
725 return call;
726}
727
728/* Build IR to calculate the condition code from flags thunk.
729 Returns an expression of type Ity_I32 */
730static IRExpr *
731s390_call_calculate_cond(UInt m)
732{
733 IRExpr **args, *call, *op, *dep1, *dep2, *ndep, *mask;
734
735 mask = mkU64(m);
florian428dfdd2012-03-27 03:09:49 +0000736 op = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_OP), Ity_I64);
737 dep1 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP1), Ity_I64);
738 dep2 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP2), Ity_I64);
739 ndep = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_NDEP), Ity_I64);
sewardj2019a972011-03-07 16:04:07 +0000740
741 args = mkIRExprVec_5(mask, op, dep1, dep2, ndep);
742 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
743 "s390_calculate_cond", &s390_calculate_cond, args);
744
745 /* Exclude the requested condition, OP and NDEP from definedness
746 checking. We're only interested in DEP1 and DEP2. */
747 call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<1) | (1<<4);
748
749 return call;
750}
751
752#define s390_cc_thunk_putZ(op,dep1) s390_cc_thunk_put1(op,dep1,False)
753#define s390_cc_thunk_putS(op,dep1) s390_cc_thunk_put1(op,dep1,True)
754#define s390_cc_thunk_putF(op,dep1) s390_cc_thunk_put1f(op,dep1)
755#define s390_cc_thunk_putZZ(op,dep1,dep2) s390_cc_thunk_put2(op,dep1,dep2,False)
756#define s390_cc_thunk_putSS(op,dep1,dep2) s390_cc_thunk_put2(op,dep1,dep2,True)
757#define s390_cc_thunk_putFF(op,dep1,dep2) s390_cc_thunk_put2f(op,dep1,dep2)
758#define s390_cc_thunk_putZZZ(op,dep1,dep2,ndep) \
759 s390_cc_thunk_put3(op,dep1,dep2,ndep,False)
760#define s390_cc_thunk_putSSS(op,dep1,dep2,ndep) \
761 s390_cc_thunk_put3(op,dep1,dep2,ndep,True)
sewardj2019a972011-03-07 16:04:07 +0000762
763
sewardj2019a972011-03-07 16:04:07 +0000764
765
766/*------------------------------------------------------------*/
767/*--- Guest register access ---*/
768/*------------------------------------------------------------*/
769
770
771/*------------------------------------------------------------*/
772/*--- ar registers ---*/
773/*------------------------------------------------------------*/
774
775/* Return the guest state offset of a ar register. */
776static UInt
777ar_offset(UInt archreg)
778{
779 static const UInt offset[16] = {
floriane88b3c92011-07-05 02:48:39 +0000780 S390X_GUEST_OFFSET(guest_a0),
781 S390X_GUEST_OFFSET(guest_a1),
782 S390X_GUEST_OFFSET(guest_a2),
783 S390X_GUEST_OFFSET(guest_a3),
784 S390X_GUEST_OFFSET(guest_a4),
785 S390X_GUEST_OFFSET(guest_a5),
786 S390X_GUEST_OFFSET(guest_a6),
787 S390X_GUEST_OFFSET(guest_a7),
788 S390X_GUEST_OFFSET(guest_a8),
789 S390X_GUEST_OFFSET(guest_a9),
790 S390X_GUEST_OFFSET(guest_a10),
791 S390X_GUEST_OFFSET(guest_a11),
792 S390X_GUEST_OFFSET(guest_a12),
793 S390X_GUEST_OFFSET(guest_a13),
794 S390X_GUEST_OFFSET(guest_a14),
795 S390X_GUEST_OFFSET(guest_a15),
sewardj2019a972011-03-07 16:04:07 +0000796 };
797
798 vassert(archreg < 16);
799
800 return offset[archreg];
801}
802
803
804/* Return the guest state offset of word #0 of a ar register. */
805static __inline__ UInt
806ar_w0_offset(UInt archreg)
807{
808 return ar_offset(archreg) + 0;
809}
810
811/* Write word #0 of a ar to the guest state. */
812static __inline__ void
813put_ar_w0(UInt archreg, IRExpr *expr)
814{
815 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
816
817 stmt(IRStmt_Put(ar_w0_offset(archreg), expr));
818}
819
820/* Read word #0 of a ar register. */
821static __inline__ IRExpr *
822get_ar_w0(UInt archreg)
823{
824 return IRExpr_Get(ar_w0_offset(archreg), Ity_I32);
825}
826
827
828/*------------------------------------------------------------*/
829/*--- fpr registers ---*/
830/*------------------------------------------------------------*/
831
832/* Return the guest state offset of a fpr register. */
833static UInt
834fpr_offset(UInt archreg)
835{
836 static const UInt offset[16] = {
floriane88b3c92011-07-05 02:48:39 +0000837 S390X_GUEST_OFFSET(guest_f0),
838 S390X_GUEST_OFFSET(guest_f1),
839 S390X_GUEST_OFFSET(guest_f2),
840 S390X_GUEST_OFFSET(guest_f3),
841 S390X_GUEST_OFFSET(guest_f4),
842 S390X_GUEST_OFFSET(guest_f5),
843 S390X_GUEST_OFFSET(guest_f6),
844 S390X_GUEST_OFFSET(guest_f7),
845 S390X_GUEST_OFFSET(guest_f8),
846 S390X_GUEST_OFFSET(guest_f9),
847 S390X_GUEST_OFFSET(guest_f10),
848 S390X_GUEST_OFFSET(guest_f11),
849 S390X_GUEST_OFFSET(guest_f12),
850 S390X_GUEST_OFFSET(guest_f13),
851 S390X_GUEST_OFFSET(guest_f14),
852 S390X_GUEST_OFFSET(guest_f15),
sewardj2019a972011-03-07 16:04:07 +0000853 };
854
855 vassert(archreg < 16);
856
857 return offset[archreg];
858}
859
860
861/* Return the guest state offset of word #0 of a fpr register. */
862static __inline__ UInt
863fpr_w0_offset(UInt archreg)
864{
865 return fpr_offset(archreg) + 0;
866}
867
868/* Write word #0 of a fpr to the guest state. */
869static __inline__ void
870put_fpr_w0(UInt archreg, IRExpr *expr)
871{
872 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_F32);
873
874 stmt(IRStmt_Put(fpr_w0_offset(archreg), expr));
875}
876
877/* Read word #0 of a fpr register. */
878static __inline__ IRExpr *
879get_fpr_w0(UInt archreg)
880{
881 return IRExpr_Get(fpr_w0_offset(archreg), Ity_F32);
882}
883
884/* Return the guest state offset of double word #0 of a fpr register. */
885static __inline__ UInt
886fpr_dw0_offset(UInt archreg)
887{
888 return fpr_offset(archreg) + 0;
889}
890
891/* Write double word #0 of a fpr to the guest state. */
892static __inline__ void
893put_fpr_dw0(UInt archreg, IRExpr *expr)
894{
895 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_F64);
896
897 stmt(IRStmt_Put(fpr_dw0_offset(archreg), expr));
898}
899
900/* Read double word #0 of a fpr register. */
901static __inline__ IRExpr *
902get_fpr_dw0(UInt archreg)
903{
904 return IRExpr_Get(fpr_dw0_offset(archreg), Ity_F64);
905}
906
907
908/*------------------------------------------------------------*/
909/*--- gpr registers ---*/
910/*------------------------------------------------------------*/
911
912/* Return the guest state offset of a gpr register. */
913static UInt
914gpr_offset(UInt archreg)
915{
916 static const UInt offset[16] = {
floriane88b3c92011-07-05 02:48:39 +0000917 S390X_GUEST_OFFSET(guest_r0),
918 S390X_GUEST_OFFSET(guest_r1),
919 S390X_GUEST_OFFSET(guest_r2),
920 S390X_GUEST_OFFSET(guest_r3),
921 S390X_GUEST_OFFSET(guest_r4),
922 S390X_GUEST_OFFSET(guest_r5),
923 S390X_GUEST_OFFSET(guest_r6),
924 S390X_GUEST_OFFSET(guest_r7),
925 S390X_GUEST_OFFSET(guest_r8),
926 S390X_GUEST_OFFSET(guest_r9),
927 S390X_GUEST_OFFSET(guest_r10),
928 S390X_GUEST_OFFSET(guest_r11),
929 S390X_GUEST_OFFSET(guest_r12),
930 S390X_GUEST_OFFSET(guest_r13),
931 S390X_GUEST_OFFSET(guest_r14),
932 S390X_GUEST_OFFSET(guest_r15),
sewardj2019a972011-03-07 16:04:07 +0000933 };
934
935 vassert(archreg < 16);
936
937 return offset[archreg];
938}
939
940
941/* Return the guest state offset of word #0 of a gpr register. */
942static __inline__ UInt
943gpr_w0_offset(UInt archreg)
944{
945 return gpr_offset(archreg) + 0;
946}
947
948/* Write word #0 of a gpr to the guest state. */
949static __inline__ void
950put_gpr_w0(UInt archreg, IRExpr *expr)
951{
952 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
953
954 stmt(IRStmt_Put(gpr_w0_offset(archreg), expr));
955}
956
957/* Read word #0 of a gpr register. */
958static __inline__ IRExpr *
959get_gpr_w0(UInt archreg)
960{
961 return IRExpr_Get(gpr_w0_offset(archreg), Ity_I32);
962}
963
964/* Return the guest state offset of double word #0 of a gpr register. */
965static __inline__ UInt
966gpr_dw0_offset(UInt archreg)
967{
968 return gpr_offset(archreg) + 0;
969}
970
971/* Write double word #0 of a gpr to the guest state. */
972static __inline__ void
973put_gpr_dw0(UInt archreg, IRExpr *expr)
974{
975 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I64);
976
977 stmt(IRStmt_Put(gpr_dw0_offset(archreg), expr));
978}
979
980/* Read double word #0 of a gpr register. */
981static __inline__ IRExpr *
982get_gpr_dw0(UInt archreg)
983{
984 return IRExpr_Get(gpr_dw0_offset(archreg), Ity_I64);
985}
986
987/* Return the guest state offset of half word #1 of a gpr register. */
988static __inline__ UInt
989gpr_hw1_offset(UInt archreg)
990{
991 return gpr_offset(archreg) + 2;
992}
993
994/* Write half word #1 of a gpr to the guest state. */
995static __inline__ void
996put_gpr_hw1(UInt archreg, IRExpr *expr)
997{
998 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
999
1000 stmt(IRStmt_Put(gpr_hw1_offset(archreg), expr));
1001}
1002
1003/* Read half word #1 of a gpr register. */
1004static __inline__ IRExpr *
1005get_gpr_hw1(UInt archreg)
1006{
1007 return IRExpr_Get(gpr_hw1_offset(archreg), Ity_I16);
1008}
1009
1010/* Return the guest state offset of byte #6 of a gpr register. */
1011static __inline__ UInt
1012gpr_b6_offset(UInt archreg)
1013{
1014 return gpr_offset(archreg) + 6;
1015}
1016
1017/* Write byte #6 of a gpr to the guest state. */
1018static __inline__ void
1019put_gpr_b6(UInt archreg, IRExpr *expr)
1020{
1021 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1022
1023 stmt(IRStmt_Put(gpr_b6_offset(archreg), expr));
1024}
1025
1026/* Read byte #6 of a gpr register. */
1027static __inline__ IRExpr *
1028get_gpr_b6(UInt archreg)
1029{
1030 return IRExpr_Get(gpr_b6_offset(archreg), Ity_I8);
1031}
1032
1033/* Return the guest state offset of byte #3 of a gpr register. */
1034static __inline__ UInt
1035gpr_b3_offset(UInt archreg)
1036{
1037 return gpr_offset(archreg) + 3;
1038}
1039
1040/* Write byte #3 of a gpr to the guest state. */
1041static __inline__ void
1042put_gpr_b3(UInt archreg, IRExpr *expr)
1043{
1044 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1045
1046 stmt(IRStmt_Put(gpr_b3_offset(archreg), expr));
1047}
1048
1049/* Read byte #3 of a gpr register. */
1050static __inline__ IRExpr *
1051get_gpr_b3(UInt archreg)
1052{
1053 return IRExpr_Get(gpr_b3_offset(archreg), Ity_I8);
1054}
1055
1056/* Return the guest state offset of byte #0 of a gpr register. */
1057static __inline__ UInt
1058gpr_b0_offset(UInt archreg)
1059{
1060 return gpr_offset(archreg) + 0;
1061}
1062
1063/* Write byte #0 of a gpr to the guest state. */
1064static __inline__ void
1065put_gpr_b0(UInt archreg, IRExpr *expr)
1066{
1067 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1068
1069 stmt(IRStmt_Put(gpr_b0_offset(archreg), expr));
1070}
1071
1072/* Read byte #0 of a gpr register. */
1073static __inline__ IRExpr *
1074get_gpr_b0(UInt archreg)
1075{
1076 return IRExpr_Get(gpr_b0_offset(archreg), Ity_I8);
1077}
1078
1079/* Return the guest state offset of word #1 of a gpr register. */
1080static __inline__ UInt
1081gpr_w1_offset(UInt archreg)
1082{
1083 return gpr_offset(archreg) + 4;
1084}
1085
1086/* Write word #1 of a gpr to the guest state. */
1087static __inline__ void
1088put_gpr_w1(UInt archreg, IRExpr *expr)
1089{
1090 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1091
1092 stmt(IRStmt_Put(gpr_w1_offset(archreg), expr));
1093}
1094
1095/* Read word #1 of a gpr register. */
1096static __inline__ IRExpr *
1097get_gpr_w1(UInt archreg)
1098{
1099 return IRExpr_Get(gpr_w1_offset(archreg), Ity_I32);
1100}
1101
1102/* Return the guest state offset of half word #3 of a gpr register. */
1103static __inline__ UInt
1104gpr_hw3_offset(UInt archreg)
1105{
1106 return gpr_offset(archreg) + 6;
1107}
1108
1109/* Write half word #3 of a gpr to the guest state. */
1110static __inline__ void
1111put_gpr_hw3(UInt archreg, IRExpr *expr)
1112{
1113 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1114
1115 stmt(IRStmt_Put(gpr_hw3_offset(archreg), expr));
1116}
1117
1118/* Read half word #3 of a gpr register. */
1119static __inline__ IRExpr *
1120get_gpr_hw3(UInt archreg)
1121{
1122 return IRExpr_Get(gpr_hw3_offset(archreg), Ity_I16);
1123}
1124
1125/* Return the guest state offset of byte #7 of a gpr register. */
1126static __inline__ UInt
1127gpr_b7_offset(UInt archreg)
1128{
1129 return gpr_offset(archreg) + 7;
1130}
1131
1132/* Write byte #7 of a gpr to the guest state. */
1133static __inline__ void
1134put_gpr_b7(UInt archreg, IRExpr *expr)
1135{
1136 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1137
1138 stmt(IRStmt_Put(gpr_b7_offset(archreg), expr));
1139}
1140
1141/* Read byte #7 of a gpr register. */
1142static __inline__ IRExpr *
1143get_gpr_b7(UInt archreg)
1144{
1145 return IRExpr_Get(gpr_b7_offset(archreg), Ity_I8);
1146}
1147
1148/* Return the guest state offset of half word #0 of a gpr register. */
1149static __inline__ UInt
1150gpr_hw0_offset(UInt archreg)
1151{
1152 return gpr_offset(archreg) + 0;
1153}
1154
1155/* Write half word #0 of a gpr to the guest state. */
1156static __inline__ void
1157put_gpr_hw0(UInt archreg, IRExpr *expr)
1158{
1159 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1160
1161 stmt(IRStmt_Put(gpr_hw0_offset(archreg), expr));
1162}
1163
1164/* Read half word #0 of a gpr register. */
1165static __inline__ IRExpr *
1166get_gpr_hw0(UInt archreg)
1167{
1168 return IRExpr_Get(gpr_hw0_offset(archreg), Ity_I16);
1169}
1170
1171/* Return the guest state offset of byte #4 of a gpr register. */
1172static __inline__ UInt
1173gpr_b4_offset(UInt archreg)
1174{
1175 return gpr_offset(archreg) + 4;
1176}
1177
1178/* Write byte #4 of a gpr to the guest state. */
1179static __inline__ void
1180put_gpr_b4(UInt archreg, IRExpr *expr)
1181{
1182 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1183
1184 stmt(IRStmt_Put(gpr_b4_offset(archreg), expr));
1185}
1186
1187/* Read byte #4 of a gpr register. */
1188static __inline__ IRExpr *
1189get_gpr_b4(UInt archreg)
1190{
1191 return IRExpr_Get(gpr_b4_offset(archreg), Ity_I8);
1192}
1193
1194/* Return the guest state offset of byte #1 of a gpr register. */
1195static __inline__ UInt
1196gpr_b1_offset(UInt archreg)
1197{
1198 return gpr_offset(archreg) + 1;
1199}
1200
1201/* Write byte #1 of a gpr to the guest state. */
1202static __inline__ void
1203put_gpr_b1(UInt archreg, IRExpr *expr)
1204{
1205 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1206
1207 stmt(IRStmt_Put(gpr_b1_offset(archreg), expr));
1208}
1209
1210/* Read byte #1 of a gpr register. */
1211static __inline__ IRExpr *
1212get_gpr_b1(UInt archreg)
1213{
1214 return IRExpr_Get(gpr_b1_offset(archreg), Ity_I8);
1215}
1216
1217/* Return the guest state offset of half word #2 of a gpr register. */
1218static __inline__ UInt
1219gpr_hw2_offset(UInt archreg)
1220{
1221 return gpr_offset(archreg) + 4;
1222}
1223
1224/* Write half word #2 of a gpr to the guest state. */
1225static __inline__ void
1226put_gpr_hw2(UInt archreg, IRExpr *expr)
1227{
1228 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1229
1230 stmt(IRStmt_Put(gpr_hw2_offset(archreg), expr));
1231}
1232
1233/* Read half word #2 of a gpr register. */
1234static __inline__ IRExpr *
1235get_gpr_hw2(UInt archreg)
1236{
1237 return IRExpr_Get(gpr_hw2_offset(archreg), Ity_I16);
1238}
1239
1240/* Return the guest state offset of byte #5 of a gpr register. */
1241static __inline__ UInt
1242gpr_b5_offset(UInt archreg)
1243{
1244 return gpr_offset(archreg) + 5;
1245}
1246
1247/* Write byte #5 of a gpr to the guest state. */
1248static __inline__ void
1249put_gpr_b5(UInt archreg, IRExpr *expr)
1250{
1251 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1252
1253 stmt(IRStmt_Put(gpr_b5_offset(archreg), expr));
1254}
1255
1256/* Read byte #5 of a gpr register. */
1257static __inline__ IRExpr *
1258get_gpr_b5(UInt archreg)
1259{
1260 return IRExpr_Get(gpr_b5_offset(archreg), Ity_I8);
1261}
1262
1263/* Return the guest state offset of byte #2 of a gpr register. */
1264static __inline__ UInt
1265gpr_b2_offset(UInt archreg)
1266{
1267 return gpr_offset(archreg) + 2;
1268}
1269
1270/* Write byte #2 of a gpr to the guest state. */
1271static __inline__ void
1272put_gpr_b2(UInt archreg, IRExpr *expr)
1273{
1274 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1275
1276 stmt(IRStmt_Put(gpr_b2_offset(archreg), expr));
1277}
1278
1279/* Read byte #2 of a gpr register. */
1280static __inline__ IRExpr *
1281get_gpr_b2(UInt archreg)
1282{
1283 return IRExpr_Get(gpr_b2_offset(archreg), Ity_I8);
1284}
1285
1286/* Return the guest state offset of the counter register. */
1287static UInt
1288counter_offset(void)
1289{
floriane88b3c92011-07-05 02:48:39 +00001290 return S390X_GUEST_OFFSET(guest_counter);
sewardj2019a972011-03-07 16:04:07 +00001291}
1292
1293/* Return the guest state offset of double word #0 of the counter register. */
1294static __inline__ UInt
1295counter_dw0_offset(void)
1296{
1297 return counter_offset() + 0;
1298}
1299
1300/* Write double word #0 of the counter to the guest state. */
1301static __inline__ void
1302put_counter_dw0(IRExpr *expr)
1303{
1304 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I64);
1305
1306 stmt(IRStmt_Put(counter_dw0_offset(), expr));
1307}
1308
1309/* Read double word #0 of the counter register. */
1310static __inline__ IRExpr *
1311get_counter_dw0(void)
1312{
1313 return IRExpr_Get(counter_dw0_offset(), Ity_I64);
1314}
1315
1316/* Return the guest state offset of word #0 of the counter register. */
1317static __inline__ UInt
1318counter_w0_offset(void)
1319{
1320 return counter_offset() + 0;
1321}
1322
1323/* Return the guest state offset of word #1 of the counter register. */
1324static __inline__ UInt
1325counter_w1_offset(void)
1326{
1327 return counter_offset() + 4;
1328}
1329
1330/* Write word #0 of the counter to the guest state. */
1331static __inline__ void
1332put_counter_w0(IRExpr *expr)
1333{
1334 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1335
1336 stmt(IRStmt_Put(counter_w0_offset(), expr));
1337}
1338
1339/* Read word #0 of the counter register. */
1340static __inline__ IRExpr *
1341get_counter_w0(void)
1342{
1343 return IRExpr_Get(counter_w0_offset(), Ity_I32);
1344}
1345
1346/* Write word #1 of the counter to the guest state. */
1347static __inline__ void
1348put_counter_w1(IRExpr *expr)
1349{
1350 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1351
1352 stmt(IRStmt_Put(counter_w1_offset(), expr));
1353}
1354
1355/* Read word #1 of the counter register. */
1356static __inline__ IRExpr *
1357get_counter_w1(void)
1358{
1359 return IRExpr_Get(counter_w1_offset(), Ity_I32);
1360}
1361
1362/* Return the guest state offset of the fpc register. */
1363static UInt
1364fpc_offset(void)
1365{
floriane88b3c92011-07-05 02:48:39 +00001366 return S390X_GUEST_OFFSET(guest_fpc);
sewardj2019a972011-03-07 16:04:07 +00001367}
1368
1369/* Return the guest state offset of word #0 of the fpc register. */
1370static __inline__ UInt
1371fpc_w0_offset(void)
1372{
1373 return fpc_offset() + 0;
1374}
1375
1376/* Write word #0 of the fpc to the guest state. */
1377static __inline__ void
1378put_fpc_w0(IRExpr *expr)
1379{
1380 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1381
1382 stmt(IRStmt_Put(fpc_w0_offset(), expr));
1383}
1384
1385/* Read word #0 of the fpc register. */
1386static __inline__ IRExpr *
1387get_fpc_w0(void)
1388{
1389 return IRExpr_Get(fpc_w0_offset(), Ity_I32);
1390}
1391
1392
1393/*------------------------------------------------------------*/
1394/*--- Build IR for formats ---*/
1395/*------------------------------------------------------------*/
1396static void
1397s390_format_I(HChar *(*irgen)(UChar i),
1398 UChar i)
1399{
1400 HChar *mnm = irgen(i);
1401
sewardj7ee97522011-05-09 21:45:04 +00001402 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001403 s390_disasm(ENC2(MNM, UINT), mnm, i);
1404}
1405
1406static void
1407s390_format_RI(HChar *(*irgen)(UChar r1, UShort i2),
1408 UChar r1, UShort i2)
1409{
1410 irgen(r1, i2);
1411}
1412
1413static void
1414s390_format_RI_RU(HChar *(*irgen)(UChar r1, UShort i2),
1415 UChar r1, UShort i2)
1416{
1417 HChar *mnm = irgen(r1, i2);
1418
sewardj7ee97522011-05-09 21:45:04 +00001419 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001420 s390_disasm(ENC3(MNM, GPR, UINT), mnm, r1, i2);
1421}
1422
1423static void
1424s390_format_RI_RI(HChar *(*irgen)(UChar r1, UShort i2),
1425 UChar r1, UShort i2)
1426{
1427 HChar *mnm = irgen(r1, i2);
1428
sewardj7ee97522011-05-09 21:45:04 +00001429 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001430 s390_disasm(ENC3(MNM, GPR, INT), mnm, r1, (Int)(Short)i2);
1431}
1432
1433static void
1434s390_format_RI_RP(HChar *(*irgen)(UChar r1, UShort i2),
1435 UChar r1, UShort i2)
1436{
1437 HChar *mnm = irgen(r1, i2);
1438
sewardj7ee97522011-05-09 21:45:04 +00001439 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001440 s390_disasm(ENC3(MNM, GPR, PCREL), mnm, r1, (Int)(Short)i2);
1441}
1442
1443static void
1444s390_format_RIE_RRP(HChar *(*irgen)(UChar r1, UChar r3, UShort i2),
1445 UChar r1, UChar r3, UShort i2)
1446{
1447 HChar *mnm = irgen(r1, r3, i2);
1448
sewardj7ee97522011-05-09 21:45:04 +00001449 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001450 s390_disasm(ENC4(MNM, GPR, GPR, PCREL), mnm, r1, r3, (Int)(Short)i2);
1451}
1452
1453static void
1454s390_format_RIE_RRI0(HChar *(*irgen)(UChar r1, UChar r3, UShort i2),
1455 UChar r1, UChar r3, UShort i2)
1456{
1457 HChar *mnm = irgen(r1, r3, i2);
1458
sewardj7ee97522011-05-09 21:45:04 +00001459 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001460 s390_disasm(ENC4(MNM, GPR, GPR, INT), mnm, r1, r3, (Int)(Short)i2);
1461}
1462
1463static void
1464s390_format_RIE_RRUUU(HChar *(*irgen)(UChar r1, UChar r2, UChar i3, UChar i4,
1465 UChar i5),
1466 UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
1467{
1468 HChar *mnm = irgen(r1, r2, i3, i4, i5);
1469
sewardj7ee97522011-05-09 21:45:04 +00001470 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001471 s390_disasm(ENC6(MNM, GPR, GPR, UINT, UINT, UINT), mnm, r1, r2, i3, i4,
1472 i5);
1473}
1474
1475static void
1476s390_format_RIE_RRPU(HChar *(*irgen)(UChar r1, UChar r2, UShort i4, UChar m3),
1477 UChar r1, UChar r2, UShort i4, UChar m3)
1478{
1479 HChar *mnm = irgen(r1, r2, i4, m3);
1480
sewardj7ee97522011-05-09 21:45:04 +00001481 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001482 s390_disasm(ENC5(XMNM, GPR, GPR, CABM, PCREL), S390_XMNM_CAB, mnm, m3, r1,
1483 r2, m3, (Int)(Short)i4);
1484}
1485
1486static void
1487s390_format_RIE_RUPU(HChar *(*irgen)(UChar r1, UChar m3, UShort i4, UChar i2),
1488 UChar r1, UChar m3, UShort i4, UChar i2)
1489{
1490 HChar *mnm = irgen(r1, m3, i4, i2);
1491
sewardj7ee97522011-05-09 21:45:04 +00001492 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001493 s390_disasm(ENC5(XMNM, GPR, UINT, CABM, PCREL), S390_XMNM_CAB, mnm, m3,
1494 r1, i2, m3, (Int)(Short)i4);
1495}
1496
1497static void
1498s390_format_RIE_RUPI(HChar *(*irgen)(UChar r1, UChar m3, UShort i4, UChar i2),
1499 UChar r1, UChar m3, UShort i4, UChar i2)
1500{
1501 HChar *mnm = irgen(r1, m3, i4, i2);
1502
sewardj7ee97522011-05-09 21:45:04 +00001503 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001504 s390_disasm(ENC5(XMNM, GPR, INT, CABM, PCREL), S390_XMNM_CAB, mnm, m3, r1,
1505 (Int)(Char)i2, m3, (Int)(Short)i4);
1506}
1507
1508static void
1509s390_format_RIL(HChar *(*irgen)(UChar r1, UInt i2),
1510 UChar r1, UInt i2)
1511{
1512 irgen(r1, i2);
1513}
1514
1515static void
1516s390_format_RIL_RU(HChar *(*irgen)(UChar r1, UInt i2),
1517 UChar r1, UInt i2)
1518{
1519 HChar *mnm = irgen(r1, i2);
1520
sewardj7ee97522011-05-09 21:45:04 +00001521 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001522 s390_disasm(ENC3(MNM, GPR, UINT), mnm, r1, i2);
1523}
1524
1525static void
1526s390_format_RIL_RI(HChar *(*irgen)(UChar r1, UInt i2),
1527 UChar r1, UInt i2)
1528{
1529 HChar *mnm = irgen(r1, i2);
1530
sewardj7ee97522011-05-09 21:45:04 +00001531 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001532 s390_disasm(ENC3(MNM, GPR, INT), mnm, r1, i2);
1533}
1534
1535static void
1536s390_format_RIL_RP(HChar *(*irgen)(UChar r1, UInt i2),
1537 UChar r1, UInt i2)
1538{
1539 HChar *mnm = irgen(r1, i2);
1540
sewardj7ee97522011-05-09 21:45:04 +00001541 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001542 s390_disasm(ENC3(MNM, GPR, PCREL), mnm, r1, i2);
1543}
1544
1545static void
1546s390_format_RIL_UP(HChar *(*irgen)(void),
1547 UChar r1, UInt i2)
1548{
1549 HChar *mnm = irgen();
1550
sewardj7ee97522011-05-09 21:45:04 +00001551 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001552 s390_disasm(ENC3(MNM, UINT, PCREL), mnm, r1, i2);
1553}
1554
1555static void
1556s390_format_RIS_RURDI(HChar *(*irgen)(UChar r1, UChar m3, UChar i2,
1557 IRTemp op4addr),
1558 UChar r1, UChar m3, UChar b4, UShort d4, UChar i2)
1559{
1560 HChar *mnm;
1561 IRTemp op4addr = newTemp(Ity_I64);
1562
1563 assign(op4addr, binop(Iop_Add64, mkU64(d4), b4 != 0 ? get_gpr_dw0(b4) :
1564 mkU64(0)));
1565
1566 mnm = irgen(r1, m3, i2, op4addr);
1567
sewardj7ee97522011-05-09 21:45:04 +00001568 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001569 s390_disasm(ENC5(XMNM, GPR, INT, CABM, UDXB), S390_XMNM_CAB, mnm, m3, r1,
1570 (Int)(Char)i2, m3, d4, 0, b4);
1571}
1572
1573static void
1574s390_format_RIS_RURDU(HChar *(*irgen)(UChar r1, UChar m3, UChar i2,
1575 IRTemp op4addr),
1576 UChar r1, UChar m3, UChar b4, UShort d4, UChar i2)
1577{
1578 HChar *mnm;
1579 IRTemp op4addr = newTemp(Ity_I64);
1580
1581 assign(op4addr, binop(Iop_Add64, mkU64(d4), b4 != 0 ? get_gpr_dw0(b4) :
1582 mkU64(0)));
1583
1584 mnm = irgen(r1, m3, i2, op4addr);
1585
sewardj7ee97522011-05-09 21:45:04 +00001586 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001587 s390_disasm(ENC5(XMNM, GPR, UINT, CABM, UDXB), S390_XMNM_CAB, mnm, m3, r1,
1588 i2, m3, d4, 0, b4);
1589}
1590
1591static void
1592s390_format_RR(HChar *(*irgen)(UChar r1, UChar r2),
1593 UChar r1, UChar r2)
1594{
1595 irgen(r1, r2);
1596}
1597
1598static void
1599s390_format_RR_RR(HChar *(*irgen)(UChar r1, UChar r2),
1600 UChar r1, UChar r2)
1601{
1602 HChar *mnm = irgen(r1, r2);
1603
sewardj7ee97522011-05-09 21:45:04 +00001604 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001605 s390_disasm(ENC3(MNM, GPR, GPR), mnm, r1, r2);
1606}
1607
1608static void
1609s390_format_RR_FF(HChar *(*irgen)(UChar r1, UChar r2),
1610 UChar r1, UChar r2)
1611{
1612 HChar *mnm = irgen(r1, r2);
1613
sewardj7ee97522011-05-09 21:45:04 +00001614 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001615 s390_disasm(ENC3(MNM, FPR, FPR), mnm, r1, r2);
1616}
1617
1618static void
1619s390_format_RRE(HChar *(*irgen)(UChar r1, UChar r2),
1620 UChar r1, UChar r2)
1621{
1622 irgen(r1, r2);
1623}
1624
1625static void
1626s390_format_RRE_RR(HChar *(*irgen)(UChar r1, UChar r2),
1627 UChar r1, UChar r2)
1628{
1629 HChar *mnm = irgen(r1, r2);
1630
sewardj7ee97522011-05-09 21:45:04 +00001631 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001632 s390_disasm(ENC3(MNM, GPR, GPR), mnm, r1, r2);
1633}
1634
1635static void
1636s390_format_RRE_FF(HChar *(*irgen)(UChar r1, UChar r2),
1637 UChar r1, UChar r2)
1638{
1639 HChar *mnm = irgen(r1, r2);
1640
sewardj7ee97522011-05-09 21:45:04 +00001641 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001642 s390_disasm(ENC3(MNM, FPR, FPR), mnm, r1, r2);
1643}
1644
1645static void
1646s390_format_RRE_RF(HChar *(*irgen)(UChar, UChar),
1647 UChar r1, UChar r2)
1648{
1649 HChar *mnm = irgen(r1, r2);
1650
sewardj7ee97522011-05-09 21:45:04 +00001651 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001652 s390_disasm(ENC3(MNM, GPR, FPR), mnm, r1, r2);
1653}
1654
1655static void
1656s390_format_RRE_FR(HChar *(*irgen)(UChar r1, UChar r2),
1657 UChar r1, UChar r2)
1658{
1659 HChar *mnm = irgen(r1, r2);
1660
sewardj7ee97522011-05-09 21:45:04 +00001661 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001662 s390_disasm(ENC3(MNM, FPR, GPR), mnm, r1, r2);
1663}
1664
1665static void
1666s390_format_RRE_R0(HChar *(*irgen)(UChar r1),
1667 UChar r1)
1668{
1669 HChar *mnm = irgen(r1);
1670
sewardj7ee97522011-05-09 21:45:04 +00001671 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001672 s390_disasm(ENC2(MNM, GPR), mnm, r1);
1673}
1674
1675static void
1676s390_format_RRE_F0(HChar *(*irgen)(UChar r1),
1677 UChar r1)
1678{
1679 HChar *mnm = irgen(r1);
1680
sewardj7ee97522011-05-09 21:45:04 +00001681 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001682 s390_disasm(ENC2(MNM, FPR), mnm, r1);
1683}
1684
1685static void
florian9af37692012-01-15 21:01:16 +00001686s390_format_RRF_M0RERE(HChar *(*irgen)(UChar m3, UChar r1, UChar r2),
1687 UChar m3, UChar r1, UChar r2)
1688{
florianfed3ea32012-07-19 14:54:03 +00001689 HChar *mnm = irgen(m3, r1, r2);
florian9af37692012-01-15 21:01:16 +00001690
1691 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
florianfed3ea32012-07-19 14:54:03 +00001692 s390_disasm(ENC4(MNM, GPR, GPR, UINT), mnm, r1, r2, m3);
florian9af37692012-01-15 21:01:16 +00001693}
1694
1695static void
sewardj2019a972011-03-07 16:04:07 +00001696s390_format_RRF_F0FF(HChar *(*irgen)(UChar, UChar, UChar),
1697 UChar r1, UChar r3, UChar r2)
1698{
1699 HChar *mnm = irgen(r1, r3, r2);
1700
sewardj7ee97522011-05-09 21:45:04 +00001701 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001702 s390_disasm(ENC4(MNM, FPR, FPR, FPR), mnm, r1, r3, r2);
1703}
1704
1705static void
sewardjd7bde722011-04-05 13:19:33 +00001706s390_format_RRF_U0RR(HChar *(*irgen)(UChar m3, UChar r1, UChar r2),
1707 UChar m3, UChar r1, UChar r2, Int xmnm_kind)
1708{
1709 irgen(m3, r1, r2);
1710
sewardj7ee97522011-05-09 21:45:04 +00001711 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardjd7bde722011-04-05 13:19:33 +00001712 s390_disasm(ENC3(XMNM, GPR, GPR), xmnm_kind, m3, r1, r2);
1713}
1714
1715static void
sewardj2019a972011-03-07 16:04:07 +00001716s390_format_RRF_U0RF(HChar *(*irgen)(UChar r3, UChar r1, UChar r2),
1717 UChar r3, UChar r1, UChar r2)
1718{
1719 HChar *mnm = irgen(r3, r1, r2);
1720
sewardj7ee97522011-05-09 21:45:04 +00001721 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001722 s390_disasm(ENC4(MNM, GPR, UINT, FPR), mnm, r1, r3, r2);
1723}
1724
1725static void
1726s390_format_RRF_F0FF2(HChar *(*irgen)(UChar, UChar, UChar),
1727 UChar r3, UChar r1, UChar r2)
1728{
1729 HChar *mnm = irgen(r3, r1, r2);
1730
sewardj7ee97522011-05-09 21:45:04 +00001731 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001732 s390_disasm(ENC4(MNM, FPR, FPR, FPR), mnm, r1, r3, r2);
1733}
1734
1735static void
1736s390_format_RRF_R0RR2(HChar *(*irgen)(UChar r3, UChar r1, UChar r2),
1737 UChar r3, UChar r1, UChar r2)
1738{
1739 HChar *mnm = irgen(r3, r1, r2);
1740
sewardj7ee97522011-05-09 21:45:04 +00001741 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001742 s390_disasm(ENC4(MNM, GPR, GPR, GPR), mnm, r1, r2, r3);
1743}
1744
1745static void
1746s390_format_RRS(HChar *(*irgen)(UChar r1, UChar r2, UChar m3, IRTemp op4addr),
1747 UChar r1, UChar r2, UChar b4, UShort d4, UChar m3)
1748{
1749 HChar *mnm;
1750 IRTemp op4addr = newTemp(Ity_I64);
1751
1752 assign(op4addr, binop(Iop_Add64, mkU64(d4), b4 != 0 ? get_gpr_dw0(b4) :
1753 mkU64(0)));
1754
1755 mnm = irgen(r1, r2, m3, op4addr);
1756
sewardj7ee97522011-05-09 21:45:04 +00001757 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001758 s390_disasm(ENC5(XMNM, GPR, GPR, CABM, UDXB), S390_XMNM_CAB, mnm, m3, r1,
1759 r2, m3, d4, 0, b4);
1760}
1761
1762static void
1763s390_format_RS_R0RD(HChar *(*irgen)(UChar r1, IRTemp op2addr),
1764 UChar r1, UChar b2, UShort d2)
1765{
1766 HChar *mnm;
1767 IRTemp op2addr = newTemp(Ity_I64);
1768
1769 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
1770 mkU64(0)));
1771
1772 mnm = irgen(r1, op2addr);
1773
sewardj7ee97522011-05-09 21:45:04 +00001774 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001775 s390_disasm(ENC3(MNM, GPR, UDXB), mnm, r1, d2, 0, b2);
1776}
1777
1778static void
1779s390_format_RS_RRRD(HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
1780 UChar r1, UChar r3, UChar b2, UShort d2)
1781{
1782 HChar *mnm;
1783 IRTemp op2addr = newTemp(Ity_I64);
1784
1785 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
1786 mkU64(0)));
1787
1788 mnm = irgen(r1, r3, op2addr);
1789
sewardj7ee97522011-05-09 21:45:04 +00001790 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001791 s390_disasm(ENC4(MNM, GPR, GPR, UDXB), mnm, r1, r3, d2, 0, b2);
1792}
1793
1794static void
1795s390_format_RS_RURD(HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
1796 UChar r1, UChar r3, UChar b2, UShort d2)
1797{
1798 HChar *mnm;
1799 IRTemp op2addr = newTemp(Ity_I64);
1800
1801 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
1802 mkU64(0)));
1803
1804 mnm = irgen(r1, r3, op2addr);
1805
sewardj7ee97522011-05-09 21:45:04 +00001806 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001807 s390_disasm(ENC4(MNM, GPR, UINT, UDXB), mnm, r1, r3, d2, 0, b2);
1808}
1809
1810static void
1811s390_format_RS_AARD(HChar *(*irgen)(UChar, UChar, IRTemp),
1812 UChar r1, UChar r3, UChar b2, UShort d2)
1813{
1814 HChar *mnm;
1815 IRTemp op2addr = newTemp(Ity_I64);
1816
1817 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
1818 mkU64(0)));
1819
1820 mnm = irgen(r1, r3, op2addr);
1821
sewardj7ee97522011-05-09 21:45:04 +00001822 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001823 s390_disasm(ENC4(MNM, AR, AR, UDXB), mnm, r1, r3, d2, 0, b2);
1824}
1825
1826static void
1827s390_format_RSI_RRP(HChar *(*irgen)(UChar r1, UChar r3, UShort i2),
1828 UChar r1, UChar r3, UShort i2)
1829{
1830 HChar *mnm = irgen(r1, r3, i2);
1831
sewardj7ee97522011-05-09 21:45:04 +00001832 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001833 s390_disasm(ENC4(MNM, GPR, GPR, PCREL), mnm, r1, r3, (Int)(Short)i2);
1834}
1835
1836static void
1837s390_format_RSY_RRRD(HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
1838 UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2)
1839{
1840 HChar *mnm;
1841 IRTemp op2addr = newTemp(Ity_I64);
1842 IRTemp d2 = newTemp(Ity_I64);
1843
1844 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
1845 assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
1846 mkU64(0)));
1847
1848 mnm = irgen(r1, r3, op2addr);
1849
sewardj7ee97522011-05-09 21:45:04 +00001850 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001851 s390_disasm(ENC4(MNM, GPR, GPR, SDXB), mnm, r1, r3, dh2, dl2, 0, b2);
1852}
1853
1854static void
1855s390_format_RSY_AARD(HChar *(*irgen)(UChar, UChar, IRTemp),
1856 UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2)
1857{
1858 HChar *mnm;
1859 IRTemp op2addr = newTemp(Ity_I64);
1860 IRTemp d2 = newTemp(Ity_I64);
1861
1862 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
1863 assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
1864 mkU64(0)));
1865
1866 mnm = irgen(r1, r3, op2addr);
1867
sewardj7ee97522011-05-09 21:45:04 +00001868 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001869 s390_disasm(ENC4(MNM, AR, AR, SDXB), mnm, r1, r3, dh2, dl2, 0, b2);
1870}
1871
1872static void
1873s390_format_RSY_RURD(HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
1874 UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2)
1875{
1876 HChar *mnm;
1877 IRTemp op2addr = newTemp(Ity_I64);
1878 IRTemp d2 = newTemp(Ity_I64);
1879
1880 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
1881 assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
1882 mkU64(0)));
1883
1884 mnm = irgen(r1, r3, op2addr);
1885
sewardj7ee97522011-05-09 21:45:04 +00001886 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001887 s390_disasm(ENC4(MNM, GPR, UINT, SDXB), mnm, r1, r3, dh2, dl2, 0, b2);
1888}
1889
1890static void
sewardjd7bde722011-04-05 13:19:33 +00001891s390_format_RSY_RDRM(HChar *(*irgen)(UChar r1, IRTemp op2addr),
1892 UChar r1, UChar m3, UChar b2, UShort dl2, UChar dh2,
1893 Int xmnm_kind)
1894{
1895 IRTemp op2addr = newTemp(Ity_I64);
1896 IRTemp d2 = newTemp(Ity_I64);
1897
florian6820ba52012-07-26 02:01:50 +00001898 next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0)));
1899
sewardjd7bde722011-04-05 13:19:33 +00001900 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
1901 assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
1902 mkU64(0)));
1903
1904 irgen(r1, op2addr);
florian6820ba52012-07-26 02:01:50 +00001905
1906 vassert(dis_res->whatNext == Dis_Continue);
sewardjd7bde722011-04-05 13:19:33 +00001907
sewardj7ee97522011-05-09 21:45:04 +00001908 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardjd7bde722011-04-05 13:19:33 +00001909 s390_disasm(ENC3(XMNM, GPR, SDXB), xmnm_kind, m3, r1, dh2, dl2, 0, b2);
1910}
1911
1912static void
sewardj2019a972011-03-07 16:04:07 +00001913s390_format_RX(HChar *(*irgen)(UChar r1, UChar x2, UChar b2, UShort d2,
1914 IRTemp op2addr),
1915 UChar r1, UChar x2, UChar b2, UShort d2)
1916{
1917 IRTemp op2addr = newTemp(Ity_I64);
1918
1919 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
1920 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
1921 mkU64(0)));
1922
1923 irgen(r1, x2, b2, d2, op2addr);
1924}
1925
1926static void
1927s390_format_RX_RRRD(HChar *(*irgen)(UChar r1, IRTemp op2addr),
1928 UChar r1, UChar x2, UChar b2, UShort d2)
1929{
1930 HChar *mnm;
1931 IRTemp op2addr = newTemp(Ity_I64);
1932
1933 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
1934 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
1935 mkU64(0)));
1936
1937 mnm = irgen(r1, op2addr);
1938
sewardj7ee97522011-05-09 21:45:04 +00001939 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001940 s390_disasm(ENC3(MNM, GPR, UDXB), mnm, r1, d2, x2, b2);
1941}
1942
1943static void
1944s390_format_RX_FRRD(HChar *(*irgen)(UChar r1, IRTemp op2addr),
1945 UChar r1, UChar x2, UChar b2, UShort d2)
1946{
1947 HChar *mnm;
1948 IRTemp op2addr = newTemp(Ity_I64);
1949
1950 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
1951 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
1952 mkU64(0)));
1953
1954 mnm = irgen(r1, op2addr);
1955
sewardj7ee97522011-05-09 21:45:04 +00001956 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001957 s390_disasm(ENC3(MNM, FPR, UDXB), mnm, r1, d2, x2, b2);
1958}
1959
1960static void
1961s390_format_RXE_FRRD(HChar *(*irgen)(UChar r1, IRTemp op2addr),
1962 UChar r1, UChar x2, UChar b2, UShort d2)
1963{
1964 HChar *mnm;
1965 IRTemp op2addr = newTemp(Ity_I64);
1966
1967 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
1968 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
1969 mkU64(0)));
1970
1971 mnm = irgen(r1, op2addr);
1972
sewardj7ee97522011-05-09 21:45:04 +00001973 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001974 s390_disasm(ENC3(MNM, FPR, UDXB), mnm, r1, d2, x2, b2);
1975}
1976
1977static void
1978s390_format_RXF_FRRDF(HChar *(*irgen)(UChar, IRTemp, UChar),
1979 UChar r3, UChar x2, UChar b2, UShort d2, UChar r1)
1980{
1981 HChar *mnm;
1982 IRTemp op2addr = newTemp(Ity_I64);
1983
1984 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
1985 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
1986 mkU64(0)));
1987
1988 mnm = irgen(r3, op2addr, r1);
1989
sewardj7ee97522011-05-09 21:45:04 +00001990 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001991 s390_disasm(ENC4(MNM, FPR, FPR, UDXB), mnm, r1, r3, d2, x2, b2);
1992}
1993
1994static void
1995s390_format_RXY_RRRD(HChar *(*irgen)(UChar r1, IRTemp op2addr),
1996 UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
1997{
1998 HChar *mnm;
1999 IRTemp op2addr = newTemp(Ity_I64);
2000 IRTemp d2 = newTemp(Ity_I64);
2001
2002 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2003 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkexpr(d2),
2004 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2005 mkU64(0)));
2006
2007 mnm = irgen(r1, op2addr);
2008
sewardj7ee97522011-05-09 21:45:04 +00002009 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002010 s390_disasm(ENC3(MNM, GPR, SDXB), mnm, r1, dh2, dl2, x2, b2);
2011}
2012
2013static void
2014s390_format_RXY_FRRD(HChar *(*irgen)(UChar r1, IRTemp op2addr),
2015 UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
2016{
2017 HChar *mnm;
2018 IRTemp op2addr = newTemp(Ity_I64);
2019 IRTemp d2 = newTemp(Ity_I64);
2020
2021 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2022 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkexpr(d2),
2023 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2024 mkU64(0)));
2025
2026 mnm = irgen(r1, op2addr);
2027
sewardj7ee97522011-05-09 21:45:04 +00002028 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002029 s390_disasm(ENC3(MNM, FPR, SDXB), mnm, r1, dh2, dl2, x2, b2);
2030}
2031
2032static void
2033s390_format_RXY_URRD(HChar *(*irgen)(void),
2034 UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
2035{
2036 HChar *mnm;
2037 IRTemp op2addr = newTemp(Ity_I64);
2038 IRTemp d2 = newTemp(Ity_I64);
2039
2040 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2041 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkexpr(d2),
2042 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2043 mkU64(0)));
2044
2045 mnm = irgen();
2046
sewardj7ee97522011-05-09 21:45:04 +00002047 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002048 s390_disasm(ENC3(MNM, UINT, SDXB), mnm, r1, dh2, dl2, x2, b2);
2049}
2050
2051static void
2052s390_format_S_RD(HChar *(*irgen)(IRTemp op2addr),
2053 UChar b2, UShort d2)
2054{
2055 HChar *mnm;
2056 IRTemp op2addr = newTemp(Ity_I64);
2057
2058 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2059 mkU64(0)));
2060
2061 mnm = irgen(op2addr);
2062
sewardj7ee97522011-05-09 21:45:04 +00002063 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002064 s390_disasm(ENC2(MNM, UDXB), mnm, d2, 0, b2);
2065}
2066
2067static void
2068s390_format_SI_URD(HChar *(*irgen)(UChar i2, IRTemp op1addr),
2069 UChar i2, UChar b1, UShort d1)
2070{
2071 HChar *mnm;
2072 IRTemp op1addr = newTemp(Ity_I64);
2073
2074 assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
2075 mkU64(0)));
2076
2077 mnm = irgen(i2, op1addr);
2078
sewardj7ee97522011-05-09 21:45:04 +00002079 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002080 s390_disasm(ENC3(MNM, UDXB, UINT), mnm, d1, 0, b1, i2);
2081}
2082
2083static void
2084s390_format_SIY_URD(HChar *(*irgen)(UChar i2, IRTemp op1addr),
2085 UChar i2, UChar b1, UShort dl1, UChar dh1)
2086{
2087 HChar *mnm;
2088 IRTemp op1addr = newTemp(Ity_I64);
2089 IRTemp d1 = newTemp(Ity_I64);
2090
2091 assign(d1, mkU64(((ULong)(Long)(Char)dh1 << 12) | ((ULong)dl1)));
2092 assign(op1addr, binop(Iop_Add64, mkexpr(d1), b1 != 0 ? get_gpr_dw0(b1) :
2093 mkU64(0)));
2094
2095 mnm = irgen(i2, op1addr);
2096
sewardj7ee97522011-05-09 21:45:04 +00002097 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002098 s390_disasm(ENC3(MNM, SDXB, UINT), mnm, dh1, dl1, 0, b1, i2);
2099}
2100
2101static void
2102s390_format_SIY_IRD(HChar *(*irgen)(UChar i2, IRTemp op1addr),
2103 UChar i2, UChar b1, UShort dl1, UChar dh1)
2104{
2105 HChar *mnm;
2106 IRTemp op1addr = newTemp(Ity_I64);
2107 IRTemp d1 = newTemp(Ity_I64);
2108
2109 assign(d1, mkU64(((ULong)(Long)(Char)dh1 << 12) | ((ULong)dl1)));
2110 assign(op1addr, binop(Iop_Add64, mkexpr(d1), b1 != 0 ? get_gpr_dw0(b1) :
2111 mkU64(0)));
2112
2113 mnm = irgen(i2, op1addr);
2114
sewardj7ee97522011-05-09 21:45:04 +00002115 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002116 s390_disasm(ENC3(MNM, SDXB, INT), mnm, dh1, dl1, 0, b1, (Int)(Char)i2);
2117}
2118
2119static void
2120s390_format_SS_L0RDRD(HChar *(*irgen)(UChar, IRTemp, IRTemp),
2121 UChar l, UChar b1, UShort d1, UChar b2, UShort d2)
2122{
2123 HChar *mnm;
2124 IRTemp op1addr = newTemp(Ity_I64);
2125 IRTemp op2addr = newTemp(Ity_I64);
2126
2127 assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
2128 mkU64(0)));
2129 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2130 mkU64(0)));
2131
2132 mnm = irgen(l, op1addr, op2addr);
2133
sewardj7ee97522011-05-09 21:45:04 +00002134 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002135 s390_disasm(ENC3(MNM, UDLB, UDXB), mnm, d1, l, b1, d2, 0, b2);
2136}
2137
2138static void
2139s390_format_SIL_RDI(HChar *(*irgen)(UShort i2, IRTemp op1addr),
2140 UChar b1, UShort d1, UShort i2)
2141{
2142 HChar *mnm;
2143 IRTemp op1addr = newTemp(Ity_I64);
2144
2145 assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
2146 mkU64(0)));
2147
2148 mnm = irgen(i2, op1addr);
2149
sewardj7ee97522011-05-09 21:45:04 +00002150 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002151 s390_disasm(ENC3(MNM, UDXB, INT), mnm, d1, 0, b1, (Int)(Short)i2);
2152}
2153
2154static void
2155s390_format_SIL_RDU(HChar *(*irgen)(UShort i2, IRTemp op1addr),
2156 UChar b1, UShort d1, UShort i2)
2157{
2158 HChar *mnm;
2159 IRTemp op1addr = newTemp(Ity_I64);
2160
2161 assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
2162 mkU64(0)));
2163
2164 mnm = irgen(i2, op1addr);
2165
sewardj7ee97522011-05-09 21:45:04 +00002166 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002167 s390_disasm(ENC3(MNM, UDXB, UINT), mnm, d1, 0, b1, i2);
2168}
2169
2170
2171
2172/*------------------------------------------------------------*/
2173/*--- Build IR for opcodes ---*/
2174/*------------------------------------------------------------*/
2175
2176static HChar *
2177s390_irgen_AR(UChar r1, UChar r2)
2178{
2179 IRTemp op1 = newTemp(Ity_I32);
2180 IRTemp op2 = newTemp(Ity_I32);
2181 IRTemp result = newTemp(Ity_I32);
2182
2183 assign(op1, get_gpr_w1(r1));
2184 assign(op2, get_gpr_w1(r2));
2185 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2186 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2187 put_gpr_w1(r1, mkexpr(result));
2188
2189 return "ar";
2190}
2191
2192static HChar *
2193s390_irgen_AGR(UChar r1, UChar r2)
2194{
2195 IRTemp op1 = newTemp(Ity_I64);
2196 IRTemp op2 = newTemp(Ity_I64);
2197 IRTemp result = newTemp(Ity_I64);
2198
2199 assign(op1, get_gpr_dw0(r1));
2200 assign(op2, get_gpr_dw0(r2));
2201 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2202 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
2203 put_gpr_dw0(r1, mkexpr(result));
2204
2205 return "agr";
2206}
2207
2208static HChar *
2209s390_irgen_AGFR(UChar r1, UChar r2)
2210{
2211 IRTemp op1 = newTemp(Ity_I64);
2212 IRTemp op2 = newTemp(Ity_I64);
2213 IRTemp result = newTemp(Ity_I64);
2214
2215 assign(op1, get_gpr_dw0(r1));
2216 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
2217 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2218 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
2219 put_gpr_dw0(r1, mkexpr(result));
2220
2221 return "agfr";
2222}
2223
2224static HChar *
2225s390_irgen_ARK(UChar r3, UChar r1, UChar r2)
2226{
2227 IRTemp op2 = newTemp(Ity_I32);
2228 IRTemp op3 = newTemp(Ity_I32);
2229 IRTemp result = newTemp(Ity_I32);
2230
2231 assign(op2, get_gpr_w1(r2));
2232 assign(op3, get_gpr_w1(r3));
2233 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2234 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
2235 put_gpr_w1(r1, mkexpr(result));
2236
2237 return "ark";
2238}
2239
2240static HChar *
2241s390_irgen_AGRK(UChar r3, UChar r1, UChar r2)
2242{
2243 IRTemp op2 = newTemp(Ity_I64);
2244 IRTemp op3 = newTemp(Ity_I64);
2245 IRTemp result = newTemp(Ity_I64);
2246
2247 assign(op2, get_gpr_dw0(r2));
2248 assign(op3, get_gpr_dw0(r3));
2249 assign(result, binop(Iop_Add64, mkexpr(op2), mkexpr(op3)));
2250 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op2, op3);
2251 put_gpr_dw0(r1, mkexpr(result));
2252
2253 return "agrk";
2254}
2255
2256static HChar *
2257s390_irgen_A(UChar r1, IRTemp op2addr)
2258{
2259 IRTemp op1 = newTemp(Ity_I32);
2260 IRTemp op2 = newTemp(Ity_I32);
2261 IRTemp result = newTemp(Ity_I32);
2262
2263 assign(op1, get_gpr_w1(r1));
2264 assign(op2, load(Ity_I32, mkexpr(op2addr)));
2265 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2266 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2267 put_gpr_w1(r1, mkexpr(result));
2268
2269 return "a";
2270}
2271
2272static HChar *
2273s390_irgen_AY(UChar r1, IRTemp op2addr)
2274{
2275 IRTemp op1 = newTemp(Ity_I32);
2276 IRTemp op2 = newTemp(Ity_I32);
2277 IRTemp result = newTemp(Ity_I32);
2278
2279 assign(op1, get_gpr_w1(r1));
2280 assign(op2, load(Ity_I32, mkexpr(op2addr)));
2281 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2282 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2283 put_gpr_w1(r1, mkexpr(result));
2284
2285 return "ay";
2286}
2287
2288static HChar *
2289s390_irgen_AG(UChar r1, IRTemp op2addr)
2290{
2291 IRTemp op1 = newTemp(Ity_I64);
2292 IRTemp op2 = newTemp(Ity_I64);
2293 IRTemp result = newTemp(Ity_I64);
2294
2295 assign(op1, get_gpr_dw0(r1));
2296 assign(op2, load(Ity_I64, mkexpr(op2addr)));
2297 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2298 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
2299 put_gpr_dw0(r1, mkexpr(result));
2300
2301 return "ag";
2302}
2303
2304static HChar *
2305s390_irgen_AGF(UChar r1, IRTemp op2addr)
2306{
2307 IRTemp op1 = newTemp(Ity_I64);
2308 IRTemp op2 = newTemp(Ity_I64);
2309 IRTemp result = newTemp(Ity_I64);
2310
2311 assign(op1, get_gpr_dw0(r1));
2312 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
2313 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2314 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
2315 put_gpr_dw0(r1, mkexpr(result));
2316
2317 return "agf";
2318}
2319
2320static HChar *
2321s390_irgen_AFI(UChar r1, UInt i2)
2322{
2323 IRTemp op1 = newTemp(Ity_I32);
2324 Int op2;
2325 IRTemp result = newTemp(Ity_I32);
2326
2327 assign(op1, get_gpr_w1(r1));
2328 op2 = (Int)i2;
2329 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
2330 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
2331 mkU32((UInt)op2)));
2332 put_gpr_w1(r1, mkexpr(result));
2333
2334 return "afi";
2335}
2336
2337static HChar *
2338s390_irgen_AGFI(UChar r1, UInt i2)
2339{
2340 IRTemp op1 = newTemp(Ity_I64);
2341 Long op2;
2342 IRTemp result = newTemp(Ity_I64);
2343
2344 assign(op1, get_gpr_dw0(r1));
2345 op2 = (Long)(Int)i2;
2346 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64((ULong)op2)));
2347 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, mktemp(Ity_I64,
2348 mkU64((ULong)op2)));
2349 put_gpr_dw0(r1, mkexpr(result));
2350
2351 return "agfi";
2352}
2353
2354static HChar *
2355s390_irgen_AHIK(UChar r1, UChar r3, UShort i2)
2356{
2357 Int op2;
2358 IRTemp op3 = newTemp(Ity_I32);
2359 IRTemp result = newTemp(Ity_I32);
2360
2361 op2 = (Int)(Short)i2;
2362 assign(op3, get_gpr_w1(r3));
2363 assign(result, binop(Iop_Add32, mkU32((UInt)op2), mkexpr(op3)));
2364 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, mktemp(Ity_I32, mkU32((UInt)
2365 op2)), op3);
2366 put_gpr_w1(r1, mkexpr(result));
2367
2368 return "ahik";
2369}
2370
2371static HChar *
2372s390_irgen_AGHIK(UChar r1, UChar r3, UShort i2)
2373{
2374 Long op2;
2375 IRTemp op3 = newTemp(Ity_I64);
2376 IRTemp result = newTemp(Ity_I64);
2377
2378 op2 = (Long)(Short)i2;
2379 assign(op3, get_gpr_dw0(r3));
2380 assign(result, binop(Iop_Add64, mkU64((ULong)op2), mkexpr(op3)));
2381 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, mktemp(Ity_I64, mkU64((ULong)
2382 op2)), op3);
2383 put_gpr_dw0(r1, mkexpr(result));
2384
2385 return "aghik";
2386}
2387
2388static HChar *
2389s390_irgen_ASI(UChar i2, IRTemp op1addr)
2390{
2391 IRTemp op1 = newTemp(Ity_I32);
2392 Int op2;
2393 IRTemp result = newTemp(Ity_I32);
2394
2395 assign(op1, load(Ity_I32, mkexpr(op1addr)));
2396 op2 = (Int)(Char)i2;
2397 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
2398 store(mkexpr(op1addr), mkexpr(result));
2399 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
2400 mkU32((UInt)op2)));
2401
2402 return "asi";
2403}
2404
2405static HChar *
2406s390_irgen_AGSI(UChar i2, IRTemp op1addr)
2407{
2408 IRTemp op1 = newTemp(Ity_I64);
2409 Long op2;
2410 IRTemp result = newTemp(Ity_I64);
2411
2412 assign(op1, load(Ity_I64, mkexpr(op1addr)));
2413 op2 = (Long)(Char)i2;
2414 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64((ULong)op2)));
2415 store(mkexpr(op1addr), mkexpr(result));
2416 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, mktemp(Ity_I64,
2417 mkU64((ULong)op2)));
2418
2419 return "agsi";
2420}
2421
2422static HChar *
2423s390_irgen_AH(UChar r1, IRTemp op2addr)
2424{
2425 IRTemp op1 = newTemp(Ity_I32);
2426 IRTemp op2 = newTemp(Ity_I32);
2427 IRTemp result = newTemp(Ity_I32);
2428
2429 assign(op1, get_gpr_w1(r1));
2430 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
2431 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2432 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2433 put_gpr_w1(r1, mkexpr(result));
2434
2435 return "ah";
2436}
2437
2438static HChar *
2439s390_irgen_AHY(UChar r1, IRTemp op2addr)
2440{
2441 IRTemp op1 = newTemp(Ity_I32);
2442 IRTemp op2 = newTemp(Ity_I32);
2443 IRTemp result = newTemp(Ity_I32);
2444
2445 assign(op1, get_gpr_w1(r1));
2446 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
2447 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2448 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2449 put_gpr_w1(r1, mkexpr(result));
2450
2451 return "ahy";
2452}
2453
2454static HChar *
2455s390_irgen_AHI(UChar r1, UShort i2)
2456{
2457 IRTemp op1 = newTemp(Ity_I32);
2458 Int op2;
2459 IRTemp result = newTemp(Ity_I32);
2460
2461 assign(op1, get_gpr_w1(r1));
2462 op2 = (Int)(Short)i2;
2463 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
2464 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
2465 mkU32((UInt)op2)));
2466 put_gpr_w1(r1, mkexpr(result));
2467
2468 return "ahi";
2469}
2470
2471static HChar *
2472s390_irgen_AGHI(UChar r1, UShort i2)
2473{
2474 IRTemp op1 = newTemp(Ity_I64);
2475 Long op2;
2476 IRTemp result = newTemp(Ity_I64);
2477
2478 assign(op1, get_gpr_dw0(r1));
2479 op2 = (Long)(Short)i2;
2480 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64((ULong)op2)));
2481 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, mktemp(Ity_I64,
2482 mkU64((ULong)op2)));
2483 put_gpr_dw0(r1, mkexpr(result));
2484
2485 return "aghi";
2486}
2487
2488static HChar *
2489s390_irgen_AHHHR(UChar r3, UChar r1, UChar r2)
2490{
2491 IRTemp op2 = newTemp(Ity_I32);
2492 IRTemp op3 = newTemp(Ity_I32);
2493 IRTemp result = newTemp(Ity_I32);
2494
2495 assign(op2, get_gpr_w0(r2));
2496 assign(op3, get_gpr_w0(r3));
2497 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2498 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
2499 put_gpr_w0(r1, mkexpr(result));
2500
2501 return "ahhhr";
2502}
2503
2504static HChar *
2505s390_irgen_AHHLR(UChar r3, UChar r1, UChar r2)
2506{
2507 IRTemp op2 = newTemp(Ity_I32);
2508 IRTemp op3 = newTemp(Ity_I32);
2509 IRTemp result = newTemp(Ity_I32);
2510
2511 assign(op2, get_gpr_w0(r2));
2512 assign(op3, get_gpr_w1(r3));
2513 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2514 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
2515 put_gpr_w0(r1, mkexpr(result));
2516
2517 return "ahhlr";
2518}
2519
2520static HChar *
2521s390_irgen_AIH(UChar r1, UInt i2)
2522{
2523 IRTemp op1 = newTemp(Ity_I32);
2524 Int op2;
2525 IRTemp result = newTemp(Ity_I32);
2526
2527 assign(op1, get_gpr_w0(r1));
2528 op2 = (Int)i2;
2529 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
2530 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
2531 mkU32((UInt)op2)));
2532 put_gpr_w0(r1, mkexpr(result));
2533
2534 return "aih";
2535}
2536
2537static HChar *
2538s390_irgen_ALR(UChar r1, UChar r2)
2539{
2540 IRTemp op1 = newTemp(Ity_I32);
2541 IRTemp op2 = newTemp(Ity_I32);
2542 IRTemp result = newTemp(Ity_I32);
2543
2544 assign(op1, get_gpr_w1(r1));
2545 assign(op2, get_gpr_w1(r2));
2546 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2547 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, op2);
2548 put_gpr_w1(r1, mkexpr(result));
2549
2550 return "alr";
2551}
2552
2553static HChar *
2554s390_irgen_ALGR(UChar r1, UChar r2)
2555{
2556 IRTemp op1 = newTemp(Ity_I64);
2557 IRTemp op2 = newTemp(Ity_I64);
2558 IRTemp result = newTemp(Ity_I64);
2559
2560 assign(op1, get_gpr_dw0(r1));
2561 assign(op2, get_gpr_dw0(r2));
2562 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2563 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
2564 put_gpr_dw0(r1, mkexpr(result));
2565
2566 return "algr";
2567}
2568
2569static HChar *
2570s390_irgen_ALGFR(UChar r1, UChar r2)
2571{
2572 IRTemp op1 = newTemp(Ity_I64);
2573 IRTemp op2 = newTemp(Ity_I64);
2574 IRTemp result = newTemp(Ity_I64);
2575
2576 assign(op1, get_gpr_dw0(r1));
2577 assign(op2, unop(Iop_32Uto64, get_gpr_w1(r2)));
2578 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2579 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
2580 put_gpr_dw0(r1, mkexpr(result));
2581
2582 return "algfr";
2583}
2584
2585static HChar *
2586s390_irgen_ALRK(UChar r3, UChar r1, UChar r2)
2587{
2588 IRTemp op2 = newTemp(Ity_I32);
2589 IRTemp op3 = newTemp(Ity_I32);
2590 IRTemp result = newTemp(Ity_I32);
2591
2592 assign(op2, get_gpr_w1(r2));
2593 assign(op3, get_gpr_w1(r3));
2594 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2595 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
2596 put_gpr_w1(r1, mkexpr(result));
2597
2598 return "alrk";
2599}
2600
2601static HChar *
2602s390_irgen_ALGRK(UChar r3, UChar r1, UChar r2)
2603{
2604 IRTemp op2 = newTemp(Ity_I64);
2605 IRTemp op3 = newTemp(Ity_I64);
2606 IRTemp result = newTemp(Ity_I64);
2607
2608 assign(op2, get_gpr_dw0(r2));
2609 assign(op3, get_gpr_dw0(r3));
2610 assign(result, binop(Iop_Add64, mkexpr(op2), mkexpr(op3)));
2611 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op2, op3);
2612 put_gpr_dw0(r1, mkexpr(result));
2613
2614 return "algrk";
2615}
2616
2617static HChar *
2618s390_irgen_AL(UChar r1, IRTemp op2addr)
2619{
2620 IRTemp op1 = newTemp(Ity_I32);
2621 IRTemp op2 = newTemp(Ity_I32);
2622 IRTemp result = newTemp(Ity_I32);
2623
2624 assign(op1, get_gpr_w1(r1));
2625 assign(op2, load(Ity_I32, mkexpr(op2addr)));
2626 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2627 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, op2);
2628 put_gpr_w1(r1, mkexpr(result));
2629
2630 return "al";
2631}
2632
2633static HChar *
2634s390_irgen_ALY(UChar r1, IRTemp op2addr)
2635{
2636 IRTemp op1 = newTemp(Ity_I32);
2637 IRTemp op2 = newTemp(Ity_I32);
2638 IRTemp result = newTemp(Ity_I32);
2639
2640 assign(op1, get_gpr_w1(r1));
2641 assign(op2, load(Ity_I32, mkexpr(op2addr)));
2642 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2643 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, op2);
2644 put_gpr_w1(r1, mkexpr(result));
2645
2646 return "aly";
2647}
2648
2649static HChar *
2650s390_irgen_ALG(UChar r1, IRTemp op2addr)
2651{
2652 IRTemp op1 = newTemp(Ity_I64);
2653 IRTemp op2 = newTemp(Ity_I64);
2654 IRTemp result = newTemp(Ity_I64);
2655
2656 assign(op1, get_gpr_dw0(r1));
2657 assign(op2, load(Ity_I64, mkexpr(op2addr)));
2658 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2659 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
2660 put_gpr_dw0(r1, mkexpr(result));
2661
2662 return "alg";
2663}
2664
2665static HChar *
2666s390_irgen_ALGF(UChar r1, IRTemp op2addr)
2667{
2668 IRTemp op1 = newTemp(Ity_I64);
2669 IRTemp op2 = newTemp(Ity_I64);
2670 IRTemp result = newTemp(Ity_I64);
2671
2672 assign(op1, get_gpr_dw0(r1));
2673 assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
2674 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2675 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
2676 put_gpr_dw0(r1, mkexpr(result));
2677
2678 return "algf";
2679}
2680
2681static HChar *
2682s390_irgen_ALFI(UChar r1, UInt i2)
2683{
2684 IRTemp op1 = newTemp(Ity_I32);
2685 UInt op2;
2686 IRTemp result = newTemp(Ity_I32);
2687
2688 assign(op1, get_gpr_w1(r1));
2689 op2 = i2;
2690 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
2691 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, mktemp(Ity_I32,
2692 mkU32(op2)));
2693 put_gpr_w1(r1, mkexpr(result));
2694
2695 return "alfi";
2696}
2697
2698static HChar *
2699s390_irgen_ALGFI(UChar r1, UInt i2)
2700{
2701 IRTemp op1 = newTemp(Ity_I64);
2702 ULong op2;
2703 IRTemp result = newTemp(Ity_I64);
2704
2705 assign(op1, get_gpr_dw0(r1));
2706 op2 = (ULong)i2;
2707 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64(op2)));
2708 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, mktemp(Ity_I64,
2709 mkU64(op2)));
2710 put_gpr_dw0(r1, mkexpr(result));
2711
2712 return "algfi";
2713}
2714
2715static HChar *
2716s390_irgen_ALHHHR(UChar r3, UChar r1, UChar r2)
2717{
2718 IRTemp op2 = newTemp(Ity_I32);
2719 IRTemp op3 = newTemp(Ity_I32);
2720 IRTemp result = newTemp(Ity_I32);
2721
2722 assign(op2, get_gpr_w0(r2));
2723 assign(op3, get_gpr_w0(r3));
2724 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2725 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
2726 put_gpr_w0(r1, mkexpr(result));
2727
2728 return "alhhhr";
2729}
2730
2731static HChar *
2732s390_irgen_ALHHLR(UChar r3, UChar r1, UChar r2)
2733{
2734 IRTemp op2 = newTemp(Ity_I32);
2735 IRTemp op3 = newTemp(Ity_I32);
2736 IRTemp result = newTemp(Ity_I32);
2737
2738 assign(op2, get_gpr_w0(r2));
2739 assign(op3, get_gpr_w1(r3));
2740 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2741 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
2742 put_gpr_w0(r1, mkexpr(result));
2743
2744 return "alhhlr";
2745}
2746
2747static HChar *
2748s390_irgen_ALCR(UChar r1, UChar r2)
2749{
2750 IRTemp op1 = newTemp(Ity_I32);
2751 IRTemp op2 = newTemp(Ity_I32);
2752 IRTemp result = newTemp(Ity_I32);
2753 IRTemp carry_in = newTemp(Ity_I32);
2754
2755 assign(op1, get_gpr_w1(r1));
2756 assign(op2, get_gpr_w1(r2));
2757 assign(carry_in, binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)));
2758 assign(result, binop(Iop_Add32, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)),
2759 mkexpr(carry_in)));
2760 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_32, op1, op2, carry_in);
2761 put_gpr_w1(r1, mkexpr(result));
2762
2763 return "alcr";
2764}
2765
2766static HChar *
2767s390_irgen_ALCGR(UChar r1, UChar r2)
2768{
2769 IRTemp op1 = newTemp(Ity_I64);
2770 IRTemp op2 = newTemp(Ity_I64);
2771 IRTemp result = newTemp(Ity_I64);
2772 IRTemp carry_in = newTemp(Ity_I64);
2773
2774 assign(op1, get_gpr_dw0(r1));
2775 assign(op2, get_gpr_dw0(r2));
2776 assign(carry_in, unop(Iop_32Uto64, binop(Iop_Shr32, s390_call_calculate_cc(),
2777 mkU8(1))));
2778 assign(result, binop(Iop_Add64, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)),
2779 mkexpr(carry_in)));
2780 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_64, op1, op2, carry_in);
2781 put_gpr_dw0(r1, mkexpr(result));
2782
2783 return "alcgr";
2784}
2785
2786static HChar *
2787s390_irgen_ALC(UChar r1, IRTemp op2addr)
2788{
2789 IRTemp op1 = newTemp(Ity_I32);
2790 IRTemp op2 = newTemp(Ity_I32);
2791 IRTemp result = newTemp(Ity_I32);
2792 IRTemp carry_in = newTemp(Ity_I32);
2793
2794 assign(op1, get_gpr_w1(r1));
2795 assign(op2, load(Ity_I32, mkexpr(op2addr)));
2796 assign(carry_in, binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)));
2797 assign(result, binop(Iop_Add32, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)),
2798 mkexpr(carry_in)));
2799 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_32, op1, op2, carry_in);
2800 put_gpr_w1(r1, mkexpr(result));
2801
2802 return "alc";
2803}
2804
2805static HChar *
2806s390_irgen_ALCG(UChar r1, IRTemp op2addr)
2807{
2808 IRTemp op1 = newTemp(Ity_I64);
2809 IRTemp op2 = newTemp(Ity_I64);
2810 IRTemp result = newTemp(Ity_I64);
2811 IRTemp carry_in = newTemp(Ity_I64);
2812
2813 assign(op1, get_gpr_dw0(r1));
2814 assign(op2, load(Ity_I64, mkexpr(op2addr)));
2815 assign(carry_in, unop(Iop_32Uto64, binop(Iop_Shr32, s390_call_calculate_cc(),
2816 mkU8(1))));
2817 assign(result, binop(Iop_Add64, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)),
2818 mkexpr(carry_in)));
2819 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_64, op1, op2, carry_in);
2820 put_gpr_dw0(r1, mkexpr(result));
2821
2822 return "alcg";
2823}
2824
2825static HChar *
2826s390_irgen_ALSI(UChar i2, IRTemp op1addr)
2827{
2828 IRTemp op1 = newTemp(Ity_I32);
2829 UInt op2;
2830 IRTemp result = newTemp(Ity_I32);
2831
2832 assign(op1, load(Ity_I32, mkexpr(op1addr)));
2833 op2 = (UInt)(Int)(Char)i2;
2834 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
2835 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, mktemp(Ity_I32,
2836 mkU32(op2)));
2837 store(mkexpr(op1addr), mkexpr(result));
2838
2839 return "alsi";
2840}
2841
2842static HChar *
2843s390_irgen_ALGSI(UChar i2, IRTemp op1addr)
2844{
2845 IRTemp op1 = newTemp(Ity_I64);
2846 ULong op2;
2847 IRTemp result = newTemp(Ity_I64);
2848
2849 assign(op1, load(Ity_I64, mkexpr(op1addr)));
2850 op2 = (ULong)(Long)(Char)i2;
2851 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64(op2)));
2852 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, mktemp(Ity_I64,
2853 mkU64(op2)));
2854 store(mkexpr(op1addr), mkexpr(result));
2855
2856 return "algsi";
2857}
2858
2859static HChar *
2860s390_irgen_ALHSIK(UChar r1, UChar r3, UShort i2)
2861{
2862 UInt op2;
2863 IRTemp op3 = newTemp(Ity_I32);
2864 IRTemp result = newTemp(Ity_I32);
2865
2866 op2 = (UInt)(Int)(Short)i2;
2867 assign(op3, get_gpr_w1(r3));
2868 assign(result, binop(Iop_Add32, mkU32(op2), mkexpr(op3)));
2869 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, mktemp(Ity_I32, mkU32(op2)),
2870 op3);
2871 put_gpr_w1(r1, mkexpr(result));
2872
2873 return "alhsik";
2874}
2875
2876static HChar *
2877s390_irgen_ALGHSIK(UChar r1, UChar r3, UShort i2)
2878{
2879 ULong op2;
2880 IRTemp op3 = newTemp(Ity_I64);
2881 IRTemp result = newTemp(Ity_I64);
2882
2883 op2 = (ULong)(Long)(Short)i2;
2884 assign(op3, get_gpr_dw0(r3));
2885 assign(result, binop(Iop_Add64, mkU64(op2), mkexpr(op3)));
2886 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, mktemp(Ity_I64, mkU64(op2)),
2887 op3);
2888 put_gpr_dw0(r1, mkexpr(result));
2889
2890 return "alghsik";
2891}
2892
2893static HChar *
2894s390_irgen_ALSIH(UChar r1, UInt i2)
2895{
2896 IRTemp op1 = newTemp(Ity_I32);
2897 UInt op2;
2898 IRTemp result = newTemp(Ity_I32);
2899
2900 assign(op1, get_gpr_w0(r1));
2901 op2 = i2;
2902 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
2903 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, mktemp(Ity_I32,
2904 mkU32(op2)));
2905 put_gpr_w0(r1, mkexpr(result));
2906
2907 return "alsih";
2908}
2909
2910static HChar *
2911s390_irgen_ALSIHN(UChar r1, UInt i2)
2912{
2913 IRTemp op1 = newTemp(Ity_I32);
2914 UInt op2;
2915 IRTemp result = newTemp(Ity_I32);
2916
2917 assign(op1, get_gpr_w0(r1));
2918 op2 = i2;
2919 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
2920 put_gpr_w0(r1, mkexpr(result));
2921
2922 return "alsihn";
2923}
2924
2925static HChar *
2926s390_irgen_NR(UChar r1, UChar r2)
2927{
2928 IRTemp op1 = newTemp(Ity_I32);
2929 IRTemp op2 = newTemp(Ity_I32);
2930 IRTemp result = newTemp(Ity_I32);
2931
2932 assign(op1, get_gpr_w1(r1));
2933 assign(op2, get_gpr_w1(r2));
2934 assign(result, binop(Iop_And32, mkexpr(op1), mkexpr(op2)));
2935 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
2936 put_gpr_w1(r1, mkexpr(result));
2937
2938 return "nr";
2939}
2940
2941static HChar *
2942s390_irgen_NGR(UChar r1, UChar r2)
2943{
2944 IRTemp op1 = newTemp(Ity_I64);
2945 IRTemp op2 = newTemp(Ity_I64);
2946 IRTemp result = newTemp(Ity_I64);
2947
2948 assign(op1, get_gpr_dw0(r1));
2949 assign(op2, get_gpr_dw0(r2));
2950 assign(result, binop(Iop_And64, mkexpr(op1), mkexpr(op2)));
2951 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
2952 put_gpr_dw0(r1, mkexpr(result));
2953
2954 return "ngr";
2955}
2956
2957static HChar *
2958s390_irgen_NRK(UChar r3, UChar r1, UChar r2)
2959{
2960 IRTemp op2 = newTemp(Ity_I32);
2961 IRTemp op3 = newTemp(Ity_I32);
2962 IRTemp result = newTemp(Ity_I32);
2963
2964 assign(op2, get_gpr_w1(r2));
2965 assign(op3, get_gpr_w1(r3));
2966 assign(result, binop(Iop_And32, mkexpr(op2), mkexpr(op3)));
2967 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
2968 put_gpr_w1(r1, mkexpr(result));
2969
2970 return "nrk";
2971}
2972
2973static HChar *
2974s390_irgen_NGRK(UChar r3, UChar r1, UChar r2)
2975{
2976 IRTemp op2 = newTemp(Ity_I64);
2977 IRTemp op3 = newTemp(Ity_I64);
2978 IRTemp result = newTemp(Ity_I64);
2979
2980 assign(op2, get_gpr_dw0(r2));
2981 assign(op3, get_gpr_dw0(r3));
2982 assign(result, binop(Iop_And64, mkexpr(op2), mkexpr(op3)));
2983 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
2984 put_gpr_dw0(r1, mkexpr(result));
2985
2986 return "ngrk";
2987}
2988
2989static HChar *
2990s390_irgen_N(UChar r1, IRTemp op2addr)
2991{
2992 IRTemp op1 = newTemp(Ity_I32);
2993 IRTemp op2 = newTemp(Ity_I32);
2994 IRTemp result = newTemp(Ity_I32);
2995
2996 assign(op1, get_gpr_w1(r1));
2997 assign(op2, load(Ity_I32, mkexpr(op2addr)));
2998 assign(result, binop(Iop_And32, mkexpr(op1), mkexpr(op2)));
2999 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3000 put_gpr_w1(r1, mkexpr(result));
3001
3002 return "n";
3003}
3004
3005static HChar *
3006s390_irgen_NY(UChar r1, IRTemp op2addr)
3007{
3008 IRTemp op1 = newTemp(Ity_I32);
3009 IRTemp op2 = newTemp(Ity_I32);
3010 IRTemp result = newTemp(Ity_I32);
3011
3012 assign(op1, get_gpr_w1(r1));
3013 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3014 assign(result, binop(Iop_And32, mkexpr(op1), mkexpr(op2)));
3015 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3016 put_gpr_w1(r1, mkexpr(result));
3017
3018 return "ny";
3019}
3020
3021static HChar *
3022s390_irgen_NG(UChar r1, IRTemp op2addr)
3023{
3024 IRTemp op1 = newTemp(Ity_I64);
3025 IRTemp op2 = newTemp(Ity_I64);
3026 IRTemp result = newTemp(Ity_I64);
3027
3028 assign(op1, get_gpr_dw0(r1));
3029 assign(op2, load(Ity_I64, mkexpr(op2addr)));
3030 assign(result, binop(Iop_And64, mkexpr(op1), mkexpr(op2)));
3031 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3032 put_gpr_dw0(r1, mkexpr(result));
3033
3034 return "ng";
3035}
3036
3037static HChar *
3038s390_irgen_NI(UChar i2, IRTemp op1addr)
3039{
3040 IRTemp op1 = newTemp(Ity_I8);
3041 UChar op2;
3042 IRTemp result = newTemp(Ity_I8);
3043
3044 assign(op1, load(Ity_I8, mkexpr(op1addr)));
3045 op2 = i2;
3046 assign(result, binop(Iop_And8, mkexpr(op1), mkU8(op2)));
3047 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3048 store(mkexpr(op1addr), mkexpr(result));
3049
3050 return "ni";
3051}
3052
3053static HChar *
3054s390_irgen_NIY(UChar i2, IRTemp op1addr)
3055{
3056 IRTemp op1 = newTemp(Ity_I8);
3057 UChar op2;
3058 IRTemp result = newTemp(Ity_I8);
3059
3060 assign(op1, load(Ity_I8, mkexpr(op1addr)));
3061 op2 = i2;
3062 assign(result, binop(Iop_And8, mkexpr(op1), mkU8(op2)));
3063 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3064 store(mkexpr(op1addr), mkexpr(result));
3065
3066 return "niy";
3067}
3068
3069static HChar *
3070s390_irgen_NIHF(UChar r1, UInt i2)
3071{
3072 IRTemp op1 = newTemp(Ity_I32);
3073 UInt op2;
3074 IRTemp result = newTemp(Ity_I32);
3075
3076 assign(op1, get_gpr_w0(r1));
3077 op2 = i2;
3078 assign(result, binop(Iop_And32, mkexpr(op1), mkU32(op2)));
3079 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3080 put_gpr_w0(r1, mkexpr(result));
3081
3082 return "nihf";
3083}
3084
3085static HChar *
3086s390_irgen_NIHH(UChar r1, UShort i2)
3087{
3088 IRTemp op1 = newTemp(Ity_I16);
3089 UShort op2;
3090 IRTemp result = newTemp(Ity_I16);
3091
3092 assign(op1, get_gpr_hw0(r1));
3093 op2 = i2;
3094 assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
3095 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3096 put_gpr_hw0(r1, mkexpr(result));
3097
3098 return "nihh";
3099}
3100
3101static HChar *
3102s390_irgen_NIHL(UChar r1, UShort i2)
3103{
3104 IRTemp op1 = newTemp(Ity_I16);
3105 UShort op2;
3106 IRTemp result = newTemp(Ity_I16);
3107
3108 assign(op1, get_gpr_hw1(r1));
3109 op2 = i2;
3110 assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
3111 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3112 put_gpr_hw1(r1, mkexpr(result));
3113
3114 return "nihl";
3115}
3116
3117static HChar *
3118s390_irgen_NILF(UChar r1, UInt i2)
3119{
3120 IRTemp op1 = newTemp(Ity_I32);
3121 UInt op2;
3122 IRTemp result = newTemp(Ity_I32);
3123
3124 assign(op1, get_gpr_w1(r1));
3125 op2 = i2;
3126 assign(result, binop(Iop_And32, mkexpr(op1), mkU32(op2)));
3127 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3128 put_gpr_w1(r1, mkexpr(result));
3129
3130 return "nilf";
3131}
3132
3133static HChar *
3134s390_irgen_NILH(UChar r1, UShort i2)
3135{
3136 IRTemp op1 = newTemp(Ity_I16);
3137 UShort op2;
3138 IRTemp result = newTemp(Ity_I16);
3139
3140 assign(op1, get_gpr_hw2(r1));
3141 op2 = i2;
3142 assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
3143 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3144 put_gpr_hw2(r1, mkexpr(result));
3145
3146 return "nilh";
3147}
3148
3149static HChar *
3150s390_irgen_NILL(UChar r1, UShort i2)
3151{
3152 IRTemp op1 = newTemp(Ity_I16);
3153 UShort op2;
3154 IRTemp result = newTemp(Ity_I16);
3155
3156 assign(op1, get_gpr_hw3(r1));
3157 op2 = i2;
3158 assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
3159 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3160 put_gpr_hw3(r1, mkexpr(result));
3161
3162 return "nill";
3163}
3164
3165static HChar *
3166s390_irgen_BASR(UChar r1, UChar r2)
3167{
3168 IRTemp target = newTemp(Ity_I64);
3169
3170 if (r2 == 0) {
3171 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 2ULL));
3172 } else {
3173 if (r1 != r2) {
3174 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 2ULL));
3175 call_function(get_gpr_dw0(r2));
3176 } else {
3177 assign(target, get_gpr_dw0(r2));
3178 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 2ULL));
3179 call_function(mkexpr(target));
3180 }
3181 }
3182
3183 return "basr";
3184}
3185
3186static HChar *
3187s390_irgen_BAS(UChar r1, IRTemp op2addr)
3188{
3189 IRTemp target = newTemp(Ity_I64);
3190
3191 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 4ULL));
3192 assign(target, mkexpr(op2addr));
3193 call_function(mkexpr(target));
3194
3195 return "bas";
3196}
3197
3198static HChar *
3199s390_irgen_BCR(UChar r1, UChar r2)
3200{
3201 IRTemp cond = newTemp(Ity_I32);
3202
sewardja52e37e2011-04-28 18:48:06 +00003203 if (r2 == 0 && (r1 >= 14)) { /* serialization */
3204 stmt(IRStmt_MBE(Imbe_Fence));
3205 }
3206
sewardj2019a972011-03-07 16:04:07 +00003207 if ((r2 == 0) || (r1 == 0)) {
3208 } else {
3209 if (r1 == 15) {
3210 return_from_function(get_gpr_dw0(r2));
3211 } else {
3212 assign(cond, s390_call_calculate_cond(r1));
florianf321da72012-07-21 20:32:57 +00003213 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3214 get_gpr_dw0(r2));
sewardj2019a972011-03-07 16:04:07 +00003215 }
3216 }
sewardj7ee97522011-05-09 21:45:04 +00003217 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00003218 s390_disasm(ENC2(XMNM, GPR), S390_XMNM_BCR, r1, r2);
3219
3220 return "bcr";
3221}
3222
3223static HChar *
3224s390_irgen_BC(UChar r1, UChar x2, UChar b2, UShort d2, IRTemp op2addr)
3225{
3226 IRTemp cond = newTemp(Ity_I32);
3227
3228 if (r1 == 0) {
3229 } else {
3230 if (r1 == 15) {
3231 always_goto(mkexpr(op2addr));
3232 } else {
3233 assign(cond, s390_call_calculate_cond(r1));
florianf321da72012-07-21 20:32:57 +00003234 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3235 mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003236 }
3237 }
sewardj7ee97522011-05-09 21:45:04 +00003238 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00003239 s390_disasm(ENC2(XMNM, UDXB), S390_XMNM_BC, r1, d2, x2, b2);
3240
3241 return "bc";
3242}
3243
3244static HChar *
3245s390_irgen_BCTR(UChar r1, UChar r2)
3246{
3247 put_gpr_w1(r1, binop(Iop_Sub32, get_gpr_w1(r1), mkU32(1)));
3248 if (r2 != 0) {
florianf321da72012-07-21 20:32:57 +00003249 if_condition_goto_computed(binop(Iop_CmpNE32, get_gpr_w1(r1), mkU32(0)),
3250 get_gpr_dw0(r2));
sewardj2019a972011-03-07 16:04:07 +00003251 }
3252
3253 return "bctr";
3254}
3255
3256static HChar *
3257s390_irgen_BCTGR(UChar r1, UChar r2)
3258{
3259 put_gpr_dw0(r1, binop(Iop_Sub64, get_gpr_dw0(r1), mkU64(1)));
3260 if (r2 != 0) {
florianf321da72012-07-21 20:32:57 +00003261 if_condition_goto_computed(binop(Iop_CmpNE64, get_gpr_dw0(r1), mkU64(0)),
3262 get_gpr_dw0(r2));
sewardj2019a972011-03-07 16:04:07 +00003263 }
3264
3265 return "bctgr";
3266}
3267
3268static HChar *
3269s390_irgen_BCT(UChar r1, IRTemp op2addr)
3270{
3271 put_gpr_w1(r1, binop(Iop_Sub32, get_gpr_w1(r1), mkU32(1)));
florianf321da72012-07-21 20:32:57 +00003272 if_condition_goto_computed(binop(Iop_CmpNE32, get_gpr_w1(r1), mkU32(0)),
3273 mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003274
3275 return "bct";
3276}
3277
3278static HChar *
3279s390_irgen_BCTG(UChar r1, IRTemp op2addr)
3280{
3281 put_gpr_dw0(r1, binop(Iop_Sub64, get_gpr_dw0(r1), mkU64(1)));
florianf321da72012-07-21 20:32:57 +00003282 if_condition_goto_computed(binop(Iop_CmpNE64, get_gpr_dw0(r1), mkU64(0)),
3283 mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003284
3285 return "bctg";
3286}
3287
3288static HChar *
3289s390_irgen_BXH(UChar r1, UChar r3, IRTemp op2addr)
3290{
3291 IRTemp value = newTemp(Ity_I32);
3292
3293 assign(value, get_gpr_w1(r3 | 1));
3294 put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
florianf321da72012-07-21 20:32:57 +00003295 if_condition_goto_computed(binop(Iop_CmpLT32S, mkexpr(value),
3296 get_gpr_w1(r1)), mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003297
3298 return "bxh";
3299}
3300
3301static HChar *
3302s390_irgen_BXHG(UChar r1, UChar r3, IRTemp op2addr)
3303{
3304 IRTemp value = newTemp(Ity_I64);
3305
3306 assign(value, get_gpr_dw0(r3 | 1));
3307 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
florianf321da72012-07-21 20:32:57 +00003308 if_condition_goto_computed(binop(Iop_CmpLT64S, mkexpr(value),
3309 get_gpr_dw0(r1)), mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003310
3311 return "bxhg";
3312}
3313
3314static HChar *
3315s390_irgen_BXLE(UChar r1, UChar r3, IRTemp op2addr)
3316{
3317 IRTemp value = newTemp(Ity_I32);
3318
3319 assign(value, get_gpr_w1(r3 | 1));
3320 put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
florianf321da72012-07-21 20:32:57 +00003321 if_condition_goto_computed(binop(Iop_CmpLE32S, get_gpr_w1(r1),
3322 mkexpr(value)), mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003323
3324 return "bxle";
3325}
3326
3327static HChar *
3328s390_irgen_BXLEG(UChar r1, UChar r3, IRTemp op2addr)
3329{
3330 IRTemp value = newTemp(Ity_I64);
3331
3332 assign(value, get_gpr_dw0(r3 | 1));
3333 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
florianf321da72012-07-21 20:32:57 +00003334 if_condition_goto_computed(binop(Iop_CmpLE64S, get_gpr_dw0(r1),
3335 mkexpr(value)), mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003336
3337 return "bxleg";
3338}
3339
3340static HChar *
3341s390_irgen_BRAS(UChar r1, UShort i2)
3342{
3343 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 4ULL));
floriana64c2432011-07-16 02:11:50 +00003344 call_function_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
sewardj2019a972011-03-07 16:04:07 +00003345
3346 return "bras";
3347}
3348
3349static HChar *
3350s390_irgen_BRASL(UChar r1, UInt i2)
3351{
3352 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 6ULL));
floriana64c2432011-07-16 02:11:50 +00003353 call_function_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1));
sewardj2019a972011-03-07 16:04:07 +00003354
3355 return "brasl";
3356}
3357
3358static HChar *
3359s390_irgen_BRC(UChar r1, UShort i2)
3360{
3361 IRTemp cond = newTemp(Ity_I32);
3362
3363 if (r1 == 0) {
3364 } else {
3365 if (r1 == 15) {
floriana64c2432011-07-16 02:11:50 +00003366 always_goto_and_chase(
3367 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
sewardj2019a972011-03-07 16:04:07 +00003368 } else {
3369 assign(cond, s390_call_calculate_cond(r1));
3370 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3371 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3372
3373 }
3374 }
sewardj7ee97522011-05-09 21:45:04 +00003375 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00003376 s390_disasm(ENC2(XMNM, PCREL), S390_XMNM_BRC, r1, (Int)(Short)i2);
3377
3378 return "brc";
3379}
3380
3381static HChar *
3382s390_irgen_BRCL(UChar r1, UInt i2)
3383{
3384 IRTemp cond = newTemp(Ity_I32);
3385
3386 if (r1 == 0) {
3387 } else {
3388 if (r1 == 15) {
floriana64c2432011-07-16 02:11:50 +00003389 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1));
sewardj2019a972011-03-07 16:04:07 +00003390 } else {
3391 assign(cond, s390_call_calculate_cond(r1));
3392 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3393 guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1));
3394 }
3395 }
sewardj7ee97522011-05-09 21:45:04 +00003396 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00003397 s390_disasm(ENC2(XMNM, PCREL), S390_XMNM_BRCL, r1, i2);
3398
3399 return "brcl";
3400}
3401
3402static HChar *
3403s390_irgen_BRCT(UChar r1, UShort i2)
3404{
3405 put_gpr_w1(r1, binop(Iop_Sub32, get_gpr_w1(r1), mkU32(1)));
3406 if_condition_goto(binop(Iop_CmpNE32, get_gpr_w1(r1), mkU32(0)),
3407 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3408
3409 return "brct";
3410}
3411
3412static HChar *
3413s390_irgen_BRCTG(UChar r1, UShort i2)
3414{
3415 put_gpr_dw0(r1, binop(Iop_Sub64, get_gpr_dw0(r1), mkU64(1)));
3416 if_condition_goto(binop(Iop_CmpNE64, get_gpr_dw0(r1), mkU64(0)),
3417 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3418
3419 return "brctg";
3420}
3421
3422static HChar *
3423s390_irgen_BRXH(UChar r1, UChar r3, UShort i2)
3424{
3425 IRTemp value = newTemp(Ity_I32);
3426
3427 assign(value, get_gpr_w1(r3 | 1));
3428 put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
3429 if_condition_goto(binop(Iop_CmpLT32S, mkexpr(value), get_gpr_w1(r1)),
3430 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3431
3432 return "brxh";
3433}
3434
3435static HChar *
3436s390_irgen_BRXHG(UChar r1, UChar r3, UShort i2)
3437{
3438 IRTemp value = newTemp(Ity_I64);
3439
3440 assign(value, get_gpr_dw0(r3 | 1));
3441 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
3442 if_condition_goto(binop(Iop_CmpLT64S, mkexpr(value), get_gpr_dw0(r1)),
3443 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3444
3445 return "brxhg";
3446}
3447
3448static HChar *
3449s390_irgen_BRXLE(UChar r1, UChar r3, UShort i2)
3450{
3451 IRTemp value = newTemp(Ity_I32);
3452
3453 assign(value, get_gpr_w1(r3 | 1));
3454 put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
3455 if_condition_goto(binop(Iop_CmpLE32S, get_gpr_w1(r1), mkexpr(value)),
3456 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3457
3458 return "brxle";
3459}
3460
3461static HChar *
3462s390_irgen_BRXLG(UChar r1, UChar r3, UShort i2)
3463{
3464 IRTemp value = newTemp(Ity_I64);
3465
3466 assign(value, get_gpr_dw0(r3 | 1));
3467 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
3468 if_condition_goto(binop(Iop_CmpLE64S, get_gpr_dw0(r1), mkexpr(value)),
3469 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3470
3471 return "brxlg";
3472}
3473
3474static HChar *
3475s390_irgen_CR(UChar r1, UChar r2)
3476{
3477 IRTemp op1 = newTemp(Ity_I32);
3478 IRTemp op2 = newTemp(Ity_I32);
3479
3480 assign(op1, get_gpr_w1(r1));
3481 assign(op2, get_gpr_w1(r2));
3482 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3483
3484 return "cr";
3485}
3486
3487static HChar *
3488s390_irgen_CGR(UChar r1, UChar r2)
3489{
3490 IRTemp op1 = newTemp(Ity_I64);
3491 IRTemp op2 = newTemp(Ity_I64);
3492
3493 assign(op1, get_gpr_dw0(r1));
3494 assign(op2, get_gpr_dw0(r2));
3495 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3496
3497 return "cgr";
3498}
3499
3500static HChar *
3501s390_irgen_CGFR(UChar r1, UChar r2)
3502{
3503 IRTemp op1 = newTemp(Ity_I64);
3504 IRTemp op2 = newTemp(Ity_I64);
3505
3506 assign(op1, get_gpr_dw0(r1));
3507 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
3508 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3509
3510 return "cgfr";
3511}
3512
3513static HChar *
3514s390_irgen_C(UChar r1, IRTemp op2addr)
3515{
3516 IRTemp op1 = newTemp(Ity_I32);
3517 IRTemp op2 = newTemp(Ity_I32);
3518
3519 assign(op1, get_gpr_w1(r1));
3520 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3521 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3522
3523 return "c";
3524}
3525
3526static HChar *
3527s390_irgen_CY(UChar r1, IRTemp op2addr)
3528{
3529 IRTemp op1 = newTemp(Ity_I32);
3530 IRTemp op2 = newTemp(Ity_I32);
3531
3532 assign(op1, get_gpr_w1(r1));
3533 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3534 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3535
3536 return "cy";
3537}
3538
3539static HChar *
3540s390_irgen_CG(UChar r1, IRTemp op2addr)
3541{
3542 IRTemp op1 = newTemp(Ity_I64);
3543 IRTemp op2 = newTemp(Ity_I64);
3544
3545 assign(op1, get_gpr_dw0(r1));
3546 assign(op2, load(Ity_I64, mkexpr(op2addr)));
3547 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3548
3549 return "cg";
3550}
3551
3552static HChar *
3553s390_irgen_CGF(UChar r1, IRTemp op2addr)
3554{
3555 IRTemp op1 = newTemp(Ity_I64);
3556 IRTemp op2 = newTemp(Ity_I64);
3557
3558 assign(op1, get_gpr_dw0(r1));
3559 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
3560 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3561
3562 return "cgf";
3563}
3564
3565static HChar *
3566s390_irgen_CFI(UChar r1, UInt i2)
3567{
3568 IRTemp op1 = newTemp(Ity_I32);
3569 Int op2;
3570
3571 assign(op1, get_gpr_w1(r1));
3572 op2 = (Int)i2;
3573 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
3574 mkU32((UInt)op2)));
3575
3576 return "cfi";
3577}
3578
3579static HChar *
3580s390_irgen_CGFI(UChar r1, UInt i2)
3581{
3582 IRTemp op1 = newTemp(Ity_I64);
3583 Long op2;
3584
3585 assign(op1, get_gpr_dw0(r1));
3586 op2 = (Long)(Int)i2;
3587 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I64,
3588 mkU64((ULong)op2)));
3589
3590 return "cgfi";
3591}
3592
3593static HChar *
3594s390_irgen_CRL(UChar r1, UInt i2)
3595{
3596 IRTemp op1 = newTemp(Ity_I32);
3597 IRTemp op2 = newTemp(Ity_I32);
3598
3599 assign(op1, get_gpr_w1(r1));
3600 assign(op2, load(Ity_I32, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
3601 i2 << 1))));
3602 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3603
3604 return "crl";
3605}
3606
3607static HChar *
3608s390_irgen_CGRL(UChar r1, UInt i2)
3609{
3610 IRTemp op1 = newTemp(Ity_I64);
3611 IRTemp op2 = newTemp(Ity_I64);
3612
3613 assign(op1, get_gpr_dw0(r1));
3614 assign(op2, load(Ity_I64, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
3615 i2 << 1))));
3616 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3617
3618 return "cgrl";
3619}
3620
3621static HChar *
3622s390_irgen_CGFRL(UChar r1, UInt i2)
3623{
3624 IRTemp op1 = newTemp(Ity_I64);
3625 IRTemp op2 = newTemp(Ity_I64);
3626
3627 assign(op1, get_gpr_dw0(r1));
3628 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
3629 ((ULong)(Long)(Int)i2 << 1)))));
3630 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3631
3632 return "cgfrl";
3633}
3634
3635static HChar *
3636s390_irgen_CRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
3637{
3638 IRTemp op1 = newTemp(Ity_I32);
3639 IRTemp op2 = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00003640 IRTemp cond = newTemp(Ity_I32);
3641
3642 if (m3 == 0) {
3643 } else {
3644 if (m3 == 14) {
3645 always_goto(mkexpr(op4addr));
3646 } else {
3647 assign(op1, get_gpr_w1(r1));
3648 assign(op2, get_gpr_w1(r2));
florianff9613f2012-05-12 15:26:44 +00003649 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
3650 op1, op2));
florianf321da72012-07-21 20:32:57 +00003651 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond),
3652 mkU32(0)), mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00003653 }
3654 }
3655
3656 return "crb";
3657}
3658
3659static HChar *
3660s390_irgen_CGRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
3661{
3662 IRTemp op1 = newTemp(Ity_I64);
3663 IRTemp op2 = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00003664 IRTemp cond = newTemp(Ity_I32);
3665
3666 if (m3 == 0) {
3667 } else {
3668 if (m3 == 14) {
3669 always_goto(mkexpr(op4addr));
3670 } else {
3671 assign(op1, get_gpr_dw0(r1));
3672 assign(op2, get_gpr_dw0(r2));
florianff9613f2012-05-12 15:26:44 +00003673 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
3674 op1, op2));
florianf321da72012-07-21 20:32:57 +00003675 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond),
3676 mkU32(0)), mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00003677 }
3678 }
3679
3680 return "cgrb";
3681}
3682
3683static HChar *
3684s390_irgen_CRJ(UChar r1, UChar r2, UShort i4, UChar m3)
3685{
3686 IRTemp op1 = newTemp(Ity_I32);
3687 IRTemp op2 = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00003688 IRTemp cond = newTemp(Ity_I32);
3689
3690 if (m3 == 0) {
3691 } else {
3692 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00003693 always_goto_and_chase(
3694 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00003695 } else {
3696 assign(op1, get_gpr_w1(r1));
3697 assign(op2, get_gpr_w1(r2));
florianff9613f2012-05-12 15:26:44 +00003698 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
3699 op1, op2));
sewardj2019a972011-03-07 16:04:07 +00003700 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3701 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
3702
3703 }
3704 }
3705
3706 return "crj";
3707}
3708
3709static HChar *
3710s390_irgen_CGRJ(UChar r1, UChar r2, UShort i4, UChar m3)
3711{
3712 IRTemp op1 = newTemp(Ity_I64);
3713 IRTemp op2 = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00003714 IRTemp cond = newTemp(Ity_I32);
3715
3716 if (m3 == 0) {
3717 } else {
3718 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00003719 always_goto_and_chase(
3720 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00003721 } else {
3722 assign(op1, get_gpr_dw0(r1));
3723 assign(op2, get_gpr_dw0(r2));
florianff9613f2012-05-12 15:26:44 +00003724 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
3725 op1, op2));
sewardj2019a972011-03-07 16:04:07 +00003726 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3727 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
3728
3729 }
3730 }
3731
3732 return "cgrj";
3733}
3734
3735static HChar *
3736s390_irgen_CIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
3737{
3738 IRTemp op1 = newTemp(Ity_I32);
3739 Int op2;
sewardj2019a972011-03-07 16:04:07 +00003740 IRTemp cond = newTemp(Ity_I32);
3741
3742 if (m3 == 0) {
3743 } else {
3744 if (m3 == 14) {
3745 always_goto(mkexpr(op4addr));
3746 } else {
3747 assign(op1, get_gpr_w1(r1));
3748 op2 = (Int)(Char)i2;
florianff9613f2012-05-12 15:26:44 +00003749 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
3750 mktemp(Ity_I32, mkU32((UInt)op2))));
florianf321da72012-07-21 20:32:57 +00003751 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3752 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00003753 }
3754 }
3755
3756 return "cib";
3757}
3758
3759static HChar *
3760s390_irgen_CGIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
3761{
3762 IRTemp op1 = newTemp(Ity_I64);
3763 Long op2;
sewardj2019a972011-03-07 16:04:07 +00003764 IRTemp cond = newTemp(Ity_I32);
3765
3766 if (m3 == 0) {
3767 } else {
3768 if (m3 == 14) {
3769 always_goto(mkexpr(op4addr));
3770 } else {
3771 assign(op1, get_gpr_dw0(r1));
3772 op2 = (Long)(Char)i2;
florianff9613f2012-05-12 15:26:44 +00003773 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
3774 mktemp(Ity_I64, mkU64((ULong)op2))));
florianf321da72012-07-21 20:32:57 +00003775 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3776 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00003777 }
3778 }
3779
3780 return "cgib";
3781}
3782
3783static HChar *
3784s390_irgen_CIJ(UChar r1, UChar m3, UShort i4, UChar i2)
3785{
3786 IRTemp op1 = newTemp(Ity_I32);
3787 Int op2;
sewardj2019a972011-03-07 16:04:07 +00003788 IRTemp cond = newTemp(Ity_I32);
3789
3790 if (m3 == 0) {
3791 } else {
3792 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00003793 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00003794 } else {
3795 assign(op1, get_gpr_w1(r1));
3796 op2 = (Int)(Char)i2;
florianff9613f2012-05-12 15:26:44 +00003797 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
3798 mktemp(Ity_I32, mkU32((UInt)op2))));
sewardj2019a972011-03-07 16:04:07 +00003799 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3800 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
3801
3802 }
3803 }
3804
3805 return "cij";
3806}
3807
3808static HChar *
3809s390_irgen_CGIJ(UChar r1, UChar m3, UShort i4, UChar i2)
3810{
3811 IRTemp op1 = newTemp(Ity_I64);
3812 Long op2;
sewardj2019a972011-03-07 16:04:07 +00003813 IRTemp cond = newTemp(Ity_I32);
3814
3815 if (m3 == 0) {
3816 } else {
3817 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00003818 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00003819 } else {
3820 assign(op1, get_gpr_dw0(r1));
3821 op2 = (Long)(Char)i2;
florianff9613f2012-05-12 15:26:44 +00003822 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
3823 mktemp(Ity_I64, mkU64((ULong)op2))));
sewardj2019a972011-03-07 16:04:07 +00003824 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3825 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
3826
3827 }
3828 }
3829
3830 return "cgij";
3831}
3832
3833static HChar *
3834s390_irgen_CH(UChar r1, IRTemp op2addr)
3835{
3836 IRTemp op1 = newTemp(Ity_I32);
3837 IRTemp op2 = newTemp(Ity_I32);
3838
3839 assign(op1, get_gpr_w1(r1));
3840 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
3841 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3842
3843 return "ch";
3844}
3845
3846static HChar *
3847s390_irgen_CHY(UChar r1, IRTemp op2addr)
3848{
3849 IRTemp op1 = newTemp(Ity_I32);
3850 IRTemp op2 = newTemp(Ity_I32);
3851
3852 assign(op1, get_gpr_w1(r1));
3853 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
3854 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3855
3856 return "chy";
3857}
3858
3859static HChar *
3860s390_irgen_CGH(UChar r1, IRTemp op2addr)
3861{
3862 IRTemp op1 = newTemp(Ity_I64);
3863 IRTemp op2 = newTemp(Ity_I64);
3864
3865 assign(op1, get_gpr_dw0(r1));
3866 assign(op2, unop(Iop_16Sto64, load(Ity_I16, mkexpr(op2addr))));
3867 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3868
3869 return "cgh";
3870}
3871
3872static HChar *
3873s390_irgen_CHI(UChar r1, UShort i2)
3874{
3875 IRTemp op1 = newTemp(Ity_I32);
3876 Int op2;
3877
3878 assign(op1, get_gpr_w1(r1));
3879 op2 = (Int)(Short)i2;
3880 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
3881 mkU32((UInt)op2)));
3882
3883 return "chi";
3884}
3885
3886static HChar *
3887s390_irgen_CGHI(UChar r1, UShort i2)
3888{
3889 IRTemp op1 = newTemp(Ity_I64);
3890 Long op2;
3891
3892 assign(op1, get_gpr_dw0(r1));
3893 op2 = (Long)(Short)i2;
3894 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I64,
3895 mkU64((ULong)op2)));
3896
3897 return "cghi";
3898}
3899
3900static HChar *
3901s390_irgen_CHHSI(UShort i2, IRTemp op1addr)
3902{
3903 IRTemp op1 = newTemp(Ity_I16);
3904 Short op2;
3905
3906 assign(op1, load(Ity_I16, mkexpr(op1addr)));
3907 op2 = (Short)i2;
3908 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I16,
3909 mkU16((UShort)op2)));
3910
3911 return "chhsi";
3912}
3913
3914static HChar *
3915s390_irgen_CHSI(UShort i2, IRTemp op1addr)
3916{
3917 IRTemp op1 = newTemp(Ity_I32);
3918 Int op2;
3919
3920 assign(op1, load(Ity_I32, mkexpr(op1addr)));
3921 op2 = (Int)(Short)i2;
3922 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
3923 mkU32((UInt)op2)));
3924
3925 return "chsi";
3926}
3927
3928static HChar *
3929s390_irgen_CGHSI(UShort i2, IRTemp op1addr)
3930{
3931 IRTemp op1 = newTemp(Ity_I64);
3932 Long op2;
3933
3934 assign(op1, load(Ity_I64, mkexpr(op1addr)));
3935 op2 = (Long)(Short)i2;
3936 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I64,
3937 mkU64((ULong)op2)));
3938
3939 return "cghsi";
3940}
3941
3942static HChar *
3943s390_irgen_CHRL(UChar r1, UInt i2)
3944{
3945 IRTemp op1 = newTemp(Ity_I32);
3946 IRTemp op2 = newTemp(Ity_I32);
3947
3948 assign(op1, get_gpr_w1(r1));
3949 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
3950 ((ULong)(Long)(Int)i2 << 1)))));
3951 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3952
3953 return "chrl";
3954}
3955
3956static HChar *
3957s390_irgen_CGHRL(UChar r1, UInt i2)
3958{
3959 IRTemp op1 = newTemp(Ity_I64);
3960 IRTemp op2 = newTemp(Ity_I64);
3961
3962 assign(op1, get_gpr_dw0(r1));
3963 assign(op2, unop(Iop_16Sto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
3964 ((ULong)(Long)(Int)i2 << 1)))));
3965 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3966
3967 return "cghrl";
3968}
3969
3970static HChar *
3971s390_irgen_CHHR(UChar r1, UChar r2)
3972{
3973 IRTemp op1 = newTemp(Ity_I32);
3974 IRTemp op2 = newTemp(Ity_I32);
3975
3976 assign(op1, get_gpr_w0(r1));
3977 assign(op2, get_gpr_w0(r2));
3978 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3979
3980 return "chhr";
3981}
3982
3983static HChar *
3984s390_irgen_CHLR(UChar r1, UChar r2)
3985{
3986 IRTemp op1 = newTemp(Ity_I32);
3987 IRTemp op2 = newTemp(Ity_I32);
3988
3989 assign(op1, get_gpr_w0(r1));
3990 assign(op2, get_gpr_w1(r2));
3991 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3992
3993 return "chlr";
3994}
3995
3996static HChar *
3997s390_irgen_CHF(UChar r1, IRTemp op2addr)
3998{
3999 IRTemp op1 = newTemp(Ity_I32);
4000 IRTemp op2 = newTemp(Ity_I32);
4001
4002 assign(op1, get_gpr_w0(r1));
4003 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4004 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4005
4006 return "chf";
4007}
4008
4009static HChar *
4010s390_irgen_CIH(UChar r1, UInt i2)
4011{
4012 IRTemp op1 = newTemp(Ity_I32);
4013 Int op2;
4014
4015 assign(op1, get_gpr_w0(r1));
4016 op2 = (Int)i2;
4017 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
4018 mkU32((UInt)op2)));
4019
4020 return "cih";
4021}
4022
4023static HChar *
4024s390_irgen_CLR(UChar r1, UChar r2)
4025{
4026 IRTemp op1 = newTemp(Ity_I32);
4027 IRTemp op2 = newTemp(Ity_I32);
4028
4029 assign(op1, get_gpr_w1(r1));
4030 assign(op2, get_gpr_w1(r2));
4031 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4032
4033 return "clr";
4034}
4035
4036static HChar *
4037s390_irgen_CLGR(UChar r1, UChar r2)
4038{
4039 IRTemp op1 = newTemp(Ity_I64);
4040 IRTemp op2 = newTemp(Ity_I64);
4041
4042 assign(op1, get_gpr_dw0(r1));
4043 assign(op2, get_gpr_dw0(r2));
4044 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4045
4046 return "clgr";
4047}
4048
4049static HChar *
4050s390_irgen_CLGFR(UChar r1, UChar r2)
4051{
4052 IRTemp op1 = newTemp(Ity_I64);
4053 IRTemp op2 = newTemp(Ity_I64);
4054
4055 assign(op1, get_gpr_dw0(r1));
4056 assign(op2, unop(Iop_32Uto64, get_gpr_w1(r2)));
4057 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4058
4059 return "clgfr";
4060}
4061
4062static HChar *
4063s390_irgen_CL(UChar r1, IRTemp op2addr)
4064{
4065 IRTemp op1 = newTemp(Ity_I32);
4066 IRTemp op2 = newTemp(Ity_I32);
4067
4068 assign(op1, get_gpr_w1(r1));
4069 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4070 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4071
4072 return "cl";
4073}
4074
4075static HChar *
4076s390_irgen_CLY(UChar r1, IRTemp op2addr)
4077{
4078 IRTemp op1 = newTemp(Ity_I32);
4079 IRTemp op2 = newTemp(Ity_I32);
4080
4081 assign(op1, get_gpr_w1(r1));
4082 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4083 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4084
4085 return "cly";
4086}
4087
4088static HChar *
4089s390_irgen_CLG(UChar r1, IRTemp op2addr)
4090{
4091 IRTemp op1 = newTemp(Ity_I64);
4092 IRTemp op2 = newTemp(Ity_I64);
4093
4094 assign(op1, get_gpr_dw0(r1));
4095 assign(op2, load(Ity_I64, mkexpr(op2addr)));
4096 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4097
4098 return "clg";
4099}
4100
4101static HChar *
4102s390_irgen_CLGF(UChar r1, IRTemp op2addr)
4103{
4104 IRTemp op1 = newTemp(Ity_I64);
4105 IRTemp op2 = newTemp(Ity_I64);
4106
4107 assign(op1, get_gpr_dw0(r1));
4108 assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
4109 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4110
4111 return "clgf";
4112}
4113
4114static HChar *
4115s390_irgen_CLFI(UChar r1, UInt i2)
4116{
4117 IRTemp op1 = newTemp(Ity_I32);
4118 UInt op2;
4119
4120 assign(op1, get_gpr_w1(r1));
4121 op2 = i2;
4122 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I32,
4123 mkU32(op2)));
4124
4125 return "clfi";
4126}
4127
4128static HChar *
4129s390_irgen_CLGFI(UChar r1, UInt i2)
4130{
4131 IRTemp op1 = newTemp(Ity_I64);
4132 ULong op2;
4133
4134 assign(op1, get_gpr_dw0(r1));
4135 op2 = (ULong)i2;
4136 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I64,
4137 mkU64(op2)));
4138
4139 return "clgfi";
4140}
4141
4142static HChar *
4143s390_irgen_CLI(UChar i2, IRTemp op1addr)
4144{
4145 IRTemp op1 = newTemp(Ity_I8);
4146 UChar op2;
4147
4148 assign(op1, load(Ity_I8, mkexpr(op1addr)));
4149 op2 = i2;
4150 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I8,
4151 mkU8(op2)));
4152
4153 return "cli";
4154}
4155
4156static HChar *
4157s390_irgen_CLIY(UChar i2, IRTemp op1addr)
4158{
4159 IRTemp op1 = newTemp(Ity_I8);
4160 UChar op2;
4161
4162 assign(op1, load(Ity_I8, mkexpr(op1addr)));
4163 op2 = i2;
4164 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I8,
4165 mkU8(op2)));
4166
4167 return "cliy";
4168}
4169
4170static HChar *
4171s390_irgen_CLFHSI(UShort i2, IRTemp op1addr)
4172{
4173 IRTemp op1 = newTemp(Ity_I32);
4174 UInt op2;
4175
4176 assign(op1, load(Ity_I32, mkexpr(op1addr)));
4177 op2 = (UInt)i2;
4178 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I32,
4179 mkU32(op2)));
4180
4181 return "clfhsi";
4182}
4183
4184static HChar *
4185s390_irgen_CLGHSI(UShort i2, IRTemp op1addr)
4186{
4187 IRTemp op1 = newTemp(Ity_I64);
4188 ULong op2;
4189
4190 assign(op1, load(Ity_I64, mkexpr(op1addr)));
4191 op2 = (ULong)i2;
4192 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I64,
4193 mkU64(op2)));
4194
4195 return "clghsi";
4196}
4197
4198static HChar *
4199s390_irgen_CLHHSI(UShort i2, IRTemp op1addr)
4200{
4201 IRTemp op1 = newTemp(Ity_I16);
4202 UShort op2;
4203
4204 assign(op1, load(Ity_I16, mkexpr(op1addr)));
4205 op2 = i2;
4206 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I16,
4207 mkU16(op2)));
4208
4209 return "clhhsi";
4210}
4211
4212static HChar *
4213s390_irgen_CLRL(UChar r1, UInt i2)
4214{
4215 IRTemp op1 = newTemp(Ity_I32);
4216 IRTemp op2 = newTemp(Ity_I32);
4217
4218 assign(op1, get_gpr_w1(r1));
4219 assign(op2, load(Ity_I32, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
4220 i2 << 1))));
4221 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4222
4223 return "clrl";
4224}
4225
4226static HChar *
4227s390_irgen_CLGRL(UChar r1, UInt i2)
4228{
4229 IRTemp op1 = newTemp(Ity_I64);
4230 IRTemp op2 = newTemp(Ity_I64);
4231
4232 assign(op1, get_gpr_dw0(r1));
4233 assign(op2, load(Ity_I64, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
4234 i2 << 1))));
4235 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4236
4237 return "clgrl";
4238}
4239
4240static HChar *
4241s390_irgen_CLGFRL(UChar r1, UInt i2)
4242{
4243 IRTemp op1 = newTemp(Ity_I64);
4244 IRTemp op2 = newTemp(Ity_I64);
4245
4246 assign(op1, get_gpr_dw0(r1));
4247 assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
4248 ((ULong)(Long)(Int)i2 << 1)))));
4249 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4250
4251 return "clgfrl";
4252}
4253
4254static HChar *
4255s390_irgen_CLHRL(UChar r1, UInt i2)
4256{
4257 IRTemp op1 = newTemp(Ity_I32);
4258 IRTemp op2 = newTemp(Ity_I32);
4259
4260 assign(op1, get_gpr_w1(r1));
4261 assign(op2, unop(Iop_16Uto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
4262 ((ULong)(Long)(Int)i2 << 1)))));
4263 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4264
4265 return "clhrl";
4266}
4267
4268static HChar *
4269s390_irgen_CLGHRL(UChar r1, UInt i2)
4270{
4271 IRTemp op1 = newTemp(Ity_I64);
4272 IRTemp op2 = newTemp(Ity_I64);
4273
4274 assign(op1, get_gpr_dw0(r1));
4275 assign(op2, unop(Iop_16Uto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
4276 ((ULong)(Long)(Int)i2 << 1)))));
4277 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4278
4279 return "clghrl";
4280}
4281
4282static HChar *
4283s390_irgen_CLRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
4284{
4285 IRTemp op1 = newTemp(Ity_I32);
4286 IRTemp op2 = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00004287 IRTemp cond = newTemp(Ity_I32);
4288
4289 if (m3 == 0) {
4290 } else {
4291 if (m3 == 14) {
4292 always_goto(mkexpr(op4addr));
4293 } else {
4294 assign(op1, get_gpr_w1(r1));
4295 assign(op2, get_gpr_w1(r2));
florianff9613f2012-05-12 15:26:44 +00004296 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4297 op1, op2));
florianf321da72012-07-21 20:32:57 +00004298 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4299 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004300 }
4301 }
4302
4303 return "clrb";
4304}
4305
4306static HChar *
4307s390_irgen_CLGRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
4308{
4309 IRTemp op1 = newTemp(Ity_I64);
4310 IRTemp op2 = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00004311 IRTemp cond = newTemp(Ity_I32);
4312
4313 if (m3 == 0) {
4314 } else {
4315 if (m3 == 14) {
4316 always_goto(mkexpr(op4addr));
4317 } else {
4318 assign(op1, get_gpr_dw0(r1));
4319 assign(op2, get_gpr_dw0(r2));
florianff9613f2012-05-12 15:26:44 +00004320 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4321 op1, op2));
florianf321da72012-07-21 20:32:57 +00004322 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4323 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004324 }
4325 }
4326
4327 return "clgrb";
4328}
4329
4330static HChar *
4331s390_irgen_CLRJ(UChar r1, UChar r2, UShort i4, UChar m3)
4332{
4333 IRTemp op1 = newTemp(Ity_I32);
4334 IRTemp op2 = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00004335 IRTemp cond = newTemp(Ity_I32);
4336
4337 if (m3 == 0) {
4338 } else {
4339 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004340 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004341 } else {
4342 assign(op1, get_gpr_w1(r1));
4343 assign(op2, get_gpr_w1(r2));
florianff9613f2012-05-12 15:26:44 +00004344 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4345 op1, op2));
sewardj2019a972011-03-07 16:04:07 +00004346 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4347 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4348
4349 }
4350 }
4351
4352 return "clrj";
4353}
4354
4355static HChar *
4356s390_irgen_CLGRJ(UChar r1, UChar r2, UShort i4, UChar m3)
4357{
4358 IRTemp op1 = newTemp(Ity_I64);
4359 IRTemp op2 = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00004360 IRTemp cond = newTemp(Ity_I32);
4361
4362 if (m3 == 0) {
4363 } else {
4364 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004365 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004366 } else {
4367 assign(op1, get_gpr_dw0(r1));
4368 assign(op2, get_gpr_dw0(r2));
florianff9613f2012-05-12 15:26:44 +00004369 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4370 op1, op2));
sewardj2019a972011-03-07 16:04:07 +00004371 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4372 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4373
4374 }
4375 }
4376
4377 return "clgrj";
4378}
4379
4380static HChar *
4381s390_irgen_CLIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
4382{
4383 IRTemp op1 = newTemp(Ity_I32);
4384 UInt op2;
sewardj2019a972011-03-07 16:04:07 +00004385 IRTemp cond = newTemp(Ity_I32);
4386
4387 if (m3 == 0) {
4388 } else {
4389 if (m3 == 14) {
4390 always_goto(mkexpr(op4addr));
4391 } else {
4392 assign(op1, get_gpr_w1(r1));
4393 op2 = (UInt)i2;
florianff9613f2012-05-12 15:26:44 +00004394 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4395 mktemp(Ity_I32, mkU32(op2))));
florianf321da72012-07-21 20:32:57 +00004396 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4397 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004398 }
4399 }
4400
4401 return "clib";
4402}
4403
4404static HChar *
4405s390_irgen_CLGIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
4406{
4407 IRTemp op1 = newTemp(Ity_I64);
4408 ULong op2;
sewardj2019a972011-03-07 16:04:07 +00004409 IRTemp cond = newTemp(Ity_I32);
4410
4411 if (m3 == 0) {
4412 } else {
4413 if (m3 == 14) {
4414 always_goto(mkexpr(op4addr));
4415 } else {
4416 assign(op1, get_gpr_dw0(r1));
4417 op2 = (ULong)i2;
florianff9613f2012-05-12 15:26:44 +00004418 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4419 mktemp(Ity_I64, mkU64(op2))));
florianf321da72012-07-21 20:32:57 +00004420 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4421 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004422 }
4423 }
4424
4425 return "clgib";
4426}
4427
4428static HChar *
4429s390_irgen_CLIJ(UChar r1, UChar m3, UShort i4, UChar i2)
4430{
4431 IRTemp op1 = newTemp(Ity_I32);
4432 UInt op2;
sewardj2019a972011-03-07 16:04:07 +00004433 IRTemp cond = newTemp(Ity_I32);
4434
4435 if (m3 == 0) {
4436 } else {
4437 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004438 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004439 } else {
4440 assign(op1, get_gpr_w1(r1));
4441 op2 = (UInt)i2;
florianff9613f2012-05-12 15:26:44 +00004442 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4443 mktemp(Ity_I32, mkU32(op2))));
sewardj2019a972011-03-07 16:04:07 +00004444 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4445 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4446
4447 }
4448 }
4449
4450 return "clij";
4451}
4452
4453static HChar *
4454s390_irgen_CLGIJ(UChar r1, UChar m3, UShort i4, UChar i2)
4455{
4456 IRTemp op1 = newTemp(Ity_I64);
4457 ULong op2;
sewardj2019a972011-03-07 16:04:07 +00004458 IRTemp cond = newTemp(Ity_I32);
4459
4460 if (m3 == 0) {
4461 } else {
4462 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004463 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004464 } else {
4465 assign(op1, get_gpr_dw0(r1));
4466 op2 = (ULong)i2;
florianff9613f2012-05-12 15:26:44 +00004467 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4468 mktemp(Ity_I64, mkU64(op2))));
sewardj2019a972011-03-07 16:04:07 +00004469 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4470 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4471
4472 }
4473 }
4474
4475 return "clgij";
4476}
4477
4478static HChar *
4479s390_irgen_CLM(UChar r1, UChar r3, IRTemp op2addr)
4480{
4481 IRTemp op1 = newTemp(Ity_I32);
4482 IRTemp op2 = newTemp(Ity_I32);
4483 IRTemp b0 = newTemp(Ity_I32);
4484 IRTemp b1 = newTemp(Ity_I32);
4485 IRTemp b2 = newTemp(Ity_I32);
4486 IRTemp b3 = newTemp(Ity_I32);
4487 IRTemp c0 = newTemp(Ity_I32);
4488 IRTemp c1 = newTemp(Ity_I32);
4489 IRTemp c2 = newTemp(Ity_I32);
4490 IRTemp c3 = newTemp(Ity_I32);
4491 UChar n;
4492
4493 n = 0;
4494 if ((r3 & 8) != 0) {
4495 assign(b0, unop(Iop_8Uto32, get_gpr_b4(r1)));
4496 assign(c0, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
4497 n = n + 1;
4498 } else {
4499 assign(b0, mkU32(0));
4500 assign(c0, mkU32(0));
4501 }
4502 if ((r3 & 4) != 0) {
4503 assign(b1, unop(Iop_8Uto32, get_gpr_b5(r1)));
4504 assign(c1, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4505 mkU64(n)))));
4506 n = n + 1;
4507 } else {
4508 assign(b1, mkU32(0));
4509 assign(c1, mkU32(0));
4510 }
4511 if ((r3 & 2) != 0) {
4512 assign(b2, unop(Iop_8Uto32, get_gpr_b6(r1)));
4513 assign(c2, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4514 mkU64(n)))));
4515 n = n + 1;
4516 } else {
4517 assign(b2, mkU32(0));
4518 assign(c2, mkU32(0));
4519 }
4520 if ((r3 & 1) != 0) {
4521 assign(b3, unop(Iop_8Uto32, get_gpr_b7(r1)));
4522 assign(c3, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4523 mkU64(n)))));
4524 n = n + 1;
4525 } else {
4526 assign(b3, mkU32(0));
4527 assign(c3, mkU32(0));
4528 }
4529 assign(op1, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4530 mkexpr(b0), mkU8(24)), binop(Iop_Shl32, mkexpr(b1), mkU8(16))),
4531 binop(Iop_Shl32, mkexpr(b2), mkU8(8))), mkexpr(b3)));
4532 assign(op2, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4533 mkexpr(c0), mkU8(24)), binop(Iop_Shl32, mkexpr(c1), mkU8(16))),
4534 binop(Iop_Shl32, mkexpr(c2), mkU8(8))), mkexpr(c3)));
4535 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4536
4537 return "clm";
4538}
4539
4540static HChar *
4541s390_irgen_CLMY(UChar r1, UChar r3, IRTemp op2addr)
4542{
4543 IRTemp op1 = newTemp(Ity_I32);
4544 IRTemp op2 = newTemp(Ity_I32);
4545 IRTemp b0 = newTemp(Ity_I32);
4546 IRTemp b1 = newTemp(Ity_I32);
4547 IRTemp b2 = newTemp(Ity_I32);
4548 IRTemp b3 = newTemp(Ity_I32);
4549 IRTemp c0 = newTemp(Ity_I32);
4550 IRTemp c1 = newTemp(Ity_I32);
4551 IRTemp c2 = newTemp(Ity_I32);
4552 IRTemp c3 = newTemp(Ity_I32);
4553 UChar n;
4554
4555 n = 0;
4556 if ((r3 & 8) != 0) {
4557 assign(b0, unop(Iop_8Uto32, get_gpr_b4(r1)));
4558 assign(c0, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
4559 n = n + 1;
4560 } else {
4561 assign(b0, mkU32(0));
4562 assign(c0, mkU32(0));
4563 }
4564 if ((r3 & 4) != 0) {
4565 assign(b1, unop(Iop_8Uto32, get_gpr_b5(r1)));
4566 assign(c1, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4567 mkU64(n)))));
4568 n = n + 1;
4569 } else {
4570 assign(b1, mkU32(0));
4571 assign(c1, mkU32(0));
4572 }
4573 if ((r3 & 2) != 0) {
4574 assign(b2, unop(Iop_8Uto32, get_gpr_b6(r1)));
4575 assign(c2, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4576 mkU64(n)))));
4577 n = n + 1;
4578 } else {
4579 assign(b2, mkU32(0));
4580 assign(c2, mkU32(0));
4581 }
4582 if ((r3 & 1) != 0) {
4583 assign(b3, unop(Iop_8Uto32, get_gpr_b7(r1)));
4584 assign(c3, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4585 mkU64(n)))));
4586 n = n + 1;
4587 } else {
4588 assign(b3, mkU32(0));
4589 assign(c3, mkU32(0));
4590 }
4591 assign(op1, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4592 mkexpr(b0), mkU8(24)), binop(Iop_Shl32, mkexpr(b1), mkU8(16))),
4593 binop(Iop_Shl32, mkexpr(b2), mkU8(8))), mkexpr(b3)));
4594 assign(op2, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4595 mkexpr(c0), mkU8(24)), binop(Iop_Shl32, mkexpr(c1), mkU8(16))),
4596 binop(Iop_Shl32, mkexpr(c2), mkU8(8))), mkexpr(c3)));
4597 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4598
4599 return "clmy";
4600}
4601
4602static HChar *
4603s390_irgen_CLMH(UChar r1, UChar r3, IRTemp op2addr)
4604{
4605 IRTemp op1 = newTemp(Ity_I32);
4606 IRTemp op2 = newTemp(Ity_I32);
4607 IRTemp b0 = newTemp(Ity_I32);
4608 IRTemp b1 = newTemp(Ity_I32);
4609 IRTemp b2 = newTemp(Ity_I32);
4610 IRTemp b3 = newTemp(Ity_I32);
4611 IRTemp c0 = newTemp(Ity_I32);
4612 IRTemp c1 = newTemp(Ity_I32);
4613 IRTemp c2 = newTemp(Ity_I32);
4614 IRTemp c3 = newTemp(Ity_I32);
4615 UChar n;
4616
4617 n = 0;
4618 if ((r3 & 8) != 0) {
4619 assign(b0, unop(Iop_8Uto32, get_gpr_b0(r1)));
4620 assign(c0, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
4621 n = n + 1;
4622 } else {
4623 assign(b0, mkU32(0));
4624 assign(c0, mkU32(0));
4625 }
4626 if ((r3 & 4) != 0) {
4627 assign(b1, unop(Iop_8Uto32, get_gpr_b1(r1)));
4628 assign(c1, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4629 mkU64(n)))));
4630 n = n + 1;
4631 } else {
4632 assign(b1, mkU32(0));
4633 assign(c1, mkU32(0));
4634 }
4635 if ((r3 & 2) != 0) {
4636 assign(b2, unop(Iop_8Uto32, get_gpr_b2(r1)));
4637 assign(c2, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4638 mkU64(n)))));
4639 n = n + 1;
4640 } else {
4641 assign(b2, mkU32(0));
4642 assign(c2, mkU32(0));
4643 }
4644 if ((r3 & 1) != 0) {
4645 assign(b3, unop(Iop_8Uto32, get_gpr_b3(r1)));
4646 assign(c3, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4647 mkU64(n)))));
4648 n = n + 1;
4649 } else {
4650 assign(b3, mkU32(0));
4651 assign(c3, mkU32(0));
4652 }
4653 assign(op1, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4654 mkexpr(b0), mkU8(24)), binop(Iop_Shl32, mkexpr(b1), mkU8(16))),
4655 binop(Iop_Shl32, mkexpr(b2), mkU8(8))), mkexpr(b3)));
4656 assign(op2, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4657 mkexpr(c0), mkU8(24)), binop(Iop_Shl32, mkexpr(c1), mkU8(16))),
4658 binop(Iop_Shl32, mkexpr(c2), mkU8(8))), mkexpr(c3)));
4659 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4660
4661 return "clmh";
4662}
4663
4664static HChar *
4665s390_irgen_CLHHR(UChar r1, UChar r2)
4666{
4667 IRTemp op1 = newTemp(Ity_I32);
4668 IRTemp op2 = newTemp(Ity_I32);
4669
4670 assign(op1, get_gpr_w0(r1));
4671 assign(op2, get_gpr_w0(r2));
4672 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4673
4674 return "clhhr";
4675}
4676
4677static HChar *
4678s390_irgen_CLHLR(UChar r1, UChar r2)
4679{
4680 IRTemp op1 = newTemp(Ity_I32);
4681 IRTemp op2 = newTemp(Ity_I32);
4682
4683 assign(op1, get_gpr_w0(r1));
4684 assign(op2, get_gpr_w1(r2));
4685 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4686
4687 return "clhlr";
4688}
4689
4690static HChar *
4691s390_irgen_CLHF(UChar r1, IRTemp op2addr)
4692{
4693 IRTemp op1 = newTemp(Ity_I32);
4694 IRTemp op2 = newTemp(Ity_I32);
4695
4696 assign(op1, get_gpr_w0(r1));
4697 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4698 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4699
4700 return "clhf";
4701}
4702
4703static HChar *
4704s390_irgen_CLIH(UChar r1, UInt i2)
4705{
4706 IRTemp op1 = newTemp(Ity_I32);
4707 UInt op2;
4708
4709 assign(op1, get_gpr_w0(r1));
4710 op2 = i2;
4711 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I32,
4712 mkU32(op2)));
4713
4714 return "clih";
4715}
4716
4717static HChar *
4718s390_irgen_CPYA(UChar r1, UChar r2)
4719{
4720 put_ar_w0(r1, get_ar_w0(r2));
sewardj7ee97522011-05-09 21:45:04 +00004721 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00004722 s390_disasm(ENC3(MNM, AR, AR), "cpya", r1, r2);
4723
4724 return "cpya";
4725}
4726
4727static HChar *
4728s390_irgen_XR(UChar r1, UChar r2)
4729{
4730 IRTemp op1 = newTemp(Ity_I32);
4731 IRTemp op2 = newTemp(Ity_I32);
4732 IRTemp result = newTemp(Ity_I32);
4733
4734 if (r1 == r2) {
4735 assign(result, mkU32(0));
4736 } else {
4737 assign(op1, get_gpr_w1(r1));
4738 assign(op2, get_gpr_w1(r2));
4739 assign(result, binop(Iop_Xor32, mkexpr(op1), mkexpr(op2)));
4740 }
4741 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4742 put_gpr_w1(r1, mkexpr(result));
4743
4744 return "xr";
4745}
4746
4747static HChar *
4748s390_irgen_XGR(UChar r1, UChar r2)
4749{
4750 IRTemp op1 = newTemp(Ity_I64);
4751 IRTemp op2 = newTemp(Ity_I64);
4752 IRTemp result = newTemp(Ity_I64);
4753
4754 if (r1 == r2) {
4755 assign(result, mkU64(0));
4756 } else {
4757 assign(op1, get_gpr_dw0(r1));
4758 assign(op2, get_gpr_dw0(r2));
4759 assign(result, binop(Iop_Xor64, mkexpr(op1), mkexpr(op2)));
4760 }
4761 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4762 put_gpr_dw0(r1, mkexpr(result));
4763
4764 return "xgr";
4765}
4766
4767static HChar *
4768s390_irgen_XRK(UChar r3, UChar r1, UChar r2)
4769{
4770 IRTemp op2 = newTemp(Ity_I32);
4771 IRTemp op3 = newTemp(Ity_I32);
4772 IRTemp result = newTemp(Ity_I32);
4773
4774 assign(op2, get_gpr_w1(r2));
4775 assign(op3, get_gpr_w1(r3));
4776 assign(result, binop(Iop_Xor32, mkexpr(op2), mkexpr(op3)));
4777 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4778 put_gpr_w1(r1, mkexpr(result));
4779
4780 return "xrk";
4781}
4782
4783static HChar *
4784s390_irgen_XGRK(UChar r3, UChar r1, UChar r2)
4785{
4786 IRTemp op2 = newTemp(Ity_I64);
4787 IRTemp op3 = newTemp(Ity_I64);
4788 IRTemp result = newTemp(Ity_I64);
4789
4790 assign(op2, get_gpr_dw0(r2));
4791 assign(op3, get_gpr_dw0(r3));
4792 assign(result, binop(Iop_Xor64, mkexpr(op2), mkexpr(op3)));
4793 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4794 put_gpr_dw0(r1, mkexpr(result));
4795
4796 return "xgrk";
4797}
4798
4799static HChar *
4800s390_irgen_X(UChar r1, IRTemp op2addr)
4801{
4802 IRTemp op1 = newTemp(Ity_I32);
4803 IRTemp op2 = newTemp(Ity_I32);
4804 IRTemp result = newTemp(Ity_I32);
4805
4806 assign(op1, get_gpr_w1(r1));
4807 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4808 assign(result, binop(Iop_Xor32, mkexpr(op1), mkexpr(op2)));
4809 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4810 put_gpr_w1(r1, mkexpr(result));
4811
4812 return "x";
4813}
4814
4815static HChar *
4816s390_irgen_XY(UChar r1, IRTemp op2addr)
4817{
4818 IRTemp op1 = newTemp(Ity_I32);
4819 IRTemp op2 = newTemp(Ity_I32);
4820 IRTemp result = newTemp(Ity_I32);
4821
4822 assign(op1, get_gpr_w1(r1));
4823 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4824 assign(result, binop(Iop_Xor32, mkexpr(op1), mkexpr(op2)));
4825 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4826 put_gpr_w1(r1, mkexpr(result));
4827
4828 return "xy";
4829}
4830
4831static HChar *
4832s390_irgen_XG(UChar r1, IRTemp op2addr)
4833{
4834 IRTemp op1 = newTemp(Ity_I64);
4835 IRTemp op2 = newTemp(Ity_I64);
4836 IRTemp result = newTemp(Ity_I64);
4837
4838 assign(op1, get_gpr_dw0(r1));
4839 assign(op2, load(Ity_I64, mkexpr(op2addr)));
4840 assign(result, binop(Iop_Xor64, mkexpr(op1), mkexpr(op2)));
4841 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4842 put_gpr_dw0(r1, mkexpr(result));
4843
4844 return "xg";
4845}
4846
4847static HChar *
4848s390_irgen_XI(UChar i2, IRTemp op1addr)
4849{
4850 IRTemp op1 = newTemp(Ity_I8);
4851 UChar op2;
4852 IRTemp result = newTemp(Ity_I8);
4853
4854 assign(op1, load(Ity_I8, mkexpr(op1addr)));
4855 op2 = i2;
4856 assign(result, binop(Iop_Xor8, mkexpr(op1), mkU8(op2)));
4857 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4858 store(mkexpr(op1addr), mkexpr(result));
4859
4860 return "xi";
4861}
4862
4863static HChar *
4864s390_irgen_XIY(UChar i2, IRTemp op1addr)
4865{
4866 IRTemp op1 = newTemp(Ity_I8);
4867 UChar op2;
4868 IRTemp result = newTemp(Ity_I8);
4869
4870 assign(op1, load(Ity_I8, mkexpr(op1addr)));
4871 op2 = i2;
4872 assign(result, binop(Iop_Xor8, mkexpr(op1), mkU8(op2)));
4873 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4874 store(mkexpr(op1addr), mkexpr(result));
4875
4876 return "xiy";
4877}
4878
4879static HChar *
4880s390_irgen_XIHF(UChar r1, UInt i2)
4881{
4882 IRTemp op1 = newTemp(Ity_I32);
4883 UInt op2;
4884 IRTemp result = newTemp(Ity_I32);
4885
4886 assign(op1, get_gpr_w0(r1));
4887 op2 = i2;
4888 assign(result, binop(Iop_Xor32, mkexpr(op1), mkU32(op2)));
4889 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4890 put_gpr_w0(r1, mkexpr(result));
4891
4892 return "xihf";
4893}
4894
4895static HChar *
4896s390_irgen_XILF(UChar r1, UInt i2)
4897{
4898 IRTemp op1 = newTemp(Ity_I32);
4899 UInt op2;
4900 IRTemp result = newTemp(Ity_I32);
4901
4902 assign(op1, get_gpr_w1(r1));
4903 op2 = i2;
4904 assign(result, binop(Iop_Xor32, mkexpr(op1), mkU32(op2)));
4905 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4906 put_gpr_w1(r1, mkexpr(result));
4907
4908 return "xilf";
4909}
4910
4911static HChar *
4912s390_irgen_EAR(UChar r1, UChar r2)
4913{
4914 put_gpr_w1(r1, get_ar_w0(r2));
sewardj7ee97522011-05-09 21:45:04 +00004915 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00004916 s390_disasm(ENC3(MNM, GPR, AR), "ear", r1, r2);
4917
4918 return "ear";
4919}
4920
4921static HChar *
4922s390_irgen_IC(UChar r1, IRTemp op2addr)
4923{
4924 put_gpr_b7(r1, load(Ity_I8, mkexpr(op2addr)));
4925
4926 return "ic";
4927}
4928
4929static HChar *
4930s390_irgen_ICY(UChar r1, IRTemp op2addr)
4931{
4932 put_gpr_b7(r1, load(Ity_I8, mkexpr(op2addr)));
4933
4934 return "icy";
4935}
4936
4937static HChar *
4938s390_irgen_ICM(UChar r1, UChar r3, IRTemp op2addr)
4939{
4940 UChar n;
4941 IRTemp result = newTemp(Ity_I32);
4942 UInt mask;
4943
4944 n = 0;
4945 mask = (UInt)r3;
4946 if ((mask & 8) != 0) {
4947 put_gpr_b4(r1, load(Ity_I8, mkexpr(op2addr)));
4948 n = n + 1;
4949 }
4950 if ((mask & 4) != 0) {
4951 put_gpr_b5(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
4952
4953 n = n + 1;
4954 }
4955 if ((mask & 2) != 0) {
4956 put_gpr_b6(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
4957
4958 n = n + 1;
4959 }
4960 if ((mask & 1) != 0) {
4961 put_gpr_b7(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
4962
4963 n = n + 1;
4964 }
4965 assign(result, get_gpr_w1(r1));
4966 s390_cc_thunk_putZZ(S390_CC_OP_INSERT_CHAR_MASK_32, result, mktemp(Ity_I32,
4967 mkU32(mask)));
4968
4969 return "icm";
4970}
4971
4972static HChar *
4973s390_irgen_ICMY(UChar r1, UChar r3, IRTemp op2addr)
4974{
4975 UChar n;
4976 IRTemp result = newTemp(Ity_I32);
4977 UInt mask;
4978
4979 n = 0;
4980 mask = (UInt)r3;
4981 if ((mask & 8) != 0) {
4982 put_gpr_b4(r1, load(Ity_I8, mkexpr(op2addr)));
4983 n = n + 1;
4984 }
4985 if ((mask & 4) != 0) {
4986 put_gpr_b5(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
4987
4988 n = n + 1;
4989 }
4990 if ((mask & 2) != 0) {
4991 put_gpr_b6(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
4992
4993 n = n + 1;
4994 }
4995 if ((mask & 1) != 0) {
4996 put_gpr_b7(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
4997
4998 n = n + 1;
4999 }
5000 assign(result, get_gpr_w1(r1));
5001 s390_cc_thunk_putZZ(S390_CC_OP_INSERT_CHAR_MASK_32, result, mktemp(Ity_I32,
5002 mkU32(mask)));
5003
5004 return "icmy";
5005}
5006
5007static HChar *
5008s390_irgen_ICMH(UChar r1, UChar r3, IRTemp op2addr)
5009{
5010 UChar n;
5011 IRTemp result = newTemp(Ity_I32);
5012 UInt mask;
5013
5014 n = 0;
5015 mask = (UInt)r3;
5016 if ((mask & 8) != 0) {
5017 put_gpr_b0(r1, load(Ity_I8, mkexpr(op2addr)));
5018 n = n + 1;
5019 }
5020 if ((mask & 4) != 0) {
5021 put_gpr_b1(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5022
5023 n = n + 1;
5024 }
5025 if ((mask & 2) != 0) {
5026 put_gpr_b2(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5027
5028 n = n + 1;
5029 }
5030 if ((mask & 1) != 0) {
5031 put_gpr_b3(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5032
5033 n = n + 1;
5034 }
5035 assign(result, get_gpr_w0(r1));
5036 s390_cc_thunk_putZZ(S390_CC_OP_INSERT_CHAR_MASK_32, result, mktemp(Ity_I32,
5037 mkU32(mask)));
5038
5039 return "icmh";
5040}
5041
5042static HChar *
5043s390_irgen_IIHF(UChar r1, UInt i2)
5044{
5045 put_gpr_w0(r1, mkU32(i2));
5046
5047 return "iihf";
5048}
5049
5050static HChar *
5051s390_irgen_IIHH(UChar r1, UShort i2)
5052{
5053 put_gpr_hw0(r1, mkU16(i2));
5054
5055 return "iihh";
5056}
5057
5058static HChar *
5059s390_irgen_IIHL(UChar r1, UShort i2)
5060{
5061 put_gpr_hw1(r1, mkU16(i2));
5062
5063 return "iihl";
5064}
5065
5066static HChar *
5067s390_irgen_IILF(UChar r1, UInt i2)
5068{
5069 put_gpr_w1(r1, mkU32(i2));
5070
5071 return "iilf";
5072}
5073
5074static HChar *
5075s390_irgen_IILH(UChar r1, UShort i2)
5076{
5077 put_gpr_hw2(r1, mkU16(i2));
5078
5079 return "iilh";
5080}
5081
5082static HChar *
5083s390_irgen_IILL(UChar r1, UShort i2)
5084{
5085 put_gpr_hw3(r1, mkU16(i2));
5086
5087 return "iill";
5088}
5089
5090static HChar *
5091s390_irgen_LR(UChar r1, UChar r2)
5092{
5093 put_gpr_w1(r1, get_gpr_w1(r2));
5094
5095 return "lr";
5096}
5097
5098static HChar *
5099s390_irgen_LGR(UChar r1, UChar r2)
5100{
5101 put_gpr_dw0(r1, get_gpr_dw0(r2));
5102
5103 return "lgr";
5104}
5105
5106static HChar *
5107s390_irgen_LGFR(UChar r1, UChar r2)
5108{
5109 put_gpr_dw0(r1, unop(Iop_32Sto64, get_gpr_w1(r2)));
5110
5111 return "lgfr";
5112}
5113
5114static HChar *
5115s390_irgen_L(UChar r1, IRTemp op2addr)
5116{
5117 put_gpr_w1(r1, load(Ity_I32, mkexpr(op2addr)));
5118
5119 return "l";
5120}
5121
5122static HChar *
5123s390_irgen_LY(UChar r1, IRTemp op2addr)
5124{
5125 put_gpr_w1(r1, load(Ity_I32, mkexpr(op2addr)));
5126
5127 return "ly";
5128}
5129
5130static HChar *
5131s390_irgen_LG(UChar r1, IRTemp op2addr)
5132{
5133 put_gpr_dw0(r1, load(Ity_I64, mkexpr(op2addr)));
5134
5135 return "lg";
5136}
5137
5138static HChar *
5139s390_irgen_LGF(UChar r1, IRTemp op2addr)
5140{
5141 put_gpr_dw0(r1, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
5142
5143 return "lgf";
5144}
5145
5146static HChar *
5147s390_irgen_LGFI(UChar r1, UInt i2)
5148{
5149 put_gpr_dw0(r1, mkU64((ULong)(Long)(Int)i2));
5150
5151 return "lgfi";
5152}
5153
5154static HChar *
5155s390_irgen_LRL(UChar r1, UInt i2)
5156{
5157 put_gpr_w1(r1, load(Ity_I32, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
5158 i2 << 1))));
5159
5160 return "lrl";
5161}
5162
5163static HChar *
5164s390_irgen_LGRL(UChar r1, UInt i2)
5165{
5166 put_gpr_dw0(r1, load(Ity_I64, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
5167 i2 << 1))));
5168
5169 return "lgrl";
5170}
5171
5172static HChar *
5173s390_irgen_LGFRL(UChar r1, UInt i2)
5174{
5175 put_gpr_dw0(r1, unop(Iop_32Sto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
5176 ((ULong)(Long)(Int)i2 << 1)))));
5177
5178 return "lgfrl";
5179}
5180
5181static HChar *
5182s390_irgen_LA(UChar r1, IRTemp op2addr)
5183{
5184 put_gpr_dw0(r1, mkexpr(op2addr));
5185
5186 return "la";
5187}
5188
5189static HChar *
5190s390_irgen_LAY(UChar r1, IRTemp op2addr)
5191{
5192 put_gpr_dw0(r1, mkexpr(op2addr));
5193
5194 return "lay";
5195}
5196
5197static HChar *
5198s390_irgen_LAE(UChar r1, IRTemp op2addr)
5199{
5200 put_gpr_dw0(r1, mkexpr(op2addr));
5201
5202 return "lae";
5203}
5204
5205static HChar *
5206s390_irgen_LAEY(UChar r1, IRTemp op2addr)
5207{
5208 put_gpr_dw0(r1, mkexpr(op2addr));
5209
5210 return "laey";
5211}
5212
5213static HChar *
5214s390_irgen_LARL(UChar r1, UInt i2)
5215{
5216 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)));
5217
5218 return "larl";
5219}
5220
5221static HChar *
5222s390_irgen_LAA(UChar r1, UChar r3, IRTemp op2addr)
5223{
5224 IRTemp op2 = newTemp(Ity_I32);
5225 IRTemp op3 = newTemp(Ity_I32);
5226 IRTemp result = newTemp(Ity_I32);
5227
5228 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5229 assign(op3, get_gpr_w1(r3));
5230 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
5231 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
5232 store(mkexpr(op2addr), mkexpr(result));
5233 put_gpr_w1(r1, mkexpr(op2));
5234
5235 return "laa";
5236}
5237
5238static HChar *
5239s390_irgen_LAAG(UChar r1, UChar r3, IRTemp op2addr)
5240{
5241 IRTemp op2 = newTemp(Ity_I64);
5242 IRTemp op3 = newTemp(Ity_I64);
5243 IRTemp result = newTemp(Ity_I64);
5244
5245 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5246 assign(op3, get_gpr_dw0(r3));
5247 assign(result, binop(Iop_Add64, mkexpr(op2), mkexpr(op3)));
5248 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op2, op3);
5249 store(mkexpr(op2addr), mkexpr(result));
5250 put_gpr_dw0(r1, mkexpr(op2));
5251
5252 return "laag";
5253}
5254
5255static HChar *
5256s390_irgen_LAAL(UChar r1, UChar r3, IRTemp op2addr)
5257{
5258 IRTemp op2 = newTemp(Ity_I32);
5259 IRTemp op3 = newTemp(Ity_I32);
5260 IRTemp result = newTemp(Ity_I32);
5261
5262 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5263 assign(op3, get_gpr_w1(r3));
5264 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
5265 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
5266 store(mkexpr(op2addr), mkexpr(result));
5267 put_gpr_w1(r1, mkexpr(op2));
5268
5269 return "laal";
5270}
5271
5272static HChar *
5273s390_irgen_LAALG(UChar r1, UChar r3, IRTemp op2addr)
5274{
5275 IRTemp op2 = newTemp(Ity_I64);
5276 IRTemp op3 = newTemp(Ity_I64);
5277 IRTemp result = newTemp(Ity_I64);
5278
5279 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5280 assign(op3, get_gpr_dw0(r3));
5281 assign(result, binop(Iop_Add64, mkexpr(op2), mkexpr(op3)));
5282 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op2, op3);
5283 store(mkexpr(op2addr), mkexpr(result));
5284 put_gpr_dw0(r1, mkexpr(op2));
5285
5286 return "laalg";
5287}
5288
5289static HChar *
5290s390_irgen_LAN(UChar r1, UChar r3, IRTemp op2addr)
5291{
5292 IRTemp op2 = newTemp(Ity_I32);
5293 IRTemp op3 = newTemp(Ity_I32);
5294 IRTemp result = newTemp(Ity_I32);
5295
5296 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5297 assign(op3, get_gpr_w1(r3));
5298 assign(result, binop(Iop_And32, mkexpr(op2), mkexpr(op3)));
5299 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5300 store(mkexpr(op2addr), mkexpr(result));
5301 put_gpr_w1(r1, mkexpr(op2));
5302
5303 return "lan";
5304}
5305
5306static HChar *
5307s390_irgen_LANG(UChar r1, UChar r3, IRTemp op2addr)
5308{
5309 IRTemp op2 = newTemp(Ity_I64);
5310 IRTemp op3 = newTemp(Ity_I64);
5311 IRTemp result = newTemp(Ity_I64);
5312
5313 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5314 assign(op3, get_gpr_dw0(r3));
5315 assign(result, binop(Iop_And64, mkexpr(op2), mkexpr(op3)));
5316 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5317 store(mkexpr(op2addr), mkexpr(result));
5318 put_gpr_dw0(r1, mkexpr(op2));
5319
5320 return "lang";
5321}
5322
5323static HChar *
5324s390_irgen_LAX(UChar r1, UChar r3, IRTemp op2addr)
5325{
5326 IRTemp op2 = newTemp(Ity_I32);
5327 IRTemp op3 = newTemp(Ity_I32);
5328 IRTemp result = newTemp(Ity_I32);
5329
5330 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5331 assign(op3, get_gpr_w1(r3));
5332 assign(result, binop(Iop_Xor32, mkexpr(op2), mkexpr(op3)));
5333 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5334 store(mkexpr(op2addr), mkexpr(result));
5335 put_gpr_w1(r1, mkexpr(op2));
5336
5337 return "lax";
5338}
5339
5340static HChar *
5341s390_irgen_LAXG(UChar r1, UChar r3, IRTemp op2addr)
5342{
5343 IRTemp op2 = newTemp(Ity_I64);
5344 IRTemp op3 = newTemp(Ity_I64);
5345 IRTemp result = newTemp(Ity_I64);
5346
5347 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5348 assign(op3, get_gpr_dw0(r3));
5349 assign(result, binop(Iop_Xor64, mkexpr(op2), mkexpr(op3)));
5350 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5351 store(mkexpr(op2addr), mkexpr(result));
5352 put_gpr_dw0(r1, mkexpr(op2));
5353
5354 return "laxg";
5355}
5356
5357static HChar *
5358s390_irgen_LAO(UChar r1, UChar r3, IRTemp op2addr)
5359{
5360 IRTemp op2 = newTemp(Ity_I32);
5361 IRTemp op3 = newTemp(Ity_I32);
5362 IRTemp result = newTemp(Ity_I32);
5363
5364 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5365 assign(op3, get_gpr_w1(r3));
5366 assign(result, binop(Iop_Or32, mkexpr(op2), mkexpr(op3)));
5367 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5368 store(mkexpr(op2addr), mkexpr(result));
5369 put_gpr_w1(r1, mkexpr(op2));
5370
5371 return "lao";
5372}
5373
5374static HChar *
5375s390_irgen_LAOG(UChar r1, UChar r3, IRTemp op2addr)
5376{
5377 IRTemp op2 = newTemp(Ity_I64);
5378 IRTemp op3 = newTemp(Ity_I64);
5379 IRTemp result = newTemp(Ity_I64);
5380
5381 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5382 assign(op3, get_gpr_dw0(r3));
5383 assign(result, binop(Iop_Or64, mkexpr(op2), mkexpr(op3)));
5384 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5385 store(mkexpr(op2addr), mkexpr(result));
5386 put_gpr_dw0(r1, mkexpr(op2));
5387
5388 return "laog";
5389}
5390
5391static HChar *
5392s390_irgen_LTR(UChar r1, UChar r2)
5393{
5394 IRTemp op2 = newTemp(Ity_I32);
5395
5396 assign(op2, get_gpr_w1(r2));
5397 put_gpr_w1(r1, mkexpr(op2));
5398 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5399
5400 return "ltr";
5401}
5402
5403static HChar *
5404s390_irgen_LTGR(UChar r1, UChar r2)
5405{
5406 IRTemp op2 = newTemp(Ity_I64);
5407
5408 assign(op2, get_gpr_dw0(r2));
5409 put_gpr_dw0(r1, mkexpr(op2));
5410 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5411
5412 return "ltgr";
5413}
5414
5415static HChar *
5416s390_irgen_LTGFR(UChar r1, UChar r2)
5417{
5418 IRTemp op2 = newTemp(Ity_I64);
5419
5420 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
5421 put_gpr_dw0(r1, mkexpr(op2));
5422 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5423
5424 return "ltgfr";
5425}
5426
5427static HChar *
5428s390_irgen_LT(UChar r1, IRTemp op2addr)
5429{
5430 IRTemp op2 = newTemp(Ity_I32);
5431
5432 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5433 put_gpr_w1(r1, mkexpr(op2));
5434 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5435
5436 return "lt";
5437}
5438
5439static HChar *
5440s390_irgen_LTG(UChar r1, IRTemp op2addr)
5441{
5442 IRTemp op2 = newTemp(Ity_I64);
5443
5444 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5445 put_gpr_dw0(r1, mkexpr(op2));
5446 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5447
5448 return "ltg";
5449}
5450
5451static HChar *
5452s390_irgen_LTGF(UChar r1, IRTemp op2addr)
5453{
5454 IRTemp op2 = newTemp(Ity_I64);
5455
5456 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
5457 put_gpr_dw0(r1, mkexpr(op2));
5458 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5459
5460 return "ltgf";
5461}
5462
5463static HChar *
5464s390_irgen_LBR(UChar r1, UChar r2)
5465{
5466 put_gpr_w1(r1, unop(Iop_8Sto32, get_gpr_b7(r2)));
5467
5468 return "lbr";
5469}
5470
5471static HChar *
5472s390_irgen_LGBR(UChar r1, UChar r2)
5473{
5474 put_gpr_dw0(r1, unop(Iop_8Sto64, get_gpr_b7(r2)));
5475
5476 return "lgbr";
5477}
5478
5479static HChar *
5480s390_irgen_LB(UChar r1, IRTemp op2addr)
5481{
5482 put_gpr_w1(r1, unop(Iop_8Sto32, load(Ity_I8, mkexpr(op2addr))));
5483
5484 return "lb";
5485}
5486
5487static HChar *
5488s390_irgen_LGB(UChar r1, IRTemp op2addr)
5489{
5490 put_gpr_dw0(r1, unop(Iop_8Sto64, load(Ity_I8, mkexpr(op2addr))));
5491
5492 return "lgb";
5493}
5494
5495static HChar *
5496s390_irgen_LBH(UChar r1, IRTemp op2addr)
5497{
5498 put_gpr_w0(r1, unop(Iop_8Sto32, load(Ity_I8, mkexpr(op2addr))));
5499
5500 return "lbh";
5501}
5502
5503static HChar *
5504s390_irgen_LCR(UChar r1, UChar r2)
5505{
5506 Int op1;
5507 IRTemp op2 = newTemp(Ity_I32);
5508 IRTemp result = newTemp(Ity_I32);
5509
5510 op1 = 0;
5511 assign(op2, get_gpr_w1(r2));
5512 assign(result, binop(Iop_Sub32, mkU32((UInt)op1), mkexpr(op2)));
5513 put_gpr_w1(r1, mkexpr(result));
5514 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, mktemp(Ity_I32, mkU32((UInt)
5515 op1)), op2);
5516
5517 return "lcr";
5518}
5519
5520static HChar *
5521s390_irgen_LCGR(UChar r1, UChar r2)
5522{
5523 Long op1;
5524 IRTemp op2 = newTemp(Ity_I64);
5525 IRTemp result = newTemp(Ity_I64);
5526
5527 op1 = 0ULL;
5528 assign(op2, get_gpr_dw0(r2));
5529 assign(result, binop(Iop_Sub64, mkU64((ULong)op1), mkexpr(op2)));
5530 put_gpr_dw0(r1, mkexpr(result));
5531 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, mktemp(Ity_I64, mkU64((ULong)
5532 op1)), op2);
5533
5534 return "lcgr";
5535}
5536
5537static HChar *
5538s390_irgen_LCGFR(UChar r1, UChar r2)
5539{
5540 Long op1;
5541 IRTemp op2 = newTemp(Ity_I64);
5542 IRTemp result = newTemp(Ity_I64);
5543
5544 op1 = 0ULL;
5545 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
5546 assign(result, binop(Iop_Sub64, mkU64((ULong)op1), mkexpr(op2)));
5547 put_gpr_dw0(r1, mkexpr(result));
5548 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, mktemp(Ity_I64, mkU64((ULong)
5549 op1)), op2);
5550
5551 return "lcgfr";
5552}
5553
5554static HChar *
5555s390_irgen_LHR(UChar r1, UChar r2)
5556{
5557 put_gpr_w1(r1, unop(Iop_16Sto32, get_gpr_hw3(r2)));
5558
5559 return "lhr";
5560}
5561
5562static HChar *
5563s390_irgen_LGHR(UChar r1, UChar r2)
5564{
5565 put_gpr_dw0(r1, unop(Iop_16Sto64, get_gpr_hw3(r2)));
5566
5567 return "lghr";
5568}
5569
5570static HChar *
5571s390_irgen_LH(UChar r1, IRTemp op2addr)
5572{
5573 put_gpr_w1(r1, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
5574
5575 return "lh";
5576}
5577
5578static HChar *
5579s390_irgen_LHY(UChar r1, IRTemp op2addr)
5580{
5581 put_gpr_w1(r1, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
5582
5583 return "lhy";
5584}
5585
5586static HChar *
5587s390_irgen_LGH(UChar r1, IRTemp op2addr)
5588{
5589 put_gpr_dw0(r1, unop(Iop_16Sto64, load(Ity_I16, mkexpr(op2addr))));
5590
5591 return "lgh";
5592}
5593
5594static HChar *
5595s390_irgen_LHI(UChar r1, UShort i2)
5596{
5597 put_gpr_w1(r1, mkU32((UInt)(Int)(Short)i2));
5598
5599 return "lhi";
5600}
5601
5602static HChar *
5603s390_irgen_LGHI(UChar r1, UShort i2)
5604{
5605 put_gpr_dw0(r1, mkU64((ULong)(Long)(Short)i2));
5606
5607 return "lghi";
5608}
5609
5610static HChar *
5611s390_irgen_LHRL(UChar r1, UInt i2)
5612{
5613 put_gpr_w1(r1, unop(Iop_16Sto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
5614 ((ULong)(Long)(Int)i2 << 1)))));
5615
5616 return "lhrl";
5617}
5618
5619static HChar *
5620s390_irgen_LGHRL(UChar r1, UInt i2)
5621{
5622 put_gpr_dw0(r1, unop(Iop_16Sto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
5623 ((ULong)(Long)(Int)i2 << 1)))));
5624
5625 return "lghrl";
5626}
5627
5628static HChar *
5629s390_irgen_LHH(UChar r1, IRTemp op2addr)
5630{
5631 put_gpr_w0(r1, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
5632
5633 return "lhh";
5634}
5635
5636static HChar *
5637s390_irgen_LFH(UChar r1, IRTemp op2addr)
5638{
5639 put_gpr_w0(r1, load(Ity_I32, mkexpr(op2addr)));
5640
5641 return "lfh";
5642}
5643
5644static HChar *
5645s390_irgen_LLGFR(UChar r1, UChar r2)
5646{
5647 put_gpr_dw0(r1, unop(Iop_32Uto64, get_gpr_w1(r2)));
5648
5649 return "llgfr";
5650}
5651
5652static HChar *
5653s390_irgen_LLGF(UChar r1, IRTemp op2addr)
5654{
5655 put_gpr_dw0(r1, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
5656
5657 return "llgf";
5658}
5659
5660static HChar *
5661s390_irgen_LLGFRL(UChar r1, UInt i2)
5662{
5663 put_gpr_dw0(r1, unop(Iop_32Uto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
5664 ((ULong)(Long)(Int)i2 << 1)))));
5665
5666 return "llgfrl";
5667}
5668
5669static HChar *
5670s390_irgen_LLCR(UChar r1, UChar r2)
5671{
5672 put_gpr_w1(r1, unop(Iop_8Uto32, get_gpr_b7(r2)));
5673
5674 return "llcr";
5675}
5676
5677static HChar *
5678s390_irgen_LLGCR(UChar r1, UChar r2)
5679{
5680 put_gpr_dw0(r1, unop(Iop_8Uto64, get_gpr_b7(r2)));
5681
5682 return "llgcr";
5683}
5684
5685static HChar *
5686s390_irgen_LLC(UChar r1, IRTemp op2addr)
5687{
5688 put_gpr_w1(r1, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
5689
5690 return "llc";
5691}
5692
5693static HChar *
5694s390_irgen_LLGC(UChar r1, IRTemp op2addr)
5695{
5696 put_gpr_dw0(r1, unop(Iop_8Uto64, load(Ity_I8, mkexpr(op2addr))));
5697
5698 return "llgc";
5699}
5700
5701static HChar *
5702s390_irgen_LLCH(UChar r1, IRTemp op2addr)
5703{
5704 put_gpr_w0(r1, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
5705
5706 return "llch";
5707}
5708
5709static HChar *
5710s390_irgen_LLHR(UChar r1, UChar r2)
5711{
5712 put_gpr_w1(r1, unop(Iop_16Uto32, get_gpr_hw3(r2)));
5713
5714 return "llhr";
5715}
5716
5717static HChar *
5718s390_irgen_LLGHR(UChar r1, UChar r2)
5719{
5720 put_gpr_dw0(r1, unop(Iop_16Uto64, get_gpr_hw3(r2)));
5721
5722 return "llghr";
5723}
5724
5725static HChar *
5726s390_irgen_LLH(UChar r1, IRTemp op2addr)
5727{
5728 put_gpr_w1(r1, unop(Iop_16Uto32, load(Ity_I16, mkexpr(op2addr))));
5729
5730 return "llh";
5731}
5732
5733static HChar *
5734s390_irgen_LLGH(UChar r1, IRTemp op2addr)
5735{
5736 put_gpr_dw0(r1, unop(Iop_16Uto64, load(Ity_I16, mkexpr(op2addr))));
5737
5738 return "llgh";
5739}
5740
5741static HChar *
5742s390_irgen_LLHRL(UChar r1, UInt i2)
5743{
5744 put_gpr_w1(r1, unop(Iop_16Uto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
5745 ((ULong)(Long)(Int)i2 << 1)))));
5746
5747 return "llhrl";
5748}
5749
5750static HChar *
5751s390_irgen_LLGHRL(UChar r1, UInt i2)
5752{
5753 put_gpr_dw0(r1, unop(Iop_16Uto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
5754 ((ULong)(Long)(Int)i2 << 1)))));
5755
5756 return "llghrl";
5757}
5758
5759static HChar *
5760s390_irgen_LLHH(UChar r1, IRTemp op2addr)
5761{
5762 put_gpr_w0(r1, unop(Iop_16Uto32, load(Ity_I16, mkexpr(op2addr))));
5763
5764 return "llhh";
5765}
5766
5767static HChar *
5768s390_irgen_LLIHF(UChar r1, UInt i2)
5769{
5770 put_gpr_dw0(r1, mkU64(((ULong)i2) << 32));
5771
5772 return "llihf";
5773}
5774
5775static HChar *
5776s390_irgen_LLIHH(UChar r1, UShort i2)
5777{
5778 put_gpr_dw0(r1, mkU64(((ULong)i2) << 48));
5779
5780 return "llihh";
5781}
5782
5783static HChar *
5784s390_irgen_LLIHL(UChar r1, UShort i2)
5785{
5786 put_gpr_dw0(r1, mkU64(((ULong)i2) << 32));
5787
5788 return "llihl";
5789}
5790
5791static HChar *
5792s390_irgen_LLILF(UChar r1, UInt i2)
5793{
5794 put_gpr_dw0(r1, mkU64(i2));
5795
5796 return "llilf";
5797}
5798
5799static HChar *
5800s390_irgen_LLILH(UChar r1, UShort i2)
5801{
5802 put_gpr_dw0(r1, mkU64(((ULong)i2) << 16));
5803
5804 return "llilh";
5805}
5806
5807static HChar *
5808s390_irgen_LLILL(UChar r1, UShort i2)
5809{
5810 put_gpr_dw0(r1, mkU64(i2));
5811
5812 return "llill";
5813}
5814
5815static HChar *
5816s390_irgen_LLGTR(UChar r1, UChar r2)
5817{
5818 put_gpr_dw0(r1, unop(Iop_32Uto64, binop(Iop_And32, get_gpr_w1(r2),
5819 mkU32(2147483647))));
5820
5821 return "llgtr";
5822}
5823
5824static HChar *
5825s390_irgen_LLGT(UChar r1, IRTemp op2addr)
5826{
5827 put_gpr_dw0(r1, unop(Iop_32Uto64, binop(Iop_And32, load(Ity_I32,
5828 mkexpr(op2addr)), mkU32(2147483647))));
5829
5830 return "llgt";
5831}
5832
5833static HChar *
5834s390_irgen_LNR(UChar r1, UChar r2)
5835{
5836 IRTemp op2 = newTemp(Ity_I32);
5837 IRTemp result = newTemp(Ity_I32);
5838
5839 assign(op2, get_gpr_w1(r2));
5840 assign(result, mkite(binop(Iop_CmpLE32S, mkexpr(op2), mkU32(0)), mkexpr(op2),
5841 binop(Iop_Sub32, mkU32(0), mkexpr(op2))));
5842 put_gpr_w1(r1, mkexpr(result));
5843 s390_cc_thunk_putS(S390_CC_OP_BITWISE, result);
5844
5845 return "lnr";
5846}
5847
5848static HChar *
5849s390_irgen_LNGR(UChar r1, UChar r2)
5850{
5851 IRTemp op2 = newTemp(Ity_I64);
5852 IRTemp result = newTemp(Ity_I64);
5853
5854 assign(op2, get_gpr_dw0(r2));
5855 assign(result, mkite(binop(Iop_CmpLE64S, mkexpr(op2), mkU64(0)), mkexpr(op2),
5856 binop(Iop_Sub64, mkU64(0), mkexpr(op2))));
5857 put_gpr_dw0(r1, mkexpr(result));
5858 s390_cc_thunk_putS(S390_CC_OP_BITWISE, result);
5859
5860 return "lngr";
5861}
5862
5863static HChar *
5864s390_irgen_LNGFR(UChar r1, UChar r2 __attribute__((unused)))
5865{
5866 IRTemp op2 = newTemp(Ity_I64);
5867 IRTemp result = newTemp(Ity_I64);
5868
5869 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r1)));
5870 assign(result, mkite(binop(Iop_CmpLE64S, mkexpr(op2), mkU64(0)), mkexpr(op2),
5871 binop(Iop_Sub64, mkU64(0), mkexpr(op2))));
5872 put_gpr_dw0(r1, mkexpr(result));
5873 s390_cc_thunk_putS(S390_CC_OP_BITWISE, result);
5874
5875 return "lngfr";
5876}
5877
5878static HChar *
sewardjd7bde722011-04-05 13:19:33 +00005879s390_irgen_LOCR(UChar m3, UChar r1, UChar r2)
5880{
florian6820ba52012-07-26 02:01:50 +00005881 next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0)));
sewardjd7bde722011-04-05 13:19:33 +00005882 put_gpr_w1(r1, get_gpr_w1(r2));
5883
5884 return "locr";
5885}
5886
5887static HChar *
5888s390_irgen_LOCGR(UChar m3, UChar r1, UChar r2)
5889{
florian6820ba52012-07-26 02:01:50 +00005890 next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0)));
sewardjd7bde722011-04-05 13:19:33 +00005891 put_gpr_dw0(r1, get_gpr_dw0(r2));
5892
5893 return "locgr";
5894}
5895
5896static HChar *
5897s390_irgen_LOC(UChar r1, IRTemp op2addr)
5898{
5899 /* condition is checked in format handler */
5900 put_gpr_w1(r1, load(Ity_I32, mkexpr(op2addr)));
5901
5902 return "loc";
5903}
5904
5905static HChar *
5906s390_irgen_LOCG(UChar r1, IRTemp op2addr)
5907{
5908 /* condition is checked in format handler */
5909 put_gpr_dw0(r1, load(Ity_I64, mkexpr(op2addr)));
5910
5911 return "locg";
5912}
5913
5914static HChar *
sewardj2019a972011-03-07 16:04:07 +00005915s390_irgen_LPQ(UChar r1, IRTemp op2addr)
5916{
5917 put_gpr_dw0(r1, load(Ity_I64, mkexpr(op2addr)));
5918 put_gpr_dw0(r1 + 1, load(Ity_I64, binop(Iop_Add64, mkexpr(op2addr), mkU64(8))
5919 ));
5920
5921 return "lpq";
5922}
5923
5924static HChar *
5925s390_irgen_LPR(UChar r1, UChar r2)
5926{
5927 IRTemp op2 = newTemp(Ity_I32);
5928 IRTemp result = newTemp(Ity_I32);
5929
5930 assign(op2, get_gpr_w1(r2));
5931 assign(result, mkite(binop(Iop_CmpLT32S, mkexpr(op2), mkU32(0)),
5932 binop(Iop_Sub32, mkU32(0), mkexpr(op2)), mkexpr(op2)));
5933 put_gpr_w1(r1, mkexpr(result));
5934 s390_cc_thunk_putS(S390_CC_OP_LOAD_POSITIVE_32, op2);
5935
5936 return "lpr";
5937}
5938
5939static HChar *
5940s390_irgen_LPGR(UChar r1, UChar r2)
5941{
5942 IRTemp op2 = newTemp(Ity_I64);
5943 IRTemp result = newTemp(Ity_I64);
5944
5945 assign(op2, get_gpr_dw0(r2));
5946 assign(result, mkite(binop(Iop_CmpLT64S, mkexpr(op2), mkU64(0)),
5947 binop(Iop_Sub64, mkU64(0), mkexpr(op2)), mkexpr(op2)));
5948 put_gpr_dw0(r1, mkexpr(result));
5949 s390_cc_thunk_putS(S390_CC_OP_LOAD_POSITIVE_64, op2);
5950
5951 return "lpgr";
5952}
5953
5954static HChar *
5955s390_irgen_LPGFR(UChar r1, UChar r2)
5956{
5957 IRTemp op2 = newTemp(Ity_I64);
5958 IRTemp result = newTemp(Ity_I64);
5959
5960 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
5961 assign(result, mkite(binop(Iop_CmpLT64S, mkexpr(op2), mkU64(0)),
5962 binop(Iop_Sub64, mkU64(0), mkexpr(op2)), mkexpr(op2)));
5963 put_gpr_dw0(r1, mkexpr(result));
5964 s390_cc_thunk_putS(S390_CC_OP_LOAD_POSITIVE_64, op2);
5965
5966 return "lpgfr";
5967}
5968
5969static HChar *
5970s390_irgen_LRVR(UChar r1, UChar r2)
5971{
5972 IRTemp b0 = newTemp(Ity_I8);
5973 IRTemp b1 = newTemp(Ity_I8);
5974 IRTemp b2 = newTemp(Ity_I8);
5975 IRTemp b3 = newTemp(Ity_I8);
5976
5977 assign(b3, get_gpr_b7(r2));
5978 assign(b2, get_gpr_b6(r2));
5979 assign(b1, get_gpr_b5(r2));
5980 assign(b0, get_gpr_b4(r2));
5981 put_gpr_b4(r1, mkexpr(b3));
5982 put_gpr_b5(r1, mkexpr(b2));
5983 put_gpr_b6(r1, mkexpr(b1));
5984 put_gpr_b7(r1, mkexpr(b0));
5985
5986 return "lrvr";
5987}
5988
5989static HChar *
5990s390_irgen_LRVGR(UChar r1, UChar r2)
5991{
5992 IRTemp b0 = newTemp(Ity_I8);
5993 IRTemp b1 = newTemp(Ity_I8);
5994 IRTemp b2 = newTemp(Ity_I8);
5995 IRTemp b3 = newTemp(Ity_I8);
5996 IRTemp b4 = newTemp(Ity_I8);
5997 IRTemp b5 = newTemp(Ity_I8);
5998 IRTemp b6 = newTemp(Ity_I8);
5999 IRTemp b7 = newTemp(Ity_I8);
6000
6001 assign(b7, get_gpr_b7(r2));
6002 assign(b6, get_gpr_b6(r2));
6003 assign(b5, get_gpr_b5(r2));
6004 assign(b4, get_gpr_b4(r2));
6005 assign(b3, get_gpr_b3(r2));
6006 assign(b2, get_gpr_b2(r2));
6007 assign(b1, get_gpr_b1(r2));
6008 assign(b0, get_gpr_b0(r2));
6009 put_gpr_b0(r1, mkexpr(b7));
6010 put_gpr_b1(r1, mkexpr(b6));
6011 put_gpr_b2(r1, mkexpr(b5));
6012 put_gpr_b3(r1, mkexpr(b4));
6013 put_gpr_b4(r1, mkexpr(b3));
6014 put_gpr_b5(r1, mkexpr(b2));
6015 put_gpr_b6(r1, mkexpr(b1));
6016 put_gpr_b7(r1, mkexpr(b0));
6017
6018 return "lrvgr";
6019}
6020
6021static HChar *
6022s390_irgen_LRVH(UChar r1, IRTemp op2addr)
6023{
6024 IRTemp op2 = newTemp(Ity_I16);
6025
6026 assign(op2, load(Ity_I16, mkexpr(op2addr)));
6027 put_gpr_b6(r1, unop(Iop_16to8, mkexpr(op2)));
6028 put_gpr_b7(r1, unop(Iop_16HIto8, mkexpr(op2)));
6029
6030 return "lrvh";
6031}
6032
6033static HChar *
6034s390_irgen_LRV(UChar r1, IRTemp op2addr)
6035{
6036 IRTemp op2 = newTemp(Ity_I32);
6037
6038 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6039 put_gpr_b4(r1, unop(Iop_32to8, binop(Iop_And32, mkexpr(op2), mkU32(255))));
6040 put_gpr_b5(r1, unop(Iop_32to8, binop(Iop_And32, binop(Iop_Shr32, mkexpr(op2),
6041 mkU8(8)), mkU32(255))));
6042 put_gpr_b6(r1, unop(Iop_32to8, binop(Iop_And32, binop(Iop_Shr32, mkexpr(op2),
6043 mkU8(16)), mkU32(255))));
6044 put_gpr_b7(r1, unop(Iop_32to8, binop(Iop_And32, binop(Iop_Shr32, mkexpr(op2),
6045 mkU8(24)), mkU32(255))));
6046
6047 return "lrv";
6048}
6049
6050static HChar *
6051s390_irgen_LRVG(UChar r1, IRTemp op2addr)
6052{
6053 IRTemp op2 = newTemp(Ity_I64);
6054
6055 assign(op2, load(Ity_I64, mkexpr(op2addr)));
6056 put_gpr_b0(r1, unop(Iop_64to8, binop(Iop_And64, mkexpr(op2), mkU64(255))));
6057 put_gpr_b1(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6058 mkU8(8)), mkU64(255))));
6059 put_gpr_b2(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6060 mkU8(16)), mkU64(255))));
6061 put_gpr_b3(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6062 mkU8(24)), mkU64(255))));
6063 put_gpr_b4(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6064 mkU8(32)), mkU64(255))));
6065 put_gpr_b5(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6066 mkU8(40)), mkU64(255))));
6067 put_gpr_b6(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6068 mkU8(48)), mkU64(255))));
6069 put_gpr_b7(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6070 mkU8(56)), mkU64(255))));
6071
6072 return "lrvg";
6073}
6074
6075static HChar *
6076s390_irgen_MVHHI(UShort i2, IRTemp op1addr)
6077{
6078 store(mkexpr(op1addr), mkU16(i2));
6079
6080 return "mvhhi";
6081}
6082
6083static HChar *
6084s390_irgen_MVHI(UShort i2, IRTemp op1addr)
6085{
6086 store(mkexpr(op1addr), mkU32((UInt)(Int)(Short)i2));
6087
6088 return "mvhi";
6089}
6090
6091static HChar *
6092s390_irgen_MVGHI(UShort i2, IRTemp op1addr)
6093{
6094 store(mkexpr(op1addr), mkU64((ULong)(Long)(Short)i2));
6095
6096 return "mvghi";
6097}
6098
6099static HChar *
6100s390_irgen_MVI(UChar i2, IRTemp op1addr)
6101{
6102 store(mkexpr(op1addr), mkU8(i2));
6103
6104 return "mvi";
6105}
6106
6107static HChar *
6108s390_irgen_MVIY(UChar i2, IRTemp op1addr)
6109{
6110 store(mkexpr(op1addr), mkU8(i2));
6111
6112 return "mviy";
6113}
6114
6115static HChar *
6116s390_irgen_MR(UChar r1, UChar r2)
6117{
6118 IRTemp op1 = newTemp(Ity_I32);
6119 IRTemp op2 = newTemp(Ity_I32);
6120 IRTemp result = newTemp(Ity_I64);
6121
6122 assign(op1, get_gpr_w1(r1 + 1));
6123 assign(op2, get_gpr_w1(r2));
6124 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6125 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6126 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6127
6128 return "mr";
6129}
6130
6131static HChar *
6132s390_irgen_M(UChar r1, IRTemp op2addr)
6133{
6134 IRTemp op1 = newTemp(Ity_I32);
6135 IRTemp op2 = newTemp(Ity_I32);
6136 IRTemp result = newTemp(Ity_I64);
6137
6138 assign(op1, get_gpr_w1(r1 + 1));
6139 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6140 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6141 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6142 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6143
6144 return "m";
6145}
6146
6147static HChar *
6148s390_irgen_MFY(UChar r1, IRTemp op2addr)
6149{
6150 IRTemp op1 = newTemp(Ity_I32);
6151 IRTemp op2 = newTemp(Ity_I32);
6152 IRTemp result = newTemp(Ity_I64);
6153
6154 assign(op1, get_gpr_w1(r1 + 1));
6155 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6156 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6157 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6158 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6159
6160 return "mfy";
6161}
6162
6163static HChar *
6164s390_irgen_MH(UChar r1, IRTemp op2addr)
6165{
6166 IRTemp op1 = newTemp(Ity_I32);
6167 IRTemp op2 = newTemp(Ity_I16);
6168 IRTemp result = newTemp(Ity_I64);
6169
6170 assign(op1, get_gpr_w1(r1));
6171 assign(op2, load(Ity_I16, mkexpr(op2addr)));
6172 assign(result, binop(Iop_MullS32, mkexpr(op1), unop(Iop_16Sto32, mkexpr(op2))
6173 ));
6174 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6175
6176 return "mh";
6177}
6178
6179static HChar *
6180s390_irgen_MHY(UChar r1, IRTemp op2addr)
6181{
6182 IRTemp op1 = newTemp(Ity_I32);
6183 IRTemp op2 = newTemp(Ity_I16);
6184 IRTemp result = newTemp(Ity_I64);
6185
6186 assign(op1, get_gpr_w1(r1));
6187 assign(op2, load(Ity_I16, mkexpr(op2addr)));
6188 assign(result, binop(Iop_MullS32, mkexpr(op1), unop(Iop_16Sto32, mkexpr(op2))
6189 ));
6190 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6191
6192 return "mhy";
6193}
6194
6195static HChar *
6196s390_irgen_MHI(UChar r1, UShort i2)
6197{
6198 IRTemp op1 = newTemp(Ity_I32);
6199 Short op2;
6200 IRTemp result = newTemp(Ity_I64);
6201
6202 assign(op1, get_gpr_w1(r1));
6203 op2 = (Short)i2;
6204 assign(result, binop(Iop_MullS32, mkexpr(op1), unop(Iop_16Sto32,
6205 mkU16((UShort)op2))));
6206 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6207
6208 return "mhi";
6209}
6210
6211static HChar *
6212s390_irgen_MGHI(UChar r1, UShort i2)
6213{
6214 IRTemp op1 = newTemp(Ity_I64);
6215 Short op2;
6216 IRTemp result = newTemp(Ity_I128);
6217
6218 assign(op1, get_gpr_dw0(r1));
6219 op2 = (Short)i2;
6220 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_16Sto64,
6221 mkU16((UShort)op2))));
6222 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6223
6224 return "mghi";
6225}
6226
6227static HChar *
6228s390_irgen_MLR(UChar r1, UChar r2)
6229{
6230 IRTemp op1 = newTemp(Ity_I32);
6231 IRTemp op2 = newTemp(Ity_I32);
6232 IRTemp result = newTemp(Ity_I64);
6233
6234 assign(op1, get_gpr_w1(r1 + 1));
6235 assign(op2, get_gpr_w1(r2));
6236 assign(result, binop(Iop_MullU32, mkexpr(op1), mkexpr(op2)));
6237 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6238 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6239
6240 return "mlr";
6241}
6242
6243static HChar *
6244s390_irgen_MLGR(UChar r1, UChar r2)
6245{
6246 IRTemp op1 = newTemp(Ity_I64);
6247 IRTemp op2 = newTemp(Ity_I64);
6248 IRTemp result = newTemp(Ity_I128);
6249
6250 assign(op1, get_gpr_dw0(r1 + 1));
6251 assign(op2, get_gpr_dw0(r2));
6252 assign(result, binop(Iop_MullU64, mkexpr(op1), mkexpr(op2)));
6253 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result)));
6254 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result)));
6255
6256 return "mlgr";
6257}
6258
6259static HChar *
6260s390_irgen_ML(UChar r1, IRTemp op2addr)
6261{
6262 IRTemp op1 = newTemp(Ity_I32);
6263 IRTemp op2 = newTemp(Ity_I32);
6264 IRTemp result = newTemp(Ity_I64);
6265
6266 assign(op1, get_gpr_w1(r1 + 1));
6267 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6268 assign(result, binop(Iop_MullU32, mkexpr(op1), mkexpr(op2)));
6269 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6270 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6271
6272 return "ml";
6273}
6274
6275static HChar *
6276s390_irgen_MLG(UChar r1, IRTemp op2addr)
6277{
6278 IRTemp op1 = newTemp(Ity_I64);
6279 IRTemp op2 = newTemp(Ity_I64);
6280 IRTemp result = newTemp(Ity_I128);
6281
6282 assign(op1, get_gpr_dw0(r1 + 1));
6283 assign(op2, load(Ity_I64, mkexpr(op2addr)));
6284 assign(result, binop(Iop_MullU64, mkexpr(op1), mkexpr(op2)));
6285 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result)));
6286 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result)));
6287
6288 return "mlg";
6289}
6290
6291static HChar *
6292s390_irgen_MSR(UChar r1, UChar r2)
6293{
6294 IRTemp op1 = newTemp(Ity_I32);
6295 IRTemp op2 = newTemp(Ity_I32);
6296 IRTemp result = newTemp(Ity_I64);
6297
6298 assign(op1, get_gpr_w1(r1));
6299 assign(op2, get_gpr_w1(r2));
6300 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6301 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6302
6303 return "msr";
6304}
6305
6306static HChar *
6307s390_irgen_MSGR(UChar r1, UChar r2)
6308{
6309 IRTemp op1 = newTemp(Ity_I64);
6310 IRTemp op2 = newTemp(Ity_I64);
6311 IRTemp result = newTemp(Ity_I128);
6312
6313 assign(op1, get_gpr_dw0(r1));
6314 assign(op2, get_gpr_dw0(r2));
6315 assign(result, binop(Iop_MullS64, mkexpr(op1), mkexpr(op2)));
6316 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6317
6318 return "msgr";
6319}
6320
6321static HChar *
6322s390_irgen_MSGFR(UChar r1, UChar r2)
6323{
6324 IRTemp op1 = newTemp(Ity_I64);
6325 IRTemp op2 = newTemp(Ity_I32);
6326 IRTemp result = newTemp(Ity_I128);
6327
6328 assign(op1, get_gpr_dw0(r1));
6329 assign(op2, get_gpr_w1(r2));
6330 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_32Sto64, mkexpr(op2))
6331 ));
6332 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6333
6334 return "msgfr";
6335}
6336
6337static HChar *
6338s390_irgen_MS(UChar r1, IRTemp op2addr)
6339{
6340 IRTemp op1 = newTemp(Ity_I32);
6341 IRTemp op2 = newTemp(Ity_I32);
6342 IRTemp result = newTemp(Ity_I64);
6343
6344 assign(op1, get_gpr_w1(r1));
6345 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6346 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6347 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6348
6349 return "ms";
6350}
6351
6352static HChar *
6353s390_irgen_MSY(UChar r1, IRTemp op2addr)
6354{
6355 IRTemp op1 = newTemp(Ity_I32);
6356 IRTemp op2 = newTemp(Ity_I32);
6357 IRTemp result = newTemp(Ity_I64);
6358
6359 assign(op1, get_gpr_w1(r1));
6360 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6361 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6362 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6363
6364 return "msy";
6365}
6366
6367static HChar *
6368s390_irgen_MSG(UChar r1, IRTemp op2addr)
6369{
6370 IRTemp op1 = newTemp(Ity_I64);
6371 IRTemp op2 = newTemp(Ity_I64);
6372 IRTemp result = newTemp(Ity_I128);
6373
6374 assign(op1, get_gpr_dw0(r1));
6375 assign(op2, load(Ity_I64, mkexpr(op2addr)));
6376 assign(result, binop(Iop_MullS64, mkexpr(op1), mkexpr(op2)));
6377 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6378
6379 return "msg";
6380}
6381
6382static HChar *
6383s390_irgen_MSGF(UChar r1, IRTemp op2addr)
6384{
6385 IRTemp op1 = newTemp(Ity_I64);
6386 IRTemp op2 = newTemp(Ity_I32);
6387 IRTemp result = newTemp(Ity_I128);
6388
6389 assign(op1, get_gpr_dw0(r1));
6390 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6391 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_32Sto64, mkexpr(op2))
6392 ));
6393 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6394
6395 return "msgf";
6396}
6397
6398static HChar *
6399s390_irgen_MSFI(UChar r1, UInt i2)
6400{
6401 IRTemp op1 = newTemp(Ity_I32);
6402 Int op2;
6403 IRTemp result = newTemp(Ity_I64);
6404
6405 assign(op1, get_gpr_w1(r1));
6406 op2 = (Int)i2;
6407 assign(result, binop(Iop_MullS32, mkexpr(op1), mkU32((UInt)op2)));
6408 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6409
6410 return "msfi";
6411}
6412
6413static HChar *
6414s390_irgen_MSGFI(UChar r1, UInt i2)
6415{
6416 IRTemp op1 = newTemp(Ity_I64);
6417 Int op2;
6418 IRTemp result = newTemp(Ity_I128);
6419
6420 assign(op1, get_gpr_dw0(r1));
6421 op2 = (Int)i2;
6422 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_32Sto64, mkU32((UInt)
6423 op2))));
6424 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6425
6426 return "msgfi";
6427}
6428
6429static HChar *
6430s390_irgen_OR(UChar r1, UChar r2)
6431{
6432 IRTemp op1 = newTemp(Ity_I32);
6433 IRTemp op2 = newTemp(Ity_I32);
6434 IRTemp result = newTemp(Ity_I32);
6435
6436 assign(op1, get_gpr_w1(r1));
6437 assign(op2, get_gpr_w1(r2));
6438 assign(result, binop(Iop_Or32, mkexpr(op1), mkexpr(op2)));
6439 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6440 put_gpr_w1(r1, mkexpr(result));
6441
6442 return "or";
6443}
6444
6445static HChar *
6446s390_irgen_OGR(UChar r1, UChar r2)
6447{
6448 IRTemp op1 = newTemp(Ity_I64);
6449 IRTemp op2 = newTemp(Ity_I64);
6450 IRTemp result = newTemp(Ity_I64);
6451
6452 assign(op1, get_gpr_dw0(r1));
6453 assign(op2, get_gpr_dw0(r2));
6454 assign(result, binop(Iop_Or64, mkexpr(op1), mkexpr(op2)));
6455 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6456 put_gpr_dw0(r1, mkexpr(result));
6457
6458 return "ogr";
6459}
6460
6461static HChar *
6462s390_irgen_ORK(UChar r3, UChar r1, UChar r2)
6463{
6464 IRTemp op2 = newTemp(Ity_I32);
6465 IRTemp op3 = newTemp(Ity_I32);
6466 IRTemp result = newTemp(Ity_I32);
6467
6468 assign(op2, get_gpr_w1(r2));
6469 assign(op3, get_gpr_w1(r3));
6470 assign(result, binop(Iop_Or32, mkexpr(op2), mkexpr(op3)));
6471 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6472 put_gpr_w1(r1, mkexpr(result));
6473
6474 return "ork";
6475}
6476
6477static HChar *
6478s390_irgen_OGRK(UChar r3, UChar r1, UChar r2)
6479{
6480 IRTemp op2 = newTemp(Ity_I64);
6481 IRTemp op3 = newTemp(Ity_I64);
6482 IRTemp result = newTemp(Ity_I64);
6483
6484 assign(op2, get_gpr_dw0(r2));
6485 assign(op3, get_gpr_dw0(r3));
6486 assign(result, binop(Iop_Or64, mkexpr(op2), mkexpr(op3)));
6487 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6488 put_gpr_dw0(r1, mkexpr(result));
6489
6490 return "ogrk";
6491}
6492
6493static HChar *
6494s390_irgen_O(UChar r1, IRTemp op2addr)
6495{
6496 IRTemp op1 = newTemp(Ity_I32);
6497 IRTemp op2 = newTemp(Ity_I32);
6498 IRTemp result = newTemp(Ity_I32);
6499
6500 assign(op1, get_gpr_w1(r1));
6501 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6502 assign(result, binop(Iop_Or32, mkexpr(op1), mkexpr(op2)));
6503 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6504 put_gpr_w1(r1, mkexpr(result));
6505
6506 return "o";
6507}
6508
6509static HChar *
6510s390_irgen_OY(UChar r1, IRTemp op2addr)
6511{
6512 IRTemp op1 = newTemp(Ity_I32);
6513 IRTemp op2 = newTemp(Ity_I32);
6514 IRTemp result = newTemp(Ity_I32);
6515
6516 assign(op1, get_gpr_w1(r1));
6517 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6518 assign(result, binop(Iop_Or32, mkexpr(op1), mkexpr(op2)));
6519 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6520 put_gpr_w1(r1, mkexpr(result));
6521
6522 return "oy";
6523}
6524
6525static HChar *
6526s390_irgen_OG(UChar r1, IRTemp op2addr)
6527{
6528 IRTemp op1 = newTemp(Ity_I64);
6529 IRTemp op2 = newTemp(Ity_I64);
6530 IRTemp result = newTemp(Ity_I64);
6531
6532 assign(op1, get_gpr_dw0(r1));
6533 assign(op2, load(Ity_I64, mkexpr(op2addr)));
6534 assign(result, binop(Iop_Or64, mkexpr(op1), mkexpr(op2)));
6535 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6536 put_gpr_dw0(r1, mkexpr(result));
6537
6538 return "og";
6539}
6540
6541static HChar *
6542s390_irgen_OI(UChar i2, IRTemp op1addr)
6543{
6544 IRTemp op1 = newTemp(Ity_I8);
6545 UChar op2;
6546 IRTemp result = newTemp(Ity_I8);
6547
6548 assign(op1, load(Ity_I8, mkexpr(op1addr)));
6549 op2 = i2;
6550 assign(result, binop(Iop_Or8, mkexpr(op1), mkU8(op2)));
6551 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6552 store(mkexpr(op1addr), mkexpr(result));
6553
6554 return "oi";
6555}
6556
6557static HChar *
6558s390_irgen_OIY(UChar i2, IRTemp op1addr)
6559{
6560 IRTemp op1 = newTemp(Ity_I8);
6561 UChar op2;
6562 IRTemp result = newTemp(Ity_I8);
6563
6564 assign(op1, load(Ity_I8, mkexpr(op1addr)));
6565 op2 = i2;
6566 assign(result, binop(Iop_Or8, mkexpr(op1), mkU8(op2)));
6567 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6568 store(mkexpr(op1addr), mkexpr(result));
6569
6570 return "oiy";
6571}
6572
6573static HChar *
6574s390_irgen_OIHF(UChar r1, UInt i2)
6575{
6576 IRTemp op1 = newTemp(Ity_I32);
6577 UInt op2;
6578 IRTemp result = newTemp(Ity_I32);
6579
6580 assign(op1, get_gpr_w0(r1));
6581 op2 = i2;
6582 assign(result, binop(Iop_Or32, mkexpr(op1), mkU32(op2)));
6583 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6584 put_gpr_w0(r1, mkexpr(result));
6585
6586 return "oihf";
6587}
6588
6589static HChar *
6590s390_irgen_OIHH(UChar r1, UShort i2)
6591{
6592 IRTemp op1 = newTemp(Ity_I16);
6593 UShort op2;
6594 IRTemp result = newTemp(Ity_I16);
6595
6596 assign(op1, get_gpr_hw0(r1));
6597 op2 = i2;
6598 assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
6599 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6600 put_gpr_hw0(r1, mkexpr(result));
6601
6602 return "oihh";
6603}
6604
6605static HChar *
6606s390_irgen_OIHL(UChar r1, UShort i2)
6607{
6608 IRTemp op1 = newTemp(Ity_I16);
6609 UShort op2;
6610 IRTemp result = newTemp(Ity_I16);
6611
6612 assign(op1, get_gpr_hw1(r1));
6613 op2 = i2;
6614 assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
6615 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6616 put_gpr_hw1(r1, mkexpr(result));
6617
6618 return "oihl";
6619}
6620
6621static HChar *
6622s390_irgen_OILF(UChar r1, UInt i2)
6623{
6624 IRTemp op1 = newTemp(Ity_I32);
6625 UInt op2;
6626 IRTemp result = newTemp(Ity_I32);
6627
6628 assign(op1, get_gpr_w1(r1));
6629 op2 = i2;
6630 assign(result, binop(Iop_Or32, mkexpr(op1), mkU32(op2)));
6631 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6632 put_gpr_w1(r1, mkexpr(result));
6633
6634 return "oilf";
6635}
6636
6637static HChar *
6638s390_irgen_OILH(UChar r1, UShort i2)
6639{
6640 IRTemp op1 = newTemp(Ity_I16);
6641 UShort op2;
6642 IRTemp result = newTemp(Ity_I16);
6643
6644 assign(op1, get_gpr_hw2(r1));
6645 op2 = i2;
6646 assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
6647 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6648 put_gpr_hw2(r1, mkexpr(result));
6649
6650 return "oilh";
6651}
6652
6653static HChar *
6654s390_irgen_OILL(UChar r1, UShort i2)
6655{
6656 IRTemp op1 = newTemp(Ity_I16);
6657 UShort op2;
6658 IRTemp result = newTemp(Ity_I16);
6659
6660 assign(op1, get_gpr_hw3(r1));
6661 op2 = i2;
6662 assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
6663 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6664 put_gpr_hw3(r1, mkexpr(result));
6665
6666 return "oill";
6667}
6668
6669static HChar *
6670s390_irgen_PFD(void)
6671{
6672
6673 return "pfd";
6674}
6675
6676static HChar *
6677s390_irgen_PFDRL(void)
6678{
6679
6680 return "pfdrl";
6681}
6682
6683static HChar *
6684s390_irgen_RLL(UChar r1, UChar r3, IRTemp op2addr)
6685{
6686 IRTemp amount = newTemp(Ity_I64);
6687 IRTemp op = newTemp(Ity_I32);
6688
6689 assign(amount, binop(Iop_And64, mkexpr(op2addr), mkU64(31)));
6690 assign(op, get_gpr_w1(r3));
6691 put_gpr_w1(r1, binop(Iop_Or32, binop(Iop_Shl32, mkexpr(op), unop(Iop_64to8,
6692 mkexpr(amount))), binop(Iop_Shr32, mkexpr(op), unop(Iop_64to8,
6693 binop(Iop_Sub64, mkU64(32), mkexpr(amount))))));
6694
6695 return "rll";
6696}
6697
6698static HChar *
6699s390_irgen_RLLG(UChar r1, UChar r3, IRTemp op2addr)
6700{
6701 IRTemp amount = newTemp(Ity_I64);
6702 IRTemp op = newTemp(Ity_I64);
6703
6704 assign(amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
6705 assign(op, get_gpr_dw0(r3));
6706 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(op), unop(Iop_64to8,
6707 mkexpr(amount))), binop(Iop_Shr64, mkexpr(op), unop(Iop_64to8,
6708 binop(Iop_Sub64, mkU64(64), mkexpr(amount))))));
6709
6710 return "rllg";
6711}
6712
6713static HChar *
6714s390_irgen_RNSBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
6715{
6716 UChar from;
6717 UChar to;
6718 UChar rot;
6719 UChar t_bit;
6720 ULong mask;
6721 ULong maskc;
6722 IRTemp result = newTemp(Ity_I64);
6723 IRTemp op2 = newTemp(Ity_I64);
6724
6725 from = i3 & 63;
6726 to = i4 & 63;
6727 rot = i5 & 63;
6728 t_bit = i3 & 128;
6729 assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
6730 get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
6731 mkU8(64 - rot))));
6732 if (from <= to) {
6733 mask = ~0ULL;
6734 mask = (mask >> from) & (mask << (63 - to));
6735 maskc = ~mask;
6736 } else {
6737 maskc = ~0ULL;
6738 maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
6739 mask = ~maskc;
6740 }
6741 assign(result, binop(Iop_And64, binop(Iop_And64, get_gpr_dw0(r1), mkexpr(op2)
6742 ), mkU64(mask)));
6743 if (t_bit == 0) {
6744 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
6745 mkU64(maskc)), mkexpr(result)));
6746 }
6747 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6748
6749 return "rnsbg";
6750}
6751
6752static HChar *
6753s390_irgen_RXSBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
6754{
6755 UChar from;
6756 UChar to;
6757 UChar rot;
6758 UChar t_bit;
6759 ULong mask;
6760 ULong maskc;
6761 IRTemp result = newTemp(Ity_I64);
6762 IRTemp op2 = newTemp(Ity_I64);
6763
6764 from = i3 & 63;
6765 to = i4 & 63;
6766 rot = i5 & 63;
6767 t_bit = i3 & 128;
6768 assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
6769 get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
6770 mkU8(64 - rot))));
6771 if (from <= to) {
6772 mask = ~0ULL;
6773 mask = (mask >> from) & (mask << (63 - to));
6774 maskc = ~mask;
6775 } else {
6776 maskc = ~0ULL;
6777 maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
6778 mask = ~maskc;
6779 }
6780 assign(result, binop(Iop_And64, binop(Iop_Xor64, get_gpr_dw0(r1), mkexpr(op2)
6781 ), mkU64(mask)));
6782 if (t_bit == 0) {
6783 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
6784 mkU64(maskc)), mkexpr(result)));
6785 }
6786 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6787
6788 return "rxsbg";
6789}
6790
6791static HChar *
6792s390_irgen_ROSBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
6793{
6794 UChar from;
6795 UChar to;
6796 UChar rot;
6797 UChar t_bit;
6798 ULong mask;
6799 ULong maskc;
6800 IRTemp result = newTemp(Ity_I64);
6801 IRTemp op2 = newTemp(Ity_I64);
6802
6803 from = i3 & 63;
6804 to = i4 & 63;
6805 rot = i5 & 63;
6806 t_bit = i3 & 128;
6807 assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
6808 get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
6809 mkU8(64 - rot))));
6810 if (from <= to) {
6811 mask = ~0ULL;
6812 mask = (mask >> from) & (mask << (63 - to));
6813 maskc = ~mask;
6814 } else {
6815 maskc = ~0ULL;
6816 maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
6817 mask = ~maskc;
6818 }
6819 assign(result, binop(Iop_And64, binop(Iop_Or64, get_gpr_dw0(r1), mkexpr(op2)
6820 ), mkU64(mask)));
6821 if (t_bit == 0) {
6822 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
6823 mkU64(maskc)), mkexpr(result)));
6824 }
6825 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6826
6827 return "rosbg";
6828}
6829
6830static HChar *
6831s390_irgen_RISBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
6832{
6833 UChar from;
6834 UChar to;
6835 UChar rot;
6836 UChar z_bit;
6837 ULong mask;
6838 ULong maskc;
6839 IRTemp op2 = newTemp(Ity_I64);
6840 IRTemp result = newTemp(Ity_I64);
6841
6842 from = i3 & 63;
6843 to = i4 & 63;
6844 rot = i5 & 63;
6845 z_bit = i4 & 128;
6846 assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
6847 get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
6848 mkU8(64 - rot))));
6849 if (from <= to) {
6850 mask = ~0ULL;
6851 mask = (mask >> from) & (mask << (63 - to));
6852 maskc = ~mask;
6853 } else {
6854 maskc = ~0ULL;
6855 maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
6856 mask = ~maskc;
6857 }
6858 if (z_bit == 0) {
6859 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
6860 mkU64(maskc)), binop(Iop_And64, mkexpr(op2), mkU64(mask))));
6861 } else {
6862 put_gpr_dw0(r1, binop(Iop_And64, mkexpr(op2), mkU64(mask)));
6863 }
6864 assign(result, get_gpr_dw0(r1));
6865 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
6866
6867 return "risbg";
6868}
6869
6870static HChar *
6871s390_irgen_SAR(UChar r1, UChar r2)
6872{
6873 put_ar_w0(r1, get_gpr_w1(r2));
sewardj7ee97522011-05-09 21:45:04 +00006874 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00006875 s390_disasm(ENC3(MNM, AR, GPR), "sar", r1, r2);
6876
6877 return "sar";
6878}
6879
6880static HChar *
6881s390_irgen_SLDA(UChar r1, IRTemp op2addr)
6882{
6883 IRTemp p1 = newTemp(Ity_I64);
6884 IRTemp p2 = newTemp(Ity_I64);
6885 IRTemp op = newTemp(Ity_I64);
6886 IRTemp result = newTemp(Ity_I64);
florian417b22d2012-07-13 13:41:41 +00006887 ULong sign_mask;
sewardj2019a972011-03-07 16:04:07 +00006888 IRTemp shift_amount = newTemp(Ity_I64);
6889
6890 assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
6891 assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
6892 assign(op, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1), mkU8(32)), mkexpr(p2)
6893 ));
6894 sign_mask = 1ULL << 63;
6895 assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
6896 assign(result, binop(Iop_Or64, binop(Iop_And64, binop(Iop_Shl64, mkexpr(op),
florian417b22d2012-07-13 13:41:41 +00006897 unop(Iop_64to8, mkexpr(shift_amount))), mkU64(~sign_mask)),
6898 binop(Iop_And64, mkexpr(op), mkU64(sign_mask))));
sewardj2019a972011-03-07 16:04:07 +00006899 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6900 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6901 s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_64, op, shift_amount);
6902
6903 return "slda";
6904}
6905
6906static HChar *
6907s390_irgen_SLDL(UChar r1, IRTemp op2addr)
6908{
6909 IRTemp p1 = newTemp(Ity_I64);
6910 IRTemp p2 = newTemp(Ity_I64);
6911 IRTemp result = newTemp(Ity_I64);
6912
6913 assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
6914 assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
6915 assign(result, binop(Iop_Shl64, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1),
6916 mkU8(32)), mkexpr(p2)), unop(Iop_64to8, binop(Iop_And64,
6917 mkexpr(op2addr), mkU64(63)))));
6918 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6919 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6920
6921 return "sldl";
6922}
6923
6924static HChar *
6925s390_irgen_SLA(UChar r1, IRTemp op2addr)
6926{
6927 IRTemp uop = newTemp(Ity_I32);
6928 IRTemp result = newTemp(Ity_I32);
6929 UInt sign_mask;
6930 IRTemp shift_amount = newTemp(Ity_I64);
6931 IRTemp op = newTemp(Ity_I32);
6932
6933 assign(op, get_gpr_w1(r1));
6934 assign(uop, get_gpr_w1(r1));
6935 sign_mask = 2147483648U;
6936 assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
6937 assign(result, binop(Iop_Or32, binop(Iop_And32, binop(Iop_Shl32, mkexpr(uop),
6938 unop(Iop_64to8, mkexpr(shift_amount))), mkU32(~sign_mask)),
6939 binop(Iop_And32, mkexpr(uop), mkU32(sign_mask))));
6940 put_gpr_w1(r1, mkexpr(result));
6941 s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_32, op, shift_amount);
6942
6943 return "sla";
6944}
6945
6946static HChar *
6947s390_irgen_SLAK(UChar r1, UChar r3, IRTemp op2addr)
6948{
6949 IRTemp uop = newTemp(Ity_I32);
6950 IRTemp result = newTemp(Ity_I32);
6951 UInt sign_mask;
6952 IRTemp shift_amount = newTemp(Ity_I64);
6953 IRTemp op = newTemp(Ity_I32);
6954
6955 assign(op, get_gpr_w1(r3));
6956 assign(uop, get_gpr_w1(r3));
6957 sign_mask = 2147483648U;
6958 assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
6959 assign(result, binop(Iop_Or32, binop(Iop_And32, binop(Iop_Shl32, mkexpr(uop),
6960 unop(Iop_64to8, mkexpr(shift_amount))), mkU32(~sign_mask)),
6961 binop(Iop_And32, mkexpr(uop), mkU32(sign_mask))));
6962 put_gpr_w1(r1, mkexpr(result));
6963 s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_32, op, shift_amount);
6964
6965 return "slak";
6966}
6967
6968static HChar *
6969s390_irgen_SLAG(UChar r1, UChar r3, IRTemp op2addr)
6970{
6971 IRTemp uop = newTemp(Ity_I64);
6972 IRTemp result = newTemp(Ity_I64);
6973 ULong sign_mask;
6974 IRTemp shift_amount = newTemp(Ity_I64);
6975 IRTemp op = newTemp(Ity_I64);
6976
6977 assign(op, get_gpr_dw0(r3));
6978 assign(uop, get_gpr_dw0(r3));
6979 sign_mask = 9223372036854775808ULL;
6980 assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
6981 assign(result, binop(Iop_Or64, binop(Iop_And64, binop(Iop_Shl64, mkexpr(uop),
6982 unop(Iop_64to8, mkexpr(shift_amount))), mkU64(~sign_mask)),
6983 binop(Iop_And64, mkexpr(uop), mkU64(sign_mask))));
6984 put_gpr_dw0(r1, mkexpr(result));
6985 s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_64, op, shift_amount);
6986
6987 return "slag";
6988}
6989
6990static HChar *
6991s390_irgen_SLL(UChar r1, IRTemp op2addr)
6992{
6993 put_gpr_w1(r1, binop(Iop_Shl32, get_gpr_w1(r1), unop(Iop_64to8,
6994 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
6995
6996 return "sll";
6997}
6998
6999static HChar *
7000s390_irgen_SLLK(UChar r1, UChar r3, IRTemp op2addr)
7001{
7002 put_gpr_w1(r1, binop(Iop_Shl32, get_gpr_w1(r3), unop(Iop_64to8,
7003 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
7004
7005 return "sllk";
7006}
7007
7008static HChar *
7009s390_irgen_SLLG(UChar r1, UChar r3, IRTemp op2addr)
7010{
7011 put_gpr_dw0(r1, binop(Iop_Shl64, get_gpr_dw0(r3), unop(Iop_64to8,
7012 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
7013
7014 return "sllg";
7015}
7016
7017static HChar *
7018s390_irgen_SRDA(UChar r1, IRTemp op2addr)
7019{
7020 IRTemp p1 = newTemp(Ity_I64);
7021 IRTemp p2 = newTemp(Ity_I64);
7022 IRTemp result = newTemp(Ity_I64);
7023
7024 assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
7025 assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
7026 assign(result, binop(Iop_Sar64, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1),
7027 mkU8(32)), mkexpr(p2)), unop(Iop_64to8, binop(Iop_And64,
7028 mkexpr(op2addr), mkU64(63)))));
7029 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
7030 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
7031 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7032
7033 return "srda";
7034}
7035
7036static HChar *
7037s390_irgen_SRDL(UChar r1, IRTemp op2addr)
7038{
7039 IRTemp p1 = newTemp(Ity_I64);
7040 IRTemp p2 = newTemp(Ity_I64);
7041 IRTemp result = newTemp(Ity_I64);
7042
7043 assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
7044 assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
7045 assign(result, binop(Iop_Shr64, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1),
7046 mkU8(32)), mkexpr(p2)), unop(Iop_64to8, binop(Iop_And64,
7047 mkexpr(op2addr), mkU64(63)))));
7048 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
7049 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
7050
7051 return "srdl";
7052}
7053
7054static HChar *
7055s390_irgen_SRA(UChar r1, IRTemp op2addr)
7056{
7057 IRTemp result = newTemp(Ity_I32);
7058 IRTemp op = newTemp(Ity_I32);
7059
7060 assign(op, get_gpr_w1(r1));
7061 assign(result, binop(Iop_Sar32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7062 mkexpr(op2addr), mkU64(63)))));
7063 put_gpr_w1(r1, mkexpr(result));
7064 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7065
7066 return "sra";
7067}
7068
7069static HChar *
7070s390_irgen_SRAK(UChar r1, UChar r3, IRTemp op2addr)
7071{
7072 IRTemp result = newTemp(Ity_I32);
7073 IRTemp op = newTemp(Ity_I32);
7074
7075 assign(op, get_gpr_w1(r3));
7076 assign(result, binop(Iop_Sar32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7077 mkexpr(op2addr), mkU64(63)))));
7078 put_gpr_w1(r1, mkexpr(result));
7079 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7080
7081 return "srak";
7082}
7083
7084static HChar *
7085s390_irgen_SRAG(UChar r1, UChar r3, IRTemp op2addr)
7086{
7087 IRTemp result = newTemp(Ity_I64);
7088 IRTemp op = newTemp(Ity_I64);
7089
7090 assign(op, get_gpr_dw0(r3));
7091 assign(result, binop(Iop_Sar64, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7092 mkexpr(op2addr), mkU64(63)))));
7093 put_gpr_dw0(r1, mkexpr(result));
7094 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7095
7096 return "srag";
7097}
7098
7099static HChar *
7100s390_irgen_SRL(UChar r1, IRTemp op2addr)
7101{
7102 IRTemp op = newTemp(Ity_I32);
7103
7104 assign(op, get_gpr_w1(r1));
7105 put_gpr_w1(r1, binop(Iop_Shr32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7106 mkexpr(op2addr), mkU64(63)))));
7107
7108 return "srl";
7109}
7110
7111static HChar *
7112s390_irgen_SRLK(UChar r1, UChar r3, IRTemp op2addr)
7113{
7114 IRTemp op = newTemp(Ity_I32);
7115
7116 assign(op, get_gpr_w1(r3));
7117 put_gpr_w1(r1, binop(Iop_Shr32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7118 mkexpr(op2addr), mkU64(63)))));
7119
7120 return "srlk";
7121}
7122
7123static HChar *
7124s390_irgen_SRLG(UChar r1, UChar r3, IRTemp op2addr)
7125{
7126 IRTemp op = newTemp(Ity_I64);
7127
7128 assign(op, get_gpr_dw0(r3));
7129 put_gpr_dw0(r1, binop(Iop_Shr64, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7130 mkexpr(op2addr), mkU64(63)))));
7131
7132 return "srlg";
7133}
7134
7135static HChar *
7136s390_irgen_ST(UChar r1, IRTemp op2addr)
7137{
7138 store(mkexpr(op2addr), get_gpr_w1(r1));
7139
7140 return "st";
7141}
7142
7143static HChar *
7144s390_irgen_STY(UChar r1, IRTemp op2addr)
7145{
7146 store(mkexpr(op2addr), get_gpr_w1(r1));
7147
7148 return "sty";
7149}
7150
7151static HChar *
7152s390_irgen_STG(UChar r1, IRTemp op2addr)
7153{
7154 store(mkexpr(op2addr), get_gpr_dw0(r1));
7155
7156 return "stg";
7157}
7158
7159static HChar *
7160s390_irgen_STRL(UChar r1, UInt i2)
7161{
7162 store(mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)),
7163 get_gpr_w1(r1));
7164
7165 return "strl";
7166}
7167
7168static HChar *
7169s390_irgen_STGRL(UChar r1, UInt i2)
7170{
7171 store(mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)),
7172 get_gpr_dw0(r1));
7173
7174 return "stgrl";
7175}
7176
7177static HChar *
7178s390_irgen_STC(UChar r1, IRTemp op2addr)
7179{
7180 store(mkexpr(op2addr), get_gpr_b7(r1));
7181
7182 return "stc";
7183}
7184
7185static HChar *
7186s390_irgen_STCY(UChar r1, IRTemp op2addr)
7187{
7188 store(mkexpr(op2addr), get_gpr_b7(r1));
7189
7190 return "stcy";
7191}
7192
7193static HChar *
7194s390_irgen_STCH(UChar r1, IRTemp op2addr)
7195{
7196 store(mkexpr(op2addr), get_gpr_b3(r1));
7197
7198 return "stch";
7199}
7200
7201static HChar *
7202s390_irgen_STCM(UChar r1, UChar r3, IRTemp op2addr)
7203{
7204 UChar mask;
7205 UChar n;
7206
7207 mask = (UChar)r3;
7208 n = 0;
7209 if ((mask & 8) != 0) {
7210 store(mkexpr(op2addr), get_gpr_b4(r1));
7211 n = n + 1;
7212 }
7213 if ((mask & 4) != 0) {
7214 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b5(r1));
7215 n = n + 1;
7216 }
7217 if ((mask & 2) != 0) {
7218 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b6(r1));
7219 n = n + 1;
7220 }
7221 if ((mask & 1) != 0) {
7222 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b7(r1));
7223 }
7224
7225 return "stcm";
7226}
7227
7228static HChar *
7229s390_irgen_STCMY(UChar r1, UChar r3, IRTemp op2addr)
7230{
7231 UChar mask;
7232 UChar n;
7233
7234 mask = (UChar)r3;
7235 n = 0;
7236 if ((mask & 8) != 0) {
7237 store(mkexpr(op2addr), get_gpr_b4(r1));
7238 n = n + 1;
7239 }
7240 if ((mask & 4) != 0) {
7241 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b5(r1));
7242 n = n + 1;
7243 }
7244 if ((mask & 2) != 0) {
7245 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b6(r1));
7246 n = n + 1;
7247 }
7248 if ((mask & 1) != 0) {
7249 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b7(r1));
7250 }
7251
7252 return "stcmy";
7253}
7254
7255static HChar *
7256s390_irgen_STCMH(UChar r1, UChar r3, IRTemp op2addr)
7257{
7258 UChar mask;
7259 UChar n;
7260
7261 mask = (UChar)r3;
7262 n = 0;
7263 if ((mask & 8) != 0) {
7264 store(mkexpr(op2addr), get_gpr_b0(r1));
7265 n = n + 1;
7266 }
7267 if ((mask & 4) != 0) {
7268 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b1(r1));
7269 n = n + 1;
7270 }
7271 if ((mask & 2) != 0) {
7272 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b2(r1));
7273 n = n + 1;
7274 }
7275 if ((mask & 1) != 0) {
7276 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b3(r1));
7277 }
7278
7279 return "stcmh";
7280}
7281
7282static HChar *
7283s390_irgen_STH(UChar r1, IRTemp op2addr)
7284{
7285 store(mkexpr(op2addr), get_gpr_hw3(r1));
7286
7287 return "sth";
7288}
7289
7290static HChar *
7291s390_irgen_STHY(UChar r1, IRTemp op2addr)
7292{
7293 store(mkexpr(op2addr), get_gpr_hw3(r1));
7294
7295 return "sthy";
7296}
7297
7298static HChar *
7299s390_irgen_STHRL(UChar r1, UInt i2)
7300{
7301 store(mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)),
7302 get_gpr_hw3(r1));
7303
7304 return "sthrl";
7305}
7306
7307static HChar *
7308s390_irgen_STHH(UChar r1, IRTemp op2addr)
7309{
7310 store(mkexpr(op2addr), get_gpr_hw1(r1));
7311
7312 return "sthh";
7313}
7314
7315static HChar *
7316s390_irgen_STFH(UChar r1, IRTemp op2addr)
7317{
7318 store(mkexpr(op2addr), get_gpr_w0(r1));
7319
7320 return "stfh";
7321}
7322
7323static HChar *
sewardjd7bde722011-04-05 13:19:33 +00007324s390_irgen_STOC(UChar r1, IRTemp op2addr)
7325{
7326 /* condition is checked in format handler */
7327 store(mkexpr(op2addr), get_gpr_w1(r1));
7328
7329 return "stoc";
7330}
7331
7332static HChar *
7333s390_irgen_STOCG(UChar r1, IRTemp op2addr)
7334{
7335 /* condition is checked in format handler */
7336 store(mkexpr(op2addr), get_gpr_dw0(r1));
7337
7338 return "stocg";
7339}
7340
7341static HChar *
sewardj2019a972011-03-07 16:04:07 +00007342s390_irgen_STPQ(UChar r1, IRTemp op2addr)
7343{
7344 store(mkexpr(op2addr), get_gpr_dw0(r1));
7345 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(8)), get_gpr_dw0(r1 + 1));
7346
7347 return "stpq";
7348}
7349
7350static HChar *
7351s390_irgen_STRVH(UChar r1, IRTemp op2addr)
7352{
7353 store(mkexpr(op2addr), get_gpr_b7(r1));
7354 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(1)), get_gpr_b6(r1));
7355
7356 return "strvh";
7357}
7358
7359static HChar *
7360s390_irgen_STRV(UChar r1, IRTemp op2addr)
7361{
7362 store(mkexpr(op2addr), get_gpr_b7(r1));
7363 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(1)), get_gpr_b6(r1));
7364 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(2)), get_gpr_b5(r1));
7365 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(3)), get_gpr_b4(r1));
7366
7367 return "strv";
7368}
7369
7370static HChar *
7371s390_irgen_STRVG(UChar r1, IRTemp op2addr)
7372{
7373 store(mkexpr(op2addr), get_gpr_b7(r1));
7374 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(1)), get_gpr_b6(r1));
7375 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(2)), get_gpr_b5(r1));
7376 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(3)), get_gpr_b4(r1));
7377 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(4)), get_gpr_b3(r1));
7378 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(5)), get_gpr_b2(r1));
7379 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(6)), get_gpr_b1(r1));
7380 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(7)), get_gpr_b0(r1));
7381
7382 return "strvg";
7383}
7384
7385static HChar *
7386s390_irgen_SR(UChar r1, UChar r2)
7387{
7388 IRTemp op1 = newTemp(Ity_I32);
7389 IRTemp op2 = newTemp(Ity_I32);
7390 IRTemp result = newTemp(Ity_I32);
7391
7392 assign(op1, get_gpr_w1(r1));
7393 assign(op2, get_gpr_w1(r2));
7394 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7395 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
7396 put_gpr_w1(r1, mkexpr(result));
7397
7398 return "sr";
7399}
7400
7401static HChar *
7402s390_irgen_SGR(UChar r1, UChar r2)
7403{
7404 IRTemp op1 = newTemp(Ity_I64);
7405 IRTemp op2 = newTemp(Ity_I64);
7406 IRTemp result = newTemp(Ity_I64);
7407
7408 assign(op1, get_gpr_dw0(r1));
7409 assign(op2, get_gpr_dw0(r2));
7410 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7411 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
7412 put_gpr_dw0(r1, mkexpr(result));
7413
7414 return "sgr";
7415}
7416
7417static HChar *
7418s390_irgen_SGFR(UChar r1, UChar r2)
7419{
7420 IRTemp op1 = newTemp(Ity_I64);
7421 IRTemp op2 = newTemp(Ity_I64);
7422 IRTemp result = newTemp(Ity_I64);
7423
7424 assign(op1, get_gpr_dw0(r1));
7425 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
7426 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7427 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
7428 put_gpr_dw0(r1, mkexpr(result));
7429
7430 return "sgfr";
7431}
7432
7433static HChar *
7434s390_irgen_SRK(UChar r3, UChar r1, UChar r2)
7435{
7436 IRTemp op2 = newTemp(Ity_I32);
7437 IRTemp op3 = newTemp(Ity_I32);
7438 IRTemp result = newTemp(Ity_I32);
7439
7440 assign(op2, get_gpr_w1(r2));
7441 assign(op3, get_gpr_w1(r3));
7442 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
7443 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op2, op3);
7444 put_gpr_w1(r1, mkexpr(result));
7445
7446 return "srk";
7447}
7448
7449static HChar *
7450s390_irgen_SGRK(UChar r3, UChar r1, UChar r2)
7451{
7452 IRTemp op2 = newTemp(Ity_I64);
7453 IRTemp op3 = newTemp(Ity_I64);
7454 IRTemp result = newTemp(Ity_I64);
7455
7456 assign(op2, get_gpr_dw0(r2));
7457 assign(op3, get_gpr_dw0(r3));
7458 assign(result, binop(Iop_Sub64, mkexpr(op2), mkexpr(op3)));
7459 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op2, op3);
7460 put_gpr_dw0(r1, mkexpr(result));
7461
7462 return "sgrk";
7463}
7464
7465static HChar *
7466s390_irgen_S(UChar r1, IRTemp op2addr)
7467{
7468 IRTemp op1 = newTemp(Ity_I32);
7469 IRTemp op2 = newTemp(Ity_I32);
7470 IRTemp result = newTemp(Ity_I32);
7471
7472 assign(op1, get_gpr_w1(r1));
7473 assign(op2, load(Ity_I32, mkexpr(op2addr)));
7474 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7475 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
7476 put_gpr_w1(r1, mkexpr(result));
7477
7478 return "s";
7479}
7480
7481static HChar *
7482s390_irgen_SY(UChar r1, IRTemp op2addr)
7483{
7484 IRTemp op1 = newTemp(Ity_I32);
7485 IRTemp op2 = newTemp(Ity_I32);
7486 IRTemp result = newTemp(Ity_I32);
7487
7488 assign(op1, get_gpr_w1(r1));
7489 assign(op2, load(Ity_I32, mkexpr(op2addr)));
7490 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7491 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
7492 put_gpr_w1(r1, mkexpr(result));
7493
7494 return "sy";
7495}
7496
7497static HChar *
7498s390_irgen_SG(UChar r1, IRTemp op2addr)
7499{
7500 IRTemp op1 = newTemp(Ity_I64);
7501 IRTemp op2 = newTemp(Ity_I64);
7502 IRTemp result = newTemp(Ity_I64);
7503
7504 assign(op1, get_gpr_dw0(r1));
7505 assign(op2, load(Ity_I64, mkexpr(op2addr)));
7506 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7507 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
7508 put_gpr_dw0(r1, mkexpr(result));
7509
7510 return "sg";
7511}
7512
7513static HChar *
7514s390_irgen_SGF(UChar r1, IRTemp op2addr)
7515{
7516 IRTemp op1 = newTemp(Ity_I64);
7517 IRTemp op2 = newTemp(Ity_I64);
7518 IRTemp result = newTemp(Ity_I64);
7519
7520 assign(op1, get_gpr_dw0(r1));
7521 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
7522 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7523 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
7524 put_gpr_dw0(r1, mkexpr(result));
7525
7526 return "sgf";
7527}
7528
7529static HChar *
7530s390_irgen_SH(UChar r1, IRTemp op2addr)
7531{
7532 IRTemp op1 = newTemp(Ity_I32);
7533 IRTemp op2 = newTemp(Ity_I32);
7534 IRTemp result = newTemp(Ity_I32);
7535
7536 assign(op1, get_gpr_w1(r1));
7537 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
7538 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7539 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
7540 put_gpr_w1(r1, mkexpr(result));
7541
7542 return "sh";
7543}
7544
7545static HChar *
7546s390_irgen_SHY(UChar r1, IRTemp op2addr)
7547{
7548 IRTemp op1 = newTemp(Ity_I32);
7549 IRTemp op2 = newTemp(Ity_I32);
7550 IRTemp result = newTemp(Ity_I32);
7551
7552 assign(op1, get_gpr_w1(r1));
7553 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
7554 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7555 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
7556 put_gpr_w1(r1, mkexpr(result));
7557
7558 return "shy";
7559}
7560
7561static HChar *
7562s390_irgen_SHHHR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
7563{
7564 IRTemp op2 = newTemp(Ity_I32);
7565 IRTemp op3 = newTemp(Ity_I32);
7566 IRTemp result = newTemp(Ity_I32);
7567
7568 assign(op2, get_gpr_w0(r1));
7569 assign(op3, get_gpr_w0(r2));
7570 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
7571 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op2, op3);
7572 put_gpr_w0(r1, mkexpr(result));
7573
7574 return "shhhr";
7575}
7576
7577static HChar *
7578s390_irgen_SHHLR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
7579{
7580 IRTemp op2 = newTemp(Ity_I32);
7581 IRTemp op3 = newTemp(Ity_I32);
7582 IRTemp result = newTemp(Ity_I32);
7583
7584 assign(op2, get_gpr_w0(r1));
7585 assign(op3, get_gpr_w1(r2));
7586 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
7587 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op2, op3);
7588 put_gpr_w0(r1, mkexpr(result));
7589
7590 return "shhlr";
7591}
7592
7593static HChar *
7594s390_irgen_SLR(UChar r1, UChar r2)
7595{
7596 IRTemp op1 = newTemp(Ity_I32);
7597 IRTemp op2 = newTemp(Ity_I32);
7598 IRTemp result = newTemp(Ity_I32);
7599
7600 assign(op1, get_gpr_w1(r1));
7601 assign(op2, get_gpr_w1(r2));
7602 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7603 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, op2);
7604 put_gpr_w1(r1, mkexpr(result));
7605
7606 return "slr";
7607}
7608
7609static HChar *
7610s390_irgen_SLGR(UChar r1, UChar r2)
7611{
7612 IRTemp op1 = newTemp(Ity_I64);
7613 IRTemp op2 = newTemp(Ity_I64);
7614 IRTemp result = newTemp(Ity_I64);
7615
7616 assign(op1, get_gpr_dw0(r1));
7617 assign(op2, get_gpr_dw0(r2));
7618 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7619 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
7620 put_gpr_dw0(r1, mkexpr(result));
7621
7622 return "slgr";
7623}
7624
7625static HChar *
7626s390_irgen_SLGFR(UChar r1, UChar r2)
7627{
7628 IRTemp op1 = newTemp(Ity_I64);
7629 IRTemp op2 = newTemp(Ity_I64);
7630 IRTemp result = newTemp(Ity_I64);
7631
7632 assign(op1, get_gpr_dw0(r1));
7633 assign(op2, unop(Iop_32Uto64, get_gpr_w1(r2)));
7634 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7635 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
7636 put_gpr_dw0(r1, mkexpr(result));
7637
7638 return "slgfr";
7639}
7640
7641static HChar *
7642s390_irgen_SLRK(UChar r3, UChar r1, UChar r2)
7643{
7644 IRTemp op2 = newTemp(Ity_I32);
7645 IRTemp op3 = newTemp(Ity_I32);
7646 IRTemp result = newTemp(Ity_I32);
7647
7648 assign(op2, get_gpr_w1(r2));
7649 assign(op3, get_gpr_w1(r3));
7650 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
7651 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op2, op3);
7652 put_gpr_w1(r1, mkexpr(result));
7653
7654 return "slrk";
7655}
7656
7657static HChar *
7658s390_irgen_SLGRK(UChar r3, UChar r1, UChar r2)
7659{
7660 IRTemp op2 = newTemp(Ity_I64);
7661 IRTemp op3 = newTemp(Ity_I64);
7662 IRTemp result = newTemp(Ity_I64);
7663
7664 assign(op2, get_gpr_dw0(r2));
7665 assign(op3, get_gpr_dw0(r3));
7666 assign(result, binop(Iop_Sub64, mkexpr(op2), mkexpr(op3)));
7667 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op2, op3);
7668 put_gpr_dw0(r1, mkexpr(result));
7669
7670 return "slgrk";
7671}
7672
7673static HChar *
7674s390_irgen_SL(UChar r1, IRTemp op2addr)
7675{
7676 IRTemp op1 = newTemp(Ity_I32);
7677 IRTemp op2 = newTemp(Ity_I32);
7678 IRTemp result = newTemp(Ity_I32);
7679
7680 assign(op1, get_gpr_w1(r1));
7681 assign(op2, load(Ity_I32, mkexpr(op2addr)));
7682 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7683 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, op2);
7684 put_gpr_w1(r1, mkexpr(result));
7685
7686 return "sl";
7687}
7688
7689static HChar *
7690s390_irgen_SLY(UChar r1, IRTemp op2addr)
7691{
7692 IRTemp op1 = newTemp(Ity_I32);
7693 IRTemp op2 = newTemp(Ity_I32);
7694 IRTemp result = newTemp(Ity_I32);
7695
7696 assign(op1, get_gpr_w1(r1));
7697 assign(op2, load(Ity_I32, mkexpr(op2addr)));
7698 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7699 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, op2);
7700 put_gpr_w1(r1, mkexpr(result));
7701
7702 return "sly";
7703}
7704
7705static HChar *
7706s390_irgen_SLG(UChar r1, IRTemp op2addr)
7707{
7708 IRTemp op1 = newTemp(Ity_I64);
7709 IRTemp op2 = newTemp(Ity_I64);
7710 IRTemp result = newTemp(Ity_I64);
7711
7712 assign(op1, get_gpr_dw0(r1));
7713 assign(op2, load(Ity_I64, mkexpr(op2addr)));
7714 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7715 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
7716 put_gpr_dw0(r1, mkexpr(result));
7717
7718 return "slg";
7719}
7720
7721static HChar *
7722s390_irgen_SLGF(UChar r1, IRTemp op2addr)
7723{
7724 IRTemp op1 = newTemp(Ity_I64);
7725 IRTemp op2 = newTemp(Ity_I64);
7726 IRTemp result = newTemp(Ity_I64);
7727
7728 assign(op1, get_gpr_dw0(r1));
7729 assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
7730 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7731 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
7732 put_gpr_dw0(r1, mkexpr(result));
7733
7734 return "slgf";
7735}
7736
7737static HChar *
7738s390_irgen_SLFI(UChar r1, UInt i2)
7739{
7740 IRTemp op1 = newTemp(Ity_I32);
7741 UInt op2;
7742 IRTemp result = newTemp(Ity_I32);
7743
7744 assign(op1, get_gpr_w1(r1));
7745 op2 = i2;
7746 assign(result, binop(Iop_Sub32, mkexpr(op1), mkU32(op2)));
7747 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, mktemp(Ity_I32,
7748 mkU32(op2)));
7749 put_gpr_w1(r1, mkexpr(result));
7750
7751 return "slfi";
7752}
7753
7754static HChar *
7755s390_irgen_SLGFI(UChar r1, UInt i2)
7756{
7757 IRTemp op1 = newTemp(Ity_I64);
7758 ULong op2;
7759 IRTemp result = newTemp(Ity_I64);
7760
7761 assign(op1, get_gpr_dw0(r1));
7762 op2 = (ULong)i2;
7763 assign(result, binop(Iop_Sub64, mkexpr(op1), mkU64(op2)));
7764 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, mktemp(Ity_I64,
7765 mkU64(op2)));
7766 put_gpr_dw0(r1, mkexpr(result));
7767
7768 return "slgfi";
7769}
7770
7771static HChar *
7772s390_irgen_SLHHHR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
7773{
7774 IRTemp op2 = newTemp(Ity_I32);
7775 IRTemp op3 = newTemp(Ity_I32);
7776 IRTemp result = newTemp(Ity_I32);
7777
7778 assign(op2, get_gpr_w0(r1));
7779 assign(op3, get_gpr_w0(r2));
7780 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
7781 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op2, op3);
7782 put_gpr_w0(r1, mkexpr(result));
7783
7784 return "slhhhr";
7785}
7786
7787static HChar *
7788s390_irgen_SLHHLR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
7789{
7790 IRTemp op2 = newTemp(Ity_I32);
7791 IRTemp op3 = newTemp(Ity_I32);
7792 IRTemp result = newTemp(Ity_I32);
7793
7794 assign(op2, get_gpr_w0(r1));
7795 assign(op3, get_gpr_w1(r2));
7796 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
7797 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op2, op3);
7798 put_gpr_w0(r1, mkexpr(result));
7799
7800 return "slhhlr";
7801}
7802
7803static HChar *
7804s390_irgen_SLBR(UChar r1, UChar r2)
7805{
7806 IRTemp op1 = newTemp(Ity_I32);
7807 IRTemp op2 = newTemp(Ity_I32);
7808 IRTemp result = newTemp(Ity_I32);
7809 IRTemp borrow_in = newTemp(Ity_I32);
7810
7811 assign(op1, get_gpr_w1(r1));
7812 assign(op2, get_gpr_w1(r2));
7813 assign(borrow_in, binop(Iop_Sub32, mkU32(1), binop(Iop_Shr32,
7814 s390_call_calculate_cc(), mkU8(1))));
7815 assign(result, binop(Iop_Sub32, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)),
7816 mkexpr(borrow_in)));
7817 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_32, op1, op2, borrow_in);
7818 put_gpr_w1(r1, mkexpr(result));
7819
7820 return "slbr";
7821}
7822
7823static HChar *
7824s390_irgen_SLBGR(UChar r1, UChar r2)
7825{
7826 IRTemp op1 = newTemp(Ity_I64);
7827 IRTemp op2 = newTemp(Ity_I64);
7828 IRTemp result = newTemp(Ity_I64);
7829 IRTemp borrow_in = newTemp(Ity_I64);
7830
7831 assign(op1, get_gpr_dw0(r1));
7832 assign(op2, get_gpr_dw0(r2));
7833 assign(borrow_in, unop(Iop_32Uto64, binop(Iop_Sub32, mkU32(1),
7834 binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)))));
7835 assign(result, binop(Iop_Sub64, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)),
7836 mkexpr(borrow_in)));
7837 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_64, op1, op2, borrow_in);
7838 put_gpr_dw0(r1, mkexpr(result));
7839
7840 return "slbgr";
7841}
7842
7843static HChar *
7844s390_irgen_SLB(UChar r1, IRTemp op2addr)
7845{
7846 IRTemp op1 = newTemp(Ity_I32);
7847 IRTemp op2 = newTemp(Ity_I32);
7848 IRTemp result = newTemp(Ity_I32);
7849 IRTemp borrow_in = newTemp(Ity_I32);
7850
7851 assign(op1, get_gpr_w1(r1));
7852 assign(op2, load(Ity_I32, mkexpr(op2addr)));
7853 assign(borrow_in, binop(Iop_Sub32, mkU32(1), binop(Iop_Shr32,
7854 s390_call_calculate_cc(), mkU8(1))));
7855 assign(result, binop(Iop_Sub32, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)),
7856 mkexpr(borrow_in)));
7857 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_32, op1, op2, borrow_in);
7858 put_gpr_w1(r1, mkexpr(result));
7859
7860 return "slb";
7861}
7862
7863static HChar *
7864s390_irgen_SLBG(UChar r1, IRTemp op2addr)
7865{
7866 IRTemp op1 = newTemp(Ity_I64);
7867 IRTemp op2 = newTemp(Ity_I64);
7868 IRTemp result = newTemp(Ity_I64);
7869 IRTemp borrow_in = newTemp(Ity_I64);
7870
7871 assign(op1, get_gpr_dw0(r1));
7872 assign(op2, load(Ity_I64, mkexpr(op2addr)));
7873 assign(borrow_in, unop(Iop_32Uto64, binop(Iop_Sub32, mkU32(1),
7874 binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)))));
7875 assign(result, binop(Iop_Sub64, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)),
7876 mkexpr(borrow_in)));
7877 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_64, op1, op2, borrow_in);
7878 put_gpr_dw0(r1, mkexpr(result));
7879
7880 return "slbg";
7881}
7882
7883static HChar *
7884s390_irgen_SVC(UChar i)
7885{
7886 IRTemp sysno = newTemp(Ity_I64);
7887
7888 if (i != 0) {
7889 assign(sysno, mkU64(i));
7890 } else {
7891 assign(sysno, unop(Iop_32Uto64, get_gpr_w1(1)));
7892 }
7893 system_call(mkexpr(sysno));
7894
7895 return "svc";
7896}
7897
7898static HChar *
sewardj2019a972011-03-07 16:04:07 +00007899s390_irgen_TM(UChar i2, IRTemp op1addr)
7900{
7901 UChar mask;
7902 IRTemp value = newTemp(Ity_I8);
7903
7904 mask = i2;
7905 assign(value, load(Ity_I8, mkexpr(op1addr)));
7906 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_8, value, mktemp(Ity_I8,
7907 mkU8(mask)));
7908
7909 return "tm";
7910}
7911
7912static HChar *
7913s390_irgen_TMY(UChar i2, IRTemp op1addr)
7914{
7915 UChar mask;
7916 IRTemp value = newTemp(Ity_I8);
7917
7918 mask = i2;
7919 assign(value, load(Ity_I8, mkexpr(op1addr)));
7920 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_8, value, mktemp(Ity_I8,
7921 mkU8(mask)));
7922
7923 return "tmy";
7924}
7925
7926static HChar *
7927s390_irgen_TMHH(UChar r1, UShort i2)
7928{
7929 UShort mask;
7930 IRTemp value = newTemp(Ity_I16);
7931
7932 mask = i2;
7933 assign(value, get_gpr_hw0(r1));
7934 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
7935 mkU16(mask)));
7936
7937 return "tmhh";
7938}
7939
7940static HChar *
7941s390_irgen_TMHL(UChar r1, UShort i2)
7942{
7943 UShort mask;
7944 IRTemp value = newTemp(Ity_I16);
7945
7946 mask = i2;
7947 assign(value, get_gpr_hw1(r1));
7948 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
7949 mkU16(mask)));
7950
7951 return "tmhl";
7952}
7953
7954static HChar *
7955s390_irgen_TMLH(UChar r1, UShort i2)
7956{
7957 UShort mask;
7958 IRTemp value = newTemp(Ity_I16);
7959
7960 mask = i2;
7961 assign(value, get_gpr_hw2(r1));
7962 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
7963 mkU16(mask)));
7964
7965 return "tmlh";
7966}
7967
7968static HChar *
7969s390_irgen_TMLL(UChar r1, UShort i2)
7970{
7971 UShort mask;
7972 IRTemp value = newTemp(Ity_I16);
7973
7974 mask = i2;
7975 assign(value, get_gpr_hw3(r1));
7976 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
7977 mkU16(mask)));
7978
7979 return "tmll";
7980}
7981
7982static HChar *
7983s390_irgen_EFPC(UChar r1)
7984{
7985 put_gpr_w1(r1, get_fpc_w0());
7986
7987 return "efpc";
7988}
7989
7990static HChar *
7991s390_irgen_LER(UChar r1, UChar r2)
7992{
7993 put_fpr_w0(r1, get_fpr_w0(r2));
7994
7995 return "ler";
7996}
7997
7998static HChar *
7999s390_irgen_LDR(UChar r1, UChar r2)
8000{
8001 put_fpr_dw0(r1, get_fpr_dw0(r2));
8002
8003 return "ldr";
8004}
8005
8006static HChar *
8007s390_irgen_LXR(UChar r1, UChar r2)
8008{
8009 put_fpr_dw0(r1, get_fpr_dw0(r2));
8010 put_fpr_dw0(r1 + 2, get_fpr_dw0(r2 + 2));
8011
8012 return "lxr";
8013}
8014
8015static HChar *
8016s390_irgen_LE(UChar r1, IRTemp op2addr)
8017{
8018 put_fpr_w0(r1, load(Ity_F32, mkexpr(op2addr)));
8019
8020 return "le";
8021}
8022
8023static HChar *
8024s390_irgen_LD(UChar r1, IRTemp op2addr)
8025{
8026 put_fpr_dw0(r1, load(Ity_F64, mkexpr(op2addr)));
8027
8028 return "ld";
8029}
8030
8031static HChar *
8032s390_irgen_LEY(UChar r1, IRTemp op2addr)
8033{
8034 put_fpr_w0(r1, load(Ity_F32, mkexpr(op2addr)));
8035
8036 return "ley";
8037}
8038
8039static HChar *
8040s390_irgen_LDY(UChar r1, IRTemp op2addr)
8041{
8042 put_fpr_dw0(r1, load(Ity_F64, mkexpr(op2addr)));
8043
8044 return "ldy";
8045}
8046
8047static HChar *
8048s390_irgen_LFPC(IRTemp op2addr)
8049{
8050 put_fpc_w0(load(Ity_I32, mkexpr(op2addr)));
8051
8052 return "lfpc";
8053}
8054
8055static HChar *
8056s390_irgen_LZER(UChar r1)
8057{
8058 put_fpr_w0(r1, mkF32i(0x0));
8059
8060 return "lzer";
8061}
8062
8063static HChar *
8064s390_irgen_LZDR(UChar r1)
8065{
8066 put_fpr_dw0(r1, mkF64i(0x0));
8067
8068 return "lzdr";
8069}
8070
8071static HChar *
8072s390_irgen_LZXR(UChar r1)
8073{
8074 put_fpr_dw0(r1, mkF64i(0x0));
8075 put_fpr_dw0(r1 + 2, mkF64i(0x0));
8076
8077 return "lzxr";
8078}
8079
8080static HChar *
8081s390_irgen_SRNM(IRTemp op2addr)
8082{
8083 UInt mask;
8084
8085 mask = 3;
8086 put_fpc_w0(binop(Iop_Or32, binop(Iop_And32, get_fpc_w0(), mkU32(~mask)),
8087 binop(Iop_And32, unop(Iop_64to32, mkexpr(op2addr)), mkU32(mask)))
8088 );
8089
8090 return "srnm";
8091}
8092
8093static HChar *
8094s390_irgen_SFPC(UChar r1)
8095{
8096 put_fpc_w0(get_gpr_w1(r1));
8097
8098 return "sfpc";
8099}
8100
8101static HChar *
8102s390_irgen_STE(UChar r1, IRTemp op2addr)
8103{
8104 store(mkexpr(op2addr), get_fpr_w0(r1));
8105
8106 return "ste";
8107}
8108
8109static HChar *
8110s390_irgen_STD(UChar r1, IRTemp op2addr)
8111{
8112 store(mkexpr(op2addr), get_fpr_dw0(r1));
8113
8114 return "std";
8115}
8116
8117static HChar *
8118s390_irgen_STEY(UChar r1, IRTemp op2addr)
8119{
8120 store(mkexpr(op2addr), get_fpr_w0(r1));
8121
8122 return "stey";
8123}
8124
8125static HChar *
8126s390_irgen_STDY(UChar r1, IRTemp op2addr)
8127{
8128 store(mkexpr(op2addr), get_fpr_dw0(r1));
8129
8130 return "stdy";
8131}
8132
8133static HChar *
8134s390_irgen_STFPC(IRTemp op2addr)
8135{
8136 store(mkexpr(op2addr), get_fpc_w0());
8137
8138 return "stfpc";
8139}
8140
8141static HChar *
8142s390_irgen_AEBR(UChar r1, UChar r2)
8143{
8144 IRTemp op1 = newTemp(Ity_F32);
8145 IRTemp op2 = newTemp(Ity_F32);
8146 IRTemp result = newTemp(Ity_F32);
8147
8148 assign(op1, get_fpr_w0(r1));
8149 assign(op2, get_fpr_w0(r2));
8150 assign(result, triop(Iop_AddF32, mkU32(Irrm_NEAREST), mkexpr(op1),
8151 mkexpr(op2)));
8152 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
8153 put_fpr_w0(r1, mkexpr(result));
8154
8155 return "aebr";
8156}
8157
8158static HChar *
8159s390_irgen_ADBR(UChar r1, UChar r2)
8160{
8161 IRTemp op1 = newTemp(Ity_F64);
8162 IRTemp op2 = newTemp(Ity_F64);
8163 IRTemp result = newTemp(Ity_F64);
8164
8165 assign(op1, get_fpr_dw0(r1));
8166 assign(op2, get_fpr_dw0(r2));
8167 assign(result, triop(Iop_AddF64, mkU32(Irrm_NEAREST), mkexpr(op1),
8168 mkexpr(op2)));
8169 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
8170 put_fpr_dw0(r1, mkexpr(result));
8171
8172 return "adbr";
8173}
8174
8175static HChar *
8176s390_irgen_AEB(UChar r1, IRTemp op2addr)
8177{
8178 IRTemp op1 = newTemp(Ity_F32);
8179 IRTemp op2 = newTemp(Ity_F32);
8180 IRTemp result = newTemp(Ity_F32);
8181
8182 assign(op1, get_fpr_w0(r1));
8183 assign(op2, load(Ity_F32, mkexpr(op2addr)));
8184 assign(result, triop(Iop_AddF32, mkU32(Irrm_NEAREST), mkexpr(op1),
8185 mkexpr(op2)));
8186 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
8187 put_fpr_w0(r1, mkexpr(result));
8188
8189 return "aeb";
8190}
8191
8192static HChar *
8193s390_irgen_ADB(UChar r1, IRTemp op2addr)
8194{
8195 IRTemp op1 = newTemp(Ity_F64);
8196 IRTemp op2 = newTemp(Ity_F64);
8197 IRTemp result = newTemp(Ity_F64);
8198
8199 assign(op1, get_fpr_dw0(r1));
8200 assign(op2, load(Ity_F64, mkexpr(op2addr)));
8201 assign(result, triop(Iop_AddF64, mkU32(Irrm_NEAREST), mkexpr(op1),
8202 mkexpr(op2)));
8203 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
8204 put_fpr_dw0(r1, mkexpr(result));
8205
8206 return "adb";
8207}
8208
8209static HChar *
8210s390_irgen_CEFBR(UChar r1, UChar r2)
8211{
8212 IRTemp op2 = newTemp(Ity_I32);
8213
8214 assign(op2, get_gpr_w1(r2));
8215 put_fpr_w0(r1, binop(Iop_I32StoF32, mkU32(Irrm_NEAREST), mkexpr(op2)));
8216
8217 return "cefbr";
8218}
8219
8220static HChar *
8221s390_irgen_CDFBR(UChar r1, UChar r2)
8222{
8223 IRTemp op2 = newTemp(Ity_I32);
8224
8225 assign(op2, get_gpr_w1(r2));
8226 put_fpr_dw0(r1, unop(Iop_I32StoF64, mkexpr(op2)));
8227
8228 return "cdfbr";
8229}
8230
8231static HChar *
8232s390_irgen_CEGBR(UChar r1, UChar r2)
8233{
8234 IRTemp op2 = newTemp(Ity_I64);
8235
8236 assign(op2, get_gpr_dw0(r2));
8237 put_fpr_w0(r1, binop(Iop_I64StoF32, mkU32(Irrm_NEAREST), mkexpr(op2)));
8238
8239 return "cegbr";
8240}
8241
8242static HChar *
8243s390_irgen_CDGBR(UChar r1, UChar r2)
8244{
8245 IRTemp op2 = newTemp(Ity_I64);
8246
8247 assign(op2, get_gpr_dw0(r2));
8248 put_fpr_dw0(r1, binop(Iop_I64StoF64, mkU32(Irrm_NEAREST), mkexpr(op2)));
8249
8250 return "cdgbr";
8251}
8252
8253static HChar *
8254s390_irgen_CFEBR(UChar r3, UChar r1, UChar r2)
8255{
8256 IRTemp op = newTemp(Ity_F32);
8257 IRTemp result = newTemp(Ity_I32);
8258
8259 assign(op, get_fpr_w0(r2));
8260 assign(result, binop(Iop_F32toI32S, mkU32(encode_rounding_mode(r3)),
8261 mkexpr(op)));
8262 put_gpr_w1(r1, mkexpr(result));
8263 s390_cc_thunk_putF(S390_CC_OP_BFP_32_TO_INT_32, op);
8264
8265 return "cfebr";
8266}
8267
8268static HChar *
8269s390_irgen_CFDBR(UChar r3, UChar r1, UChar r2)
8270{
8271 IRTemp op = newTemp(Ity_F64);
8272 IRTemp result = newTemp(Ity_I32);
8273
8274 assign(op, get_fpr_dw0(r2));
8275 assign(result, binop(Iop_F64toI32S, mkU32(encode_rounding_mode(r3)),
8276 mkexpr(op)));
8277 put_gpr_w1(r1, mkexpr(result));
8278 s390_cc_thunk_putF(S390_CC_OP_BFP_64_TO_INT_32, op);
8279
8280 return "cfdbr";
8281}
8282
8283static HChar *
8284s390_irgen_CGEBR(UChar r3, UChar r1, UChar r2)
8285{
8286 IRTemp op = newTemp(Ity_F32);
8287 IRTemp result = newTemp(Ity_I64);
8288
8289 assign(op, get_fpr_w0(r2));
8290 assign(result, binop(Iop_F32toI64S, mkU32(encode_rounding_mode(r3)),
8291 mkexpr(op)));
8292 put_gpr_dw0(r1, mkexpr(result));
8293 s390_cc_thunk_putF(S390_CC_OP_BFP_32_TO_INT_64, op);
8294
8295 return "cgebr";
8296}
8297
8298static HChar *
8299s390_irgen_CGDBR(UChar r3, UChar r1, UChar r2)
8300{
8301 IRTemp op = newTemp(Ity_F64);
8302 IRTemp result = newTemp(Ity_I64);
8303
8304 assign(op, get_fpr_dw0(r2));
8305 assign(result, binop(Iop_F64toI64S, mkU32(encode_rounding_mode(r3)),
8306 mkexpr(op)));
8307 put_gpr_dw0(r1, mkexpr(result));
8308 s390_cc_thunk_putF(S390_CC_OP_BFP_64_TO_INT_64, op);
8309
8310 return "cgdbr";
8311}
8312
8313static HChar *
8314s390_irgen_DEBR(UChar r1, UChar r2)
8315{
8316 IRTemp op1 = newTemp(Ity_F32);
8317 IRTemp op2 = newTemp(Ity_F32);
8318 IRTemp result = newTemp(Ity_F32);
8319
8320 assign(op1, get_fpr_w0(r1));
8321 assign(op2, get_fpr_w0(r2));
8322 assign(result, triop(Iop_DivF32, mkU32(Irrm_NEAREST), mkexpr(op1),
8323 mkexpr(op2)));
8324 put_fpr_w0(r1, mkexpr(result));
8325
8326 return "debr";
8327}
8328
8329static HChar *
8330s390_irgen_DDBR(UChar r1, UChar r2)
8331{
8332 IRTemp op1 = newTemp(Ity_F64);
8333 IRTemp op2 = newTemp(Ity_F64);
8334 IRTemp result = newTemp(Ity_F64);
8335
8336 assign(op1, get_fpr_dw0(r1));
8337 assign(op2, get_fpr_dw0(r2));
8338 assign(result, triop(Iop_DivF64, mkU32(Irrm_NEAREST), mkexpr(op1),
8339 mkexpr(op2)));
8340 put_fpr_dw0(r1, mkexpr(result));
8341
8342 return "ddbr";
8343}
8344
8345static HChar *
8346s390_irgen_DEB(UChar r1, IRTemp op2addr)
8347{
8348 IRTemp op1 = newTemp(Ity_F32);
8349 IRTemp op2 = newTemp(Ity_F32);
8350 IRTemp result = newTemp(Ity_F32);
8351
8352 assign(op1, get_fpr_w0(r1));
8353 assign(op2, load(Ity_F32, mkexpr(op2addr)));
8354 assign(result, triop(Iop_DivF32, mkU32(Irrm_NEAREST), mkexpr(op1),
8355 mkexpr(op2)));
8356 put_fpr_w0(r1, mkexpr(result));
8357
8358 return "deb";
8359}
8360
8361static HChar *
8362s390_irgen_DDB(UChar r1, IRTemp op2addr)
8363{
8364 IRTemp op1 = newTemp(Ity_F64);
8365 IRTemp op2 = newTemp(Ity_F64);
8366 IRTemp result = newTemp(Ity_F64);
8367
8368 assign(op1, get_fpr_dw0(r1));
8369 assign(op2, load(Ity_F64, mkexpr(op2addr)));
8370 assign(result, triop(Iop_DivF64, mkU32(Irrm_NEAREST), mkexpr(op1),
8371 mkexpr(op2)));
8372 put_fpr_dw0(r1, mkexpr(result));
8373
8374 return "ddb";
8375}
8376
8377static HChar *
8378s390_irgen_LTEBR(UChar r1, UChar r2)
8379{
8380 IRTemp result = newTemp(Ity_F32);
8381
8382 assign(result, get_fpr_w0(r2));
8383 put_fpr_w0(r1, mkexpr(result));
8384 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
8385
8386 return "ltebr";
8387}
8388
8389static HChar *
8390s390_irgen_LTDBR(UChar r1, UChar r2)
8391{
8392 IRTemp result = newTemp(Ity_F64);
8393
8394 assign(result, get_fpr_dw0(r2));
8395 put_fpr_dw0(r1, mkexpr(result));
8396 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
8397
8398 return "ltdbr";
8399}
8400
8401static HChar *
8402s390_irgen_LCEBR(UChar r1, UChar r2)
8403{
8404 IRTemp result = newTemp(Ity_F32);
8405
8406 assign(result, unop(Iop_NegF32, get_fpr_w0(r2)));
8407 put_fpr_w0(r1, mkexpr(result));
8408 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
8409
8410 return "lcebr";
8411}
8412
8413static HChar *
8414s390_irgen_LCDBR(UChar r1, UChar r2)
8415{
8416 IRTemp result = newTemp(Ity_F64);
8417
8418 assign(result, unop(Iop_NegF64, get_fpr_dw0(r2)));
8419 put_fpr_dw0(r1, mkexpr(result));
8420 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
8421
8422 return "lcdbr";
8423}
8424
8425static HChar *
8426s390_irgen_LDEBR(UChar r1, UChar r2)
8427{
8428 IRTemp op = newTemp(Ity_F32);
8429
8430 assign(op, get_fpr_w0(r2));
8431 put_fpr_dw0(r1, unop(Iop_F32toF64, mkexpr(op)));
8432
8433 return "ldebr";
8434}
8435
8436static HChar *
8437s390_irgen_LDEB(UChar r1, IRTemp op2addr)
8438{
8439 IRTemp op = newTemp(Ity_F32);
8440
8441 assign(op, load(Ity_F32, mkexpr(op2addr)));
8442 put_fpr_dw0(r1, unop(Iop_F32toF64, mkexpr(op)));
8443
8444 return "ldeb";
8445}
8446
8447static HChar *
8448s390_irgen_LEDBR(UChar r1, UChar r2)
8449{
8450 IRTemp op = newTemp(Ity_F64);
8451
8452 assign(op, get_fpr_dw0(r2));
8453 put_fpr_w0(r1, binop(Iop_F64toF32, mkU32(Irrm_NEAREST), mkexpr(op)));
8454
8455 return "ledbr";
8456}
8457
8458static HChar *
8459s390_irgen_MEEBR(UChar r1, UChar r2)
8460{
8461 IRTemp op1 = newTemp(Ity_F32);
8462 IRTemp op2 = newTemp(Ity_F32);
8463 IRTemp result = newTemp(Ity_F32);
8464
8465 assign(op1, get_fpr_w0(r1));
8466 assign(op2, get_fpr_w0(r2));
8467 assign(result, triop(Iop_MulF32, mkU32(Irrm_NEAREST), mkexpr(op1),
8468 mkexpr(op2)));
8469 put_fpr_w0(r1, mkexpr(result));
8470
8471 return "meebr";
8472}
8473
8474static HChar *
8475s390_irgen_MDBR(UChar r1, UChar r2)
8476{
8477 IRTemp op1 = newTemp(Ity_F64);
8478 IRTemp op2 = newTemp(Ity_F64);
8479 IRTemp result = newTemp(Ity_F64);
8480
8481 assign(op1, get_fpr_dw0(r1));
8482 assign(op2, get_fpr_dw0(r2));
8483 assign(result, triop(Iop_MulF64, mkU32(Irrm_NEAREST), mkexpr(op1),
8484 mkexpr(op2)));
8485 put_fpr_dw0(r1, mkexpr(result));
8486
8487 return "mdbr";
8488}
8489
8490static HChar *
8491s390_irgen_MEEB(UChar r1, IRTemp op2addr)
8492{
8493 IRTemp op1 = newTemp(Ity_F32);
8494 IRTemp op2 = newTemp(Ity_F32);
8495 IRTemp result = newTemp(Ity_F32);
8496
8497 assign(op1, get_fpr_w0(r1));
8498 assign(op2, load(Ity_F32, mkexpr(op2addr)));
8499 assign(result, triop(Iop_MulF32, mkU32(Irrm_NEAREST), mkexpr(op1),
8500 mkexpr(op2)));
8501 put_fpr_w0(r1, mkexpr(result));
8502
8503 return "meeb";
8504}
8505
8506static HChar *
8507s390_irgen_MDB(UChar r1, IRTemp op2addr)
8508{
8509 IRTemp op1 = newTemp(Ity_F64);
8510 IRTemp op2 = newTemp(Ity_F64);
8511 IRTemp result = newTemp(Ity_F64);
8512
8513 assign(op1, get_fpr_dw0(r1));
8514 assign(op2, load(Ity_F64, mkexpr(op2addr)));
8515 assign(result, triop(Iop_MulF64, mkU32(Irrm_NEAREST), mkexpr(op1),
8516 mkexpr(op2)));
8517 put_fpr_dw0(r1, mkexpr(result));
8518
8519 return "mdb";
8520}
8521
8522static HChar *
8523s390_irgen_SEBR(UChar r1, UChar r2)
8524{
8525 IRTemp op1 = newTemp(Ity_F32);
8526 IRTemp op2 = newTemp(Ity_F32);
8527 IRTemp result = newTemp(Ity_F32);
8528
8529 assign(op1, get_fpr_w0(r1));
8530 assign(op2, get_fpr_w0(r2));
8531 assign(result, triop(Iop_SubF32, mkU32(Irrm_NEAREST), mkexpr(op1),
8532 mkexpr(op2)));
8533 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
8534 put_fpr_w0(r1, mkexpr(result));
8535
8536 return "sebr";
8537}
8538
8539static HChar *
8540s390_irgen_SDBR(UChar r1, UChar r2)
8541{
8542 IRTemp op1 = newTemp(Ity_F64);
8543 IRTemp op2 = newTemp(Ity_F64);
8544 IRTemp result = newTemp(Ity_F64);
8545
8546 assign(op1, get_fpr_dw0(r1));
8547 assign(op2, get_fpr_dw0(r2));
8548 assign(result, triop(Iop_SubF64, mkU32(Irrm_NEAREST), mkexpr(op1),
8549 mkexpr(op2)));
8550 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
8551 put_fpr_dw0(r1, mkexpr(result));
8552
8553 return "sdbr";
8554}
8555
8556static HChar *
8557s390_irgen_SEB(UChar r1, IRTemp op2addr)
8558{
8559 IRTemp op1 = newTemp(Ity_F32);
8560 IRTemp op2 = newTemp(Ity_F32);
8561 IRTemp result = newTemp(Ity_F32);
8562
8563 assign(op1, get_fpr_w0(r1));
8564 assign(op2, load(Ity_F32, mkexpr(op2addr)));
8565 assign(result, triop(Iop_SubF32, mkU32(Irrm_NEAREST), mkexpr(op1),
8566 mkexpr(op2)));
8567 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
8568 put_fpr_w0(r1, mkexpr(result));
8569
8570 return "seb";
8571}
8572
8573static HChar *
8574s390_irgen_SDB(UChar r1, IRTemp op2addr)
8575{
8576 IRTemp op1 = newTemp(Ity_F64);
8577 IRTemp op2 = newTemp(Ity_F64);
8578 IRTemp result = newTemp(Ity_F64);
8579
8580 assign(op1, get_fpr_dw0(r1));
8581 assign(op2, load(Ity_F64, mkexpr(op2addr)));
8582 assign(result, triop(Iop_SubF64, mkU32(Irrm_NEAREST), mkexpr(op1),
8583 mkexpr(op2)));
8584 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
8585 put_fpr_dw0(r1, mkexpr(result));
8586
8587 return "sdb";
8588}
8589
8590
8591static HChar *
8592s390_irgen_CLC(UChar length, IRTemp start1, IRTemp start2)
8593{
florian79e839e2012-05-05 02:20:30 +00008594 IRTemp len = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00008595
florian79e839e2012-05-05 02:20:30 +00008596 assign(len, mkU64(length));
8597 s390_irgen_CLC_EX(len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +00008598
8599 return "clc";
8600}
8601
8602static HChar *
florianb0c9a132011-09-08 15:37:39 +00008603s390_irgen_CLCL(UChar r1, UChar r2)
8604{
8605 IRTemp addr1 = newTemp(Ity_I64);
8606 IRTemp addr2 = newTemp(Ity_I64);
8607 IRTemp addr1_load = newTemp(Ity_I64);
8608 IRTemp addr2_load = newTemp(Ity_I64);
8609 IRTemp len1 = newTemp(Ity_I32);
8610 IRTemp len2 = newTemp(Ity_I32);
8611 IRTemp r1p1 = newTemp(Ity_I32); /* contents of r1 + 1 */
8612 IRTemp r2p1 = newTemp(Ity_I32); /* contents of r2 + 1 */
8613 IRTemp single1 = newTemp(Ity_I8);
8614 IRTemp single2 = newTemp(Ity_I8);
8615 IRTemp pad = newTemp(Ity_I8);
8616
8617 assign(addr1, get_gpr_dw0(r1));
8618 assign(r1p1, get_gpr_w1(r1 + 1));
8619 assign(len1, binop(Iop_And32, mkexpr(r1p1), mkU32(0x00ffffff)));
8620 assign(addr2, get_gpr_dw0(r2));
8621 assign(r2p1, get_gpr_w1(r2 + 1));
8622 assign(len2, binop(Iop_And32, mkexpr(r2p1), mkU32(0x00ffffff)));
8623 assign(pad, get_gpr_b4(r2 + 1));
8624
8625 /* len1 == 0 and len2 == 0? Exit */
8626 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +00008627 next_insn_if(binop(Iop_CmpEQ32, binop(Iop_Or32, mkexpr(len1),
8628 mkexpr(len2)), mkU32(0)));
florianb0c9a132011-09-08 15:37:39 +00008629
8630 /* Because mkite evaluates both the then-clause and the else-clause
8631 we cannot load directly from addr1 here. If len1 is 0, then adddr1
8632 may be NULL and loading from there would segfault. So we provide a
8633 valid dummy address in that case. Loading from there does no harm and
8634 the value will be discarded at runtime. */
8635 assign(addr1_load,
8636 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
8637 mkU64(guest_IA_curr_instr), mkexpr(addr1)));
8638 assign(single1,
8639 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
8640 mkexpr(pad), load(Ity_I8, mkexpr(addr1_load))));
8641
8642 assign(addr2_load,
8643 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
8644 mkU64(guest_IA_curr_instr), mkexpr(addr2)));
8645 assign(single2,
8646 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
8647 mkexpr(pad), load(Ity_I8, mkexpr(addr2_load))));
8648
8649 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, single1, single2, False);
8650 /* Fields differ ? */
florian6820ba52012-07-26 02:01:50 +00008651 next_insn_if(binop(Iop_CmpNE8, mkexpr(single1), mkexpr(single2)));
florianb0c9a132011-09-08 15:37:39 +00008652
8653 /* Update len1 and addr1, unless len1 == 0. */
8654 put_gpr_dw0(r1,
8655 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
8656 mkexpr(addr1),
8657 binop(Iop_Add64, mkexpr(addr1), mkU64(1))));
8658
8659 /* When updating len1 we must not modify bits (r1+1)[0:39] */
8660 put_gpr_w1(r1 + 1,
8661 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
8662 binop(Iop_And32, mkexpr(r1p1), mkU32(0xFF000000u)),
8663 binop(Iop_Sub32, mkexpr(r1p1), mkU32(1))));
8664
8665 /* Update len2 and addr2, unless len2 == 0. */
8666 put_gpr_dw0(r2,
8667 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
8668 mkexpr(addr2),
8669 binop(Iop_Add64, mkexpr(addr2), mkU64(1))));
8670
8671 /* When updating len2 we must not modify bits (r2+1)[0:39] */
8672 put_gpr_w1(r2 + 1,
8673 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
8674 binop(Iop_And32, mkexpr(r2p1), mkU32(0xFF000000u)),
8675 binop(Iop_Sub32, mkexpr(r2p1), mkU32(1))));
8676
florian6820ba52012-07-26 02:01:50 +00008677 iterate();
florianb0c9a132011-09-08 15:37:39 +00008678
8679 return "clcl";
8680}
8681
8682static HChar *
sewardj2019a972011-03-07 16:04:07 +00008683s390_irgen_CLCLE(UChar r1, UChar r3, IRTemp pad2)
8684{
8685 IRTemp addr1, addr3, addr1_load, addr3_load, len1, len3, single1, single3;
8686
8687 addr1 = newTemp(Ity_I64);
8688 addr3 = newTemp(Ity_I64);
8689 addr1_load = newTemp(Ity_I64);
8690 addr3_load = newTemp(Ity_I64);
8691 len1 = newTemp(Ity_I64);
8692 len3 = newTemp(Ity_I64);
8693 single1 = newTemp(Ity_I8);
8694 single3 = newTemp(Ity_I8);
8695
8696 assign(addr1, get_gpr_dw0(r1));
8697 assign(len1, get_gpr_dw0(r1 + 1));
8698 assign(addr3, get_gpr_dw0(r3));
8699 assign(len3, get_gpr_dw0(r3 + 1));
8700
8701 /* len1 == 0 and len3 == 0? Exit */
8702 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +00008703 next_insn_if(binop(Iop_CmpEQ64,binop(Iop_Or64, mkexpr(len1),
8704 mkexpr(len3)), mkU64(0)));
sewardj2019a972011-03-07 16:04:07 +00008705
8706 /* A mux requires both ways to be possible. This is a way to prevent clcle
8707 from reading from addr1 if it should read from the pad. Since the pad
8708 has no address, just read from the instruction, we discard that anyway */
8709 assign(addr1_load,
florian6ad49522011-09-09 02:38:55 +00008710 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
8711 mkU64(guest_IA_curr_instr), mkexpr(addr1)));
sewardj2019a972011-03-07 16:04:07 +00008712
8713 /* same for addr3 */
8714 assign(addr3_load,
florian6ad49522011-09-09 02:38:55 +00008715 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
8716 mkU64(guest_IA_curr_instr), mkexpr(addr3)));
sewardj2019a972011-03-07 16:04:07 +00008717
8718 assign(single1,
florian6ad49522011-09-09 02:38:55 +00008719 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
8720 unop(Iop_64to8, mkexpr(pad2)),
8721 load(Ity_I8, mkexpr(addr1_load))));
sewardj2019a972011-03-07 16:04:07 +00008722
8723 assign(single3,
florian6ad49522011-09-09 02:38:55 +00008724 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
8725 unop(Iop_64to8, mkexpr(pad2)),
8726 load(Ity_I8, mkexpr(addr3_load))));
sewardj2019a972011-03-07 16:04:07 +00008727
8728 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, single1, single3, False);
8729 /* Both fields differ ? */
florian6820ba52012-07-26 02:01:50 +00008730 next_insn_if(binop(Iop_CmpNE8, mkexpr(single1), mkexpr(single3)));
sewardj2019a972011-03-07 16:04:07 +00008731
8732 /* If a length in 0 we must not change this length and the address */
8733 put_gpr_dw0(r1,
florian6ad49522011-09-09 02:38:55 +00008734 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
8735 mkexpr(addr1),
8736 binop(Iop_Add64, mkexpr(addr1), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +00008737
8738 put_gpr_dw0(r1 + 1,
florian6ad49522011-09-09 02:38:55 +00008739 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
8740 mkU64(0), binop(Iop_Sub64, mkexpr(len1), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +00008741
8742 put_gpr_dw0(r3,
florian6ad49522011-09-09 02:38:55 +00008743 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
8744 mkexpr(addr3),
8745 binop(Iop_Add64, mkexpr(addr3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +00008746
8747 put_gpr_dw0(r3 + 1,
florian6ad49522011-09-09 02:38:55 +00008748 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
8749 mkU64(0), binop(Iop_Sub64, mkexpr(len3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +00008750
florian6820ba52012-07-26 02:01:50 +00008751 iterate();
sewardj2019a972011-03-07 16:04:07 +00008752
8753 return "clcle";
8754}
floriana64c2432011-07-16 02:11:50 +00008755
florianb0bf6602012-05-05 00:01:16 +00008756
sewardj2019a972011-03-07 16:04:07 +00008757static void
8758s390_irgen_XC_EX(IRTemp length, IRTemp start1, IRTemp start2)
8759{
florianb0bf6602012-05-05 00:01:16 +00008760 s390_irgen_xonc(Iop_Xor8, length, start1, start2);
8761}
sewardj2019a972011-03-07 16:04:07 +00008762
sewardj2019a972011-03-07 16:04:07 +00008763
florianb0bf6602012-05-05 00:01:16 +00008764static void
8765s390_irgen_NC_EX(IRTemp length, IRTemp start1, IRTemp start2)
8766{
8767 s390_irgen_xonc(Iop_And8, length, start1, start2);
8768}
sewardj2019a972011-03-07 16:04:07 +00008769
sewardj2019a972011-03-07 16:04:07 +00008770
florianb0bf6602012-05-05 00:01:16 +00008771static void
8772s390_irgen_OC_EX(IRTemp length, IRTemp start1, IRTemp start2)
8773{
8774 s390_irgen_xonc(Iop_Or8, length, start1, start2);
sewardj2019a972011-03-07 16:04:07 +00008775}
8776
8777
8778static void
8779s390_irgen_CLC_EX(IRTemp length, IRTemp start1, IRTemp start2)
8780{
8781 IRTemp current1 = newTemp(Ity_I8);
8782 IRTemp current2 = newTemp(Ity_I8);
8783 IRTemp counter = newTemp(Ity_I64);
8784
8785 assign(counter, get_counter_dw0());
8786 put_counter_dw0(mkU64(0));
8787
8788 assign(current1, load(Ity_I8, binop(Iop_Add64, mkexpr(start1),
8789 mkexpr(counter))));
8790 assign(current2, load(Ity_I8, binop(Iop_Add64, mkexpr(start2),
8791 mkexpr(counter))));
8792 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, current1, current2,
8793 False);
8794
8795 /* Both fields differ ? */
florian6820ba52012-07-26 02:01:50 +00008796 next_insn_if(binop(Iop_CmpNE8, mkexpr(current1), mkexpr(current2)));
sewardj2019a972011-03-07 16:04:07 +00008797
8798 /* Check for end of field */
8799 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
florian6820ba52012-07-26 02:01:50 +00008800 iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)));
sewardj2019a972011-03-07 16:04:07 +00008801 put_counter_dw0(mkU64(0));
8802}
8803
8804static void
8805s390_irgen_MVC_EX(IRTemp length, IRTemp start1, IRTemp start2)
8806{
8807 IRTemp counter = newTemp(Ity_I64);
8808
8809 assign(counter, get_counter_dw0());
8810
8811 store(binop(Iop_Add64, mkexpr(start1), mkexpr(counter)),
8812 load(Ity_I8, binop(Iop_Add64, mkexpr(start2), mkexpr(counter))));
8813
8814 /* Check for end of field */
8815 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
florian6820ba52012-07-26 02:01:50 +00008816 iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)));
sewardj2019a972011-03-07 16:04:07 +00008817 put_counter_dw0(mkU64(0));
8818}
8819
florianf87d4fb2012-05-05 02:55:24 +00008820static void
8821s390_irgen_TR_EX(IRTemp length, IRTemp start1, IRTemp start2)
8822{
8823 IRTemp op = newTemp(Ity_I8);
8824 IRTemp op1 = newTemp(Ity_I8);
8825 IRTemp result = newTemp(Ity_I64);
8826 IRTemp counter = newTemp(Ity_I64);
8827
8828 assign(counter, get_counter_dw0());
8829
8830 assign(op, load(Ity_I8, binop(Iop_Add64, mkexpr(start1), mkexpr(counter))));
8831
8832 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)), mkexpr(start2)));
8833
8834 assign(op1, load(Ity_I8, mkexpr(result)));
8835 store(binop(Iop_Add64, mkexpr(start1), mkexpr(counter)), mkexpr(op1));
8836
8837 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
florian6820ba52012-07-26 02:01:50 +00008838 iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)));
florianf87d4fb2012-05-05 02:55:24 +00008839 put_counter_dw0(mkU64(0));
8840}
sewardj2019a972011-03-07 16:04:07 +00008841
8842
8843static void
8844s390_irgen_EX_SS(UChar r, IRTemp addr2,
florian6820ba52012-07-26 02:01:50 +00008845 void (*irgen)(IRTemp length, IRTemp start1, IRTemp start2),
8846 int lensize)
sewardj2019a972011-03-07 16:04:07 +00008847{
8848 struct SS {
8849 unsigned int op : 8;
8850 unsigned int l : 8;
8851 unsigned int b1 : 4;
8852 unsigned int d1 : 12;
8853 unsigned int b2 : 4;
8854 unsigned int d2 : 12;
8855 };
8856 union {
8857 struct SS dec;
8858 unsigned long bytes;
8859 } ss;
8860 IRTemp cond;
8861 IRDirty *d;
8862 IRTemp torun;
8863
8864 IRTemp start1 = newTemp(Ity_I64);
8865 IRTemp start2 = newTemp(Ity_I64);
8866 IRTemp len = newTemp(lensize == 64 ? Ity_I64 : Ity_I32);
8867 cond = newTemp(Ity_I1);
8868 torun = newTemp(Ity_I64);
8869
8870 assign(torun, load(Ity_I64, mkexpr(addr2)));
8871 /* Start with a check that the saved code is still correct */
8872 assign(cond, binop(Iop_CmpNE64, mkexpr(torun), mkU64(last_execute_target)));
8873 /* If not, save the new value */
8874 d = unsafeIRDirty_0_N (0, "s390x_dirtyhelper_EX", &s390x_dirtyhelper_EX,
8875 mkIRExprVec_1(mkexpr(torun)));
8876 d->guard = mkexpr(cond);
8877 stmt(IRStmt_Dirty(d));
8878
8879 /* and restart */
florian428dfdd2012-03-27 03:09:49 +00008880 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TISTART),
8881 mkU64(guest_IA_curr_instr)));
8882 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TILEN), mkU64(4)));
florian6820ba52012-07-26 02:01:50 +00008883 restart_if(mkexpr(cond));
sewardj2019a972011-03-07 16:04:07 +00008884
8885 ss.bytes = last_execute_target;
8886 assign(start1, binop(Iop_Add64, mkU64(ss.dec.d1),
8887 ss.dec.b1 != 0 ? get_gpr_dw0(ss.dec.b1) : mkU64(0)));
8888 assign(start2, binop(Iop_Add64, mkU64(ss.dec.d2),
8889 ss.dec.b2 != 0 ? get_gpr_dw0(ss.dec.b2) : mkU64(0)));
8890 assign(len, unop(lensize == 64 ? Iop_8Uto64 : Iop_8Uto32, binop(Iop_Or8,
8891 r != 0 ? get_gpr_b7(r): mkU8(0), mkU8(ss.dec.l))));
8892 irgen(len, start1, start2);
florian8844a632012-04-13 04:04:06 +00008893
sewardj2019a972011-03-07 16:04:07 +00008894 last_execute_target = 0;
8895}
8896
8897static HChar *
8898s390_irgen_EX(UChar r1, IRTemp addr2)
8899{
8900 switch(last_execute_target & 0xff00000000000000ULL) {
8901 case 0:
8902 {
8903 /* no code information yet */
8904 IRDirty *d;
8905
8906 /* so safe the code... */
8907 d = unsafeIRDirty_0_N (0, "s390x_dirtyhelper_EX", &s390x_dirtyhelper_EX,
8908 mkIRExprVec_1(load(Ity_I64, mkexpr(addr2))));
8909 stmt(IRStmt_Dirty(d));
8910 /* and restart */
florian428dfdd2012-03-27 03:09:49 +00008911 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TISTART),
8912 mkU64(guest_IA_curr_instr)));
8913 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TILEN), mkU64(4)));
florian6820ba52012-07-26 02:01:50 +00008914 restart_if(IRExpr_Const(IRConst_U1(True)));
8915
sewardj2019a972011-03-07 16:04:07 +00008916 /* we know that this will be invalidated */
florianf9e1ed72012-04-17 02:41:56 +00008917 put_IA(mkaddr_expr(guest_IA_next_instr));
sewardj2019a972011-03-07 16:04:07 +00008918 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +00008919 dis_res->jk_StopHere = Ijk_TInval;
sewardj2019a972011-03-07 16:04:07 +00008920 break;
8921 }
8922
8923 case 0xd200000000000000ULL:
8924 /* special case MVC */
8925 s390_irgen_EX_SS(r1, addr2, s390_irgen_MVC_EX, 64);
8926 return "mvc via ex";
8927
8928 case 0xd500000000000000ULL:
8929 /* special case CLC */
8930 s390_irgen_EX_SS(r1, addr2, s390_irgen_CLC_EX, 64);
8931 return "clc via ex";
8932
8933 case 0xd700000000000000ULL:
8934 /* special case XC */
8935 s390_irgen_EX_SS(r1, addr2, s390_irgen_XC_EX, 32);
8936 return "xc via ex";
8937
florianb0bf6602012-05-05 00:01:16 +00008938 case 0xd600000000000000ULL:
8939 /* special case OC */
8940 s390_irgen_EX_SS(r1, addr2, s390_irgen_OC_EX, 32);
8941 return "oc via ex";
8942
8943 case 0xd400000000000000ULL:
8944 /* special case NC */
8945 s390_irgen_EX_SS(r1, addr2, s390_irgen_NC_EX, 32);
8946 return "nc via ex";
sewardj2019a972011-03-07 16:04:07 +00008947
florianf87d4fb2012-05-05 02:55:24 +00008948 case 0xdc00000000000000ULL:
8949 /* special case TR */
8950 s390_irgen_EX_SS(r1, addr2, s390_irgen_TR_EX, 64);
8951 return "tr via ex";
8952
sewardj2019a972011-03-07 16:04:07 +00008953 default:
8954 {
8955 /* everything else will get a self checking prefix that also checks the
8956 register content */
8957 IRDirty *d;
8958 UChar *bytes;
8959 IRTemp cond;
8960 IRTemp orperand;
8961 IRTemp torun;
8962
8963 cond = newTemp(Ity_I1);
8964 orperand = newTemp(Ity_I64);
8965 torun = newTemp(Ity_I64);
8966
8967 if (r1 == 0)
8968 assign(orperand, mkU64(0));
8969 else
8970 assign(orperand, unop(Iop_8Uto64,get_gpr_b7(r1)));
8971 /* This code is going to be translated */
8972 assign(torun, binop(Iop_Or64, load(Ity_I64, mkexpr(addr2)),
8973 binop(Iop_Shl64, mkexpr(orperand), mkU8(48))));
8974
8975 /* Start with a check that saved code is still correct */
8976 assign(cond, binop(Iop_CmpNE64, mkexpr(torun),
8977 mkU64(last_execute_target)));
8978 /* If not, save the new value */
8979 d = unsafeIRDirty_0_N (0, "s390x_dirtyhelper_EX", &s390x_dirtyhelper_EX,
8980 mkIRExprVec_1(mkexpr(torun)));
8981 d->guard = mkexpr(cond);
8982 stmt(IRStmt_Dirty(d));
8983
8984 /* and restart */
florian428dfdd2012-03-27 03:09:49 +00008985 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TISTART), mkU64(guest_IA_curr_instr)));
8986 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TILEN), mkU64(4)));
florian6820ba52012-07-26 02:01:50 +00008987 restart_if(mkexpr(cond));
sewardj2019a972011-03-07 16:04:07 +00008988
8989 /* Now comes the actual translation */
8990 bytes = (UChar *) &last_execute_target;
8991 s390_decode_and_irgen(bytes, ((((bytes[0] >> 6) + 1) >> 1) + 1) << 1,
8992 dis_res);
sewardj7ee97522011-05-09 21:45:04 +00008993 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00008994 vex_printf(" which was executed by\n");
8995 /* dont make useless translations in the next execute */
8996 last_execute_target = 0;
8997 }
8998 }
8999 return "ex";
9000}
9001
9002static HChar *
9003s390_irgen_EXRL(UChar r1, UInt offset)
9004{
9005 IRTemp addr = newTemp(Ity_I64);
9006 /* we might save one round trip because we know the target */
9007 if (!last_execute_target)
9008 last_execute_target = *(ULong *)(HWord)
9009 (guest_IA_curr_instr + offset * 2UL);
9010 assign(addr, mkU64(guest_IA_curr_instr + offset * 2UL));
9011 s390_irgen_EX(r1, addr);
9012 return "exrl";
9013}
9014
9015static HChar *
9016s390_irgen_IPM(UChar r1)
9017{
9018 // As long as we dont support SPM, lets just assume 0 as program mask
9019 put_gpr_b4(r1, unop(Iop_32to8, binop(Iop_Or32, mkU32(0 /* program mask */),
9020 binop(Iop_Shl32, s390_call_calculate_cc(), mkU8(4)))));
9021
9022 return "ipm";
9023}
9024
9025
9026static HChar *
9027s390_irgen_SRST(UChar r1, UChar r2)
9028{
9029 IRTemp address = newTemp(Ity_I64);
9030 IRTemp next = newTemp(Ity_I64);
9031 IRTemp delim = newTemp(Ity_I8);
9032 IRTemp counter = newTemp(Ity_I64);
9033 IRTemp byte = newTemp(Ity_I8);
9034
9035 assign(address, get_gpr_dw0(r2));
9036 assign(next, get_gpr_dw0(r1));
9037
9038 assign(counter, get_counter_dw0());
9039 put_counter_dw0(mkU64(0));
9040
9041 // start = next? CC=2 and out r1 and r2 unchanged
9042 s390_cc_set(2);
9043 put_gpr_dw0(r2, binop(Iop_Sub64, mkexpr(address), mkexpr(counter)));
florian6820ba52012-07-26 02:01:50 +00009044 next_insn_if(binop(Iop_CmpEQ64, mkexpr(address), mkexpr(next)));
sewardj2019a972011-03-07 16:04:07 +00009045
9046 assign(byte, load(Ity_I8, mkexpr(address)));
9047 assign(delim, get_gpr_b7(0));
9048
9049 // byte = delim? CC=1, R1=address
9050 s390_cc_set(1);
9051 put_gpr_dw0(r1, mkexpr(address));
florian6820ba52012-07-26 02:01:50 +00009052 next_insn_if(binop(Iop_CmpEQ8, mkexpr(delim), mkexpr(byte)));
sewardj2019a972011-03-07 16:04:07 +00009053
9054 // else: all equal, no end yet, loop
9055 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
9056 put_gpr_dw0(r1, mkexpr(next));
9057 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(address), mkU64(1)));
floriancf87c942012-07-25 00:52:21 +00009058
florian6820ba52012-07-26 02:01:50 +00009059 iterate();
sewardj2019a972011-03-07 16:04:07 +00009060
9061 return "srst";
9062}
9063
9064static HChar *
9065s390_irgen_CLST(UChar r1, UChar r2)
9066{
9067 IRTemp address1 = newTemp(Ity_I64);
9068 IRTemp address2 = newTemp(Ity_I64);
9069 IRTemp end = newTemp(Ity_I8);
9070 IRTemp counter = newTemp(Ity_I64);
9071 IRTemp byte1 = newTemp(Ity_I8);
9072 IRTemp byte2 = newTemp(Ity_I8);
9073
9074 assign(address1, get_gpr_dw0(r1));
9075 assign(address2, get_gpr_dw0(r2));
9076 assign(end, get_gpr_b7(0));
9077 assign(counter, get_counter_dw0());
9078 put_counter_dw0(mkU64(0));
9079 assign(byte1, load(Ity_I8, mkexpr(address1)));
9080 assign(byte2, load(Ity_I8, mkexpr(address2)));
9081
9082 // end in both? all equal, reset r1 and r2 to start values
9083 s390_cc_set(0);
9084 put_gpr_dw0(r1, binop(Iop_Sub64, mkexpr(address1), mkexpr(counter)));
9085 put_gpr_dw0(r2, binop(Iop_Sub64, mkexpr(address2), mkexpr(counter)));
florian6820ba52012-07-26 02:01:50 +00009086 next_insn_if(binop(Iop_CmpEQ8, mkU8(0),
9087 binop(Iop_Or8,
9088 binop(Iop_Xor8, mkexpr(byte1), mkexpr(end)),
9089 binop(Iop_Xor8, mkexpr(byte2), mkexpr(end)))));
sewardj2019a972011-03-07 16:04:07 +00009090
9091 put_gpr_dw0(r1, mkexpr(address1));
9092 put_gpr_dw0(r2, mkexpr(address2));
9093
9094 // End found in string1
9095 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +00009096 next_insn_if(binop(Iop_CmpEQ8, mkexpr(end), mkexpr(byte1)));
sewardj2019a972011-03-07 16:04:07 +00009097
9098 // End found in string2
9099 s390_cc_set(2);
florian6820ba52012-07-26 02:01:50 +00009100 next_insn_if(binop(Iop_CmpEQ8, mkexpr(end), mkexpr(byte2)));
sewardj2019a972011-03-07 16:04:07 +00009101
9102 // string1 < string2
9103 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +00009104 next_insn_if(binop(Iop_CmpLT32U, unop(Iop_8Uto32, mkexpr(byte1)),
9105 unop(Iop_8Uto32, mkexpr(byte2))));
sewardj2019a972011-03-07 16:04:07 +00009106
9107 // string2 < string1
9108 s390_cc_set(2);
florian6820ba52012-07-26 02:01:50 +00009109 next_insn_if(binop(Iop_CmpLT32U, unop(Iop_8Uto32, mkexpr(byte2)),
9110 unop(Iop_8Uto32, mkexpr(byte1))));
sewardj2019a972011-03-07 16:04:07 +00009111
9112 // else: all equal, no end yet, loop
9113 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
9114 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), mkU64(1)));
9115 put_gpr_dw0(r2, binop(Iop_Add64, get_gpr_dw0(r2), mkU64(1)));
floriancf87c942012-07-25 00:52:21 +00009116
florian6820ba52012-07-26 02:01:50 +00009117 iterate();
sewardj2019a972011-03-07 16:04:07 +00009118
9119 return "clst";
9120}
9121
9122static void
9123s390_irgen_load_multiple_32bit(UChar r1, UChar r3, IRTemp op2addr)
9124{
9125 UChar reg;
9126 IRTemp addr = newTemp(Ity_I64);
9127
9128 assign(addr, mkexpr(op2addr));
9129 reg = r1;
9130 do {
9131 IRTemp old = addr;
9132
9133 reg %= 16;
9134 put_gpr_w1(reg, load(Ity_I32, mkexpr(addr)));
9135 addr = newTemp(Ity_I64);
9136 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
9137 reg++;
9138 } while (reg != (r3 + 1));
9139}
9140
9141static HChar *
9142s390_irgen_LM(UChar r1, UChar r3, IRTemp op2addr)
9143{
9144 s390_irgen_load_multiple_32bit(r1, r3, op2addr);
9145
9146 return "lm";
9147}
9148
9149static HChar *
9150s390_irgen_LMY(UChar r1, UChar r3, IRTemp op2addr)
9151{
9152 s390_irgen_load_multiple_32bit(r1, r3, op2addr);
9153
9154 return "lmy";
9155}
9156
9157static HChar *
9158s390_irgen_LMH(UChar r1, UChar r3, IRTemp op2addr)
9159{
9160 UChar reg;
9161 IRTemp addr = newTemp(Ity_I64);
9162
9163 assign(addr, mkexpr(op2addr));
9164 reg = r1;
9165 do {
9166 IRTemp old = addr;
9167
9168 reg %= 16;
9169 put_gpr_w0(reg, load(Ity_I32, mkexpr(addr)));
9170 addr = newTemp(Ity_I64);
9171 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
9172 reg++;
9173 } while (reg != (r3 + 1));
9174
9175 return "lmh";
9176}
9177
9178static HChar *
9179s390_irgen_LMG(UChar r1, UChar r3, IRTemp op2addr)
9180{
9181 UChar reg;
9182 IRTemp addr = newTemp(Ity_I64);
9183
9184 assign(addr, mkexpr(op2addr));
9185 reg = r1;
9186 do {
9187 IRTemp old = addr;
9188
9189 reg %= 16;
9190 put_gpr_dw0(reg, load(Ity_I64, mkexpr(addr)));
9191 addr = newTemp(Ity_I64);
9192 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(8)));
9193 reg++;
9194 } while (reg != (r3 + 1));
9195
9196 return "lmg";
9197}
9198
9199static void
9200s390_irgen_store_multiple_32bit(UChar r1, UChar r3, IRTemp op2addr)
9201{
9202 UChar reg;
9203 IRTemp addr = newTemp(Ity_I64);
9204
9205 assign(addr, mkexpr(op2addr));
9206 reg = r1;
9207 do {
9208 IRTemp old = addr;
9209
9210 reg %= 16;
9211 store(mkexpr(addr), get_gpr_w1(reg));
9212 addr = newTemp(Ity_I64);
9213 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
9214 reg++;
9215 } while( reg != (r3 + 1));
9216}
9217
9218static HChar *
9219s390_irgen_STM(UChar r1, UChar r3, IRTemp op2addr)
9220{
9221 s390_irgen_store_multiple_32bit(r1, r3, op2addr);
9222
9223 return "stm";
9224}
9225
9226static HChar *
9227s390_irgen_STMY(UChar r1, UChar r3, IRTemp op2addr)
9228{
9229 s390_irgen_store_multiple_32bit(r1, r3, op2addr);
9230
9231 return "stmy";
9232}
9233
9234static HChar *
9235s390_irgen_STMH(UChar r1, UChar r3, IRTemp op2addr)
9236{
9237 UChar reg;
9238 IRTemp addr = newTemp(Ity_I64);
9239
9240 assign(addr, mkexpr(op2addr));
9241 reg = r1;
9242 do {
9243 IRTemp old = addr;
9244
9245 reg %= 16;
9246 store(mkexpr(addr), get_gpr_w0(reg));
9247 addr = newTemp(Ity_I64);
9248 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
9249 reg++;
9250 } while( reg != (r3 + 1));
9251
9252 return "stmh";
9253}
9254
9255static HChar *
9256s390_irgen_STMG(UChar r1, UChar r3, IRTemp op2addr)
9257{
9258 UChar reg;
9259 IRTemp addr = newTemp(Ity_I64);
9260
9261 assign(addr, mkexpr(op2addr));
9262 reg = r1;
9263 do {
9264 IRTemp old = addr;
9265
9266 reg %= 16;
9267 store(mkexpr(addr), get_gpr_dw0(reg));
9268 addr = newTemp(Ity_I64);
9269 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(8)));
9270 reg++;
9271 } while( reg != (r3 + 1));
9272
9273 return "stmg";
9274}
9275
9276static void
florianb0bf6602012-05-05 00:01:16 +00009277s390_irgen_xonc(IROp op, IRTemp length, IRTemp start1, IRTemp start2)
sewardj2019a972011-03-07 16:04:07 +00009278{
9279 IRTemp old1 = newTemp(Ity_I8);
9280 IRTemp old2 = newTemp(Ity_I8);
9281 IRTemp new1 = newTemp(Ity_I8);
9282 IRTemp counter = newTemp(Ity_I32);
9283 IRTemp addr1 = newTemp(Ity_I64);
9284
9285 assign(counter, get_counter_w0());
9286
9287 assign(addr1, binop(Iop_Add64, mkexpr(start1),
9288 unop(Iop_32Uto64, mkexpr(counter))));
9289
9290 assign(old1, load(Ity_I8, mkexpr(addr1)));
9291 assign(old2, load(Ity_I8, binop(Iop_Add64, mkexpr(start2),
9292 unop(Iop_32Uto64,mkexpr(counter)))));
9293 assign(new1, binop(op, mkexpr(old1), mkexpr(old2)));
9294
9295 /* Special case: xc is used to zero memory */
sewardj2019a972011-03-07 16:04:07 +00009296 if (op == Iop_Xor8) {
9297 store(mkexpr(addr1),
florian6ad49522011-09-09 02:38:55 +00009298 mkite(binop(Iop_CmpEQ64, mkexpr(start1), mkexpr(start2)),
9299 mkU8(0), mkexpr(new1)));
sewardj2019a972011-03-07 16:04:07 +00009300 } else
9301 store(mkexpr(addr1), mkexpr(new1));
9302 put_counter_w1(binop(Iop_Or32, unop(Iop_8Uto32, mkexpr(new1)),
9303 get_counter_w1()));
9304
9305 /* Check for end of field */
9306 put_counter_w0(binop(Iop_Add32, mkexpr(counter), mkU32(1)));
florian6820ba52012-07-26 02:01:50 +00009307 iterate_if(binop(Iop_CmpNE32, mkexpr(counter), mkexpr(length)));
sewardj2019a972011-03-07 16:04:07 +00009308 s390_cc_thunk_put1(S390_CC_OP_BITWISE, mktemp(Ity_I32, get_counter_w1()),
9309 False);
9310 put_counter_dw0(mkU64(0));
9311}
9312
9313static HChar *
9314s390_irgen_XC(UChar length, IRTemp start1, IRTemp start2)
9315{
florianb0bf6602012-05-05 00:01:16 +00009316 IRTemp len = newTemp(Ity_I32);
9317
9318 assign(len, mkU32(length));
9319 s390_irgen_xonc(Iop_Xor8, len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +00009320
9321 return "xc";
9322}
9323
sewardjb63967e2011-03-24 08:50:04 +00009324static void
9325s390_irgen_XC_sameloc(UChar length, UChar b, UShort d)
9326{
9327 IRTemp counter = newTemp(Ity_I32);
9328 IRTemp start = newTemp(Ity_I64);
9329 IRTemp addr = newTemp(Ity_I64);
9330
9331 assign(start,
9332 binop(Iop_Add64, mkU64(d), b != 0 ? get_gpr_dw0(b) : mkU64(0)));
9333
9334 if (length < 8) {
9335 UInt i;
9336
9337 for (i = 0; i <= length; ++i) {
9338 store(binop(Iop_Add64, mkexpr(start), mkU64(i)), mkU8(0));
9339 }
9340 } else {
9341 assign(counter, get_counter_w0());
9342
9343 assign(addr, binop(Iop_Add64, mkexpr(start),
9344 unop(Iop_32Uto64, mkexpr(counter))));
9345
9346 store(mkexpr(addr), mkU8(0));
9347
9348 /* Check for end of field */
9349 put_counter_w0(binop(Iop_Add32, mkexpr(counter), mkU32(1)));
florian6820ba52012-07-26 02:01:50 +00009350 iterate_if(binop(Iop_CmpNE32, mkexpr(counter), mkU32(length)));
sewardjb63967e2011-03-24 08:50:04 +00009351
9352 /* Reset counter */
9353 put_counter_dw0(mkU64(0));
9354 }
9355
9356 s390_cc_thunk_put1(S390_CC_OP_BITWISE, mktemp(Ity_I32, mkU32(0)), False);
9357
sewardj7ee97522011-05-09 21:45:04 +00009358 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardjb63967e2011-03-24 08:50:04 +00009359 s390_disasm(ENC3(MNM, UDLB, UDXB), "xc", d, length, b, d, 0, b);
9360}
9361
sewardj2019a972011-03-07 16:04:07 +00009362static HChar *
9363s390_irgen_NC(UChar length, IRTemp start1, IRTemp start2)
9364{
florianb0bf6602012-05-05 00:01:16 +00009365 IRTemp len = newTemp(Ity_I32);
9366
9367 assign(len, mkU32(length));
9368 s390_irgen_xonc(Iop_And8, len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +00009369
9370 return "nc";
9371}
9372
9373static HChar *
9374s390_irgen_OC(UChar length, IRTemp start1, IRTemp start2)
9375{
florianb0bf6602012-05-05 00:01:16 +00009376 IRTemp len = newTemp(Ity_I32);
9377
9378 assign(len, mkU32(length));
9379 s390_irgen_xonc(Iop_Or8, len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +00009380
9381 return "oc";
9382}
9383
9384
9385static HChar *
9386s390_irgen_MVC(UChar length, IRTemp start1, IRTemp start2)
9387{
florian79e839e2012-05-05 02:20:30 +00009388 IRTemp len = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00009389
florian79e839e2012-05-05 02:20:30 +00009390 assign(len, mkU64(length));
9391 s390_irgen_MVC_EX(len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +00009392
9393 return "mvc";
9394}
9395
9396static HChar *
florianb0c9a132011-09-08 15:37:39 +00009397s390_irgen_MVCL(UChar r1, UChar r2)
9398{
9399 IRTemp addr1 = newTemp(Ity_I64);
9400 IRTemp addr2 = newTemp(Ity_I64);
9401 IRTemp addr2_load = newTemp(Ity_I64);
9402 IRTemp r1p1 = newTemp(Ity_I32); /* contents of r1 + 1 */
9403 IRTemp r2p1 = newTemp(Ity_I32); /* contents of r2 + 1 */
9404 IRTemp len1 = newTemp(Ity_I32);
9405 IRTemp len2 = newTemp(Ity_I32);
9406 IRTemp pad = newTemp(Ity_I8);
9407 IRTemp single = newTemp(Ity_I8);
9408
9409 assign(addr1, get_gpr_dw0(r1));
9410 assign(r1p1, get_gpr_w1(r1 + 1));
9411 assign(len1, binop(Iop_And32, mkexpr(r1p1), mkU32(0x00ffffff)));
9412 assign(addr2, get_gpr_dw0(r2));
9413 assign(r2p1, get_gpr_w1(r2 + 1));
9414 assign(len2, binop(Iop_And32, mkexpr(r2p1), mkU32(0x00ffffff)));
9415 assign(pad, get_gpr_b4(r2 + 1));
9416
9417 /* len1 == 0 ? */
9418 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len2, False);
florian6820ba52012-07-26 02:01:50 +00009419 next_insn_if(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)));
florianb0c9a132011-09-08 15:37:39 +00009420
9421 /* Check for destructive overlap:
9422 addr1 > addr2 && addr2 + len1 > addr1 && (addr2 + len2) > addr1 */
9423 s390_cc_set(3);
9424 IRTemp cond1 = newTemp(Ity_I32);
9425 assign(cond1, unop(Iop_1Uto32,
9426 binop(Iop_CmpLT64U, mkexpr(addr2), mkexpr(addr1))));
9427 IRTemp cond2 = newTemp(Ity_I32);
9428 assign(cond2, unop(Iop_1Uto32,
9429 binop(Iop_CmpLT64U, mkexpr(addr1),
9430 binop(Iop_Add64, mkexpr(addr2),
9431 unop(Iop_32Uto64, mkexpr(len1))))));
9432 IRTemp cond3 = newTemp(Ity_I32);
9433 assign(cond3, unop(Iop_1Uto32,
9434 binop(Iop_CmpLT64U,
9435 mkexpr(addr1),
9436 binop(Iop_Add64, mkexpr(addr2),
9437 unop(Iop_32Uto64, mkexpr(len2))))));
9438
florian6820ba52012-07-26 02:01:50 +00009439 next_insn_if(binop(Iop_CmpEQ32,
9440 binop(Iop_And32,
9441 binop(Iop_And32, mkexpr(cond1), mkexpr(cond2)),
9442 mkexpr(cond3)),
9443 mkU32(1)));
florianb0c9a132011-09-08 15:37:39 +00009444
9445 /* See s390_irgen_CLCL for explanation why we cannot load directly
9446 and need two steps. */
9447 assign(addr2_load,
9448 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
9449 mkU64(guest_IA_curr_instr), mkexpr(addr2)));
9450 assign(single,
9451 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
9452 mkexpr(pad), load(Ity_I8, mkexpr(addr2_load))));
9453
9454 store(mkexpr(addr1), mkexpr(single));
9455
9456 /* Update addr1 and len1 */
9457 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkU64(1)));
9458 put_gpr_w1(r1 + 1, binop(Iop_Sub32, mkexpr(r1p1), mkU32(1)));
9459
9460 /* Update addr2 and len2 */
9461 put_gpr_dw0(r2,
9462 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
9463 mkexpr(addr2),
9464 binop(Iop_Add64, mkexpr(addr2), mkU64(1))));
9465
9466 /* When updating len2 we must not modify bits (r2+1)[0:39] */
9467 put_gpr_w1(r2 + 1,
9468 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
9469 binop(Iop_And32, mkexpr(r2p1), mkU32(0xFF000000u)),
9470 binop(Iop_Sub32, mkexpr(r2p1), mkU32(1))));
9471
9472 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len2, False);
florian6820ba52012-07-26 02:01:50 +00009473 iterate_if(binop(Iop_CmpNE32, mkexpr(len1), mkU32(1)));
florianb0c9a132011-09-08 15:37:39 +00009474
9475 return "mvcl";
9476}
9477
9478
9479static HChar *
sewardj2019a972011-03-07 16:04:07 +00009480s390_irgen_MVCLE(UChar r1, UChar r3, IRTemp pad2)
9481{
9482 IRTemp addr1, addr3, addr3_load, len1, len3, single;
9483
9484 addr1 = newTemp(Ity_I64);
9485 addr3 = newTemp(Ity_I64);
9486 addr3_load = newTemp(Ity_I64);
9487 len1 = newTemp(Ity_I64);
9488 len3 = newTemp(Ity_I64);
9489 single = newTemp(Ity_I8);
9490
9491 assign(addr1, get_gpr_dw0(r1));
9492 assign(len1, get_gpr_dw0(r1 + 1));
9493 assign(addr3, get_gpr_dw0(r3));
9494 assign(len3, get_gpr_dw0(r3 + 1));
9495
9496 // len1 == 0 ?
9497 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len3, False);
florian6820ba52012-07-26 02:01:50 +00009498 next_insn_if(binop(Iop_CmpEQ64,mkexpr(len1), mkU64(0)));
sewardj2019a972011-03-07 16:04:07 +00009499
9500 /* This is a hack to prevent mvcle from reading from addr3 if it
9501 should read from the pad. Since the pad has no address, just
9502 read from the instruction, we discard that anyway */
9503 assign(addr3_load,
florian6ad49522011-09-09 02:38:55 +00009504 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
9505 mkU64(guest_IA_curr_instr), mkexpr(addr3)));
sewardj2019a972011-03-07 16:04:07 +00009506
9507 assign(single,
florian6ad49522011-09-09 02:38:55 +00009508 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
9509 unop(Iop_64to8, mkexpr(pad2)),
9510 load(Ity_I8, mkexpr(addr3_load))));
sewardj2019a972011-03-07 16:04:07 +00009511 store(mkexpr(addr1), mkexpr(single));
9512
9513 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkU64(1)));
9514
9515 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkU64(1)));
9516
9517 put_gpr_dw0(r3,
florian6ad49522011-09-09 02:38:55 +00009518 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
9519 mkexpr(addr3),
9520 binop(Iop_Add64, mkexpr(addr3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +00009521
9522 put_gpr_dw0(r3 + 1,
florian6ad49522011-09-09 02:38:55 +00009523 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
9524 mkU64(0), binop(Iop_Sub64, mkexpr(len3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +00009525
sewardj2019a972011-03-07 16:04:07 +00009526 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len3, False);
florian6820ba52012-07-26 02:01:50 +00009527 iterate_if(binop(Iop_CmpNE64, mkexpr(len1), mkU64(1)));
sewardj2019a972011-03-07 16:04:07 +00009528
9529 return "mvcle";
9530}
9531
9532static HChar *
9533s390_irgen_MVST(UChar r1, UChar r2)
9534{
9535 IRTemp addr1 = newTemp(Ity_I64);
9536 IRTemp addr2 = newTemp(Ity_I64);
9537 IRTemp end = newTemp(Ity_I8);
9538 IRTemp byte = newTemp(Ity_I8);
9539 IRTemp counter = newTemp(Ity_I64);
9540
9541 assign(addr1, get_gpr_dw0(r1));
9542 assign(addr2, get_gpr_dw0(r2));
9543 assign(counter, get_counter_dw0());
9544 assign(end, get_gpr_b7(0));
9545 assign(byte, load(Ity_I8, binop(Iop_Add64, mkexpr(addr2),mkexpr(counter))));
9546 store(binop(Iop_Add64,mkexpr(addr1),mkexpr(counter)), mkexpr(byte));
9547
9548 // We use unlimited as cpu-determined number
9549 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
florian6820ba52012-07-26 02:01:50 +00009550 iterate_if(binop(Iop_CmpNE8, mkexpr(end), mkexpr(byte)));
sewardj2019a972011-03-07 16:04:07 +00009551
9552 // and always set cc=1 at the end + update r1
9553 s390_cc_set(1);
9554 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(counter)));
9555 put_counter_dw0(mkU64(0));
9556
9557 return "mvst";
9558}
9559
9560static void
9561s390_irgen_divide_64to32(IROp op, UChar r1, IRTemp op2)
9562{
9563 IRTemp op1 = newTemp(Ity_I64);
9564 IRTemp result = newTemp(Ity_I64);
9565
9566 assign(op1, binop(Iop_32HLto64,
9567 get_gpr_w1(r1), // high 32 bits
9568 get_gpr_w1(r1 + 1))); // low 32 bits
9569 assign(result, binop(op, mkexpr(op1), mkexpr(op2)));
9570 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result))); // remainder
9571 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result))); // quotient
9572}
9573
9574static void
9575s390_irgen_divide_128to64(IROp op, UChar r1, IRTemp op2)
9576{
9577 IRTemp op1 = newTemp(Ity_I128);
9578 IRTemp result = newTemp(Ity_I128);
9579
9580 assign(op1, binop(Iop_64HLto128,
9581 get_gpr_dw0(r1), // high 64 bits
9582 get_gpr_dw0(r1 + 1))); // low 64 bits
9583 assign(result, binop(op, mkexpr(op1), mkexpr(op2)));
9584 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result))); // remainder
9585 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result))); // quotient
9586}
9587
9588static void
9589s390_irgen_divide_64to64(IROp op, UChar r1, IRTemp op2)
9590{
9591 IRTemp op1 = newTemp(Ity_I64);
9592 IRTemp result = newTemp(Ity_I128);
9593
9594 assign(op1, get_gpr_dw0(r1 + 1));
9595 assign(result, binop(op, mkexpr(op1), mkexpr(op2)));
9596 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result))); // remainder
9597 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result))); // quotient
9598}
9599
9600static HChar *
9601s390_irgen_DR(UChar r1, UChar r2)
9602{
9603 IRTemp op2 = newTemp(Ity_I32);
9604
9605 assign(op2, get_gpr_w1(r2));
9606
9607 s390_irgen_divide_64to32(Iop_DivModS64to32, r1, op2);
9608
9609 return "dr";
9610}
9611
9612static HChar *
9613s390_irgen_D(UChar r1, IRTemp op2addr)
9614{
9615 IRTemp op2 = newTemp(Ity_I32);
9616
9617 assign(op2, load(Ity_I32, mkexpr(op2addr)));
9618
9619 s390_irgen_divide_64to32(Iop_DivModS64to32, r1, op2);
9620
9621 return "d";
9622}
9623
9624static HChar *
9625s390_irgen_DLR(UChar r1, UChar r2)
9626{
9627 IRTemp op2 = newTemp(Ity_I32);
9628
9629 assign(op2, get_gpr_w1(r2));
9630
9631 s390_irgen_divide_64to32(Iop_DivModU64to32, r1, op2);
9632
9633 return "dr";
9634}
9635
9636static HChar *
9637s390_irgen_DL(UChar r1, IRTemp op2addr)
9638{
9639 IRTemp op2 = newTemp(Ity_I32);
9640
9641 assign(op2, load(Ity_I32, mkexpr(op2addr)));
9642
9643 s390_irgen_divide_64to32(Iop_DivModU64to32, r1, op2);
9644
9645 return "dl";
9646}
9647
9648static HChar *
9649s390_irgen_DLG(UChar r1, IRTemp op2addr)
9650{
9651 IRTemp op2 = newTemp(Ity_I64);
9652
9653 assign(op2, load(Ity_I64, mkexpr(op2addr)));
9654
9655 s390_irgen_divide_128to64(Iop_DivModU128to64, r1, op2);
9656
9657 return "dlg";
9658}
9659
9660static HChar *
9661s390_irgen_DLGR(UChar r1, UChar r2)
9662{
9663 IRTemp op2 = newTemp(Ity_I64);
9664
9665 assign(op2, get_gpr_dw0(r2));
9666
9667 s390_irgen_divide_128to64(Iop_DivModU128to64, r1, op2);
9668
9669 return "dlgr";
9670}
9671
9672static HChar *
9673s390_irgen_DSGR(UChar r1, UChar r2)
9674{
9675 IRTemp op2 = newTemp(Ity_I64);
9676
9677 assign(op2, get_gpr_dw0(r2));
9678
9679 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
9680
9681 return "dsgr";
9682}
9683
9684static HChar *
9685s390_irgen_DSG(UChar r1, IRTemp op2addr)
9686{
9687 IRTemp op2 = newTemp(Ity_I64);
9688
9689 assign(op2, load(Ity_I64, mkexpr(op2addr)));
9690
9691 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
9692
9693 return "dsg";
9694}
9695
9696static HChar *
9697s390_irgen_DSGFR(UChar r1, UChar r2)
9698{
9699 IRTemp op2 = newTemp(Ity_I64);
9700
9701 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
9702
9703 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
9704
9705 return "dsgfr";
9706}
9707
9708static HChar *
9709s390_irgen_DSGF(UChar r1, IRTemp op2addr)
9710{
9711 IRTemp op2 = newTemp(Ity_I64);
9712
9713 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
9714
9715 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
9716
9717 return "dsgf";
9718}
9719
9720static void
9721s390_irgen_load_ar_multiple(UChar r1, UChar r3, IRTemp op2addr)
9722{
9723 UChar reg;
9724 IRTemp addr = newTemp(Ity_I64);
9725
9726 assign(addr, mkexpr(op2addr));
9727 reg = r1;
9728 do {
9729 IRTemp old = addr;
9730
9731 reg %= 16;
9732 put_ar_w0(reg, load(Ity_I32, mkexpr(addr)));
9733 addr = newTemp(Ity_I64);
9734 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
9735 reg++;
9736 } while (reg != (r3 + 1));
9737}
9738
9739static HChar *
9740s390_irgen_LAM(UChar r1, UChar r3, IRTemp op2addr)
9741{
9742 s390_irgen_load_ar_multiple(r1, r3, op2addr);
9743
9744 return "lam";
9745}
9746
9747static HChar *
9748s390_irgen_LAMY(UChar r1, UChar r3, IRTemp op2addr)
9749{
9750 s390_irgen_load_ar_multiple(r1, r3, op2addr);
9751
9752 return "lamy";
9753}
9754
9755static void
9756s390_irgen_store_ar_multiple(UChar r1, UChar r3, IRTemp op2addr)
9757{
9758 UChar reg;
9759 IRTemp addr = newTemp(Ity_I64);
9760
9761 assign(addr, mkexpr(op2addr));
9762 reg = r1;
9763 do {
9764 IRTemp old = addr;
9765
9766 reg %= 16;
9767 store(mkexpr(addr), get_ar_w0(reg));
9768 addr = newTemp(Ity_I64);
9769 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
9770 reg++;
9771 } while (reg != (r3 + 1));
9772}
9773
9774static HChar *
9775s390_irgen_STAM(UChar r1, UChar r3, IRTemp op2addr)
9776{
9777 s390_irgen_store_ar_multiple(r1, r3, op2addr);
9778
9779 return "stam";
9780}
9781
9782static HChar *
9783s390_irgen_STAMY(UChar r1, UChar r3, IRTemp op2addr)
9784{
9785 s390_irgen_store_ar_multiple(r1, r3, op2addr);
9786
9787 return "stamy";
9788}
9789
9790
9791/* Implementation for 32-bit compare-and-swap */
9792static void
9793s390_irgen_cas_32(UChar r1, UChar r3, IRTemp op2addr)
9794{
9795 IRCAS *cas;
9796 IRTemp op1 = newTemp(Ity_I32);
9797 IRTemp old_mem = newTemp(Ity_I32);
9798 IRTemp op3 = newTemp(Ity_I32);
9799 IRTemp result = newTemp(Ity_I32);
9800 IRTemp nequal = newTemp(Ity_I1);
9801
9802 assign(op1, get_gpr_w1(r1));
9803 assign(op3, get_gpr_w1(r3));
9804
9805 /* The first and second operands are compared. If they are equal,
9806 the third operand is stored at the second- operand location. */
9807 cas = mkIRCAS(IRTemp_INVALID, old_mem,
9808 Iend_BE, mkexpr(op2addr),
9809 NULL, mkexpr(op1), /* expected value */
9810 NULL, mkexpr(op3) /* new value */);
9811 stmt(IRStmt_CAS(cas));
9812
9813 /* Set CC. Operands compared equal -> 0, else 1. */
9814 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(old_mem)));
9815 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
9816
9817 /* If operands were equal (cc == 0) just store the old value op1 in r1.
9818 Otherwise, store the old_value from memory in r1 and yield. */
9819 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
9820 put_gpr_w1(r1, mkite(mkexpr(nequal), mkexpr(old_mem), mkexpr(op1)));
florian6820ba52012-07-26 02:01:50 +00009821 yield_if(mkexpr(nequal));
sewardj2019a972011-03-07 16:04:07 +00009822}
9823
9824static HChar *
9825s390_irgen_CS(UChar r1, UChar r3, IRTemp op2addr)
9826{
9827 s390_irgen_cas_32(r1, r3, op2addr);
9828
9829 return "cs";
9830}
9831
9832static HChar *
9833s390_irgen_CSY(UChar r1, UChar r3, IRTemp op2addr)
9834{
9835 s390_irgen_cas_32(r1, r3, op2addr);
9836
9837 return "csy";
9838}
9839
9840static HChar *
9841s390_irgen_CSG(UChar r1, UChar r3, IRTemp op2addr)
9842{
9843 IRCAS *cas;
9844 IRTemp op1 = newTemp(Ity_I64);
9845 IRTemp old_mem = newTemp(Ity_I64);
9846 IRTemp op3 = newTemp(Ity_I64);
9847 IRTemp result = newTemp(Ity_I64);
9848 IRTemp nequal = newTemp(Ity_I1);
9849
9850 assign(op1, get_gpr_dw0(r1));
9851 assign(op3, get_gpr_dw0(r3));
9852
9853 /* The first and second operands are compared. If they are equal,
9854 the third operand is stored at the second- operand location. */
9855 cas = mkIRCAS(IRTemp_INVALID, old_mem,
9856 Iend_BE, mkexpr(op2addr),
9857 NULL, mkexpr(op1), /* expected value */
9858 NULL, mkexpr(op3) /* new value */);
9859 stmt(IRStmt_CAS(cas));
9860
9861 /* Set CC. Operands compared equal -> 0, else 1. */
9862 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(old_mem)));
9863 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
9864
9865 /* If operands were equal (cc == 0) just store the old value op1 in r1.
9866 Otherwise, store the old_value from memory in r1 and yield. */
9867 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
9868 put_gpr_dw0(r1, mkite(mkexpr(nequal), mkexpr(old_mem), mkexpr(op1)));
florian6820ba52012-07-26 02:01:50 +00009869 yield_if(mkexpr(nequal));
sewardj2019a972011-03-07 16:04:07 +00009870
9871 return "csg";
9872}
9873
florian448cbba2012-06-06 02:26:01 +00009874/* Implementation for 32-bit compare-double-and-swap */
9875static void
9876s390_irgen_cdas_32(UChar r1, UChar r3, IRTemp op2addr)
9877{
9878 IRCAS *cas;
9879 IRTemp op1_high = newTemp(Ity_I32);
9880 IRTemp op1_low = newTemp(Ity_I32);
9881 IRTemp old_mem_high = newTemp(Ity_I32);
9882 IRTemp old_mem_low = newTemp(Ity_I32);
9883 IRTemp op3_high = newTemp(Ity_I32);
9884 IRTemp op3_low = newTemp(Ity_I32);
9885 IRTemp result = newTemp(Ity_I32);
9886 IRTemp nequal = newTemp(Ity_I1);
9887
9888 assign(op1_high, get_gpr_w1(r1));
9889 assign(op1_low, get_gpr_w1(r1+1));
9890 assign(op3_high, get_gpr_w1(r3));
9891 assign(op3_low, get_gpr_w1(r3+1));
9892
9893 /* The first and second operands are compared. If they are equal,
9894 the third operand is stored at the second-operand location. */
9895 cas = mkIRCAS(old_mem_high, old_mem_low,
9896 Iend_BE, mkexpr(op2addr),
9897 mkexpr(op1_high), mkexpr(op1_low), /* expected value */
9898 mkexpr(op3_high), mkexpr(op3_low) /* new value */);
9899 stmt(IRStmt_CAS(cas));
9900
9901 /* Set CC. Operands compared equal -> 0, else 1. */
9902 assign(result, unop(Iop_1Uto32,
9903 binop(Iop_CmpNE32,
9904 binop(Iop_Or32,
9905 binop(Iop_Xor32, mkexpr(op1_high), mkexpr(old_mem_high)),
9906 binop(Iop_Xor32, mkexpr(op1_low), mkexpr(old_mem_low))),
9907 mkU32(0))));
9908
9909 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
9910
9911 /* If operands were equal (cc == 0) just store the old value op1 in r1.
9912 Otherwise, store the old_value from memory in r1 and yield. */
9913 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
9914 put_gpr_w1(r1, mkite(mkexpr(nequal), mkexpr(old_mem_high), mkexpr(op1_high)));
9915 put_gpr_w1(r1+1, mkite(mkexpr(nequal), mkexpr(old_mem_low), mkexpr(op1_low)));
florian6820ba52012-07-26 02:01:50 +00009916 yield_if(mkexpr(nequal));
florian448cbba2012-06-06 02:26:01 +00009917}
9918
9919static HChar *
9920s390_irgen_CDS(UChar r1, UChar r3, IRTemp op2addr)
9921{
9922 s390_irgen_cdas_32(r1, r3, op2addr);
9923
9924 return "cds";
9925}
9926
9927static HChar *
9928s390_irgen_CDSY(UChar r1, UChar r3, IRTemp op2addr)
9929{
9930 s390_irgen_cdas_32(r1, r3, op2addr);
9931
9932 return "cdsy";
9933}
9934
9935static HChar *
9936s390_irgen_CDSG(UChar r1, UChar r3, IRTemp op2addr)
9937{
9938 IRCAS *cas;
9939 IRTemp op1_high = newTemp(Ity_I64);
9940 IRTemp op1_low = newTemp(Ity_I64);
9941 IRTemp old_mem_high = newTemp(Ity_I64);
9942 IRTemp old_mem_low = newTemp(Ity_I64);
9943 IRTemp op3_high = newTemp(Ity_I64);
9944 IRTemp op3_low = newTemp(Ity_I64);
9945 IRTemp result = newTemp(Ity_I64);
9946 IRTemp nequal = newTemp(Ity_I1);
9947
9948 assign(op1_high, get_gpr_dw0(r1));
9949 assign(op1_low, get_gpr_dw0(r1+1));
9950 assign(op3_high, get_gpr_dw0(r3));
9951 assign(op3_low, get_gpr_dw0(r3+1));
9952
9953 /* The first and second operands are compared. If they are equal,
9954 the third operand is stored at the second-operand location. */
9955 cas = mkIRCAS(old_mem_high, old_mem_low,
9956 Iend_BE, mkexpr(op2addr),
9957 mkexpr(op1_high), mkexpr(op1_low), /* expected value */
9958 mkexpr(op3_high), mkexpr(op3_low) /* new value */);
9959 stmt(IRStmt_CAS(cas));
9960
9961 /* Set CC. Operands compared equal -> 0, else 1. */
9962 assign(result, unop(Iop_1Uto64,
9963 binop(Iop_CmpNE64,
9964 binop(Iop_Or64,
9965 binop(Iop_Xor64, mkexpr(op1_high), mkexpr(old_mem_high)),
9966 binop(Iop_Xor64, mkexpr(op1_low), mkexpr(old_mem_low))),
9967 mkU64(0))));
9968
9969 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
9970
9971 /* If operands were equal (cc == 0) just store the old value op1 in r1.
9972 Otherwise, store the old_value from memory in r1 and yield. */
9973 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
9974 put_gpr_dw0(r1, mkite(mkexpr(nequal), mkexpr(old_mem_high), mkexpr(op1_high)));
9975 put_gpr_dw0(r1+1, mkite(mkexpr(nequal), mkexpr(old_mem_low), mkexpr(op1_low)));
florian6820ba52012-07-26 02:01:50 +00009976 yield_if(mkexpr(nequal));
9977
florian448cbba2012-06-06 02:26:01 +00009978 return "cdsg";
9979}
9980
sewardj2019a972011-03-07 16:04:07 +00009981
9982/* Binary floating point */
9983
9984static HChar *
9985s390_irgen_AXBR(UChar r1, UChar r2)
9986{
9987 IRTemp op1 = newTemp(Ity_F128);
9988 IRTemp op2 = newTemp(Ity_F128);
9989 IRTemp result = newTemp(Ity_F128);
9990
9991 assign(op1, get_fpr_pair(r1));
9992 assign(op2, get_fpr_pair(r2));
9993 assign(result, triop(Iop_AddF128, mkU32(Irrm_NEAREST), mkexpr(op1),
9994 mkexpr(op2)));
9995 put_fpr_pair(r1, mkexpr(result));
9996
9997 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
9998
9999 return "axbr";
10000}
10001
10002/* The result of a Iop_CmdFxx operation is a condition code. It is
10003 encoded using the values defined in type IRCmpFxxResult.
10004 Before we can store the condition code into the guest state (or do
10005 anything else with it for that matter) we need to convert it to
10006 the encoding that s390 uses. This is what this function does.
10007
10008 s390 VEX b6 b2 b0 cc.1 cc.0
10009 0 0x40 EQ 1 0 0 0 0
10010 1 0x01 LT 0 0 1 0 1
10011 2 0x00 GT 0 0 0 1 0
10012 3 0x45 Unordered 1 1 1 1 1
10013
10014 The following bits from the VEX encoding are interesting:
10015 b0, b2, b6 with b0 being the LSB. We observe:
10016
10017 cc.0 = b0;
10018 cc.1 = b2 | (~b0 & ~b6)
10019
10020 with cc being the s390 condition code.
10021*/
10022static IRExpr *
10023convert_vex_fpcc_to_s390(IRTemp vex_cc)
10024{
10025 IRTemp cc0 = newTemp(Ity_I32);
10026 IRTemp cc1 = newTemp(Ity_I32);
10027 IRTemp b0 = newTemp(Ity_I32);
10028 IRTemp b2 = newTemp(Ity_I32);
10029 IRTemp b6 = newTemp(Ity_I32);
10030
10031 assign(b0, binop(Iop_And32, mkexpr(vex_cc), mkU32(1)));
10032 assign(b2, binop(Iop_And32, binop(Iop_Shr32, mkexpr(vex_cc), mkU8(2)),
10033 mkU32(1)));
10034 assign(b6, binop(Iop_And32, binop(Iop_Shr32, mkexpr(vex_cc), mkU8(6)),
10035 mkU32(1)));
10036
10037 assign(cc0, mkexpr(b0));
10038 assign(cc1, binop(Iop_Or32, mkexpr(b2),
10039 binop(Iop_And32,
10040 binop(Iop_Sub32, mkU32(1), mkexpr(b0)), /* ~b0 */
10041 binop(Iop_Sub32, mkU32(1), mkexpr(b6)) /* ~b6 */
10042 )));
10043
10044 return binop(Iop_Or32, mkexpr(cc0), binop(Iop_Shl32, mkexpr(cc1), mkU8(1)));
10045}
10046
10047static HChar *
10048s390_irgen_CEBR(UChar r1, UChar r2)
10049{
10050 IRTemp op1 = newTemp(Ity_F32);
10051 IRTemp op2 = newTemp(Ity_F32);
10052 IRTemp cc_vex = newTemp(Ity_I32);
10053 IRTemp cc_s390 = newTemp(Ity_I32);
10054
10055 assign(op1, get_fpr_w0(r1));
10056 assign(op2, get_fpr_w0(r2));
10057 assign(cc_vex, binop(Iop_CmpF32, mkexpr(op1), mkexpr(op2)));
10058
10059 assign(cc_s390, convert_vex_fpcc_to_s390(cc_vex));
10060 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
10061
10062 return "cebr";
10063}
10064
10065static HChar *
10066s390_irgen_CDBR(UChar r1, UChar r2)
10067{
10068 IRTemp op1 = newTemp(Ity_F64);
10069 IRTemp op2 = newTemp(Ity_F64);
10070 IRTemp cc_vex = newTemp(Ity_I32);
10071 IRTemp cc_s390 = newTemp(Ity_I32);
10072
10073 assign(op1, get_fpr_dw0(r1));
10074 assign(op2, get_fpr_dw0(r2));
10075 assign(cc_vex, binop(Iop_CmpF64, mkexpr(op1), mkexpr(op2)));
10076
10077 assign(cc_s390, convert_vex_fpcc_to_s390(cc_vex));
10078 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
10079
10080 return "cdbr";
10081}
10082
10083static HChar *
10084s390_irgen_CXBR(UChar r1, UChar r2)
10085{
10086 IRTemp op1 = newTemp(Ity_F128);
10087 IRTemp op2 = newTemp(Ity_F128);
10088 IRTemp cc_vex = newTemp(Ity_I32);
10089 IRTemp cc_s390 = newTemp(Ity_I32);
10090
10091 assign(op1, get_fpr_pair(r1));
10092 assign(op2, get_fpr_pair(r2));
10093 assign(cc_vex, binop(Iop_CmpF128, mkexpr(op1), mkexpr(op2)));
10094
10095 assign(cc_s390, convert_vex_fpcc_to_s390(cc_vex));
10096 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
10097
10098 return "cxbr";
10099}
10100
10101static HChar *
10102s390_irgen_CEB(UChar r1, IRTemp op2addr)
10103{
10104 IRTemp op1 = newTemp(Ity_F32);
10105 IRTemp op2 = newTemp(Ity_F32);
10106 IRTemp cc_vex = newTemp(Ity_I32);
10107 IRTemp cc_s390 = newTemp(Ity_I32);
10108
10109 assign(op1, get_fpr_w0(r1));
10110 assign(op2, load(Ity_F32, mkexpr(op2addr)));
10111 assign(cc_vex, binop(Iop_CmpF32, mkexpr(op1), mkexpr(op2)));
10112
10113 assign(cc_s390, convert_vex_fpcc_to_s390(cc_vex));
10114 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
10115
10116 return "ceb";
10117}
10118
10119static HChar *
10120s390_irgen_CDB(UChar r1, IRTemp op2addr)
10121{
10122 IRTemp op1 = newTemp(Ity_F64);
10123 IRTemp op2 = newTemp(Ity_F64);
10124 IRTemp cc_vex = newTemp(Ity_I32);
10125 IRTemp cc_s390 = newTemp(Ity_I32);
10126
10127 assign(op1, get_fpr_dw0(r1));
10128 assign(op2, load(Ity_F64, mkexpr(op2addr)));
10129 assign(cc_vex, binop(Iop_CmpF64, mkexpr(op1), mkexpr(op2)));
10130
10131 assign(cc_s390, convert_vex_fpcc_to_s390(cc_vex));
10132 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
10133
10134 return "cdb";
10135}
10136
10137static HChar *
10138s390_irgen_CXFBR(UChar r1, UChar r2)
10139{
10140 IRTemp op2 = newTemp(Ity_I32);
10141
10142 assign(op2, get_gpr_w1(r2));
10143 put_fpr_pair(r1, unop(Iop_I32StoF128, mkexpr(op2)));
10144
10145 return "cxfbr";
10146}
10147
10148static HChar *
10149s390_irgen_CXGBR(UChar r1, UChar r2)
10150{
10151 IRTemp op2 = newTemp(Ity_I64);
10152
10153 assign(op2, get_gpr_dw0(r2));
10154 put_fpr_pair(r1, unop(Iop_I64StoF128, mkexpr(op2)));
10155
10156 return "cxgbr";
10157}
10158
10159static HChar *
10160s390_irgen_CFXBR(UChar r3, UChar r1, UChar r2)
10161{
10162 IRTemp op = newTemp(Ity_F128);
10163 IRTemp result = newTemp(Ity_I32);
10164
10165 assign(op, get_fpr_pair(r2));
10166 assign(result, binop(Iop_F128toI32S, mkU32(encode_rounding_mode(r3)),
10167 mkexpr(op)));
10168 put_gpr_w1(r1, mkexpr(result));
10169 s390_cc_thunk_put1f128(S390_CC_OP_BFP_128_TO_INT_32, op);
10170
10171 return "cfxbr";
10172}
10173
10174static HChar *
10175s390_irgen_CGXBR(UChar r3, UChar r1, UChar r2)
10176{
10177 IRTemp op = newTemp(Ity_F128);
10178 IRTemp result = newTemp(Ity_I64);
10179
10180 assign(op, get_fpr_pair(r2));
10181 assign(result, binop(Iop_F128toI64S, mkU32(encode_rounding_mode(r3)),
10182 mkexpr(op)));
10183 put_gpr_dw0(r1, mkexpr(result));
10184 s390_cc_thunk_put1f128(S390_CC_OP_BFP_128_TO_INT_64, op);
10185
10186 return "cgxbr";
10187}
10188
10189static HChar *
10190s390_irgen_DXBR(UChar r1, UChar r2)
10191{
10192 IRTemp op1 = newTemp(Ity_F128);
10193 IRTemp op2 = newTemp(Ity_F128);
10194 IRTemp result = newTemp(Ity_F128);
10195
10196 assign(op1, get_fpr_pair(r1));
10197 assign(op2, get_fpr_pair(r2));
10198 assign(result, triop(Iop_DivF128, mkU32(Irrm_NEAREST), mkexpr(op1),
10199 mkexpr(op2)));
10200 put_fpr_pair(r1, mkexpr(result));
10201
10202 return "dxbr";
10203}
10204
10205static HChar *
10206s390_irgen_LTXBR(UChar r1, UChar r2)
10207{
10208 IRTemp result = newTemp(Ity_F128);
10209
10210 assign(result, get_fpr_pair(r2));
10211 put_fpr_pair(r1, mkexpr(result));
10212 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
10213
10214 return "ltxbr";
10215}
10216
10217static HChar *
10218s390_irgen_LCXBR(UChar r1, UChar r2)
10219{
10220 IRTemp result = newTemp(Ity_F128);
10221
10222 assign(result, unop(Iop_NegF128, get_fpr_pair(r2)));
10223 put_fpr_pair(r1, mkexpr(result));
10224 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
10225
10226 return "lcxbr";
10227}
10228
10229static HChar *
10230s390_irgen_LXDBR(UChar r1, UChar r2)
10231{
10232 IRTemp op = newTemp(Ity_F64);
10233
10234 assign(op, get_fpr_dw0(r2));
10235 put_fpr_pair(r1, unop(Iop_F64toF128, mkexpr(op)));
10236
10237 return "lxdbr";
10238}
10239
10240static HChar *
10241s390_irgen_LXEBR(UChar r1, UChar r2)
10242{
10243 IRTemp op = newTemp(Ity_F32);
10244
10245 assign(op, get_fpr_w0(r2));
10246 put_fpr_pair(r1, unop(Iop_F32toF128, mkexpr(op)));
10247
10248 return "lxebr";
10249}
10250
10251static HChar *
10252s390_irgen_LXDB(UChar r1, IRTemp op2addr)
10253{
10254 IRTemp op = newTemp(Ity_F64);
10255
10256 assign(op, load(Ity_F64, mkexpr(op2addr)));
10257 put_fpr_pair(r1, unop(Iop_F64toF128, mkexpr(op)));
10258
10259 return "lxdb";
10260}
10261
10262static HChar *
10263s390_irgen_LXEB(UChar r1, IRTemp op2addr)
10264{
10265 IRTemp op = newTemp(Ity_F32);
10266
10267 assign(op, load(Ity_F32, mkexpr(op2addr)));
10268 put_fpr_pair(r1, unop(Iop_F32toF128, mkexpr(op)));
10269
10270 return "lxeb";
10271}
10272
10273static HChar *
10274s390_irgen_LNEBR(UChar r1, UChar r2)
10275{
10276 IRTemp result = newTemp(Ity_F32);
10277
10278 assign(result, unop(Iop_NegF32, unop(Iop_AbsF32, get_fpr_w0(r2))));
10279 put_fpr_w0(r1, mkexpr(result));
10280 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_32, result);
10281
10282 return "lnebr";
10283}
10284
10285static HChar *
10286s390_irgen_LNDBR(UChar r1, UChar r2)
10287{
10288 IRTemp result = newTemp(Ity_F64);
10289
10290 assign(result, unop(Iop_NegF64, unop(Iop_AbsF64, get_fpr_dw0(r2))));
10291 put_fpr_dw0(r1, mkexpr(result));
10292 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_64, result);
10293
10294 return "lndbr";
10295}
10296
10297static HChar *
10298s390_irgen_LNXBR(UChar r1, UChar r2)
10299{
10300 IRTemp result = newTemp(Ity_F128);
10301
10302 assign(result, unop(Iop_NegF128, unop(Iop_AbsF128, get_fpr_pair(r2))));
10303 put_fpr_pair(r1, mkexpr(result));
10304 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
10305
10306 return "lnxbr";
10307}
10308
10309static HChar *
10310s390_irgen_LPEBR(UChar r1, UChar r2)
10311{
10312 IRTemp result = newTemp(Ity_F32);
10313
10314 assign(result, unop(Iop_AbsF32, get_fpr_w0(r2)));
10315 put_fpr_w0(r1, mkexpr(result));
10316 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_32, result);
10317
10318 return "lpebr";
10319}
10320
10321static HChar *
10322s390_irgen_LPDBR(UChar r1, UChar r2)
10323{
10324 IRTemp result = newTemp(Ity_F64);
10325
10326 assign(result, unop(Iop_AbsF64, get_fpr_dw0(r2)));
10327 put_fpr_dw0(r1, mkexpr(result));
10328 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_64, result);
10329
10330 return "lpdbr";
10331}
10332
10333static HChar *
10334s390_irgen_LPXBR(UChar r1, UChar r2)
10335{
10336 IRTemp result = newTemp(Ity_F128);
10337
10338 assign(result, unop(Iop_AbsF128, get_fpr_pair(r2)));
10339 put_fpr_pair(r1, mkexpr(result));
10340 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
10341
10342 return "lpxbr";
10343}
10344
10345static HChar *
10346s390_irgen_LDXBR(UChar r1, UChar r2)
10347{
10348 IRTemp result = newTemp(Ity_F64);
10349
10350 assign(result, binop(Iop_F128toF64, mkU32(Irrm_NEAREST), get_fpr_pair(r2)));
10351 put_fpr_dw0(r1, mkexpr(result));
10352
10353 return "ldxbr";
10354}
10355
10356static HChar *
10357s390_irgen_LEXBR(UChar r1, UChar r2)
10358{
10359 IRTemp result = newTemp(Ity_F32);
10360
10361 assign(result, binop(Iop_F128toF32, mkU32(Irrm_NEAREST), get_fpr_pair(r2)));
10362 put_fpr_w0(r1, mkexpr(result));
10363
10364 return "lexbr";
10365}
10366
10367static HChar *
10368s390_irgen_MXBR(UChar r1, UChar r2)
10369{
10370 IRTemp op1 = newTemp(Ity_F128);
10371 IRTemp op2 = newTemp(Ity_F128);
10372 IRTemp result = newTemp(Ity_F128);
10373
10374 assign(op1, get_fpr_pair(r1));
10375 assign(op2, get_fpr_pair(r2));
10376 assign(result, triop(Iop_MulF128, mkU32(Irrm_NEAREST), mkexpr(op1),
10377 mkexpr(op2)));
10378 put_fpr_pair(r1, mkexpr(result));
10379
10380 return "mxbr";
10381}
10382
10383static HChar *
10384s390_irgen_MAEBR(UChar r1, UChar r3, UChar r2)
10385{
10386 put_fpr_w0(r1, qop(Iop_MAddF32, mkU32(Irrm_NEAREST),
10387 get_fpr_w0(r1), get_fpr_w0(r2), get_fpr_w0(r3)));
10388
10389 return "maebr";
10390}
10391
10392static HChar *
10393s390_irgen_MADBR(UChar r1, UChar r3, UChar r2)
10394{
10395 put_fpr_dw0(r1, qop(Iop_MAddF64, mkU32(Irrm_NEAREST),
10396 get_fpr_dw0(r1), get_fpr_dw0(r2), get_fpr_dw0(r3)));
10397
10398 return "madbr";
10399}
10400
10401static HChar *
10402s390_irgen_MAEB(UChar r3, IRTemp op2addr, UChar r1)
10403{
10404 IRExpr *op2 = load(Ity_F32, mkexpr(op2addr));
10405
10406 put_fpr_w0(r1, qop(Iop_MAddF32, mkU32(Irrm_NEAREST),
10407 get_fpr_w0(r1), op2, get_fpr_w0(r3)));
10408
10409 return "maeb";
10410}
10411
10412static HChar *
10413s390_irgen_MADB(UChar r3, IRTemp op2addr, UChar r1)
10414{
10415 IRExpr *op2 = load(Ity_F64, mkexpr(op2addr));
10416
10417 put_fpr_dw0(r1, qop(Iop_MAddF64, mkU32(Irrm_NEAREST),
10418 get_fpr_dw0(r1), op2, get_fpr_dw0(r3)));
10419
10420 return "madb";
10421}
10422
10423static HChar *
10424s390_irgen_MSEBR(UChar r1, UChar r3, UChar r2)
10425{
10426 put_fpr_w0(r1, qop(Iop_MSubF32, mkU32(Irrm_NEAREST),
10427 get_fpr_w0(r1), get_fpr_w0(r2), get_fpr_w0(r3)));
10428
10429 return "msebr";
10430}
10431
10432static HChar *
10433s390_irgen_MSDBR(UChar r1, UChar r3, UChar r2)
10434{
10435 put_fpr_dw0(r1, qop(Iop_MSubF64, mkU32(Irrm_NEAREST),
10436 get_fpr_dw0(r1), get_fpr_dw0(r2), get_fpr_dw0(r3)));
10437
10438 return "msdbr";
10439}
10440
10441static HChar *
10442s390_irgen_MSEB(UChar r3, IRTemp op2addr, UChar r1)
10443{
10444 IRExpr *op2 = load(Ity_F32, mkexpr(op2addr));
10445
10446 put_fpr_w0(r1, qop(Iop_MSubF32, mkU32(Irrm_NEAREST),
10447 get_fpr_w0(r1), op2, get_fpr_w0(r3)));
10448
10449 return "mseb";
10450}
10451
10452static HChar *
10453s390_irgen_MSDB(UChar r3, IRTemp op2addr, UChar r1)
10454{
10455 IRExpr *op2 = load(Ity_F64, mkexpr(op2addr));
10456
10457 put_fpr_dw0(r1, qop(Iop_MSubF64, mkU32(Irrm_NEAREST),
10458 get_fpr_dw0(r1), op2, get_fpr_dw0(r3)));
10459
10460 return "msdb";
10461}
10462
10463static HChar *
10464s390_irgen_SQEBR(UChar r1, UChar r2)
10465{
10466 IRTemp result = newTemp(Ity_F32);
10467
10468 assign(result, binop(Iop_SqrtF32, mkU32(Irrm_NEAREST), get_fpr_w0(r2)));
10469 put_fpr_w0(r1, mkexpr(result));
10470
10471 return "sqebr";
10472}
10473
10474static HChar *
10475s390_irgen_SQDBR(UChar r1, UChar r2)
10476{
10477 IRTemp result = newTemp(Ity_F64);
10478
10479 assign(result, binop(Iop_SqrtF64, mkU32(Irrm_NEAREST), get_fpr_dw0(r2)));
10480 put_fpr_dw0(r1, mkexpr(result));
10481
10482 return "sqdbr";
10483}
10484
10485static HChar *
10486s390_irgen_SQXBR(UChar r1, UChar r2)
10487{
10488 IRTemp result = newTemp(Ity_F128);
10489
10490 assign(result, binop(Iop_SqrtF128, mkU32(Irrm_NEAREST), get_fpr_pair(r2)));
10491 put_fpr_pair(r1, mkexpr(result));
10492
10493 return "sqxbr";
10494}
10495
10496static HChar *
10497s390_irgen_SQEB(UChar r1, IRTemp op2addr)
10498{
10499 IRTemp op = newTemp(Ity_F32);
10500
10501 assign(op, load(Ity_F32, mkexpr(op2addr)));
10502 put_fpr_w0(r1, binop(Iop_SqrtF32, mkU32(Irrm_NEAREST), mkexpr(op)));
10503
10504 return "sqeb";
10505}
10506
10507static HChar *
10508s390_irgen_SQDB(UChar r1, IRTemp op2addr)
10509{
10510 IRTemp op = newTemp(Ity_F64);
10511
10512 assign(op, load(Ity_F64, mkexpr(op2addr)));
10513 put_fpr_dw0(r1, binop(Iop_SqrtF64, mkU32(Irrm_NEAREST), mkexpr(op)));
10514
10515 return "sqdb";
10516}
10517
10518static HChar *
10519s390_irgen_SXBR(UChar r1, UChar r2)
10520{
10521 IRTemp op1 = newTemp(Ity_F128);
10522 IRTemp op2 = newTemp(Ity_F128);
10523 IRTemp result = newTemp(Ity_F128);
10524
10525 assign(op1, get_fpr_pair(r1));
10526 assign(op2, get_fpr_pair(r2));
10527 assign(result, triop(Iop_SubF128, mkU32(Irrm_NEAREST), mkexpr(op1),
10528 mkexpr(op2)));
10529 put_fpr_pair(r1, mkexpr(result));
10530 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
10531
10532 return "sxbr";
10533}
10534
10535static HChar *
10536s390_irgen_TCEB(UChar r1, IRTemp op2addr)
10537{
10538 IRTemp value = newTemp(Ity_F32);
10539
10540 assign(value, get_fpr_w0(r1));
10541
10542 s390_cc_thunk_putFZ(S390_CC_OP_BFP_TDC_32, value, op2addr);
10543
10544 return "tceb";
10545}
10546
10547static HChar *
10548s390_irgen_TCDB(UChar r1, IRTemp op2addr)
10549{
10550 IRTemp value = newTemp(Ity_F64);
10551
10552 assign(value, get_fpr_dw0(r1));
10553
10554 s390_cc_thunk_putFZ(S390_CC_OP_BFP_TDC_64, value, op2addr);
10555
10556 return "tcdb";
10557}
10558
10559static HChar *
10560s390_irgen_TCXB(UChar r1, IRTemp op2addr)
10561{
10562 IRTemp value = newTemp(Ity_F128);
10563
10564 assign(value, get_fpr_pair(r1));
10565
10566 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_TDC_128, value, op2addr);
10567
10568 return "tcxb";
10569}
10570
10571static HChar *
10572s390_irgen_LCDFR(UChar r1, UChar r2)
10573{
10574 IRTemp result = newTemp(Ity_F64);
10575
10576 assign(result, unop(Iop_NegF64, get_fpr_dw0(r2)));
10577 put_fpr_dw0(r1, mkexpr(result));
10578
10579 return "lcdfr";
10580}
10581
10582static HChar *
10583s390_irgen_LNDFR(UChar r1, UChar r2)
10584{
10585 IRTemp result = newTemp(Ity_F64);
10586
10587 assign(result, unop(Iop_NegF64, unop(Iop_AbsF64, get_fpr_dw0(r2))));
10588 put_fpr_dw0(r1, mkexpr(result));
10589
10590 return "lndfr";
10591}
10592
10593static HChar *
10594s390_irgen_LPDFR(UChar r1, UChar r2)
10595{
10596 IRTemp result = newTemp(Ity_F64);
10597
10598 assign(result, unop(Iop_AbsF64, get_fpr_dw0(r2)));
10599 put_fpr_dw0(r1, mkexpr(result));
10600
10601 return "lpdfr";
10602}
10603
10604static HChar *
10605s390_irgen_LDGR(UChar r1, UChar r2)
10606{
10607 put_fpr_dw0(r1, unop(Iop_ReinterpI64asF64, get_gpr_dw0(r2)));
10608
10609 return "ldgr";
10610}
10611
10612static HChar *
10613s390_irgen_LGDR(UChar r1, UChar r2)
10614{
10615 put_gpr_dw0(r1, unop(Iop_ReinterpF64asI64, get_fpr_dw0(r2)));
10616
10617 return "lgdr";
10618}
10619
10620
10621static HChar *
10622s390_irgen_CPSDR(UChar r3, UChar r1, UChar r2)
10623{
10624 IRTemp sign = newTemp(Ity_I64);
10625 IRTemp value = newTemp(Ity_I64);
10626
10627 assign(sign, binop(Iop_And64, unop(Iop_ReinterpF64asI64, get_fpr_dw0(r3)),
10628 mkU64(1ULL << 63)));
10629 assign(value, binop(Iop_And64, unop(Iop_ReinterpF64asI64, get_fpr_dw0(r2)),
10630 mkU64((1ULL << 63) - 1)));
10631 put_fpr_dw0(r1, unop(Iop_ReinterpI64asF64, binop(Iop_Or64, mkexpr(value),
10632 mkexpr(sign))));
10633
10634 return "cpsdr";
10635}
10636
10637
sewardj2019a972011-03-07 16:04:07 +000010638static IRExpr *
10639s390_call_cvb(IRExpr *in)
10640{
10641 IRExpr **args, *call;
10642
10643 args = mkIRExprVec_1(in);
10644 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
10645 "s390_do_cvb", &s390_do_cvb, args);
10646
10647 /* Nothing is excluded from definedness checking. */
10648 call->Iex.CCall.cee->mcx_mask = 0;
10649
10650 return call;
10651}
10652
10653static HChar *
10654s390_irgen_CVB(UChar r1, IRTemp op2addr)
10655{
10656 put_gpr_w1(r1, s390_call_cvb(load(Ity_I64, mkexpr(op2addr))));
10657
10658 return "cvb";
10659}
10660
10661static HChar *
10662s390_irgen_CVBY(UChar r1, IRTemp op2addr)
10663{
10664 put_gpr_w1(r1, s390_call_cvb(load(Ity_I64, mkexpr(op2addr))));
10665
10666 return "cvby";
10667}
10668
10669
sewardj2019a972011-03-07 16:04:07 +000010670static IRExpr *
10671s390_call_cvd(IRExpr *in)
10672{
10673 IRExpr **args, *call;
10674
10675 args = mkIRExprVec_1(in);
10676 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
10677 "s390_do_cvd", &s390_do_cvd, args);
10678
10679 /* Nothing is excluded from definedness checking. */
10680 call->Iex.CCall.cee->mcx_mask = 0;
10681
10682 return call;
10683}
10684
10685static HChar *
10686s390_irgen_CVD(UChar r1, IRTemp op2addr)
10687{
10688 store(mkexpr(op2addr), s390_call_cvd(get_gpr_w1(r1)));
10689
10690 return "cvd";
10691}
10692
10693static HChar *
10694s390_irgen_CVDY(UChar r1, IRTemp op2addr)
10695{
10696 store(mkexpr(op2addr), s390_call_cvd(get_gpr_w1(r1)));
10697
10698 return "cvdy";
10699}
10700
10701static HChar *
10702s390_irgen_FLOGR(UChar r1, UChar r2)
10703{
10704 IRTemp input = newTemp(Ity_I64);
10705 IRTemp not_zero = newTemp(Ity_I64);
10706 IRTemp tmpnum = newTemp(Ity_I64);
10707 IRTemp num = newTemp(Ity_I64);
10708 IRTemp shift_amount = newTemp(Ity_I8);
10709
10710 /* We use the "count leading zeroes" operator because the number of
10711 leading zeroes is identical with the bit position of the first '1' bit.
10712 However, that operator does not work when the input value is zero.
10713 Therefore, we set the LSB of the input value to 1 and use Clz64 on
10714 the modified value. If input == 0, then the result is 64. Otherwise,
10715 the result of Clz64 is what we want. */
10716
10717 assign(input, get_gpr_dw0(r2));
10718 assign(not_zero, binop(Iop_Or64, mkexpr(input), mkU64(1)));
10719 assign(tmpnum, unop(Iop_Clz64, mkexpr(not_zero)));
10720
10721 /* num = (input == 0) ? 64 : tmpnum */
10722 assign(num, mkite(binop(Iop_CmpEQ64, mkexpr(input), mkU64(0)),
10723 /* == 0 */ mkU64(64),
10724 /* != 0 */ mkexpr(tmpnum)));
10725
10726 put_gpr_dw0(r1, mkexpr(num));
10727
10728 /* Set the leftmost '1' bit of the input value to zero. The general scheme
10729 is to first shift the input value by NUM + 1 bits to the left which
10730 causes the leftmost '1' bit to disappear. Then we shift logically to
10731 the right by NUM + 1 bits. Because the semantics of Iop_Shl64 and
10732 Iop_Shr64 are undefined if the shift-amount is greater than or equal to
10733 the width of the value-to-be-shifted, we need to special case
10734 NUM + 1 >= 64. This is equivalent to INPUT != 0 && INPUT != 1.
10735 For both such INPUT values the result will be 0. */
10736
10737 assign(shift_amount, unop(Iop_64to8, binop(Iop_Add64, mkexpr(num),
10738 mkU64(1))));
10739
10740 put_gpr_dw0(r1 + 1,
florian6ad49522011-09-09 02:38:55 +000010741 mkite(binop(Iop_CmpLE64U, mkexpr(input), mkU64(1)),
10742 /* == 0 || == 1*/ mkU64(0),
10743 /* otherwise */
10744 binop(Iop_Shr64,
10745 binop(Iop_Shl64, mkexpr(input),
10746 mkexpr(shift_amount)),
10747 mkexpr(shift_amount))));
sewardj2019a972011-03-07 16:04:07 +000010748
10749 /* Compare the original value as an unsigned integer with 0. */
10750 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, input,
10751 mktemp(Ity_I64, mkU64(0)), False);
10752
10753 return "flogr";
10754}
10755
sewardj1e5fea62011-05-17 16:18:36 +000010756static HChar *
10757s390_irgen_STCK(IRTemp op2addr)
10758{
10759 IRDirty *d;
10760 IRTemp cc = newTemp(Ity_I64);
10761
10762 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STCK",
10763 &s390x_dirtyhelper_STCK,
10764 mkIRExprVec_1(mkexpr(op2addr)));
10765 d->mFx = Ifx_Write;
10766 d->mAddr = mkexpr(op2addr);
10767 d->mSize = 8;
10768 stmt(IRStmt_Dirty(d));
10769 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
10770 mkexpr(cc), mkU64(0), mkU64(0));
10771 return "stck";
10772}
10773
10774static HChar *
10775s390_irgen_STCKF(IRTemp op2addr)
10776{
10777 IRDirty *d;
10778 IRTemp cc = newTemp(Ity_I64);
10779
10780 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STCKF",
10781 &s390x_dirtyhelper_STCKF,
10782 mkIRExprVec_1(mkexpr(op2addr)));
10783 d->mFx = Ifx_Write;
10784 d->mAddr = mkexpr(op2addr);
10785 d->mSize = 8;
10786 stmt(IRStmt_Dirty(d));
10787 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
10788 mkexpr(cc), mkU64(0), mkU64(0));
10789 return "stckf";
10790}
10791
10792static HChar *
10793s390_irgen_STCKE(IRTemp op2addr)
10794{
10795 IRDirty *d;
10796 IRTemp cc = newTemp(Ity_I64);
10797
10798 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STCKE",
10799 &s390x_dirtyhelper_STCKE,
10800 mkIRExprVec_1(mkexpr(op2addr)));
10801 d->mFx = Ifx_Write;
10802 d->mAddr = mkexpr(op2addr);
10803 d->mSize = 16;
10804 stmt(IRStmt_Dirty(d));
10805 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
10806 mkexpr(cc), mkU64(0), mkU64(0));
10807 return "stcke";
10808}
10809
florian933065d2011-07-11 01:48:02 +000010810static HChar *
10811s390_irgen_STFLE(IRTemp op2addr)
10812{
10813 IRDirty *d;
10814 IRTemp cc = newTemp(Ity_I64);
10815
10816 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STFLE",
10817 &s390x_dirtyhelper_STFLE,
10818 mkIRExprVec_1(mkexpr(op2addr)));
10819
10820 d->needsBBP = 1; /* Need to pass pointer to guest state to helper */
10821
sewardjc9069f22012-06-01 16:09:50 +000010822 d->nFxState = 1;
10823 vex_bzero(&d->fxState, sizeof(d->fxState));
10824
florian933065d2011-07-11 01:48:02 +000010825 d->fxState[0].fx = Ifx_Modify; /* read then write */
10826 d->fxState[0].offset = S390X_GUEST_OFFSET(guest_r0);
10827 d->fxState[0].size = sizeof(ULong);
florian933065d2011-07-11 01:48:02 +000010828
10829 d->mAddr = mkexpr(op2addr);
10830 /* Pretend all double words are written */
10831 d->mSize = S390_NUM_FACILITY_DW * sizeof(ULong);
10832 d->mFx = Ifx_Write;
10833
10834 stmt(IRStmt_Dirty(d));
10835
10836 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET), mkexpr(cc), mkU64(0), mkU64(0));
10837
10838 return "stfle";
10839}
10840
floriana4384a32011-08-11 16:58:45 +000010841static HChar *
10842s390_irgen_CKSM(UChar r1,UChar r2)
10843{
10844 IRTemp addr = newTemp(Ity_I64);
10845 IRTemp op = newTemp(Ity_I32);
10846 IRTemp len = newTemp(Ity_I64);
10847 IRTemp oldval = newTemp(Ity_I32);
10848 IRTemp mask = newTemp(Ity_I32);
10849 IRTemp newop = newTemp(Ity_I32);
10850 IRTemp result = newTemp(Ity_I32);
10851 IRTemp result1 = newTemp(Ity_I32);
10852 IRTemp inc = newTemp(Ity_I64);
10853
10854 assign(oldval, get_gpr_w1(r1));
10855 assign(addr, get_gpr_dw0(r2));
10856 assign(len, get_gpr_dw0(r2+1));
10857
10858 /* Condition code is always zero. */
10859 s390_cc_set(0);
10860
10861 /* If length is zero, there is no need to calculate the checksum */
florian6820ba52012-07-26 02:01:50 +000010862 next_insn_if(binop(Iop_CmpEQ64, mkexpr(len), mkU64(0)));
floriana4384a32011-08-11 16:58:45 +000010863
10864 /* Assiging the increment variable to adjust address and length
10865 later on. */
10866 assign(inc, mkite(binop(Iop_CmpLT64U, mkexpr(len), mkU64(4)),
10867 mkexpr(len), mkU64(4)));
10868
10869 /* If length < 4 the final 4-byte 2nd operand value is computed by
10870 appending the remaining bytes to the right with 0. This is done
10871 by AND'ing the 4 bytes loaded from memory with an appropriate
10872 mask. If length >= 4, that mask is simply 0xffffffff. */
10873
10874 assign(mask, mkite(binop(Iop_CmpLT64U, mkexpr(len), mkU64(4)),
10875 /* Mask computation when len < 4:
10876 0xffffffff << (32 - (len % 4)*8) */
10877 binop(Iop_Shl32, mkU32(0xffffffff),
10878 unop(Iop_32to8,
10879 binop(Iop_Sub32, mkU32(32),
10880 binop(Iop_Shl32,
10881 unop(Iop_64to32,
10882 binop(Iop_And64,
10883 mkexpr(len), mkU64(3))),
10884 mkU8(3))))),
10885 mkU32(0xffffffff)));
10886
10887 assign(op, load(Ity_I32, mkexpr(addr)));
10888 assign(newop, binop(Iop_And32, mkexpr(op), mkexpr(mask)));
10889 assign(result, binop(Iop_Add32, mkexpr(newop), mkexpr(oldval)));
10890
10891 /* Checking for carry */
10892 assign(result1, mkite(binop(Iop_CmpLT32U, mkexpr(result), mkexpr(newop)),
10893 binop(Iop_Add32, mkexpr(result), mkU32(1)),
10894 mkexpr(result)));
10895
10896 put_gpr_w1(r1, mkexpr(result1));
10897 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr), mkexpr(inc)));
10898 put_gpr_dw0(r2+1, binop(Iop_Sub64, mkexpr(len), mkexpr(inc)));
10899
florian6820ba52012-07-26 02:01:50 +000010900 iterate_if(binop(Iop_CmpNE64, mkexpr(len), mkU64(0)));
floriana4384a32011-08-11 16:58:45 +000010901
10902 return "cksm";
10903}
10904
florian9af37692012-01-15 21:01:16 +000010905static HChar *
10906s390_irgen_TROO(UChar m3, UChar r1, UChar r2)
10907{
10908 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
10909 src_addr = newTemp(Ity_I64);
10910 des_addr = newTemp(Ity_I64);
10911 tab_addr = newTemp(Ity_I64);
10912 test_byte = newTemp(Ity_I8);
10913 src_len = newTemp(Ity_I64);
10914
10915 assign(src_addr, get_gpr_dw0(r2));
10916 assign(des_addr, get_gpr_dw0(r1));
10917 assign(tab_addr, get_gpr_dw0(1));
florian53518532012-01-18 14:00:31 +000010918 assign(src_len, get_gpr_dw0(r1+1));
florian9af37692012-01-15 21:01:16 +000010919 assign(test_byte, get_gpr_b7(0));
10920
10921 IRTemp op = newTemp(Ity_I8);
10922 IRTemp op1 = newTemp(Ity_I8);
10923 IRTemp result = newTemp(Ity_I64);
10924
10925 /* End of source string? We're done; proceed to next insn */
10926 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000010927 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian9af37692012-01-15 21:01:16 +000010928
10929 /* Load character from source string, index translation table and
10930 store translated character in op1. */
10931 assign(op, load(Ity_I8, mkexpr(src_addr)));
10932
10933 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)),
10934 mkexpr(tab_addr)));
10935 assign(op1, load(Ity_I8, mkexpr(result)));
10936
10937 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
10938 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000010939 next_insn_if(binop(Iop_CmpEQ8, mkexpr(op1), mkexpr(test_byte)));
florian9af37692012-01-15 21:01:16 +000010940 }
10941 store(get_gpr_dw0(r1), mkexpr(op1));
10942
10943 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(1)));
10944 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(1)));
10945 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(1)));
10946
florian6820ba52012-07-26 02:01:50 +000010947 iterate();
florian9af37692012-01-15 21:01:16 +000010948
10949 return "troo";
10950}
10951
florian730448f2012-02-04 17:07:07 +000010952static HChar *
10953s390_irgen_TRTO(UChar m3, UChar r1, UChar r2)
10954{
10955 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
10956 src_addr = newTemp(Ity_I64);
10957 des_addr = newTemp(Ity_I64);
10958 tab_addr = newTemp(Ity_I64);
10959 test_byte = newTemp(Ity_I8);
10960 src_len = newTemp(Ity_I64);
10961
10962 assign(src_addr, get_gpr_dw0(r2));
10963 assign(des_addr, get_gpr_dw0(r1));
10964 assign(tab_addr, get_gpr_dw0(1));
10965 assign(src_len, get_gpr_dw0(r1+1));
10966 assign(test_byte, get_gpr_b7(0));
10967
10968 IRTemp op = newTemp(Ity_I16);
10969 IRTemp op1 = newTemp(Ity_I8);
10970 IRTemp result = newTemp(Ity_I64);
10971
10972 /* End of source string? We're done; proceed to next insn */
10973 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000010974 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian730448f2012-02-04 17:07:07 +000010975
10976 /* Load character from source string, index translation table and
10977 store translated character in op1. */
10978 assign(op, load(Ity_I16, mkexpr(src_addr)));
10979
10980 assign(result, binop(Iop_Add64, unop(Iop_16Uto64, mkexpr(op)),
10981 mkexpr(tab_addr)));
10982
10983 assign(op1, load(Ity_I8, mkexpr(result)));
10984
10985 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
10986 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000010987 next_insn_if(binop(Iop_CmpEQ8, mkexpr(op1), mkexpr(test_byte)));
florian730448f2012-02-04 17:07:07 +000010988 }
10989 store(get_gpr_dw0(r1), mkexpr(op1));
10990
10991 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(2)));
10992 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(1)));
10993 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(2)));
10994
florian6820ba52012-07-26 02:01:50 +000010995 iterate();
florian730448f2012-02-04 17:07:07 +000010996
10997 return "trto";
10998}
10999
11000static HChar *
11001s390_irgen_TROT(UChar m3, UChar r1, UChar r2)
11002{
11003 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
11004 src_addr = newTemp(Ity_I64);
11005 des_addr = newTemp(Ity_I64);
11006 tab_addr = newTemp(Ity_I64);
11007 test_byte = newTemp(Ity_I16);
11008 src_len = newTemp(Ity_I64);
11009
11010 assign(src_addr, get_gpr_dw0(r2));
11011 assign(des_addr, get_gpr_dw0(r1));
11012 assign(tab_addr, get_gpr_dw0(1));
11013 assign(src_len, get_gpr_dw0(r1+1));
11014 assign(test_byte, get_gpr_hw3(0));
11015
11016 IRTemp op = newTemp(Ity_I8);
11017 IRTemp op1 = newTemp(Ity_I16);
11018 IRTemp result = newTemp(Ity_I64);
11019
11020 /* End of source string? We're done; proceed to next insn */
11021 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000011022 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian730448f2012-02-04 17:07:07 +000011023
11024 /* Load character from source string, index translation table and
11025 store translated character in op1. */
11026 assign(op, binop(Iop_Shl8, load(Ity_I8, mkexpr(src_addr)), mkU8(1)));
11027
11028 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)),
11029 mkexpr(tab_addr)));
11030 assign(op1, load(Ity_I16, mkexpr(result)));
11031
11032 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
11033 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000011034 next_insn_if(binop(Iop_CmpEQ16, mkexpr(op1), mkexpr(test_byte)));
florian730448f2012-02-04 17:07:07 +000011035 }
11036 store(get_gpr_dw0(r1), mkexpr(op1));
11037
11038 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(1)));
11039 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(2)));
11040 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(1)));
11041
florian6820ba52012-07-26 02:01:50 +000011042 iterate();
florian730448f2012-02-04 17:07:07 +000011043
11044 return "trot";
11045}
11046
11047static HChar *
11048s390_irgen_TRTT(UChar m3, UChar r1, UChar r2)
11049{
11050 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
11051 src_addr = newTemp(Ity_I64);
11052 des_addr = newTemp(Ity_I64);
11053 tab_addr = newTemp(Ity_I64);
11054 test_byte = newTemp(Ity_I16);
11055 src_len = newTemp(Ity_I64);
11056
11057 assign(src_addr, get_gpr_dw0(r2));
11058 assign(des_addr, get_gpr_dw0(r1));
11059 assign(tab_addr, get_gpr_dw0(1));
11060 assign(src_len, get_gpr_dw0(r1+1));
11061 assign(test_byte, get_gpr_hw3(0));
11062
11063 IRTemp op = newTemp(Ity_I16);
11064 IRTemp op1 = newTemp(Ity_I16);
11065 IRTemp result = newTemp(Ity_I64);
11066
11067 /* End of source string? We're done; proceed to next insn */
11068 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000011069 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian730448f2012-02-04 17:07:07 +000011070
11071 /* Load character from source string, index translation table and
11072 store translated character in op1. */
11073 assign(op, binop(Iop_Shl16, load(Ity_I16, mkexpr(src_addr)), mkU8(1)));
11074
11075 assign(result, binop(Iop_Add64, unop(Iop_16Uto64, mkexpr(op)),
11076 mkexpr(tab_addr)));
11077 assign(op1, load(Ity_I16, mkexpr(result)));
11078
11079 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
11080 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000011081 next_insn_if(binop(Iop_CmpEQ16, mkexpr(op1), mkexpr(test_byte)));
florian730448f2012-02-04 17:07:07 +000011082 }
11083
11084 store(get_gpr_dw0(r1), mkexpr(op1));
11085
11086 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(2)));
11087 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(2)));
11088 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(2)));
11089
florian6820ba52012-07-26 02:01:50 +000011090 iterate();
florian730448f2012-02-04 17:07:07 +000011091
11092 return "trtt";
11093}
11094
11095static HChar *
11096s390_irgen_TR(UChar length, IRTemp start1, IRTemp start2)
11097{
florianf87d4fb2012-05-05 02:55:24 +000011098 IRTemp len = newTemp(Ity_I64);
florian730448f2012-02-04 17:07:07 +000011099
florianf87d4fb2012-05-05 02:55:24 +000011100 assign(len, mkU64(length));
11101 s390_irgen_TR_EX(len, start1, start2);
florian730448f2012-02-04 17:07:07 +000011102
11103 return "tr";
11104}
11105
11106static HChar *
11107s390_irgen_TRE(UChar r1,UChar r2)
11108{
11109 IRTemp src_addr, tab_addr, src_len, test_byte;
11110 src_addr = newTemp(Ity_I64);
11111 tab_addr = newTemp(Ity_I64);
11112 src_len = newTemp(Ity_I64);
11113 test_byte = newTemp(Ity_I8);
11114
11115 assign(src_addr, get_gpr_dw0(r1));
11116 assign(src_len, get_gpr_dw0(r1+1));
11117 assign(tab_addr, get_gpr_dw0(r2));
11118 assign(test_byte, get_gpr_b7(0));
11119
11120 IRTemp op = newTemp(Ity_I8);
11121 IRTemp op1 = newTemp(Ity_I8);
11122 IRTemp result = newTemp(Ity_I64);
11123
11124 /* End of source string? We're done; proceed to next insn */
11125 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000011126 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian730448f2012-02-04 17:07:07 +000011127
11128 /* Load character from source string and compare with test byte */
11129 assign(op, load(Ity_I8, mkexpr(src_addr)));
11130
11131 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000011132 next_insn_if(binop(Iop_CmpEQ8, mkexpr(op), mkexpr(test_byte)));
florian730448f2012-02-04 17:07:07 +000011133
11134 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)),
11135 mkexpr(tab_addr)));
11136
11137 assign(op1, load(Ity_I8, mkexpr(result)));
11138
11139 store(get_gpr_dw0(r1), mkexpr(op1));
11140 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(src_addr), mkU64(1)));
11141 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(1)));
11142
florian6820ba52012-07-26 02:01:50 +000011143 iterate();
florian730448f2012-02-04 17:07:07 +000011144
11145 return "tre";
11146}
11147
floriana0100c92012-07-20 00:06:35 +000011148static IRExpr *
11149s390_call_cu21(IRExpr *srcval, IRExpr *low_surrogate)
11150{
11151 IRExpr **args, *call;
11152 args = mkIRExprVec_2(srcval, low_surrogate);
11153 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
11154 "s390_do_cu21", &s390_do_cu21, args);
11155
11156 /* Nothing is excluded from definedness checking. */
11157 call->Iex.CCall.cee->mcx_mask = 0;
11158
11159 return call;
11160}
11161
11162static HChar *
11163s390_irgen_CU21(UChar m3, UChar r1, UChar r2)
11164{
11165 IRTemp addr1 = newTemp(Ity_I64);
11166 IRTemp addr2 = newTemp(Ity_I64);
11167 IRTemp len1 = newTemp(Ity_I64);
11168 IRTemp len2 = newTemp(Ity_I64);
11169
11170 assign(addr1, get_gpr_dw0(r1));
11171 assign(addr2, get_gpr_dw0(r2));
11172 assign(len1, get_gpr_dw0(r1 + 1));
11173 assign(len2, get_gpr_dw0(r2 + 1));
11174
11175 /* We're processing the 2nd operand 2 bytes at a time. Therefore, if
11176 there are less than 2 bytes left, then the 2nd operand is exhausted
11177 and we're done here. cc = 0 */
11178 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000011179 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(2)));
floriana0100c92012-07-20 00:06:35 +000011180
11181 /* There are at least two bytes there. Read them. */
11182 IRTemp srcval = newTemp(Ity_I32);
11183 assign(srcval, unop(Iop_16Uto32, load(Ity_I16, mkexpr(addr2))));
11184
11185 /* Find out whether this is a high surrogate. I.e. SRCVAL lies
11186 inside the interval [0xd800 - 0xdbff] */
11187 IRTemp is_high_surrogate = newTemp(Ity_I32);
11188 IRExpr *flag1 = mkite(binop(Iop_CmpLE32U, mkU32(0xd800), mkexpr(srcval)),
11189 mkU32(1), mkU32(0));
11190 IRExpr *flag2 = mkite(binop(Iop_CmpLE32U, mkexpr(srcval), mkU32(0xdbff)),
11191 mkU32(1), mkU32(0));
11192 assign(is_high_surrogate, binop(Iop_And32, flag1, flag2));
11193
11194 /* If SRCVAL is a high surrogate and there are less than 4 bytes left,
11195 then the 2nd operand is exhausted and we're done here. cc = 0 */
11196 IRExpr *not_enough_bytes =
11197 mkite(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)), mkU32(1), mkU32(0));
11198
florian6820ba52012-07-26 02:01:50 +000011199 next_insn_if(binop(Iop_CmpEQ32,
11200 binop(Iop_And32, mkexpr(is_high_surrogate),
11201 not_enough_bytes), mkU32(1)));
floriana0100c92012-07-20 00:06:35 +000011202
11203 /* The 2nd operand is not exhausted. If the first 2 bytes are a high
11204 surrogate, read the next two bytes (low surrogate). */
11205 IRTemp low_surrogate = newTemp(Ity_I32);
11206 IRExpr *low_surrogate_addr = binop(Iop_Add64, mkexpr(addr2), mkU64(2));
11207
11208 assign(low_surrogate,
11209 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
11210 unop(Iop_16Uto32, load(Ity_I16, low_surrogate_addr)),
11211 mkU32(0))); // any value is fine; it will not be used
11212
11213 /* Call the helper */
11214 IRTemp retval = newTemp(Ity_I64);
11215 assign(retval, s390_call_cu21(mkexpr(srcval), mkexpr(low_surrogate)));
11216
11217 /* Before we can test whether the 1st operand is exhausted we need to
11218 test for an invalid low surrogate. Because cc=2 outranks cc=1. */
11219 if (s390_host_has_etf3 && (m3 & 0x1) == 1) {
11220 IRExpr *invalid_low_surrogate =
11221 binop(Iop_And64, mkexpr(retval), mkU64(0xff));
11222
11223 s390_cc_set(2);
florian6820ba52012-07-26 02:01:50 +000011224 next_insn_if(binop(Iop_CmpEQ64, invalid_low_surrogate, mkU64(1)));
floriana0100c92012-07-20 00:06:35 +000011225 }
11226
11227 /* Now test whether the 1st operand is exhausted */
11228 IRTemp num_bytes = newTemp(Ity_I64);
11229 assign(num_bytes, binop(Iop_And64,
11230 binop(Iop_Shr64, mkexpr(retval), mkU8(8)),
11231 mkU64(0xff)));
11232 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000011233 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
floriana0100c92012-07-20 00:06:35 +000011234
11235 /* Extract the bytes to be stored at addr1 */
11236 IRTemp data = newTemp(Ity_I64);
11237 assign(data, binop(Iop_Shr64, mkexpr(retval), mkU8(16)));
11238
11239 /* To store the bytes construct 4 dirty helper calls. The helper calls
11240 are guarded (num_bytes == 1, num_bytes == 2, etc) such that only
11241 one of them will be called at runtime. */
11242 int i;
11243 for (i = 1; i <= 4; ++i) {
11244 IRDirty *d;
11245
11246 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
11247 &s390x_dirtyhelper_CUxy,
11248 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
11249 mkexpr(num_bytes)));
11250 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
11251 d->mFx = Ifx_Write;
11252 d->mAddr = mkexpr(addr1);
11253 d->mSize = i;
11254 stmt(IRStmt_Dirty(d));
11255 }
11256
11257 /* Update source address and length */
11258 IRTemp num_src_bytes = newTemp(Ity_I64);
11259 assign(num_src_bytes,
11260 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
11261 mkU64(4), mkU64(2)));
11262 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkexpr(num_src_bytes)));
11263 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkexpr(num_src_bytes)));
11264
11265 /* Update destination address and length */
11266 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
11267 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
11268
florian6820ba52012-07-26 02:01:50 +000011269 iterate();
floriana0100c92012-07-20 00:06:35 +000011270
11271 return "cu21";
11272}
11273
florian2a415a12012-07-21 17:41:36 +000011274static IRExpr *
11275s390_call_cu24(IRExpr *srcval, IRExpr *low_surrogate)
11276{
11277 IRExpr **args, *call;
11278 args = mkIRExprVec_2(srcval, low_surrogate);
11279 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
11280 "s390_do_cu24", &s390_do_cu24, args);
11281
11282 /* Nothing is excluded from definedness checking. */
11283 call->Iex.CCall.cee->mcx_mask = 0;
11284
11285 return call;
11286}
11287
11288static HChar *
11289s390_irgen_CU24(UChar m3, UChar r1, UChar r2)
11290{
11291 IRTemp addr1 = newTemp(Ity_I64);
11292 IRTemp addr2 = newTemp(Ity_I64);
11293 IRTemp len1 = newTemp(Ity_I64);
11294 IRTemp len2 = newTemp(Ity_I64);
11295
11296 assign(addr1, get_gpr_dw0(r1));
11297 assign(addr2, get_gpr_dw0(r2));
11298 assign(len1, get_gpr_dw0(r1 + 1));
11299 assign(len2, get_gpr_dw0(r2 + 1));
11300
11301 /* We're processing the 2nd operand 2 bytes at a time. Therefore, if
11302 there are less than 2 bytes left, then the 2nd operand is exhausted
11303 and we're done here. cc = 0 */
11304 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000011305 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(2)));
florian2a415a12012-07-21 17:41:36 +000011306
11307 /* There are at least two bytes there. Read them. */
11308 IRTemp srcval = newTemp(Ity_I32);
11309 assign(srcval, unop(Iop_16Uto32, load(Ity_I16, mkexpr(addr2))));
11310
11311 /* Find out whether this is a high surrogate. I.e. SRCVAL lies
11312 inside the interval [0xd800 - 0xdbff] */
11313 IRTemp is_high_surrogate = newTemp(Ity_I32);
11314 IRExpr *flag1 = mkite(binop(Iop_CmpLE32U, mkU32(0xd800), mkexpr(srcval)),
11315 mkU32(1), mkU32(0));
11316 IRExpr *flag2 = mkite(binop(Iop_CmpLE32U, mkexpr(srcval), mkU32(0xdbff)),
11317 mkU32(1), mkU32(0));
11318 assign(is_high_surrogate, binop(Iop_And32, flag1, flag2));
11319
11320 /* If SRCVAL is a high surrogate and there are less than 4 bytes left,
11321 then the 2nd operand is exhausted and we're done here. cc = 0 */
11322 IRExpr *not_enough_bytes =
11323 mkite(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)), mkU32(1), mkU32(0));
11324
florian6820ba52012-07-26 02:01:50 +000011325 next_insn_if(binop(Iop_CmpEQ32,
11326 binop(Iop_And32, mkexpr(is_high_surrogate),
11327 not_enough_bytes),
11328 mkU32(1)));
florian2a415a12012-07-21 17:41:36 +000011329
11330 /* The 2nd operand is not exhausted. If the first 2 bytes are a high
11331 surrogate, read the next two bytes (low surrogate). */
11332 IRTemp low_surrogate = newTemp(Ity_I32);
11333 IRExpr *low_surrogate_addr = binop(Iop_Add64, mkexpr(addr2), mkU64(2));
11334
11335 assign(low_surrogate,
11336 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
11337 unop(Iop_16Uto32, load(Ity_I16, low_surrogate_addr)),
11338 mkU32(0))); // any value is fine; it will not be used
11339
11340 /* Call the helper */
11341 IRTemp retval = newTemp(Ity_I64);
11342 assign(retval, s390_call_cu24(mkexpr(srcval), mkexpr(low_surrogate)));
11343
11344 /* Before we can test whether the 1st operand is exhausted we need to
11345 test for an invalid low surrogate. Because cc=2 outranks cc=1. */
11346 if (s390_host_has_etf3 && (m3 & 0x1) == 1) {
11347 IRExpr *invalid_low_surrogate =
11348 binop(Iop_And64, mkexpr(retval), mkU64(0xff));
11349
11350 s390_cc_set(2);
florian6820ba52012-07-26 02:01:50 +000011351 next_insn_if(binop(Iop_CmpEQ64, invalid_low_surrogate, mkU64(1)));
florian2a415a12012-07-21 17:41:36 +000011352 }
11353
11354 /* Now test whether the 1st operand is exhausted */
11355 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000011356 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkU64(4)));
florian2a415a12012-07-21 17:41:36 +000011357
11358 /* Extract the bytes to be stored at addr1 */
11359 IRExpr *data = unop(Iop_64to32, binop(Iop_Shr64, mkexpr(retval), mkU8(8)));
11360
11361 store(mkexpr(addr1), data);
11362
11363 /* Update source address and length */
11364 IRTemp num_src_bytes = newTemp(Ity_I64);
11365 assign(num_src_bytes,
11366 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
11367 mkU64(4), mkU64(2)));
11368 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkexpr(num_src_bytes)));
11369 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkexpr(num_src_bytes)));
11370
11371 /* Update destination address and length */
11372 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkU64(4)));
11373 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkU64(4)));
11374
florian6820ba52012-07-26 02:01:50 +000011375 iterate();
florian2a415a12012-07-21 17:41:36 +000011376
11377 return "cu24";
11378}
floriana4384a32011-08-11 16:58:45 +000011379
florian956194b2012-07-28 22:18:32 +000011380static IRExpr *
11381s390_call_cu42(IRExpr *srcval)
11382{
11383 IRExpr **args, *call;
11384 args = mkIRExprVec_1(srcval);
11385 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
11386 "s390_do_cu42", &s390_do_cu42, args);
11387
11388 /* Nothing is excluded from definedness checking. */
11389 call->Iex.CCall.cee->mcx_mask = 0;
11390
11391 return call;
11392}
11393
11394static HChar *
11395s390_irgen_CU42(UChar r1, UChar r2)
11396{
11397 IRTemp addr1 = newTemp(Ity_I64);
11398 IRTemp addr2 = newTemp(Ity_I64);
11399 IRTemp len1 = newTemp(Ity_I64);
11400 IRTemp len2 = newTemp(Ity_I64);
11401
11402 assign(addr1, get_gpr_dw0(r1));
11403 assign(addr2, get_gpr_dw0(r2));
11404 assign(len1, get_gpr_dw0(r1 + 1));
11405 assign(len2, get_gpr_dw0(r2 + 1));
11406
11407 /* We're processing the 2nd operand 4 bytes at a time. Therefore, if
11408 there are less than 4 bytes left, then the 2nd operand is exhausted
11409 and we're done here. cc = 0 */
11410 s390_cc_set(0);
11411 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)));
11412
11413 /* Read the 2nd operand. */
11414 IRTemp srcval = newTemp(Ity_I32);
11415 assign(srcval, load(Ity_I32, mkexpr(addr2)));
11416
11417 /* Call the helper */
11418 IRTemp retval = newTemp(Ity_I64);
11419 assign(retval, s390_call_cu42(mkexpr(srcval)));
11420
11421 /* If the UTF-32 character was invalid, set cc=2 and we're done.
11422 cc=2 outranks cc=1 (1st operand exhausted) */
11423 IRExpr *invalid_character = binop(Iop_And64, mkexpr(retval), mkU64(0xff));
11424
11425 s390_cc_set(2);
11426 next_insn_if(binop(Iop_CmpEQ64, invalid_character, mkU64(1)));
11427
11428 /* Now test whether the 1st operand is exhausted */
11429 IRTemp num_bytes = newTemp(Ity_I64);
11430 assign(num_bytes, binop(Iop_And64,
11431 binop(Iop_Shr64, mkexpr(retval), mkU8(8)),
11432 mkU64(0xff)));
11433 s390_cc_set(1);
11434 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
11435
11436 /* Extract the bytes to be stored at addr1 */
11437 IRTemp data = newTemp(Ity_I64);
11438 assign(data, binop(Iop_Shr64, mkexpr(retval), mkU8(16)));
11439
11440 /* To store the bytes construct 2 dirty helper calls. The helper calls
11441 are guarded (num_bytes == 2 and num_bytes == 4, respectively) such
11442 that only one of them will be called at runtime. */
11443
11444 Int i;
11445 for (i = 2; i <= 4; ++i) {
11446 IRDirty *d;
11447
11448 if (i == 3) continue; // skip this one
11449
11450 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
11451 &s390x_dirtyhelper_CUxy,
11452 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
11453 mkexpr(num_bytes)));
11454 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
11455 d->mFx = Ifx_Write;
11456 d->mAddr = mkexpr(addr1);
11457 d->mSize = i;
11458 stmt(IRStmt_Dirty(d));
11459 }
11460
11461 /* Update source address and length */
11462 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkU64(4)));
11463 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkU64(4)));
11464
11465 /* Update destination address and length */
11466 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
11467 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
11468
11469 iterate();
11470
11471 return "cu42";
11472}
11473
florian6d9b9b22012-08-03 18:35:39 +000011474static IRExpr *
florian3f8a96a2012-08-05 02:59:55 +000011475s390_call_cu12_cu14_helper1(IRExpr *byte1, IRExpr *etf3_and_m3_is_1)
florian6d9b9b22012-08-03 18:35:39 +000011476{
11477 IRExpr **args, *call;
11478 args = mkIRExprVec_2(byte1, etf3_and_m3_is_1);
florian3f8a96a2012-08-05 02:59:55 +000011479 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/, "s390_do_cu12_cu14_helper1",
11480 &s390_do_cu12_cu14_helper1, args);
florian6d9b9b22012-08-03 18:35:39 +000011481
11482 /* Nothing is excluded from definedness checking. */
11483 call->Iex.CCall.cee->mcx_mask = 0;
11484
11485 return call;
11486}
11487
11488static IRExpr *
11489s390_call_cu12_helper2(IRExpr *byte1, IRExpr *byte2, IRExpr *byte3,
11490 IRExpr *byte4, IRExpr *stuff)
11491{
11492 IRExpr **args, *call;
11493 args = mkIRExprVec_5(byte1, byte2, byte3, byte4, stuff);
11494 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
11495 "s390_do_cu12_helper2", &s390_do_cu12_helper2, args);
11496
11497 /* Nothing is excluded from definedness checking. */
11498 call->Iex.CCall.cee->mcx_mask = 0;
11499
11500 return call;
11501}
11502
florian3f8a96a2012-08-05 02:59:55 +000011503static IRExpr *
11504s390_call_cu14_helper2(IRExpr *byte1, IRExpr *byte2, IRExpr *byte3,
11505 IRExpr *byte4, IRExpr *stuff)
11506{
11507 IRExpr **args, *call;
11508 args = mkIRExprVec_5(byte1, byte2, byte3, byte4, stuff);
11509 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
11510 "s390_do_cu14_helper2", &s390_do_cu14_helper2, args);
11511
11512 /* Nothing is excluded from definedness checking. */
11513 call->Iex.CCall.cee->mcx_mask = 0;
11514
11515 return call;
11516}
11517
11518static void
11519s390_irgen_cu12_cu14(UChar m3, UChar r1, UChar r2, Bool is_cu12)
florian6d9b9b22012-08-03 18:35:39 +000011520{
11521 IRTemp addr1 = newTemp(Ity_I64);
11522 IRTemp addr2 = newTemp(Ity_I64);
11523 IRTemp len1 = newTemp(Ity_I64);
11524 IRTemp len2 = newTemp(Ity_I64);
11525
11526 assign(addr1, get_gpr_dw0(r1));
11527 assign(addr2, get_gpr_dw0(r2));
11528 assign(len1, get_gpr_dw0(r1 + 1));
11529 assign(len2, get_gpr_dw0(r2 + 1));
11530
11531 UInt extended_checking = s390_host_has_etf3 && (m3 & 0x1) == 1;
11532
11533 /* We're processing the 2nd operand 1 byte at a time. Therefore, if
11534 there is less than 1 byte left, then the 2nd operand is exhausted
11535 and we're done here. cc = 0 */
11536 s390_cc_set(0);
11537 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(1)));
11538
11539 /* There is at least one byte there. Read it. */
11540 IRTemp byte1 = newTemp(Ity_I32);
11541 assign(byte1, unop(Iop_8Uto32, load(Ity_I8, mkexpr(addr2))));
11542
11543 /* Call the helper to get number of bytes and invalid byte indicator */
11544 IRTemp retval1 = newTemp(Ity_I64);
florian3f8a96a2012-08-05 02:59:55 +000011545 assign(retval1, s390_call_cu12_cu14_helper1(mkexpr(byte1),
11546 mkU32(extended_checking)));
florian6d9b9b22012-08-03 18:35:39 +000011547
11548 /* Check for invalid 1st byte */
11549 IRExpr *is_invalid = unop(Iop_64to1, mkexpr(retval1));
11550 s390_cc_set(2);
11551 next_insn_if(is_invalid);
11552
11553 /* How many bytes do we have to read? */
11554 IRTemp num_src_bytes = newTemp(Ity_I64);
11555 assign(num_src_bytes, binop(Iop_Shr64, mkexpr(retval1), mkU8(8)));
11556
11557 /* Now test whether the 2nd operand is exhausted */
11558 s390_cc_set(0);
11559 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkexpr(num_src_bytes)));
11560
11561 /* Read the remaining bytes */
11562 IRExpr *cond, *addr, *byte2, *byte3, *byte4;
11563
11564 cond = binop(Iop_CmpLE64U, mkU64(2), mkexpr(num_src_bytes));
11565 addr = binop(Iop_Add64, mkexpr(addr2), mkU64(1));
11566 byte2 = mkite(cond, unop(Iop_8Uto32, load(Ity_I8, addr)), mkU32(0));
11567 cond = binop(Iop_CmpLE64U, mkU64(3), mkexpr(num_src_bytes));
11568 addr = binop(Iop_Add64, mkexpr(addr2), mkU64(2));
11569 byte3 = mkite(cond, unop(Iop_8Uto32, load(Ity_I8, addr)), mkU32(0));
11570 cond = binop(Iop_CmpLE64U, mkU64(4), mkexpr(num_src_bytes));
11571 addr = binop(Iop_Add64, mkexpr(addr2), mkU64(3));
11572 byte4 = mkite(cond, unop(Iop_8Uto32, load(Ity_I8, addr)), mkU32(0));
11573
11574 /* Call the helper to get the converted value and invalid byte indicator.
11575 We can pass at most 5 arguments; therefore some encoding is needed
11576 here */
11577 IRExpr *stuff = binop(Iop_Or64,
11578 binop(Iop_Shl64, mkexpr(num_src_bytes), mkU8(1)),
11579 mkU64(extended_checking));
11580 IRTemp retval2 = newTemp(Ity_I64);
florian3f8a96a2012-08-05 02:59:55 +000011581
11582 if (is_cu12) {
11583 assign(retval2, s390_call_cu12_helper2(mkexpr(byte1), byte2, byte3,
11584 byte4, stuff));
11585 } else {
11586 assign(retval2, s390_call_cu14_helper2(mkexpr(byte1), byte2, byte3,
11587 byte4, stuff));
11588 }
florian6d9b9b22012-08-03 18:35:39 +000011589
11590 /* Check for invalid character */
11591 s390_cc_set(2);
11592 is_invalid = unop(Iop_64to1, mkexpr(retval2));
11593 next_insn_if(is_invalid);
11594
11595 /* Now test whether the 1st operand is exhausted */
11596 IRTemp num_bytes = newTemp(Ity_I64);
11597 assign(num_bytes, binop(Iop_And64,
11598 binop(Iop_Shr64, mkexpr(retval2), mkU8(8)),
11599 mkU64(0xff)));
11600 s390_cc_set(1);
11601 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
11602
11603 /* Extract the bytes to be stored at addr1 */
11604 IRTemp data = newTemp(Ity_I64);
11605 assign(data, binop(Iop_Shr64, mkexpr(retval2), mkU8(16)));
11606
florian3f8a96a2012-08-05 02:59:55 +000011607 if (is_cu12) {
11608 /* To store the bytes construct 2 dirty helper calls. The helper calls
11609 are guarded (num_bytes == 2 and num_bytes == 4, respectively) such
11610 that only one of them will be called at runtime. */
florian6d9b9b22012-08-03 18:35:39 +000011611
florian3f8a96a2012-08-05 02:59:55 +000011612 Int i;
11613 for (i = 2; i <= 4; ++i) {
11614 IRDirty *d;
florian6d9b9b22012-08-03 18:35:39 +000011615
florian3f8a96a2012-08-05 02:59:55 +000011616 if (i == 3) continue; // skip this one
florian6d9b9b22012-08-03 18:35:39 +000011617
florian3f8a96a2012-08-05 02:59:55 +000011618 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
11619 &s390x_dirtyhelper_CUxy,
11620 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
11621 mkexpr(num_bytes)));
11622 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
11623 d->mFx = Ifx_Write;
11624 d->mAddr = mkexpr(addr1);
11625 d->mSize = i;
11626 stmt(IRStmt_Dirty(d));
11627 }
11628 } else {
11629 // cu14
11630 store(mkexpr(addr1), unop(Iop_64to32, mkexpr(data)));
florian6d9b9b22012-08-03 18:35:39 +000011631 }
11632
11633 /* Update source address and length */
11634 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkexpr(num_src_bytes)));
11635 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkexpr(num_src_bytes)));
11636
11637 /* Update destination address and length */
11638 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
11639 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
11640
11641 iterate();
florian3f8a96a2012-08-05 02:59:55 +000011642}
11643
11644static HChar *
11645s390_irgen_CU12(UChar m3, UChar r1, UChar r2)
11646{
11647 s390_irgen_cu12_cu14(m3, r1, r2, /* is_cu12 = */ 1);
florian6d9b9b22012-08-03 18:35:39 +000011648
11649 return "cu12";
11650}
11651
florian3f8a96a2012-08-05 02:59:55 +000011652static HChar *
11653s390_irgen_CU14(UChar m3, UChar r1, UChar r2)
11654{
11655 s390_irgen_cu12_cu14(m3, r1, r2, /* is_cu12 = */ 0);
11656
11657 return "cu14";
11658}
11659
sewardj2019a972011-03-07 16:04:07 +000011660/*------------------------------------------------------------*/
11661/*--- Build IR for special instructions ---*/
11662/*------------------------------------------------------------*/
11663
florianb4df7682011-07-05 02:09:01 +000011664static void
sewardj2019a972011-03-07 16:04:07 +000011665s390_irgen_client_request(void)
11666{
11667 if (0)
11668 vex_printf("%%R3 = client_request ( %%R2 )\n");
11669
florianf9e1ed72012-04-17 02:41:56 +000011670 Addr64 next = guest_IA_curr_instr + S390_SPECIAL_OP_PREAMBLE_SIZE
11671 + S390_SPECIAL_OP_SIZE;
sewardj2019a972011-03-07 16:04:07 +000011672
florianf9e1ed72012-04-17 02:41:56 +000011673 dis_res->jk_StopHere = Ijk_ClientReq;
sewardj2019a972011-03-07 16:04:07 +000011674 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +000011675
11676 put_IA(mkaddr_expr(next));
sewardj2019a972011-03-07 16:04:07 +000011677}
11678
florianb4df7682011-07-05 02:09:01 +000011679static void
sewardj2019a972011-03-07 16:04:07 +000011680s390_irgen_guest_NRADDR(void)
11681{
11682 if (0)
11683 vex_printf("%%R3 = guest_NRADDR\n");
11684
floriane88b3c92011-07-05 02:48:39 +000011685 put_gpr_dw0(3, IRExpr_Get(S390X_GUEST_OFFSET(guest_NRADDR), Ity_I64));
sewardj2019a972011-03-07 16:04:07 +000011686}
11687
florianb4df7682011-07-05 02:09:01 +000011688static void
sewardj2019a972011-03-07 16:04:07 +000011689s390_irgen_call_noredir(void)
11690{
florianf9e1ed72012-04-17 02:41:56 +000011691 Addr64 next = guest_IA_curr_instr + S390_SPECIAL_OP_PREAMBLE_SIZE
11692 + S390_SPECIAL_OP_SIZE;
11693
sewardj2019a972011-03-07 16:04:07 +000011694 /* Continue after special op */
florianf9e1ed72012-04-17 02:41:56 +000011695 put_gpr_dw0(14, mkaddr_expr(next));
sewardj2019a972011-03-07 16:04:07 +000011696
11697 /* The address is in REG1, all parameters are in the right (guest) places */
florianf9e1ed72012-04-17 02:41:56 +000011698 put_IA(get_gpr_dw0(1));
sewardj2019a972011-03-07 16:04:07 +000011699
11700 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +000011701 dis_res->jk_StopHere = Ijk_NoRedir;
sewardj2019a972011-03-07 16:04:07 +000011702}
11703
11704/* Force proper alignment for the structures below. */
11705#pragma pack(1)
11706
11707
11708static s390_decode_t
11709s390_decode_2byte_and_irgen(UChar *bytes)
11710{
11711 typedef union {
11712 struct {
11713 unsigned int op : 16;
11714 } E;
11715 struct {
11716 unsigned int op : 8;
11717 unsigned int i : 8;
11718 } I;
11719 struct {
11720 unsigned int op : 8;
11721 unsigned int r1 : 4;
11722 unsigned int r2 : 4;
11723 } RR;
11724 } formats;
11725 union {
11726 formats fmt;
11727 UShort value;
11728 } ovl;
11729
11730 vassert(sizeof(formats) == 2);
11731
11732 ((char *)(&ovl.value))[0] = bytes[0];
11733 ((char *)(&ovl.value))[1] = bytes[1];
11734
11735 switch (ovl.value & 0xffff) {
11736 case 0x0101: /* PR */ goto unimplemented;
11737 case 0x0102: /* UPT */ goto unimplemented;
11738 case 0x0104: /* PTFF */ goto unimplemented;
11739 case 0x0107: /* SCKPF */ goto unimplemented;
11740 case 0x010a: /* PFPO */ goto unimplemented;
11741 case 0x010b: /* TAM */ goto unimplemented;
11742 case 0x010c: /* SAM24 */ goto unimplemented;
11743 case 0x010d: /* SAM31 */ goto unimplemented;
11744 case 0x010e: /* SAM64 */ goto unimplemented;
11745 case 0x01ff: /* TRAP2 */ goto unimplemented;
11746 }
11747
11748 switch ((ovl.value & 0xff00) >> 8) {
11749 case 0x04: /* SPM */ goto unimplemented;
11750 case 0x05: /* BALR */ goto unimplemented;
11751 case 0x06: s390_format_RR_RR(s390_irgen_BCTR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
11752 goto ok;
11753 case 0x07: s390_format_RR(s390_irgen_BCR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
11754 goto ok;
11755 case 0x0a: s390_format_I(s390_irgen_SVC, ovl.fmt.I.i); goto ok;
11756 case 0x0b: /* BSM */ goto unimplemented;
11757 case 0x0c: /* BASSM */ goto unimplemented;
11758 case 0x0d: s390_format_RR_RR(s390_irgen_BASR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
11759 goto ok;
florianb0c9a132011-09-08 15:37:39 +000011760 case 0x0e: s390_format_RR(s390_irgen_MVCL, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
11761 goto ok;
11762 case 0x0f: s390_format_RR(s390_irgen_CLCL, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
11763 goto ok;
sewardj2019a972011-03-07 16:04:07 +000011764 case 0x10: s390_format_RR_RR(s390_irgen_LPR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
11765 goto ok;
11766 case 0x11: s390_format_RR_RR(s390_irgen_LNR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
11767 goto ok;
11768 case 0x12: s390_format_RR_RR(s390_irgen_LTR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
11769 goto ok;
11770 case 0x13: s390_format_RR_RR(s390_irgen_LCR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
11771 goto ok;
11772 case 0x14: s390_format_RR_RR(s390_irgen_NR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
11773 goto ok;
11774 case 0x15: s390_format_RR_RR(s390_irgen_CLR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
11775 goto ok;
11776 case 0x16: s390_format_RR_RR(s390_irgen_OR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
11777 goto ok;
11778 case 0x17: s390_format_RR_RR(s390_irgen_XR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
11779 goto ok;
11780 case 0x18: s390_format_RR_RR(s390_irgen_LR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
11781 goto ok;
11782 case 0x19: s390_format_RR_RR(s390_irgen_CR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
11783 goto ok;
11784 case 0x1a: s390_format_RR_RR(s390_irgen_AR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
11785 goto ok;
11786 case 0x1b: s390_format_RR_RR(s390_irgen_SR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
11787 goto ok;
11788 case 0x1c: s390_format_RR_RR(s390_irgen_MR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
11789 goto ok;
11790 case 0x1d: s390_format_RR_RR(s390_irgen_DR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
11791 goto ok;
11792 case 0x1e: s390_format_RR_RR(s390_irgen_ALR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
11793 goto ok;
11794 case 0x1f: s390_format_RR_RR(s390_irgen_SLR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
11795 goto ok;
11796 case 0x20: /* LPDR */ goto unimplemented;
11797 case 0x21: /* LNDR */ goto unimplemented;
11798 case 0x22: /* LTDR */ goto unimplemented;
11799 case 0x23: /* LCDR */ goto unimplemented;
11800 case 0x24: /* HDR */ goto unimplemented;
11801 case 0x25: /* LDXR */ goto unimplemented;
11802 case 0x26: /* MXR */ goto unimplemented;
11803 case 0x27: /* MXDR */ goto unimplemented;
11804 case 0x28: s390_format_RR_FF(s390_irgen_LDR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
11805 goto ok;
11806 case 0x29: /* CDR */ goto unimplemented;
11807 case 0x2a: /* ADR */ goto unimplemented;
11808 case 0x2b: /* SDR */ goto unimplemented;
11809 case 0x2c: /* MDR */ goto unimplemented;
11810 case 0x2d: /* DDR */ goto unimplemented;
11811 case 0x2e: /* AWR */ goto unimplemented;
11812 case 0x2f: /* SWR */ goto unimplemented;
11813 case 0x30: /* LPER */ goto unimplemented;
11814 case 0x31: /* LNER */ goto unimplemented;
11815 case 0x32: /* LTER */ goto unimplemented;
11816 case 0x33: /* LCER */ goto unimplemented;
11817 case 0x34: /* HER */ goto unimplemented;
11818 case 0x35: /* LEDR */ goto unimplemented;
11819 case 0x36: /* AXR */ goto unimplemented;
11820 case 0x37: /* SXR */ goto unimplemented;
11821 case 0x38: s390_format_RR_FF(s390_irgen_LER, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
11822 goto ok;
11823 case 0x39: /* CER */ goto unimplemented;
11824 case 0x3a: /* AER */ goto unimplemented;
11825 case 0x3b: /* SER */ goto unimplemented;
11826 case 0x3c: /* MDER */ goto unimplemented;
11827 case 0x3d: /* DER */ goto unimplemented;
11828 case 0x3e: /* AUR */ goto unimplemented;
11829 case 0x3f: /* SUR */ goto unimplemented;
11830 }
11831
11832 return S390_DECODE_UNKNOWN_INSN;
11833
11834ok:
11835 return S390_DECODE_OK;
11836
11837unimplemented:
11838 return S390_DECODE_UNIMPLEMENTED_INSN;
11839}
11840
11841static s390_decode_t
11842s390_decode_4byte_and_irgen(UChar *bytes)
11843{
11844 typedef union {
11845 struct {
11846 unsigned int op1 : 8;
11847 unsigned int r1 : 4;
11848 unsigned int op2 : 4;
11849 unsigned int i2 : 16;
11850 } RI;
11851 struct {
11852 unsigned int op : 16;
11853 unsigned int : 8;
11854 unsigned int r1 : 4;
11855 unsigned int r2 : 4;
11856 } RRE;
11857 struct {
11858 unsigned int op : 16;
11859 unsigned int r1 : 4;
11860 unsigned int : 4;
11861 unsigned int r3 : 4;
11862 unsigned int r2 : 4;
11863 } RRF;
11864 struct {
11865 unsigned int op : 16;
11866 unsigned int r3 : 4;
11867 unsigned int m4 : 4;
11868 unsigned int r1 : 4;
11869 unsigned int r2 : 4;
11870 } RRF2;
11871 struct {
11872 unsigned int op : 16;
11873 unsigned int r3 : 4;
11874 unsigned int : 4;
11875 unsigned int r1 : 4;
11876 unsigned int r2 : 4;
11877 } RRF3;
11878 struct {
11879 unsigned int op : 16;
11880 unsigned int r3 : 4;
11881 unsigned int : 4;
11882 unsigned int r1 : 4;
11883 unsigned int r2 : 4;
11884 } RRR;
11885 struct {
11886 unsigned int op : 16;
11887 unsigned int r3 : 4;
11888 unsigned int : 4;
11889 unsigned int r1 : 4;
11890 unsigned int r2 : 4;
11891 } RRF4;
11892 struct {
11893 unsigned int op : 8;
11894 unsigned int r1 : 4;
11895 unsigned int r3 : 4;
11896 unsigned int b2 : 4;
11897 unsigned int d2 : 12;
11898 } RS;
11899 struct {
11900 unsigned int op : 8;
11901 unsigned int r1 : 4;
11902 unsigned int r3 : 4;
11903 unsigned int i2 : 16;
11904 } RSI;
11905 struct {
11906 unsigned int op : 8;
11907 unsigned int r1 : 4;
11908 unsigned int x2 : 4;
11909 unsigned int b2 : 4;
11910 unsigned int d2 : 12;
11911 } RX;
11912 struct {
11913 unsigned int op : 16;
11914 unsigned int b2 : 4;
11915 unsigned int d2 : 12;
11916 } S;
11917 struct {
11918 unsigned int op : 8;
11919 unsigned int i2 : 8;
11920 unsigned int b1 : 4;
11921 unsigned int d1 : 12;
11922 } SI;
11923 } formats;
11924 union {
11925 formats fmt;
11926 UInt value;
11927 } ovl;
11928
11929 vassert(sizeof(formats) == 4);
11930
11931 ((char *)(&ovl.value))[0] = bytes[0];
11932 ((char *)(&ovl.value))[1] = bytes[1];
11933 ((char *)(&ovl.value))[2] = bytes[2];
11934 ((char *)(&ovl.value))[3] = bytes[3];
11935
11936 switch ((ovl.value & 0xff0f0000) >> 16) {
11937 case 0xa500: s390_format_RI_RU(s390_irgen_IIHH, ovl.fmt.RI.r1,
11938 ovl.fmt.RI.i2); goto ok;
11939 case 0xa501: s390_format_RI_RU(s390_irgen_IIHL, ovl.fmt.RI.r1,
11940 ovl.fmt.RI.i2); goto ok;
11941 case 0xa502: s390_format_RI_RU(s390_irgen_IILH, ovl.fmt.RI.r1,
11942 ovl.fmt.RI.i2); goto ok;
11943 case 0xa503: s390_format_RI_RU(s390_irgen_IILL, ovl.fmt.RI.r1,
11944 ovl.fmt.RI.i2); goto ok;
11945 case 0xa504: s390_format_RI_RU(s390_irgen_NIHH, ovl.fmt.RI.r1,
11946 ovl.fmt.RI.i2); goto ok;
11947 case 0xa505: s390_format_RI_RU(s390_irgen_NIHL, ovl.fmt.RI.r1,
11948 ovl.fmt.RI.i2); goto ok;
11949 case 0xa506: s390_format_RI_RU(s390_irgen_NILH, ovl.fmt.RI.r1,
11950 ovl.fmt.RI.i2); goto ok;
11951 case 0xa507: s390_format_RI_RU(s390_irgen_NILL, ovl.fmt.RI.r1,
11952 ovl.fmt.RI.i2); goto ok;
11953 case 0xa508: s390_format_RI_RU(s390_irgen_OIHH, ovl.fmt.RI.r1,
11954 ovl.fmt.RI.i2); goto ok;
11955 case 0xa509: s390_format_RI_RU(s390_irgen_OIHL, ovl.fmt.RI.r1,
11956 ovl.fmt.RI.i2); goto ok;
11957 case 0xa50a: s390_format_RI_RU(s390_irgen_OILH, ovl.fmt.RI.r1,
11958 ovl.fmt.RI.i2); goto ok;
11959 case 0xa50b: s390_format_RI_RU(s390_irgen_OILL, ovl.fmt.RI.r1,
11960 ovl.fmt.RI.i2); goto ok;
11961 case 0xa50c: s390_format_RI_RU(s390_irgen_LLIHH, ovl.fmt.RI.r1,
11962 ovl.fmt.RI.i2); goto ok;
11963 case 0xa50d: s390_format_RI_RU(s390_irgen_LLIHL, ovl.fmt.RI.r1,
11964 ovl.fmt.RI.i2); goto ok;
11965 case 0xa50e: s390_format_RI_RU(s390_irgen_LLILH, ovl.fmt.RI.r1,
11966 ovl.fmt.RI.i2); goto ok;
11967 case 0xa50f: s390_format_RI_RU(s390_irgen_LLILL, ovl.fmt.RI.r1,
11968 ovl.fmt.RI.i2); goto ok;
11969 case 0xa700: s390_format_RI_RU(s390_irgen_TMLH, ovl.fmt.RI.r1,
11970 ovl.fmt.RI.i2); goto ok;
11971 case 0xa701: s390_format_RI_RU(s390_irgen_TMLL, ovl.fmt.RI.r1,
11972 ovl.fmt.RI.i2); goto ok;
11973 case 0xa702: s390_format_RI_RU(s390_irgen_TMHH, ovl.fmt.RI.r1,
11974 ovl.fmt.RI.i2); goto ok;
11975 case 0xa703: s390_format_RI_RU(s390_irgen_TMHL, ovl.fmt.RI.r1,
11976 ovl.fmt.RI.i2); goto ok;
11977 case 0xa704: s390_format_RI(s390_irgen_BRC, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
11978 goto ok;
11979 case 0xa705: s390_format_RI_RP(s390_irgen_BRAS, ovl.fmt.RI.r1,
11980 ovl.fmt.RI.i2); goto ok;
11981 case 0xa706: s390_format_RI_RP(s390_irgen_BRCT, ovl.fmt.RI.r1,
11982 ovl.fmt.RI.i2); goto ok;
11983 case 0xa707: s390_format_RI_RP(s390_irgen_BRCTG, ovl.fmt.RI.r1,
11984 ovl.fmt.RI.i2); goto ok;
11985 case 0xa708: s390_format_RI_RI(s390_irgen_LHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
11986 goto ok;
11987 case 0xa709: s390_format_RI_RI(s390_irgen_LGHI, ovl.fmt.RI.r1,
11988 ovl.fmt.RI.i2); goto ok;
11989 case 0xa70a: s390_format_RI_RI(s390_irgen_AHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
11990 goto ok;
11991 case 0xa70b: s390_format_RI_RI(s390_irgen_AGHI, ovl.fmt.RI.r1,
11992 ovl.fmt.RI.i2); goto ok;
11993 case 0xa70c: s390_format_RI_RI(s390_irgen_MHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
11994 goto ok;
11995 case 0xa70d: s390_format_RI_RI(s390_irgen_MGHI, ovl.fmt.RI.r1,
11996 ovl.fmt.RI.i2); goto ok;
11997 case 0xa70e: s390_format_RI_RI(s390_irgen_CHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
11998 goto ok;
11999 case 0xa70f: s390_format_RI_RI(s390_irgen_CGHI, ovl.fmt.RI.r1,
12000 ovl.fmt.RI.i2); goto ok;
12001 }
12002
12003 switch ((ovl.value & 0xffff0000) >> 16) {
12004 case 0x8000: /* SSM */ goto unimplemented;
12005 case 0x8200: /* LPSW */ goto unimplemented;
florian7700fc92012-01-16 17:25:55 +000012006 case 0x9300: /* TS */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000012007 case 0xb202: /* STIDP */ goto unimplemented;
12008 case 0xb204: /* SCK */ goto unimplemented;
florian7700fc92012-01-16 17:25:55 +000012009 case 0xb205: s390_format_S_RD(s390_irgen_STCK, ovl.fmt.S.b2, ovl.fmt.S.d2);
12010 goto ok;
sewardj2019a972011-03-07 16:04:07 +000012011 case 0xb206: /* SCKC */ goto unimplemented;
12012 case 0xb207: /* STCKC */ goto unimplemented;
12013 case 0xb208: /* SPT */ goto unimplemented;
12014 case 0xb209: /* STPT */ goto unimplemented;
12015 case 0xb20a: /* SPKA */ goto unimplemented;
12016 case 0xb20b: /* IPK */ goto unimplemented;
12017 case 0xb20d: /* PTLB */ goto unimplemented;
12018 case 0xb210: /* SPX */ goto unimplemented;
12019 case 0xb211: /* STPX */ goto unimplemented;
12020 case 0xb212: /* STAP */ goto unimplemented;
12021 case 0xb214: /* SIE */ goto unimplemented;
12022 case 0xb218: /* PC */ goto unimplemented;
12023 case 0xb219: /* SAC */ goto unimplemented;
12024 case 0xb21a: /* CFC */ goto unimplemented;
12025 case 0xb221: /* IPTE */ goto unimplemented;
12026 case 0xb222: s390_format_RRE_R0(s390_irgen_IPM, ovl.fmt.RRE.r1); goto ok;
12027 case 0xb223: /* IVSK */ goto unimplemented;
12028 case 0xb224: /* IAC */ goto unimplemented;
12029 case 0xb225: /* SSAR */ goto unimplemented;
12030 case 0xb226: /* EPAR */ goto unimplemented;
12031 case 0xb227: /* ESAR */ goto unimplemented;
12032 case 0xb228: /* PT */ goto unimplemented;
12033 case 0xb229: /* ISKE */ goto unimplemented;
12034 case 0xb22a: /* RRBE */ goto unimplemented;
12035 case 0xb22b: /* SSKE */ goto unimplemented;
12036 case 0xb22c: /* TB */ goto unimplemented;
12037 case 0xb22d: /* DXR */ goto unimplemented;
12038 case 0xb22e: /* PGIN */ goto unimplemented;
12039 case 0xb22f: /* PGOUT */ goto unimplemented;
12040 case 0xb230: /* CSCH */ goto unimplemented;
12041 case 0xb231: /* HSCH */ goto unimplemented;
12042 case 0xb232: /* MSCH */ goto unimplemented;
12043 case 0xb233: /* SSCH */ goto unimplemented;
12044 case 0xb234: /* STSCH */ goto unimplemented;
12045 case 0xb235: /* TSCH */ goto unimplemented;
12046 case 0xb236: /* TPI */ goto unimplemented;
12047 case 0xb237: /* SAL */ goto unimplemented;
12048 case 0xb238: /* RSCH */ goto unimplemented;
12049 case 0xb239: /* STCRW */ goto unimplemented;
12050 case 0xb23a: /* STCPS */ goto unimplemented;
12051 case 0xb23b: /* RCHP */ goto unimplemented;
12052 case 0xb23c: /* SCHM */ goto unimplemented;
12053 case 0xb240: /* BAKR */ goto unimplemented;
floriana4384a32011-08-11 16:58:45 +000012054 case 0xb241: s390_format_RRE(s390_irgen_CKSM, ovl.fmt.RRE.r1,
12055 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000012056 case 0xb244: /* SQDR */ goto unimplemented;
12057 case 0xb245: /* SQER */ goto unimplemented;
12058 case 0xb246: /* STURA */ goto unimplemented;
12059 case 0xb247: /* MSTA */ goto unimplemented;
12060 case 0xb248: /* PALB */ goto unimplemented;
12061 case 0xb249: /* EREG */ goto unimplemented;
12062 case 0xb24a: /* ESTA */ goto unimplemented;
12063 case 0xb24b: /* LURA */ goto unimplemented;
12064 case 0xb24c: /* TAR */ goto unimplemented;
12065 case 0xb24d: s390_format_RRE(s390_irgen_CPYA, ovl.fmt.RRE.r1,
12066 ovl.fmt.RRE.r2); goto ok;
12067 case 0xb24e: s390_format_RRE(s390_irgen_SAR, ovl.fmt.RRE.r1, ovl.fmt.RRE.r2);
12068 goto ok;
12069 case 0xb24f: s390_format_RRE(s390_irgen_EAR, ovl.fmt.RRE.r1, ovl.fmt.RRE.r2);
12070 goto ok;
12071 case 0xb250: /* CSP */ goto unimplemented;
12072 case 0xb252: s390_format_RRE_RR(s390_irgen_MSR, ovl.fmt.RRE.r1,
12073 ovl.fmt.RRE.r2); goto ok;
12074 case 0xb254: /* MVPG */ goto unimplemented;
12075 case 0xb255: s390_format_RRE_RR(s390_irgen_MVST, ovl.fmt.RRE.r1,
12076 ovl.fmt.RRE.r2); goto ok;
12077 case 0xb257: /* CUSE */ goto unimplemented;
12078 case 0xb258: /* BSG */ goto unimplemented;
12079 case 0xb25a: /* BSA */ goto unimplemented;
12080 case 0xb25d: s390_format_RRE_RR(s390_irgen_CLST, ovl.fmt.RRE.r1,
12081 ovl.fmt.RRE.r2); goto ok;
12082 case 0xb25e: s390_format_RRE_RR(s390_irgen_SRST, ovl.fmt.RRE.r1,
12083 ovl.fmt.RRE.r2); goto ok;
12084 case 0xb263: /* CMPSC */ goto unimplemented;
12085 case 0xb274: /* SIGA */ goto unimplemented;
12086 case 0xb276: /* XSCH */ goto unimplemented;
12087 case 0xb277: /* RP */ goto unimplemented;
sewardj1e5fea62011-05-17 16:18:36 +000012088 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 +000012089 case 0xb279: /* SACF */ goto unimplemented;
sewardj1e5fea62011-05-17 16:18:36 +000012090 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 +000012091 case 0xb27d: /* STSI */ goto unimplemented;
12092 case 0xb299: s390_format_S_RD(s390_irgen_SRNM, ovl.fmt.S.b2, ovl.fmt.S.d2);
12093 goto ok;
12094 case 0xb29c: s390_format_S_RD(s390_irgen_STFPC, ovl.fmt.S.b2, ovl.fmt.S.d2);
12095 goto ok;
12096 case 0xb29d: s390_format_S_RD(s390_irgen_LFPC, ovl.fmt.S.b2, ovl.fmt.S.d2);
12097 goto ok;
florian730448f2012-02-04 17:07:07 +000012098 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 +000012099 case 0xb2a6: s390_format_RRF_M0RERE(s390_irgen_CU21, ovl.fmt.RRF3.r3,
12100 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
12101 goto ok;
florian6d9b9b22012-08-03 18:35:39 +000012102 case 0xb2a7: s390_format_RRF_M0RERE(s390_irgen_CU12, ovl.fmt.RRF3.r3,
12103 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
12104 goto ok;
florian933065d2011-07-11 01:48:02 +000012105 case 0xb2b0: s390_format_S_RD(s390_irgen_STFLE, ovl.fmt.S.b2, ovl.fmt.S.d2);
12106 goto ok;
sewardj2019a972011-03-07 16:04:07 +000012107 case 0xb2b1: /* STFL */ goto unimplemented;
12108 case 0xb2b2: /* LPSWE */ goto unimplemented;
12109 case 0xb2b8: /* SRNMB */ goto unimplemented;
12110 case 0xb2b9: /* SRNMT */ goto unimplemented;
12111 case 0xb2bd: /* LFAS */ goto unimplemented;
12112 case 0xb2ff: /* TRAP4 */ goto unimplemented;
12113 case 0xb300: s390_format_RRE_FF(s390_irgen_LPEBR, ovl.fmt.RRE.r1,
12114 ovl.fmt.RRE.r2); goto ok;
12115 case 0xb301: s390_format_RRE_FF(s390_irgen_LNEBR, ovl.fmt.RRE.r1,
12116 ovl.fmt.RRE.r2); goto ok;
12117 case 0xb302: s390_format_RRE_FF(s390_irgen_LTEBR, ovl.fmt.RRE.r1,
12118 ovl.fmt.RRE.r2); goto ok;
12119 case 0xb303: s390_format_RRE_FF(s390_irgen_LCEBR, ovl.fmt.RRE.r1,
12120 ovl.fmt.RRE.r2); goto ok;
12121 case 0xb304: s390_format_RRE_FF(s390_irgen_LDEBR, ovl.fmt.RRE.r1,
12122 ovl.fmt.RRE.r2); goto ok;
12123 case 0xb305: s390_format_RRE_FF(s390_irgen_LXDBR, ovl.fmt.RRE.r1,
12124 ovl.fmt.RRE.r2); goto ok;
12125 case 0xb306: s390_format_RRE_FF(s390_irgen_LXEBR, ovl.fmt.RRE.r1,
12126 ovl.fmt.RRE.r2); goto ok;
12127 case 0xb307: /* MXDBR */ goto unimplemented;
12128 case 0xb308: /* KEBR */ goto unimplemented;
12129 case 0xb309: s390_format_RRE_FF(s390_irgen_CEBR, ovl.fmt.RRE.r1,
12130 ovl.fmt.RRE.r2); goto ok;
12131 case 0xb30a: s390_format_RRE_FF(s390_irgen_AEBR, ovl.fmt.RRE.r1,
12132 ovl.fmt.RRE.r2); goto ok;
12133 case 0xb30b: s390_format_RRE_FF(s390_irgen_SEBR, ovl.fmt.RRE.r1,
12134 ovl.fmt.RRE.r2); goto ok;
12135 case 0xb30c: /* MDEBR */ goto unimplemented;
12136 case 0xb30d: s390_format_RRE_FF(s390_irgen_DEBR, ovl.fmt.RRE.r1,
12137 ovl.fmt.RRE.r2); goto ok;
12138 case 0xb30e: s390_format_RRF_F0FF(s390_irgen_MAEBR, ovl.fmt.RRF.r1,
12139 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
12140 case 0xb30f: s390_format_RRF_F0FF(s390_irgen_MSEBR, ovl.fmt.RRF.r1,
12141 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
12142 case 0xb310: s390_format_RRE_FF(s390_irgen_LPDBR, ovl.fmt.RRE.r1,
12143 ovl.fmt.RRE.r2); goto ok;
12144 case 0xb311: s390_format_RRE_FF(s390_irgen_LNDBR, ovl.fmt.RRE.r1,
12145 ovl.fmt.RRE.r2); goto ok;
12146 case 0xb312: s390_format_RRE_FF(s390_irgen_LTDBR, ovl.fmt.RRE.r1,
12147 ovl.fmt.RRE.r2); goto ok;
12148 case 0xb313: s390_format_RRE_FF(s390_irgen_LCDBR, ovl.fmt.RRE.r1,
12149 ovl.fmt.RRE.r2); goto ok;
12150 case 0xb314: s390_format_RRE_FF(s390_irgen_SQEBR, ovl.fmt.RRE.r1,
12151 ovl.fmt.RRE.r2); goto ok;
12152 case 0xb315: s390_format_RRE_FF(s390_irgen_SQDBR, ovl.fmt.RRE.r1,
12153 ovl.fmt.RRE.r2); goto ok;
12154 case 0xb316: s390_format_RRE_FF(s390_irgen_SQXBR, ovl.fmt.RRE.r1,
12155 ovl.fmt.RRE.r2); goto ok;
12156 case 0xb317: s390_format_RRE_FF(s390_irgen_MEEBR, ovl.fmt.RRE.r1,
12157 ovl.fmt.RRE.r2); goto ok;
12158 case 0xb318: /* KDBR */ goto unimplemented;
12159 case 0xb319: s390_format_RRE_FF(s390_irgen_CDBR, ovl.fmt.RRE.r1,
12160 ovl.fmt.RRE.r2); goto ok;
12161 case 0xb31a: s390_format_RRE_FF(s390_irgen_ADBR, ovl.fmt.RRE.r1,
12162 ovl.fmt.RRE.r2); goto ok;
12163 case 0xb31b: s390_format_RRE_FF(s390_irgen_SDBR, ovl.fmt.RRE.r1,
12164 ovl.fmt.RRE.r2); goto ok;
12165 case 0xb31c: s390_format_RRE_FF(s390_irgen_MDBR, ovl.fmt.RRE.r1,
12166 ovl.fmt.RRE.r2); goto ok;
12167 case 0xb31d: s390_format_RRE_FF(s390_irgen_DDBR, ovl.fmt.RRE.r1,
12168 ovl.fmt.RRE.r2); goto ok;
12169 case 0xb31e: s390_format_RRF_F0FF(s390_irgen_MADBR, ovl.fmt.RRF.r1,
12170 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
12171 case 0xb31f: s390_format_RRF_F0FF(s390_irgen_MSDBR, ovl.fmt.RRF.r1,
12172 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
12173 case 0xb324: /* LDER */ goto unimplemented;
12174 case 0xb325: /* LXDR */ goto unimplemented;
12175 case 0xb326: /* LXER */ goto unimplemented;
12176 case 0xb32e: /* MAER */ goto unimplemented;
12177 case 0xb32f: /* MSER */ goto unimplemented;
12178 case 0xb336: /* SQXR */ goto unimplemented;
12179 case 0xb337: /* MEER */ goto unimplemented;
12180 case 0xb338: /* MAYLR */ goto unimplemented;
12181 case 0xb339: /* MYLR */ goto unimplemented;
12182 case 0xb33a: /* MAYR */ goto unimplemented;
12183 case 0xb33b: /* MYR */ goto unimplemented;
12184 case 0xb33c: /* MAYHR */ goto unimplemented;
12185 case 0xb33d: /* MYHR */ goto unimplemented;
12186 case 0xb33e: /* MADR */ goto unimplemented;
12187 case 0xb33f: /* MSDR */ goto unimplemented;
12188 case 0xb340: s390_format_RRE_FF(s390_irgen_LPXBR, ovl.fmt.RRE.r1,
12189 ovl.fmt.RRE.r2); goto ok;
12190 case 0xb341: s390_format_RRE_FF(s390_irgen_LNXBR, ovl.fmt.RRE.r1,
12191 ovl.fmt.RRE.r2); goto ok;
12192 case 0xb342: s390_format_RRE_FF(s390_irgen_LTXBR, ovl.fmt.RRE.r1,
12193 ovl.fmt.RRE.r2); goto ok;
12194 case 0xb343: s390_format_RRE_FF(s390_irgen_LCXBR, ovl.fmt.RRE.r1,
12195 ovl.fmt.RRE.r2); goto ok;
12196 case 0xb344: s390_format_RRE_FF(s390_irgen_LEDBR, ovl.fmt.RRE.r1,
12197 ovl.fmt.RRE.r2); goto ok;
12198 case 0xb345: s390_format_RRE_FF(s390_irgen_LDXBR, ovl.fmt.RRE.r1,
12199 ovl.fmt.RRE.r2); goto ok;
12200 case 0xb346: s390_format_RRE_FF(s390_irgen_LEXBR, ovl.fmt.RRE.r1,
12201 ovl.fmt.RRE.r2); goto ok;
12202 case 0xb347: /* FIXBR */ goto unimplemented;
12203 case 0xb348: /* KXBR */ goto unimplemented;
12204 case 0xb349: s390_format_RRE_FF(s390_irgen_CXBR, ovl.fmt.RRE.r1,
12205 ovl.fmt.RRE.r2); goto ok;
12206 case 0xb34a: s390_format_RRE_FF(s390_irgen_AXBR, ovl.fmt.RRE.r1,
12207 ovl.fmt.RRE.r2); goto ok;
12208 case 0xb34b: s390_format_RRE_FF(s390_irgen_SXBR, ovl.fmt.RRE.r1,
12209 ovl.fmt.RRE.r2); goto ok;
12210 case 0xb34c: s390_format_RRE_FF(s390_irgen_MXBR, ovl.fmt.RRE.r1,
12211 ovl.fmt.RRE.r2); goto ok;
12212 case 0xb34d: s390_format_RRE_FF(s390_irgen_DXBR, ovl.fmt.RRE.r1,
12213 ovl.fmt.RRE.r2); goto ok;
12214 case 0xb350: /* TBEDR */ goto unimplemented;
12215 case 0xb351: /* TBDR */ goto unimplemented;
12216 case 0xb353: /* DIEBR */ goto unimplemented;
12217 case 0xb357: /* FIEBR */ goto unimplemented;
12218 case 0xb358: /* THDER */ goto unimplemented;
12219 case 0xb359: /* THDR */ goto unimplemented;
12220 case 0xb35b: /* DIDBR */ goto unimplemented;
12221 case 0xb35f: /* FIDBR */ goto unimplemented;
12222 case 0xb360: /* LPXR */ goto unimplemented;
12223 case 0xb361: /* LNXR */ goto unimplemented;
12224 case 0xb362: /* LTXR */ goto unimplemented;
12225 case 0xb363: /* LCXR */ goto unimplemented;
12226 case 0xb365: s390_format_RRE_FF(s390_irgen_LXR, ovl.fmt.RRE.r1,
12227 ovl.fmt.RRE.r2); goto ok;
12228 case 0xb366: /* LEXR */ goto unimplemented;
12229 case 0xb367: /* FIXR */ goto unimplemented;
12230 case 0xb369: /* CXR */ goto unimplemented;
12231 case 0xb370: s390_format_RRE_FF(s390_irgen_LPDFR, ovl.fmt.RRE.r1,
12232 ovl.fmt.RRE.r2); goto ok;
12233 case 0xb371: s390_format_RRE_FF(s390_irgen_LNDFR, ovl.fmt.RRE.r1,
12234 ovl.fmt.RRE.r2); goto ok;
12235 case 0xb372: s390_format_RRF_F0FF2(s390_irgen_CPSDR, ovl.fmt.RRF3.r3,
12236 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
12237 goto ok;
12238 case 0xb373: s390_format_RRE_FF(s390_irgen_LCDFR, ovl.fmt.RRE.r1,
12239 ovl.fmt.RRE.r2); goto ok;
12240 case 0xb374: s390_format_RRE_F0(s390_irgen_LZER, ovl.fmt.RRE.r1); goto ok;
12241 case 0xb375: s390_format_RRE_F0(s390_irgen_LZDR, ovl.fmt.RRE.r1); goto ok;
12242 case 0xb376: s390_format_RRE_F0(s390_irgen_LZXR, ovl.fmt.RRE.r1); goto ok;
12243 case 0xb377: /* FIER */ goto unimplemented;
12244 case 0xb37f: /* FIDR */ goto unimplemented;
12245 case 0xb384: s390_format_RRE_R0(s390_irgen_SFPC, ovl.fmt.RRE.r1); goto ok;
12246 case 0xb385: /* SFASR */ goto unimplemented;
12247 case 0xb38c: s390_format_RRE_R0(s390_irgen_EFPC, ovl.fmt.RRE.r1); goto ok;
12248 case 0xb390: /* CELFBR */ goto unimplemented;
12249 case 0xb391: /* CDLFBR */ goto unimplemented;
12250 case 0xb392: /* CXLFBR */ goto unimplemented;
12251 case 0xb394: s390_format_RRE_FR(s390_irgen_CEFBR, ovl.fmt.RRE.r1,
12252 ovl.fmt.RRE.r2); goto ok;
12253 case 0xb395: s390_format_RRE_FR(s390_irgen_CDFBR, ovl.fmt.RRE.r1,
12254 ovl.fmt.RRE.r2); goto ok;
12255 case 0xb396: s390_format_RRE_FR(s390_irgen_CXFBR, ovl.fmt.RRE.r1,
12256 ovl.fmt.RRE.r2); goto ok;
12257 case 0xb398: s390_format_RRF_U0RF(s390_irgen_CFEBR, ovl.fmt.RRF3.r3,
12258 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
12259 goto ok;
12260 case 0xb399: s390_format_RRF_U0RF(s390_irgen_CFDBR, ovl.fmt.RRF3.r3,
12261 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
12262 goto ok;
12263 case 0xb39a: s390_format_RRF_U0RF(s390_irgen_CFXBR, ovl.fmt.RRF3.r3,
12264 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
12265 goto ok;
12266 case 0xb3a0: /* CELGBR */ goto unimplemented;
12267 case 0xb3a1: /* CDLGBR */ goto unimplemented;
12268 case 0xb3a2: /* CXLGBR */ goto unimplemented;
12269 case 0xb3a4: s390_format_RRE_FR(s390_irgen_CEGBR, ovl.fmt.RRE.r1,
12270 ovl.fmt.RRE.r2); goto ok;
12271 case 0xb3a5: s390_format_RRE_FR(s390_irgen_CDGBR, ovl.fmt.RRE.r1,
12272 ovl.fmt.RRE.r2); goto ok;
12273 case 0xb3a6: s390_format_RRE_FR(s390_irgen_CXGBR, ovl.fmt.RRE.r1,
12274 ovl.fmt.RRE.r2); goto ok;
12275 case 0xb3a8: s390_format_RRF_U0RF(s390_irgen_CGEBR, ovl.fmt.RRF3.r3,
12276 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
12277 goto ok;
12278 case 0xb3a9: s390_format_RRF_U0RF(s390_irgen_CGDBR, ovl.fmt.RRF3.r3,
12279 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
12280 goto ok;
12281 case 0xb3aa: s390_format_RRF_U0RF(s390_irgen_CGXBR, ovl.fmt.RRF3.r3,
12282 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
12283 goto ok;
12284 case 0xb3b4: /* CEFR */ goto unimplemented;
12285 case 0xb3b5: /* CDFR */ goto unimplemented;
12286 case 0xb3b6: /* CXFR */ goto unimplemented;
12287 case 0xb3b8: /* CFER */ goto unimplemented;
12288 case 0xb3b9: /* CFDR */ goto unimplemented;
12289 case 0xb3ba: /* CFXR */ goto unimplemented;
12290 case 0xb3c1: s390_format_RRE_FR(s390_irgen_LDGR, ovl.fmt.RRE.r1,
12291 ovl.fmt.RRE.r2); goto ok;
12292 case 0xb3c4: /* CEGR */ goto unimplemented;
12293 case 0xb3c5: /* CDGR */ goto unimplemented;
12294 case 0xb3c6: /* CXGR */ goto unimplemented;
12295 case 0xb3c8: /* CGER */ goto unimplemented;
12296 case 0xb3c9: /* CGDR */ goto unimplemented;
12297 case 0xb3ca: /* CGXR */ goto unimplemented;
12298 case 0xb3cd: s390_format_RRE_RF(s390_irgen_LGDR, ovl.fmt.RRE.r1,
12299 ovl.fmt.RRE.r2); goto ok;
12300 case 0xb3d0: /* MDTR */ goto unimplemented;
12301 case 0xb3d1: /* DDTR */ goto unimplemented;
12302 case 0xb3d2: /* ADTR */ goto unimplemented;
12303 case 0xb3d3: /* SDTR */ goto unimplemented;
12304 case 0xb3d4: /* LDETR */ goto unimplemented;
12305 case 0xb3d5: /* LEDTR */ goto unimplemented;
12306 case 0xb3d6: /* LTDTR */ goto unimplemented;
12307 case 0xb3d7: /* FIDTR */ goto unimplemented;
12308 case 0xb3d8: /* MXTR */ goto unimplemented;
12309 case 0xb3d9: /* DXTR */ goto unimplemented;
12310 case 0xb3da: /* AXTR */ goto unimplemented;
12311 case 0xb3db: /* SXTR */ goto unimplemented;
12312 case 0xb3dc: /* LXDTR */ goto unimplemented;
12313 case 0xb3dd: /* LDXTR */ goto unimplemented;
12314 case 0xb3de: /* LTXTR */ goto unimplemented;
12315 case 0xb3df: /* FIXTR */ goto unimplemented;
12316 case 0xb3e0: /* KDTR */ goto unimplemented;
12317 case 0xb3e1: /* CGDTR */ goto unimplemented;
12318 case 0xb3e2: /* CUDTR */ goto unimplemented;
12319 case 0xb3e3: /* CSDTR */ goto unimplemented;
12320 case 0xb3e4: /* CDTR */ goto unimplemented;
12321 case 0xb3e5: /* EEDTR */ goto unimplemented;
12322 case 0xb3e7: /* ESDTR */ goto unimplemented;
12323 case 0xb3e8: /* KXTR */ goto unimplemented;
12324 case 0xb3e9: /* CGXTR */ goto unimplemented;
12325 case 0xb3ea: /* CUXTR */ goto unimplemented;
12326 case 0xb3eb: /* CSXTR */ goto unimplemented;
12327 case 0xb3ec: /* CXTR */ goto unimplemented;
12328 case 0xb3ed: /* EEXTR */ goto unimplemented;
12329 case 0xb3ef: /* ESXTR */ goto unimplemented;
12330 case 0xb3f1: /* CDGTR */ goto unimplemented;
12331 case 0xb3f2: /* CDUTR */ goto unimplemented;
12332 case 0xb3f3: /* CDSTR */ goto unimplemented;
12333 case 0xb3f4: /* CEDTR */ goto unimplemented;
12334 case 0xb3f5: /* QADTR */ goto unimplemented;
12335 case 0xb3f6: /* IEDTR */ goto unimplemented;
12336 case 0xb3f7: /* RRDTR */ goto unimplemented;
12337 case 0xb3f9: /* CXGTR */ goto unimplemented;
12338 case 0xb3fa: /* CXUTR */ goto unimplemented;
12339 case 0xb3fb: /* CXSTR */ goto unimplemented;
12340 case 0xb3fc: /* CEXTR */ goto unimplemented;
12341 case 0xb3fd: /* QAXTR */ goto unimplemented;
12342 case 0xb3fe: /* IEXTR */ goto unimplemented;
12343 case 0xb3ff: /* RRXTR */ goto unimplemented;
12344 case 0xb900: s390_format_RRE_RR(s390_irgen_LPGR, ovl.fmt.RRE.r1,
12345 ovl.fmt.RRE.r2); goto ok;
12346 case 0xb901: s390_format_RRE_RR(s390_irgen_LNGR, ovl.fmt.RRE.r1,
12347 ovl.fmt.RRE.r2); goto ok;
12348 case 0xb902: s390_format_RRE_RR(s390_irgen_LTGR, ovl.fmt.RRE.r1,
12349 ovl.fmt.RRE.r2); goto ok;
12350 case 0xb903: s390_format_RRE_RR(s390_irgen_LCGR, ovl.fmt.RRE.r1,
12351 ovl.fmt.RRE.r2); goto ok;
12352 case 0xb904: s390_format_RRE_RR(s390_irgen_LGR, ovl.fmt.RRE.r1,
12353 ovl.fmt.RRE.r2); goto ok;
12354 case 0xb905: /* LURAG */ goto unimplemented;
12355 case 0xb906: s390_format_RRE_RR(s390_irgen_LGBR, ovl.fmt.RRE.r1,
12356 ovl.fmt.RRE.r2); goto ok;
12357 case 0xb907: s390_format_RRE_RR(s390_irgen_LGHR, ovl.fmt.RRE.r1,
12358 ovl.fmt.RRE.r2); goto ok;
12359 case 0xb908: s390_format_RRE_RR(s390_irgen_AGR, ovl.fmt.RRE.r1,
12360 ovl.fmt.RRE.r2); goto ok;
12361 case 0xb909: s390_format_RRE_RR(s390_irgen_SGR, ovl.fmt.RRE.r1,
12362 ovl.fmt.RRE.r2); goto ok;
12363 case 0xb90a: s390_format_RRE_RR(s390_irgen_ALGR, ovl.fmt.RRE.r1,
12364 ovl.fmt.RRE.r2); goto ok;
12365 case 0xb90b: s390_format_RRE_RR(s390_irgen_SLGR, ovl.fmt.RRE.r1,
12366 ovl.fmt.RRE.r2); goto ok;
12367 case 0xb90c: s390_format_RRE_RR(s390_irgen_MSGR, ovl.fmt.RRE.r1,
12368 ovl.fmt.RRE.r2); goto ok;
12369 case 0xb90d: s390_format_RRE_RR(s390_irgen_DSGR, ovl.fmt.RRE.r1,
12370 ovl.fmt.RRE.r2); goto ok;
12371 case 0xb90e: /* EREGG */ goto unimplemented;
12372 case 0xb90f: s390_format_RRE_RR(s390_irgen_LRVGR, ovl.fmt.RRE.r1,
12373 ovl.fmt.RRE.r2); goto ok;
12374 case 0xb910: s390_format_RRE_RR(s390_irgen_LPGFR, ovl.fmt.RRE.r1,
12375 ovl.fmt.RRE.r2); goto ok;
12376 case 0xb911: s390_format_RRE_RR(s390_irgen_LNGFR, ovl.fmt.RRE.r1,
12377 ovl.fmt.RRE.r2); goto ok;
12378 case 0xb912: s390_format_RRE_RR(s390_irgen_LTGFR, ovl.fmt.RRE.r1,
12379 ovl.fmt.RRE.r2); goto ok;
12380 case 0xb913: s390_format_RRE_RR(s390_irgen_LCGFR, ovl.fmt.RRE.r1,
12381 ovl.fmt.RRE.r2); goto ok;
12382 case 0xb914: s390_format_RRE_RR(s390_irgen_LGFR, ovl.fmt.RRE.r1,
12383 ovl.fmt.RRE.r2); goto ok;
12384 case 0xb916: s390_format_RRE_RR(s390_irgen_LLGFR, ovl.fmt.RRE.r1,
12385 ovl.fmt.RRE.r2); goto ok;
12386 case 0xb917: s390_format_RRE_RR(s390_irgen_LLGTR, ovl.fmt.RRE.r1,
12387 ovl.fmt.RRE.r2); goto ok;
12388 case 0xb918: s390_format_RRE_RR(s390_irgen_AGFR, ovl.fmt.RRE.r1,
12389 ovl.fmt.RRE.r2); goto ok;
12390 case 0xb919: s390_format_RRE_RR(s390_irgen_SGFR, ovl.fmt.RRE.r1,
12391 ovl.fmt.RRE.r2); goto ok;
12392 case 0xb91a: s390_format_RRE_RR(s390_irgen_ALGFR, ovl.fmt.RRE.r1,
12393 ovl.fmt.RRE.r2); goto ok;
12394 case 0xb91b: s390_format_RRE_RR(s390_irgen_SLGFR, ovl.fmt.RRE.r1,
12395 ovl.fmt.RRE.r2); goto ok;
12396 case 0xb91c: s390_format_RRE_RR(s390_irgen_MSGFR, ovl.fmt.RRE.r1,
12397 ovl.fmt.RRE.r2); goto ok;
12398 case 0xb91d: s390_format_RRE_RR(s390_irgen_DSGFR, ovl.fmt.RRE.r1,
12399 ovl.fmt.RRE.r2); goto ok;
12400 case 0xb91e: /* KMAC */ goto unimplemented;
12401 case 0xb91f: s390_format_RRE_RR(s390_irgen_LRVR, ovl.fmt.RRE.r1,
12402 ovl.fmt.RRE.r2); goto ok;
12403 case 0xb920: s390_format_RRE_RR(s390_irgen_CGR, ovl.fmt.RRE.r1,
12404 ovl.fmt.RRE.r2); goto ok;
12405 case 0xb921: s390_format_RRE_RR(s390_irgen_CLGR, ovl.fmt.RRE.r1,
12406 ovl.fmt.RRE.r2); goto ok;
12407 case 0xb925: /* STURG */ goto unimplemented;
12408 case 0xb926: s390_format_RRE_RR(s390_irgen_LBR, ovl.fmt.RRE.r1,
12409 ovl.fmt.RRE.r2); goto ok;
12410 case 0xb927: s390_format_RRE_RR(s390_irgen_LHR, ovl.fmt.RRE.r1,
12411 ovl.fmt.RRE.r2); goto ok;
12412 case 0xb928: /* PCKMO */ goto unimplemented;
12413 case 0xb92b: /* KMO */ goto unimplemented;
12414 case 0xb92c: /* PCC */ goto unimplemented;
12415 case 0xb92d: /* KMCTR */ goto unimplemented;
12416 case 0xb92e: /* KM */ goto unimplemented;
12417 case 0xb92f: /* KMC */ goto unimplemented;
12418 case 0xb930: s390_format_RRE_RR(s390_irgen_CGFR, ovl.fmt.RRE.r1,
12419 ovl.fmt.RRE.r2); goto ok;
12420 case 0xb931: s390_format_RRE_RR(s390_irgen_CLGFR, ovl.fmt.RRE.r1,
12421 ovl.fmt.RRE.r2); goto ok;
12422 case 0xb93e: /* KIMD */ goto unimplemented;
12423 case 0xb93f: /* KLMD */ goto unimplemented;
12424 case 0xb941: /* CFDTR */ goto unimplemented;
12425 case 0xb942: /* CLGDTR */ goto unimplemented;
12426 case 0xb943: /* CLFDTR */ goto unimplemented;
12427 case 0xb946: s390_format_RRE_RR(s390_irgen_BCTGR, ovl.fmt.RRE.r1,
12428 ovl.fmt.RRE.r2); goto ok;
12429 case 0xb949: /* CFXTR */ goto unimplemented;
12430 case 0xb94a: /* CLGXTR */ goto unimplemented;
12431 case 0xb94b: /* CLFXTR */ goto unimplemented;
12432 case 0xb951: /* CDFTR */ goto unimplemented;
12433 case 0xb952: /* CDLGTR */ goto unimplemented;
12434 case 0xb953: /* CDLFTR */ goto unimplemented;
12435 case 0xb959: /* CXFTR */ goto unimplemented;
12436 case 0xb95a: /* CXLGTR */ goto unimplemented;
12437 case 0xb95b: /* CXLFTR */ goto unimplemented;
12438 case 0xb960: /* CGRT */ goto unimplemented;
12439 case 0xb961: /* CLGRT */ goto unimplemented;
12440 case 0xb972: /* CRT */ goto unimplemented;
12441 case 0xb973: /* CLRT */ goto unimplemented;
12442 case 0xb980: s390_format_RRE_RR(s390_irgen_NGR, ovl.fmt.RRE.r1,
12443 ovl.fmt.RRE.r2); goto ok;
12444 case 0xb981: s390_format_RRE_RR(s390_irgen_OGR, ovl.fmt.RRE.r1,
12445 ovl.fmt.RRE.r2); goto ok;
12446 case 0xb982: s390_format_RRE_RR(s390_irgen_XGR, ovl.fmt.RRE.r1,
12447 ovl.fmt.RRE.r2); goto ok;
12448 case 0xb983: s390_format_RRE_RR(s390_irgen_FLOGR, ovl.fmt.RRE.r1,
12449 ovl.fmt.RRE.r2); goto ok;
12450 case 0xb984: s390_format_RRE_RR(s390_irgen_LLGCR, ovl.fmt.RRE.r1,
12451 ovl.fmt.RRE.r2); goto ok;
12452 case 0xb985: s390_format_RRE_RR(s390_irgen_LLGHR, ovl.fmt.RRE.r1,
12453 ovl.fmt.RRE.r2); goto ok;
12454 case 0xb986: s390_format_RRE_RR(s390_irgen_MLGR, ovl.fmt.RRE.r1,
12455 ovl.fmt.RRE.r2); goto ok;
12456 case 0xb987: s390_format_RRE_RR(s390_irgen_DLGR, ovl.fmt.RRE.r1,
12457 ovl.fmt.RRE.r2); goto ok;
12458 case 0xb988: s390_format_RRE_RR(s390_irgen_ALCGR, ovl.fmt.RRE.r1,
12459 ovl.fmt.RRE.r2); goto ok;
12460 case 0xb989: s390_format_RRE_RR(s390_irgen_SLBGR, ovl.fmt.RRE.r1,
12461 ovl.fmt.RRE.r2); goto ok;
12462 case 0xb98a: /* CSPG */ goto unimplemented;
12463 case 0xb98d: /* EPSW */ goto unimplemented;
12464 case 0xb98e: /* IDTE */ goto unimplemented;
florian730448f2012-02-04 17:07:07 +000012465 case 0xb990: s390_format_RRF_M0RERE(s390_irgen_TRTT, ovl.fmt.RRF3.r3,
12466 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
12467 case 0xb991: s390_format_RRF_M0RERE(s390_irgen_TRTO, ovl.fmt.RRF3.r3,
12468 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
12469 case 0xb992: s390_format_RRF_M0RERE(s390_irgen_TROT, ovl.fmt.RRF3.r3,
12470 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
florian9af37692012-01-15 21:01:16 +000012471 case 0xb993: s390_format_RRF_M0RERE(s390_irgen_TROO, ovl.fmt.RRF3.r3,
12472 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000012473 case 0xb994: s390_format_RRE_RR(s390_irgen_LLCR, ovl.fmt.RRE.r1,
12474 ovl.fmt.RRE.r2); goto ok;
12475 case 0xb995: s390_format_RRE_RR(s390_irgen_LLHR, ovl.fmt.RRE.r1,
12476 ovl.fmt.RRE.r2); goto ok;
12477 case 0xb996: s390_format_RRE_RR(s390_irgen_MLR, ovl.fmt.RRE.r1,
12478 ovl.fmt.RRE.r2); goto ok;
12479 case 0xb997: s390_format_RRE_RR(s390_irgen_DLR, ovl.fmt.RRE.r1,
12480 ovl.fmt.RRE.r2); goto ok;
12481 case 0xb998: s390_format_RRE_RR(s390_irgen_ALCR, ovl.fmt.RRE.r1,
12482 ovl.fmt.RRE.r2); goto ok;
12483 case 0xb999: s390_format_RRE_RR(s390_irgen_SLBR, ovl.fmt.RRE.r1,
12484 ovl.fmt.RRE.r2); goto ok;
12485 case 0xb99a: /* EPAIR */ goto unimplemented;
12486 case 0xb99b: /* ESAIR */ goto unimplemented;
12487 case 0xb99d: /* ESEA */ goto unimplemented;
12488 case 0xb99e: /* PTI */ goto unimplemented;
12489 case 0xb99f: /* SSAIR */ goto unimplemented;
12490 case 0xb9a2: /* PTF */ goto unimplemented;
12491 case 0xb9aa: /* LPTEA */ goto unimplemented;
12492 case 0xb9ae: /* RRBM */ goto unimplemented;
12493 case 0xb9af: /* PFMF */ goto unimplemented;
florian3f8a96a2012-08-05 02:59:55 +000012494 case 0xb9b0: s390_format_RRF_M0RERE(s390_irgen_CU14, ovl.fmt.RRF3.r3,
12495 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
12496 goto ok;
florian2a415a12012-07-21 17:41:36 +000012497 case 0xb9b1: s390_format_RRF_M0RERE(s390_irgen_CU24, ovl.fmt.RRF3.r3,
12498 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
12499 goto ok;
sewardj2019a972011-03-07 16:04:07 +000012500 case 0xb9b2: /* CU41 */ goto unimplemented;
florian956194b2012-07-28 22:18:32 +000012501 case 0xb9b3: s390_format_RRE_RR(s390_irgen_CU42, ovl.fmt.RRE.r1,
12502 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000012503 case 0xb9bd: /* TRTRE */ goto unimplemented;
12504 case 0xb9be: /* SRSTU */ goto unimplemented;
12505 case 0xb9bf: /* TRTE */ goto unimplemented;
12506 case 0xb9c8: s390_format_RRF_R0RR2(s390_irgen_AHHHR, ovl.fmt.RRF4.r3,
12507 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12508 goto ok;
12509 case 0xb9c9: s390_format_RRF_R0RR2(s390_irgen_SHHHR, ovl.fmt.RRF4.r3,
12510 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12511 goto ok;
12512 case 0xb9ca: s390_format_RRF_R0RR2(s390_irgen_ALHHHR, ovl.fmt.RRF4.r3,
12513 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12514 goto ok;
12515 case 0xb9cb: s390_format_RRF_R0RR2(s390_irgen_SLHHHR, ovl.fmt.RRF4.r3,
12516 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12517 goto ok;
12518 case 0xb9cd: s390_format_RRE_RR(s390_irgen_CHHR, ovl.fmt.RRE.r1,
12519 ovl.fmt.RRE.r2); goto ok;
12520 case 0xb9cf: s390_format_RRE_RR(s390_irgen_CLHHR, ovl.fmt.RRE.r1,
12521 ovl.fmt.RRE.r2); goto ok;
12522 case 0xb9d8: s390_format_RRF_R0RR2(s390_irgen_AHHLR, ovl.fmt.RRF4.r3,
12523 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12524 goto ok;
12525 case 0xb9d9: s390_format_RRF_R0RR2(s390_irgen_SHHLR, ovl.fmt.RRF4.r3,
12526 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12527 goto ok;
12528 case 0xb9da: s390_format_RRF_R0RR2(s390_irgen_ALHHLR, ovl.fmt.RRF4.r3,
12529 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12530 goto ok;
12531 case 0xb9db: s390_format_RRF_R0RR2(s390_irgen_SLHHLR, ovl.fmt.RRF4.r3,
12532 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12533 goto ok;
12534 case 0xb9dd: s390_format_RRE_RR(s390_irgen_CHLR, ovl.fmt.RRE.r1,
12535 ovl.fmt.RRE.r2); goto ok;
12536 case 0xb9df: s390_format_RRE_RR(s390_irgen_CLHLR, ovl.fmt.RRE.r1,
12537 ovl.fmt.RRE.r2); goto ok;
12538 case 0xb9e1: /* POPCNT */ goto unimplemented;
sewardjd7bde722011-04-05 13:19:33 +000012539 case 0xb9e2: s390_format_RRF_U0RR(s390_irgen_LOCGR, ovl.fmt.RRF3.r3,
12540 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2,
12541 S390_XMNM_LOCGR); goto ok;
sewardj2019a972011-03-07 16:04:07 +000012542 case 0xb9e4: s390_format_RRF_R0RR2(s390_irgen_NGRK, ovl.fmt.RRF4.r3,
12543 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12544 goto ok;
12545 case 0xb9e6: s390_format_RRF_R0RR2(s390_irgen_OGRK, ovl.fmt.RRF4.r3,
12546 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12547 goto ok;
12548 case 0xb9e7: s390_format_RRF_R0RR2(s390_irgen_XGRK, ovl.fmt.RRF4.r3,
12549 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12550 goto ok;
12551 case 0xb9e8: s390_format_RRF_R0RR2(s390_irgen_AGRK, ovl.fmt.RRF4.r3,
12552 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12553 goto ok;
12554 case 0xb9e9: s390_format_RRF_R0RR2(s390_irgen_SGRK, ovl.fmt.RRF4.r3,
12555 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12556 goto ok;
12557 case 0xb9ea: s390_format_RRF_R0RR2(s390_irgen_ALGRK, ovl.fmt.RRF4.r3,
12558 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12559 goto ok;
12560 case 0xb9eb: s390_format_RRF_R0RR2(s390_irgen_SLGRK, ovl.fmt.RRF4.r3,
12561 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12562 goto ok;
sewardjd7bde722011-04-05 13:19:33 +000012563 case 0xb9f2: s390_format_RRF_U0RR(s390_irgen_LOCR, ovl.fmt.RRF3.r3,
12564 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2,
12565 S390_XMNM_LOCR); goto ok;
sewardj2019a972011-03-07 16:04:07 +000012566 case 0xb9f4: s390_format_RRF_R0RR2(s390_irgen_NRK, ovl.fmt.RRF4.r3,
12567 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12568 goto ok;
12569 case 0xb9f6: s390_format_RRF_R0RR2(s390_irgen_ORK, ovl.fmt.RRF4.r3,
12570 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12571 goto ok;
12572 case 0xb9f7: s390_format_RRF_R0RR2(s390_irgen_XRK, ovl.fmt.RRF4.r3,
12573 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12574 goto ok;
12575 case 0xb9f8: s390_format_RRF_R0RR2(s390_irgen_ARK, ovl.fmt.RRF4.r3,
12576 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12577 goto ok;
12578 case 0xb9f9: s390_format_RRF_R0RR2(s390_irgen_SRK, ovl.fmt.RRF4.r3,
12579 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12580 goto ok;
12581 case 0xb9fa: s390_format_RRF_R0RR2(s390_irgen_ALRK, ovl.fmt.RRF4.r3,
12582 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12583 goto ok;
12584 case 0xb9fb: s390_format_RRF_R0RR2(s390_irgen_SLRK, ovl.fmt.RRF4.r3,
12585 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12586 goto ok;
12587 }
12588
12589 switch ((ovl.value & 0xff000000) >> 24) {
12590 case 0x40: s390_format_RX_RRRD(s390_irgen_STH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12591 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12592 case 0x41: s390_format_RX_RRRD(s390_irgen_LA, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12593 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12594 case 0x42: s390_format_RX_RRRD(s390_irgen_STC, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12595 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12596 case 0x43: s390_format_RX_RRRD(s390_irgen_IC, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12597 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12598 case 0x44: s390_format_RX_RRRD(s390_irgen_EX, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12599 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12600 case 0x45: /* BAL */ goto unimplemented;
12601 case 0x46: s390_format_RX_RRRD(s390_irgen_BCT, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12602 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12603 case 0x47: s390_format_RX(s390_irgen_BC, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12604 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12605 case 0x48: s390_format_RX_RRRD(s390_irgen_LH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12606 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12607 case 0x49: s390_format_RX_RRRD(s390_irgen_CH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12608 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12609 case 0x4a: s390_format_RX_RRRD(s390_irgen_AH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12610 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12611 case 0x4b: s390_format_RX_RRRD(s390_irgen_SH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12612 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12613 case 0x4c: s390_format_RX_RRRD(s390_irgen_MH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12614 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12615 case 0x4d: s390_format_RX_RRRD(s390_irgen_BAS, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12616 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12617 case 0x4e: s390_format_RX_RRRD(s390_irgen_CVD, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12618 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12619 case 0x4f: s390_format_RX_RRRD(s390_irgen_CVB, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12620 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12621 case 0x50: s390_format_RX_RRRD(s390_irgen_ST, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12622 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12623 case 0x51: s390_format_RX_RRRD(s390_irgen_LAE, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12624 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12625 case 0x54: s390_format_RX_RRRD(s390_irgen_N, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12626 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12627 case 0x55: s390_format_RX_RRRD(s390_irgen_CL, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12628 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12629 case 0x56: s390_format_RX_RRRD(s390_irgen_O, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12630 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12631 case 0x57: s390_format_RX_RRRD(s390_irgen_X, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12632 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12633 case 0x58: s390_format_RX_RRRD(s390_irgen_L, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12634 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12635 case 0x59: s390_format_RX_RRRD(s390_irgen_C, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12636 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12637 case 0x5a: s390_format_RX_RRRD(s390_irgen_A, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12638 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12639 case 0x5b: s390_format_RX_RRRD(s390_irgen_S, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12640 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12641 case 0x5c: s390_format_RX_RRRD(s390_irgen_M, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12642 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12643 case 0x5d: s390_format_RX_RRRD(s390_irgen_D, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12644 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12645 case 0x5e: s390_format_RX_RRRD(s390_irgen_AL, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12646 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12647 case 0x5f: s390_format_RX_RRRD(s390_irgen_SL, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12648 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12649 case 0x60: s390_format_RX_FRRD(s390_irgen_STD, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12650 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12651 case 0x67: /* MXD */ goto unimplemented;
12652 case 0x68: s390_format_RX_FRRD(s390_irgen_LD, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12653 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12654 case 0x69: /* CD */ goto unimplemented;
12655 case 0x6a: /* AD */ goto unimplemented;
12656 case 0x6b: /* SD */ goto unimplemented;
12657 case 0x6c: /* MD */ goto unimplemented;
12658 case 0x6d: /* DD */ goto unimplemented;
12659 case 0x6e: /* AW */ goto unimplemented;
12660 case 0x6f: /* SW */ goto unimplemented;
12661 case 0x70: s390_format_RX_FRRD(s390_irgen_STE, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12662 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12663 case 0x71: s390_format_RX_RRRD(s390_irgen_MS, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12664 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12665 case 0x78: s390_format_RX_FRRD(s390_irgen_LE, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12666 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12667 case 0x79: /* CE */ goto unimplemented;
12668 case 0x7a: /* AE */ goto unimplemented;
12669 case 0x7b: /* SE */ goto unimplemented;
12670 case 0x7c: /* MDE */ goto unimplemented;
12671 case 0x7d: /* DE */ goto unimplemented;
12672 case 0x7e: /* AU */ goto unimplemented;
12673 case 0x7f: /* SU */ goto unimplemented;
12674 case 0x83: /* DIAG */ goto unimplemented;
12675 case 0x84: s390_format_RSI_RRP(s390_irgen_BRXH, ovl.fmt.RSI.r1,
12676 ovl.fmt.RSI.r3, ovl.fmt.RSI.i2); goto ok;
12677 case 0x85: s390_format_RSI_RRP(s390_irgen_BRXLE, ovl.fmt.RSI.r1,
12678 ovl.fmt.RSI.r3, ovl.fmt.RSI.i2); goto ok;
12679 case 0x86: s390_format_RS_RRRD(s390_irgen_BXH, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
12680 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
12681 case 0x87: s390_format_RS_RRRD(s390_irgen_BXLE, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
12682 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
12683 case 0x88: s390_format_RS_R0RD(s390_irgen_SRL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
12684 ovl.fmt.RS.d2); goto ok;
12685 case 0x89: s390_format_RS_R0RD(s390_irgen_SLL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
12686 ovl.fmt.RS.d2); goto ok;
12687 case 0x8a: s390_format_RS_R0RD(s390_irgen_SRA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
12688 ovl.fmt.RS.d2); goto ok;
12689 case 0x8b: s390_format_RS_R0RD(s390_irgen_SLA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
12690 ovl.fmt.RS.d2); goto ok;
12691 case 0x8c: s390_format_RS_R0RD(s390_irgen_SRDL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
12692 ovl.fmt.RS.d2); goto ok;
12693 case 0x8d: s390_format_RS_R0RD(s390_irgen_SLDL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
12694 ovl.fmt.RS.d2); goto ok;
12695 case 0x8e: s390_format_RS_R0RD(s390_irgen_SRDA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
12696 ovl.fmt.RS.d2); goto ok;
12697 case 0x8f: s390_format_RS_R0RD(s390_irgen_SLDA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
12698 ovl.fmt.RS.d2); goto ok;
12699 case 0x90: s390_format_RS_RRRD(s390_irgen_STM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
12700 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
12701 case 0x91: s390_format_SI_URD(s390_irgen_TM, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
12702 ovl.fmt.SI.d1); goto ok;
12703 case 0x92: s390_format_SI_URD(s390_irgen_MVI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
12704 ovl.fmt.SI.d1); goto ok;
12705 case 0x94: s390_format_SI_URD(s390_irgen_NI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
12706 ovl.fmt.SI.d1); goto ok;
12707 case 0x95: s390_format_SI_URD(s390_irgen_CLI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
12708 ovl.fmt.SI.d1); goto ok;
12709 case 0x96: s390_format_SI_URD(s390_irgen_OI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
12710 ovl.fmt.SI.d1); goto ok;
12711 case 0x97: s390_format_SI_URD(s390_irgen_XI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
12712 ovl.fmt.SI.d1); goto ok;
12713 case 0x98: s390_format_RS_RRRD(s390_irgen_LM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
12714 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
12715 case 0x99: /* TRACE */ goto unimplemented;
12716 case 0x9a: s390_format_RS_AARD(s390_irgen_LAM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
12717 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
12718 case 0x9b: s390_format_RS_AARD(s390_irgen_STAM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
12719 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
12720 case 0xa8: s390_format_RS_RRRD(s390_irgen_MVCLE, ovl.fmt.RS.r1,
12721 ovl.fmt.RS.r3, ovl.fmt.RS.b2, ovl.fmt.RS.d2);
12722 goto ok;
12723 case 0xa9: s390_format_RS_RRRD(s390_irgen_CLCLE, ovl.fmt.RS.r1,
12724 ovl.fmt.RS.r3, ovl.fmt.RS.b2, ovl.fmt.RS.d2);
12725 goto ok;
12726 case 0xac: /* STNSM */ goto unimplemented;
12727 case 0xad: /* STOSM */ goto unimplemented;
12728 case 0xae: /* SIGP */ goto unimplemented;
12729 case 0xaf: /* MC */ goto unimplemented;
12730 case 0xb1: /* LRA */ goto unimplemented;
12731 case 0xb6: /* STCTL */ goto unimplemented;
12732 case 0xb7: /* LCTL */ goto unimplemented;
12733 case 0xba: s390_format_RS_RRRD(s390_irgen_CS, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
12734 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
florian448cbba2012-06-06 02:26:01 +000012735 case 0xbb: s390_format_RS_RRRD(s390_irgen_CDS, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
12736 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000012737 case 0xbd: s390_format_RS_RURD(s390_irgen_CLM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
12738 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
12739 case 0xbe: s390_format_RS_RURD(s390_irgen_STCM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
12740 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
12741 case 0xbf: s390_format_RS_RURD(s390_irgen_ICM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
12742 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
12743 }
12744
12745 return S390_DECODE_UNKNOWN_INSN;
12746
12747ok:
12748 return S390_DECODE_OK;
12749
12750unimplemented:
12751 return S390_DECODE_UNIMPLEMENTED_INSN;
12752}
12753
12754static s390_decode_t
12755s390_decode_6byte_and_irgen(UChar *bytes)
12756{
12757 typedef union {
12758 struct {
12759 unsigned int op1 : 8;
12760 unsigned int r1 : 4;
12761 unsigned int r3 : 4;
12762 unsigned int i2 : 16;
12763 unsigned int : 8;
12764 unsigned int op2 : 8;
12765 } RIE;
12766 struct {
12767 unsigned int op1 : 8;
12768 unsigned int r1 : 4;
12769 unsigned int r2 : 4;
12770 unsigned int i3 : 8;
12771 unsigned int i4 : 8;
12772 unsigned int i5 : 8;
12773 unsigned int op2 : 8;
12774 } RIE_RRUUU;
12775 struct {
12776 unsigned int op1 : 8;
12777 unsigned int r1 : 4;
12778 unsigned int : 4;
12779 unsigned int i2 : 16;
12780 unsigned int m3 : 4;
12781 unsigned int : 4;
12782 unsigned int op2 : 8;
12783 } RIEv1;
12784 struct {
12785 unsigned int op1 : 8;
12786 unsigned int r1 : 4;
12787 unsigned int r2 : 4;
12788 unsigned int i4 : 16;
12789 unsigned int m3 : 4;
12790 unsigned int : 4;
12791 unsigned int op2 : 8;
12792 } RIE_RRPU;
12793 struct {
12794 unsigned int op1 : 8;
12795 unsigned int r1 : 4;
12796 unsigned int m3 : 4;
12797 unsigned int i4 : 16;
12798 unsigned int i2 : 8;
12799 unsigned int op2 : 8;
12800 } RIEv3;
12801 struct {
12802 unsigned int op1 : 8;
12803 unsigned int r1 : 4;
12804 unsigned int op2 : 4;
12805 unsigned int i2 : 32;
12806 } RIL;
12807 struct {
12808 unsigned int op1 : 8;
12809 unsigned int r1 : 4;
12810 unsigned int m3 : 4;
12811 unsigned int b4 : 4;
12812 unsigned int d4 : 12;
12813 unsigned int i2 : 8;
12814 unsigned int op2 : 8;
12815 } RIS;
12816 struct {
12817 unsigned int op1 : 8;
12818 unsigned int r1 : 4;
12819 unsigned int r2 : 4;
12820 unsigned int b4 : 4;
12821 unsigned int d4 : 12;
12822 unsigned int m3 : 4;
12823 unsigned int : 4;
12824 unsigned int op2 : 8;
12825 } RRS;
12826 struct {
12827 unsigned int op1 : 8;
12828 unsigned int l1 : 4;
12829 unsigned int : 4;
12830 unsigned int b1 : 4;
12831 unsigned int d1 : 12;
12832 unsigned int : 8;
12833 unsigned int op2 : 8;
12834 } RSL;
12835 struct {
12836 unsigned int op1 : 8;
12837 unsigned int r1 : 4;
12838 unsigned int r3 : 4;
12839 unsigned int b2 : 4;
12840 unsigned int dl2 : 12;
12841 unsigned int dh2 : 8;
12842 unsigned int op2 : 8;
12843 } RSY;
12844 struct {
12845 unsigned int op1 : 8;
12846 unsigned int r1 : 4;
12847 unsigned int x2 : 4;
12848 unsigned int b2 : 4;
12849 unsigned int d2 : 12;
12850 unsigned int : 8;
12851 unsigned int op2 : 8;
12852 } RXE;
12853 struct {
12854 unsigned int op1 : 8;
12855 unsigned int r3 : 4;
12856 unsigned int x2 : 4;
12857 unsigned int b2 : 4;
12858 unsigned int d2 : 12;
12859 unsigned int r1 : 4;
12860 unsigned int : 4;
12861 unsigned int op2 : 8;
12862 } RXF;
12863 struct {
12864 unsigned int op1 : 8;
12865 unsigned int r1 : 4;
12866 unsigned int x2 : 4;
12867 unsigned int b2 : 4;
12868 unsigned int dl2 : 12;
12869 unsigned int dh2 : 8;
12870 unsigned int op2 : 8;
12871 } RXY;
12872 struct {
12873 unsigned int op1 : 8;
12874 unsigned int i2 : 8;
12875 unsigned int b1 : 4;
12876 unsigned int dl1 : 12;
12877 unsigned int dh1 : 8;
12878 unsigned int op2 : 8;
12879 } SIY;
12880 struct {
12881 unsigned int op : 8;
12882 unsigned int l : 8;
12883 unsigned int b1 : 4;
12884 unsigned int d1 : 12;
12885 unsigned int b2 : 4;
12886 unsigned int d2 : 12;
12887 } SS;
12888 struct {
12889 unsigned int op : 8;
12890 unsigned int l1 : 4;
12891 unsigned int l2 : 4;
12892 unsigned int b1 : 4;
12893 unsigned int d1 : 12;
12894 unsigned int b2 : 4;
12895 unsigned int d2 : 12;
12896 } SS_LLRDRD;
12897 struct {
12898 unsigned int op : 8;
12899 unsigned int r1 : 4;
12900 unsigned int r3 : 4;
12901 unsigned int b2 : 4;
12902 unsigned int d2 : 12;
12903 unsigned int b4 : 4;
12904 unsigned int d4 : 12;
12905 } SS_RRRDRD2;
12906 struct {
12907 unsigned int op : 16;
12908 unsigned int b1 : 4;
12909 unsigned int d1 : 12;
12910 unsigned int b2 : 4;
12911 unsigned int d2 : 12;
12912 } SSE;
12913 struct {
12914 unsigned int op1 : 8;
12915 unsigned int r3 : 4;
12916 unsigned int op2 : 4;
12917 unsigned int b1 : 4;
12918 unsigned int d1 : 12;
12919 unsigned int b2 : 4;
12920 unsigned int d2 : 12;
12921 } SSF;
12922 struct {
12923 unsigned int op : 16;
12924 unsigned int b1 : 4;
12925 unsigned int d1 : 12;
12926 unsigned int i2 : 16;
12927 } SIL;
12928 } formats;
12929 union {
12930 formats fmt;
12931 ULong value;
12932 } ovl;
12933
12934 vassert(sizeof(formats) == 6);
12935
12936 ((char *)(&ovl.value))[0] = bytes[0];
12937 ((char *)(&ovl.value))[1] = bytes[1];
12938 ((char *)(&ovl.value))[2] = bytes[2];
12939 ((char *)(&ovl.value))[3] = bytes[3];
12940 ((char *)(&ovl.value))[4] = bytes[4];
12941 ((char *)(&ovl.value))[5] = bytes[5];
12942 ((char *)(&ovl.value))[6] = 0x0;
12943 ((char *)(&ovl.value))[7] = 0x0;
12944
12945 switch ((ovl.value >> 16) & 0xff00000000ffULL) {
12946 case 0xe30000000002ULL: s390_format_RXY_RRRD(s390_irgen_LTG, ovl.fmt.RXY.r1,
12947 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12948 ovl.fmt.RXY.dl2,
12949 ovl.fmt.RXY.dh2); goto ok;
12950 case 0xe30000000003ULL: /* LRAG */ goto unimplemented;
12951 case 0xe30000000004ULL: s390_format_RXY_RRRD(s390_irgen_LG, ovl.fmt.RXY.r1,
12952 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12953 ovl.fmt.RXY.dl2,
12954 ovl.fmt.RXY.dh2); goto ok;
12955 case 0xe30000000006ULL: s390_format_RXY_RRRD(s390_irgen_CVBY, ovl.fmt.RXY.r1,
12956 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12957 ovl.fmt.RXY.dl2,
12958 ovl.fmt.RXY.dh2); goto ok;
12959 case 0xe30000000008ULL: s390_format_RXY_RRRD(s390_irgen_AG, ovl.fmt.RXY.r1,
12960 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12961 ovl.fmt.RXY.dl2,
12962 ovl.fmt.RXY.dh2); goto ok;
12963 case 0xe30000000009ULL: s390_format_RXY_RRRD(s390_irgen_SG, ovl.fmt.RXY.r1,
12964 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12965 ovl.fmt.RXY.dl2,
12966 ovl.fmt.RXY.dh2); goto ok;
12967 case 0xe3000000000aULL: s390_format_RXY_RRRD(s390_irgen_ALG, ovl.fmt.RXY.r1,
12968 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12969 ovl.fmt.RXY.dl2,
12970 ovl.fmt.RXY.dh2); goto ok;
12971 case 0xe3000000000bULL: s390_format_RXY_RRRD(s390_irgen_SLG, ovl.fmt.RXY.r1,
12972 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12973 ovl.fmt.RXY.dl2,
12974 ovl.fmt.RXY.dh2); goto ok;
12975 case 0xe3000000000cULL: s390_format_RXY_RRRD(s390_irgen_MSG, ovl.fmt.RXY.r1,
12976 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12977 ovl.fmt.RXY.dl2,
12978 ovl.fmt.RXY.dh2); goto ok;
12979 case 0xe3000000000dULL: s390_format_RXY_RRRD(s390_irgen_DSG, ovl.fmt.RXY.r1,
12980 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12981 ovl.fmt.RXY.dl2,
12982 ovl.fmt.RXY.dh2); goto ok;
12983 case 0xe3000000000eULL: /* CVBG */ goto unimplemented;
12984 case 0xe3000000000fULL: s390_format_RXY_RRRD(s390_irgen_LRVG, ovl.fmt.RXY.r1,
12985 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12986 ovl.fmt.RXY.dl2,
12987 ovl.fmt.RXY.dh2); goto ok;
12988 case 0xe30000000012ULL: s390_format_RXY_RRRD(s390_irgen_LT, ovl.fmt.RXY.r1,
12989 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12990 ovl.fmt.RXY.dl2,
12991 ovl.fmt.RXY.dh2); goto ok;
12992 case 0xe30000000013ULL: /* LRAY */ goto unimplemented;
12993 case 0xe30000000014ULL: s390_format_RXY_RRRD(s390_irgen_LGF, ovl.fmt.RXY.r1,
12994 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12995 ovl.fmt.RXY.dl2,
12996 ovl.fmt.RXY.dh2); goto ok;
12997 case 0xe30000000015ULL: s390_format_RXY_RRRD(s390_irgen_LGH, ovl.fmt.RXY.r1,
12998 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12999 ovl.fmt.RXY.dl2,
13000 ovl.fmt.RXY.dh2); goto ok;
13001 case 0xe30000000016ULL: s390_format_RXY_RRRD(s390_irgen_LLGF, ovl.fmt.RXY.r1,
13002 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13003 ovl.fmt.RXY.dl2,
13004 ovl.fmt.RXY.dh2); goto ok;
13005 case 0xe30000000017ULL: s390_format_RXY_RRRD(s390_irgen_LLGT, ovl.fmt.RXY.r1,
13006 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13007 ovl.fmt.RXY.dl2,
13008 ovl.fmt.RXY.dh2); goto ok;
13009 case 0xe30000000018ULL: s390_format_RXY_RRRD(s390_irgen_AGF, ovl.fmt.RXY.r1,
13010 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13011 ovl.fmt.RXY.dl2,
13012 ovl.fmt.RXY.dh2); goto ok;
13013 case 0xe30000000019ULL: s390_format_RXY_RRRD(s390_irgen_SGF, ovl.fmt.RXY.r1,
13014 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13015 ovl.fmt.RXY.dl2,
13016 ovl.fmt.RXY.dh2); goto ok;
13017 case 0xe3000000001aULL: s390_format_RXY_RRRD(s390_irgen_ALGF, ovl.fmt.RXY.r1,
13018 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13019 ovl.fmt.RXY.dl2,
13020 ovl.fmt.RXY.dh2); goto ok;
13021 case 0xe3000000001bULL: s390_format_RXY_RRRD(s390_irgen_SLGF, ovl.fmt.RXY.r1,
13022 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13023 ovl.fmt.RXY.dl2,
13024 ovl.fmt.RXY.dh2); goto ok;
13025 case 0xe3000000001cULL: s390_format_RXY_RRRD(s390_irgen_MSGF, ovl.fmt.RXY.r1,
13026 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13027 ovl.fmt.RXY.dl2,
13028 ovl.fmt.RXY.dh2); goto ok;
13029 case 0xe3000000001dULL: s390_format_RXY_RRRD(s390_irgen_DSGF, ovl.fmt.RXY.r1,
13030 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13031 ovl.fmt.RXY.dl2,
13032 ovl.fmt.RXY.dh2); goto ok;
13033 case 0xe3000000001eULL: s390_format_RXY_RRRD(s390_irgen_LRV, ovl.fmt.RXY.r1,
13034 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13035 ovl.fmt.RXY.dl2,
13036 ovl.fmt.RXY.dh2); goto ok;
13037 case 0xe3000000001fULL: s390_format_RXY_RRRD(s390_irgen_LRVH, ovl.fmt.RXY.r1,
13038 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13039 ovl.fmt.RXY.dl2,
13040 ovl.fmt.RXY.dh2); goto ok;
13041 case 0xe30000000020ULL: s390_format_RXY_RRRD(s390_irgen_CG, ovl.fmt.RXY.r1,
13042 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13043 ovl.fmt.RXY.dl2,
13044 ovl.fmt.RXY.dh2); goto ok;
13045 case 0xe30000000021ULL: s390_format_RXY_RRRD(s390_irgen_CLG, ovl.fmt.RXY.r1,
13046 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13047 ovl.fmt.RXY.dl2,
13048 ovl.fmt.RXY.dh2); goto ok;
13049 case 0xe30000000024ULL: s390_format_RXY_RRRD(s390_irgen_STG, ovl.fmt.RXY.r1,
13050 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13051 ovl.fmt.RXY.dl2,
13052 ovl.fmt.RXY.dh2); goto ok;
13053 case 0xe30000000026ULL: s390_format_RXY_RRRD(s390_irgen_CVDY, ovl.fmt.RXY.r1,
13054 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13055 ovl.fmt.RXY.dl2,
13056 ovl.fmt.RXY.dh2); goto ok;
13057 case 0xe3000000002eULL: /* CVDG */ goto unimplemented;
13058 case 0xe3000000002fULL: s390_format_RXY_RRRD(s390_irgen_STRVG,
13059 ovl.fmt.RXY.r1, ovl.fmt.RXY.x2,
13060 ovl.fmt.RXY.b2, ovl.fmt.RXY.dl2,
13061 ovl.fmt.RXY.dh2); goto ok;
13062 case 0xe30000000030ULL: s390_format_RXY_RRRD(s390_irgen_CGF, ovl.fmt.RXY.r1,
13063 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13064 ovl.fmt.RXY.dl2,
13065 ovl.fmt.RXY.dh2); goto ok;
13066 case 0xe30000000031ULL: s390_format_RXY_RRRD(s390_irgen_CLGF, ovl.fmt.RXY.r1,
13067 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13068 ovl.fmt.RXY.dl2,
13069 ovl.fmt.RXY.dh2); goto ok;
13070 case 0xe30000000032ULL: s390_format_RXY_RRRD(s390_irgen_LTGF, ovl.fmt.RXY.r1,
13071 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13072 ovl.fmt.RXY.dl2,
13073 ovl.fmt.RXY.dh2); goto ok;
13074 case 0xe30000000034ULL: s390_format_RXY_RRRD(s390_irgen_CGH, ovl.fmt.RXY.r1,
13075 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13076 ovl.fmt.RXY.dl2,
13077 ovl.fmt.RXY.dh2); goto ok;
13078 case 0xe30000000036ULL: s390_format_RXY_URRD(s390_irgen_PFD, ovl.fmt.RXY.r1,
13079 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13080 ovl.fmt.RXY.dl2,
13081 ovl.fmt.RXY.dh2); goto ok;
13082 case 0xe3000000003eULL: s390_format_RXY_RRRD(s390_irgen_STRV, ovl.fmt.RXY.r1,
13083 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13084 ovl.fmt.RXY.dl2,
13085 ovl.fmt.RXY.dh2); goto ok;
13086 case 0xe3000000003fULL: s390_format_RXY_RRRD(s390_irgen_STRVH,
13087 ovl.fmt.RXY.r1, ovl.fmt.RXY.x2,
13088 ovl.fmt.RXY.b2, ovl.fmt.RXY.dl2,
13089 ovl.fmt.RXY.dh2); goto ok;
13090 case 0xe30000000046ULL: s390_format_RXY_RRRD(s390_irgen_BCTG, ovl.fmt.RXY.r1,
13091 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13092 ovl.fmt.RXY.dl2,
13093 ovl.fmt.RXY.dh2); goto ok;
13094 case 0xe30000000050ULL: s390_format_RXY_RRRD(s390_irgen_STY, ovl.fmt.RXY.r1,
13095 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13096 ovl.fmt.RXY.dl2,
13097 ovl.fmt.RXY.dh2); goto ok;
13098 case 0xe30000000051ULL: s390_format_RXY_RRRD(s390_irgen_MSY, ovl.fmt.RXY.r1,
13099 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13100 ovl.fmt.RXY.dl2,
13101 ovl.fmt.RXY.dh2); goto ok;
13102 case 0xe30000000054ULL: s390_format_RXY_RRRD(s390_irgen_NY, ovl.fmt.RXY.r1,
13103 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13104 ovl.fmt.RXY.dl2,
13105 ovl.fmt.RXY.dh2); goto ok;
13106 case 0xe30000000055ULL: s390_format_RXY_RRRD(s390_irgen_CLY, ovl.fmt.RXY.r1,
13107 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13108 ovl.fmt.RXY.dl2,
13109 ovl.fmt.RXY.dh2); goto ok;
13110 case 0xe30000000056ULL: s390_format_RXY_RRRD(s390_irgen_OY, ovl.fmt.RXY.r1,
13111 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13112 ovl.fmt.RXY.dl2,
13113 ovl.fmt.RXY.dh2); goto ok;
13114 case 0xe30000000057ULL: s390_format_RXY_RRRD(s390_irgen_XY, ovl.fmt.RXY.r1,
13115 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13116 ovl.fmt.RXY.dl2,
13117 ovl.fmt.RXY.dh2); goto ok;
13118 case 0xe30000000058ULL: s390_format_RXY_RRRD(s390_irgen_LY, ovl.fmt.RXY.r1,
13119 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13120 ovl.fmt.RXY.dl2,
13121 ovl.fmt.RXY.dh2); goto ok;
13122 case 0xe30000000059ULL: s390_format_RXY_RRRD(s390_irgen_CY, ovl.fmt.RXY.r1,
13123 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13124 ovl.fmt.RXY.dl2,
13125 ovl.fmt.RXY.dh2); goto ok;
13126 case 0xe3000000005aULL: s390_format_RXY_RRRD(s390_irgen_AY, ovl.fmt.RXY.r1,
13127 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13128 ovl.fmt.RXY.dl2,
13129 ovl.fmt.RXY.dh2); goto ok;
13130 case 0xe3000000005bULL: s390_format_RXY_RRRD(s390_irgen_SY, ovl.fmt.RXY.r1,
13131 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13132 ovl.fmt.RXY.dl2,
13133 ovl.fmt.RXY.dh2); goto ok;
13134 case 0xe3000000005cULL: s390_format_RXY_RRRD(s390_irgen_MFY, ovl.fmt.RXY.r1,
13135 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13136 ovl.fmt.RXY.dl2,
13137 ovl.fmt.RXY.dh2); goto ok;
13138 case 0xe3000000005eULL: s390_format_RXY_RRRD(s390_irgen_ALY, ovl.fmt.RXY.r1,
13139 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13140 ovl.fmt.RXY.dl2,
13141 ovl.fmt.RXY.dh2); goto ok;
13142 case 0xe3000000005fULL: s390_format_RXY_RRRD(s390_irgen_SLY, ovl.fmt.RXY.r1,
13143 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13144 ovl.fmt.RXY.dl2,
13145 ovl.fmt.RXY.dh2); goto ok;
13146 case 0xe30000000070ULL: s390_format_RXY_RRRD(s390_irgen_STHY, ovl.fmt.RXY.r1,
13147 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13148 ovl.fmt.RXY.dl2,
13149 ovl.fmt.RXY.dh2); goto ok;
13150 case 0xe30000000071ULL: s390_format_RXY_RRRD(s390_irgen_LAY, ovl.fmt.RXY.r1,
13151 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13152 ovl.fmt.RXY.dl2,
13153 ovl.fmt.RXY.dh2); goto ok;
13154 case 0xe30000000072ULL: s390_format_RXY_RRRD(s390_irgen_STCY, ovl.fmt.RXY.r1,
13155 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13156 ovl.fmt.RXY.dl2,
13157 ovl.fmt.RXY.dh2); goto ok;
13158 case 0xe30000000073ULL: s390_format_RXY_RRRD(s390_irgen_ICY, ovl.fmt.RXY.r1,
13159 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13160 ovl.fmt.RXY.dl2,
13161 ovl.fmt.RXY.dh2); goto ok;
13162 case 0xe30000000075ULL: s390_format_RXY_RRRD(s390_irgen_LAEY, ovl.fmt.RXY.r1,
13163 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13164 ovl.fmt.RXY.dl2,
13165 ovl.fmt.RXY.dh2); goto ok;
13166 case 0xe30000000076ULL: s390_format_RXY_RRRD(s390_irgen_LB, ovl.fmt.RXY.r1,
13167 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13168 ovl.fmt.RXY.dl2,
13169 ovl.fmt.RXY.dh2); goto ok;
13170 case 0xe30000000077ULL: s390_format_RXY_RRRD(s390_irgen_LGB, ovl.fmt.RXY.r1,
13171 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13172 ovl.fmt.RXY.dl2,
13173 ovl.fmt.RXY.dh2); goto ok;
13174 case 0xe30000000078ULL: s390_format_RXY_RRRD(s390_irgen_LHY, ovl.fmt.RXY.r1,
13175 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13176 ovl.fmt.RXY.dl2,
13177 ovl.fmt.RXY.dh2); goto ok;
13178 case 0xe30000000079ULL: s390_format_RXY_RRRD(s390_irgen_CHY, ovl.fmt.RXY.r1,
13179 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13180 ovl.fmt.RXY.dl2,
13181 ovl.fmt.RXY.dh2); goto ok;
13182 case 0xe3000000007aULL: s390_format_RXY_RRRD(s390_irgen_AHY, ovl.fmt.RXY.r1,
13183 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13184 ovl.fmt.RXY.dl2,
13185 ovl.fmt.RXY.dh2); goto ok;
13186 case 0xe3000000007bULL: s390_format_RXY_RRRD(s390_irgen_SHY, ovl.fmt.RXY.r1,
13187 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13188 ovl.fmt.RXY.dl2,
13189 ovl.fmt.RXY.dh2); goto ok;
13190 case 0xe3000000007cULL: s390_format_RXY_RRRD(s390_irgen_MHY, ovl.fmt.RXY.r1,
13191 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13192 ovl.fmt.RXY.dl2,
13193 ovl.fmt.RXY.dh2); goto ok;
13194 case 0xe30000000080ULL: s390_format_RXY_RRRD(s390_irgen_NG, ovl.fmt.RXY.r1,
13195 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13196 ovl.fmt.RXY.dl2,
13197 ovl.fmt.RXY.dh2); goto ok;
13198 case 0xe30000000081ULL: s390_format_RXY_RRRD(s390_irgen_OG, ovl.fmt.RXY.r1,
13199 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13200 ovl.fmt.RXY.dl2,
13201 ovl.fmt.RXY.dh2); goto ok;
13202 case 0xe30000000082ULL: s390_format_RXY_RRRD(s390_irgen_XG, ovl.fmt.RXY.r1,
13203 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13204 ovl.fmt.RXY.dl2,
13205 ovl.fmt.RXY.dh2); goto ok;
13206 case 0xe30000000086ULL: s390_format_RXY_RRRD(s390_irgen_MLG, ovl.fmt.RXY.r1,
13207 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13208 ovl.fmt.RXY.dl2,
13209 ovl.fmt.RXY.dh2); goto ok;
13210 case 0xe30000000087ULL: s390_format_RXY_RRRD(s390_irgen_DLG, ovl.fmt.RXY.r1,
13211 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13212 ovl.fmt.RXY.dl2,
13213 ovl.fmt.RXY.dh2); goto ok;
13214 case 0xe30000000088ULL: s390_format_RXY_RRRD(s390_irgen_ALCG, ovl.fmt.RXY.r1,
13215 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13216 ovl.fmt.RXY.dl2,
13217 ovl.fmt.RXY.dh2); goto ok;
13218 case 0xe30000000089ULL: s390_format_RXY_RRRD(s390_irgen_SLBG, ovl.fmt.RXY.r1,
13219 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13220 ovl.fmt.RXY.dl2,
13221 ovl.fmt.RXY.dh2); goto ok;
13222 case 0xe3000000008eULL: s390_format_RXY_RRRD(s390_irgen_STPQ, ovl.fmt.RXY.r1,
13223 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13224 ovl.fmt.RXY.dl2,
13225 ovl.fmt.RXY.dh2); goto ok;
13226 case 0xe3000000008fULL: s390_format_RXY_RRRD(s390_irgen_LPQ, ovl.fmt.RXY.r1,
13227 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13228 ovl.fmt.RXY.dl2,
13229 ovl.fmt.RXY.dh2); goto ok;
13230 case 0xe30000000090ULL: s390_format_RXY_RRRD(s390_irgen_LLGC, ovl.fmt.RXY.r1,
13231 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13232 ovl.fmt.RXY.dl2,
13233 ovl.fmt.RXY.dh2); goto ok;
13234 case 0xe30000000091ULL: s390_format_RXY_RRRD(s390_irgen_LLGH, ovl.fmt.RXY.r1,
13235 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13236 ovl.fmt.RXY.dl2,
13237 ovl.fmt.RXY.dh2); goto ok;
13238 case 0xe30000000094ULL: s390_format_RXY_RRRD(s390_irgen_LLC, ovl.fmt.RXY.r1,
13239 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13240 ovl.fmt.RXY.dl2,
13241 ovl.fmt.RXY.dh2); goto ok;
13242 case 0xe30000000095ULL: s390_format_RXY_RRRD(s390_irgen_LLH, ovl.fmt.RXY.r1,
13243 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13244 ovl.fmt.RXY.dl2,
13245 ovl.fmt.RXY.dh2); goto ok;
13246 case 0xe30000000096ULL: s390_format_RXY_RRRD(s390_irgen_ML, ovl.fmt.RXY.r1,
13247 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13248 ovl.fmt.RXY.dl2,
13249 ovl.fmt.RXY.dh2); goto ok;
13250 case 0xe30000000097ULL: s390_format_RXY_RRRD(s390_irgen_DL, ovl.fmt.RXY.r1,
13251 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13252 ovl.fmt.RXY.dl2,
13253 ovl.fmt.RXY.dh2); goto ok;
13254 case 0xe30000000098ULL: s390_format_RXY_RRRD(s390_irgen_ALC, ovl.fmt.RXY.r1,
13255 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13256 ovl.fmt.RXY.dl2,
13257 ovl.fmt.RXY.dh2); goto ok;
13258 case 0xe30000000099ULL: s390_format_RXY_RRRD(s390_irgen_SLB, ovl.fmt.RXY.r1,
13259 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13260 ovl.fmt.RXY.dl2,
13261 ovl.fmt.RXY.dh2); goto ok;
13262 case 0xe300000000c0ULL: s390_format_RXY_RRRD(s390_irgen_LBH, ovl.fmt.RXY.r1,
13263 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13264 ovl.fmt.RXY.dl2,
13265 ovl.fmt.RXY.dh2); goto ok;
13266 case 0xe300000000c2ULL: s390_format_RXY_RRRD(s390_irgen_LLCH, ovl.fmt.RXY.r1,
13267 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13268 ovl.fmt.RXY.dl2,
13269 ovl.fmt.RXY.dh2); goto ok;
13270 case 0xe300000000c3ULL: s390_format_RXY_RRRD(s390_irgen_STCH, ovl.fmt.RXY.r1,
13271 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13272 ovl.fmt.RXY.dl2,
13273 ovl.fmt.RXY.dh2); goto ok;
13274 case 0xe300000000c4ULL: s390_format_RXY_RRRD(s390_irgen_LHH, ovl.fmt.RXY.r1,
13275 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13276 ovl.fmt.RXY.dl2,
13277 ovl.fmt.RXY.dh2); goto ok;
13278 case 0xe300000000c6ULL: s390_format_RXY_RRRD(s390_irgen_LLHH, ovl.fmt.RXY.r1,
13279 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13280 ovl.fmt.RXY.dl2,
13281 ovl.fmt.RXY.dh2); goto ok;
13282 case 0xe300000000c7ULL: s390_format_RXY_RRRD(s390_irgen_STHH, ovl.fmt.RXY.r1,
13283 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13284 ovl.fmt.RXY.dl2,
13285 ovl.fmt.RXY.dh2); goto ok;
13286 case 0xe300000000caULL: s390_format_RXY_RRRD(s390_irgen_LFH, ovl.fmt.RXY.r1,
13287 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13288 ovl.fmt.RXY.dl2,
13289 ovl.fmt.RXY.dh2); goto ok;
13290 case 0xe300000000cbULL: s390_format_RXY_RRRD(s390_irgen_STFH, ovl.fmt.RXY.r1,
13291 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13292 ovl.fmt.RXY.dl2,
13293 ovl.fmt.RXY.dh2); goto ok;
13294 case 0xe300000000cdULL: s390_format_RXY_RRRD(s390_irgen_CHF, ovl.fmt.RXY.r1,
13295 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13296 ovl.fmt.RXY.dl2,
13297 ovl.fmt.RXY.dh2); goto ok;
13298 case 0xe300000000cfULL: s390_format_RXY_RRRD(s390_irgen_CLHF, ovl.fmt.RXY.r1,
13299 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13300 ovl.fmt.RXY.dl2,
13301 ovl.fmt.RXY.dh2); goto ok;
13302 case 0xeb0000000004ULL: s390_format_RSY_RRRD(s390_irgen_LMG, ovl.fmt.RSY.r1,
13303 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13304 ovl.fmt.RSY.dl2,
13305 ovl.fmt.RSY.dh2); goto ok;
13306 case 0xeb000000000aULL: s390_format_RSY_RRRD(s390_irgen_SRAG, ovl.fmt.RSY.r1,
13307 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13308 ovl.fmt.RSY.dl2,
13309 ovl.fmt.RSY.dh2); goto ok;
13310 case 0xeb000000000bULL: s390_format_RSY_RRRD(s390_irgen_SLAG, ovl.fmt.RSY.r1,
13311 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13312 ovl.fmt.RSY.dl2,
13313 ovl.fmt.RSY.dh2); goto ok;
13314 case 0xeb000000000cULL: s390_format_RSY_RRRD(s390_irgen_SRLG, ovl.fmt.RSY.r1,
13315 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13316 ovl.fmt.RSY.dl2,
13317 ovl.fmt.RSY.dh2); goto ok;
13318 case 0xeb000000000dULL: s390_format_RSY_RRRD(s390_irgen_SLLG, ovl.fmt.RSY.r1,
13319 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13320 ovl.fmt.RSY.dl2,
13321 ovl.fmt.RSY.dh2); goto ok;
13322 case 0xeb000000000fULL: /* TRACG */ goto unimplemented;
13323 case 0xeb0000000014ULL: s390_format_RSY_RRRD(s390_irgen_CSY, ovl.fmt.RSY.r1,
13324 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13325 ovl.fmt.RSY.dl2,
13326 ovl.fmt.RSY.dh2); goto ok;
13327 case 0xeb000000001cULL: s390_format_RSY_RRRD(s390_irgen_RLLG, ovl.fmt.RSY.r1,
13328 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13329 ovl.fmt.RSY.dl2,
13330 ovl.fmt.RSY.dh2); goto ok;
13331 case 0xeb000000001dULL: s390_format_RSY_RRRD(s390_irgen_RLL, ovl.fmt.RSY.r1,
13332 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13333 ovl.fmt.RSY.dl2,
13334 ovl.fmt.RSY.dh2); goto ok;
13335 case 0xeb0000000020ULL: s390_format_RSY_RURD(s390_irgen_CLMH, ovl.fmt.RSY.r1,
13336 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13337 ovl.fmt.RSY.dl2,
13338 ovl.fmt.RSY.dh2); goto ok;
13339 case 0xeb0000000021ULL: s390_format_RSY_RURD(s390_irgen_CLMY, ovl.fmt.RSY.r1,
13340 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13341 ovl.fmt.RSY.dl2,
13342 ovl.fmt.RSY.dh2); goto ok;
13343 case 0xeb0000000024ULL: s390_format_RSY_RRRD(s390_irgen_STMG, ovl.fmt.RSY.r1,
13344 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13345 ovl.fmt.RSY.dl2,
13346 ovl.fmt.RSY.dh2); goto ok;
13347 case 0xeb0000000025ULL: /* STCTG */ goto unimplemented;
13348 case 0xeb0000000026ULL: s390_format_RSY_RRRD(s390_irgen_STMH, ovl.fmt.RSY.r1,
13349 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13350 ovl.fmt.RSY.dl2,
13351 ovl.fmt.RSY.dh2); goto ok;
13352 case 0xeb000000002cULL: s390_format_RSY_RURD(s390_irgen_STCMH,
13353 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
13354 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
13355 ovl.fmt.RSY.dh2); goto ok;
13356 case 0xeb000000002dULL: s390_format_RSY_RURD(s390_irgen_STCMY,
13357 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
13358 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
13359 ovl.fmt.RSY.dh2); goto ok;
13360 case 0xeb000000002fULL: /* LCTLG */ goto unimplemented;
13361 case 0xeb0000000030ULL: s390_format_RSY_RRRD(s390_irgen_CSG, ovl.fmt.RSY.r1,
13362 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13363 ovl.fmt.RSY.dl2,
13364 ovl.fmt.RSY.dh2); goto ok;
florian448cbba2012-06-06 02:26:01 +000013365 case 0xeb0000000031ULL: s390_format_RSY_RRRD(s390_irgen_CDSY, ovl.fmt.RSY.r1,
13366 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13367 ovl.fmt.RSY.dl2,
13368 ovl.fmt.RSY.dh2); goto ok;
13369 case 0xeb000000003eULL: s390_format_RSY_RRRD(s390_irgen_CDSG, ovl.fmt.RSY.r1,
13370 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13371 ovl.fmt.RSY.dl2,
13372 ovl.fmt.RSY.dh2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013373 case 0xeb0000000044ULL: s390_format_RSY_RRRD(s390_irgen_BXHG, ovl.fmt.RSY.r1,
13374 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13375 ovl.fmt.RSY.dl2,
13376 ovl.fmt.RSY.dh2); goto ok;
13377 case 0xeb0000000045ULL: s390_format_RSY_RRRD(s390_irgen_BXLEG,
13378 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
13379 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
13380 ovl.fmt.RSY.dh2); goto ok;
13381 case 0xeb000000004cULL: /* ECAG */ goto unimplemented;
13382 case 0xeb0000000051ULL: s390_format_SIY_URD(s390_irgen_TMY, ovl.fmt.SIY.i2,
13383 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
13384 ovl.fmt.SIY.dh1); goto ok;
13385 case 0xeb0000000052ULL: s390_format_SIY_URD(s390_irgen_MVIY, ovl.fmt.SIY.i2,
13386 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
13387 ovl.fmt.SIY.dh1); goto ok;
13388 case 0xeb0000000054ULL: s390_format_SIY_URD(s390_irgen_NIY, ovl.fmt.SIY.i2,
13389 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
13390 ovl.fmt.SIY.dh1); goto ok;
13391 case 0xeb0000000055ULL: s390_format_SIY_URD(s390_irgen_CLIY, ovl.fmt.SIY.i2,
13392 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
13393 ovl.fmt.SIY.dh1); goto ok;
13394 case 0xeb0000000056ULL: s390_format_SIY_URD(s390_irgen_OIY, ovl.fmt.SIY.i2,
13395 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
13396 ovl.fmt.SIY.dh1); goto ok;
13397 case 0xeb0000000057ULL: s390_format_SIY_URD(s390_irgen_XIY, ovl.fmt.SIY.i2,
13398 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
13399 ovl.fmt.SIY.dh1); goto ok;
13400 case 0xeb000000006aULL: s390_format_SIY_IRD(s390_irgen_ASI, ovl.fmt.SIY.i2,
13401 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
13402 ovl.fmt.SIY.dh1); goto ok;
13403 case 0xeb000000006eULL: s390_format_SIY_IRD(s390_irgen_ALSI, ovl.fmt.SIY.i2,
13404 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
13405 ovl.fmt.SIY.dh1); goto ok;
13406 case 0xeb000000007aULL: s390_format_SIY_IRD(s390_irgen_AGSI, ovl.fmt.SIY.i2,
13407 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
13408 ovl.fmt.SIY.dh1); goto ok;
13409 case 0xeb000000007eULL: s390_format_SIY_IRD(s390_irgen_ALGSI, ovl.fmt.SIY.i2,
13410 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
13411 ovl.fmt.SIY.dh1); goto ok;
13412 case 0xeb0000000080ULL: s390_format_RSY_RURD(s390_irgen_ICMH, ovl.fmt.RSY.r1,
13413 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13414 ovl.fmt.RSY.dl2,
13415 ovl.fmt.RSY.dh2); goto ok;
13416 case 0xeb0000000081ULL: s390_format_RSY_RURD(s390_irgen_ICMY, ovl.fmt.RSY.r1,
13417 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13418 ovl.fmt.RSY.dl2,
13419 ovl.fmt.RSY.dh2); goto ok;
13420 case 0xeb000000008eULL: /* MVCLU */ goto unimplemented;
13421 case 0xeb000000008fULL: /* CLCLU */ goto unimplemented;
13422 case 0xeb0000000090ULL: s390_format_RSY_RRRD(s390_irgen_STMY, ovl.fmt.RSY.r1,
13423 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13424 ovl.fmt.RSY.dl2,
13425 ovl.fmt.RSY.dh2); goto ok;
13426 case 0xeb0000000096ULL: s390_format_RSY_RRRD(s390_irgen_LMH, ovl.fmt.RSY.r1,
13427 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13428 ovl.fmt.RSY.dl2,
13429 ovl.fmt.RSY.dh2); goto ok;
13430 case 0xeb0000000098ULL: s390_format_RSY_RRRD(s390_irgen_LMY, ovl.fmt.RSY.r1,
13431 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13432 ovl.fmt.RSY.dl2,
13433 ovl.fmt.RSY.dh2); goto ok;
13434 case 0xeb000000009aULL: s390_format_RSY_AARD(s390_irgen_LAMY, ovl.fmt.RSY.r1,
13435 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13436 ovl.fmt.RSY.dl2,
13437 ovl.fmt.RSY.dh2); goto ok;
13438 case 0xeb000000009bULL: s390_format_RSY_AARD(s390_irgen_STAMY,
13439 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
13440 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
13441 ovl.fmt.RSY.dh2); goto ok;
13442 case 0xeb00000000c0ULL: /* TP */ goto unimplemented;
13443 case 0xeb00000000dcULL: s390_format_RSY_RRRD(s390_irgen_SRAK, ovl.fmt.RSY.r1,
13444 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13445 ovl.fmt.RSY.dl2,
13446 ovl.fmt.RSY.dh2); goto ok;
13447 case 0xeb00000000ddULL: s390_format_RSY_RRRD(s390_irgen_SLAK, ovl.fmt.RSY.r1,
13448 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13449 ovl.fmt.RSY.dl2,
13450 ovl.fmt.RSY.dh2); goto ok;
13451 case 0xeb00000000deULL: s390_format_RSY_RRRD(s390_irgen_SRLK, ovl.fmt.RSY.r1,
13452 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13453 ovl.fmt.RSY.dl2,
13454 ovl.fmt.RSY.dh2); goto ok;
13455 case 0xeb00000000dfULL: s390_format_RSY_RRRD(s390_irgen_SLLK, ovl.fmt.RSY.r1,
13456 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13457 ovl.fmt.RSY.dl2,
13458 ovl.fmt.RSY.dh2); goto ok;
sewardjd7bde722011-04-05 13:19:33 +000013459 case 0xeb00000000e2ULL: s390_format_RSY_RDRM(s390_irgen_LOCG, ovl.fmt.RSY.r1,
13460 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13461 ovl.fmt.RSY.dl2,
13462 ovl.fmt.RSY.dh2,
13463 S390_XMNM_LOCG); goto ok;
13464 case 0xeb00000000e3ULL: s390_format_RSY_RDRM(s390_irgen_STOCG,
13465 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
13466 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
13467 ovl.fmt.RSY.dh2,
13468 S390_XMNM_STOCG); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013469 case 0xeb00000000e4ULL: s390_format_RSY_RRRD(s390_irgen_LANG, ovl.fmt.RSY.r1,
13470 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13471 ovl.fmt.RSY.dl2,
13472 ovl.fmt.RSY.dh2); goto ok;
13473 case 0xeb00000000e6ULL: s390_format_RSY_RRRD(s390_irgen_LAOG, ovl.fmt.RSY.r1,
13474 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13475 ovl.fmt.RSY.dl2,
13476 ovl.fmt.RSY.dh2); goto ok;
13477 case 0xeb00000000e7ULL: s390_format_RSY_RRRD(s390_irgen_LAXG, ovl.fmt.RSY.r1,
13478 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13479 ovl.fmt.RSY.dl2,
13480 ovl.fmt.RSY.dh2); goto ok;
13481 case 0xeb00000000e8ULL: s390_format_RSY_RRRD(s390_irgen_LAAG, ovl.fmt.RSY.r1,
13482 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13483 ovl.fmt.RSY.dl2,
13484 ovl.fmt.RSY.dh2); goto ok;
13485 case 0xeb00000000eaULL: s390_format_RSY_RRRD(s390_irgen_LAALG,
13486 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
13487 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
13488 ovl.fmt.RSY.dh2); goto ok;
sewardjd7bde722011-04-05 13:19:33 +000013489 case 0xeb00000000f2ULL: s390_format_RSY_RDRM(s390_irgen_LOC, ovl.fmt.RSY.r1,
13490 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13491 ovl.fmt.RSY.dl2,
13492 ovl.fmt.RSY.dh2, S390_XMNM_LOC);
13493 goto ok;
13494 case 0xeb00000000f3ULL: s390_format_RSY_RDRM(s390_irgen_STOC, ovl.fmt.RSY.r1,
13495 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13496 ovl.fmt.RSY.dl2,
13497 ovl.fmt.RSY.dh2,
13498 S390_XMNM_STOC); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013499 case 0xeb00000000f4ULL: s390_format_RSY_RRRD(s390_irgen_LAN, ovl.fmt.RSY.r1,
13500 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13501 ovl.fmt.RSY.dl2,
13502 ovl.fmt.RSY.dh2); goto ok;
13503 case 0xeb00000000f6ULL: s390_format_RSY_RRRD(s390_irgen_LAO, ovl.fmt.RSY.r1,
13504 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13505 ovl.fmt.RSY.dl2,
13506 ovl.fmt.RSY.dh2); goto ok;
13507 case 0xeb00000000f7ULL: s390_format_RSY_RRRD(s390_irgen_LAX, ovl.fmt.RSY.r1,
13508 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13509 ovl.fmt.RSY.dl2,
13510 ovl.fmt.RSY.dh2); goto ok;
13511 case 0xeb00000000f8ULL: s390_format_RSY_RRRD(s390_irgen_LAA, ovl.fmt.RSY.r1,
13512 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13513 ovl.fmt.RSY.dl2,
13514 ovl.fmt.RSY.dh2); goto ok;
13515 case 0xeb00000000faULL: s390_format_RSY_RRRD(s390_irgen_LAAL, ovl.fmt.RSY.r1,
13516 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13517 ovl.fmt.RSY.dl2,
13518 ovl.fmt.RSY.dh2); goto ok;
13519 case 0xec0000000044ULL: s390_format_RIE_RRP(s390_irgen_BRXHG, ovl.fmt.RIE.r1,
13520 ovl.fmt.RIE.r3, ovl.fmt.RIE.i2);
13521 goto ok;
13522 case 0xec0000000045ULL: s390_format_RIE_RRP(s390_irgen_BRXLG, ovl.fmt.RIE.r1,
13523 ovl.fmt.RIE.r3, ovl.fmt.RIE.i2);
13524 goto ok;
13525 case 0xec0000000051ULL: /* RISBLG */ goto unimplemented;
13526 case 0xec0000000054ULL: s390_format_RIE_RRUUU(s390_irgen_RNSBG,
13527 ovl.fmt.RIE_RRUUU.r1,
13528 ovl.fmt.RIE_RRUUU.r2,
13529 ovl.fmt.RIE_RRUUU.i3,
13530 ovl.fmt.RIE_RRUUU.i4,
13531 ovl.fmt.RIE_RRUUU.i5);
13532 goto ok;
13533 case 0xec0000000055ULL: s390_format_RIE_RRUUU(s390_irgen_RISBG,
13534 ovl.fmt.RIE_RRUUU.r1,
13535 ovl.fmt.RIE_RRUUU.r2,
13536 ovl.fmt.RIE_RRUUU.i3,
13537 ovl.fmt.RIE_RRUUU.i4,
13538 ovl.fmt.RIE_RRUUU.i5);
13539 goto ok;
13540 case 0xec0000000056ULL: s390_format_RIE_RRUUU(s390_irgen_ROSBG,
13541 ovl.fmt.RIE_RRUUU.r1,
13542 ovl.fmt.RIE_RRUUU.r2,
13543 ovl.fmt.RIE_RRUUU.i3,
13544 ovl.fmt.RIE_RRUUU.i4,
13545 ovl.fmt.RIE_RRUUU.i5);
13546 goto ok;
13547 case 0xec0000000057ULL: s390_format_RIE_RRUUU(s390_irgen_RXSBG,
13548 ovl.fmt.RIE_RRUUU.r1,
13549 ovl.fmt.RIE_RRUUU.r2,
13550 ovl.fmt.RIE_RRUUU.i3,
13551 ovl.fmt.RIE_RRUUU.i4,
13552 ovl.fmt.RIE_RRUUU.i5);
13553 goto ok;
13554 case 0xec000000005dULL: /* RISBHG */ goto unimplemented;
13555 case 0xec0000000064ULL: s390_format_RIE_RRPU(s390_irgen_CGRJ,
13556 ovl.fmt.RIE_RRPU.r1,
13557 ovl.fmt.RIE_RRPU.r2,
13558 ovl.fmt.RIE_RRPU.i4,
13559 ovl.fmt.RIE_RRPU.m3); goto ok;
13560 case 0xec0000000065ULL: s390_format_RIE_RRPU(s390_irgen_CLGRJ,
13561 ovl.fmt.RIE_RRPU.r1,
13562 ovl.fmt.RIE_RRPU.r2,
13563 ovl.fmt.RIE_RRPU.i4,
13564 ovl.fmt.RIE_RRPU.m3); goto ok;
13565 case 0xec0000000070ULL: /* CGIT */ goto unimplemented;
13566 case 0xec0000000071ULL: /* CLGIT */ goto unimplemented;
13567 case 0xec0000000072ULL: /* CIT */ goto unimplemented;
13568 case 0xec0000000073ULL: /* CLFIT */ goto unimplemented;
13569 case 0xec0000000076ULL: s390_format_RIE_RRPU(s390_irgen_CRJ,
13570 ovl.fmt.RIE_RRPU.r1,
13571 ovl.fmt.RIE_RRPU.r2,
13572 ovl.fmt.RIE_RRPU.i4,
13573 ovl.fmt.RIE_RRPU.m3); goto ok;
13574 case 0xec0000000077ULL: s390_format_RIE_RRPU(s390_irgen_CLRJ,
13575 ovl.fmt.RIE_RRPU.r1,
13576 ovl.fmt.RIE_RRPU.r2,
13577 ovl.fmt.RIE_RRPU.i4,
13578 ovl.fmt.RIE_RRPU.m3); goto ok;
13579 case 0xec000000007cULL: s390_format_RIE_RUPI(s390_irgen_CGIJ,
13580 ovl.fmt.RIEv3.r1,
13581 ovl.fmt.RIEv3.m3,
13582 ovl.fmt.RIEv3.i4,
13583 ovl.fmt.RIEv3.i2); goto ok;
13584 case 0xec000000007dULL: s390_format_RIE_RUPU(s390_irgen_CLGIJ,
13585 ovl.fmt.RIEv3.r1,
13586 ovl.fmt.RIEv3.m3,
13587 ovl.fmt.RIEv3.i4,
13588 ovl.fmt.RIEv3.i2); goto ok;
13589 case 0xec000000007eULL: s390_format_RIE_RUPI(s390_irgen_CIJ,
13590 ovl.fmt.RIEv3.r1,
13591 ovl.fmt.RIEv3.m3,
13592 ovl.fmt.RIEv3.i4,
13593 ovl.fmt.RIEv3.i2); goto ok;
13594 case 0xec000000007fULL: s390_format_RIE_RUPU(s390_irgen_CLIJ,
13595 ovl.fmt.RIEv3.r1,
13596 ovl.fmt.RIEv3.m3,
13597 ovl.fmt.RIEv3.i4,
13598 ovl.fmt.RIEv3.i2); goto ok;
13599 case 0xec00000000d8ULL: s390_format_RIE_RRI0(s390_irgen_AHIK, ovl.fmt.RIE.r1,
13600 ovl.fmt.RIE.r3, ovl.fmt.RIE.i2);
13601 goto ok;
13602 case 0xec00000000d9ULL: s390_format_RIE_RRI0(s390_irgen_AGHIK,
13603 ovl.fmt.RIE.r1, ovl.fmt.RIE.r3,
13604 ovl.fmt.RIE.i2); goto ok;
13605 case 0xec00000000daULL: s390_format_RIE_RRI0(s390_irgen_ALHSIK,
13606 ovl.fmt.RIE.r1, ovl.fmt.RIE.r3,
13607 ovl.fmt.RIE.i2); goto ok;
13608 case 0xec00000000dbULL: s390_format_RIE_RRI0(s390_irgen_ALGHSIK,
13609 ovl.fmt.RIE.r1, ovl.fmt.RIE.r3,
13610 ovl.fmt.RIE.i2); goto ok;
13611 case 0xec00000000e4ULL: s390_format_RRS(s390_irgen_CGRB, ovl.fmt.RRS.r1,
13612 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
13613 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
13614 goto ok;
13615 case 0xec00000000e5ULL: s390_format_RRS(s390_irgen_CLGRB, ovl.fmt.RRS.r1,
13616 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
13617 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
13618 goto ok;
13619 case 0xec00000000f6ULL: s390_format_RRS(s390_irgen_CRB, ovl.fmt.RRS.r1,
13620 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
13621 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
13622 goto ok;
13623 case 0xec00000000f7ULL: s390_format_RRS(s390_irgen_CLRB, ovl.fmt.RRS.r1,
13624 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
13625 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
13626 goto ok;
13627 case 0xec00000000fcULL: s390_format_RIS_RURDI(s390_irgen_CGIB,
13628 ovl.fmt.RIS.r1, ovl.fmt.RIS.m3,
13629 ovl.fmt.RIS.b4, ovl.fmt.RIS.d4,
13630 ovl.fmt.RIS.i2); goto ok;
13631 case 0xec00000000fdULL: s390_format_RIS_RURDU(s390_irgen_CLGIB,
13632 ovl.fmt.RIS.r1, ovl.fmt.RIS.m3,
13633 ovl.fmt.RIS.b4, ovl.fmt.RIS.d4,
13634 ovl.fmt.RIS.i2); goto ok;
13635 case 0xec00000000feULL: s390_format_RIS_RURDI(s390_irgen_CIB, ovl.fmt.RIS.r1,
13636 ovl.fmt.RIS.m3, ovl.fmt.RIS.b4,
13637 ovl.fmt.RIS.d4,
13638 ovl.fmt.RIS.i2); goto ok;
13639 case 0xec00000000ffULL: s390_format_RIS_RURDU(s390_irgen_CLIB,
13640 ovl.fmt.RIS.r1, ovl.fmt.RIS.m3,
13641 ovl.fmt.RIS.b4, ovl.fmt.RIS.d4,
13642 ovl.fmt.RIS.i2); goto ok;
13643 case 0xed0000000004ULL: s390_format_RXE_FRRD(s390_irgen_LDEB, ovl.fmt.RXE.r1,
13644 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
13645 ovl.fmt.RXE.d2); goto ok;
13646 case 0xed0000000005ULL: s390_format_RXE_FRRD(s390_irgen_LXDB, ovl.fmt.RXE.r1,
13647 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
13648 ovl.fmt.RXE.d2); goto ok;
13649 case 0xed0000000006ULL: s390_format_RXE_FRRD(s390_irgen_LXEB, ovl.fmt.RXE.r1,
13650 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
13651 ovl.fmt.RXE.d2); goto ok;
13652 case 0xed0000000007ULL: /* MXDB */ goto unimplemented;
13653 case 0xed0000000008ULL: /* KEB */ goto unimplemented;
13654 case 0xed0000000009ULL: s390_format_RXE_FRRD(s390_irgen_CEB, ovl.fmt.RXE.r1,
13655 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
13656 ovl.fmt.RXE.d2); goto ok;
13657 case 0xed000000000aULL: s390_format_RXE_FRRD(s390_irgen_AEB, ovl.fmt.RXE.r1,
13658 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
13659 ovl.fmt.RXE.d2); goto ok;
13660 case 0xed000000000bULL: s390_format_RXE_FRRD(s390_irgen_SEB, ovl.fmt.RXE.r1,
13661 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
13662 ovl.fmt.RXE.d2); goto ok;
13663 case 0xed000000000cULL: /* MDEB */ goto unimplemented;
13664 case 0xed000000000dULL: s390_format_RXE_FRRD(s390_irgen_DEB, ovl.fmt.RXE.r1,
13665 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
13666 ovl.fmt.RXE.d2); goto ok;
13667 case 0xed000000000eULL: s390_format_RXF_FRRDF(s390_irgen_MAEB,
13668 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
13669 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
13670 ovl.fmt.RXF.r1); goto ok;
13671 case 0xed000000000fULL: s390_format_RXF_FRRDF(s390_irgen_MSEB,
13672 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
13673 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
13674 ovl.fmt.RXF.r1); goto ok;
13675 case 0xed0000000010ULL: s390_format_RXE_FRRD(s390_irgen_TCEB, ovl.fmt.RXE.r1,
13676 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
13677 ovl.fmt.RXE.d2); goto ok;
13678 case 0xed0000000011ULL: s390_format_RXE_FRRD(s390_irgen_TCDB, ovl.fmt.RXE.r1,
13679 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
13680 ovl.fmt.RXE.d2); goto ok;
13681 case 0xed0000000012ULL: s390_format_RXE_FRRD(s390_irgen_TCXB, ovl.fmt.RXE.r1,
13682 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
13683 ovl.fmt.RXE.d2); goto ok;
13684 case 0xed0000000014ULL: s390_format_RXE_FRRD(s390_irgen_SQEB, ovl.fmt.RXE.r1,
13685 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
13686 ovl.fmt.RXE.d2); goto ok;
13687 case 0xed0000000015ULL: s390_format_RXE_FRRD(s390_irgen_SQDB, ovl.fmt.RXE.r1,
13688 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
13689 ovl.fmt.RXE.d2); goto ok;
13690 case 0xed0000000017ULL: s390_format_RXE_FRRD(s390_irgen_MEEB, ovl.fmt.RXE.r1,
13691 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
13692 ovl.fmt.RXE.d2); goto ok;
13693 case 0xed0000000018ULL: /* KDB */ goto unimplemented;
13694 case 0xed0000000019ULL: s390_format_RXE_FRRD(s390_irgen_CDB, ovl.fmt.RXE.r1,
13695 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
13696 ovl.fmt.RXE.d2); goto ok;
13697 case 0xed000000001aULL: s390_format_RXE_FRRD(s390_irgen_ADB, ovl.fmt.RXE.r1,
13698 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
13699 ovl.fmt.RXE.d2); goto ok;
13700 case 0xed000000001bULL: s390_format_RXE_FRRD(s390_irgen_SDB, ovl.fmt.RXE.r1,
13701 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
13702 ovl.fmt.RXE.d2); goto ok;
13703 case 0xed000000001cULL: s390_format_RXE_FRRD(s390_irgen_MDB, ovl.fmt.RXE.r1,
13704 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
13705 ovl.fmt.RXE.d2); goto ok;
13706 case 0xed000000001dULL: s390_format_RXE_FRRD(s390_irgen_DDB, ovl.fmt.RXE.r1,
13707 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
13708 ovl.fmt.RXE.d2); goto ok;
13709 case 0xed000000001eULL: s390_format_RXF_FRRDF(s390_irgen_MADB,
13710 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
13711 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
13712 ovl.fmt.RXF.r1); goto ok;
13713 case 0xed000000001fULL: s390_format_RXF_FRRDF(s390_irgen_MSDB,
13714 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
13715 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
13716 ovl.fmt.RXF.r1); goto ok;
13717 case 0xed0000000024ULL: /* LDE */ goto unimplemented;
13718 case 0xed0000000025ULL: /* LXD */ goto unimplemented;
13719 case 0xed0000000026ULL: /* LXE */ goto unimplemented;
13720 case 0xed000000002eULL: /* MAE */ goto unimplemented;
13721 case 0xed000000002fULL: /* MSE */ goto unimplemented;
13722 case 0xed0000000034ULL: /* SQE */ goto unimplemented;
13723 case 0xed0000000035ULL: /* SQD */ goto unimplemented;
13724 case 0xed0000000037ULL: /* MEE */ goto unimplemented;
13725 case 0xed0000000038ULL: /* MAYL */ goto unimplemented;
13726 case 0xed0000000039ULL: /* MYL */ goto unimplemented;
13727 case 0xed000000003aULL: /* MAY */ goto unimplemented;
13728 case 0xed000000003bULL: /* MY */ goto unimplemented;
13729 case 0xed000000003cULL: /* MAYH */ goto unimplemented;
13730 case 0xed000000003dULL: /* MYH */ goto unimplemented;
13731 case 0xed000000003eULL: /* MAD */ goto unimplemented;
13732 case 0xed000000003fULL: /* MSD */ goto unimplemented;
13733 case 0xed0000000040ULL: /* SLDT */ goto unimplemented;
13734 case 0xed0000000041ULL: /* SRDT */ goto unimplemented;
13735 case 0xed0000000048ULL: /* SLXT */ goto unimplemented;
13736 case 0xed0000000049ULL: /* SRXT */ goto unimplemented;
13737 case 0xed0000000050ULL: /* TDCET */ goto unimplemented;
13738 case 0xed0000000051ULL: /* TDGET */ goto unimplemented;
13739 case 0xed0000000054ULL: /* TDCDT */ goto unimplemented;
13740 case 0xed0000000055ULL: /* TDGDT */ goto unimplemented;
13741 case 0xed0000000058ULL: /* TDCXT */ goto unimplemented;
13742 case 0xed0000000059ULL: /* TDGXT */ goto unimplemented;
13743 case 0xed0000000064ULL: s390_format_RXY_FRRD(s390_irgen_LEY, ovl.fmt.RXY.r1,
13744 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13745 ovl.fmt.RXY.dl2,
13746 ovl.fmt.RXY.dh2); goto ok;
13747 case 0xed0000000065ULL: s390_format_RXY_FRRD(s390_irgen_LDY, ovl.fmt.RXY.r1,
13748 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13749 ovl.fmt.RXY.dl2,
13750 ovl.fmt.RXY.dh2); goto ok;
13751 case 0xed0000000066ULL: s390_format_RXY_FRRD(s390_irgen_STEY, ovl.fmt.RXY.r1,
13752 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13753 ovl.fmt.RXY.dl2,
13754 ovl.fmt.RXY.dh2); goto ok;
13755 case 0xed0000000067ULL: s390_format_RXY_FRRD(s390_irgen_STDY, ovl.fmt.RXY.r1,
13756 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13757 ovl.fmt.RXY.dl2,
13758 ovl.fmt.RXY.dh2); goto ok;
13759 }
13760
13761 switch (((ovl.value >> 16) & 0xff0f00000000ULL) >> 32) {
13762 case 0xc000ULL: s390_format_RIL_RP(s390_irgen_LARL, ovl.fmt.RIL.r1,
13763 ovl.fmt.RIL.i2); goto ok;
13764 case 0xc001ULL: s390_format_RIL_RI(s390_irgen_LGFI, ovl.fmt.RIL.r1,
13765 ovl.fmt.RIL.i2); goto ok;
13766 case 0xc004ULL: s390_format_RIL(s390_irgen_BRCL, ovl.fmt.RIL.r1,
13767 ovl.fmt.RIL.i2); goto ok;
13768 case 0xc005ULL: s390_format_RIL_RP(s390_irgen_BRASL, ovl.fmt.RIL.r1,
13769 ovl.fmt.RIL.i2); goto ok;
13770 case 0xc006ULL: s390_format_RIL_RU(s390_irgen_XIHF, ovl.fmt.RIL.r1,
13771 ovl.fmt.RIL.i2); goto ok;
13772 case 0xc007ULL: s390_format_RIL_RU(s390_irgen_XILF, ovl.fmt.RIL.r1,
13773 ovl.fmt.RIL.i2); goto ok;
13774 case 0xc008ULL: s390_format_RIL_RU(s390_irgen_IIHF, ovl.fmt.RIL.r1,
13775 ovl.fmt.RIL.i2); goto ok;
13776 case 0xc009ULL: s390_format_RIL_RU(s390_irgen_IILF, ovl.fmt.RIL.r1,
13777 ovl.fmt.RIL.i2); goto ok;
13778 case 0xc00aULL: s390_format_RIL_RU(s390_irgen_NIHF, ovl.fmt.RIL.r1,
13779 ovl.fmt.RIL.i2); goto ok;
13780 case 0xc00bULL: s390_format_RIL_RU(s390_irgen_NILF, ovl.fmt.RIL.r1,
13781 ovl.fmt.RIL.i2); goto ok;
13782 case 0xc00cULL: s390_format_RIL_RU(s390_irgen_OIHF, ovl.fmt.RIL.r1,
13783 ovl.fmt.RIL.i2); goto ok;
13784 case 0xc00dULL: s390_format_RIL_RU(s390_irgen_OILF, ovl.fmt.RIL.r1,
13785 ovl.fmt.RIL.i2); goto ok;
13786 case 0xc00eULL: s390_format_RIL_RU(s390_irgen_LLIHF, ovl.fmt.RIL.r1,
13787 ovl.fmt.RIL.i2); goto ok;
13788 case 0xc00fULL: s390_format_RIL_RU(s390_irgen_LLILF, ovl.fmt.RIL.r1,
13789 ovl.fmt.RIL.i2); goto ok;
13790 case 0xc200ULL: s390_format_RIL_RI(s390_irgen_MSGFI, ovl.fmt.RIL.r1,
13791 ovl.fmt.RIL.i2); goto ok;
13792 case 0xc201ULL: s390_format_RIL_RI(s390_irgen_MSFI, ovl.fmt.RIL.r1,
13793 ovl.fmt.RIL.i2); goto ok;
13794 case 0xc204ULL: s390_format_RIL_RU(s390_irgen_SLGFI, ovl.fmt.RIL.r1,
13795 ovl.fmt.RIL.i2); goto ok;
13796 case 0xc205ULL: s390_format_RIL_RU(s390_irgen_SLFI, ovl.fmt.RIL.r1,
13797 ovl.fmt.RIL.i2); goto ok;
13798 case 0xc208ULL: s390_format_RIL_RI(s390_irgen_AGFI, ovl.fmt.RIL.r1,
13799 ovl.fmt.RIL.i2); goto ok;
13800 case 0xc209ULL: s390_format_RIL_RI(s390_irgen_AFI, ovl.fmt.RIL.r1,
13801 ovl.fmt.RIL.i2); goto ok;
13802 case 0xc20aULL: s390_format_RIL_RU(s390_irgen_ALGFI, ovl.fmt.RIL.r1,
13803 ovl.fmt.RIL.i2); goto ok;
13804 case 0xc20bULL: s390_format_RIL_RU(s390_irgen_ALFI, ovl.fmt.RIL.r1,
13805 ovl.fmt.RIL.i2); goto ok;
13806 case 0xc20cULL: s390_format_RIL_RI(s390_irgen_CGFI, ovl.fmt.RIL.r1,
13807 ovl.fmt.RIL.i2); goto ok;
13808 case 0xc20dULL: s390_format_RIL_RI(s390_irgen_CFI, ovl.fmt.RIL.r1,
13809 ovl.fmt.RIL.i2); goto ok;
13810 case 0xc20eULL: s390_format_RIL_RU(s390_irgen_CLGFI, ovl.fmt.RIL.r1,
13811 ovl.fmt.RIL.i2); goto ok;
13812 case 0xc20fULL: s390_format_RIL_RU(s390_irgen_CLFI, ovl.fmt.RIL.r1,
13813 ovl.fmt.RIL.i2); goto ok;
13814 case 0xc402ULL: s390_format_RIL_RP(s390_irgen_LLHRL, ovl.fmt.RIL.r1,
13815 ovl.fmt.RIL.i2); goto ok;
13816 case 0xc404ULL: s390_format_RIL_RP(s390_irgen_LGHRL, ovl.fmt.RIL.r1,
13817 ovl.fmt.RIL.i2); goto ok;
13818 case 0xc405ULL: s390_format_RIL_RP(s390_irgen_LHRL, ovl.fmt.RIL.r1,
13819 ovl.fmt.RIL.i2); goto ok;
13820 case 0xc406ULL: s390_format_RIL_RP(s390_irgen_LLGHRL, ovl.fmt.RIL.r1,
13821 ovl.fmt.RIL.i2); goto ok;
13822 case 0xc407ULL: s390_format_RIL_RP(s390_irgen_STHRL, ovl.fmt.RIL.r1,
13823 ovl.fmt.RIL.i2); goto ok;
13824 case 0xc408ULL: s390_format_RIL_RP(s390_irgen_LGRL, ovl.fmt.RIL.r1,
13825 ovl.fmt.RIL.i2); goto ok;
13826 case 0xc40bULL: s390_format_RIL_RP(s390_irgen_STGRL, ovl.fmt.RIL.r1,
13827 ovl.fmt.RIL.i2); goto ok;
13828 case 0xc40cULL: s390_format_RIL_RP(s390_irgen_LGFRL, ovl.fmt.RIL.r1,
13829 ovl.fmt.RIL.i2); goto ok;
13830 case 0xc40dULL: s390_format_RIL_RP(s390_irgen_LRL, ovl.fmt.RIL.r1,
13831 ovl.fmt.RIL.i2); goto ok;
13832 case 0xc40eULL: s390_format_RIL_RP(s390_irgen_LLGFRL, ovl.fmt.RIL.r1,
13833 ovl.fmt.RIL.i2); goto ok;
13834 case 0xc40fULL: s390_format_RIL_RP(s390_irgen_STRL, ovl.fmt.RIL.r1,
13835 ovl.fmt.RIL.i2); goto ok;
13836 case 0xc600ULL: s390_format_RIL_RP(s390_irgen_EXRL, ovl.fmt.RIL.r1,
13837 ovl.fmt.RIL.i2); goto ok;
13838 case 0xc602ULL: s390_format_RIL_UP(s390_irgen_PFDRL, ovl.fmt.RIL.r1,
13839 ovl.fmt.RIL.i2); goto ok;
13840 case 0xc604ULL: s390_format_RIL_RP(s390_irgen_CGHRL, ovl.fmt.RIL.r1,
13841 ovl.fmt.RIL.i2); goto ok;
13842 case 0xc605ULL: s390_format_RIL_RP(s390_irgen_CHRL, ovl.fmt.RIL.r1,
13843 ovl.fmt.RIL.i2); goto ok;
13844 case 0xc606ULL: s390_format_RIL_RP(s390_irgen_CLGHRL, ovl.fmt.RIL.r1,
13845 ovl.fmt.RIL.i2); goto ok;
13846 case 0xc607ULL: s390_format_RIL_RP(s390_irgen_CLHRL, ovl.fmt.RIL.r1,
13847 ovl.fmt.RIL.i2); goto ok;
13848 case 0xc608ULL: s390_format_RIL_RP(s390_irgen_CGRL, ovl.fmt.RIL.r1,
13849 ovl.fmt.RIL.i2); goto ok;
13850 case 0xc60aULL: s390_format_RIL_RP(s390_irgen_CLGRL, ovl.fmt.RIL.r1,
13851 ovl.fmt.RIL.i2); goto ok;
13852 case 0xc60cULL: s390_format_RIL_RP(s390_irgen_CGFRL, ovl.fmt.RIL.r1,
13853 ovl.fmt.RIL.i2); goto ok;
13854 case 0xc60dULL: s390_format_RIL_RP(s390_irgen_CRL, ovl.fmt.RIL.r1,
13855 ovl.fmt.RIL.i2); goto ok;
13856 case 0xc60eULL: s390_format_RIL_RP(s390_irgen_CLGFRL, ovl.fmt.RIL.r1,
13857 ovl.fmt.RIL.i2); goto ok;
13858 case 0xc60fULL: s390_format_RIL_RP(s390_irgen_CLRL, ovl.fmt.RIL.r1,
13859 ovl.fmt.RIL.i2); goto ok;
13860 case 0xc800ULL: /* MVCOS */ goto unimplemented;
13861 case 0xc801ULL: /* ECTG */ goto unimplemented;
13862 case 0xc802ULL: /* CSST */ goto unimplemented;
13863 case 0xc804ULL: /* LPD */ goto unimplemented;
13864 case 0xc805ULL: /* LPDG */ goto unimplemented;
13865 case 0xcc06ULL: /* BRCTH */ goto unimplemented;
13866 case 0xcc08ULL: s390_format_RIL_RI(s390_irgen_AIH, ovl.fmt.RIL.r1,
13867 ovl.fmt.RIL.i2); goto ok;
13868 case 0xcc0aULL: s390_format_RIL_RI(s390_irgen_ALSIH, ovl.fmt.RIL.r1,
13869 ovl.fmt.RIL.i2); goto ok;
13870 case 0xcc0bULL: s390_format_RIL_RI(s390_irgen_ALSIHN, ovl.fmt.RIL.r1,
13871 ovl.fmt.RIL.i2); goto ok;
13872 case 0xcc0dULL: s390_format_RIL_RI(s390_irgen_CIH, ovl.fmt.RIL.r1,
13873 ovl.fmt.RIL.i2); goto ok;
13874 case 0xcc0fULL: s390_format_RIL_RU(s390_irgen_CLIH, ovl.fmt.RIL.r1,
13875 ovl.fmt.RIL.i2); goto ok;
13876 }
13877
13878 switch (((ovl.value >> 16) & 0xff0000000000ULL) >> 40) {
13879 case 0xd0ULL: /* TRTR */ goto unimplemented;
13880 case 0xd1ULL: /* MVN */ goto unimplemented;
13881 case 0xd2ULL: s390_format_SS_L0RDRD(s390_irgen_MVC, ovl.fmt.SS.l,
13882 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
13883 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
13884 case 0xd3ULL: /* MVZ */ goto unimplemented;
13885 case 0xd4ULL: s390_format_SS_L0RDRD(s390_irgen_NC, ovl.fmt.SS.l,
13886 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
13887 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
13888 case 0xd5ULL: s390_format_SS_L0RDRD(s390_irgen_CLC, ovl.fmt.SS.l,
13889 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
13890 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
13891 case 0xd6ULL: s390_format_SS_L0RDRD(s390_irgen_OC, ovl.fmt.SS.l,
13892 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
13893 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
sewardjb63967e2011-03-24 08:50:04 +000013894 case 0xd7ULL:
13895 if (ovl.fmt.SS.b1 == ovl.fmt.SS.b2 && ovl.fmt.SS.d1 == ovl.fmt.SS.d2)
13896 s390_irgen_XC_sameloc(ovl.fmt.SS.l, ovl.fmt.SS.b1, ovl.fmt.SS.d1);
13897 else
13898 s390_format_SS_L0RDRD(s390_irgen_XC, ovl.fmt.SS.l,
13899 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
13900 ovl.fmt.SS.b2, ovl.fmt.SS.d2);
13901 goto ok;
sewardj2019a972011-03-07 16:04:07 +000013902 case 0xd9ULL: /* MVCK */ goto unimplemented;
13903 case 0xdaULL: /* MVCP */ goto unimplemented;
13904 case 0xdbULL: /* MVCS */ goto unimplemented;
florian730448f2012-02-04 17:07:07 +000013905 case 0xdcULL: s390_format_SS_L0RDRD(s390_irgen_TR, ovl.fmt.SS.l,
13906 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
13907 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013908 case 0xddULL: /* TRT */ goto unimplemented;
13909 case 0xdeULL: /* ED */ goto unimplemented;
13910 case 0xdfULL: /* EDMK */ goto unimplemented;
13911 case 0xe1ULL: /* PKU */ goto unimplemented;
13912 case 0xe2ULL: /* UNPKU */ goto unimplemented;
13913 case 0xe8ULL: /* MVCIN */ goto unimplemented;
13914 case 0xe9ULL: /* PKA */ goto unimplemented;
13915 case 0xeaULL: /* UNPKA */ goto unimplemented;
13916 case 0xeeULL: /* PLO */ goto unimplemented;
13917 case 0xefULL: /* LMD */ goto unimplemented;
13918 case 0xf0ULL: /* SRP */ goto unimplemented;
13919 case 0xf1ULL: /* MVO */ goto unimplemented;
13920 case 0xf2ULL: /* PACK */ goto unimplemented;
13921 case 0xf3ULL: /* UNPK */ goto unimplemented;
13922 case 0xf8ULL: /* ZAP */ goto unimplemented;
13923 case 0xf9ULL: /* CP */ goto unimplemented;
13924 case 0xfaULL: /* AP */ goto unimplemented;
13925 case 0xfbULL: /* SP */ goto unimplemented;
13926 case 0xfcULL: /* MP */ goto unimplemented;
13927 case 0xfdULL: /* DP */ goto unimplemented;
13928 }
13929
13930 switch (((ovl.value >> 16) & 0xffff00000000ULL) >> 32) {
13931 case 0xe500ULL: /* LASP */ goto unimplemented;
13932 case 0xe501ULL: /* TPROT */ goto unimplemented;
13933 case 0xe502ULL: /* STRAG */ goto unimplemented;
13934 case 0xe50eULL: /* MVCSK */ goto unimplemented;
13935 case 0xe50fULL: /* MVCDK */ goto unimplemented;
13936 case 0xe544ULL: s390_format_SIL_RDI(s390_irgen_MVHHI, ovl.fmt.SIL.b1,
13937 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
13938 goto ok;
13939 case 0xe548ULL: s390_format_SIL_RDI(s390_irgen_MVGHI, ovl.fmt.SIL.b1,
13940 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
13941 goto ok;
13942 case 0xe54cULL: s390_format_SIL_RDI(s390_irgen_MVHI, ovl.fmt.SIL.b1,
13943 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
13944 goto ok;
13945 case 0xe554ULL: s390_format_SIL_RDI(s390_irgen_CHHSI, ovl.fmt.SIL.b1,
13946 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
13947 goto ok;
13948 case 0xe555ULL: s390_format_SIL_RDU(s390_irgen_CLHHSI, ovl.fmt.SIL.b1,
13949 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
13950 goto ok;
13951 case 0xe558ULL: s390_format_SIL_RDI(s390_irgen_CGHSI, ovl.fmt.SIL.b1,
13952 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
13953 goto ok;
13954 case 0xe559ULL: s390_format_SIL_RDU(s390_irgen_CLGHSI, ovl.fmt.SIL.b1,
13955 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
13956 goto ok;
13957 case 0xe55cULL: s390_format_SIL_RDI(s390_irgen_CHSI, ovl.fmt.SIL.b1,
13958 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
13959 goto ok;
13960 case 0xe55dULL: s390_format_SIL_RDU(s390_irgen_CLFHSI, ovl.fmt.SIL.b1,
13961 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
13962 goto ok;
13963 }
13964
13965 return S390_DECODE_UNKNOWN_INSN;
13966
13967ok:
13968 return S390_DECODE_OK;
13969
13970unimplemented:
13971 return S390_DECODE_UNIMPLEMENTED_INSN;
13972}
13973
13974/* Handle "special" instructions. */
13975static s390_decode_t
13976s390_decode_special_and_irgen(UChar *bytes)
13977{
13978 s390_decode_t status = S390_DECODE_OK;
13979
13980 /* Got a "Special" instruction preamble. Which one is it? */
13981 if (bytes[0] == 0x18 && bytes[1] == 0x22 /* lr %r2, %r2 */) {
13982 s390_irgen_client_request();
13983 } else if (bytes[0] == 0x18 && bytes[1] == 0x33 /* lr %r3, %r3 */) {
13984 s390_irgen_guest_NRADDR();
13985 } else if (bytes[0] == 0x18 && bytes[1] == 0x44 /* lr %r4, %r4 */) {
13986 s390_irgen_call_noredir();
13987 } else {
13988 /* We don't know what it is. */
13989 return S390_DECODE_UNKNOWN_SPECIAL_INSN;
13990 }
13991
13992 dis_res->len = S390_SPECIAL_OP_PREAMBLE_SIZE + S390_SPECIAL_OP_SIZE;
13993
13994 return status;
13995}
13996
13997
13998/* Function returns # bytes that were decoded or 0 in case of failure */
florianb4df7682011-07-05 02:09:01 +000013999static UInt
sewardj2019a972011-03-07 16:04:07 +000014000s390_decode_and_irgen(UChar *bytes, UInt insn_length, DisResult *dres)
14001{
14002 s390_decode_t status;
14003
14004 dis_res = dres;
14005
14006 /* Spot the 8-byte preamble: 18ff lr r15,r15
14007 1811 lr r1,r1
14008 1822 lr r2,r2
14009 1833 lr r3,r3 */
14010 if (bytes[ 0] == 0x18 && bytes[ 1] == 0xff && bytes[ 2] == 0x18 &&
14011 bytes[ 3] == 0x11 && bytes[ 4] == 0x18 && bytes[ 5] == 0x22 &&
14012 bytes[ 6] == 0x18 && bytes[ 7] == 0x33) {
14013
14014 /* Handle special instruction that follows that preamble. */
14015 if (0) vex_printf("special function handling...\n");
florian2c8ed942011-08-01 22:07:51 +000014016
14017 insn_length = S390_SPECIAL_OP_PREAMBLE_SIZE + S390_SPECIAL_OP_SIZE;
14018 guest_IA_next_instr = guest_IA_curr_instr + insn_length;
14019
14020 status =
14021 s390_decode_special_and_irgen(bytes + S390_SPECIAL_OP_PREAMBLE_SIZE);
sewardj2019a972011-03-07 16:04:07 +000014022 } else {
14023 /* Handle normal instructions. */
14024 switch (insn_length) {
14025 case 2:
14026 status = s390_decode_2byte_and_irgen(bytes);
14027 break;
14028
14029 case 4:
14030 status = s390_decode_4byte_and_irgen(bytes);
14031 break;
14032
14033 case 6:
14034 status = s390_decode_6byte_and_irgen(bytes);
14035 break;
14036
14037 default:
14038 status = S390_DECODE_ERROR;
14039 break;
14040 }
14041 }
florian5fcbba22011-07-27 20:40:22 +000014042 /* If next instruction is execute, stop here */
florianf9e1ed72012-04-17 02:41:56 +000014043 if (dis_res->whatNext == Dis_Continue && bytes[insn_length] == 0x44) {
14044 put_IA(mkaddr_expr(guest_IA_next_instr));
sewardj2019a972011-03-07 16:04:07 +000014045 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +000014046 dis_res->jk_StopHere = Ijk_Boring;
sewardj2019a972011-03-07 16:04:07 +000014047 }
14048
14049 if (status == S390_DECODE_OK) return insn_length; /* OK */
14050
14051 /* Decoding failed somehow */
14052 vex_printf("vex s390->IR: ");
14053 switch (status) {
14054 case S390_DECODE_UNKNOWN_INSN:
14055 vex_printf("unknown insn: ");
14056 break;
14057
14058 case S390_DECODE_UNIMPLEMENTED_INSN:
14059 vex_printf("unimplemented insn: ");
14060 break;
14061
14062 case S390_DECODE_UNKNOWN_SPECIAL_INSN:
14063 vex_printf("unimplemented special insn: ");
14064 break;
14065
14066 default:
14067 case S390_DECODE_ERROR:
14068 vex_printf("decoding error: ");
14069 break;
14070 }
14071
14072 vex_printf("%02x%02x", bytes[0], bytes[1]);
14073 if (insn_length > 2) {
14074 vex_printf(" %02x%02x", bytes[2], bytes[3]);
14075 }
14076 if (insn_length > 4) {
14077 vex_printf(" %02x%02x", bytes[4], bytes[5]);
14078 }
14079 vex_printf("\n");
14080
14081 return 0; /* Failed */
14082}
14083
14084
sewardj2019a972011-03-07 16:04:07 +000014085/* Disassemble a single instruction INSN into IR. */
14086static DisResult
florian420c5012011-07-22 02:12:28 +000014087disInstr_S390_WRK(UChar *insn)
sewardj2019a972011-03-07 16:04:07 +000014088{
14089 UChar byte;
14090 UInt insn_length;
14091 DisResult dres;
14092
14093 /* ---------------------------------------------------- */
14094 /* --- Compute instruction length -- */
14095 /* ---------------------------------------------------- */
14096
14097 /* Get the first byte of the insn. */
14098 byte = insn[0];
14099
14100 /* The leftmost two bits (0:1) encode the length of the insn in bytes.
14101 00 -> 2 bytes, 01 -> 4 bytes, 10 -> 4 bytes, 11 -> 6 bytes. */
14102 insn_length = ((((byte >> 6) + 1) >> 1) + 1) << 1;
14103
14104 guest_IA_next_instr = guest_IA_curr_instr + insn_length;
14105
14106 /* ---------------------------------------------------- */
14107 /* --- Initialise the DisResult data -- */
14108 /* ---------------------------------------------------- */
14109 dres.whatNext = Dis_Continue;
14110 dres.len = insn_length;
14111 dres.continueAt = 0;
florian8844a632012-04-13 04:04:06 +000014112 dres.jk_StopHere = Ijk_INVALID;
sewardj2019a972011-03-07 16:04:07 +000014113
floriana99f20e2011-07-17 14:16:41 +000014114 /* fixs390: consider chasing of conditional jumps */
14115
sewardj2019a972011-03-07 16:04:07 +000014116 /* Normal and special instruction handling starts here. */
14117 if (s390_decode_and_irgen(insn, insn_length, &dres) == 0) {
14118 /* All decode failures end up here. The decoder has already issued an
14119 error message.
14120 Tell the dispatcher that this insn cannot be decoded, and so has
florian342e01a2012-07-26 02:37:49 +000014121 not been executed, and (is currently) the next to be executed.
14122 The insn address in the guest state needs to be set to
14123 guest_IA_curr_instr, otherwise the complaint will report an
14124 incorrect address. */
14125 put_IA(mkaddr_expr(guest_IA_curr_instr));
sewardj2019a972011-03-07 16:04:07 +000014126
florian8844a632012-04-13 04:04:06 +000014127 dres.whatNext = Dis_StopHere;
14128 dres.jk_StopHere = Ijk_NoDecode;
14129 dres.continueAt = 0;
14130 dres.len = 0;
14131 } else {
14132 /* Decode success */
14133 switch (dres.whatNext) {
14134 case Dis_Continue:
florian8559e412012-04-19 14:23:48 +000014135 put_IA(mkaddr_expr(guest_IA_next_instr));
florian8844a632012-04-13 04:04:06 +000014136 break;
14137 case Dis_ResteerU:
14138 case Dis_ResteerC:
14139 put_IA(mkaddr_expr(dres.continueAt));
14140 break;
14141 case Dis_StopHere:
14142 break;
14143 default:
14144 vassert(0);
14145 }
sewardj2019a972011-03-07 16:04:07 +000014146 }
14147
14148 return dres;
14149}
14150
14151
14152/*------------------------------------------------------------*/
14153/*--- Top-level fn ---*/
14154/*------------------------------------------------------------*/
14155
14156/* Disassemble a single instruction into IR. The instruction
14157 is located in host memory at &guest_code[delta]. */
14158
14159DisResult
14160disInstr_S390(IRSB *irsb_IN,
sewardj2019a972011-03-07 16:04:07 +000014161 Bool (*resteerOkFn)(void *, Addr64),
14162 Bool resteerCisOk,
14163 void *callback_opaque,
14164 UChar *guest_code,
14165 Long delta,
14166 Addr64 guest_IP,
14167 VexArch guest_arch,
14168 VexArchInfo *archinfo,
14169 VexAbiInfo *abiinfo,
14170 Bool host_bigendian)
14171{
14172 vassert(guest_arch == VexArchS390X);
14173
14174 /* The instruction decoder requires a big-endian machine. */
14175 vassert(host_bigendian == True);
14176
14177 /* Set globals (see top of this file) */
14178 guest_IA_curr_instr = guest_IP;
sewardj2019a972011-03-07 16:04:07 +000014179 irsb = irsb_IN;
florian420c5012011-07-22 02:12:28 +000014180 resteer_fn = resteerOkFn;
14181 resteer_data = callback_opaque;
sewardj2019a972011-03-07 16:04:07 +000014182
florian420c5012011-07-22 02:12:28 +000014183 return disInstr_S390_WRK(guest_code + delta);
sewardj2019a972011-03-07 16:04:07 +000014184}
14185
14186/*---------------------------------------------------------------*/
14187/*--- end guest_s390_toIR.c ---*/
14188/*---------------------------------------------------------------*/