blob: 188992f748f2de09ef92e89b078e07b2aa3f3abb [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 *
florianaf2194f2012-08-06 00:07:54 +000011475s390_call_cu41(IRExpr *srcval)
11476{
11477 IRExpr **args, *call;
11478 args = mkIRExprVec_1(srcval);
11479 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
11480 "s390_do_cu41", &s390_do_cu41, args);
11481
11482 /* Nothing is excluded from definedness checking. */
11483 call->Iex.CCall.cee->mcx_mask = 0;
11484
11485 return call;
11486}
11487
11488static HChar *
11489s390_irgen_CU41(UChar r1, UChar r2)
11490{
11491 IRTemp addr1 = newTemp(Ity_I64);
11492 IRTemp addr2 = newTemp(Ity_I64);
11493 IRTemp len1 = newTemp(Ity_I64);
11494 IRTemp len2 = newTemp(Ity_I64);
11495
11496 assign(addr1, get_gpr_dw0(r1));
11497 assign(addr2, get_gpr_dw0(r2));
11498 assign(len1, get_gpr_dw0(r1 + 1));
11499 assign(len2, get_gpr_dw0(r2 + 1));
11500
11501 /* We're processing the 2nd operand 4 bytes at a time. Therefore, if
11502 there are less than 4 bytes left, then the 2nd operand is exhausted
11503 and we're done here. cc = 0 */
11504 s390_cc_set(0);
11505 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)));
11506
11507 /* Read the 2nd operand. */
11508 IRTemp srcval = newTemp(Ity_I32);
11509 assign(srcval, load(Ity_I32, mkexpr(addr2)));
11510
11511 /* Call the helper */
11512 IRTemp retval = newTemp(Ity_I64);
11513 assign(retval, s390_call_cu41(mkexpr(srcval)));
11514
11515 /* If the UTF-32 character was invalid, set cc=2 and we're done.
11516 cc=2 outranks cc=1 (1st operand exhausted) */
11517 IRExpr *invalid_character = binop(Iop_And64, mkexpr(retval), mkU64(0xff));
11518
11519 s390_cc_set(2);
11520 next_insn_if(binop(Iop_CmpEQ64, invalid_character, mkU64(1)));
11521
11522 /* Now test whether the 1st operand is exhausted */
11523 IRTemp num_bytes = newTemp(Ity_I64);
11524 assign(num_bytes, binop(Iop_And64,
11525 binop(Iop_Shr64, mkexpr(retval), mkU8(8)),
11526 mkU64(0xff)));
11527 s390_cc_set(1);
11528 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
11529
11530 /* Extract the bytes to be stored at addr1 */
11531 IRTemp data = newTemp(Ity_I64);
11532 assign(data, binop(Iop_Shr64, mkexpr(retval), mkU8(16)));
11533
11534 /* To store the bytes construct 4 dirty helper calls. The helper calls
11535 are guarded (num_bytes == 1, num_bytes == 2, etc) such that only
11536 one of them will be called at runtime. */
11537 int i;
11538 for (i = 1; i <= 4; ++i) {
11539 IRDirty *d;
11540
11541 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
11542 &s390x_dirtyhelper_CUxy,
11543 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
11544 mkexpr(num_bytes)));
11545 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
11546 d->mFx = Ifx_Write;
11547 d->mAddr = mkexpr(addr1);
11548 d->mSize = i;
11549 stmt(IRStmt_Dirty(d));
11550 }
11551
11552 /* Update source address and length */
11553 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkU64(4)));
11554 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkU64(4)));
11555
11556 /* Update destination address and length */
11557 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
11558 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
11559
11560 iterate();
11561
11562 return "cu41";
11563}
11564
11565static IRExpr *
florian3f8a96a2012-08-05 02:59:55 +000011566s390_call_cu12_cu14_helper1(IRExpr *byte1, IRExpr *etf3_and_m3_is_1)
florian6d9b9b22012-08-03 18:35:39 +000011567{
11568 IRExpr **args, *call;
11569 args = mkIRExprVec_2(byte1, etf3_and_m3_is_1);
florian3f8a96a2012-08-05 02:59:55 +000011570 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/, "s390_do_cu12_cu14_helper1",
11571 &s390_do_cu12_cu14_helper1, args);
florian6d9b9b22012-08-03 18:35:39 +000011572
11573 /* Nothing is excluded from definedness checking. */
11574 call->Iex.CCall.cee->mcx_mask = 0;
11575
11576 return call;
11577}
11578
11579static IRExpr *
11580s390_call_cu12_helper2(IRExpr *byte1, IRExpr *byte2, IRExpr *byte3,
11581 IRExpr *byte4, IRExpr *stuff)
11582{
11583 IRExpr **args, *call;
11584 args = mkIRExprVec_5(byte1, byte2, byte3, byte4, stuff);
11585 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
11586 "s390_do_cu12_helper2", &s390_do_cu12_helper2, args);
11587
11588 /* Nothing is excluded from definedness checking. */
11589 call->Iex.CCall.cee->mcx_mask = 0;
11590
11591 return call;
11592}
11593
florian3f8a96a2012-08-05 02:59:55 +000011594static IRExpr *
11595s390_call_cu14_helper2(IRExpr *byte1, IRExpr *byte2, IRExpr *byte3,
11596 IRExpr *byte4, IRExpr *stuff)
11597{
11598 IRExpr **args, *call;
11599 args = mkIRExprVec_5(byte1, byte2, byte3, byte4, stuff);
11600 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
11601 "s390_do_cu14_helper2", &s390_do_cu14_helper2, args);
11602
11603 /* Nothing is excluded from definedness checking. */
11604 call->Iex.CCall.cee->mcx_mask = 0;
11605
11606 return call;
11607}
11608
11609static void
11610s390_irgen_cu12_cu14(UChar m3, UChar r1, UChar r2, Bool is_cu12)
florian6d9b9b22012-08-03 18:35:39 +000011611{
11612 IRTemp addr1 = newTemp(Ity_I64);
11613 IRTemp addr2 = newTemp(Ity_I64);
11614 IRTemp len1 = newTemp(Ity_I64);
11615 IRTemp len2 = newTemp(Ity_I64);
11616
11617 assign(addr1, get_gpr_dw0(r1));
11618 assign(addr2, get_gpr_dw0(r2));
11619 assign(len1, get_gpr_dw0(r1 + 1));
11620 assign(len2, get_gpr_dw0(r2 + 1));
11621
11622 UInt extended_checking = s390_host_has_etf3 && (m3 & 0x1) == 1;
11623
11624 /* We're processing the 2nd operand 1 byte at a time. Therefore, if
11625 there is less than 1 byte left, then the 2nd operand is exhausted
11626 and we're done here. cc = 0 */
11627 s390_cc_set(0);
11628 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(1)));
11629
11630 /* There is at least one byte there. Read it. */
11631 IRTemp byte1 = newTemp(Ity_I32);
11632 assign(byte1, unop(Iop_8Uto32, load(Ity_I8, mkexpr(addr2))));
11633
11634 /* Call the helper to get number of bytes and invalid byte indicator */
11635 IRTemp retval1 = newTemp(Ity_I64);
florian3f8a96a2012-08-05 02:59:55 +000011636 assign(retval1, s390_call_cu12_cu14_helper1(mkexpr(byte1),
11637 mkU32(extended_checking)));
florian6d9b9b22012-08-03 18:35:39 +000011638
11639 /* Check for invalid 1st byte */
11640 IRExpr *is_invalid = unop(Iop_64to1, mkexpr(retval1));
11641 s390_cc_set(2);
11642 next_insn_if(is_invalid);
11643
11644 /* How many bytes do we have to read? */
11645 IRTemp num_src_bytes = newTemp(Ity_I64);
11646 assign(num_src_bytes, binop(Iop_Shr64, mkexpr(retval1), mkU8(8)));
11647
11648 /* Now test whether the 2nd operand is exhausted */
11649 s390_cc_set(0);
11650 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkexpr(num_src_bytes)));
11651
11652 /* Read the remaining bytes */
11653 IRExpr *cond, *addr, *byte2, *byte3, *byte4;
11654
11655 cond = binop(Iop_CmpLE64U, mkU64(2), mkexpr(num_src_bytes));
11656 addr = binop(Iop_Add64, mkexpr(addr2), mkU64(1));
11657 byte2 = mkite(cond, unop(Iop_8Uto32, load(Ity_I8, addr)), mkU32(0));
11658 cond = binop(Iop_CmpLE64U, mkU64(3), mkexpr(num_src_bytes));
11659 addr = binop(Iop_Add64, mkexpr(addr2), mkU64(2));
11660 byte3 = mkite(cond, unop(Iop_8Uto32, load(Ity_I8, addr)), mkU32(0));
11661 cond = binop(Iop_CmpLE64U, mkU64(4), mkexpr(num_src_bytes));
11662 addr = binop(Iop_Add64, mkexpr(addr2), mkU64(3));
11663 byte4 = mkite(cond, unop(Iop_8Uto32, load(Ity_I8, addr)), mkU32(0));
11664
11665 /* Call the helper to get the converted value and invalid byte indicator.
11666 We can pass at most 5 arguments; therefore some encoding is needed
11667 here */
11668 IRExpr *stuff = binop(Iop_Or64,
11669 binop(Iop_Shl64, mkexpr(num_src_bytes), mkU8(1)),
11670 mkU64(extended_checking));
11671 IRTemp retval2 = newTemp(Ity_I64);
florian3f8a96a2012-08-05 02:59:55 +000011672
11673 if (is_cu12) {
11674 assign(retval2, s390_call_cu12_helper2(mkexpr(byte1), byte2, byte3,
11675 byte4, stuff));
11676 } else {
11677 assign(retval2, s390_call_cu14_helper2(mkexpr(byte1), byte2, byte3,
11678 byte4, stuff));
11679 }
florian6d9b9b22012-08-03 18:35:39 +000011680
11681 /* Check for invalid character */
11682 s390_cc_set(2);
11683 is_invalid = unop(Iop_64to1, mkexpr(retval2));
11684 next_insn_if(is_invalid);
11685
11686 /* Now test whether the 1st operand is exhausted */
11687 IRTemp num_bytes = newTemp(Ity_I64);
11688 assign(num_bytes, binop(Iop_And64,
11689 binop(Iop_Shr64, mkexpr(retval2), mkU8(8)),
11690 mkU64(0xff)));
11691 s390_cc_set(1);
11692 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
11693
11694 /* Extract the bytes to be stored at addr1 */
11695 IRTemp data = newTemp(Ity_I64);
11696 assign(data, binop(Iop_Shr64, mkexpr(retval2), mkU8(16)));
11697
florian3f8a96a2012-08-05 02:59:55 +000011698 if (is_cu12) {
11699 /* To store the bytes construct 2 dirty helper calls. The helper calls
11700 are guarded (num_bytes == 2 and num_bytes == 4, respectively) such
11701 that only one of them will be called at runtime. */
florian6d9b9b22012-08-03 18:35:39 +000011702
florian3f8a96a2012-08-05 02:59:55 +000011703 Int i;
11704 for (i = 2; i <= 4; ++i) {
11705 IRDirty *d;
florian6d9b9b22012-08-03 18:35:39 +000011706
florian3f8a96a2012-08-05 02:59:55 +000011707 if (i == 3) continue; // skip this one
florian6d9b9b22012-08-03 18:35:39 +000011708
florian3f8a96a2012-08-05 02:59:55 +000011709 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
11710 &s390x_dirtyhelper_CUxy,
11711 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
11712 mkexpr(num_bytes)));
11713 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
11714 d->mFx = Ifx_Write;
11715 d->mAddr = mkexpr(addr1);
11716 d->mSize = i;
11717 stmt(IRStmt_Dirty(d));
11718 }
11719 } else {
11720 // cu14
11721 store(mkexpr(addr1), unop(Iop_64to32, mkexpr(data)));
florian6d9b9b22012-08-03 18:35:39 +000011722 }
11723
11724 /* Update source address and length */
11725 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkexpr(num_src_bytes)));
11726 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkexpr(num_src_bytes)));
11727
11728 /* Update destination address and length */
11729 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
11730 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
11731
11732 iterate();
florian3f8a96a2012-08-05 02:59:55 +000011733}
11734
11735static HChar *
11736s390_irgen_CU12(UChar m3, UChar r1, UChar r2)
11737{
11738 s390_irgen_cu12_cu14(m3, r1, r2, /* is_cu12 = */ 1);
florian6d9b9b22012-08-03 18:35:39 +000011739
11740 return "cu12";
11741}
11742
florian3f8a96a2012-08-05 02:59:55 +000011743static HChar *
11744s390_irgen_CU14(UChar m3, UChar r1, UChar r2)
11745{
11746 s390_irgen_cu12_cu14(m3, r1, r2, /* is_cu12 = */ 0);
11747
11748 return "cu14";
11749}
11750
sewardj2019a972011-03-07 16:04:07 +000011751/*------------------------------------------------------------*/
11752/*--- Build IR for special instructions ---*/
11753/*------------------------------------------------------------*/
11754
florianb4df7682011-07-05 02:09:01 +000011755static void
sewardj2019a972011-03-07 16:04:07 +000011756s390_irgen_client_request(void)
11757{
11758 if (0)
11759 vex_printf("%%R3 = client_request ( %%R2 )\n");
11760
florianf9e1ed72012-04-17 02:41:56 +000011761 Addr64 next = guest_IA_curr_instr + S390_SPECIAL_OP_PREAMBLE_SIZE
11762 + S390_SPECIAL_OP_SIZE;
sewardj2019a972011-03-07 16:04:07 +000011763
florianf9e1ed72012-04-17 02:41:56 +000011764 dis_res->jk_StopHere = Ijk_ClientReq;
sewardj2019a972011-03-07 16:04:07 +000011765 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +000011766
11767 put_IA(mkaddr_expr(next));
sewardj2019a972011-03-07 16:04:07 +000011768}
11769
florianb4df7682011-07-05 02:09:01 +000011770static void
sewardj2019a972011-03-07 16:04:07 +000011771s390_irgen_guest_NRADDR(void)
11772{
11773 if (0)
11774 vex_printf("%%R3 = guest_NRADDR\n");
11775
floriane88b3c92011-07-05 02:48:39 +000011776 put_gpr_dw0(3, IRExpr_Get(S390X_GUEST_OFFSET(guest_NRADDR), Ity_I64));
sewardj2019a972011-03-07 16:04:07 +000011777}
11778
florianb4df7682011-07-05 02:09:01 +000011779static void
sewardj2019a972011-03-07 16:04:07 +000011780s390_irgen_call_noredir(void)
11781{
florianf9e1ed72012-04-17 02:41:56 +000011782 Addr64 next = guest_IA_curr_instr + S390_SPECIAL_OP_PREAMBLE_SIZE
11783 + S390_SPECIAL_OP_SIZE;
11784
sewardj2019a972011-03-07 16:04:07 +000011785 /* Continue after special op */
florianf9e1ed72012-04-17 02:41:56 +000011786 put_gpr_dw0(14, mkaddr_expr(next));
sewardj2019a972011-03-07 16:04:07 +000011787
11788 /* The address is in REG1, all parameters are in the right (guest) places */
florianf9e1ed72012-04-17 02:41:56 +000011789 put_IA(get_gpr_dw0(1));
sewardj2019a972011-03-07 16:04:07 +000011790
11791 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +000011792 dis_res->jk_StopHere = Ijk_NoRedir;
sewardj2019a972011-03-07 16:04:07 +000011793}
11794
11795/* Force proper alignment for the structures below. */
11796#pragma pack(1)
11797
11798
11799static s390_decode_t
11800s390_decode_2byte_and_irgen(UChar *bytes)
11801{
11802 typedef union {
11803 struct {
11804 unsigned int op : 16;
11805 } E;
11806 struct {
11807 unsigned int op : 8;
11808 unsigned int i : 8;
11809 } I;
11810 struct {
11811 unsigned int op : 8;
11812 unsigned int r1 : 4;
11813 unsigned int r2 : 4;
11814 } RR;
11815 } formats;
11816 union {
11817 formats fmt;
11818 UShort value;
11819 } ovl;
11820
11821 vassert(sizeof(formats) == 2);
11822
11823 ((char *)(&ovl.value))[0] = bytes[0];
11824 ((char *)(&ovl.value))[1] = bytes[1];
11825
11826 switch (ovl.value & 0xffff) {
11827 case 0x0101: /* PR */ goto unimplemented;
11828 case 0x0102: /* UPT */ goto unimplemented;
11829 case 0x0104: /* PTFF */ goto unimplemented;
11830 case 0x0107: /* SCKPF */ goto unimplemented;
11831 case 0x010a: /* PFPO */ goto unimplemented;
11832 case 0x010b: /* TAM */ goto unimplemented;
11833 case 0x010c: /* SAM24 */ goto unimplemented;
11834 case 0x010d: /* SAM31 */ goto unimplemented;
11835 case 0x010e: /* SAM64 */ goto unimplemented;
11836 case 0x01ff: /* TRAP2 */ goto unimplemented;
11837 }
11838
11839 switch ((ovl.value & 0xff00) >> 8) {
11840 case 0x04: /* SPM */ goto unimplemented;
11841 case 0x05: /* BALR */ goto unimplemented;
11842 case 0x06: s390_format_RR_RR(s390_irgen_BCTR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
11843 goto ok;
11844 case 0x07: s390_format_RR(s390_irgen_BCR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
11845 goto ok;
11846 case 0x0a: s390_format_I(s390_irgen_SVC, ovl.fmt.I.i); goto ok;
11847 case 0x0b: /* BSM */ goto unimplemented;
11848 case 0x0c: /* BASSM */ goto unimplemented;
11849 case 0x0d: s390_format_RR_RR(s390_irgen_BASR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
11850 goto ok;
florianb0c9a132011-09-08 15:37:39 +000011851 case 0x0e: s390_format_RR(s390_irgen_MVCL, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
11852 goto ok;
11853 case 0x0f: s390_format_RR(s390_irgen_CLCL, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
11854 goto ok;
sewardj2019a972011-03-07 16:04:07 +000011855 case 0x10: s390_format_RR_RR(s390_irgen_LPR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
11856 goto ok;
11857 case 0x11: s390_format_RR_RR(s390_irgen_LNR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
11858 goto ok;
11859 case 0x12: s390_format_RR_RR(s390_irgen_LTR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
11860 goto ok;
11861 case 0x13: s390_format_RR_RR(s390_irgen_LCR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
11862 goto ok;
11863 case 0x14: s390_format_RR_RR(s390_irgen_NR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
11864 goto ok;
11865 case 0x15: s390_format_RR_RR(s390_irgen_CLR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
11866 goto ok;
11867 case 0x16: s390_format_RR_RR(s390_irgen_OR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
11868 goto ok;
11869 case 0x17: s390_format_RR_RR(s390_irgen_XR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
11870 goto ok;
11871 case 0x18: s390_format_RR_RR(s390_irgen_LR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
11872 goto ok;
11873 case 0x19: s390_format_RR_RR(s390_irgen_CR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
11874 goto ok;
11875 case 0x1a: s390_format_RR_RR(s390_irgen_AR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
11876 goto ok;
11877 case 0x1b: s390_format_RR_RR(s390_irgen_SR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
11878 goto ok;
11879 case 0x1c: s390_format_RR_RR(s390_irgen_MR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
11880 goto ok;
11881 case 0x1d: s390_format_RR_RR(s390_irgen_DR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
11882 goto ok;
11883 case 0x1e: s390_format_RR_RR(s390_irgen_ALR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
11884 goto ok;
11885 case 0x1f: s390_format_RR_RR(s390_irgen_SLR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
11886 goto ok;
11887 case 0x20: /* LPDR */ goto unimplemented;
11888 case 0x21: /* LNDR */ goto unimplemented;
11889 case 0x22: /* LTDR */ goto unimplemented;
11890 case 0x23: /* LCDR */ goto unimplemented;
11891 case 0x24: /* HDR */ goto unimplemented;
11892 case 0x25: /* LDXR */ goto unimplemented;
11893 case 0x26: /* MXR */ goto unimplemented;
11894 case 0x27: /* MXDR */ goto unimplemented;
11895 case 0x28: s390_format_RR_FF(s390_irgen_LDR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
11896 goto ok;
11897 case 0x29: /* CDR */ goto unimplemented;
11898 case 0x2a: /* ADR */ goto unimplemented;
11899 case 0x2b: /* SDR */ goto unimplemented;
11900 case 0x2c: /* MDR */ goto unimplemented;
11901 case 0x2d: /* DDR */ goto unimplemented;
11902 case 0x2e: /* AWR */ goto unimplemented;
11903 case 0x2f: /* SWR */ goto unimplemented;
11904 case 0x30: /* LPER */ goto unimplemented;
11905 case 0x31: /* LNER */ goto unimplemented;
11906 case 0x32: /* LTER */ goto unimplemented;
11907 case 0x33: /* LCER */ goto unimplemented;
11908 case 0x34: /* HER */ goto unimplemented;
11909 case 0x35: /* LEDR */ goto unimplemented;
11910 case 0x36: /* AXR */ goto unimplemented;
11911 case 0x37: /* SXR */ goto unimplemented;
11912 case 0x38: s390_format_RR_FF(s390_irgen_LER, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
11913 goto ok;
11914 case 0x39: /* CER */ goto unimplemented;
11915 case 0x3a: /* AER */ goto unimplemented;
11916 case 0x3b: /* SER */ goto unimplemented;
11917 case 0x3c: /* MDER */ goto unimplemented;
11918 case 0x3d: /* DER */ goto unimplemented;
11919 case 0x3e: /* AUR */ goto unimplemented;
11920 case 0x3f: /* SUR */ goto unimplemented;
11921 }
11922
11923 return S390_DECODE_UNKNOWN_INSN;
11924
11925ok:
11926 return S390_DECODE_OK;
11927
11928unimplemented:
11929 return S390_DECODE_UNIMPLEMENTED_INSN;
11930}
11931
11932static s390_decode_t
11933s390_decode_4byte_and_irgen(UChar *bytes)
11934{
11935 typedef union {
11936 struct {
11937 unsigned int op1 : 8;
11938 unsigned int r1 : 4;
11939 unsigned int op2 : 4;
11940 unsigned int i2 : 16;
11941 } RI;
11942 struct {
11943 unsigned int op : 16;
11944 unsigned int : 8;
11945 unsigned int r1 : 4;
11946 unsigned int r2 : 4;
11947 } RRE;
11948 struct {
11949 unsigned int op : 16;
11950 unsigned int r1 : 4;
11951 unsigned int : 4;
11952 unsigned int r3 : 4;
11953 unsigned int r2 : 4;
11954 } RRF;
11955 struct {
11956 unsigned int op : 16;
11957 unsigned int r3 : 4;
11958 unsigned int m4 : 4;
11959 unsigned int r1 : 4;
11960 unsigned int r2 : 4;
11961 } RRF2;
11962 struct {
11963 unsigned int op : 16;
11964 unsigned int r3 : 4;
11965 unsigned int : 4;
11966 unsigned int r1 : 4;
11967 unsigned int r2 : 4;
11968 } RRF3;
11969 struct {
11970 unsigned int op : 16;
11971 unsigned int r3 : 4;
11972 unsigned int : 4;
11973 unsigned int r1 : 4;
11974 unsigned int r2 : 4;
11975 } RRR;
11976 struct {
11977 unsigned int op : 16;
11978 unsigned int r3 : 4;
11979 unsigned int : 4;
11980 unsigned int r1 : 4;
11981 unsigned int r2 : 4;
11982 } RRF4;
11983 struct {
11984 unsigned int op : 8;
11985 unsigned int r1 : 4;
11986 unsigned int r3 : 4;
11987 unsigned int b2 : 4;
11988 unsigned int d2 : 12;
11989 } RS;
11990 struct {
11991 unsigned int op : 8;
11992 unsigned int r1 : 4;
11993 unsigned int r3 : 4;
11994 unsigned int i2 : 16;
11995 } RSI;
11996 struct {
11997 unsigned int op : 8;
11998 unsigned int r1 : 4;
11999 unsigned int x2 : 4;
12000 unsigned int b2 : 4;
12001 unsigned int d2 : 12;
12002 } RX;
12003 struct {
12004 unsigned int op : 16;
12005 unsigned int b2 : 4;
12006 unsigned int d2 : 12;
12007 } S;
12008 struct {
12009 unsigned int op : 8;
12010 unsigned int i2 : 8;
12011 unsigned int b1 : 4;
12012 unsigned int d1 : 12;
12013 } SI;
12014 } formats;
12015 union {
12016 formats fmt;
12017 UInt value;
12018 } ovl;
12019
12020 vassert(sizeof(formats) == 4);
12021
12022 ((char *)(&ovl.value))[0] = bytes[0];
12023 ((char *)(&ovl.value))[1] = bytes[1];
12024 ((char *)(&ovl.value))[2] = bytes[2];
12025 ((char *)(&ovl.value))[3] = bytes[3];
12026
12027 switch ((ovl.value & 0xff0f0000) >> 16) {
12028 case 0xa500: s390_format_RI_RU(s390_irgen_IIHH, ovl.fmt.RI.r1,
12029 ovl.fmt.RI.i2); goto ok;
12030 case 0xa501: s390_format_RI_RU(s390_irgen_IIHL, ovl.fmt.RI.r1,
12031 ovl.fmt.RI.i2); goto ok;
12032 case 0xa502: s390_format_RI_RU(s390_irgen_IILH, ovl.fmt.RI.r1,
12033 ovl.fmt.RI.i2); goto ok;
12034 case 0xa503: s390_format_RI_RU(s390_irgen_IILL, ovl.fmt.RI.r1,
12035 ovl.fmt.RI.i2); goto ok;
12036 case 0xa504: s390_format_RI_RU(s390_irgen_NIHH, ovl.fmt.RI.r1,
12037 ovl.fmt.RI.i2); goto ok;
12038 case 0xa505: s390_format_RI_RU(s390_irgen_NIHL, ovl.fmt.RI.r1,
12039 ovl.fmt.RI.i2); goto ok;
12040 case 0xa506: s390_format_RI_RU(s390_irgen_NILH, ovl.fmt.RI.r1,
12041 ovl.fmt.RI.i2); goto ok;
12042 case 0xa507: s390_format_RI_RU(s390_irgen_NILL, ovl.fmt.RI.r1,
12043 ovl.fmt.RI.i2); goto ok;
12044 case 0xa508: s390_format_RI_RU(s390_irgen_OIHH, ovl.fmt.RI.r1,
12045 ovl.fmt.RI.i2); goto ok;
12046 case 0xa509: s390_format_RI_RU(s390_irgen_OIHL, ovl.fmt.RI.r1,
12047 ovl.fmt.RI.i2); goto ok;
12048 case 0xa50a: s390_format_RI_RU(s390_irgen_OILH, ovl.fmt.RI.r1,
12049 ovl.fmt.RI.i2); goto ok;
12050 case 0xa50b: s390_format_RI_RU(s390_irgen_OILL, ovl.fmt.RI.r1,
12051 ovl.fmt.RI.i2); goto ok;
12052 case 0xa50c: s390_format_RI_RU(s390_irgen_LLIHH, ovl.fmt.RI.r1,
12053 ovl.fmt.RI.i2); goto ok;
12054 case 0xa50d: s390_format_RI_RU(s390_irgen_LLIHL, ovl.fmt.RI.r1,
12055 ovl.fmt.RI.i2); goto ok;
12056 case 0xa50e: s390_format_RI_RU(s390_irgen_LLILH, ovl.fmt.RI.r1,
12057 ovl.fmt.RI.i2); goto ok;
12058 case 0xa50f: s390_format_RI_RU(s390_irgen_LLILL, ovl.fmt.RI.r1,
12059 ovl.fmt.RI.i2); goto ok;
12060 case 0xa700: s390_format_RI_RU(s390_irgen_TMLH, ovl.fmt.RI.r1,
12061 ovl.fmt.RI.i2); goto ok;
12062 case 0xa701: s390_format_RI_RU(s390_irgen_TMLL, ovl.fmt.RI.r1,
12063 ovl.fmt.RI.i2); goto ok;
12064 case 0xa702: s390_format_RI_RU(s390_irgen_TMHH, ovl.fmt.RI.r1,
12065 ovl.fmt.RI.i2); goto ok;
12066 case 0xa703: s390_format_RI_RU(s390_irgen_TMHL, ovl.fmt.RI.r1,
12067 ovl.fmt.RI.i2); goto ok;
12068 case 0xa704: s390_format_RI(s390_irgen_BRC, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
12069 goto ok;
12070 case 0xa705: s390_format_RI_RP(s390_irgen_BRAS, ovl.fmt.RI.r1,
12071 ovl.fmt.RI.i2); goto ok;
12072 case 0xa706: s390_format_RI_RP(s390_irgen_BRCT, ovl.fmt.RI.r1,
12073 ovl.fmt.RI.i2); goto ok;
12074 case 0xa707: s390_format_RI_RP(s390_irgen_BRCTG, ovl.fmt.RI.r1,
12075 ovl.fmt.RI.i2); goto ok;
12076 case 0xa708: s390_format_RI_RI(s390_irgen_LHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
12077 goto ok;
12078 case 0xa709: s390_format_RI_RI(s390_irgen_LGHI, ovl.fmt.RI.r1,
12079 ovl.fmt.RI.i2); goto ok;
12080 case 0xa70a: s390_format_RI_RI(s390_irgen_AHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
12081 goto ok;
12082 case 0xa70b: s390_format_RI_RI(s390_irgen_AGHI, ovl.fmt.RI.r1,
12083 ovl.fmt.RI.i2); goto ok;
12084 case 0xa70c: s390_format_RI_RI(s390_irgen_MHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
12085 goto ok;
12086 case 0xa70d: s390_format_RI_RI(s390_irgen_MGHI, ovl.fmt.RI.r1,
12087 ovl.fmt.RI.i2); goto ok;
12088 case 0xa70e: s390_format_RI_RI(s390_irgen_CHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
12089 goto ok;
12090 case 0xa70f: s390_format_RI_RI(s390_irgen_CGHI, ovl.fmt.RI.r1,
12091 ovl.fmt.RI.i2); goto ok;
12092 }
12093
12094 switch ((ovl.value & 0xffff0000) >> 16) {
12095 case 0x8000: /* SSM */ goto unimplemented;
12096 case 0x8200: /* LPSW */ goto unimplemented;
florian7700fc92012-01-16 17:25:55 +000012097 case 0x9300: /* TS */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000012098 case 0xb202: /* STIDP */ goto unimplemented;
12099 case 0xb204: /* SCK */ goto unimplemented;
florian7700fc92012-01-16 17:25:55 +000012100 case 0xb205: s390_format_S_RD(s390_irgen_STCK, ovl.fmt.S.b2, ovl.fmt.S.d2);
12101 goto ok;
sewardj2019a972011-03-07 16:04:07 +000012102 case 0xb206: /* SCKC */ goto unimplemented;
12103 case 0xb207: /* STCKC */ goto unimplemented;
12104 case 0xb208: /* SPT */ goto unimplemented;
12105 case 0xb209: /* STPT */ goto unimplemented;
12106 case 0xb20a: /* SPKA */ goto unimplemented;
12107 case 0xb20b: /* IPK */ goto unimplemented;
12108 case 0xb20d: /* PTLB */ goto unimplemented;
12109 case 0xb210: /* SPX */ goto unimplemented;
12110 case 0xb211: /* STPX */ goto unimplemented;
12111 case 0xb212: /* STAP */ goto unimplemented;
12112 case 0xb214: /* SIE */ goto unimplemented;
12113 case 0xb218: /* PC */ goto unimplemented;
12114 case 0xb219: /* SAC */ goto unimplemented;
12115 case 0xb21a: /* CFC */ goto unimplemented;
12116 case 0xb221: /* IPTE */ goto unimplemented;
12117 case 0xb222: s390_format_RRE_R0(s390_irgen_IPM, ovl.fmt.RRE.r1); goto ok;
12118 case 0xb223: /* IVSK */ goto unimplemented;
12119 case 0xb224: /* IAC */ goto unimplemented;
12120 case 0xb225: /* SSAR */ goto unimplemented;
12121 case 0xb226: /* EPAR */ goto unimplemented;
12122 case 0xb227: /* ESAR */ goto unimplemented;
12123 case 0xb228: /* PT */ goto unimplemented;
12124 case 0xb229: /* ISKE */ goto unimplemented;
12125 case 0xb22a: /* RRBE */ goto unimplemented;
12126 case 0xb22b: /* SSKE */ goto unimplemented;
12127 case 0xb22c: /* TB */ goto unimplemented;
12128 case 0xb22d: /* DXR */ goto unimplemented;
12129 case 0xb22e: /* PGIN */ goto unimplemented;
12130 case 0xb22f: /* PGOUT */ goto unimplemented;
12131 case 0xb230: /* CSCH */ goto unimplemented;
12132 case 0xb231: /* HSCH */ goto unimplemented;
12133 case 0xb232: /* MSCH */ goto unimplemented;
12134 case 0xb233: /* SSCH */ goto unimplemented;
12135 case 0xb234: /* STSCH */ goto unimplemented;
12136 case 0xb235: /* TSCH */ goto unimplemented;
12137 case 0xb236: /* TPI */ goto unimplemented;
12138 case 0xb237: /* SAL */ goto unimplemented;
12139 case 0xb238: /* RSCH */ goto unimplemented;
12140 case 0xb239: /* STCRW */ goto unimplemented;
12141 case 0xb23a: /* STCPS */ goto unimplemented;
12142 case 0xb23b: /* RCHP */ goto unimplemented;
12143 case 0xb23c: /* SCHM */ goto unimplemented;
12144 case 0xb240: /* BAKR */ goto unimplemented;
floriana4384a32011-08-11 16:58:45 +000012145 case 0xb241: s390_format_RRE(s390_irgen_CKSM, ovl.fmt.RRE.r1,
12146 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000012147 case 0xb244: /* SQDR */ goto unimplemented;
12148 case 0xb245: /* SQER */ goto unimplemented;
12149 case 0xb246: /* STURA */ goto unimplemented;
12150 case 0xb247: /* MSTA */ goto unimplemented;
12151 case 0xb248: /* PALB */ goto unimplemented;
12152 case 0xb249: /* EREG */ goto unimplemented;
12153 case 0xb24a: /* ESTA */ goto unimplemented;
12154 case 0xb24b: /* LURA */ goto unimplemented;
12155 case 0xb24c: /* TAR */ goto unimplemented;
12156 case 0xb24d: s390_format_RRE(s390_irgen_CPYA, ovl.fmt.RRE.r1,
12157 ovl.fmt.RRE.r2); goto ok;
12158 case 0xb24e: s390_format_RRE(s390_irgen_SAR, ovl.fmt.RRE.r1, ovl.fmt.RRE.r2);
12159 goto ok;
12160 case 0xb24f: s390_format_RRE(s390_irgen_EAR, ovl.fmt.RRE.r1, ovl.fmt.RRE.r2);
12161 goto ok;
12162 case 0xb250: /* CSP */ goto unimplemented;
12163 case 0xb252: s390_format_RRE_RR(s390_irgen_MSR, ovl.fmt.RRE.r1,
12164 ovl.fmt.RRE.r2); goto ok;
12165 case 0xb254: /* MVPG */ goto unimplemented;
12166 case 0xb255: s390_format_RRE_RR(s390_irgen_MVST, ovl.fmt.RRE.r1,
12167 ovl.fmt.RRE.r2); goto ok;
12168 case 0xb257: /* CUSE */ goto unimplemented;
12169 case 0xb258: /* BSG */ goto unimplemented;
12170 case 0xb25a: /* BSA */ goto unimplemented;
12171 case 0xb25d: s390_format_RRE_RR(s390_irgen_CLST, ovl.fmt.RRE.r1,
12172 ovl.fmt.RRE.r2); goto ok;
12173 case 0xb25e: s390_format_RRE_RR(s390_irgen_SRST, ovl.fmt.RRE.r1,
12174 ovl.fmt.RRE.r2); goto ok;
12175 case 0xb263: /* CMPSC */ goto unimplemented;
12176 case 0xb274: /* SIGA */ goto unimplemented;
12177 case 0xb276: /* XSCH */ goto unimplemented;
12178 case 0xb277: /* RP */ goto unimplemented;
sewardj1e5fea62011-05-17 16:18:36 +000012179 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 +000012180 case 0xb279: /* SACF */ goto unimplemented;
sewardj1e5fea62011-05-17 16:18:36 +000012181 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 +000012182 case 0xb27d: /* STSI */ goto unimplemented;
12183 case 0xb299: s390_format_S_RD(s390_irgen_SRNM, ovl.fmt.S.b2, ovl.fmt.S.d2);
12184 goto ok;
12185 case 0xb29c: s390_format_S_RD(s390_irgen_STFPC, ovl.fmt.S.b2, ovl.fmt.S.d2);
12186 goto ok;
12187 case 0xb29d: s390_format_S_RD(s390_irgen_LFPC, ovl.fmt.S.b2, ovl.fmt.S.d2);
12188 goto ok;
florian730448f2012-02-04 17:07:07 +000012189 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 +000012190 case 0xb2a6: s390_format_RRF_M0RERE(s390_irgen_CU21, ovl.fmt.RRF3.r3,
12191 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
12192 goto ok;
florian6d9b9b22012-08-03 18:35:39 +000012193 case 0xb2a7: s390_format_RRF_M0RERE(s390_irgen_CU12, ovl.fmt.RRF3.r3,
12194 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
12195 goto ok;
florian933065d2011-07-11 01:48:02 +000012196 case 0xb2b0: s390_format_S_RD(s390_irgen_STFLE, ovl.fmt.S.b2, ovl.fmt.S.d2);
12197 goto ok;
sewardj2019a972011-03-07 16:04:07 +000012198 case 0xb2b1: /* STFL */ goto unimplemented;
12199 case 0xb2b2: /* LPSWE */ goto unimplemented;
12200 case 0xb2b8: /* SRNMB */ goto unimplemented;
12201 case 0xb2b9: /* SRNMT */ goto unimplemented;
12202 case 0xb2bd: /* LFAS */ goto unimplemented;
12203 case 0xb2ff: /* TRAP4 */ goto unimplemented;
12204 case 0xb300: s390_format_RRE_FF(s390_irgen_LPEBR, ovl.fmt.RRE.r1,
12205 ovl.fmt.RRE.r2); goto ok;
12206 case 0xb301: s390_format_RRE_FF(s390_irgen_LNEBR, ovl.fmt.RRE.r1,
12207 ovl.fmt.RRE.r2); goto ok;
12208 case 0xb302: s390_format_RRE_FF(s390_irgen_LTEBR, ovl.fmt.RRE.r1,
12209 ovl.fmt.RRE.r2); goto ok;
12210 case 0xb303: s390_format_RRE_FF(s390_irgen_LCEBR, ovl.fmt.RRE.r1,
12211 ovl.fmt.RRE.r2); goto ok;
12212 case 0xb304: s390_format_RRE_FF(s390_irgen_LDEBR, ovl.fmt.RRE.r1,
12213 ovl.fmt.RRE.r2); goto ok;
12214 case 0xb305: s390_format_RRE_FF(s390_irgen_LXDBR, ovl.fmt.RRE.r1,
12215 ovl.fmt.RRE.r2); goto ok;
12216 case 0xb306: s390_format_RRE_FF(s390_irgen_LXEBR, ovl.fmt.RRE.r1,
12217 ovl.fmt.RRE.r2); goto ok;
12218 case 0xb307: /* MXDBR */ goto unimplemented;
12219 case 0xb308: /* KEBR */ goto unimplemented;
12220 case 0xb309: s390_format_RRE_FF(s390_irgen_CEBR, ovl.fmt.RRE.r1,
12221 ovl.fmt.RRE.r2); goto ok;
12222 case 0xb30a: s390_format_RRE_FF(s390_irgen_AEBR, ovl.fmt.RRE.r1,
12223 ovl.fmt.RRE.r2); goto ok;
12224 case 0xb30b: s390_format_RRE_FF(s390_irgen_SEBR, ovl.fmt.RRE.r1,
12225 ovl.fmt.RRE.r2); goto ok;
12226 case 0xb30c: /* MDEBR */ goto unimplemented;
12227 case 0xb30d: s390_format_RRE_FF(s390_irgen_DEBR, ovl.fmt.RRE.r1,
12228 ovl.fmt.RRE.r2); goto ok;
12229 case 0xb30e: s390_format_RRF_F0FF(s390_irgen_MAEBR, ovl.fmt.RRF.r1,
12230 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
12231 case 0xb30f: s390_format_RRF_F0FF(s390_irgen_MSEBR, ovl.fmt.RRF.r1,
12232 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
12233 case 0xb310: s390_format_RRE_FF(s390_irgen_LPDBR, ovl.fmt.RRE.r1,
12234 ovl.fmt.RRE.r2); goto ok;
12235 case 0xb311: s390_format_RRE_FF(s390_irgen_LNDBR, ovl.fmt.RRE.r1,
12236 ovl.fmt.RRE.r2); goto ok;
12237 case 0xb312: s390_format_RRE_FF(s390_irgen_LTDBR, ovl.fmt.RRE.r1,
12238 ovl.fmt.RRE.r2); goto ok;
12239 case 0xb313: s390_format_RRE_FF(s390_irgen_LCDBR, ovl.fmt.RRE.r1,
12240 ovl.fmt.RRE.r2); goto ok;
12241 case 0xb314: s390_format_RRE_FF(s390_irgen_SQEBR, ovl.fmt.RRE.r1,
12242 ovl.fmt.RRE.r2); goto ok;
12243 case 0xb315: s390_format_RRE_FF(s390_irgen_SQDBR, ovl.fmt.RRE.r1,
12244 ovl.fmt.RRE.r2); goto ok;
12245 case 0xb316: s390_format_RRE_FF(s390_irgen_SQXBR, ovl.fmt.RRE.r1,
12246 ovl.fmt.RRE.r2); goto ok;
12247 case 0xb317: s390_format_RRE_FF(s390_irgen_MEEBR, ovl.fmt.RRE.r1,
12248 ovl.fmt.RRE.r2); goto ok;
12249 case 0xb318: /* KDBR */ goto unimplemented;
12250 case 0xb319: s390_format_RRE_FF(s390_irgen_CDBR, ovl.fmt.RRE.r1,
12251 ovl.fmt.RRE.r2); goto ok;
12252 case 0xb31a: s390_format_RRE_FF(s390_irgen_ADBR, ovl.fmt.RRE.r1,
12253 ovl.fmt.RRE.r2); goto ok;
12254 case 0xb31b: s390_format_RRE_FF(s390_irgen_SDBR, ovl.fmt.RRE.r1,
12255 ovl.fmt.RRE.r2); goto ok;
12256 case 0xb31c: s390_format_RRE_FF(s390_irgen_MDBR, ovl.fmt.RRE.r1,
12257 ovl.fmt.RRE.r2); goto ok;
12258 case 0xb31d: s390_format_RRE_FF(s390_irgen_DDBR, ovl.fmt.RRE.r1,
12259 ovl.fmt.RRE.r2); goto ok;
12260 case 0xb31e: s390_format_RRF_F0FF(s390_irgen_MADBR, ovl.fmt.RRF.r1,
12261 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
12262 case 0xb31f: s390_format_RRF_F0FF(s390_irgen_MSDBR, ovl.fmt.RRF.r1,
12263 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
12264 case 0xb324: /* LDER */ goto unimplemented;
12265 case 0xb325: /* LXDR */ goto unimplemented;
12266 case 0xb326: /* LXER */ goto unimplemented;
12267 case 0xb32e: /* MAER */ goto unimplemented;
12268 case 0xb32f: /* MSER */ goto unimplemented;
12269 case 0xb336: /* SQXR */ goto unimplemented;
12270 case 0xb337: /* MEER */ goto unimplemented;
12271 case 0xb338: /* MAYLR */ goto unimplemented;
12272 case 0xb339: /* MYLR */ goto unimplemented;
12273 case 0xb33a: /* MAYR */ goto unimplemented;
12274 case 0xb33b: /* MYR */ goto unimplemented;
12275 case 0xb33c: /* MAYHR */ goto unimplemented;
12276 case 0xb33d: /* MYHR */ goto unimplemented;
12277 case 0xb33e: /* MADR */ goto unimplemented;
12278 case 0xb33f: /* MSDR */ goto unimplemented;
12279 case 0xb340: s390_format_RRE_FF(s390_irgen_LPXBR, ovl.fmt.RRE.r1,
12280 ovl.fmt.RRE.r2); goto ok;
12281 case 0xb341: s390_format_RRE_FF(s390_irgen_LNXBR, ovl.fmt.RRE.r1,
12282 ovl.fmt.RRE.r2); goto ok;
12283 case 0xb342: s390_format_RRE_FF(s390_irgen_LTXBR, ovl.fmt.RRE.r1,
12284 ovl.fmt.RRE.r2); goto ok;
12285 case 0xb343: s390_format_RRE_FF(s390_irgen_LCXBR, ovl.fmt.RRE.r1,
12286 ovl.fmt.RRE.r2); goto ok;
12287 case 0xb344: s390_format_RRE_FF(s390_irgen_LEDBR, ovl.fmt.RRE.r1,
12288 ovl.fmt.RRE.r2); goto ok;
12289 case 0xb345: s390_format_RRE_FF(s390_irgen_LDXBR, ovl.fmt.RRE.r1,
12290 ovl.fmt.RRE.r2); goto ok;
12291 case 0xb346: s390_format_RRE_FF(s390_irgen_LEXBR, ovl.fmt.RRE.r1,
12292 ovl.fmt.RRE.r2); goto ok;
12293 case 0xb347: /* FIXBR */ goto unimplemented;
12294 case 0xb348: /* KXBR */ goto unimplemented;
12295 case 0xb349: s390_format_RRE_FF(s390_irgen_CXBR, ovl.fmt.RRE.r1,
12296 ovl.fmt.RRE.r2); goto ok;
12297 case 0xb34a: s390_format_RRE_FF(s390_irgen_AXBR, ovl.fmt.RRE.r1,
12298 ovl.fmt.RRE.r2); goto ok;
12299 case 0xb34b: s390_format_RRE_FF(s390_irgen_SXBR, ovl.fmt.RRE.r1,
12300 ovl.fmt.RRE.r2); goto ok;
12301 case 0xb34c: s390_format_RRE_FF(s390_irgen_MXBR, ovl.fmt.RRE.r1,
12302 ovl.fmt.RRE.r2); goto ok;
12303 case 0xb34d: s390_format_RRE_FF(s390_irgen_DXBR, ovl.fmt.RRE.r1,
12304 ovl.fmt.RRE.r2); goto ok;
12305 case 0xb350: /* TBEDR */ goto unimplemented;
12306 case 0xb351: /* TBDR */ goto unimplemented;
12307 case 0xb353: /* DIEBR */ goto unimplemented;
12308 case 0xb357: /* FIEBR */ goto unimplemented;
12309 case 0xb358: /* THDER */ goto unimplemented;
12310 case 0xb359: /* THDR */ goto unimplemented;
12311 case 0xb35b: /* DIDBR */ goto unimplemented;
12312 case 0xb35f: /* FIDBR */ goto unimplemented;
12313 case 0xb360: /* LPXR */ goto unimplemented;
12314 case 0xb361: /* LNXR */ goto unimplemented;
12315 case 0xb362: /* LTXR */ goto unimplemented;
12316 case 0xb363: /* LCXR */ goto unimplemented;
12317 case 0xb365: s390_format_RRE_FF(s390_irgen_LXR, ovl.fmt.RRE.r1,
12318 ovl.fmt.RRE.r2); goto ok;
12319 case 0xb366: /* LEXR */ goto unimplemented;
12320 case 0xb367: /* FIXR */ goto unimplemented;
12321 case 0xb369: /* CXR */ goto unimplemented;
12322 case 0xb370: s390_format_RRE_FF(s390_irgen_LPDFR, ovl.fmt.RRE.r1,
12323 ovl.fmt.RRE.r2); goto ok;
12324 case 0xb371: s390_format_RRE_FF(s390_irgen_LNDFR, ovl.fmt.RRE.r1,
12325 ovl.fmt.RRE.r2); goto ok;
12326 case 0xb372: s390_format_RRF_F0FF2(s390_irgen_CPSDR, ovl.fmt.RRF3.r3,
12327 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
12328 goto ok;
12329 case 0xb373: s390_format_RRE_FF(s390_irgen_LCDFR, ovl.fmt.RRE.r1,
12330 ovl.fmt.RRE.r2); goto ok;
12331 case 0xb374: s390_format_RRE_F0(s390_irgen_LZER, ovl.fmt.RRE.r1); goto ok;
12332 case 0xb375: s390_format_RRE_F0(s390_irgen_LZDR, ovl.fmt.RRE.r1); goto ok;
12333 case 0xb376: s390_format_RRE_F0(s390_irgen_LZXR, ovl.fmt.RRE.r1); goto ok;
12334 case 0xb377: /* FIER */ goto unimplemented;
12335 case 0xb37f: /* FIDR */ goto unimplemented;
12336 case 0xb384: s390_format_RRE_R0(s390_irgen_SFPC, ovl.fmt.RRE.r1); goto ok;
12337 case 0xb385: /* SFASR */ goto unimplemented;
12338 case 0xb38c: s390_format_RRE_R0(s390_irgen_EFPC, ovl.fmt.RRE.r1); goto ok;
12339 case 0xb390: /* CELFBR */ goto unimplemented;
12340 case 0xb391: /* CDLFBR */ goto unimplemented;
12341 case 0xb392: /* CXLFBR */ goto unimplemented;
12342 case 0xb394: s390_format_RRE_FR(s390_irgen_CEFBR, ovl.fmt.RRE.r1,
12343 ovl.fmt.RRE.r2); goto ok;
12344 case 0xb395: s390_format_RRE_FR(s390_irgen_CDFBR, ovl.fmt.RRE.r1,
12345 ovl.fmt.RRE.r2); goto ok;
12346 case 0xb396: s390_format_RRE_FR(s390_irgen_CXFBR, ovl.fmt.RRE.r1,
12347 ovl.fmt.RRE.r2); goto ok;
12348 case 0xb398: s390_format_RRF_U0RF(s390_irgen_CFEBR, ovl.fmt.RRF3.r3,
12349 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
12350 goto ok;
12351 case 0xb399: s390_format_RRF_U0RF(s390_irgen_CFDBR, ovl.fmt.RRF3.r3,
12352 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
12353 goto ok;
12354 case 0xb39a: s390_format_RRF_U0RF(s390_irgen_CFXBR, ovl.fmt.RRF3.r3,
12355 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
12356 goto ok;
12357 case 0xb3a0: /* CELGBR */ goto unimplemented;
12358 case 0xb3a1: /* CDLGBR */ goto unimplemented;
12359 case 0xb3a2: /* CXLGBR */ goto unimplemented;
12360 case 0xb3a4: s390_format_RRE_FR(s390_irgen_CEGBR, ovl.fmt.RRE.r1,
12361 ovl.fmt.RRE.r2); goto ok;
12362 case 0xb3a5: s390_format_RRE_FR(s390_irgen_CDGBR, ovl.fmt.RRE.r1,
12363 ovl.fmt.RRE.r2); goto ok;
12364 case 0xb3a6: s390_format_RRE_FR(s390_irgen_CXGBR, ovl.fmt.RRE.r1,
12365 ovl.fmt.RRE.r2); goto ok;
12366 case 0xb3a8: s390_format_RRF_U0RF(s390_irgen_CGEBR, ovl.fmt.RRF3.r3,
12367 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
12368 goto ok;
12369 case 0xb3a9: s390_format_RRF_U0RF(s390_irgen_CGDBR, ovl.fmt.RRF3.r3,
12370 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
12371 goto ok;
12372 case 0xb3aa: s390_format_RRF_U0RF(s390_irgen_CGXBR, ovl.fmt.RRF3.r3,
12373 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
12374 goto ok;
12375 case 0xb3b4: /* CEFR */ goto unimplemented;
12376 case 0xb3b5: /* CDFR */ goto unimplemented;
12377 case 0xb3b6: /* CXFR */ goto unimplemented;
12378 case 0xb3b8: /* CFER */ goto unimplemented;
12379 case 0xb3b9: /* CFDR */ goto unimplemented;
12380 case 0xb3ba: /* CFXR */ goto unimplemented;
12381 case 0xb3c1: s390_format_RRE_FR(s390_irgen_LDGR, ovl.fmt.RRE.r1,
12382 ovl.fmt.RRE.r2); goto ok;
12383 case 0xb3c4: /* CEGR */ goto unimplemented;
12384 case 0xb3c5: /* CDGR */ goto unimplemented;
12385 case 0xb3c6: /* CXGR */ goto unimplemented;
12386 case 0xb3c8: /* CGER */ goto unimplemented;
12387 case 0xb3c9: /* CGDR */ goto unimplemented;
12388 case 0xb3ca: /* CGXR */ goto unimplemented;
12389 case 0xb3cd: s390_format_RRE_RF(s390_irgen_LGDR, ovl.fmt.RRE.r1,
12390 ovl.fmt.RRE.r2); goto ok;
12391 case 0xb3d0: /* MDTR */ goto unimplemented;
12392 case 0xb3d1: /* DDTR */ goto unimplemented;
12393 case 0xb3d2: /* ADTR */ goto unimplemented;
12394 case 0xb3d3: /* SDTR */ goto unimplemented;
12395 case 0xb3d4: /* LDETR */ goto unimplemented;
12396 case 0xb3d5: /* LEDTR */ goto unimplemented;
12397 case 0xb3d6: /* LTDTR */ goto unimplemented;
12398 case 0xb3d7: /* FIDTR */ goto unimplemented;
12399 case 0xb3d8: /* MXTR */ goto unimplemented;
12400 case 0xb3d9: /* DXTR */ goto unimplemented;
12401 case 0xb3da: /* AXTR */ goto unimplemented;
12402 case 0xb3db: /* SXTR */ goto unimplemented;
12403 case 0xb3dc: /* LXDTR */ goto unimplemented;
12404 case 0xb3dd: /* LDXTR */ goto unimplemented;
12405 case 0xb3de: /* LTXTR */ goto unimplemented;
12406 case 0xb3df: /* FIXTR */ goto unimplemented;
12407 case 0xb3e0: /* KDTR */ goto unimplemented;
12408 case 0xb3e1: /* CGDTR */ goto unimplemented;
12409 case 0xb3e2: /* CUDTR */ goto unimplemented;
12410 case 0xb3e3: /* CSDTR */ goto unimplemented;
12411 case 0xb3e4: /* CDTR */ goto unimplemented;
12412 case 0xb3e5: /* EEDTR */ goto unimplemented;
12413 case 0xb3e7: /* ESDTR */ goto unimplemented;
12414 case 0xb3e8: /* KXTR */ goto unimplemented;
12415 case 0xb3e9: /* CGXTR */ goto unimplemented;
12416 case 0xb3ea: /* CUXTR */ goto unimplemented;
12417 case 0xb3eb: /* CSXTR */ goto unimplemented;
12418 case 0xb3ec: /* CXTR */ goto unimplemented;
12419 case 0xb3ed: /* EEXTR */ goto unimplemented;
12420 case 0xb3ef: /* ESXTR */ goto unimplemented;
12421 case 0xb3f1: /* CDGTR */ goto unimplemented;
12422 case 0xb3f2: /* CDUTR */ goto unimplemented;
12423 case 0xb3f3: /* CDSTR */ goto unimplemented;
12424 case 0xb3f4: /* CEDTR */ goto unimplemented;
12425 case 0xb3f5: /* QADTR */ goto unimplemented;
12426 case 0xb3f6: /* IEDTR */ goto unimplemented;
12427 case 0xb3f7: /* RRDTR */ goto unimplemented;
12428 case 0xb3f9: /* CXGTR */ goto unimplemented;
12429 case 0xb3fa: /* CXUTR */ goto unimplemented;
12430 case 0xb3fb: /* CXSTR */ goto unimplemented;
12431 case 0xb3fc: /* CEXTR */ goto unimplemented;
12432 case 0xb3fd: /* QAXTR */ goto unimplemented;
12433 case 0xb3fe: /* IEXTR */ goto unimplemented;
12434 case 0xb3ff: /* RRXTR */ goto unimplemented;
12435 case 0xb900: s390_format_RRE_RR(s390_irgen_LPGR, ovl.fmt.RRE.r1,
12436 ovl.fmt.RRE.r2); goto ok;
12437 case 0xb901: s390_format_RRE_RR(s390_irgen_LNGR, ovl.fmt.RRE.r1,
12438 ovl.fmt.RRE.r2); goto ok;
12439 case 0xb902: s390_format_RRE_RR(s390_irgen_LTGR, ovl.fmt.RRE.r1,
12440 ovl.fmt.RRE.r2); goto ok;
12441 case 0xb903: s390_format_RRE_RR(s390_irgen_LCGR, ovl.fmt.RRE.r1,
12442 ovl.fmt.RRE.r2); goto ok;
12443 case 0xb904: s390_format_RRE_RR(s390_irgen_LGR, ovl.fmt.RRE.r1,
12444 ovl.fmt.RRE.r2); goto ok;
12445 case 0xb905: /* LURAG */ goto unimplemented;
12446 case 0xb906: s390_format_RRE_RR(s390_irgen_LGBR, ovl.fmt.RRE.r1,
12447 ovl.fmt.RRE.r2); goto ok;
12448 case 0xb907: s390_format_RRE_RR(s390_irgen_LGHR, ovl.fmt.RRE.r1,
12449 ovl.fmt.RRE.r2); goto ok;
12450 case 0xb908: s390_format_RRE_RR(s390_irgen_AGR, ovl.fmt.RRE.r1,
12451 ovl.fmt.RRE.r2); goto ok;
12452 case 0xb909: s390_format_RRE_RR(s390_irgen_SGR, ovl.fmt.RRE.r1,
12453 ovl.fmt.RRE.r2); goto ok;
12454 case 0xb90a: s390_format_RRE_RR(s390_irgen_ALGR, ovl.fmt.RRE.r1,
12455 ovl.fmt.RRE.r2); goto ok;
12456 case 0xb90b: s390_format_RRE_RR(s390_irgen_SLGR, ovl.fmt.RRE.r1,
12457 ovl.fmt.RRE.r2); goto ok;
12458 case 0xb90c: s390_format_RRE_RR(s390_irgen_MSGR, ovl.fmt.RRE.r1,
12459 ovl.fmt.RRE.r2); goto ok;
12460 case 0xb90d: s390_format_RRE_RR(s390_irgen_DSGR, ovl.fmt.RRE.r1,
12461 ovl.fmt.RRE.r2); goto ok;
12462 case 0xb90e: /* EREGG */ goto unimplemented;
12463 case 0xb90f: s390_format_RRE_RR(s390_irgen_LRVGR, ovl.fmt.RRE.r1,
12464 ovl.fmt.RRE.r2); goto ok;
12465 case 0xb910: s390_format_RRE_RR(s390_irgen_LPGFR, ovl.fmt.RRE.r1,
12466 ovl.fmt.RRE.r2); goto ok;
12467 case 0xb911: s390_format_RRE_RR(s390_irgen_LNGFR, ovl.fmt.RRE.r1,
12468 ovl.fmt.RRE.r2); goto ok;
12469 case 0xb912: s390_format_RRE_RR(s390_irgen_LTGFR, ovl.fmt.RRE.r1,
12470 ovl.fmt.RRE.r2); goto ok;
12471 case 0xb913: s390_format_RRE_RR(s390_irgen_LCGFR, ovl.fmt.RRE.r1,
12472 ovl.fmt.RRE.r2); goto ok;
12473 case 0xb914: s390_format_RRE_RR(s390_irgen_LGFR, ovl.fmt.RRE.r1,
12474 ovl.fmt.RRE.r2); goto ok;
12475 case 0xb916: s390_format_RRE_RR(s390_irgen_LLGFR, ovl.fmt.RRE.r1,
12476 ovl.fmt.RRE.r2); goto ok;
12477 case 0xb917: s390_format_RRE_RR(s390_irgen_LLGTR, ovl.fmt.RRE.r1,
12478 ovl.fmt.RRE.r2); goto ok;
12479 case 0xb918: s390_format_RRE_RR(s390_irgen_AGFR, ovl.fmt.RRE.r1,
12480 ovl.fmt.RRE.r2); goto ok;
12481 case 0xb919: s390_format_RRE_RR(s390_irgen_SGFR, ovl.fmt.RRE.r1,
12482 ovl.fmt.RRE.r2); goto ok;
12483 case 0xb91a: s390_format_RRE_RR(s390_irgen_ALGFR, ovl.fmt.RRE.r1,
12484 ovl.fmt.RRE.r2); goto ok;
12485 case 0xb91b: s390_format_RRE_RR(s390_irgen_SLGFR, ovl.fmt.RRE.r1,
12486 ovl.fmt.RRE.r2); goto ok;
12487 case 0xb91c: s390_format_RRE_RR(s390_irgen_MSGFR, ovl.fmt.RRE.r1,
12488 ovl.fmt.RRE.r2); goto ok;
12489 case 0xb91d: s390_format_RRE_RR(s390_irgen_DSGFR, ovl.fmt.RRE.r1,
12490 ovl.fmt.RRE.r2); goto ok;
12491 case 0xb91e: /* KMAC */ goto unimplemented;
12492 case 0xb91f: s390_format_RRE_RR(s390_irgen_LRVR, ovl.fmt.RRE.r1,
12493 ovl.fmt.RRE.r2); goto ok;
12494 case 0xb920: s390_format_RRE_RR(s390_irgen_CGR, ovl.fmt.RRE.r1,
12495 ovl.fmt.RRE.r2); goto ok;
12496 case 0xb921: s390_format_RRE_RR(s390_irgen_CLGR, ovl.fmt.RRE.r1,
12497 ovl.fmt.RRE.r2); goto ok;
12498 case 0xb925: /* STURG */ goto unimplemented;
12499 case 0xb926: s390_format_RRE_RR(s390_irgen_LBR, ovl.fmt.RRE.r1,
12500 ovl.fmt.RRE.r2); goto ok;
12501 case 0xb927: s390_format_RRE_RR(s390_irgen_LHR, ovl.fmt.RRE.r1,
12502 ovl.fmt.RRE.r2); goto ok;
12503 case 0xb928: /* PCKMO */ goto unimplemented;
12504 case 0xb92b: /* KMO */ goto unimplemented;
12505 case 0xb92c: /* PCC */ goto unimplemented;
12506 case 0xb92d: /* KMCTR */ goto unimplemented;
12507 case 0xb92e: /* KM */ goto unimplemented;
12508 case 0xb92f: /* KMC */ goto unimplemented;
12509 case 0xb930: s390_format_RRE_RR(s390_irgen_CGFR, ovl.fmt.RRE.r1,
12510 ovl.fmt.RRE.r2); goto ok;
12511 case 0xb931: s390_format_RRE_RR(s390_irgen_CLGFR, ovl.fmt.RRE.r1,
12512 ovl.fmt.RRE.r2); goto ok;
12513 case 0xb93e: /* KIMD */ goto unimplemented;
12514 case 0xb93f: /* KLMD */ goto unimplemented;
12515 case 0xb941: /* CFDTR */ goto unimplemented;
12516 case 0xb942: /* CLGDTR */ goto unimplemented;
12517 case 0xb943: /* CLFDTR */ goto unimplemented;
12518 case 0xb946: s390_format_RRE_RR(s390_irgen_BCTGR, ovl.fmt.RRE.r1,
12519 ovl.fmt.RRE.r2); goto ok;
12520 case 0xb949: /* CFXTR */ goto unimplemented;
12521 case 0xb94a: /* CLGXTR */ goto unimplemented;
12522 case 0xb94b: /* CLFXTR */ goto unimplemented;
12523 case 0xb951: /* CDFTR */ goto unimplemented;
12524 case 0xb952: /* CDLGTR */ goto unimplemented;
12525 case 0xb953: /* CDLFTR */ goto unimplemented;
12526 case 0xb959: /* CXFTR */ goto unimplemented;
12527 case 0xb95a: /* CXLGTR */ goto unimplemented;
12528 case 0xb95b: /* CXLFTR */ goto unimplemented;
12529 case 0xb960: /* CGRT */ goto unimplemented;
12530 case 0xb961: /* CLGRT */ goto unimplemented;
12531 case 0xb972: /* CRT */ goto unimplemented;
12532 case 0xb973: /* CLRT */ goto unimplemented;
12533 case 0xb980: s390_format_RRE_RR(s390_irgen_NGR, ovl.fmt.RRE.r1,
12534 ovl.fmt.RRE.r2); goto ok;
12535 case 0xb981: s390_format_RRE_RR(s390_irgen_OGR, ovl.fmt.RRE.r1,
12536 ovl.fmt.RRE.r2); goto ok;
12537 case 0xb982: s390_format_RRE_RR(s390_irgen_XGR, ovl.fmt.RRE.r1,
12538 ovl.fmt.RRE.r2); goto ok;
12539 case 0xb983: s390_format_RRE_RR(s390_irgen_FLOGR, ovl.fmt.RRE.r1,
12540 ovl.fmt.RRE.r2); goto ok;
12541 case 0xb984: s390_format_RRE_RR(s390_irgen_LLGCR, ovl.fmt.RRE.r1,
12542 ovl.fmt.RRE.r2); goto ok;
12543 case 0xb985: s390_format_RRE_RR(s390_irgen_LLGHR, ovl.fmt.RRE.r1,
12544 ovl.fmt.RRE.r2); goto ok;
12545 case 0xb986: s390_format_RRE_RR(s390_irgen_MLGR, ovl.fmt.RRE.r1,
12546 ovl.fmt.RRE.r2); goto ok;
12547 case 0xb987: s390_format_RRE_RR(s390_irgen_DLGR, ovl.fmt.RRE.r1,
12548 ovl.fmt.RRE.r2); goto ok;
12549 case 0xb988: s390_format_RRE_RR(s390_irgen_ALCGR, ovl.fmt.RRE.r1,
12550 ovl.fmt.RRE.r2); goto ok;
12551 case 0xb989: s390_format_RRE_RR(s390_irgen_SLBGR, ovl.fmt.RRE.r1,
12552 ovl.fmt.RRE.r2); goto ok;
12553 case 0xb98a: /* CSPG */ goto unimplemented;
12554 case 0xb98d: /* EPSW */ goto unimplemented;
12555 case 0xb98e: /* IDTE */ goto unimplemented;
florian730448f2012-02-04 17:07:07 +000012556 case 0xb990: s390_format_RRF_M0RERE(s390_irgen_TRTT, ovl.fmt.RRF3.r3,
12557 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
12558 case 0xb991: s390_format_RRF_M0RERE(s390_irgen_TRTO, ovl.fmt.RRF3.r3,
12559 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
12560 case 0xb992: s390_format_RRF_M0RERE(s390_irgen_TROT, ovl.fmt.RRF3.r3,
12561 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
florian9af37692012-01-15 21:01:16 +000012562 case 0xb993: s390_format_RRF_M0RERE(s390_irgen_TROO, ovl.fmt.RRF3.r3,
12563 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000012564 case 0xb994: s390_format_RRE_RR(s390_irgen_LLCR, ovl.fmt.RRE.r1,
12565 ovl.fmt.RRE.r2); goto ok;
12566 case 0xb995: s390_format_RRE_RR(s390_irgen_LLHR, ovl.fmt.RRE.r1,
12567 ovl.fmt.RRE.r2); goto ok;
12568 case 0xb996: s390_format_RRE_RR(s390_irgen_MLR, ovl.fmt.RRE.r1,
12569 ovl.fmt.RRE.r2); goto ok;
12570 case 0xb997: s390_format_RRE_RR(s390_irgen_DLR, ovl.fmt.RRE.r1,
12571 ovl.fmt.RRE.r2); goto ok;
12572 case 0xb998: s390_format_RRE_RR(s390_irgen_ALCR, ovl.fmt.RRE.r1,
12573 ovl.fmt.RRE.r2); goto ok;
12574 case 0xb999: s390_format_RRE_RR(s390_irgen_SLBR, ovl.fmt.RRE.r1,
12575 ovl.fmt.RRE.r2); goto ok;
12576 case 0xb99a: /* EPAIR */ goto unimplemented;
12577 case 0xb99b: /* ESAIR */ goto unimplemented;
12578 case 0xb99d: /* ESEA */ goto unimplemented;
12579 case 0xb99e: /* PTI */ goto unimplemented;
12580 case 0xb99f: /* SSAIR */ goto unimplemented;
12581 case 0xb9a2: /* PTF */ goto unimplemented;
12582 case 0xb9aa: /* LPTEA */ goto unimplemented;
12583 case 0xb9ae: /* RRBM */ goto unimplemented;
12584 case 0xb9af: /* PFMF */ goto unimplemented;
florian3f8a96a2012-08-05 02:59:55 +000012585 case 0xb9b0: s390_format_RRF_M0RERE(s390_irgen_CU14, ovl.fmt.RRF3.r3,
12586 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
12587 goto ok;
florian2a415a12012-07-21 17:41:36 +000012588 case 0xb9b1: s390_format_RRF_M0RERE(s390_irgen_CU24, ovl.fmt.RRF3.r3,
12589 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
12590 goto ok;
florianaf2194f2012-08-06 00:07:54 +000012591 case 0xb9b2: s390_format_RRE_RR(s390_irgen_CU41, ovl.fmt.RRE.r1,
12592 ovl.fmt.RRE.r2); goto ok;
florian956194b2012-07-28 22:18:32 +000012593 case 0xb9b3: s390_format_RRE_RR(s390_irgen_CU42, ovl.fmt.RRE.r1,
12594 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000012595 case 0xb9bd: /* TRTRE */ goto unimplemented;
12596 case 0xb9be: /* SRSTU */ goto unimplemented;
12597 case 0xb9bf: /* TRTE */ goto unimplemented;
12598 case 0xb9c8: s390_format_RRF_R0RR2(s390_irgen_AHHHR, ovl.fmt.RRF4.r3,
12599 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12600 goto ok;
12601 case 0xb9c9: s390_format_RRF_R0RR2(s390_irgen_SHHHR, ovl.fmt.RRF4.r3,
12602 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12603 goto ok;
12604 case 0xb9ca: s390_format_RRF_R0RR2(s390_irgen_ALHHHR, ovl.fmt.RRF4.r3,
12605 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12606 goto ok;
12607 case 0xb9cb: s390_format_RRF_R0RR2(s390_irgen_SLHHHR, ovl.fmt.RRF4.r3,
12608 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12609 goto ok;
12610 case 0xb9cd: s390_format_RRE_RR(s390_irgen_CHHR, ovl.fmt.RRE.r1,
12611 ovl.fmt.RRE.r2); goto ok;
12612 case 0xb9cf: s390_format_RRE_RR(s390_irgen_CLHHR, ovl.fmt.RRE.r1,
12613 ovl.fmt.RRE.r2); goto ok;
12614 case 0xb9d8: s390_format_RRF_R0RR2(s390_irgen_AHHLR, ovl.fmt.RRF4.r3,
12615 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12616 goto ok;
12617 case 0xb9d9: s390_format_RRF_R0RR2(s390_irgen_SHHLR, ovl.fmt.RRF4.r3,
12618 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12619 goto ok;
12620 case 0xb9da: s390_format_RRF_R0RR2(s390_irgen_ALHHLR, ovl.fmt.RRF4.r3,
12621 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12622 goto ok;
12623 case 0xb9db: s390_format_RRF_R0RR2(s390_irgen_SLHHLR, ovl.fmt.RRF4.r3,
12624 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12625 goto ok;
12626 case 0xb9dd: s390_format_RRE_RR(s390_irgen_CHLR, ovl.fmt.RRE.r1,
12627 ovl.fmt.RRE.r2); goto ok;
12628 case 0xb9df: s390_format_RRE_RR(s390_irgen_CLHLR, ovl.fmt.RRE.r1,
12629 ovl.fmt.RRE.r2); goto ok;
12630 case 0xb9e1: /* POPCNT */ goto unimplemented;
sewardjd7bde722011-04-05 13:19:33 +000012631 case 0xb9e2: s390_format_RRF_U0RR(s390_irgen_LOCGR, ovl.fmt.RRF3.r3,
12632 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2,
12633 S390_XMNM_LOCGR); goto ok;
sewardj2019a972011-03-07 16:04:07 +000012634 case 0xb9e4: s390_format_RRF_R0RR2(s390_irgen_NGRK, ovl.fmt.RRF4.r3,
12635 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12636 goto ok;
12637 case 0xb9e6: s390_format_RRF_R0RR2(s390_irgen_OGRK, ovl.fmt.RRF4.r3,
12638 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12639 goto ok;
12640 case 0xb9e7: s390_format_RRF_R0RR2(s390_irgen_XGRK, ovl.fmt.RRF4.r3,
12641 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12642 goto ok;
12643 case 0xb9e8: s390_format_RRF_R0RR2(s390_irgen_AGRK, ovl.fmt.RRF4.r3,
12644 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12645 goto ok;
12646 case 0xb9e9: s390_format_RRF_R0RR2(s390_irgen_SGRK, ovl.fmt.RRF4.r3,
12647 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12648 goto ok;
12649 case 0xb9ea: s390_format_RRF_R0RR2(s390_irgen_ALGRK, ovl.fmt.RRF4.r3,
12650 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12651 goto ok;
12652 case 0xb9eb: s390_format_RRF_R0RR2(s390_irgen_SLGRK, ovl.fmt.RRF4.r3,
12653 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12654 goto ok;
sewardjd7bde722011-04-05 13:19:33 +000012655 case 0xb9f2: s390_format_RRF_U0RR(s390_irgen_LOCR, ovl.fmt.RRF3.r3,
12656 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2,
12657 S390_XMNM_LOCR); goto ok;
sewardj2019a972011-03-07 16:04:07 +000012658 case 0xb9f4: s390_format_RRF_R0RR2(s390_irgen_NRK, ovl.fmt.RRF4.r3,
12659 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12660 goto ok;
12661 case 0xb9f6: s390_format_RRF_R0RR2(s390_irgen_ORK, ovl.fmt.RRF4.r3,
12662 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12663 goto ok;
12664 case 0xb9f7: s390_format_RRF_R0RR2(s390_irgen_XRK, ovl.fmt.RRF4.r3,
12665 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12666 goto ok;
12667 case 0xb9f8: s390_format_RRF_R0RR2(s390_irgen_ARK, ovl.fmt.RRF4.r3,
12668 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12669 goto ok;
12670 case 0xb9f9: s390_format_RRF_R0RR2(s390_irgen_SRK, ovl.fmt.RRF4.r3,
12671 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12672 goto ok;
12673 case 0xb9fa: s390_format_RRF_R0RR2(s390_irgen_ALRK, ovl.fmt.RRF4.r3,
12674 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12675 goto ok;
12676 case 0xb9fb: s390_format_RRF_R0RR2(s390_irgen_SLRK, ovl.fmt.RRF4.r3,
12677 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12678 goto ok;
12679 }
12680
12681 switch ((ovl.value & 0xff000000) >> 24) {
12682 case 0x40: s390_format_RX_RRRD(s390_irgen_STH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12683 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12684 case 0x41: s390_format_RX_RRRD(s390_irgen_LA, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12685 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12686 case 0x42: s390_format_RX_RRRD(s390_irgen_STC, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12687 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12688 case 0x43: s390_format_RX_RRRD(s390_irgen_IC, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12689 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12690 case 0x44: s390_format_RX_RRRD(s390_irgen_EX, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12691 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12692 case 0x45: /* BAL */ goto unimplemented;
12693 case 0x46: s390_format_RX_RRRD(s390_irgen_BCT, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12694 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12695 case 0x47: s390_format_RX(s390_irgen_BC, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12696 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12697 case 0x48: s390_format_RX_RRRD(s390_irgen_LH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12698 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12699 case 0x49: s390_format_RX_RRRD(s390_irgen_CH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12700 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12701 case 0x4a: s390_format_RX_RRRD(s390_irgen_AH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12702 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12703 case 0x4b: s390_format_RX_RRRD(s390_irgen_SH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12704 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12705 case 0x4c: s390_format_RX_RRRD(s390_irgen_MH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12706 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12707 case 0x4d: s390_format_RX_RRRD(s390_irgen_BAS, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12708 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12709 case 0x4e: s390_format_RX_RRRD(s390_irgen_CVD, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12710 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12711 case 0x4f: s390_format_RX_RRRD(s390_irgen_CVB, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12712 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12713 case 0x50: s390_format_RX_RRRD(s390_irgen_ST, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12714 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12715 case 0x51: s390_format_RX_RRRD(s390_irgen_LAE, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12716 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12717 case 0x54: s390_format_RX_RRRD(s390_irgen_N, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12718 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12719 case 0x55: s390_format_RX_RRRD(s390_irgen_CL, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12720 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12721 case 0x56: s390_format_RX_RRRD(s390_irgen_O, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12722 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12723 case 0x57: s390_format_RX_RRRD(s390_irgen_X, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12724 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12725 case 0x58: s390_format_RX_RRRD(s390_irgen_L, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12726 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12727 case 0x59: s390_format_RX_RRRD(s390_irgen_C, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12728 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12729 case 0x5a: s390_format_RX_RRRD(s390_irgen_A, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12730 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12731 case 0x5b: s390_format_RX_RRRD(s390_irgen_S, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12732 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12733 case 0x5c: s390_format_RX_RRRD(s390_irgen_M, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12734 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12735 case 0x5d: s390_format_RX_RRRD(s390_irgen_D, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12736 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12737 case 0x5e: s390_format_RX_RRRD(s390_irgen_AL, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12738 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12739 case 0x5f: s390_format_RX_RRRD(s390_irgen_SL, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12740 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12741 case 0x60: s390_format_RX_FRRD(s390_irgen_STD, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12742 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12743 case 0x67: /* MXD */ goto unimplemented;
12744 case 0x68: s390_format_RX_FRRD(s390_irgen_LD, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12745 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12746 case 0x69: /* CD */ goto unimplemented;
12747 case 0x6a: /* AD */ goto unimplemented;
12748 case 0x6b: /* SD */ goto unimplemented;
12749 case 0x6c: /* MD */ goto unimplemented;
12750 case 0x6d: /* DD */ goto unimplemented;
12751 case 0x6e: /* AW */ goto unimplemented;
12752 case 0x6f: /* SW */ goto unimplemented;
12753 case 0x70: s390_format_RX_FRRD(s390_irgen_STE, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12754 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12755 case 0x71: s390_format_RX_RRRD(s390_irgen_MS, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12756 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12757 case 0x78: s390_format_RX_FRRD(s390_irgen_LE, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12758 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12759 case 0x79: /* CE */ goto unimplemented;
12760 case 0x7a: /* AE */ goto unimplemented;
12761 case 0x7b: /* SE */ goto unimplemented;
12762 case 0x7c: /* MDE */ goto unimplemented;
12763 case 0x7d: /* DE */ goto unimplemented;
12764 case 0x7e: /* AU */ goto unimplemented;
12765 case 0x7f: /* SU */ goto unimplemented;
12766 case 0x83: /* DIAG */ goto unimplemented;
12767 case 0x84: s390_format_RSI_RRP(s390_irgen_BRXH, ovl.fmt.RSI.r1,
12768 ovl.fmt.RSI.r3, ovl.fmt.RSI.i2); goto ok;
12769 case 0x85: s390_format_RSI_RRP(s390_irgen_BRXLE, ovl.fmt.RSI.r1,
12770 ovl.fmt.RSI.r3, ovl.fmt.RSI.i2); goto ok;
12771 case 0x86: s390_format_RS_RRRD(s390_irgen_BXH, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
12772 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
12773 case 0x87: s390_format_RS_RRRD(s390_irgen_BXLE, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
12774 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
12775 case 0x88: s390_format_RS_R0RD(s390_irgen_SRL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
12776 ovl.fmt.RS.d2); goto ok;
12777 case 0x89: s390_format_RS_R0RD(s390_irgen_SLL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
12778 ovl.fmt.RS.d2); goto ok;
12779 case 0x8a: s390_format_RS_R0RD(s390_irgen_SRA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
12780 ovl.fmt.RS.d2); goto ok;
12781 case 0x8b: s390_format_RS_R0RD(s390_irgen_SLA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
12782 ovl.fmt.RS.d2); goto ok;
12783 case 0x8c: s390_format_RS_R0RD(s390_irgen_SRDL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
12784 ovl.fmt.RS.d2); goto ok;
12785 case 0x8d: s390_format_RS_R0RD(s390_irgen_SLDL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
12786 ovl.fmt.RS.d2); goto ok;
12787 case 0x8e: s390_format_RS_R0RD(s390_irgen_SRDA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
12788 ovl.fmt.RS.d2); goto ok;
12789 case 0x8f: s390_format_RS_R0RD(s390_irgen_SLDA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
12790 ovl.fmt.RS.d2); goto ok;
12791 case 0x90: s390_format_RS_RRRD(s390_irgen_STM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
12792 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
12793 case 0x91: s390_format_SI_URD(s390_irgen_TM, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
12794 ovl.fmt.SI.d1); goto ok;
12795 case 0x92: s390_format_SI_URD(s390_irgen_MVI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
12796 ovl.fmt.SI.d1); goto ok;
12797 case 0x94: s390_format_SI_URD(s390_irgen_NI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
12798 ovl.fmt.SI.d1); goto ok;
12799 case 0x95: s390_format_SI_URD(s390_irgen_CLI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
12800 ovl.fmt.SI.d1); goto ok;
12801 case 0x96: s390_format_SI_URD(s390_irgen_OI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
12802 ovl.fmt.SI.d1); goto ok;
12803 case 0x97: s390_format_SI_URD(s390_irgen_XI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
12804 ovl.fmt.SI.d1); goto ok;
12805 case 0x98: s390_format_RS_RRRD(s390_irgen_LM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
12806 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
12807 case 0x99: /* TRACE */ goto unimplemented;
12808 case 0x9a: s390_format_RS_AARD(s390_irgen_LAM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
12809 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
12810 case 0x9b: s390_format_RS_AARD(s390_irgen_STAM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
12811 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
12812 case 0xa8: s390_format_RS_RRRD(s390_irgen_MVCLE, ovl.fmt.RS.r1,
12813 ovl.fmt.RS.r3, ovl.fmt.RS.b2, ovl.fmt.RS.d2);
12814 goto ok;
12815 case 0xa9: s390_format_RS_RRRD(s390_irgen_CLCLE, ovl.fmt.RS.r1,
12816 ovl.fmt.RS.r3, ovl.fmt.RS.b2, ovl.fmt.RS.d2);
12817 goto ok;
12818 case 0xac: /* STNSM */ goto unimplemented;
12819 case 0xad: /* STOSM */ goto unimplemented;
12820 case 0xae: /* SIGP */ goto unimplemented;
12821 case 0xaf: /* MC */ goto unimplemented;
12822 case 0xb1: /* LRA */ goto unimplemented;
12823 case 0xb6: /* STCTL */ goto unimplemented;
12824 case 0xb7: /* LCTL */ goto unimplemented;
12825 case 0xba: s390_format_RS_RRRD(s390_irgen_CS, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
12826 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
florian448cbba2012-06-06 02:26:01 +000012827 case 0xbb: s390_format_RS_RRRD(s390_irgen_CDS, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
12828 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000012829 case 0xbd: s390_format_RS_RURD(s390_irgen_CLM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
12830 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
12831 case 0xbe: s390_format_RS_RURD(s390_irgen_STCM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
12832 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
12833 case 0xbf: s390_format_RS_RURD(s390_irgen_ICM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
12834 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
12835 }
12836
12837 return S390_DECODE_UNKNOWN_INSN;
12838
12839ok:
12840 return S390_DECODE_OK;
12841
12842unimplemented:
12843 return S390_DECODE_UNIMPLEMENTED_INSN;
12844}
12845
12846static s390_decode_t
12847s390_decode_6byte_and_irgen(UChar *bytes)
12848{
12849 typedef union {
12850 struct {
12851 unsigned int op1 : 8;
12852 unsigned int r1 : 4;
12853 unsigned int r3 : 4;
12854 unsigned int i2 : 16;
12855 unsigned int : 8;
12856 unsigned int op2 : 8;
12857 } RIE;
12858 struct {
12859 unsigned int op1 : 8;
12860 unsigned int r1 : 4;
12861 unsigned int r2 : 4;
12862 unsigned int i3 : 8;
12863 unsigned int i4 : 8;
12864 unsigned int i5 : 8;
12865 unsigned int op2 : 8;
12866 } RIE_RRUUU;
12867 struct {
12868 unsigned int op1 : 8;
12869 unsigned int r1 : 4;
12870 unsigned int : 4;
12871 unsigned int i2 : 16;
12872 unsigned int m3 : 4;
12873 unsigned int : 4;
12874 unsigned int op2 : 8;
12875 } RIEv1;
12876 struct {
12877 unsigned int op1 : 8;
12878 unsigned int r1 : 4;
12879 unsigned int r2 : 4;
12880 unsigned int i4 : 16;
12881 unsigned int m3 : 4;
12882 unsigned int : 4;
12883 unsigned int op2 : 8;
12884 } RIE_RRPU;
12885 struct {
12886 unsigned int op1 : 8;
12887 unsigned int r1 : 4;
12888 unsigned int m3 : 4;
12889 unsigned int i4 : 16;
12890 unsigned int i2 : 8;
12891 unsigned int op2 : 8;
12892 } RIEv3;
12893 struct {
12894 unsigned int op1 : 8;
12895 unsigned int r1 : 4;
12896 unsigned int op2 : 4;
12897 unsigned int i2 : 32;
12898 } RIL;
12899 struct {
12900 unsigned int op1 : 8;
12901 unsigned int r1 : 4;
12902 unsigned int m3 : 4;
12903 unsigned int b4 : 4;
12904 unsigned int d4 : 12;
12905 unsigned int i2 : 8;
12906 unsigned int op2 : 8;
12907 } RIS;
12908 struct {
12909 unsigned int op1 : 8;
12910 unsigned int r1 : 4;
12911 unsigned int r2 : 4;
12912 unsigned int b4 : 4;
12913 unsigned int d4 : 12;
12914 unsigned int m3 : 4;
12915 unsigned int : 4;
12916 unsigned int op2 : 8;
12917 } RRS;
12918 struct {
12919 unsigned int op1 : 8;
12920 unsigned int l1 : 4;
12921 unsigned int : 4;
12922 unsigned int b1 : 4;
12923 unsigned int d1 : 12;
12924 unsigned int : 8;
12925 unsigned int op2 : 8;
12926 } RSL;
12927 struct {
12928 unsigned int op1 : 8;
12929 unsigned int r1 : 4;
12930 unsigned int r3 : 4;
12931 unsigned int b2 : 4;
12932 unsigned int dl2 : 12;
12933 unsigned int dh2 : 8;
12934 unsigned int op2 : 8;
12935 } RSY;
12936 struct {
12937 unsigned int op1 : 8;
12938 unsigned int r1 : 4;
12939 unsigned int x2 : 4;
12940 unsigned int b2 : 4;
12941 unsigned int d2 : 12;
12942 unsigned int : 8;
12943 unsigned int op2 : 8;
12944 } RXE;
12945 struct {
12946 unsigned int op1 : 8;
12947 unsigned int r3 : 4;
12948 unsigned int x2 : 4;
12949 unsigned int b2 : 4;
12950 unsigned int d2 : 12;
12951 unsigned int r1 : 4;
12952 unsigned int : 4;
12953 unsigned int op2 : 8;
12954 } RXF;
12955 struct {
12956 unsigned int op1 : 8;
12957 unsigned int r1 : 4;
12958 unsigned int x2 : 4;
12959 unsigned int b2 : 4;
12960 unsigned int dl2 : 12;
12961 unsigned int dh2 : 8;
12962 unsigned int op2 : 8;
12963 } RXY;
12964 struct {
12965 unsigned int op1 : 8;
12966 unsigned int i2 : 8;
12967 unsigned int b1 : 4;
12968 unsigned int dl1 : 12;
12969 unsigned int dh1 : 8;
12970 unsigned int op2 : 8;
12971 } SIY;
12972 struct {
12973 unsigned int op : 8;
12974 unsigned int l : 8;
12975 unsigned int b1 : 4;
12976 unsigned int d1 : 12;
12977 unsigned int b2 : 4;
12978 unsigned int d2 : 12;
12979 } SS;
12980 struct {
12981 unsigned int op : 8;
12982 unsigned int l1 : 4;
12983 unsigned int l2 : 4;
12984 unsigned int b1 : 4;
12985 unsigned int d1 : 12;
12986 unsigned int b2 : 4;
12987 unsigned int d2 : 12;
12988 } SS_LLRDRD;
12989 struct {
12990 unsigned int op : 8;
12991 unsigned int r1 : 4;
12992 unsigned int r3 : 4;
12993 unsigned int b2 : 4;
12994 unsigned int d2 : 12;
12995 unsigned int b4 : 4;
12996 unsigned int d4 : 12;
12997 } SS_RRRDRD2;
12998 struct {
12999 unsigned int op : 16;
13000 unsigned int b1 : 4;
13001 unsigned int d1 : 12;
13002 unsigned int b2 : 4;
13003 unsigned int d2 : 12;
13004 } SSE;
13005 struct {
13006 unsigned int op1 : 8;
13007 unsigned int r3 : 4;
13008 unsigned int op2 : 4;
13009 unsigned int b1 : 4;
13010 unsigned int d1 : 12;
13011 unsigned int b2 : 4;
13012 unsigned int d2 : 12;
13013 } SSF;
13014 struct {
13015 unsigned int op : 16;
13016 unsigned int b1 : 4;
13017 unsigned int d1 : 12;
13018 unsigned int i2 : 16;
13019 } SIL;
13020 } formats;
13021 union {
13022 formats fmt;
13023 ULong value;
13024 } ovl;
13025
13026 vassert(sizeof(formats) == 6);
13027
13028 ((char *)(&ovl.value))[0] = bytes[0];
13029 ((char *)(&ovl.value))[1] = bytes[1];
13030 ((char *)(&ovl.value))[2] = bytes[2];
13031 ((char *)(&ovl.value))[3] = bytes[3];
13032 ((char *)(&ovl.value))[4] = bytes[4];
13033 ((char *)(&ovl.value))[5] = bytes[5];
13034 ((char *)(&ovl.value))[6] = 0x0;
13035 ((char *)(&ovl.value))[7] = 0x0;
13036
13037 switch ((ovl.value >> 16) & 0xff00000000ffULL) {
13038 case 0xe30000000002ULL: s390_format_RXY_RRRD(s390_irgen_LTG, ovl.fmt.RXY.r1,
13039 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13040 ovl.fmt.RXY.dl2,
13041 ovl.fmt.RXY.dh2); goto ok;
13042 case 0xe30000000003ULL: /* LRAG */ goto unimplemented;
13043 case 0xe30000000004ULL: s390_format_RXY_RRRD(s390_irgen_LG, ovl.fmt.RXY.r1,
13044 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13045 ovl.fmt.RXY.dl2,
13046 ovl.fmt.RXY.dh2); goto ok;
13047 case 0xe30000000006ULL: s390_format_RXY_RRRD(s390_irgen_CVBY, ovl.fmt.RXY.r1,
13048 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13049 ovl.fmt.RXY.dl2,
13050 ovl.fmt.RXY.dh2); goto ok;
13051 case 0xe30000000008ULL: s390_format_RXY_RRRD(s390_irgen_AG, ovl.fmt.RXY.r1,
13052 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13053 ovl.fmt.RXY.dl2,
13054 ovl.fmt.RXY.dh2); goto ok;
13055 case 0xe30000000009ULL: s390_format_RXY_RRRD(s390_irgen_SG, ovl.fmt.RXY.r1,
13056 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13057 ovl.fmt.RXY.dl2,
13058 ovl.fmt.RXY.dh2); goto ok;
13059 case 0xe3000000000aULL: s390_format_RXY_RRRD(s390_irgen_ALG, ovl.fmt.RXY.r1,
13060 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13061 ovl.fmt.RXY.dl2,
13062 ovl.fmt.RXY.dh2); goto ok;
13063 case 0xe3000000000bULL: s390_format_RXY_RRRD(s390_irgen_SLG, ovl.fmt.RXY.r1,
13064 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13065 ovl.fmt.RXY.dl2,
13066 ovl.fmt.RXY.dh2); goto ok;
13067 case 0xe3000000000cULL: s390_format_RXY_RRRD(s390_irgen_MSG, ovl.fmt.RXY.r1,
13068 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13069 ovl.fmt.RXY.dl2,
13070 ovl.fmt.RXY.dh2); goto ok;
13071 case 0xe3000000000dULL: s390_format_RXY_RRRD(s390_irgen_DSG, ovl.fmt.RXY.r1,
13072 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13073 ovl.fmt.RXY.dl2,
13074 ovl.fmt.RXY.dh2); goto ok;
13075 case 0xe3000000000eULL: /* CVBG */ goto unimplemented;
13076 case 0xe3000000000fULL: s390_format_RXY_RRRD(s390_irgen_LRVG, ovl.fmt.RXY.r1,
13077 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13078 ovl.fmt.RXY.dl2,
13079 ovl.fmt.RXY.dh2); goto ok;
13080 case 0xe30000000012ULL: s390_format_RXY_RRRD(s390_irgen_LT, ovl.fmt.RXY.r1,
13081 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13082 ovl.fmt.RXY.dl2,
13083 ovl.fmt.RXY.dh2); goto ok;
13084 case 0xe30000000013ULL: /* LRAY */ goto unimplemented;
13085 case 0xe30000000014ULL: s390_format_RXY_RRRD(s390_irgen_LGF, ovl.fmt.RXY.r1,
13086 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13087 ovl.fmt.RXY.dl2,
13088 ovl.fmt.RXY.dh2); goto ok;
13089 case 0xe30000000015ULL: s390_format_RXY_RRRD(s390_irgen_LGH, ovl.fmt.RXY.r1,
13090 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13091 ovl.fmt.RXY.dl2,
13092 ovl.fmt.RXY.dh2); goto ok;
13093 case 0xe30000000016ULL: s390_format_RXY_RRRD(s390_irgen_LLGF, ovl.fmt.RXY.r1,
13094 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13095 ovl.fmt.RXY.dl2,
13096 ovl.fmt.RXY.dh2); goto ok;
13097 case 0xe30000000017ULL: s390_format_RXY_RRRD(s390_irgen_LLGT, ovl.fmt.RXY.r1,
13098 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13099 ovl.fmt.RXY.dl2,
13100 ovl.fmt.RXY.dh2); goto ok;
13101 case 0xe30000000018ULL: s390_format_RXY_RRRD(s390_irgen_AGF, ovl.fmt.RXY.r1,
13102 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13103 ovl.fmt.RXY.dl2,
13104 ovl.fmt.RXY.dh2); goto ok;
13105 case 0xe30000000019ULL: s390_format_RXY_RRRD(s390_irgen_SGF, ovl.fmt.RXY.r1,
13106 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13107 ovl.fmt.RXY.dl2,
13108 ovl.fmt.RXY.dh2); goto ok;
13109 case 0xe3000000001aULL: s390_format_RXY_RRRD(s390_irgen_ALGF, ovl.fmt.RXY.r1,
13110 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13111 ovl.fmt.RXY.dl2,
13112 ovl.fmt.RXY.dh2); goto ok;
13113 case 0xe3000000001bULL: s390_format_RXY_RRRD(s390_irgen_SLGF, ovl.fmt.RXY.r1,
13114 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13115 ovl.fmt.RXY.dl2,
13116 ovl.fmt.RXY.dh2); goto ok;
13117 case 0xe3000000001cULL: s390_format_RXY_RRRD(s390_irgen_MSGF, ovl.fmt.RXY.r1,
13118 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13119 ovl.fmt.RXY.dl2,
13120 ovl.fmt.RXY.dh2); goto ok;
13121 case 0xe3000000001dULL: s390_format_RXY_RRRD(s390_irgen_DSGF, ovl.fmt.RXY.r1,
13122 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13123 ovl.fmt.RXY.dl2,
13124 ovl.fmt.RXY.dh2); goto ok;
13125 case 0xe3000000001eULL: s390_format_RXY_RRRD(s390_irgen_LRV, ovl.fmt.RXY.r1,
13126 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13127 ovl.fmt.RXY.dl2,
13128 ovl.fmt.RXY.dh2); goto ok;
13129 case 0xe3000000001fULL: s390_format_RXY_RRRD(s390_irgen_LRVH, ovl.fmt.RXY.r1,
13130 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13131 ovl.fmt.RXY.dl2,
13132 ovl.fmt.RXY.dh2); goto ok;
13133 case 0xe30000000020ULL: s390_format_RXY_RRRD(s390_irgen_CG, ovl.fmt.RXY.r1,
13134 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13135 ovl.fmt.RXY.dl2,
13136 ovl.fmt.RXY.dh2); goto ok;
13137 case 0xe30000000021ULL: s390_format_RXY_RRRD(s390_irgen_CLG, ovl.fmt.RXY.r1,
13138 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13139 ovl.fmt.RXY.dl2,
13140 ovl.fmt.RXY.dh2); goto ok;
13141 case 0xe30000000024ULL: s390_format_RXY_RRRD(s390_irgen_STG, ovl.fmt.RXY.r1,
13142 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13143 ovl.fmt.RXY.dl2,
13144 ovl.fmt.RXY.dh2); goto ok;
13145 case 0xe30000000026ULL: s390_format_RXY_RRRD(s390_irgen_CVDY, ovl.fmt.RXY.r1,
13146 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13147 ovl.fmt.RXY.dl2,
13148 ovl.fmt.RXY.dh2); goto ok;
13149 case 0xe3000000002eULL: /* CVDG */ goto unimplemented;
13150 case 0xe3000000002fULL: s390_format_RXY_RRRD(s390_irgen_STRVG,
13151 ovl.fmt.RXY.r1, ovl.fmt.RXY.x2,
13152 ovl.fmt.RXY.b2, ovl.fmt.RXY.dl2,
13153 ovl.fmt.RXY.dh2); goto ok;
13154 case 0xe30000000030ULL: s390_format_RXY_RRRD(s390_irgen_CGF, 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 0xe30000000031ULL: s390_format_RXY_RRRD(s390_irgen_CLGF, 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 0xe30000000032ULL: s390_format_RXY_RRRD(s390_irgen_LTGF, 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 0xe30000000034ULL: s390_format_RXY_RRRD(s390_irgen_CGH, 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 0xe30000000036ULL: s390_format_RXY_URRD(s390_irgen_PFD, 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 0xe3000000003eULL: s390_format_RXY_RRRD(s390_irgen_STRV, 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 0xe3000000003fULL: s390_format_RXY_RRRD(s390_irgen_STRVH,
13179 ovl.fmt.RXY.r1, ovl.fmt.RXY.x2,
13180 ovl.fmt.RXY.b2, ovl.fmt.RXY.dl2,
13181 ovl.fmt.RXY.dh2); goto ok;
13182 case 0xe30000000046ULL: s390_format_RXY_RRRD(s390_irgen_BCTG, 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 0xe30000000050ULL: s390_format_RXY_RRRD(s390_irgen_STY, 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 0xe30000000051ULL: s390_format_RXY_RRRD(s390_irgen_MSY, 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 0xe30000000054ULL: s390_format_RXY_RRRD(s390_irgen_NY, 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 0xe30000000055ULL: s390_format_RXY_RRRD(s390_irgen_CLY, 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 0xe30000000056ULL: s390_format_RXY_RRRD(s390_irgen_OY, 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 0xe30000000057ULL: s390_format_RXY_RRRD(s390_irgen_XY, 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 0xe30000000058ULL: s390_format_RXY_RRRD(s390_irgen_LY, 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 0xe30000000059ULL: s390_format_RXY_RRRD(s390_irgen_CY, 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 0xe3000000005aULL: s390_format_RXY_RRRD(s390_irgen_AY, 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 0xe3000000005bULL: s390_format_RXY_RRRD(s390_irgen_SY, 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 0xe3000000005cULL: s390_format_RXY_RRRD(s390_irgen_MFY, 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 0xe3000000005eULL: s390_format_RXY_RRRD(s390_irgen_ALY, 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 0xe3000000005fULL: s390_format_RXY_RRRD(s390_irgen_SLY, 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 0xe30000000070ULL: s390_format_RXY_RRRD(s390_irgen_STHY, 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 0xe30000000071ULL: s390_format_RXY_RRRD(s390_irgen_LAY, 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 0xe30000000072ULL: s390_format_RXY_RRRD(s390_irgen_STCY, 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 0xe30000000073ULL: s390_format_RXY_RRRD(s390_irgen_ICY, 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 0xe30000000075ULL: s390_format_RXY_RRRD(s390_irgen_LAEY, 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 0xe30000000076ULL: s390_format_RXY_RRRD(s390_irgen_LB, 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 0xe30000000077ULL: s390_format_RXY_RRRD(s390_irgen_LGB, 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 0xe30000000078ULL: s390_format_RXY_RRRD(s390_irgen_LHY, 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 0xe30000000079ULL: s390_format_RXY_RRRD(s390_irgen_CHY, 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 0xe3000000007aULL: s390_format_RXY_RRRD(s390_irgen_AHY, 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 0xe3000000007bULL: s390_format_RXY_RRRD(s390_irgen_SHY, 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 0xe3000000007cULL: s390_format_RXY_RRRD(s390_irgen_MHY, 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 0xe30000000080ULL: s390_format_RXY_RRRD(s390_irgen_NG, 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 0xe30000000081ULL: s390_format_RXY_RRRD(s390_irgen_OG, 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 0xe30000000082ULL: s390_format_RXY_RRRD(s390_irgen_XG, 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 0xe30000000086ULL: s390_format_RXY_RRRD(s390_irgen_MLG, 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 0xe30000000087ULL: s390_format_RXY_RRRD(s390_irgen_DLG, ovl.fmt.RXY.r1,
13303 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13304 ovl.fmt.RXY.dl2,
13305 ovl.fmt.RXY.dh2); goto ok;
13306 case 0xe30000000088ULL: s390_format_RXY_RRRD(s390_irgen_ALCG, ovl.fmt.RXY.r1,
13307 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13308 ovl.fmt.RXY.dl2,
13309 ovl.fmt.RXY.dh2); goto ok;
13310 case 0xe30000000089ULL: s390_format_RXY_RRRD(s390_irgen_SLBG, ovl.fmt.RXY.r1,
13311 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13312 ovl.fmt.RXY.dl2,
13313 ovl.fmt.RXY.dh2); goto ok;
13314 case 0xe3000000008eULL: s390_format_RXY_RRRD(s390_irgen_STPQ, ovl.fmt.RXY.r1,
13315 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13316 ovl.fmt.RXY.dl2,
13317 ovl.fmt.RXY.dh2); goto ok;
13318 case 0xe3000000008fULL: s390_format_RXY_RRRD(s390_irgen_LPQ, ovl.fmt.RXY.r1,
13319 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13320 ovl.fmt.RXY.dl2,
13321 ovl.fmt.RXY.dh2); goto ok;
13322 case 0xe30000000090ULL: s390_format_RXY_RRRD(s390_irgen_LLGC, ovl.fmt.RXY.r1,
13323 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13324 ovl.fmt.RXY.dl2,
13325 ovl.fmt.RXY.dh2); goto ok;
13326 case 0xe30000000091ULL: s390_format_RXY_RRRD(s390_irgen_LLGH, ovl.fmt.RXY.r1,
13327 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13328 ovl.fmt.RXY.dl2,
13329 ovl.fmt.RXY.dh2); goto ok;
13330 case 0xe30000000094ULL: s390_format_RXY_RRRD(s390_irgen_LLC, ovl.fmt.RXY.r1,
13331 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13332 ovl.fmt.RXY.dl2,
13333 ovl.fmt.RXY.dh2); goto ok;
13334 case 0xe30000000095ULL: s390_format_RXY_RRRD(s390_irgen_LLH, ovl.fmt.RXY.r1,
13335 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13336 ovl.fmt.RXY.dl2,
13337 ovl.fmt.RXY.dh2); goto ok;
13338 case 0xe30000000096ULL: s390_format_RXY_RRRD(s390_irgen_ML, ovl.fmt.RXY.r1,
13339 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13340 ovl.fmt.RXY.dl2,
13341 ovl.fmt.RXY.dh2); goto ok;
13342 case 0xe30000000097ULL: s390_format_RXY_RRRD(s390_irgen_DL, ovl.fmt.RXY.r1,
13343 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13344 ovl.fmt.RXY.dl2,
13345 ovl.fmt.RXY.dh2); goto ok;
13346 case 0xe30000000098ULL: s390_format_RXY_RRRD(s390_irgen_ALC, ovl.fmt.RXY.r1,
13347 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13348 ovl.fmt.RXY.dl2,
13349 ovl.fmt.RXY.dh2); goto ok;
13350 case 0xe30000000099ULL: s390_format_RXY_RRRD(s390_irgen_SLB, ovl.fmt.RXY.r1,
13351 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13352 ovl.fmt.RXY.dl2,
13353 ovl.fmt.RXY.dh2); goto ok;
13354 case 0xe300000000c0ULL: s390_format_RXY_RRRD(s390_irgen_LBH, ovl.fmt.RXY.r1,
13355 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13356 ovl.fmt.RXY.dl2,
13357 ovl.fmt.RXY.dh2); goto ok;
13358 case 0xe300000000c2ULL: s390_format_RXY_RRRD(s390_irgen_LLCH, ovl.fmt.RXY.r1,
13359 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13360 ovl.fmt.RXY.dl2,
13361 ovl.fmt.RXY.dh2); goto ok;
13362 case 0xe300000000c3ULL: s390_format_RXY_RRRD(s390_irgen_STCH, ovl.fmt.RXY.r1,
13363 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13364 ovl.fmt.RXY.dl2,
13365 ovl.fmt.RXY.dh2); goto ok;
13366 case 0xe300000000c4ULL: s390_format_RXY_RRRD(s390_irgen_LHH, ovl.fmt.RXY.r1,
13367 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13368 ovl.fmt.RXY.dl2,
13369 ovl.fmt.RXY.dh2); goto ok;
13370 case 0xe300000000c6ULL: s390_format_RXY_RRRD(s390_irgen_LLHH, ovl.fmt.RXY.r1,
13371 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13372 ovl.fmt.RXY.dl2,
13373 ovl.fmt.RXY.dh2); goto ok;
13374 case 0xe300000000c7ULL: s390_format_RXY_RRRD(s390_irgen_STHH, ovl.fmt.RXY.r1,
13375 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13376 ovl.fmt.RXY.dl2,
13377 ovl.fmt.RXY.dh2); goto ok;
13378 case 0xe300000000caULL: s390_format_RXY_RRRD(s390_irgen_LFH, ovl.fmt.RXY.r1,
13379 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13380 ovl.fmt.RXY.dl2,
13381 ovl.fmt.RXY.dh2); goto ok;
13382 case 0xe300000000cbULL: s390_format_RXY_RRRD(s390_irgen_STFH, ovl.fmt.RXY.r1,
13383 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13384 ovl.fmt.RXY.dl2,
13385 ovl.fmt.RXY.dh2); goto ok;
13386 case 0xe300000000cdULL: s390_format_RXY_RRRD(s390_irgen_CHF, ovl.fmt.RXY.r1,
13387 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13388 ovl.fmt.RXY.dl2,
13389 ovl.fmt.RXY.dh2); goto ok;
13390 case 0xe300000000cfULL: s390_format_RXY_RRRD(s390_irgen_CLHF, ovl.fmt.RXY.r1,
13391 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13392 ovl.fmt.RXY.dl2,
13393 ovl.fmt.RXY.dh2); goto ok;
13394 case 0xeb0000000004ULL: s390_format_RSY_RRRD(s390_irgen_LMG, ovl.fmt.RSY.r1,
13395 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13396 ovl.fmt.RSY.dl2,
13397 ovl.fmt.RSY.dh2); goto ok;
13398 case 0xeb000000000aULL: s390_format_RSY_RRRD(s390_irgen_SRAG, ovl.fmt.RSY.r1,
13399 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13400 ovl.fmt.RSY.dl2,
13401 ovl.fmt.RSY.dh2); goto ok;
13402 case 0xeb000000000bULL: s390_format_RSY_RRRD(s390_irgen_SLAG, ovl.fmt.RSY.r1,
13403 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13404 ovl.fmt.RSY.dl2,
13405 ovl.fmt.RSY.dh2); goto ok;
13406 case 0xeb000000000cULL: s390_format_RSY_RRRD(s390_irgen_SRLG, ovl.fmt.RSY.r1,
13407 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13408 ovl.fmt.RSY.dl2,
13409 ovl.fmt.RSY.dh2); goto ok;
13410 case 0xeb000000000dULL: s390_format_RSY_RRRD(s390_irgen_SLLG, ovl.fmt.RSY.r1,
13411 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13412 ovl.fmt.RSY.dl2,
13413 ovl.fmt.RSY.dh2); goto ok;
13414 case 0xeb000000000fULL: /* TRACG */ goto unimplemented;
13415 case 0xeb0000000014ULL: s390_format_RSY_RRRD(s390_irgen_CSY, ovl.fmt.RSY.r1,
13416 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13417 ovl.fmt.RSY.dl2,
13418 ovl.fmt.RSY.dh2); goto ok;
13419 case 0xeb000000001cULL: s390_format_RSY_RRRD(s390_irgen_RLLG, ovl.fmt.RSY.r1,
13420 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13421 ovl.fmt.RSY.dl2,
13422 ovl.fmt.RSY.dh2); goto ok;
13423 case 0xeb000000001dULL: s390_format_RSY_RRRD(s390_irgen_RLL, ovl.fmt.RSY.r1,
13424 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13425 ovl.fmt.RSY.dl2,
13426 ovl.fmt.RSY.dh2); goto ok;
13427 case 0xeb0000000020ULL: s390_format_RSY_RURD(s390_irgen_CLMH, ovl.fmt.RSY.r1,
13428 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13429 ovl.fmt.RSY.dl2,
13430 ovl.fmt.RSY.dh2); goto ok;
13431 case 0xeb0000000021ULL: s390_format_RSY_RURD(s390_irgen_CLMY, ovl.fmt.RSY.r1,
13432 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13433 ovl.fmt.RSY.dl2,
13434 ovl.fmt.RSY.dh2); goto ok;
13435 case 0xeb0000000024ULL: s390_format_RSY_RRRD(s390_irgen_STMG, ovl.fmt.RSY.r1,
13436 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13437 ovl.fmt.RSY.dl2,
13438 ovl.fmt.RSY.dh2); goto ok;
13439 case 0xeb0000000025ULL: /* STCTG */ goto unimplemented;
13440 case 0xeb0000000026ULL: s390_format_RSY_RRRD(s390_irgen_STMH, ovl.fmt.RSY.r1,
13441 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13442 ovl.fmt.RSY.dl2,
13443 ovl.fmt.RSY.dh2); goto ok;
13444 case 0xeb000000002cULL: s390_format_RSY_RURD(s390_irgen_STCMH,
13445 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
13446 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
13447 ovl.fmt.RSY.dh2); goto ok;
13448 case 0xeb000000002dULL: s390_format_RSY_RURD(s390_irgen_STCMY,
13449 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
13450 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
13451 ovl.fmt.RSY.dh2); goto ok;
13452 case 0xeb000000002fULL: /* LCTLG */ goto unimplemented;
13453 case 0xeb0000000030ULL: s390_format_RSY_RRRD(s390_irgen_CSG, ovl.fmt.RSY.r1,
13454 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13455 ovl.fmt.RSY.dl2,
13456 ovl.fmt.RSY.dh2); goto ok;
florian448cbba2012-06-06 02:26:01 +000013457 case 0xeb0000000031ULL: s390_format_RSY_RRRD(s390_irgen_CDSY, ovl.fmt.RSY.r1,
13458 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13459 ovl.fmt.RSY.dl2,
13460 ovl.fmt.RSY.dh2); goto ok;
13461 case 0xeb000000003eULL: s390_format_RSY_RRRD(s390_irgen_CDSG, ovl.fmt.RSY.r1,
13462 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13463 ovl.fmt.RSY.dl2,
13464 ovl.fmt.RSY.dh2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013465 case 0xeb0000000044ULL: s390_format_RSY_RRRD(s390_irgen_BXHG, ovl.fmt.RSY.r1,
13466 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13467 ovl.fmt.RSY.dl2,
13468 ovl.fmt.RSY.dh2); goto ok;
13469 case 0xeb0000000045ULL: s390_format_RSY_RRRD(s390_irgen_BXLEG,
13470 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
13471 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
13472 ovl.fmt.RSY.dh2); goto ok;
13473 case 0xeb000000004cULL: /* ECAG */ goto unimplemented;
13474 case 0xeb0000000051ULL: s390_format_SIY_URD(s390_irgen_TMY, ovl.fmt.SIY.i2,
13475 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
13476 ovl.fmt.SIY.dh1); goto ok;
13477 case 0xeb0000000052ULL: s390_format_SIY_URD(s390_irgen_MVIY, ovl.fmt.SIY.i2,
13478 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
13479 ovl.fmt.SIY.dh1); goto ok;
13480 case 0xeb0000000054ULL: s390_format_SIY_URD(s390_irgen_NIY, ovl.fmt.SIY.i2,
13481 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
13482 ovl.fmt.SIY.dh1); goto ok;
13483 case 0xeb0000000055ULL: s390_format_SIY_URD(s390_irgen_CLIY, ovl.fmt.SIY.i2,
13484 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
13485 ovl.fmt.SIY.dh1); goto ok;
13486 case 0xeb0000000056ULL: s390_format_SIY_URD(s390_irgen_OIY, ovl.fmt.SIY.i2,
13487 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
13488 ovl.fmt.SIY.dh1); goto ok;
13489 case 0xeb0000000057ULL: s390_format_SIY_URD(s390_irgen_XIY, ovl.fmt.SIY.i2,
13490 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
13491 ovl.fmt.SIY.dh1); goto ok;
13492 case 0xeb000000006aULL: s390_format_SIY_IRD(s390_irgen_ASI, ovl.fmt.SIY.i2,
13493 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
13494 ovl.fmt.SIY.dh1); goto ok;
13495 case 0xeb000000006eULL: s390_format_SIY_IRD(s390_irgen_ALSI, ovl.fmt.SIY.i2,
13496 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
13497 ovl.fmt.SIY.dh1); goto ok;
13498 case 0xeb000000007aULL: s390_format_SIY_IRD(s390_irgen_AGSI, ovl.fmt.SIY.i2,
13499 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
13500 ovl.fmt.SIY.dh1); goto ok;
13501 case 0xeb000000007eULL: s390_format_SIY_IRD(s390_irgen_ALGSI, ovl.fmt.SIY.i2,
13502 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
13503 ovl.fmt.SIY.dh1); goto ok;
13504 case 0xeb0000000080ULL: s390_format_RSY_RURD(s390_irgen_ICMH, ovl.fmt.RSY.r1,
13505 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13506 ovl.fmt.RSY.dl2,
13507 ovl.fmt.RSY.dh2); goto ok;
13508 case 0xeb0000000081ULL: s390_format_RSY_RURD(s390_irgen_ICMY, ovl.fmt.RSY.r1,
13509 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13510 ovl.fmt.RSY.dl2,
13511 ovl.fmt.RSY.dh2); goto ok;
13512 case 0xeb000000008eULL: /* MVCLU */ goto unimplemented;
13513 case 0xeb000000008fULL: /* CLCLU */ goto unimplemented;
13514 case 0xeb0000000090ULL: s390_format_RSY_RRRD(s390_irgen_STMY, ovl.fmt.RSY.r1,
13515 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13516 ovl.fmt.RSY.dl2,
13517 ovl.fmt.RSY.dh2); goto ok;
13518 case 0xeb0000000096ULL: s390_format_RSY_RRRD(s390_irgen_LMH, ovl.fmt.RSY.r1,
13519 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13520 ovl.fmt.RSY.dl2,
13521 ovl.fmt.RSY.dh2); goto ok;
13522 case 0xeb0000000098ULL: s390_format_RSY_RRRD(s390_irgen_LMY, ovl.fmt.RSY.r1,
13523 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13524 ovl.fmt.RSY.dl2,
13525 ovl.fmt.RSY.dh2); goto ok;
13526 case 0xeb000000009aULL: s390_format_RSY_AARD(s390_irgen_LAMY, ovl.fmt.RSY.r1,
13527 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13528 ovl.fmt.RSY.dl2,
13529 ovl.fmt.RSY.dh2); goto ok;
13530 case 0xeb000000009bULL: s390_format_RSY_AARD(s390_irgen_STAMY,
13531 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
13532 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
13533 ovl.fmt.RSY.dh2); goto ok;
13534 case 0xeb00000000c0ULL: /* TP */ goto unimplemented;
13535 case 0xeb00000000dcULL: s390_format_RSY_RRRD(s390_irgen_SRAK, ovl.fmt.RSY.r1,
13536 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13537 ovl.fmt.RSY.dl2,
13538 ovl.fmt.RSY.dh2); goto ok;
13539 case 0xeb00000000ddULL: s390_format_RSY_RRRD(s390_irgen_SLAK, ovl.fmt.RSY.r1,
13540 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13541 ovl.fmt.RSY.dl2,
13542 ovl.fmt.RSY.dh2); goto ok;
13543 case 0xeb00000000deULL: s390_format_RSY_RRRD(s390_irgen_SRLK, ovl.fmt.RSY.r1,
13544 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13545 ovl.fmt.RSY.dl2,
13546 ovl.fmt.RSY.dh2); goto ok;
13547 case 0xeb00000000dfULL: s390_format_RSY_RRRD(s390_irgen_SLLK, ovl.fmt.RSY.r1,
13548 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13549 ovl.fmt.RSY.dl2,
13550 ovl.fmt.RSY.dh2); goto ok;
sewardjd7bde722011-04-05 13:19:33 +000013551 case 0xeb00000000e2ULL: s390_format_RSY_RDRM(s390_irgen_LOCG, ovl.fmt.RSY.r1,
13552 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13553 ovl.fmt.RSY.dl2,
13554 ovl.fmt.RSY.dh2,
13555 S390_XMNM_LOCG); goto ok;
13556 case 0xeb00000000e3ULL: s390_format_RSY_RDRM(s390_irgen_STOCG,
13557 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
13558 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
13559 ovl.fmt.RSY.dh2,
13560 S390_XMNM_STOCG); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013561 case 0xeb00000000e4ULL: s390_format_RSY_RRRD(s390_irgen_LANG, ovl.fmt.RSY.r1,
13562 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13563 ovl.fmt.RSY.dl2,
13564 ovl.fmt.RSY.dh2); goto ok;
13565 case 0xeb00000000e6ULL: s390_format_RSY_RRRD(s390_irgen_LAOG, ovl.fmt.RSY.r1,
13566 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13567 ovl.fmt.RSY.dl2,
13568 ovl.fmt.RSY.dh2); goto ok;
13569 case 0xeb00000000e7ULL: s390_format_RSY_RRRD(s390_irgen_LAXG, ovl.fmt.RSY.r1,
13570 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13571 ovl.fmt.RSY.dl2,
13572 ovl.fmt.RSY.dh2); goto ok;
13573 case 0xeb00000000e8ULL: s390_format_RSY_RRRD(s390_irgen_LAAG, ovl.fmt.RSY.r1,
13574 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13575 ovl.fmt.RSY.dl2,
13576 ovl.fmt.RSY.dh2); goto ok;
13577 case 0xeb00000000eaULL: s390_format_RSY_RRRD(s390_irgen_LAALG,
13578 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
13579 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
13580 ovl.fmt.RSY.dh2); goto ok;
sewardjd7bde722011-04-05 13:19:33 +000013581 case 0xeb00000000f2ULL: s390_format_RSY_RDRM(s390_irgen_LOC, ovl.fmt.RSY.r1,
13582 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13583 ovl.fmt.RSY.dl2,
13584 ovl.fmt.RSY.dh2, S390_XMNM_LOC);
13585 goto ok;
13586 case 0xeb00000000f3ULL: s390_format_RSY_RDRM(s390_irgen_STOC, ovl.fmt.RSY.r1,
13587 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13588 ovl.fmt.RSY.dl2,
13589 ovl.fmt.RSY.dh2,
13590 S390_XMNM_STOC); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013591 case 0xeb00000000f4ULL: s390_format_RSY_RRRD(s390_irgen_LAN, ovl.fmt.RSY.r1,
13592 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13593 ovl.fmt.RSY.dl2,
13594 ovl.fmt.RSY.dh2); goto ok;
13595 case 0xeb00000000f6ULL: s390_format_RSY_RRRD(s390_irgen_LAO, ovl.fmt.RSY.r1,
13596 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13597 ovl.fmt.RSY.dl2,
13598 ovl.fmt.RSY.dh2); goto ok;
13599 case 0xeb00000000f7ULL: s390_format_RSY_RRRD(s390_irgen_LAX, ovl.fmt.RSY.r1,
13600 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13601 ovl.fmt.RSY.dl2,
13602 ovl.fmt.RSY.dh2); goto ok;
13603 case 0xeb00000000f8ULL: s390_format_RSY_RRRD(s390_irgen_LAA, ovl.fmt.RSY.r1,
13604 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13605 ovl.fmt.RSY.dl2,
13606 ovl.fmt.RSY.dh2); goto ok;
13607 case 0xeb00000000faULL: s390_format_RSY_RRRD(s390_irgen_LAAL, ovl.fmt.RSY.r1,
13608 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13609 ovl.fmt.RSY.dl2,
13610 ovl.fmt.RSY.dh2); goto ok;
13611 case 0xec0000000044ULL: s390_format_RIE_RRP(s390_irgen_BRXHG, ovl.fmt.RIE.r1,
13612 ovl.fmt.RIE.r3, ovl.fmt.RIE.i2);
13613 goto ok;
13614 case 0xec0000000045ULL: s390_format_RIE_RRP(s390_irgen_BRXLG, ovl.fmt.RIE.r1,
13615 ovl.fmt.RIE.r3, ovl.fmt.RIE.i2);
13616 goto ok;
13617 case 0xec0000000051ULL: /* RISBLG */ goto unimplemented;
13618 case 0xec0000000054ULL: s390_format_RIE_RRUUU(s390_irgen_RNSBG,
13619 ovl.fmt.RIE_RRUUU.r1,
13620 ovl.fmt.RIE_RRUUU.r2,
13621 ovl.fmt.RIE_RRUUU.i3,
13622 ovl.fmt.RIE_RRUUU.i4,
13623 ovl.fmt.RIE_RRUUU.i5);
13624 goto ok;
13625 case 0xec0000000055ULL: s390_format_RIE_RRUUU(s390_irgen_RISBG,
13626 ovl.fmt.RIE_RRUUU.r1,
13627 ovl.fmt.RIE_RRUUU.r2,
13628 ovl.fmt.RIE_RRUUU.i3,
13629 ovl.fmt.RIE_RRUUU.i4,
13630 ovl.fmt.RIE_RRUUU.i5);
13631 goto ok;
13632 case 0xec0000000056ULL: s390_format_RIE_RRUUU(s390_irgen_ROSBG,
13633 ovl.fmt.RIE_RRUUU.r1,
13634 ovl.fmt.RIE_RRUUU.r2,
13635 ovl.fmt.RIE_RRUUU.i3,
13636 ovl.fmt.RIE_RRUUU.i4,
13637 ovl.fmt.RIE_RRUUU.i5);
13638 goto ok;
13639 case 0xec0000000057ULL: s390_format_RIE_RRUUU(s390_irgen_RXSBG,
13640 ovl.fmt.RIE_RRUUU.r1,
13641 ovl.fmt.RIE_RRUUU.r2,
13642 ovl.fmt.RIE_RRUUU.i3,
13643 ovl.fmt.RIE_RRUUU.i4,
13644 ovl.fmt.RIE_RRUUU.i5);
13645 goto ok;
13646 case 0xec000000005dULL: /* RISBHG */ goto unimplemented;
13647 case 0xec0000000064ULL: s390_format_RIE_RRPU(s390_irgen_CGRJ,
13648 ovl.fmt.RIE_RRPU.r1,
13649 ovl.fmt.RIE_RRPU.r2,
13650 ovl.fmt.RIE_RRPU.i4,
13651 ovl.fmt.RIE_RRPU.m3); goto ok;
13652 case 0xec0000000065ULL: s390_format_RIE_RRPU(s390_irgen_CLGRJ,
13653 ovl.fmt.RIE_RRPU.r1,
13654 ovl.fmt.RIE_RRPU.r2,
13655 ovl.fmt.RIE_RRPU.i4,
13656 ovl.fmt.RIE_RRPU.m3); goto ok;
13657 case 0xec0000000070ULL: /* CGIT */ goto unimplemented;
13658 case 0xec0000000071ULL: /* CLGIT */ goto unimplemented;
13659 case 0xec0000000072ULL: /* CIT */ goto unimplemented;
13660 case 0xec0000000073ULL: /* CLFIT */ goto unimplemented;
13661 case 0xec0000000076ULL: s390_format_RIE_RRPU(s390_irgen_CRJ,
13662 ovl.fmt.RIE_RRPU.r1,
13663 ovl.fmt.RIE_RRPU.r2,
13664 ovl.fmt.RIE_RRPU.i4,
13665 ovl.fmt.RIE_RRPU.m3); goto ok;
13666 case 0xec0000000077ULL: s390_format_RIE_RRPU(s390_irgen_CLRJ,
13667 ovl.fmt.RIE_RRPU.r1,
13668 ovl.fmt.RIE_RRPU.r2,
13669 ovl.fmt.RIE_RRPU.i4,
13670 ovl.fmt.RIE_RRPU.m3); goto ok;
13671 case 0xec000000007cULL: s390_format_RIE_RUPI(s390_irgen_CGIJ,
13672 ovl.fmt.RIEv3.r1,
13673 ovl.fmt.RIEv3.m3,
13674 ovl.fmt.RIEv3.i4,
13675 ovl.fmt.RIEv3.i2); goto ok;
13676 case 0xec000000007dULL: s390_format_RIE_RUPU(s390_irgen_CLGIJ,
13677 ovl.fmt.RIEv3.r1,
13678 ovl.fmt.RIEv3.m3,
13679 ovl.fmt.RIEv3.i4,
13680 ovl.fmt.RIEv3.i2); goto ok;
13681 case 0xec000000007eULL: s390_format_RIE_RUPI(s390_irgen_CIJ,
13682 ovl.fmt.RIEv3.r1,
13683 ovl.fmt.RIEv3.m3,
13684 ovl.fmt.RIEv3.i4,
13685 ovl.fmt.RIEv3.i2); goto ok;
13686 case 0xec000000007fULL: s390_format_RIE_RUPU(s390_irgen_CLIJ,
13687 ovl.fmt.RIEv3.r1,
13688 ovl.fmt.RIEv3.m3,
13689 ovl.fmt.RIEv3.i4,
13690 ovl.fmt.RIEv3.i2); goto ok;
13691 case 0xec00000000d8ULL: s390_format_RIE_RRI0(s390_irgen_AHIK, ovl.fmt.RIE.r1,
13692 ovl.fmt.RIE.r3, ovl.fmt.RIE.i2);
13693 goto ok;
13694 case 0xec00000000d9ULL: s390_format_RIE_RRI0(s390_irgen_AGHIK,
13695 ovl.fmt.RIE.r1, ovl.fmt.RIE.r3,
13696 ovl.fmt.RIE.i2); goto ok;
13697 case 0xec00000000daULL: s390_format_RIE_RRI0(s390_irgen_ALHSIK,
13698 ovl.fmt.RIE.r1, ovl.fmt.RIE.r3,
13699 ovl.fmt.RIE.i2); goto ok;
13700 case 0xec00000000dbULL: s390_format_RIE_RRI0(s390_irgen_ALGHSIK,
13701 ovl.fmt.RIE.r1, ovl.fmt.RIE.r3,
13702 ovl.fmt.RIE.i2); goto ok;
13703 case 0xec00000000e4ULL: s390_format_RRS(s390_irgen_CGRB, ovl.fmt.RRS.r1,
13704 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
13705 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
13706 goto ok;
13707 case 0xec00000000e5ULL: s390_format_RRS(s390_irgen_CLGRB, ovl.fmt.RRS.r1,
13708 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
13709 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
13710 goto ok;
13711 case 0xec00000000f6ULL: s390_format_RRS(s390_irgen_CRB, ovl.fmt.RRS.r1,
13712 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
13713 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
13714 goto ok;
13715 case 0xec00000000f7ULL: s390_format_RRS(s390_irgen_CLRB, ovl.fmt.RRS.r1,
13716 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
13717 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
13718 goto ok;
13719 case 0xec00000000fcULL: s390_format_RIS_RURDI(s390_irgen_CGIB,
13720 ovl.fmt.RIS.r1, ovl.fmt.RIS.m3,
13721 ovl.fmt.RIS.b4, ovl.fmt.RIS.d4,
13722 ovl.fmt.RIS.i2); goto ok;
13723 case 0xec00000000fdULL: s390_format_RIS_RURDU(s390_irgen_CLGIB,
13724 ovl.fmt.RIS.r1, ovl.fmt.RIS.m3,
13725 ovl.fmt.RIS.b4, ovl.fmt.RIS.d4,
13726 ovl.fmt.RIS.i2); goto ok;
13727 case 0xec00000000feULL: s390_format_RIS_RURDI(s390_irgen_CIB, ovl.fmt.RIS.r1,
13728 ovl.fmt.RIS.m3, ovl.fmt.RIS.b4,
13729 ovl.fmt.RIS.d4,
13730 ovl.fmt.RIS.i2); goto ok;
13731 case 0xec00000000ffULL: s390_format_RIS_RURDU(s390_irgen_CLIB,
13732 ovl.fmt.RIS.r1, ovl.fmt.RIS.m3,
13733 ovl.fmt.RIS.b4, ovl.fmt.RIS.d4,
13734 ovl.fmt.RIS.i2); goto ok;
13735 case 0xed0000000004ULL: s390_format_RXE_FRRD(s390_irgen_LDEB, ovl.fmt.RXE.r1,
13736 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
13737 ovl.fmt.RXE.d2); goto ok;
13738 case 0xed0000000005ULL: s390_format_RXE_FRRD(s390_irgen_LXDB, ovl.fmt.RXE.r1,
13739 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
13740 ovl.fmt.RXE.d2); goto ok;
13741 case 0xed0000000006ULL: s390_format_RXE_FRRD(s390_irgen_LXEB, ovl.fmt.RXE.r1,
13742 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
13743 ovl.fmt.RXE.d2); goto ok;
13744 case 0xed0000000007ULL: /* MXDB */ goto unimplemented;
13745 case 0xed0000000008ULL: /* KEB */ goto unimplemented;
13746 case 0xed0000000009ULL: s390_format_RXE_FRRD(s390_irgen_CEB, ovl.fmt.RXE.r1,
13747 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
13748 ovl.fmt.RXE.d2); goto ok;
13749 case 0xed000000000aULL: s390_format_RXE_FRRD(s390_irgen_AEB, ovl.fmt.RXE.r1,
13750 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
13751 ovl.fmt.RXE.d2); goto ok;
13752 case 0xed000000000bULL: s390_format_RXE_FRRD(s390_irgen_SEB, ovl.fmt.RXE.r1,
13753 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
13754 ovl.fmt.RXE.d2); goto ok;
13755 case 0xed000000000cULL: /* MDEB */ goto unimplemented;
13756 case 0xed000000000dULL: s390_format_RXE_FRRD(s390_irgen_DEB, ovl.fmt.RXE.r1,
13757 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
13758 ovl.fmt.RXE.d2); goto ok;
13759 case 0xed000000000eULL: s390_format_RXF_FRRDF(s390_irgen_MAEB,
13760 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
13761 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
13762 ovl.fmt.RXF.r1); goto ok;
13763 case 0xed000000000fULL: s390_format_RXF_FRRDF(s390_irgen_MSEB,
13764 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
13765 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
13766 ovl.fmt.RXF.r1); goto ok;
13767 case 0xed0000000010ULL: s390_format_RXE_FRRD(s390_irgen_TCEB, ovl.fmt.RXE.r1,
13768 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
13769 ovl.fmt.RXE.d2); goto ok;
13770 case 0xed0000000011ULL: s390_format_RXE_FRRD(s390_irgen_TCDB, ovl.fmt.RXE.r1,
13771 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
13772 ovl.fmt.RXE.d2); goto ok;
13773 case 0xed0000000012ULL: s390_format_RXE_FRRD(s390_irgen_TCXB, ovl.fmt.RXE.r1,
13774 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
13775 ovl.fmt.RXE.d2); goto ok;
13776 case 0xed0000000014ULL: s390_format_RXE_FRRD(s390_irgen_SQEB, ovl.fmt.RXE.r1,
13777 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
13778 ovl.fmt.RXE.d2); goto ok;
13779 case 0xed0000000015ULL: s390_format_RXE_FRRD(s390_irgen_SQDB, ovl.fmt.RXE.r1,
13780 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
13781 ovl.fmt.RXE.d2); goto ok;
13782 case 0xed0000000017ULL: s390_format_RXE_FRRD(s390_irgen_MEEB, ovl.fmt.RXE.r1,
13783 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
13784 ovl.fmt.RXE.d2); goto ok;
13785 case 0xed0000000018ULL: /* KDB */ goto unimplemented;
13786 case 0xed0000000019ULL: s390_format_RXE_FRRD(s390_irgen_CDB, ovl.fmt.RXE.r1,
13787 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
13788 ovl.fmt.RXE.d2); goto ok;
13789 case 0xed000000001aULL: s390_format_RXE_FRRD(s390_irgen_ADB, ovl.fmt.RXE.r1,
13790 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
13791 ovl.fmt.RXE.d2); goto ok;
13792 case 0xed000000001bULL: s390_format_RXE_FRRD(s390_irgen_SDB, ovl.fmt.RXE.r1,
13793 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
13794 ovl.fmt.RXE.d2); goto ok;
13795 case 0xed000000001cULL: s390_format_RXE_FRRD(s390_irgen_MDB, ovl.fmt.RXE.r1,
13796 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
13797 ovl.fmt.RXE.d2); goto ok;
13798 case 0xed000000001dULL: s390_format_RXE_FRRD(s390_irgen_DDB, ovl.fmt.RXE.r1,
13799 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
13800 ovl.fmt.RXE.d2); goto ok;
13801 case 0xed000000001eULL: s390_format_RXF_FRRDF(s390_irgen_MADB,
13802 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
13803 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
13804 ovl.fmt.RXF.r1); goto ok;
13805 case 0xed000000001fULL: s390_format_RXF_FRRDF(s390_irgen_MSDB,
13806 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
13807 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
13808 ovl.fmt.RXF.r1); goto ok;
13809 case 0xed0000000024ULL: /* LDE */ goto unimplemented;
13810 case 0xed0000000025ULL: /* LXD */ goto unimplemented;
13811 case 0xed0000000026ULL: /* LXE */ goto unimplemented;
13812 case 0xed000000002eULL: /* MAE */ goto unimplemented;
13813 case 0xed000000002fULL: /* MSE */ goto unimplemented;
13814 case 0xed0000000034ULL: /* SQE */ goto unimplemented;
13815 case 0xed0000000035ULL: /* SQD */ goto unimplemented;
13816 case 0xed0000000037ULL: /* MEE */ goto unimplemented;
13817 case 0xed0000000038ULL: /* MAYL */ goto unimplemented;
13818 case 0xed0000000039ULL: /* MYL */ goto unimplemented;
13819 case 0xed000000003aULL: /* MAY */ goto unimplemented;
13820 case 0xed000000003bULL: /* MY */ goto unimplemented;
13821 case 0xed000000003cULL: /* MAYH */ goto unimplemented;
13822 case 0xed000000003dULL: /* MYH */ goto unimplemented;
13823 case 0xed000000003eULL: /* MAD */ goto unimplemented;
13824 case 0xed000000003fULL: /* MSD */ goto unimplemented;
13825 case 0xed0000000040ULL: /* SLDT */ goto unimplemented;
13826 case 0xed0000000041ULL: /* SRDT */ goto unimplemented;
13827 case 0xed0000000048ULL: /* SLXT */ goto unimplemented;
13828 case 0xed0000000049ULL: /* SRXT */ goto unimplemented;
13829 case 0xed0000000050ULL: /* TDCET */ goto unimplemented;
13830 case 0xed0000000051ULL: /* TDGET */ goto unimplemented;
13831 case 0xed0000000054ULL: /* TDCDT */ goto unimplemented;
13832 case 0xed0000000055ULL: /* TDGDT */ goto unimplemented;
13833 case 0xed0000000058ULL: /* TDCXT */ goto unimplemented;
13834 case 0xed0000000059ULL: /* TDGXT */ goto unimplemented;
13835 case 0xed0000000064ULL: s390_format_RXY_FRRD(s390_irgen_LEY, ovl.fmt.RXY.r1,
13836 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13837 ovl.fmt.RXY.dl2,
13838 ovl.fmt.RXY.dh2); goto ok;
13839 case 0xed0000000065ULL: s390_format_RXY_FRRD(s390_irgen_LDY, ovl.fmt.RXY.r1,
13840 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13841 ovl.fmt.RXY.dl2,
13842 ovl.fmt.RXY.dh2); goto ok;
13843 case 0xed0000000066ULL: s390_format_RXY_FRRD(s390_irgen_STEY, ovl.fmt.RXY.r1,
13844 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13845 ovl.fmt.RXY.dl2,
13846 ovl.fmt.RXY.dh2); goto ok;
13847 case 0xed0000000067ULL: s390_format_RXY_FRRD(s390_irgen_STDY, ovl.fmt.RXY.r1,
13848 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13849 ovl.fmt.RXY.dl2,
13850 ovl.fmt.RXY.dh2); goto ok;
13851 }
13852
13853 switch (((ovl.value >> 16) & 0xff0f00000000ULL) >> 32) {
13854 case 0xc000ULL: s390_format_RIL_RP(s390_irgen_LARL, ovl.fmt.RIL.r1,
13855 ovl.fmt.RIL.i2); goto ok;
13856 case 0xc001ULL: s390_format_RIL_RI(s390_irgen_LGFI, ovl.fmt.RIL.r1,
13857 ovl.fmt.RIL.i2); goto ok;
13858 case 0xc004ULL: s390_format_RIL(s390_irgen_BRCL, ovl.fmt.RIL.r1,
13859 ovl.fmt.RIL.i2); goto ok;
13860 case 0xc005ULL: s390_format_RIL_RP(s390_irgen_BRASL, ovl.fmt.RIL.r1,
13861 ovl.fmt.RIL.i2); goto ok;
13862 case 0xc006ULL: s390_format_RIL_RU(s390_irgen_XIHF, ovl.fmt.RIL.r1,
13863 ovl.fmt.RIL.i2); goto ok;
13864 case 0xc007ULL: s390_format_RIL_RU(s390_irgen_XILF, ovl.fmt.RIL.r1,
13865 ovl.fmt.RIL.i2); goto ok;
13866 case 0xc008ULL: s390_format_RIL_RU(s390_irgen_IIHF, ovl.fmt.RIL.r1,
13867 ovl.fmt.RIL.i2); goto ok;
13868 case 0xc009ULL: s390_format_RIL_RU(s390_irgen_IILF, ovl.fmt.RIL.r1,
13869 ovl.fmt.RIL.i2); goto ok;
13870 case 0xc00aULL: s390_format_RIL_RU(s390_irgen_NIHF, ovl.fmt.RIL.r1,
13871 ovl.fmt.RIL.i2); goto ok;
13872 case 0xc00bULL: s390_format_RIL_RU(s390_irgen_NILF, ovl.fmt.RIL.r1,
13873 ovl.fmt.RIL.i2); goto ok;
13874 case 0xc00cULL: s390_format_RIL_RU(s390_irgen_OIHF, ovl.fmt.RIL.r1,
13875 ovl.fmt.RIL.i2); goto ok;
13876 case 0xc00dULL: s390_format_RIL_RU(s390_irgen_OILF, ovl.fmt.RIL.r1,
13877 ovl.fmt.RIL.i2); goto ok;
13878 case 0xc00eULL: s390_format_RIL_RU(s390_irgen_LLIHF, ovl.fmt.RIL.r1,
13879 ovl.fmt.RIL.i2); goto ok;
13880 case 0xc00fULL: s390_format_RIL_RU(s390_irgen_LLILF, ovl.fmt.RIL.r1,
13881 ovl.fmt.RIL.i2); goto ok;
13882 case 0xc200ULL: s390_format_RIL_RI(s390_irgen_MSGFI, ovl.fmt.RIL.r1,
13883 ovl.fmt.RIL.i2); goto ok;
13884 case 0xc201ULL: s390_format_RIL_RI(s390_irgen_MSFI, ovl.fmt.RIL.r1,
13885 ovl.fmt.RIL.i2); goto ok;
13886 case 0xc204ULL: s390_format_RIL_RU(s390_irgen_SLGFI, ovl.fmt.RIL.r1,
13887 ovl.fmt.RIL.i2); goto ok;
13888 case 0xc205ULL: s390_format_RIL_RU(s390_irgen_SLFI, ovl.fmt.RIL.r1,
13889 ovl.fmt.RIL.i2); goto ok;
13890 case 0xc208ULL: s390_format_RIL_RI(s390_irgen_AGFI, ovl.fmt.RIL.r1,
13891 ovl.fmt.RIL.i2); goto ok;
13892 case 0xc209ULL: s390_format_RIL_RI(s390_irgen_AFI, ovl.fmt.RIL.r1,
13893 ovl.fmt.RIL.i2); goto ok;
13894 case 0xc20aULL: s390_format_RIL_RU(s390_irgen_ALGFI, ovl.fmt.RIL.r1,
13895 ovl.fmt.RIL.i2); goto ok;
13896 case 0xc20bULL: s390_format_RIL_RU(s390_irgen_ALFI, ovl.fmt.RIL.r1,
13897 ovl.fmt.RIL.i2); goto ok;
13898 case 0xc20cULL: s390_format_RIL_RI(s390_irgen_CGFI, ovl.fmt.RIL.r1,
13899 ovl.fmt.RIL.i2); goto ok;
13900 case 0xc20dULL: s390_format_RIL_RI(s390_irgen_CFI, ovl.fmt.RIL.r1,
13901 ovl.fmt.RIL.i2); goto ok;
13902 case 0xc20eULL: s390_format_RIL_RU(s390_irgen_CLGFI, ovl.fmt.RIL.r1,
13903 ovl.fmt.RIL.i2); goto ok;
13904 case 0xc20fULL: s390_format_RIL_RU(s390_irgen_CLFI, ovl.fmt.RIL.r1,
13905 ovl.fmt.RIL.i2); goto ok;
13906 case 0xc402ULL: s390_format_RIL_RP(s390_irgen_LLHRL, ovl.fmt.RIL.r1,
13907 ovl.fmt.RIL.i2); goto ok;
13908 case 0xc404ULL: s390_format_RIL_RP(s390_irgen_LGHRL, ovl.fmt.RIL.r1,
13909 ovl.fmt.RIL.i2); goto ok;
13910 case 0xc405ULL: s390_format_RIL_RP(s390_irgen_LHRL, ovl.fmt.RIL.r1,
13911 ovl.fmt.RIL.i2); goto ok;
13912 case 0xc406ULL: s390_format_RIL_RP(s390_irgen_LLGHRL, ovl.fmt.RIL.r1,
13913 ovl.fmt.RIL.i2); goto ok;
13914 case 0xc407ULL: s390_format_RIL_RP(s390_irgen_STHRL, ovl.fmt.RIL.r1,
13915 ovl.fmt.RIL.i2); goto ok;
13916 case 0xc408ULL: s390_format_RIL_RP(s390_irgen_LGRL, ovl.fmt.RIL.r1,
13917 ovl.fmt.RIL.i2); goto ok;
13918 case 0xc40bULL: s390_format_RIL_RP(s390_irgen_STGRL, ovl.fmt.RIL.r1,
13919 ovl.fmt.RIL.i2); goto ok;
13920 case 0xc40cULL: s390_format_RIL_RP(s390_irgen_LGFRL, ovl.fmt.RIL.r1,
13921 ovl.fmt.RIL.i2); goto ok;
13922 case 0xc40dULL: s390_format_RIL_RP(s390_irgen_LRL, ovl.fmt.RIL.r1,
13923 ovl.fmt.RIL.i2); goto ok;
13924 case 0xc40eULL: s390_format_RIL_RP(s390_irgen_LLGFRL, ovl.fmt.RIL.r1,
13925 ovl.fmt.RIL.i2); goto ok;
13926 case 0xc40fULL: s390_format_RIL_RP(s390_irgen_STRL, ovl.fmt.RIL.r1,
13927 ovl.fmt.RIL.i2); goto ok;
13928 case 0xc600ULL: s390_format_RIL_RP(s390_irgen_EXRL, ovl.fmt.RIL.r1,
13929 ovl.fmt.RIL.i2); goto ok;
13930 case 0xc602ULL: s390_format_RIL_UP(s390_irgen_PFDRL, ovl.fmt.RIL.r1,
13931 ovl.fmt.RIL.i2); goto ok;
13932 case 0xc604ULL: s390_format_RIL_RP(s390_irgen_CGHRL, ovl.fmt.RIL.r1,
13933 ovl.fmt.RIL.i2); goto ok;
13934 case 0xc605ULL: s390_format_RIL_RP(s390_irgen_CHRL, ovl.fmt.RIL.r1,
13935 ovl.fmt.RIL.i2); goto ok;
13936 case 0xc606ULL: s390_format_RIL_RP(s390_irgen_CLGHRL, ovl.fmt.RIL.r1,
13937 ovl.fmt.RIL.i2); goto ok;
13938 case 0xc607ULL: s390_format_RIL_RP(s390_irgen_CLHRL, ovl.fmt.RIL.r1,
13939 ovl.fmt.RIL.i2); goto ok;
13940 case 0xc608ULL: s390_format_RIL_RP(s390_irgen_CGRL, ovl.fmt.RIL.r1,
13941 ovl.fmt.RIL.i2); goto ok;
13942 case 0xc60aULL: s390_format_RIL_RP(s390_irgen_CLGRL, ovl.fmt.RIL.r1,
13943 ovl.fmt.RIL.i2); goto ok;
13944 case 0xc60cULL: s390_format_RIL_RP(s390_irgen_CGFRL, ovl.fmt.RIL.r1,
13945 ovl.fmt.RIL.i2); goto ok;
13946 case 0xc60dULL: s390_format_RIL_RP(s390_irgen_CRL, ovl.fmt.RIL.r1,
13947 ovl.fmt.RIL.i2); goto ok;
13948 case 0xc60eULL: s390_format_RIL_RP(s390_irgen_CLGFRL, ovl.fmt.RIL.r1,
13949 ovl.fmt.RIL.i2); goto ok;
13950 case 0xc60fULL: s390_format_RIL_RP(s390_irgen_CLRL, ovl.fmt.RIL.r1,
13951 ovl.fmt.RIL.i2); goto ok;
13952 case 0xc800ULL: /* MVCOS */ goto unimplemented;
13953 case 0xc801ULL: /* ECTG */ goto unimplemented;
13954 case 0xc802ULL: /* CSST */ goto unimplemented;
13955 case 0xc804ULL: /* LPD */ goto unimplemented;
13956 case 0xc805ULL: /* LPDG */ goto unimplemented;
13957 case 0xcc06ULL: /* BRCTH */ goto unimplemented;
13958 case 0xcc08ULL: s390_format_RIL_RI(s390_irgen_AIH, ovl.fmt.RIL.r1,
13959 ovl.fmt.RIL.i2); goto ok;
13960 case 0xcc0aULL: s390_format_RIL_RI(s390_irgen_ALSIH, ovl.fmt.RIL.r1,
13961 ovl.fmt.RIL.i2); goto ok;
13962 case 0xcc0bULL: s390_format_RIL_RI(s390_irgen_ALSIHN, ovl.fmt.RIL.r1,
13963 ovl.fmt.RIL.i2); goto ok;
13964 case 0xcc0dULL: s390_format_RIL_RI(s390_irgen_CIH, ovl.fmt.RIL.r1,
13965 ovl.fmt.RIL.i2); goto ok;
13966 case 0xcc0fULL: s390_format_RIL_RU(s390_irgen_CLIH, ovl.fmt.RIL.r1,
13967 ovl.fmt.RIL.i2); goto ok;
13968 }
13969
13970 switch (((ovl.value >> 16) & 0xff0000000000ULL) >> 40) {
13971 case 0xd0ULL: /* TRTR */ goto unimplemented;
13972 case 0xd1ULL: /* MVN */ goto unimplemented;
13973 case 0xd2ULL: s390_format_SS_L0RDRD(s390_irgen_MVC, ovl.fmt.SS.l,
13974 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
13975 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
13976 case 0xd3ULL: /* MVZ */ goto unimplemented;
13977 case 0xd4ULL: s390_format_SS_L0RDRD(s390_irgen_NC, ovl.fmt.SS.l,
13978 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
13979 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
13980 case 0xd5ULL: s390_format_SS_L0RDRD(s390_irgen_CLC, ovl.fmt.SS.l,
13981 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
13982 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
13983 case 0xd6ULL: s390_format_SS_L0RDRD(s390_irgen_OC, ovl.fmt.SS.l,
13984 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
13985 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
sewardjb63967e2011-03-24 08:50:04 +000013986 case 0xd7ULL:
13987 if (ovl.fmt.SS.b1 == ovl.fmt.SS.b2 && ovl.fmt.SS.d1 == ovl.fmt.SS.d2)
13988 s390_irgen_XC_sameloc(ovl.fmt.SS.l, ovl.fmt.SS.b1, ovl.fmt.SS.d1);
13989 else
13990 s390_format_SS_L0RDRD(s390_irgen_XC, ovl.fmt.SS.l,
13991 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
13992 ovl.fmt.SS.b2, ovl.fmt.SS.d2);
13993 goto ok;
sewardj2019a972011-03-07 16:04:07 +000013994 case 0xd9ULL: /* MVCK */ goto unimplemented;
13995 case 0xdaULL: /* MVCP */ goto unimplemented;
13996 case 0xdbULL: /* MVCS */ goto unimplemented;
florian730448f2012-02-04 17:07:07 +000013997 case 0xdcULL: s390_format_SS_L0RDRD(s390_irgen_TR, ovl.fmt.SS.l,
13998 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
13999 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014000 case 0xddULL: /* TRT */ goto unimplemented;
14001 case 0xdeULL: /* ED */ goto unimplemented;
14002 case 0xdfULL: /* EDMK */ goto unimplemented;
14003 case 0xe1ULL: /* PKU */ goto unimplemented;
14004 case 0xe2ULL: /* UNPKU */ goto unimplemented;
14005 case 0xe8ULL: /* MVCIN */ goto unimplemented;
14006 case 0xe9ULL: /* PKA */ goto unimplemented;
14007 case 0xeaULL: /* UNPKA */ goto unimplemented;
14008 case 0xeeULL: /* PLO */ goto unimplemented;
14009 case 0xefULL: /* LMD */ goto unimplemented;
14010 case 0xf0ULL: /* SRP */ goto unimplemented;
14011 case 0xf1ULL: /* MVO */ goto unimplemented;
14012 case 0xf2ULL: /* PACK */ goto unimplemented;
14013 case 0xf3ULL: /* UNPK */ goto unimplemented;
14014 case 0xf8ULL: /* ZAP */ goto unimplemented;
14015 case 0xf9ULL: /* CP */ goto unimplemented;
14016 case 0xfaULL: /* AP */ goto unimplemented;
14017 case 0xfbULL: /* SP */ goto unimplemented;
14018 case 0xfcULL: /* MP */ goto unimplemented;
14019 case 0xfdULL: /* DP */ goto unimplemented;
14020 }
14021
14022 switch (((ovl.value >> 16) & 0xffff00000000ULL) >> 32) {
14023 case 0xe500ULL: /* LASP */ goto unimplemented;
14024 case 0xe501ULL: /* TPROT */ goto unimplemented;
14025 case 0xe502ULL: /* STRAG */ goto unimplemented;
14026 case 0xe50eULL: /* MVCSK */ goto unimplemented;
14027 case 0xe50fULL: /* MVCDK */ goto unimplemented;
14028 case 0xe544ULL: s390_format_SIL_RDI(s390_irgen_MVHHI, ovl.fmt.SIL.b1,
14029 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14030 goto ok;
14031 case 0xe548ULL: s390_format_SIL_RDI(s390_irgen_MVGHI, ovl.fmt.SIL.b1,
14032 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14033 goto ok;
14034 case 0xe54cULL: s390_format_SIL_RDI(s390_irgen_MVHI, ovl.fmt.SIL.b1,
14035 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14036 goto ok;
14037 case 0xe554ULL: s390_format_SIL_RDI(s390_irgen_CHHSI, ovl.fmt.SIL.b1,
14038 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14039 goto ok;
14040 case 0xe555ULL: s390_format_SIL_RDU(s390_irgen_CLHHSI, ovl.fmt.SIL.b1,
14041 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14042 goto ok;
14043 case 0xe558ULL: s390_format_SIL_RDI(s390_irgen_CGHSI, ovl.fmt.SIL.b1,
14044 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14045 goto ok;
14046 case 0xe559ULL: s390_format_SIL_RDU(s390_irgen_CLGHSI, ovl.fmt.SIL.b1,
14047 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14048 goto ok;
14049 case 0xe55cULL: s390_format_SIL_RDI(s390_irgen_CHSI, ovl.fmt.SIL.b1,
14050 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14051 goto ok;
14052 case 0xe55dULL: s390_format_SIL_RDU(s390_irgen_CLFHSI, ovl.fmt.SIL.b1,
14053 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14054 goto ok;
14055 }
14056
14057 return S390_DECODE_UNKNOWN_INSN;
14058
14059ok:
14060 return S390_DECODE_OK;
14061
14062unimplemented:
14063 return S390_DECODE_UNIMPLEMENTED_INSN;
14064}
14065
14066/* Handle "special" instructions. */
14067static s390_decode_t
14068s390_decode_special_and_irgen(UChar *bytes)
14069{
14070 s390_decode_t status = S390_DECODE_OK;
14071
14072 /* Got a "Special" instruction preamble. Which one is it? */
14073 if (bytes[0] == 0x18 && bytes[1] == 0x22 /* lr %r2, %r2 */) {
14074 s390_irgen_client_request();
14075 } else if (bytes[0] == 0x18 && bytes[1] == 0x33 /* lr %r3, %r3 */) {
14076 s390_irgen_guest_NRADDR();
14077 } else if (bytes[0] == 0x18 && bytes[1] == 0x44 /* lr %r4, %r4 */) {
14078 s390_irgen_call_noredir();
14079 } else {
14080 /* We don't know what it is. */
14081 return S390_DECODE_UNKNOWN_SPECIAL_INSN;
14082 }
14083
14084 dis_res->len = S390_SPECIAL_OP_PREAMBLE_SIZE + S390_SPECIAL_OP_SIZE;
14085
14086 return status;
14087}
14088
14089
14090/* Function returns # bytes that were decoded or 0 in case of failure */
florianb4df7682011-07-05 02:09:01 +000014091static UInt
sewardj2019a972011-03-07 16:04:07 +000014092s390_decode_and_irgen(UChar *bytes, UInt insn_length, DisResult *dres)
14093{
14094 s390_decode_t status;
14095
14096 dis_res = dres;
14097
14098 /* Spot the 8-byte preamble: 18ff lr r15,r15
14099 1811 lr r1,r1
14100 1822 lr r2,r2
14101 1833 lr r3,r3 */
14102 if (bytes[ 0] == 0x18 && bytes[ 1] == 0xff && bytes[ 2] == 0x18 &&
14103 bytes[ 3] == 0x11 && bytes[ 4] == 0x18 && bytes[ 5] == 0x22 &&
14104 bytes[ 6] == 0x18 && bytes[ 7] == 0x33) {
14105
14106 /* Handle special instruction that follows that preamble. */
14107 if (0) vex_printf("special function handling...\n");
florian2c8ed942011-08-01 22:07:51 +000014108
14109 insn_length = S390_SPECIAL_OP_PREAMBLE_SIZE + S390_SPECIAL_OP_SIZE;
14110 guest_IA_next_instr = guest_IA_curr_instr + insn_length;
14111
14112 status =
14113 s390_decode_special_and_irgen(bytes + S390_SPECIAL_OP_PREAMBLE_SIZE);
sewardj2019a972011-03-07 16:04:07 +000014114 } else {
14115 /* Handle normal instructions. */
14116 switch (insn_length) {
14117 case 2:
14118 status = s390_decode_2byte_and_irgen(bytes);
14119 break;
14120
14121 case 4:
14122 status = s390_decode_4byte_and_irgen(bytes);
14123 break;
14124
14125 case 6:
14126 status = s390_decode_6byte_and_irgen(bytes);
14127 break;
14128
14129 default:
14130 status = S390_DECODE_ERROR;
14131 break;
14132 }
14133 }
florian5fcbba22011-07-27 20:40:22 +000014134 /* If next instruction is execute, stop here */
florianf9e1ed72012-04-17 02:41:56 +000014135 if (dis_res->whatNext == Dis_Continue && bytes[insn_length] == 0x44) {
14136 put_IA(mkaddr_expr(guest_IA_next_instr));
sewardj2019a972011-03-07 16:04:07 +000014137 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +000014138 dis_res->jk_StopHere = Ijk_Boring;
sewardj2019a972011-03-07 16:04:07 +000014139 }
14140
14141 if (status == S390_DECODE_OK) return insn_length; /* OK */
14142
14143 /* Decoding failed somehow */
14144 vex_printf("vex s390->IR: ");
14145 switch (status) {
14146 case S390_DECODE_UNKNOWN_INSN:
14147 vex_printf("unknown insn: ");
14148 break;
14149
14150 case S390_DECODE_UNIMPLEMENTED_INSN:
14151 vex_printf("unimplemented insn: ");
14152 break;
14153
14154 case S390_DECODE_UNKNOWN_SPECIAL_INSN:
14155 vex_printf("unimplemented special insn: ");
14156 break;
14157
14158 default:
14159 case S390_DECODE_ERROR:
14160 vex_printf("decoding error: ");
14161 break;
14162 }
14163
14164 vex_printf("%02x%02x", bytes[0], bytes[1]);
14165 if (insn_length > 2) {
14166 vex_printf(" %02x%02x", bytes[2], bytes[3]);
14167 }
14168 if (insn_length > 4) {
14169 vex_printf(" %02x%02x", bytes[4], bytes[5]);
14170 }
14171 vex_printf("\n");
14172
14173 return 0; /* Failed */
14174}
14175
14176
sewardj2019a972011-03-07 16:04:07 +000014177/* Disassemble a single instruction INSN into IR. */
14178static DisResult
florian420c5012011-07-22 02:12:28 +000014179disInstr_S390_WRK(UChar *insn)
sewardj2019a972011-03-07 16:04:07 +000014180{
14181 UChar byte;
14182 UInt insn_length;
14183 DisResult dres;
14184
14185 /* ---------------------------------------------------- */
14186 /* --- Compute instruction length -- */
14187 /* ---------------------------------------------------- */
14188
14189 /* Get the first byte of the insn. */
14190 byte = insn[0];
14191
14192 /* The leftmost two bits (0:1) encode the length of the insn in bytes.
14193 00 -> 2 bytes, 01 -> 4 bytes, 10 -> 4 bytes, 11 -> 6 bytes. */
14194 insn_length = ((((byte >> 6) + 1) >> 1) + 1) << 1;
14195
14196 guest_IA_next_instr = guest_IA_curr_instr + insn_length;
14197
14198 /* ---------------------------------------------------- */
14199 /* --- Initialise the DisResult data -- */
14200 /* ---------------------------------------------------- */
14201 dres.whatNext = Dis_Continue;
14202 dres.len = insn_length;
14203 dres.continueAt = 0;
florian8844a632012-04-13 04:04:06 +000014204 dres.jk_StopHere = Ijk_INVALID;
sewardj2019a972011-03-07 16:04:07 +000014205
floriana99f20e2011-07-17 14:16:41 +000014206 /* fixs390: consider chasing of conditional jumps */
14207
sewardj2019a972011-03-07 16:04:07 +000014208 /* Normal and special instruction handling starts here. */
14209 if (s390_decode_and_irgen(insn, insn_length, &dres) == 0) {
14210 /* All decode failures end up here. The decoder has already issued an
14211 error message.
14212 Tell the dispatcher that this insn cannot be decoded, and so has
florian342e01a2012-07-26 02:37:49 +000014213 not been executed, and (is currently) the next to be executed.
14214 The insn address in the guest state needs to be set to
14215 guest_IA_curr_instr, otherwise the complaint will report an
14216 incorrect address. */
14217 put_IA(mkaddr_expr(guest_IA_curr_instr));
sewardj2019a972011-03-07 16:04:07 +000014218
florian8844a632012-04-13 04:04:06 +000014219 dres.whatNext = Dis_StopHere;
14220 dres.jk_StopHere = Ijk_NoDecode;
14221 dres.continueAt = 0;
14222 dres.len = 0;
14223 } else {
14224 /* Decode success */
14225 switch (dres.whatNext) {
14226 case Dis_Continue:
florian8559e412012-04-19 14:23:48 +000014227 put_IA(mkaddr_expr(guest_IA_next_instr));
florian8844a632012-04-13 04:04:06 +000014228 break;
14229 case Dis_ResteerU:
14230 case Dis_ResteerC:
14231 put_IA(mkaddr_expr(dres.continueAt));
14232 break;
14233 case Dis_StopHere:
14234 break;
14235 default:
14236 vassert(0);
14237 }
sewardj2019a972011-03-07 16:04:07 +000014238 }
14239
14240 return dres;
14241}
14242
14243
14244/*------------------------------------------------------------*/
14245/*--- Top-level fn ---*/
14246/*------------------------------------------------------------*/
14247
14248/* Disassemble a single instruction into IR. The instruction
14249 is located in host memory at &guest_code[delta]. */
14250
14251DisResult
14252disInstr_S390(IRSB *irsb_IN,
sewardj2019a972011-03-07 16:04:07 +000014253 Bool (*resteerOkFn)(void *, Addr64),
14254 Bool resteerCisOk,
14255 void *callback_opaque,
14256 UChar *guest_code,
14257 Long delta,
14258 Addr64 guest_IP,
14259 VexArch guest_arch,
14260 VexArchInfo *archinfo,
14261 VexAbiInfo *abiinfo,
14262 Bool host_bigendian)
14263{
14264 vassert(guest_arch == VexArchS390X);
14265
14266 /* The instruction decoder requires a big-endian machine. */
14267 vassert(host_bigendian == True);
14268
14269 /* Set globals (see top of this file) */
14270 guest_IA_curr_instr = guest_IP;
sewardj2019a972011-03-07 16:04:07 +000014271 irsb = irsb_IN;
florian420c5012011-07-22 02:12:28 +000014272 resteer_fn = resteerOkFn;
14273 resteer_data = callback_opaque;
sewardj2019a972011-03-07 16:04:07 +000014274
florian420c5012011-07-22 02:12:28 +000014275 return disInstr_S390_WRK(guest_code + delta);
sewardj2019a972011-03-07 16:04:07 +000014276}
14277
14278/*---------------------------------------------------------------*/
14279/*--- end guest_s390_toIR.c ---*/
14280/*---------------------------------------------------------------*/