blob: 2f60d47bc64fbfbc4c7857305fd556cd340141e2 [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
146/* Add a dummy put to the guest_IA to satisfy an assert in bb_to_IR
147 that wants the last statement in an IRSB to be a put to the guest_IA.
148 Mostly used for insns that use the "counter" pseudo guest reg. */
149static __inline__ void
150dummy_put_IA(void)
151{
152 put_IA(IRExpr_Get(S390X_GUEST_OFFSET(guest_IA), Ity_I64));
153}
154
sewardj2019a972011-03-07 16:04:07 +0000155/* Create a temporary of the given type and assign the expression to it */
156static __inline__ IRTemp
157mktemp(IRType type, IRExpr *expr)
158{
159 IRTemp temp = newTemp(type);
160
161 assign(temp, expr);
162
163 return temp;
164}
165
166/* Create a unary expression */
167static __inline__ IRExpr *
168unop(IROp kind, IRExpr *op)
169{
170 return IRExpr_Unop(kind, op);
171}
172
173/* Create a binary expression */
174static __inline__ IRExpr *
175binop(IROp kind, IRExpr *op1, IRExpr *op2)
176{
177 return IRExpr_Binop(kind, op1, op2);
178}
179
180/* Create a ternary expression */
181static __inline__ IRExpr *
182triop(IROp kind, IRExpr *op1, IRExpr *op2, IRExpr *op3)
183{
184 return IRExpr_Triop(kind, op1, op2, op3);
185}
186
187/* Create a quaternary expression */
188static __inline__ IRExpr *
189qop(IROp kind, IRExpr *op1, IRExpr *op2, IRExpr *op3, IRExpr *op4)
190{
191 return IRExpr_Qop(kind, op1, op2, op3, op4);
192}
193
194/* Create an expression node for an 8-bit integer constant */
195static __inline__ IRExpr *
196mkU8(UInt value)
197{
198 vassert(value < 256);
199
200 return IRExpr_Const(IRConst_U8((UChar)value));
201}
202
203/* Create an expression node for a 16-bit integer constant */
204static __inline__ IRExpr *
205mkU16(UInt value)
206{
207 vassert(value < 65536);
208
209 return IRExpr_Const(IRConst_U16((UShort)value));
210}
211
212/* Create an expression node for a 32-bit integer constant */
213static __inline__ IRExpr *
214mkU32(UInt value)
215{
216 return IRExpr_Const(IRConst_U32(value));
217}
218
219/* Create an expression node for a 64-bit integer constant */
220static __inline__ IRExpr *
221mkU64(ULong value)
222{
223 return IRExpr_Const(IRConst_U64(value));
224}
225
226/* Create an expression node for a 32-bit floating point constant
227 whose value is given by a bit pattern. */
228static __inline__ IRExpr *
229mkF32i(UInt value)
230{
231 return IRExpr_Const(IRConst_F32i(value));
232}
233
234/* Create an expression node for a 32-bit floating point constant
235 whose value is given by a bit pattern. */
236static __inline__ IRExpr *
237mkF64i(ULong value)
238{
239 return IRExpr_Const(IRConst_F64i(value));
240}
241
242/* Little helper function for my sanity. ITE = if-then-else */
243static IRExpr *
244mkite(IRExpr *condition, IRExpr *iftrue, IRExpr *iffalse)
245{
246 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
247
248 return IRExpr_Mux0X(unop(Iop_1Uto8, condition), iffalse, iftrue);
249}
250
251/* Add a statement that stores DATA at ADDR. This is a big-endian machine. */
252static void __inline__
253store(IRExpr *addr, IRExpr *data)
254{
255 stmt(IRStmt_Store(Iend_BE, addr, data));
256}
257
258/* Create an expression that loads a TYPE sized value from ADDR.
259 This is a big-endian machine. */
260static __inline__ IRExpr *
261load(IRType type, IRExpr *addr)
262{
263 return IRExpr_Load(Iend_BE, type, addr);
264}
265
266/* Function call */
267static void
268call_function(IRExpr *callee_address)
269{
florian8844a632012-04-13 04:04:06 +0000270 put_IA(callee_address);
sewardj2019a972011-03-07 16:04:07 +0000271
florian8844a632012-04-13 04:04:06 +0000272 dis_res->whatNext = Dis_StopHere;
273 dis_res->jk_StopHere = Ijk_Call;
sewardj2019a972011-03-07 16:04:07 +0000274}
275
floriana64c2432011-07-16 02:11:50 +0000276/* Function call with known target. */
277static void
278call_function_and_chase(Addr64 callee_address)
279{
280 if (resteer_fn(resteer_data, callee_address)) {
281 dis_res->whatNext = Dis_ResteerU;
282 dis_res->continueAt = callee_address;
283 } else {
florian8844a632012-04-13 04:04:06 +0000284 put_IA(mkaddr_expr(callee_address));
285
floriana64c2432011-07-16 02:11:50 +0000286 dis_res->whatNext = Dis_StopHere;
florian8844a632012-04-13 04:04:06 +0000287 dis_res->jk_StopHere = Ijk_Call;
floriana64c2432011-07-16 02:11:50 +0000288 }
289}
290
sewardj2019a972011-03-07 16:04:07 +0000291/* Function return sequence */
292static void
293return_from_function(IRExpr *return_address)
294{
florian8844a632012-04-13 04:04:06 +0000295 put_IA(return_address);
sewardj2019a972011-03-07 16:04:07 +0000296
florian8844a632012-04-13 04:04:06 +0000297 dis_res->whatNext = Dis_StopHere;
298 dis_res->jk_StopHere = Ijk_Ret;
sewardj2019a972011-03-07 16:04:07 +0000299}
300
301/* A conditional branch whose target is not known at instrumentation time.
302
303 if (condition) goto computed_target;
304
305 Needs to be represented as:
306
307 if (! condition) goto next_instruction;
308 goto computed_target;
309
310 This inversion is being handled at code generation time. So we just
311 take the condition here as is.
312*/
313static void
314if_not_condition_goto_computed(IRExpr *condition, IRExpr *target)
315{
316 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
317
florian8844a632012-04-13 04:04:06 +0000318 stmt(IRStmt_Exit(condition, Ijk_Boring, IRConst_U64(guest_IA_next_instr),
319 S390X_GUEST_OFFSET(guest_IA)));
sewardj2019a972011-03-07 16:04:07 +0000320
florian8844a632012-04-13 04:04:06 +0000321 put_IA(target);
sewardj2019a972011-03-07 16:04:07 +0000322
florian8844a632012-04-13 04:04:06 +0000323 dis_res->whatNext = Dis_StopHere;
324 dis_res->jk_StopHere = Ijk_Boring;
sewardj2019a972011-03-07 16:04:07 +0000325}
326
327/* A conditional branch whose target is known at instrumentation time. */
328static void
329if_condition_goto(IRExpr *condition, Addr64 target)
330{
331 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
332
florian8844a632012-04-13 04:04:06 +0000333 stmt(IRStmt_Exit(condition, Ijk_Boring, IRConst_U64(target),
334 S390X_GUEST_OFFSET(guest_IA)));
335
florian7346c7a2012-04-13 21:14:24 +0000336 put_IA(mkaddr_expr(guest_IA_next_instr));
florian8844a632012-04-13 04:04:06 +0000337
338 dis_res->whatNext = Dis_StopHere;
339 dis_res->jk_StopHere = Ijk_Boring;
sewardj2019a972011-03-07 16:04:07 +0000340}
341
342/* An unconditional branch. Target may or may not be known at instrumentation
343 time. */
344static void
345always_goto(IRExpr *target)
346{
florian8844a632012-04-13 04:04:06 +0000347 put_IA(target);
sewardj2019a972011-03-07 16:04:07 +0000348
florian8844a632012-04-13 04:04:06 +0000349 dis_res->whatNext = Dis_StopHere;
350 dis_res->jk_StopHere = Ijk_Boring;
sewardj2019a972011-03-07 16:04:07 +0000351}
352
florian8844a632012-04-13 04:04:06 +0000353
floriana64c2432011-07-16 02:11:50 +0000354/* An unconditional branch to a known target. */
355static void
356always_goto_and_chase(Addr64 target)
357{
358 if (resteer_fn(resteer_data, target)) {
florian8844a632012-04-13 04:04:06 +0000359 /* Follow into the target */
floriana64c2432011-07-16 02:11:50 +0000360 dis_res->whatNext = Dis_ResteerU;
361 dis_res->continueAt = target;
362 } else {
florian8844a632012-04-13 04:04:06 +0000363 put_IA(mkaddr_expr(target));
364
365 dis_res->whatNext = Dis_StopHere;
366 dis_res->jk_StopHere = Ijk_Boring;
floriana64c2432011-07-16 02:11:50 +0000367 }
368}
369
sewardj2019a972011-03-07 16:04:07 +0000370/* A system call */
371static void
372system_call(IRExpr *sysno)
373{
374 /* Store the system call number in the pseudo register. */
florian428dfdd2012-03-27 03:09:49 +0000375 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_SYSNO), sysno));
sewardj2019a972011-03-07 16:04:07 +0000376
sewardj69007022011-04-28 20:13:45 +0000377 /* Store the current IA into guest_IP_AT_SYSCALL. libvex_ir.h says so. */
florian428dfdd2012-03-27 03:09:49 +0000378 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_IP_AT_SYSCALL),
379 mkU64(guest_IA_curr_instr)));
sewardj2019a972011-03-07 16:04:07 +0000380
florian8844a632012-04-13 04:04:06 +0000381 put_IA(mkaddr_expr(guest_IA_next_instr));
382
sewardj2019a972011-03-07 16:04:07 +0000383 /* It's important that all ArchRegs carry their up-to-date value
384 at this point. So we declare an end-of-block here, which
385 forces any TempRegs caching ArchRegs to be flushed. */
florian8844a632012-04-13 04:04:06 +0000386 dis_res->whatNext = Dis_StopHere;
387 dis_res->jk_StopHere = Ijk_Sys_syscall;
sewardj2019a972011-03-07 16:04:07 +0000388}
389
390/* Encode the s390 rounding mode as it appears in the m3/m4 fields of certain
391 instructions to VEX's IRRoundingMode. */
392static IRRoundingMode
393encode_rounding_mode(UChar mode)
394{
395 switch (mode) {
396 case S390_ROUND_NEAREST_EVEN: return Irrm_NEAREST;
397 case S390_ROUND_ZERO: return Irrm_ZERO;
398 case S390_ROUND_POSINF: return Irrm_PosINF;
399 case S390_ROUND_NEGINF: return Irrm_NegINF;
400 }
401 vpanic("encode_rounding_mode");
402}
403
404static __inline__ IRExpr *get_fpr_dw0(UInt);
405static __inline__ void put_fpr_dw0(UInt, IRExpr *);
406
407/* Read a floating point register pair and combine their contents into a
408 128-bit value */
409static IRExpr *
410get_fpr_pair(UInt archreg)
411{
412 IRExpr *high = get_fpr_dw0(archreg);
413 IRExpr *low = get_fpr_dw0(archreg + 2);
414
415 return binop(Iop_F64HLtoF128, high, low);
416}
417
418/* Write a 128-bit floating point value into a register pair. */
419static void
420put_fpr_pair(UInt archreg, IRExpr *expr)
421{
422 IRExpr *high = unop(Iop_F128HItoF64, expr);
423 IRExpr *low = unop(Iop_F128LOtoF64, expr);
424
425 put_fpr_dw0(archreg, high);
426 put_fpr_dw0(archreg + 2, low);
427}
428
429
sewardj2019a972011-03-07 16:04:07 +0000430/*------------------------------------------------------------*/
431/*--- Build the flags thunk. ---*/
432/*------------------------------------------------------------*/
433
434/* Completely fill the flags thunk. We're always filling all fields.
435 Apparently, that is better for redundant PUT elimination. */
436static void
437s390_cc_thunk_fill(IRExpr *op, IRExpr *dep1, IRExpr *dep2, IRExpr *ndep)
438{
439 UInt op_off, dep1_off, dep2_off, ndep_off;
440
florian428dfdd2012-03-27 03:09:49 +0000441 op_off = S390X_GUEST_OFFSET(guest_CC_OP);
442 dep1_off = S390X_GUEST_OFFSET(guest_CC_DEP1);
443 dep2_off = S390X_GUEST_OFFSET(guest_CC_DEP2);
444 ndep_off = S390X_GUEST_OFFSET(guest_CC_NDEP);
sewardj2019a972011-03-07 16:04:07 +0000445
446 stmt(IRStmt_Put(op_off, op));
447 stmt(IRStmt_Put(dep1_off, dep1));
448 stmt(IRStmt_Put(dep2_off, dep2));
449 stmt(IRStmt_Put(ndep_off, ndep));
450}
451
452
453/* Create an expression for V and widen the result to 64 bit. */
454static IRExpr *
455s390_cc_widen(IRTemp v, Bool sign_extend)
456{
457 IRExpr *expr;
458
459 expr = mkexpr(v);
460
461 switch (typeOfIRTemp(irsb->tyenv, v)) {
462 case Ity_I64:
463 break;
464 case Ity_I32:
465 expr = unop(sign_extend ? Iop_32Sto64 : Iop_32Uto64, expr);
466 break;
467 case Ity_I16:
468 expr = unop(sign_extend ? Iop_16Sto64 : Iop_16Uto64, expr);
469 break;
470 case Ity_I8:
471 expr = unop(sign_extend ? Iop_8Sto64 : Iop_8Uto64, expr);
472 break;
473 default:
474 vpanic("s390_cc_widen");
475 }
476
477 return expr;
478}
479
480static void
481s390_cc_thunk_put1(UInt opc, IRTemp d1, Bool sign_extend)
482{
483 IRExpr *op, *dep1, *dep2, *ndep;
484
485 op = mkU64(opc);
486 dep1 = s390_cc_widen(d1, sign_extend);
487 dep2 = mkU64(0);
488 ndep = mkU64(0);
489
490 s390_cc_thunk_fill(op, dep1, dep2, ndep);
491}
492
493
494static void
495s390_cc_thunk_put2(UInt opc, IRTemp d1, IRTemp d2, Bool sign_extend)
496{
497 IRExpr *op, *dep1, *dep2, *ndep;
498
499 op = mkU64(opc);
500 dep1 = s390_cc_widen(d1, sign_extend);
501 dep2 = s390_cc_widen(d2, sign_extend);
502 ndep = mkU64(0);
503
504 s390_cc_thunk_fill(op, dep1, dep2, ndep);
505}
506
507
508/* memcheck believes that the NDEP field in the flags thunk is always
509 defined. But for some flag computations (e.g. add with carry) that is
510 just not true. We therefore need to convey to memcheck that the value
511 of the ndep field does matter and therefore we make the DEP2 field
512 depend on it:
513
514 DEP2 = original_DEP2 ^ NDEP
515
516 In s390_calculate_cc we exploit that (a^b)^b == a
517 I.e. we xor the DEP2 value with the NDEP value to recover the
518 original_DEP2 value. */
519static void
520s390_cc_thunk_put3(UInt opc, IRTemp d1, IRTemp d2, IRTemp nd, Bool sign_extend)
521{
522 IRExpr *op, *dep1, *dep2, *ndep, *dep2x;
523
524 op = mkU64(opc);
525 dep1 = s390_cc_widen(d1, sign_extend);
526 dep2 = s390_cc_widen(d2, sign_extend);
527 ndep = s390_cc_widen(nd, sign_extend);
528
529 dep2x = binop(Iop_Xor64, dep2, ndep);
530
531 s390_cc_thunk_fill(op, dep1, dep2x, ndep);
532}
533
534
535/* Write one floating point value into the flags thunk */
536static void
537s390_cc_thunk_put1f(UInt opc, IRTemp d1)
538{
539 IRExpr *op, *dep1, *dep2, *ndep;
540
541 op = mkU64(opc);
542 dep1 = mkexpr(d1);
543 dep2 = mkU64(0);
544 ndep = mkU64(0);
545
546 s390_cc_thunk_fill(op, dep1, dep2, ndep);
547}
548
549
550/* Write a floating point value and an integer into the flags thunk. The
551 integer value is zero-extended first. */
552static void
553s390_cc_thunk_putFZ(UInt opc, IRTemp d1, IRTemp d2)
554{
555 IRExpr *op, *dep1, *dep2, *ndep;
556
557 op = mkU64(opc);
558 dep1 = mkexpr(d1);
559 dep2 = s390_cc_widen(d2, False);
560 ndep = mkU64(0);
561
562 s390_cc_thunk_fill(op, dep1, dep2, ndep);
563}
564
565
566/* Write a 128-bit floating point value into the flags thunk. This is
567 done by splitting the value into two 64-bits values. */
568static void
569s390_cc_thunk_put1f128(UInt opc, IRTemp d1)
570{
571 IRExpr *op, *hi, *lo, *ndep;
572
573 op = mkU64(opc);
574 hi = unop(Iop_F128HItoF64, mkexpr(d1));
575 lo = unop(Iop_F128LOtoF64, mkexpr(d1));
576 ndep = mkU64(0);
577
578 s390_cc_thunk_fill(op, hi, lo, ndep);
579}
580
581
582/* Write a 128-bit floating point value and an integer into the flags thunk.
583 The integer value is zero-extended first. */
584static void
585s390_cc_thunk_put1f128Z(UInt opc, IRTemp d1, IRTemp nd)
586{
587 IRExpr *op, *hi, *lo, *lox, *ndep;
588
589 op = mkU64(opc);
590 hi = unop(Iop_F128HItoF64, mkexpr(d1));
591 lo = unop(Iop_ReinterpF64asI64, unop(Iop_F128LOtoF64, mkexpr(d1)));
592 ndep = s390_cc_widen(nd, False);
593
594 lox = binop(Iop_Xor64, lo, ndep); /* convey dependency */
595
596 s390_cc_thunk_fill(op, hi, lox, ndep);
597}
598
599
600static void
601s390_cc_set(UInt val)
602{
603 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
604 mkU64(val), mkU64(0), mkU64(0));
605}
606
607/* Build IR to calculate the condition code from flags thunk.
608 Returns an expression of type Ity_I32 */
609static IRExpr *
610s390_call_calculate_cc(void)
611{
612 IRExpr **args, *call, *op, *dep1, *dep2, *ndep;
613
florian428dfdd2012-03-27 03:09:49 +0000614 op = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_OP), Ity_I64);
615 dep1 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP1), Ity_I64);
616 dep2 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP2), Ity_I64);
617 ndep = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_NDEP), Ity_I64);
sewardj2019a972011-03-07 16:04:07 +0000618
619 args = mkIRExprVec_4(op, dep1, dep2, ndep);
620 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
621 "s390_calculate_cc", &s390_calculate_cc, args);
622
623 /* Exclude OP and NDEP from definedness checking. We're only
624 interested in DEP1 and DEP2. */
625 call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<3);
626
627 return call;
628}
629
630/* Build IR to calculate the internal condition code for a "compare and branch"
631 insn. Returns an expression of type Ity_I32 */
632static IRExpr *
florianff9613f2012-05-12 15:26:44 +0000633s390_call_calculate_icc(UInt m, UInt opc, IRTemp op1, IRTemp op2)
sewardj2019a972011-03-07 16:04:07 +0000634{
florianff9613f2012-05-12 15:26:44 +0000635 IRExpr **args, *call, *op, *dep1, *dep2, *mask;
sewardj2019a972011-03-07 16:04:07 +0000636
florianff9613f2012-05-12 15:26:44 +0000637 switch (opc) {
638 case S390_CC_OP_SIGNED_COMPARE:
639 dep1 = s390_cc_widen(op1, True);
640 dep2 = s390_cc_widen(op2, True);
641 break;
642
643 case S390_CC_OP_UNSIGNED_COMPARE:
644 dep1 = s390_cc_widen(op1, False);
645 dep2 = s390_cc_widen(op2, False);
646 break;
647
648 default:
649 vpanic("s390_call_calculate_icc");
650 }
651
652 mask = mkU64(m);
sewardj2019a972011-03-07 16:04:07 +0000653 op = mkU64(opc);
sewardj2019a972011-03-07 16:04:07 +0000654
florianff9613f2012-05-12 15:26:44 +0000655 args = mkIRExprVec_5(mask, op, dep1, dep2, mkU64(0) /* unused */);
sewardj2019a972011-03-07 16:04:07 +0000656 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
florianff9613f2012-05-12 15:26:44 +0000657 "s390_calculate_cond", &s390_calculate_cond, args);
sewardj2019a972011-03-07 16:04:07 +0000658
florianff9613f2012-05-12 15:26:44 +0000659 /* Exclude the requested condition, OP and NDEP from definedness
660 checking. We're only interested in DEP1 and DEP2. */
661 call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<1) | (1<<4);
sewardj2019a972011-03-07 16:04:07 +0000662
663 return call;
664}
665
666/* Build IR to calculate the condition code from flags thunk.
667 Returns an expression of type Ity_I32 */
668static IRExpr *
669s390_call_calculate_cond(UInt m)
670{
671 IRExpr **args, *call, *op, *dep1, *dep2, *ndep, *mask;
672
673 mask = mkU64(m);
florian428dfdd2012-03-27 03:09:49 +0000674 op = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_OP), Ity_I64);
675 dep1 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP1), Ity_I64);
676 dep2 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP2), Ity_I64);
677 ndep = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_NDEP), Ity_I64);
sewardj2019a972011-03-07 16:04:07 +0000678
679 args = mkIRExprVec_5(mask, op, dep1, dep2, ndep);
680 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
681 "s390_calculate_cond", &s390_calculate_cond, args);
682
683 /* Exclude the requested condition, OP and NDEP from definedness
684 checking. We're only interested in DEP1 and DEP2. */
685 call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<1) | (1<<4);
686
687 return call;
688}
689
690#define s390_cc_thunk_putZ(op,dep1) s390_cc_thunk_put1(op,dep1,False)
691#define s390_cc_thunk_putS(op,dep1) s390_cc_thunk_put1(op,dep1,True)
692#define s390_cc_thunk_putF(op,dep1) s390_cc_thunk_put1f(op,dep1)
693#define s390_cc_thunk_putZZ(op,dep1,dep2) s390_cc_thunk_put2(op,dep1,dep2,False)
694#define s390_cc_thunk_putSS(op,dep1,dep2) s390_cc_thunk_put2(op,dep1,dep2,True)
695#define s390_cc_thunk_putFF(op,dep1,dep2) s390_cc_thunk_put2f(op,dep1,dep2)
696#define s390_cc_thunk_putZZZ(op,dep1,dep2,ndep) \
697 s390_cc_thunk_put3(op,dep1,dep2,ndep,False)
698#define s390_cc_thunk_putSSS(op,dep1,dep2,ndep) \
699 s390_cc_thunk_put3(op,dep1,dep2,ndep,True)
sewardj2019a972011-03-07 16:04:07 +0000700
701
sewardj2019a972011-03-07 16:04:07 +0000702
703
704/*------------------------------------------------------------*/
705/*--- Guest register access ---*/
706/*------------------------------------------------------------*/
707
708
709/*------------------------------------------------------------*/
710/*--- ar registers ---*/
711/*------------------------------------------------------------*/
712
713/* Return the guest state offset of a ar register. */
714static UInt
715ar_offset(UInt archreg)
716{
717 static const UInt offset[16] = {
floriane88b3c92011-07-05 02:48:39 +0000718 S390X_GUEST_OFFSET(guest_a0),
719 S390X_GUEST_OFFSET(guest_a1),
720 S390X_GUEST_OFFSET(guest_a2),
721 S390X_GUEST_OFFSET(guest_a3),
722 S390X_GUEST_OFFSET(guest_a4),
723 S390X_GUEST_OFFSET(guest_a5),
724 S390X_GUEST_OFFSET(guest_a6),
725 S390X_GUEST_OFFSET(guest_a7),
726 S390X_GUEST_OFFSET(guest_a8),
727 S390X_GUEST_OFFSET(guest_a9),
728 S390X_GUEST_OFFSET(guest_a10),
729 S390X_GUEST_OFFSET(guest_a11),
730 S390X_GUEST_OFFSET(guest_a12),
731 S390X_GUEST_OFFSET(guest_a13),
732 S390X_GUEST_OFFSET(guest_a14),
733 S390X_GUEST_OFFSET(guest_a15),
sewardj2019a972011-03-07 16:04:07 +0000734 };
735
736 vassert(archreg < 16);
737
738 return offset[archreg];
739}
740
741
742/* Return the guest state offset of word #0 of a ar register. */
743static __inline__ UInt
744ar_w0_offset(UInt archreg)
745{
746 return ar_offset(archreg) + 0;
747}
748
749/* Write word #0 of a ar to the guest state. */
750static __inline__ void
751put_ar_w0(UInt archreg, IRExpr *expr)
752{
753 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
754
755 stmt(IRStmt_Put(ar_w0_offset(archreg), expr));
756}
757
758/* Read word #0 of a ar register. */
759static __inline__ IRExpr *
760get_ar_w0(UInt archreg)
761{
762 return IRExpr_Get(ar_w0_offset(archreg), Ity_I32);
763}
764
765
766/*------------------------------------------------------------*/
767/*--- fpr registers ---*/
768/*------------------------------------------------------------*/
769
770/* Return the guest state offset of a fpr register. */
771static UInt
772fpr_offset(UInt archreg)
773{
774 static const UInt offset[16] = {
floriane88b3c92011-07-05 02:48:39 +0000775 S390X_GUEST_OFFSET(guest_f0),
776 S390X_GUEST_OFFSET(guest_f1),
777 S390X_GUEST_OFFSET(guest_f2),
778 S390X_GUEST_OFFSET(guest_f3),
779 S390X_GUEST_OFFSET(guest_f4),
780 S390X_GUEST_OFFSET(guest_f5),
781 S390X_GUEST_OFFSET(guest_f6),
782 S390X_GUEST_OFFSET(guest_f7),
783 S390X_GUEST_OFFSET(guest_f8),
784 S390X_GUEST_OFFSET(guest_f9),
785 S390X_GUEST_OFFSET(guest_f10),
786 S390X_GUEST_OFFSET(guest_f11),
787 S390X_GUEST_OFFSET(guest_f12),
788 S390X_GUEST_OFFSET(guest_f13),
789 S390X_GUEST_OFFSET(guest_f14),
790 S390X_GUEST_OFFSET(guest_f15),
sewardj2019a972011-03-07 16:04:07 +0000791 };
792
793 vassert(archreg < 16);
794
795 return offset[archreg];
796}
797
798
799/* Return the guest state offset of word #0 of a fpr register. */
800static __inline__ UInt
801fpr_w0_offset(UInt archreg)
802{
803 return fpr_offset(archreg) + 0;
804}
805
806/* Write word #0 of a fpr to the guest state. */
807static __inline__ void
808put_fpr_w0(UInt archreg, IRExpr *expr)
809{
810 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_F32);
811
812 stmt(IRStmt_Put(fpr_w0_offset(archreg), expr));
813}
814
815/* Read word #0 of a fpr register. */
816static __inline__ IRExpr *
817get_fpr_w0(UInt archreg)
818{
819 return IRExpr_Get(fpr_w0_offset(archreg), Ity_F32);
820}
821
822/* Return the guest state offset of double word #0 of a fpr register. */
823static __inline__ UInt
824fpr_dw0_offset(UInt archreg)
825{
826 return fpr_offset(archreg) + 0;
827}
828
829/* Write double word #0 of a fpr to the guest state. */
830static __inline__ void
831put_fpr_dw0(UInt archreg, IRExpr *expr)
832{
833 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_F64);
834
835 stmt(IRStmt_Put(fpr_dw0_offset(archreg), expr));
836}
837
838/* Read double word #0 of a fpr register. */
839static __inline__ IRExpr *
840get_fpr_dw0(UInt archreg)
841{
842 return IRExpr_Get(fpr_dw0_offset(archreg), Ity_F64);
843}
844
845
846/*------------------------------------------------------------*/
847/*--- gpr registers ---*/
848/*------------------------------------------------------------*/
849
850/* Return the guest state offset of a gpr register. */
851static UInt
852gpr_offset(UInt archreg)
853{
854 static const UInt offset[16] = {
floriane88b3c92011-07-05 02:48:39 +0000855 S390X_GUEST_OFFSET(guest_r0),
856 S390X_GUEST_OFFSET(guest_r1),
857 S390X_GUEST_OFFSET(guest_r2),
858 S390X_GUEST_OFFSET(guest_r3),
859 S390X_GUEST_OFFSET(guest_r4),
860 S390X_GUEST_OFFSET(guest_r5),
861 S390X_GUEST_OFFSET(guest_r6),
862 S390X_GUEST_OFFSET(guest_r7),
863 S390X_GUEST_OFFSET(guest_r8),
864 S390X_GUEST_OFFSET(guest_r9),
865 S390X_GUEST_OFFSET(guest_r10),
866 S390X_GUEST_OFFSET(guest_r11),
867 S390X_GUEST_OFFSET(guest_r12),
868 S390X_GUEST_OFFSET(guest_r13),
869 S390X_GUEST_OFFSET(guest_r14),
870 S390X_GUEST_OFFSET(guest_r15),
sewardj2019a972011-03-07 16:04:07 +0000871 };
872
873 vassert(archreg < 16);
874
875 return offset[archreg];
876}
877
878
879/* Return the guest state offset of word #0 of a gpr register. */
880static __inline__ UInt
881gpr_w0_offset(UInt archreg)
882{
883 return gpr_offset(archreg) + 0;
884}
885
886/* Write word #0 of a gpr to the guest state. */
887static __inline__ void
888put_gpr_w0(UInt archreg, IRExpr *expr)
889{
890 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
891
892 stmt(IRStmt_Put(gpr_w0_offset(archreg), expr));
893}
894
895/* Read word #0 of a gpr register. */
896static __inline__ IRExpr *
897get_gpr_w0(UInt archreg)
898{
899 return IRExpr_Get(gpr_w0_offset(archreg), Ity_I32);
900}
901
902/* Return the guest state offset of double word #0 of a gpr register. */
903static __inline__ UInt
904gpr_dw0_offset(UInt archreg)
905{
906 return gpr_offset(archreg) + 0;
907}
908
909/* Write double word #0 of a gpr to the guest state. */
910static __inline__ void
911put_gpr_dw0(UInt archreg, IRExpr *expr)
912{
913 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I64);
914
915 stmt(IRStmt_Put(gpr_dw0_offset(archreg), expr));
916}
917
918/* Read double word #0 of a gpr register. */
919static __inline__ IRExpr *
920get_gpr_dw0(UInt archreg)
921{
922 return IRExpr_Get(gpr_dw0_offset(archreg), Ity_I64);
923}
924
925/* Return the guest state offset of half word #1 of a gpr register. */
926static __inline__ UInt
927gpr_hw1_offset(UInt archreg)
928{
929 return gpr_offset(archreg) + 2;
930}
931
932/* Write half word #1 of a gpr to the guest state. */
933static __inline__ void
934put_gpr_hw1(UInt archreg, IRExpr *expr)
935{
936 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
937
938 stmt(IRStmt_Put(gpr_hw1_offset(archreg), expr));
939}
940
941/* Read half word #1 of a gpr register. */
942static __inline__ IRExpr *
943get_gpr_hw1(UInt archreg)
944{
945 return IRExpr_Get(gpr_hw1_offset(archreg), Ity_I16);
946}
947
948/* Return the guest state offset of byte #6 of a gpr register. */
949static __inline__ UInt
950gpr_b6_offset(UInt archreg)
951{
952 return gpr_offset(archreg) + 6;
953}
954
955/* Write byte #6 of a gpr to the guest state. */
956static __inline__ void
957put_gpr_b6(UInt archreg, IRExpr *expr)
958{
959 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
960
961 stmt(IRStmt_Put(gpr_b6_offset(archreg), expr));
962}
963
964/* Read byte #6 of a gpr register. */
965static __inline__ IRExpr *
966get_gpr_b6(UInt archreg)
967{
968 return IRExpr_Get(gpr_b6_offset(archreg), Ity_I8);
969}
970
971/* Return the guest state offset of byte #3 of a gpr register. */
972static __inline__ UInt
973gpr_b3_offset(UInt archreg)
974{
975 return gpr_offset(archreg) + 3;
976}
977
978/* Write byte #3 of a gpr to the guest state. */
979static __inline__ void
980put_gpr_b3(UInt archreg, IRExpr *expr)
981{
982 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
983
984 stmt(IRStmt_Put(gpr_b3_offset(archreg), expr));
985}
986
987/* Read byte #3 of a gpr register. */
988static __inline__ IRExpr *
989get_gpr_b3(UInt archreg)
990{
991 return IRExpr_Get(gpr_b3_offset(archreg), Ity_I8);
992}
993
994/* Return the guest state offset of byte #0 of a gpr register. */
995static __inline__ UInt
996gpr_b0_offset(UInt archreg)
997{
998 return gpr_offset(archreg) + 0;
999}
1000
1001/* Write byte #0 of a gpr to the guest state. */
1002static __inline__ void
1003put_gpr_b0(UInt archreg, IRExpr *expr)
1004{
1005 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1006
1007 stmt(IRStmt_Put(gpr_b0_offset(archreg), expr));
1008}
1009
1010/* Read byte #0 of a gpr register. */
1011static __inline__ IRExpr *
1012get_gpr_b0(UInt archreg)
1013{
1014 return IRExpr_Get(gpr_b0_offset(archreg), Ity_I8);
1015}
1016
1017/* Return the guest state offset of word #1 of a gpr register. */
1018static __inline__ UInt
1019gpr_w1_offset(UInt archreg)
1020{
1021 return gpr_offset(archreg) + 4;
1022}
1023
1024/* Write word #1 of a gpr to the guest state. */
1025static __inline__ void
1026put_gpr_w1(UInt archreg, IRExpr *expr)
1027{
1028 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1029
1030 stmt(IRStmt_Put(gpr_w1_offset(archreg), expr));
1031}
1032
1033/* Read word #1 of a gpr register. */
1034static __inline__ IRExpr *
1035get_gpr_w1(UInt archreg)
1036{
1037 return IRExpr_Get(gpr_w1_offset(archreg), Ity_I32);
1038}
1039
1040/* Return the guest state offset of half word #3 of a gpr register. */
1041static __inline__ UInt
1042gpr_hw3_offset(UInt archreg)
1043{
1044 return gpr_offset(archreg) + 6;
1045}
1046
1047/* Write half word #3 of a gpr to the guest state. */
1048static __inline__ void
1049put_gpr_hw3(UInt archreg, IRExpr *expr)
1050{
1051 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1052
1053 stmt(IRStmt_Put(gpr_hw3_offset(archreg), expr));
1054}
1055
1056/* Read half word #3 of a gpr register. */
1057static __inline__ IRExpr *
1058get_gpr_hw3(UInt archreg)
1059{
1060 return IRExpr_Get(gpr_hw3_offset(archreg), Ity_I16);
1061}
1062
1063/* Return the guest state offset of byte #7 of a gpr register. */
1064static __inline__ UInt
1065gpr_b7_offset(UInt archreg)
1066{
1067 return gpr_offset(archreg) + 7;
1068}
1069
1070/* Write byte #7 of a gpr to the guest state. */
1071static __inline__ void
1072put_gpr_b7(UInt archreg, IRExpr *expr)
1073{
1074 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1075
1076 stmt(IRStmt_Put(gpr_b7_offset(archreg), expr));
1077}
1078
1079/* Read byte #7 of a gpr register. */
1080static __inline__ IRExpr *
1081get_gpr_b7(UInt archreg)
1082{
1083 return IRExpr_Get(gpr_b7_offset(archreg), Ity_I8);
1084}
1085
1086/* Return the guest state offset of half word #0 of a gpr register. */
1087static __inline__ UInt
1088gpr_hw0_offset(UInt archreg)
1089{
1090 return gpr_offset(archreg) + 0;
1091}
1092
1093/* Write half word #0 of a gpr to the guest state. */
1094static __inline__ void
1095put_gpr_hw0(UInt archreg, IRExpr *expr)
1096{
1097 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1098
1099 stmt(IRStmt_Put(gpr_hw0_offset(archreg), expr));
1100}
1101
1102/* Read half word #0 of a gpr register. */
1103static __inline__ IRExpr *
1104get_gpr_hw0(UInt archreg)
1105{
1106 return IRExpr_Get(gpr_hw0_offset(archreg), Ity_I16);
1107}
1108
1109/* Return the guest state offset of byte #4 of a gpr register. */
1110static __inline__ UInt
1111gpr_b4_offset(UInt archreg)
1112{
1113 return gpr_offset(archreg) + 4;
1114}
1115
1116/* Write byte #4 of a gpr to the guest state. */
1117static __inline__ void
1118put_gpr_b4(UInt archreg, IRExpr *expr)
1119{
1120 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1121
1122 stmt(IRStmt_Put(gpr_b4_offset(archreg), expr));
1123}
1124
1125/* Read byte #4 of a gpr register. */
1126static __inline__ IRExpr *
1127get_gpr_b4(UInt archreg)
1128{
1129 return IRExpr_Get(gpr_b4_offset(archreg), Ity_I8);
1130}
1131
1132/* Return the guest state offset of byte #1 of a gpr register. */
1133static __inline__ UInt
1134gpr_b1_offset(UInt archreg)
1135{
1136 return gpr_offset(archreg) + 1;
1137}
1138
1139/* Write byte #1 of a gpr to the guest state. */
1140static __inline__ void
1141put_gpr_b1(UInt archreg, IRExpr *expr)
1142{
1143 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1144
1145 stmt(IRStmt_Put(gpr_b1_offset(archreg), expr));
1146}
1147
1148/* Read byte #1 of a gpr register. */
1149static __inline__ IRExpr *
1150get_gpr_b1(UInt archreg)
1151{
1152 return IRExpr_Get(gpr_b1_offset(archreg), Ity_I8);
1153}
1154
1155/* Return the guest state offset of half word #2 of a gpr register. */
1156static __inline__ UInt
1157gpr_hw2_offset(UInt archreg)
1158{
1159 return gpr_offset(archreg) + 4;
1160}
1161
1162/* Write half word #2 of a gpr to the guest state. */
1163static __inline__ void
1164put_gpr_hw2(UInt archreg, IRExpr *expr)
1165{
1166 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1167
1168 stmt(IRStmt_Put(gpr_hw2_offset(archreg), expr));
1169}
1170
1171/* Read half word #2 of a gpr register. */
1172static __inline__ IRExpr *
1173get_gpr_hw2(UInt archreg)
1174{
1175 return IRExpr_Get(gpr_hw2_offset(archreg), Ity_I16);
1176}
1177
1178/* Return the guest state offset of byte #5 of a gpr register. */
1179static __inline__ UInt
1180gpr_b5_offset(UInt archreg)
1181{
1182 return gpr_offset(archreg) + 5;
1183}
1184
1185/* Write byte #5 of a gpr to the guest state. */
1186static __inline__ void
1187put_gpr_b5(UInt archreg, IRExpr *expr)
1188{
1189 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1190
1191 stmt(IRStmt_Put(gpr_b5_offset(archreg), expr));
1192}
1193
1194/* Read byte #5 of a gpr register. */
1195static __inline__ IRExpr *
1196get_gpr_b5(UInt archreg)
1197{
1198 return IRExpr_Get(gpr_b5_offset(archreg), Ity_I8);
1199}
1200
1201/* Return the guest state offset of byte #2 of a gpr register. */
1202static __inline__ UInt
1203gpr_b2_offset(UInt archreg)
1204{
1205 return gpr_offset(archreg) + 2;
1206}
1207
1208/* Write byte #2 of a gpr to the guest state. */
1209static __inline__ void
1210put_gpr_b2(UInt archreg, IRExpr *expr)
1211{
1212 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1213
1214 stmt(IRStmt_Put(gpr_b2_offset(archreg), expr));
1215}
1216
1217/* Read byte #2 of a gpr register. */
1218static __inline__ IRExpr *
1219get_gpr_b2(UInt archreg)
1220{
1221 return IRExpr_Get(gpr_b2_offset(archreg), Ity_I8);
1222}
1223
1224/* Return the guest state offset of the counter register. */
1225static UInt
1226counter_offset(void)
1227{
floriane88b3c92011-07-05 02:48:39 +00001228 return S390X_GUEST_OFFSET(guest_counter);
sewardj2019a972011-03-07 16:04:07 +00001229}
1230
1231/* Return the guest state offset of double word #0 of the counter register. */
1232static __inline__ UInt
1233counter_dw0_offset(void)
1234{
1235 return counter_offset() + 0;
1236}
1237
1238/* Write double word #0 of the counter to the guest state. */
1239static __inline__ void
1240put_counter_dw0(IRExpr *expr)
1241{
1242 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I64);
1243
1244 stmt(IRStmt_Put(counter_dw0_offset(), expr));
1245}
1246
1247/* Read double word #0 of the counter register. */
1248static __inline__ IRExpr *
1249get_counter_dw0(void)
1250{
1251 return IRExpr_Get(counter_dw0_offset(), Ity_I64);
1252}
1253
1254/* Return the guest state offset of word #0 of the counter register. */
1255static __inline__ UInt
1256counter_w0_offset(void)
1257{
1258 return counter_offset() + 0;
1259}
1260
1261/* Return the guest state offset of word #1 of the counter register. */
1262static __inline__ UInt
1263counter_w1_offset(void)
1264{
1265 return counter_offset() + 4;
1266}
1267
1268/* Write word #0 of the counter to the guest state. */
1269static __inline__ void
1270put_counter_w0(IRExpr *expr)
1271{
1272 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1273
1274 stmt(IRStmt_Put(counter_w0_offset(), expr));
1275}
1276
1277/* Read word #0 of the counter register. */
1278static __inline__ IRExpr *
1279get_counter_w0(void)
1280{
1281 return IRExpr_Get(counter_w0_offset(), Ity_I32);
1282}
1283
1284/* Write word #1 of the counter to the guest state. */
1285static __inline__ void
1286put_counter_w1(IRExpr *expr)
1287{
1288 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1289
1290 stmt(IRStmt_Put(counter_w1_offset(), expr));
1291}
1292
1293/* Read word #1 of the counter register. */
1294static __inline__ IRExpr *
1295get_counter_w1(void)
1296{
1297 return IRExpr_Get(counter_w1_offset(), Ity_I32);
1298}
1299
1300/* Return the guest state offset of the fpc register. */
1301static UInt
1302fpc_offset(void)
1303{
floriane88b3c92011-07-05 02:48:39 +00001304 return S390X_GUEST_OFFSET(guest_fpc);
sewardj2019a972011-03-07 16:04:07 +00001305}
1306
1307/* Return the guest state offset of word #0 of the fpc register. */
1308static __inline__ UInt
1309fpc_w0_offset(void)
1310{
1311 return fpc_offset() + 0;
1312}
1313
1314/* Write word #0 of the fpc to the guest state. */
1315static __inline__ void
1316put_fpc_w0(IRExpr *expr)
1317{
1318 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1319
1320 stmt(IRStmt_Put(fpc_w0_offset(), expr));
1321}
1322
1323/* Read word #0 of the fpc register. */
1324static __inline__ IRExpr *
1325get_fpc_w0(void)
1326{
1327 return IRExpr_Get(fpc_w0_offset(), Ity_I32);
1328}
1329
1330
1331/*------------------------------------------------------------*/
1332/*--- Build IR for formats ---*/
1333/*------------------------------------------------------------*/
1334static void
1335s390_format_I(HChar *(*irgen)(UChar i),
1336 UChar i)
1337{
1338 HChar *mnm = irgen(i);
1339
sewardj7ee97522011-05-09 21:45:04 +00001340 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001341 s390_disasm(ENC2(MNM, UINT), mnm, i);
1342}
1343
1344static void
1345s390_format_RI(HChar *(*irgen)(UChar r1, UShort i2),
1346 UChar r1, UShort i2)
1347{
1348 irgen(r1, i2);
1349}
1350
1351static void
1352s390_format_RI_RU(HChar *(*irgen)(UChar r1, UShort i2),
1353 UChar r1, UShort i2)
1354{
1355 HChar *mnm = irgen(r1, i2);
1356
sewardj7ee97522011-05-09 21:45:04 +00001357 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001358 s390_disasm(ENC3(MNM, GPR, UINT), mnm, r1, i2);
1359}
1360
1361static void
1362s390_format_RI_RI(HChar *(*irgen)(UChar r1, UShort i2),
1363 UChar r1, UShort i2)
1364{
1365 HChar *mnm = irgen(r1, i2);
1366
sewardj7ee97522011-05-09 21:45:04 +00001367 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001368 s390_disasm(ENC3(MNM, GPR, INT), mnm, r1, (Int)(Short)i2);
1369}
1370
1371static void
1372s390_format_RI_RP(HChar *(*irgen)(UChar r1, UShort i2),
1373 UChar r1, UShort i2)
1374{
1375 HChar *mnm = irgen(r1, i2);
1376
sewardj7ee97522011-05-09 21:45:04 +00001377 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001378 s390_disasm(ENC3(MNM, GPR, PCREL), mnm, r1, (Int)(Short)i2);
1379}
1380
1381static void
1382s390_format_RIE_RRP(HChar *(*irgen)(UChar r1, UChar r3, UShort i2),
1383 UChar r1, UChar r3, UShort i2)
1384{
1385 HChar *mnm = irgen(r1, r3, i2);
1386
sewardj7ee97522011-05-09 21:45:04 +00001387 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001388 s390_disasm(ENC4(MNM, GPR, GPR, PCREL), mnm, r1, r3, (Int)(Short)i2);
1389}
1390
1391static void
1392s390_format_RIE_RRI0(HChar *(*irgen)(UChar r1, UChar r3, UShort i2),
1393 UChar r1, UChar r3, UShort i2)
1394{
1395 HChar *mnm = irgen(r1, r3, i2);
1396
sewardj7ee97522011-05-09 21:45:04 +00001397 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001398 s390_disasm(ENC4(MNM, GPR, GPR, INT), mnm, r1, r3, (Int)(Short)i2);
1399}
1400
1401static void
1402s390_format_RIE_RRUUU(HChar *(*irgen)(UChar r1, UChar r2, UChar i3, UChar i4,
1403 UChar i5),
1404 UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
1405{
1406 HChar *mnm = irgen(r1, r2, i3, i4, i5);
1407
sewardj7ee97522011-05-09 21:45:04 +00001408 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001409 s390_disasm(ENC6(MNM, GPR, GPR, UINT, UINT, UINT), mnm, r1, r2, i3, i4,
1410 i5);
1411}
1412
1413static void
1414s390_format_RIE_RRPU(HChar *(*irgen)(UChar r1, UChar r2, UShort i4, UChar m3),
1415 UChar r1, UChar r2, UShort i4, UChar m3)
1416{
1417 HChar *mnm = irgen(r1, r2, i4, m3);
1418
sewardj7ee97522011-05-09 21:45:04 +00001419 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001420 s390_disasm(ENC5(XMNM, GPR, GPR, CABM, PCREL), S390_XMNM_CAB, mnm, m3, r1,
1421 r2, m3, (Int)(Short)i4);
1422}
1423
1424static void
1425s390_format_RIE_RUPU(HChar *(*irgen)(UChar r1, UChar m3, UShort i4, UChar i2),
1426 UChar r1, UChar m3, UShort i4, UChar i2)
1427{
1428 HChar *mnm = irgen(r1, m3, i4, i2);
1429
sewardj7ee97522011-05-09 21:45:04 +00001430 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001431 s390_disasm(ENC5(XMNM, GPR, UINT, CABM, PCREL), S390_XMNM_CAB, mnm, m3,
1432 r1, i2, m3, (Int)(Short)i4);
1433}
1434
1435static void
1436s390_format_RIE_RUPI(HChar *(*irgen)(UChar r1, UChar m3, UShort i4, UChar i2),
1437 UChar r1, UChar m3, UShort i4, UChar i2)
1438{
1439 HChar *mnm = irgen(r1, m3, i4, i2);
1440
sewardj7ee97522011-05-09 21:45:04 +00001441 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001442 s390_disasm(ENC5(XMNM, GPR, INT, CABM, PCREL), S390_XMNM_CAB, mnm, m3, r1,
1443 (Int)(Char)i2, m3, (Int)(Short)i4);
1444}
1445
1446static void
1447s390_format_RIL(HChar *(*irgen)(UChar r1, UInt i2),
1448 UChar r1, UInt i2)
1449{
1450 irgen(r1, i2);
1451}
1452
1453static void
1454s390_format_RIL_RU(HChar *(*irgen)(UChar r1, UInt i2),
1455 UChar r1, UInt i2)
1456{
1457 HChar *mnm = irgen(r1, 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(ENC3(MNM, GPR, UINT), mnm, r1, i2);
1461}
1462
1463static void
1464s390_format_RIL_RI(HChar *(*irgen)(UChar r1, UInt i2),
1465 UChar r1, UInt i2)
1466{
1467 HChar *mnm = irgen(r1, i2);
1468
sewardj7ee97522011-05-09 21:45:04 +00001469 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001470 s390_disasm(ENC3(MNM, GPR, INT), mnm, r1, i2);
1471}
1472
1473static void
1474s390_format_RIL_RP(HChar *(*irgen)(UChar r1, UInt i2),
1475 UChar r1, UInt i2)
1476{
1477 HChar *mnm = irgen(r1, i2);
1478
sewardj7ee97522011-05-09 21:45:04 +00001479 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001480 s390_disasm(ENC3(MNM, GPR, PCREL), mnm, r1, i2);
1481}
1482
1483static void
1484s390_format_RIL_UP(HChar *(*irgen)(void),
1485 UChar r1, UInt i2)
1486{
1487 HChar *mnm = irgen();
1488
sewardj7ee97522011-05-09 21:45:04 +00001489 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001490 s390_disasm(ENC3(MNM, UINT, PCREL), mnm, r1, i2);
1491}
1492
1493static void
1494s390_format_RIS_RURDI(HChar *(*irgen)(UChar r1, UChar m3, UChar i2,
1495 IRTemp op4addr),
1496 UChar r1, UChar m3, UChar b4, UShort d4, UChar i2)
1497{
1498 HChar *mnm;
1499 IRTemp op4addr = newTemp(Ity_I64);
1500
1501 assign(op4addr, binop(Iop_Add64, mkU64(d4), b4 != 0 ? get_gpr_dw0(b4) :
1502 mkU64(0)));
1503
1504 mnm = irgen(r1, m3, i2, op4addr);
1505
sewardj7ee97522011-05-09 21:45:04 +00001506 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001507 s390_disasm(ENC5(XMNM, GPR, INT, CABM, UDXB), S390_XMNM_CAB, mnm, m3, r1,
1508 (Int)(Char)i2, m3, d4, 0, b4);
1509}
1510
1511static void
1512s390_format_RIS_RURDU(HChar *(*irgen)(UChar r1, UChar m3, UChar i2,
1513 IRTemp op4addr),
1514 UChar r1, UChar m3, UChar b4, UShort d4, UChar i2)
1515{
1516 HChar *mnm;
1517 IRTemp op4addr = newTemp(Ity_I64);
1518
1519 assign(op4addr, binop(Iop_Add64, mkU64(d4), b4 != 0 ? get_gpr_dw0(b4) :
1520 mkU64(0)));
1521
1522 mnm = irgen(r1, m3, i2, op4addr);
1523
sewardj7ee97522011-05-09 21:45:04 +00001524 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001525 s390_disasm(ENC5(XMNM, GPR, UINT, CABM, UDXB), S390_XMNM_CAB, mnm, m3, r1,
1526 i2, m3, d4, 0, b4);
1527}
1528
1529static void
1530s390_format_RR(HChar *(*irgen)(UChar r1, UChar r2),
1531 UChar r1, UChar r2)
1532{
1533 irgen(r1, r2);
1534}
1535
1536static void
1537s390_format_RR_RR(HChar *(*irgen)(UChar r1, UChar r2),
1538 UChar r1, UChar r2)
1539{
1540 HChar *mnm = irgen(r1, r2);
1541
sewardj7ee97522011-05-09 21:45:04 +00001542 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001543 s390_disasm(ENC3(MNM, GPR, GPR), mnm, r1, r2);
1544}
1545
1546static void
1547s390_format_RR_FF(HChar *(*irgen)(UChar r1, UChar r2),
1548 UChar r1, UChar r2)
1549{
1550 HChar *mnm = irgen(r1, r2);
1551
sewardj7ee97522011-05-09 21:45:04 +00001552 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001553 s390_disasm(ENC3(MNM, FPR, FPR), mnm, r1, r2);
1554}
1555
1556static void
1557s390_format_RRE(HChar *(*irgen)(UChar r1, UChar r2),
1558 UChar r1, UChar r2)
1559{
1560 irgen(r1, r2);
1561}
1562
1563static void
1564s390_format_RRE_RR(HChar *(*irgen)(UChar r1, UChar r2),
1565 UChar r1, UChar r2)
1566{
1567 HChar *mnm = irgen(r1, r2);
1568
sewardj7ee97522011-05-09 21:45:04 +00001569 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001570 s390_disasm(ENC3(MNM, GPR, GPR), mnm, r1, r2);
1571}
1572
1573static void
1574s390_format_RRE_FF(HChar *(*irgen)(UChar r1, UChar r2),
1575 UChar r1, UChar r2)
1576{
1577 HChar *mnm = irgen(r1, r2);
1578
sewardj7ee97522011-05-09 21:45:04 +00001579 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001580 s390_disasm(ENC3(MNM, FPR, FPR), mnm, r1, r2);
1581}
1582
1583static void
1584s390_format_RRE_RF(HChar *(*irgen)(UChar, UChar),
1585 UChar r1, UChar r2)
1586{
1587 HChar *mnm = irgen(r1, r2);
1588
sewardj7ee97522011-05-09 21:45:04 +00001589 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001590 s390_disasm(ENC3(MNM, GPR, FPR), mnm, r1, r2);
1591}
1592
1593static void
1594s390_format_RRE_FR(HChar *(*irgen)(UChar r1, UChar r2),
1595 UChar r1, UChar r2)
1596{
1597 HChar *mnm = irgen(r1, r2);
1598
sewardj7ee97522011-05-09 21:45:04 +00001599 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001600 s390_disasm(ENC3(MNM, FPR, GPR), mnm, r1, r2);
1601}
1602
1603static void
1604s390_format_RRE_R0(HChar *(*irgen)(UChar r1),
1605 UChar r1)
1606{
1607 HChar *mnm = irgen(r1);
1608
sewardj7ee97522011-05-09 21:45:04 +00001609 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001610 s390_disasm(ENC2(MNM, GPR), mnm, r1);
1611}
1612
1613static void
1614s390_format_RRE_F0(HChar *(*irgen)(UChar r1),
1615 UChar r1)
1616{
1617 HChar *mnm = irgen(r1);
1618
sewardj7ee97522011-05-09 21:45:04 +00001619 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001620 s390_disasm(ENC2(MNM, FPR), mnm, r1);
1621}
1622
1623static void
florian9af37692012-01-15 21:01:16 +00001624s390_format_RRF_M0RERE(HChar *(*irgen)(UChar m3, UChar r1, UChar r2),
1625 UChar m3, UChar r1, UChar r2)
1626{
florianfed3ea32012-07-19 14:54:03 +00001627 HChar *mnm = irgen(m3, r1, r2);
florian9af37692012-01-15 21:01:16 +00001628
1629 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
florianfed3ea32012-07-19 14:54:03 +00001630 s390_disasm(ENC4(MNM, GPR, GPR, UINT), mnm, r1, r2, m3);
florian9af37692012-01-15 21:01:16 +00001631}
1632
1633static void
sewardj2019a972011-03-07 16:04:07 +00001634s390_format_RRF_F0FF(HChar *(*irgen)(UChar, UChar, UChar),
1635 UChar r1, UChar r3, UChar r2)
1636{
1637 HChar *mnm = irgen(r1, r3, r2);
1638
sewardj7ee97522011-05-09 21:45:04 +00001639 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001640 s390_disasm(ENC4(MNM, FPR, FPR, FPR), mnm, r1, r3, r2);
1641}
1642
1643static void
sewardjd7bde722011-04-05 13:19:33 +00001644s390_format_RRF_U0RR(HChar *(*irgen)(UChar m3, UChar r1, UChar r2),
1645 UChar m3, UChar r1, UChar r2, Int xmnm_kind)
1646{
1647 irgen(m3, r1, r2);
1648
sewardj7ee97522011-05-09 21:45:04 +00001649 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardjd7bde722011-04-05 13:19:33 +00001650 s390_disasm(ENC3(XMNM, GPR, GPR), xmnm_kind, m3, r1, r2);
1651}
1652
1653static void
sewardj2019a972011-03-07 16:04:07 +00001654s390_format_RRF_U0RF(HChar *(*irgen)(UChar r3, UChar r1, UChar r2),
1655 UChar r3, UChar r1, UChar r2)
1656{
1657 HChar *mnm = irgen(r3, r1, r2);
1658
sewardj7ee97522011-05-09 21:45:04 +00001659 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001660 s390_disasm(ENC4(MNM, GPR, UINT, FPR), mnm, r1, r3, r2);
1661}
1662
1663static void
1664s390_format_RRF_F0FF2(HChar *(*irgen)(UChar, UChar, UChar),
1665 UChar r3, UChar r1, UChar r2)
1666{
1667 HChar *mnm = irgen(r3, r1, r2);
1668
sewardj7ee97522011-05-09 21:45:04 +00001669 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001670 s390_disasm(ENC4(MNM, FPR, FPR, FPR), mnm, r1, r3, r2);
1671}
1672
1673static void
1674s390_format_RRF_R0RR2(HChar *(*irgen)(UChar r3, UChar r1, UChar r2),
1675 UChar r3, UChar r1, UChar r2)
1676{
1677 HChar *mnm = irgen(r3, r1, r2);
1678
sewardj7ee97522011-05-09 21:45:04 +00001679 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001680 s390_disasm(ENC4(MNM, GPR, GPR, GPR), mnm, r1, r2, r3);
1681}
1682
1683static void
1684s390_format_RRS(HChar *(*irgen)(UChar r1, UChar r2, UChar m3, IRTemp op4addr),
1685 UChar r1, UChar r2, UChar b4, UShort d4, UChar m3)
1686{
1687 HChar *mnm;
1688 IRTemp op4addr = newTemp(Ity_I64);
1689
1690 assign(op4addr, binop(Iop_Add64, mkU64(d4), b4 != 0 ? get_gpr_dw0(b4) :
1691 mkU64(0)));
1692
1693 mnm = irgen(r1, r2, m3, op4addr);
1694
sewardj7ee97522011-05-09 21:45:04 +00001695 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001696 s390_disasm(ENC5(XMNM, GPR, GPR, CABM, UDXB), S390_XMNM_CAB, mnm, m3, r1,
1697 r2, m3, d4, 0, b4);
1698}
1699
1700static void
1701s390_format_RS_R0RD(HChar *(*irgen)(UChar r1, IRTemp op2addr),
1702 UChar r1, UChar b2, UShort d2)
1703{
1704 HChar *mnm;
1705 IRTemp op2addr = newTemp(Ity_I64);
1706
1707 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
1708 mkU64(0)));
1709
1710 mnm = irgen(r1, op2addr);
1711
sewardj7ee97522011-05-09 21:45:04 +00001712 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001713 s390_disasm(ENC3(MNM, GPR, UDXB), mnm, r1, d2, 0, b2);
1714}
1715
1716static void
1717s390_format_RS_RRRD(HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
1718 UChar r1, UChar r3, UChar b2, UShort d2)
1719{
1720 HChar *mnm;
1721 IRTemp op2addr = newTemp(Ity_I64);
1722
1723 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
1724 mkU64(0)));
1725
1726 mnm = irgen(r1, r3, op2addr);
1727
sewardj7ee97522011-05-09 21:45:04 +00001728 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001729 s390_disasm(ENC4(MNM, GPR, GPR, UDXB), mnm, r1, r3, d2, 0, b2);
1730}
1731
1732static void
1733s390_format_RS_RURD(HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
1734 UChar r1, UChar r3, UChar b2, UShort d2)
1735{
1736 HChar *mnm;
1737 IRTemp op2addr = newTemp(Ity_I64);
1738
1739 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
1740 mkU64(0)));
1741
1742 mnm = irgen(r1, r3, op2addr);
1743
sewardj7ee97522011-05-09 21:45:04 +00001744 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001745 s390_disasm(ENC4(MNM, GPR, UINT, UDXB), mnm, r1, r3, d2, 0, b2);
1746}
1747
1748static void
1749s390_format_RS_AARD(HChar *(*irgen)(UChar, UChar, IRTemp),
1750 UChar r1, UChar r3, UChar b2, UShort d2)
1751{
1752 HChar *mnm;
1753 IRTemp op2addr = newTemp(Ity_I64);
1754
1755 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
1756 mkU64(0)));
1757
1758 mnm = irgen(r1, r3, op2addr);
1759
sewardj7ee97522011-05-09 21:45:04 +00001760 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001761 s390_disasm(ENC4(MNM, AR, AR, UDXB), mnm, r1, r3, d2, 0, b2);
1762}
1763
1764static void
1765s390_format_RSI_RRP(HChar *(*irgen)(UChar r1, UChar r3, UShort i2),
1766 UChar r1, UChar r3, UShort i2)
1767{
1768 HChar *mnm = irgen(r1, r3, i2);
1769
sewardj7ee97522011-05-09 21:45:04 +00001770 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001771 s390_disasm(ENC4(MNM, GPR, GPR, PCREL), mnm, r1, r3, (Int)(Short)i2);
1772}
1773
1774static void
1775s390_format_RSY_RRRD(HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
1776 UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2)
1777{
1778 HChar *mnm;
1779 IRTemp op2addr = newTemp(Ity_I64);
1780 IRTemp d2 = newTemp(Ity_I64);
1781
1782 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
1783 assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
1784 mkU64(0)));
1785
1786 mnm = irgen(r1, r3, op2addr);
1787
sewardj7ee97522011-05-09 21:45:04 +00001788 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001789 s390_disasm(ENC4(MNM, GPR, GPR, SDXB), mnm, r1, r3, dh2, dl2, 0, b2);
1790}
1791
1792static void
1793s390_format_RSY_AARD(HChar *(*irgen)(UChar, UChar, IRTemp),
1794 UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2)
1795{
1796 HChar *mnm;
1797 IRTemp op2addr = newTemp(Ity_I64);
1798 IRTemp d2 = newTemp(Ity_I64);
1799
1800 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
1801 assign(op2addr, binop(Iop_Add64, mkexpr(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, AR, AR, SDXB), mnm, r1, r3, dh2, dl2, 0, b2);
1808}
1809
1810static void
1811s390_format_RSY_RURD(HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
1812 UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2)
1813{
1814 HChar *mnm;
1815 IRTemp op2addr = newTemp(Ity_I64);
1816 IRTemp d2 = newTemp(Ity_I64);
1817
1818 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
1819 assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
1820 mkU64(0)));
1821
1822 mnm = irgen(r1, r3, op2addr);
1823
sewardj7ee97522011-05-09 21:45:04 +00001824 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001825 s390_disasm(ENC4(MNM, GPR, UINT, SDXB), mnm, r1, r3, dh2, dl2, 0, b2);
1826}
1827
1828static void
sewardjd7bde722011-04-05 13:19:33 +00001829s390_format_RSY_RDRM(HChar *(*irgen)(UChar r1, IRTemp op2addr),
1830 UChar r1, UChar m3, UChar b2, UShort dl2, UChar dh2,
1831 Int xmnm_kind)
1832{
1833 IRTemp op2addr = newTemp(Ity_I64);
1834 IRTemp d2 = newTemp(Ity_I64);
1835
1836 if_condition_goto(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0)),
1837 guest_IA_next_instr);
1838 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
1839 assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
1840 mkU64(0)));
1841
1842 irgen(r1, op2addr);
florianf9e1ed72012-04-17 02:41:56 +00001843 dummy_put_IA();
sewardjd7bde722011-04-05 13:19:33 +00001844
sewardj7ee97522011-05-09 21:45:04 +00001845 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardjd7bde722011-04-05 13:19:33 +00001846 s390_disasm(ENC3(XMNM, GPR, SDXB), xmnm_kind, m3, r1, dh2, dl2, 0, b2);
1847}
1848
1849static void
sewardj2019a972011-03-07 16:04:07 +00001850s390_format_RX(HChar *(*irgen)(UChar r1, UChar x2, UChar b2, UShort d2,
1851 IRTemp op2addr),
1852 UChar r1, UChar x2, UChar b2, UShort d2)
1853{
1854 IRTemp op2addr = newTemp(Ity_I64);
1855
1856 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
1857 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
1858 mkU64(0)));
1859
1860 irgen(r1, x2, b2, d2, op2addr);
1861}
1862
1863static void
1864s390_format_RX_RRRD(HChar *(*irgen)(UChar r1, IRTemp op2addr),
1865 UChar r1, UChar x2, UChar b2, UShort d2)
1866{
1867 HChar *mnm;
1868 IRTemp op2addr = newTemp(Ity_I64);
1869
1870 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
1871 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
1872 mkU64(0)));
1873
1874 mnm = irgen(r1, op2addr);
1875
sewardj7ee97522011-05-09 21:45:04 +00001876 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001877 s390_disasm(ENC3(MNM, GPR, UDXB), mnm, r1, d2, x2, b2);
1878}
1879
1880static void
1881s390_format_RX_FRRD(HChar *(*irgen)(UChar r1, IRTemp op2addr),
1882 UChar r1, UChar x2, UChar b2, UShort d2)
1883{
1884 HChar *mnm;
1885 IRTemp op2addr = newTemp(Ity_I64);
1886
1887 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
1888 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
1889 mkU64(0)));
1890
1891 mnm = irgen(r1, op2addr);
1892
sewardj7ee97522011-05-09 21:45:04 +00001893 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001894 s390_disasm(ENC3(MNM, FPR, UDXB), mnm, r1, d2, x2, b2);
1895}
1896
1897static void
1898s390_format_RXE_FRRD(HChar *(*irgen)(UChar r1, IRTemp op2addr),
1899 UChar r1, UChar x2, UChar b2, UShort d2)
1900{
1901 HChar *mnm;
1902 IRTemp op2addr = newTemp(Ity_I64);
1903
1904 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
1905 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
1906 mkU64(0)));
1907
1908 mnm = irgen(r1, op2addr);
1909
sewardj7ee97522011-05-09 21:45:04 +00001910 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001911 s390_disasm(ENC3(MNM, FPR, UDXB), mnm, r1, d2, x2, b2);
1912}
1913
1914static void
1915s390_format_RXF_FRRDF(HChar *(*irgen)(UChar, IRTemp, UChar),
1916 UChar r3, UChar x2, UChar b2, UShort d2, UChar r1)
1917{
1918 HChar *mnm;
1919 IRTemp op2addr = newTemp(Ity_I64);
1920
1921 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
1922 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
1923 mkU64(0)));
1924
1925 mnm = irgen(r3, op2addr, r1);
1926
sewardj7ee97522011-05-09 21:45:04 +00001927 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001928 s390_disasm(ENC4(MNM, FPR, FPR, UDXB), mnm, r1, r3, d2, x2, b2);
1929}
1930
1931static void
1932s390_format_RXY_RRRD(HChar *(*irgen)(UChar r1, IRTemp op2addr),
1933 UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
1934{
1935 HChar *mnm;
1936 IRTemp op2addr = newTemp(Ity_I64);
1937 IRTemp d2 = newTemp(Ity_I64);
1938
1939 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
1940 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkexpr(d2),
1941 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
1942 mkU64(0)));
1943
1944 mnm = irgen(r1, op2addr);
1945
sewardj7ee97522011-05-09 21:45:04 +00001946 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001947 s390_disasm(ENC3(MNM, GPR, SDXB), mnm, r1, dh2, dl2, x2, b2);
1948}
1949
1950static void
1951s390_format_RXY_FRRD(HChar *(*irgen)(UChar r1, IRTemp op2addr),
1952 UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
1953{
1954 HChar *mnm;
1955 IRTemp op2addr = newTemp(Ity_I64);
1956 IRTemp d2 = newTemp(Ity_I64);
1957
1958 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
1959 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkexpr(d2),
1960 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
1961 mkU64(0)));
1962
1963 mnm = irgen(r1, op2addr);
1964
sewardj7ee97522011-05-09 21:45:04 +00001965 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001966 s390_disasm(ENC3(MNM, FPR, SDXB), mnm, r1, dh2, dl2, x2, b2);
1967}
1968
1969static void
1970s390_format_RXY_URRD(HChar *(*irgen)(void),
1971 UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
1972{
1973 HChar *mnm;
1974 IRTemp op2addr = newTemp(Ity_I64);
1975 IRTemp d2 = newTemp(Ity_I64);
1976
1977 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
1978 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkexpr(d2),
1979 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
1980 mkU64(0)));
1981
1982 mnm = irgen();
1983
sewardj7ee97522011-05-09 21:45:04 +00001984 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001985 s390_disasm(ENC3(MNM, UINT, SDXB), mnm, r1, dh2, dl2, x2, b2);
1986}
1987
1988static void
1989s390_format_S_RD(HChar *(*irgen)(IRTemp op2addr),
1990 UChar b2, UShort d2)
1991{
1992 HChar *mnm;
1993 IRTemp op2addr = newTemp(Ity_I64);
1994
1995 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
1996 mkU64(0)));
1997
1998 mnm = irgen(op2addr);
1999
sewardj7ee97522011-05-09 21:45:04 +00002000 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002001 s390_disasm(ENC2(MNM, UDXB), mnm, d2, 0, b2);
2002}
2003
2004static void
2005s390_format_SI_URD(HChar *(*irgen)(UChar i2, IRTemp op1addr),
2006 UChar i2, UChar b1, UShort d1)
2007{
2008 HChar *mnm;
2009 IRTemp op1addr = newTemp(Ity_I64);
2010
2011 assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
2012 mkU64(0)));
2013
2014 mnm = irgen(i2, op1addr);
2015
sewardj7ee97522011-05-09 21:45:04 +00002016 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002017 s390_disasm(ENC3(MNM, UDXB, UINT), mnm, d1, 0, b1, i2);
2018}
2019
2020static void
2021s390_format_SIY_URD(HChar *(*irgen)(UChar i2, IRTemp op1addr),
2022 UChar i2, UChar b1, UShort dl1, UChar dh1)
2023{
2024 HChar *mnm;
2025 IRTemp op1addr = newTemp(Ity_I64);
2026 IRTemp d1 = newTemp(Ity_I64);
2027
2028 assign(d1, mkU64(((ULong)(Long)(Char)dh1 << 12) | ((ULong)dl1)));
2029 assign(op1addr, binop(Iop_Add64, mkexpr(d1), b1 != 0 ? get_gpr_dw0(b1) :
2030 mkU64(0)));
2031
2032 mnm = irgen(i2, op1addr);
2033
sewardj7ee97522011-05-09 21:45:04 +00002034 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002035 s390_disasm(ENC3(MNM, SDXB, UINT), mnm, dh1, dl1, 0, b1, i2);
2036}
2037
2038static void
2039s390_format_SIY_IRD(HChar *(*irgen)(UChar i2, IRTemp op1addr),
2040 UChar i2, UChar b1, UShort dl1, UChar dh1)
2041{
2042 HChar *mnm;
2043 IRTemp op1addr = newTemp(Ity_I64);
2044 IRTemp d1 = newTemp(Ity_I64);
2045
2046 assign(d1, mkU64(((ULong)(Long)(Char)dh1 << 12) | ((ULong)dl1)));
2047 assign(op1addr, binop(Iop_Add64, mkexpr(d1), b1 != 0 ? get_gpr_dw0(b1) :
2048 mkU64(0)));
2049
2050 mnm = irgen(i2, op1addr);
2051
sewardj7ee97522011-05-09 21:45:04 +00002052 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002053 s390_disasm(ENC3(MNM, SDXB, INT), mnm, dh1, dl1, 0, b1, (Int)(Char)i2);
2054}
2055
2056static void
2057s390_format_SS_L0RDRD(HChar *(*irgen)(UChar, IRTemp, IRTemp),
2058 UChar l, UChar b1, UShort d1, UChar b2, UShort d2)
2059{
2060 HChar *mnm;
2061 IRTemp op1addr = newTemp(Ity_I64);
2062 IRTemp op2addr = newTemp(Ity_I64);
2063
2064 assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
2065 mkU64(0)));
2066 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2067 mkU64(0)));
2068
2069 mnm = irgen(l, op1addr, op2addr);
2070
sewardj7ee97522011-05-09 21:45:04 +00002071 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002072 s390_disasm(ENC3(MNM, UDLB, UDXB), mnm, d1, l, b1, d2, 0, b2);
2073}
2074
2075static void
2076s390_format_SIL_RDI(HChar *(*irgen)(UShort i2, IRTemp op1addr),
2077 UChar b1, UShort d1, UShort i2)
2078{
2079 HChar *mnm;
2080 IRTemp op1addr = newTemp(Ity_I64);
2081
2082 assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
2083 mkU64(0)));
2084
2085 mnm = irgen(i2, op1addr);
2086
sewardj7ee97522011-05-09 21:45:04 +00002087 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002088 s390_disasm(ENC3(MNM, UDXB, INT), mnm, d1, 0, b1, (Int)(Short)i2);
2089}
2090
2091static void
2092s390_format_SIL_RDU(HChar *(*irgen)(UShort i2, IRTemp op1addr),
2093 UChar b1, UShort d1, UShort i2)
2094{
2095 HChar *mnm;
2096 IRTemp op1addr = newTemp(Ity_I64);
2097
2098 assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
2099 mkU64(0)));
2100
2101 mnm = irgen(i2, op1addr);
2102
sewardj7ee97522011-05-09 21:45:04 +00002103 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002104 s390_disasm(ENC3(MNM, UDXB, UINT), mnm, d1, 0, b1, i2);
2105}
2106
2107
2108
2109/*------------------------------------------------------------*/
2110/*--- Build IR for opcodes ---*/
2111/*------------------------------------------------------------*/
2112
2113static HChar *
florian30e89012011-08-08 18:22:58 +00002114s390_irgen_00(UChar r1 __attribute__((unused)),
2115 UChar r2 __attribute__((unused)))
2116{
2117 IRDirty *d;
2118
2119 d = unsafeIRDirty_0_N (0, "s390x_dirtyhelper_00", &s390x_dirtyhelper_00,
2120 mkIRExprVec_0());
2121 d->needsBBP = 1; /* Need to pass pointer to guest state to helper */
2122
sewardjc9069f22012-06-01 16:09:50 +00002123 d->nFxState = 1;
2124 vex_bzero(&d->fxState, sizeof(d->fxState));
2125
florian30e89012011-08-08 18:22:58 +00002126 d->fxState[0].fx = Ifx_Modify; /* read then write */
2127 d->fxState[0].offset = S390X_GUEST_OFFSET(guest_IA);
2128 d->fxState[0].size = sizeof(ULong);
florian30e89012011-08-08 18:22:58 +00002129
2130 stmt(IRStmt_Dirty(d));
2131
2132 return "00";
2133}
2134
2135static HChar *
sewardj2019a972011-03-07 16:04:07 +00002136s390_irgen_AR(UChar r1, UChar r2)
2137{
2138 IRTemp op1 = newTemp(Ity_I32);
2139 IRTemp op2 = newTemp(Ity_I32);
2140 IRTemp result = newTemp(Ity_I32);
2141
2142 assign(op1, get_gpr_w1(r1));
2143 assign(op2, get_gpr_w1(r2));
2144 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2145 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2146 put_gpr_w1(r1, mkexpr(result));
2147
2148 return "ar";
2149}
2150
2151static HChar *
2152s390_irgen_AGR(UChar r1, UChar r2)
2153{
2154 IRTemp op1 = newTemp(Ity_I64);
2155 IRTemp op2 = newTemp(Ity_I64);
2156 IRTemp result = newTemp(Ity_I64);
2157
2158 assign(op1, get_gpr_dw0(r1));
2159 assign(op2, get_gpr_dw0(r2));
2160 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2161 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
2162 put_gpr_dw0(r1, mkexpr(result));
2163
2164 return "agr";
2165}
2166
2167static HChar *
2168s390_irgen_AGFR(UChar r1, UChar r2)
2169{
2170 IRTemp op1 = newTemp(Ity_I64);
2171 IRTemp op2 = newTemp(Ity_I64);
2172 IRTemp result = newTemp(Ity_I64);
2173
2174 assign(op1, get_gpr_dw0(r1));
2175 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
2176 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2177 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
2178 put_gpr_dw0(r1, mkexpr(result));
2179
2180 return "agfr";
2181}
2182
2183static HChar *
2184s390_irgen_ARK(UChar r3, UChar r1, UChar r2)
2185{
2186 IRTemp op2 = newTemp(Ity_I32);
2187 IRTemp op3 = newTemp(Ity_I32);
2188 IRTemp result = newTemp(Ity_I32);
2189
2190 assign(op2, get_gpr_w1(r2));
2191 assign(op3, get_gpr_w1(r3));
2192 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2193 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
2194 put_gpr_w1(r1, mkexpr(result));
2195
2196 return "ark";
2197}
2198
2199static HChar *
2200s390_irgen_AGRK(UChar r3, UChar r1, UChar r2)
2201{
2202 IRTemp op2 = newTemp(Ity_I64);
2203 IRTemp op3 = newTemp(Ity_I64);
2204 IRTemp result = newTemp(Ity_I64);
2205
2206 assign(op2, get_gpr_dw0(r2));
2207 assign(op3, get_gpr_dw0(r3));
2208 assign(result, binop(Iop_Add64, mkexpr(op2), mkexpr(op3)));
2209 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op2, op3);
2210 put_gpr_dw0(r1, mkexpr(result));
2211
2212 return "agrk";
2213}
2214
2215static HChar *
2216s390_irgen_A(UChar r1, IRTemp op2addr)
2217{
2218 IRTemp op1 = newTemp(Ity_I32);
2219 IRTemp op2 = newTemp(Ity_I32);
2220 IRTemp result = newTemp(Ity_I32);
2221
2222 assign(op1, get_gpr_w1(r1));
2223 assign(op2, load(Ity_I32, mkexpr(op2addr)));
2224 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2225 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2226 put_gpr_w1(r1, mkexpr(result));
2227
2228 return "a";
2229}
2230
2231static HChar *
2232s390_irgen_AY(UChar r1, IRTemp op2addr)
2233{
2234 IRTemp op1 = newTemp(Ity_I32);
2235 IRTemp op2 = newTemp(Ity_I32);
2236 IRTemp result = newTemp(Ity_I32);
2237
2238 assign(op1, get_gpr_w1(r1));
2239 assign(op2, load(Ity_I32, mkexpr(op2addr)));
2240 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2241 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2242 put_gpr_w1(r1, mkexpr(result));
2243
2244 return "ay";
2245}
2246
2247static HChar *
2248s390_irgen_AG(UChar r1, IRTemp op2addr)
2249{
2250 IRTemp op1 = newTemp(Ity_I64);
2251 IRTemp op2 = newTemp(Ity_I64);
2252 IRTemp result = newTemp(Ity_I64);
2253
2254 assign(op1, get_gpr_dw0(r1));
2255 assign(op2, load(Ity_I64, mkexpr(op2addr)));
2256 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2257 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
2258 put_gpr_dw0(r1, mkexpr(result));
2259
2260 return "ag";
2261}
2262
2263static HChar *
2264s390_irgen_AGF(UChar r1, IRTemp op2addr)
2265{
2266 IRTemp op1 = newTemp(Ity_I64);
2267 IRTemp op2 = newTemp(Ity_I64);
2268 IRTemp result = newTemp(Ity_I64);
2269
2270 assign(op1, get_gpr_dw0(r1));
2271 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
2272 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2273 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
2274 put_gpr_dw0(r1, mkexpr(result));
2275
2276 return "agf";
2277}
2278
2279static HChar *
2280s390_irgen_AFI(UChar r1, UInt i2)
2281{
2282 IRTemp op1 = newTemp(Ity_I32);
2283 Int op2;
2284 IRTemp result = newTemp(Ity_I32);
2285
2286 assign(op1, get_gpr_w1(r1));
2287 op2 = (Int)i2;
2288 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
2289 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
2290 mkU32((UInt)op2)));
2291 put_gpr_w1(r1, mkexpr(result));
2292
2293 return "afi";
2294}
2295
2296static HChar *
2297s390_irgen_AGFI(UChar r1, UInt i2)
2298{
2299 IRTemp op1 = newTemp(Ity_I64);
2300 Long op2;
2301 IRTemp result = newTemp(Ity_I64);
2302
2303 assign(op1, get_gpr_dw0(r1));
2304 op2 = (Long)(Int)i2;
2305 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64((ULong)op2)));
2306 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, mktemp(Ity_I64,
2307 mkU64((ULong)op2)));
2308 put_gpr_dw0(r1, mkexpr(result));
2309
2310 return "agfi";
2311}
2312
2313static HChar *
2314s390_irgen_AHIK(UChar r1, UChar r3, UShort i2)
2315{
2316 Int op2;
2317 IRTemp op3 = newTemp(Ity_I32);
2318 IRTemp result = newTemp(Ity_I32);
2319
2320 op2 = (Int)(Short)i2;
2321 assign(op3, get_gpr_w1(r3));
2322 assign(result, binop(Iop_Add32, mkU32((UInt)op2), mkexpr(op3)));
2323 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, mktemp(Ity_I32, mkU32((UInt)
2324 op2)), op3);
2325 put_gpr_w1(r1, mkexpr(result));
2326
2327 return "ahik";
2328}
2329
2330static HChar *
2331s390_irgen_AGHIK(UChar r1, UChar r3, UShort i2)
2332{
2333 Long op2;
2334 IRTemp op3 = newTemp(Ity_I64);
2335 IRTemp result = newTemp(Ity_I64);
2336
2337 op2 = (Long)(Short)i2;
2338 assign(op3, get_gpr_dw0(r3));
2339 assign(result, binop(Iop_Add64, mkU64((ULong)op2), mkexpr(op3)));
2340 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, mktemp(Ity_I64, mkU64((ULong)
2341 op2)), op3);
2342 put_gpr_dw0(r1, mkexpr(result));
2343
2344 return "aghik";
2345}
2346
2347static HChar *
2348s390_irgen_ASI(UChar i2, IRTemp op1addr)
2349{
2350 IRTemp op1 = newTemp(Ity_I32);
2351 Int op2;
2352 IRTemp result = newTemp(Ity_I32);
2353
2354 assign(op1, load(Ity_I32, mkexpr(op1addr)));
2355 op2 = (Int)(Char)i2;
2356 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
2357 store(mkexpr(op1addr), mkexpr(result));
2358 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
2359 mkU32((UInt)op2)));
2360
2361 return "asi";
2362}
2363
2364static HChar *
2365s390_irgen_AGSI(UChar i2, IRTemp op1addr)
2366{
2367 IRTemp op1 = newTemp(Ity_I64);
2368 Long op2;
2369 IRTemp result = newTemp(Ity_I64);
2370
2371 assign(op1, load(Ity_I64, mkexpr(op1addr)));
2372 op2 = (Long)(Char)i2;
2373 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64((ULong)op2)));
2374 store(mkexpr(op1addr), mkexpr(result));
2375 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, mktemp(Ity_I64,
2376 mkU64((ULong)op2)));
2377
2378 return "agsi";
2379}
2380
2381static HChar *
2382s390_irgen_AH(UChar r1, IRTemp op2addr)
2383{
2384 IRTemp op1 = newTemp(Ity_I32);
2385 IRTemp op2 = newTemp(Ity_I32);
2386 IRTemp result = newTemp(Ity_I32);
2387
2388 assign(op1, get_gpr_w1(r1));
2389 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
2390 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2391 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2392 put_gpr_w1(r1, mkexpr(result));
2393
2394 return "ah";
2395}
2396
2397static HChar *
2398s390_irgen_AHY(UChar r1, IRTemp op2addr)
2399{
2400 IRTemp op1 = newTemp(Ity_I32);
2401 IRTemp op2 = newTemp(Ity_I32);
2402 IRTemp result = newTemp(Ity_I32);
2403
2404 assign(op1, get_gpr_w1(r1));
2405 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
2406 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2407 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2408 put_gpr_w1(r1, mkexpr(result));
2409
2410 return "ahy";
2411}
2412
2413static HChar *
2414s390_irgen_AHI(UChar r1, UShort i2)
2415{
2416 IRTemp op1 = newTemp(Ity_I32);
2417 Int op2;
2418 IRTemp result = newTemp(Ity_I32);
2419
2420 assign(op1, get_gpr_w1(r1));
2421 op2 = (Int)(Short)i2;
2422 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
2423 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
2424 mkU32((UInt)op2)));
2425 put_gpr_w1(r1, mkexpr(result));
2426
2427 return "ahi";
2428}
2429
2430static HChar *
2431s390_irgen_AGHI(UChar r1, UShort i2)
2432{
2433 IRTemp op1 = newTemp(Ity_I64);
2434 Long op2;
2435 IRTemp result = newTemp(Ity_I64);
2436
2437 assign(op1, get_gpr_dw0(r1));
2438 op2 = (Long)(Short)i2;
2439 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64((ULong)op2)));
2440 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, mktemp(Ity_I64,
2441 mkU64((ULong)op2)));
2442 put_gpr_dw0(r1, mkexpr(result));
2443
2444 return "aghi";
2445}
2446
2447static HChar *
2448s390_irgen_AHHHR(UChar r3, UChar r1, UChar r2)
2449{
2450 IRTemp op2 = newTemp(Ity_I32);
2451 IRTemp op3 = newTemp(Ity_I32);
2452 IRTemp result = newTemp(Ity_I32);
2453
2454 assign(op2, get_gpr_w0(r2));
2455 assign(op3, get_gpr_w0(r3));
2456 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2457 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
2458 put_gpr_w0(r1, mkexpr(result));
2459
2460 return "ahhhr";
2461}
2462
2463static HChar *
2464s390_irgen_AHHLR(UChar r3, UChar r1, UChar r2)
2465{
2466 IRTemp op2 = newTemp(Ity_I32);
2467 IRTemp op3 = newTemp(Ity_I32);
2468 IRTemp result = newTemp(Ity_I32);
2469
2470 assign(op2, get_gpr_w0(r2));
2471 assign(op3, get_gpr_w1(r3));
2472 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2473 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
2474 put_gpr_w0(r1, mkexpr(result));
2475
2476 return "ahhlr";
2477}
2478
2479static HChar *
2480s390_irgen_AIH(UChar r1, UInt i2)
2481{
2482 IRTemp op1 = newTemp(Ity_I32);
2483 Int op2;
2484 IRTemp result = newTemp(Ity_I32);
2485
2486 assign(op1, get_gpr_w0(r1));
2487 op2 = (Int)i2;
2488 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
2489 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
2490 mkU32((UInt)op2)));
2491 put_gpr_w0(r1, mkexpr(result));
2492
2493 return "aih";
2494}
2495
2496static HChar *
2497s390_irgen_ALR(UChar r1, UChar r2)
2498{
2499 IRTemp op1 = newTemp(Ity_I32);
2500 IRTemp op2 = newTemp(Ity_I32);
2501 IRTemp result = newTemp(Ity_I32);
2502
2503 assign(op1, get_gpr_w1(r1));
2504 assign(op2, get_gpr_w1(r2));
2505 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2506 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, op2);
2507 put_gpr_w1(r1, mkexpr(result));
2508
2509 return "alr";
2510}
2511
2512static HChar *
2513s390_irgen_ALGR(UChar r1, UChar r2)
2514{
2515 IRTemp op1 = newTemp(Ity_I64);
2516 IRTemp op2 = newTemp(Ity_I64);
2517 IRTemp result = newTemp(Ity_I64);
2518
2519 assign(op1, get_gpr_dw0(r1));
2520 assign(op2, get_gpr_dw0(r2));
2521 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2522 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
2523 put_gpr_dw0(r1, mkexpr(result));
2524
2525 return "algr";
2526}
2527
2528static HChar *
2529s390_irgen_ALGFR(UChar r1, UChar r2)
2530{
2531 IRTemp op1 = newTemp(Ity_I64);
2532 IRTemp op2 = newTemp(Ity_I64);
2533 IRTemp result = newTemp(Ity_I64);
2534
2535 assign(op1, get_gpr_dw0(r1));
2536 assign(op2, unop(Iop_32Uto64, get_gpr_w1(r2)));
2537 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2538 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
2539 put_gpr_dw0(r1, mkexpr(result));
2540
2541 return "algfr";
2542}
2543
2544static HChar *
2545s390_irgen_ALRK(UChar r3, UChar r1, UChar r2)
2546{
2547 IRTemp op2 = newTemp(Ity_I32);
2548 IRTemp op3 = newTemp(Ity_I32);
2549 IRTemp result = newTemp(Ity_I32);
2550
2551 assign(op2, get_gpr_w1(r2));
2552 assign(op3, get_gpr_w1(r3));
2553 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2554 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
2555 put_gpr_w1(r1, mkexpr(result));
2556
2557 return "alrk";
2558}
2559
2560static HChar *
2561s390_irgen_ALGRK(UChar r3, UChar r1, UChar r2)
2562{
2563 IRTemp op2 = newTemp(Ity_I64);
2564 IRTemp op3 = newTemp(Ity_I64);
2565 IRTemp result = newTemp(Ity_I64);
2566
2567 assign(op2, get_gpr_dw0(r2));
2568 assign(op3, get_gpr_dw0(r3));
2569 assign(result, binop(Iop_Add64, mkexpr(op2), mkexpr(op3)));
2570 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op2, op3);
2571 put_gpr_dw0(r1, mkexpr(result));
2572
2573 return "algrk";
2574}
2575
2576static HChar *
2577s390_irgen_AL(UChar r1, IRTemp op2addr)
2578{
2579 IRTemp op1 = newTemp(Ity_I32);
2580 IRTemp op2 = newTemp(Ity_I32);
2581 IRTemp result = newTemp(Ity_I32);
2582
2583 assign(op1, get_gpr_w1(r1));
2584 assign(op2, load(Ity_I32, mkexpr(op2addr)));
2585 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2586 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, op2);
2587 put_gpr_w1(r1, mkexpr(result));
2588
2589 return "al";
2590}
2591
2592static HChar *
2593s390_irgen_ALY(UChar r1, IRTemp op2addr)
2594{
2595 IRTemp op1 = newTemp(Ity_I32);
2596 IRTemp op2 = newTemp(Ity_I32);
2597 IRTemp result = newTemp(Ity_I32);
2598
2599 assign(op1, get_gpr_w1(r1));
2600 assign(op2, load(Ity_I32, mkexpr(op2addr)));
2601 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2602 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, op2);
2603 put_gpr_w1(r1, mkexpr(result));
2604
2605 return "aly";
2606}
2607
2608static HChar *
2609s390_irgen_ALG(UChar r1, IRTemp op2addr)
2610{
2611 IRTemp op1 = newTemp(Ity_I64);
2612 IRTemp op2 = newTemp(Ity_I64);
2613 IRTemp result = newTemp(Ity_I64);
2614
2615 assign(op1, get_gpr_dw0(r1));
2616 assign(op2, load(Ity_I64, mkexpr(op2addr)));
2617 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2618 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
2619 put_gpr_dw0(r1, mkexpr(result));
2620
2621 return "alg";
2622}
2623
2624static HChar *
2625s390_irgen_ALGF(UChar r1, IRTemp op2addr)
2626{
2627 IRTemp op1 = newTemp(Ity_I64);
2628 IRTemp op2 = newTemp(Ity_I64);
2629 IRTemp result = newTemp(Ity_I64);
2630
2631 assign(op1, get_gpr_dw0(r1));
2632 assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
2633 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2634 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
2635 put_gpr_dw0(r1, mkexpr(result));
2636
2637 return "algf";
2638}
2639
2640static HChar *
2641s390_irgen_ALFI(UChar r1, UInt i2)
2642{
2643 IRTemp op1 = newTemp(Ity_I32);
2644 UInt op2;
2645 IRTemp result = newTemp(Ity_I32);
2646
2647 assign(op1, get_gpr_w1(r1));
2648 op2 = i2;
2649 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
2650 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, mktemp(Ity_I32,
2651 mkU32(op2)));
2652 put_gpr_w1(r1, mkexpr(result));
2653
2654 return "alfi";
2655}
2656
2657static HChar *
2658s390_irgen_ALGFI(UChar r1, UInt i2)
2659{
2660 IRTemp op1 = newTemp(Ity_I64);
2661 ULong op2;
2662 IRTemp result = newTemp(Ity_I64);
2663
2664 assign(op1, get_gpr_dw0(r1));
2665 op2 = (ULong)i2;
2666 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64(op2)));
2667 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, mktemp(Ity_I64,
2668 mkU64(op2)));
2669 put_gpr_dw0(r1, mkexpr(result));
2670
2671 return "algfi";
2672}
2673
2674static HChar *
2675s390_irgen_ALHHHR(UChar r3, UChar r1, UChar r2)
2676{
2677 IRTemp op2 = newTemp(Ity_I32);
2678 IRTemp op3 = newTemp(Ity_I32);
2679 IRTemp result = newTemp(Ity_I32);
2680
2681 assign(op2, get_gpr_w0(r2));
2682 assign(op3, get_gpr_w0(r3));
2683 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2684 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
2685 put_gpr_w0(r1, mkexpr(result));
2686
2687 return "alhhhr";
2688}
2689
2690static HChar *
2691s390_irgen_ALHHLR(UChar r3, UChar r1, UChar r2)
2692{
2693 IRTemp op2 = newTemp(Ity_I32);
2694 IRTemp op3 = newTemp(Ity_I32);
2695 IRTemp result = newTemp(Ity_I32);
2696
2697 assign(op2, get_gpr_w0(r2));
2698 assign(op3, get_gpr_w1(r3));
2699 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2700 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
2701 put_gpr_w0(r1, mkexpr(result));
2702
2703 return "alhhlr";
2704}
2705
2706static HChar *
2707s390_irgen_ALCR(UChar r1, UChar r2)
2708{
2709 IRTemp op1 = newTemp(Ity_I32);
2710 IRTemp op2 = newTemp(Ity_I32);
2711 IRTemp result = newTemp(Ity_I32);
2712 IRTemp carry_in = newTemp(Ity_I32);
2713
2714 assign(op1, get_gpr_w1(r1));
2715 assign(op2, get_gpr_w1(r2));
2716 assign(carry_in, binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)));
2717 assign(result, binop(Iop_Add32, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)),
2718 mkexpr(carry_in)));
2719 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_32, op1, op2, carry_in);
2720 put_gpr_w1(r1, mkexpr(result));
2721
2722 return "alcr";
2723}
2724
2725static HChar *
2726s390_irgen_ALCGR(UChar r1, UChar r2)
2727{
2728 IRTemp op1 = newTemp(Ity_I64);
2729 IRTemp op2 = newTemp(Ity_I64);
2730 IRTemp result = newTemp(Ity_I64);
2731 IRTemp carry_in = newTemp(Ity_I64);
2732
2733 assign(op1, get_gpr_dw0(r1));
2734 assign(op2, get_gpr_dw0(r2));
2735 assign(carry_in, unop(Iop_32Uto64, binop(Iop_Shr32, s390_call_calculate_cc(),
2736 mkU8(1))));
2737 assign(result, binop(Iop_Add64, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)),
2738 mkexpr(carry_in)));
2739 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_64, op1, op2, carry_in);
2740 put_gpr_dw0(r1, mkexpr(result));
2741
2742 return "alcgr";
2743}
2744
2745static HChar *
2746s390_irgen_ALC(UChar r1, IRTemp op2addr)
2747{
2748 IRTemp op1 = newTemp(Ity_I32);
2749 IRTemp op2 = newTemp(Ity_I32);
2750 IRTemp result = newTemp(Ity_I32);
2751 IRTemp carry_in = newTemp(Ity_I32);
2752
2753 assign(op1, get_gpr_w1(r1));
2754 assign(op2, load(Ity_I32, mkexpr(op2addr)));
2755 assign(carry_in, binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)));
2756 assign(result, binop(Iop_Add32, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)),
2757 mkexpr(carry_in)));
2758 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_32, op1, op2, carry_in);
2759 put_gpr_w1(r1, mkexpr(result));
2760
2761 return "alc";
2762}
2763
2764static HChar *
2765s390_irgen_ALCG(UChar r1, IRTemp op2addr)
2766{
2767 IRTemp op1 = newTemp(Ity_I64);
2768 IRTemp op2 = newTemp(Ity_I64);
2769 IRTemp result = newTemp(Ity_I64);
2770 IRTemp carry_in = newTemp(Ity_I64);
2771
2772 assign(op1, get_gpr_dw0(r1));
2773 assign(op2, load(Ity_I64, mkexpr(op2addr)));
2774 assign(carry_in, unop(Iop_32Uto64, binop(Iop_Shr32, s390_call_calculate_cc(),
2775 mkU8(1))));
2776 assign(result, binop(Iop_Add64, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)),
2777 mkexpr(carry_in)));
2778 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_64, op1, op2, carry_in);
2779 put_gpr_dw0(r1, mkexpr(result));
2780
2781 return "alcg";
2782}
2783
2784static HChar *
2785s390_irgen_ALSI(UChar i2, IRTemp op1addr)
2786{
2787 IRTemp op1 = newTemp(Ity_I32);
2788 UInt op2;
2789 IRTemp result = newTemp(Ity_I32);
2790
2791 assign(op1, load(Ity_I32, mkexpr(op1addr)));
2792 op2 = (UInt)(Int)(Char)i2;
2793 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
2794 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, mktemp(Ity_I32,
2795 mkU32(op2)));
2796 store(mkexpr(op1addr), mkexpr(result));
2797
2798 return "alsi";
2799}
2800
2801static HChar *
2802s390_irgen_ALGSI(UChar i2, IRTemp op1addr)
2803{
2804 IRTemp op1 = newTemp(Ity_I64);
2805 ULong op2;
2806 IRTemp result = newTemp(Ity_I64);
2807
2808 assign(op1, load(Ity_I64, mkexpr(op1addr)));
2809 op2 = (ULong)(Long)(Char)i2;
2810 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64(op2)));
2811 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, mktemp(Ity_I64,
2812 mkU64(op2)));
2813 store(mkexpr(op1addr), mkexpr(result));
2814
2815 return "algsi";
2816}
2817
2818static HChar *
2819s390_irgen_ALHSIK(UChar r1, UChar r3, UShort i2)
2820{
2821 UInt op2;
2822 IRTemp op3 = newTemp(Ity_I32);
2823 IRTemp result = newTemp(Ity_I32);
2824
2825 op2 = (UInt)(Int)(Short)i2;
2826 assign(op3, get_gpr_w1(r3));
2827 assign(result, binop(Iop_Add32, mkU32(op2), mkexpr(op3)));
2828 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, mktemp(Ity_I32, mkU32(op2)),
2829 op3);
2830 put_gpr_w1(r1, mkexpr(result));
2831
2832 return "alhsik";
2833}
2834
2835static HChar *
2836s390_irgen_ALGHSIK(UChar r1, UChar r3, UShort i2)
2837{
2838 ULong op2;
2839 IRTemp op3 = newTemp(Ity_I64);
2840 IRTemp result = newTemp(Ity_I64);
2841
2842 op2 = (ULong)(Long)(Short)i2;
2843 assign(op3, get_gpr_dw0(r3));
2844 assign(result, binop(Iop_Add64, mkU64(op2), mkexpr(op3)));
2845 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, mktemp(Ity_I64, mkU64(op2)),
2846 op3);
2847 put_gpr_dw0(r1, mkexpr(result));
2848
2849 return "alghsik";
2850}
2851
2852static HChar *
2853s390_irgen_ALSIH(UChar r1, UInt i2)
2854{
2855 IRTemp op1 = newTemp(Ity_I32);
2856 UInt op2;
2857 IRTemp result = newTemp(Ity_I32);
2858
2859 assign(op1, get_gpr_w0(r1));
2860 op2 = i2;
2861 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
2862 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, mktemp(Ity_I32,
2863 mkU32(op2)));
2864 put_gpr_w0(r1, mkexpr(result));
2865
2866 return "alsih";
2867}
2868
2869static HChar *
2870s390_irgen_ALSIHN(UChar r1, UInt i2)
2871{
2872 IRTemp op1 = newTemp(Ity_I32);
2873 UInt op2;
2874 IRTemp result = newTemp(Ity_I32);
2875
2876 assign(op1, get_gpr_w0(r1));
2877 op2 = i2;
2878 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
2879 put_gpr_w0(r1, mkexpr(result));
2880
2881 return "alsihn";
2882}
2883
2884static HChar *
2885s390_irgen_NR(UChar r1, UChar r2)
2886{
2887 IRTemp op1 = newTemp(Ity_I32);
2888 IRTemp op2 = newTemp(Ity_I32);
2889 IRTemp result = newTemp(Ity_I32);
2890
2891 assign(op1, get_gpr_w1(r1));
2892 assign(op2, get_gpr_w1(r2));
2893 assign(result, binop(Iop_And32, mkexpr(op1), mkexpr(op2)));
2894 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
2895 put_gpr_w1(r1, mkexpr(result));
2896
2897 return "nr";
2898}
2899
2900static HChar *
2901s390_irgen_NGR(UChar r1, UChar r2)
2902{
2903 IRTemp op1 = newTemp(Ity_I64);
2904 IRTemp op2 = newTemp(Ity_I64);
2905 IRTemp result = newTemp(Ity_I64);
2906
2907 assign(op1, get_gpr_dw0(r1));
2908 assign(op2, get_gpr_dw0(r2));
2909 assign(result, binop(Iop_And64, mkexpr(op1), mkexpr(op2)));
2910 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
2911 put_gpr_dw0(r1, mkexpr(result));
2912
2913 return "ngr";
2914}
2915
2916static HChar *
2917s390_irgen_NRK(UChar r3, UChar r1, UChar r2)
2918{
2919 IRTemp op2 = newTemp(Ity_I32);
2920 IRTemp op3 = newTemp(Ity_I32);
2921 IRTemp result = newTemp(Ity_I32);
2922
2923 assign(op2, get_gpr_w1(r2));
2924 assign(op3, get_gpr_w1(r3));
2925 assign(result, binop(Iop_And32, mkexpr(op2), mkexpr(op3)));
2926 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
2927 put_gpr_w1(r1, mkexpr(result));
2928
2929 return "nrk";
2930}
2931
2932static HChar *
2933s390_irgen_NGRK(UChar r3, UChar r1, UChar r2)
2934{
2935 IRTemp op2 = newTemp(Ity_I64);
2936 IRTemp op3 = newTemp(Ity_I64);
2937 IRTemp result = newTemp(Ity_I64);
2938
2939 assign(op2, get_gpr_dw0(r2));
2940 assign(op3, get_gpr_dw0(r3));
2941 assign(result, binop(Iop_And64, mkexpr(op2), mkexpr(op3)));
2942 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
2943 put_gpr_dw0(r1, mkexpr(result));
2944
2945 return "ngrk";
2946}
2947
2948static HChar *
2949s390_irgen_N(UChar r1, IRTemp op2addr)
2950{
2951 IRTemp op1 = newTemp(Ity_I32);
2952 IRTemp op2 = newTemp(Ity_I32);
2953 IRTemp result = newTemp(Ity_I32);
2954
2955 assign(op1, get_gpr_w1(r1));
2956 assign(op2, load(Ity_I32, mkexpr(op2addr)));
2957 assign(result, binop(Iop_And32, mkexpr(op1), mkexpr(op2)));
2958 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
2959 put_gpr_w1(r1, mkexpr(result));
2960
2961 return "n";
2962}
2963
2964static HChar *
2965s390_irgen_NY(UChar r1, IRTemp op2addr)
2966{
2967 IRTemp op1 = newTemp(Ity_I32);
2968 IRTemp op2 = newTemp(Ity_I32);
2969 IRTemp result = newTemp(Ity_I32);
2970
2971 assign(op1, get_gpr_w1(r1));
2972 assign(op2, load(Ity_I32, mkexpr(op2addr)));
2973 assign(result, binop(Iop_And32, mkexpr(op1), mkexpr(op2)));
2974 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
2975 put_gpr_w1(r1, mkexpr(result));
2976
2977 return "ny";
2978}
2979
2980static HChar *
2981s390_irgen_NG(UChar r1, IRTemp op2addr)
2982{
2983 IRTemp op1 = newTemp(Ity_I64);
2984 IRTemp op2 = newTemp(Ity_I64);
2985 IRTemp result = newTemp(Ity_I64);
2986
2987 assign(op1, get_gpr_dw0(r1));
2988 assign(op2, load(Ity_I64, mkexpr(op2addr)));
2989 assign(result, binop(Iop_And64, mkexpr(op1), mkexpr(op2)));
2990 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
2991 put_gpr_dw0(r1, mkexpr(result));
2992
2993 return "ng";
2994}
2995
2996static HChar *
2997s390_irgen_NI(UChar i2, IRTemp op1addr)
2998{
2999 IRTemp op1 = newTemp(Ity_I8);
3000 UChar op2;
3001 IRTemp result = newTemp(Ity_I8);
3002
3003 assign(op1, load(Ity_I8, mkexpr(op1addr)));
3004 op2 = i2;
3005 assign(result, binop(Iop_And8, mkexpr(op1), mkU8(op2)));
3006 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3007 store(mkexpr(op1addr), mkexpr(result));
3008
3009 return "ni";
3010}
3011
3012static HChar *
3013s390_irgen_NIY(UChar i2, IRTemp op1addr)
3014{
3015 IRTemp op1 = newTemp(Ity_I8);
3016 UChar op2;
3017 IRTemp result = newTemp(Ity_I8);
3018
3019 assign(op1, load(Ity_I8, mkexpr(op1addr)));
3020 op2 = i2;
3021 assign(result, binop(Iop_And8, mkexpr(op1), mkU8(op2)));
3022 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3023 store(mkexpr(op1addr), mkexpr(result));
3024
3025 return "niy";
3026}
3027
3028static HChar *
3029s390_irgen_NIHF(UChar r1, UInt i2)
3030{
3031 IRTemp op1 = newTemp(Ity_I32);
3032 UInt op2;
3033 IRTemp result = newTemp(Ity_I32);
3034
3035 assign(op1, get_gpr_w0(r1));
3036 op2 = i2;
3037 assign(result, binop(Iop_And32, mkexpr(op1), mkU32(op2)));
3038 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3039 put_gpr_w0(r1, mkexpr(result));
3040
3041 return "nihf";
3042}
3043
3044static HChar *
3045s390_irgen_NIHH(UChar r1, UShort i2)
3046{
3047 IRTemp op1 = newTemp(Ity_I16);
3048 UShort op2;
3049 IRTemp result = newTemp(Ity_I16);
3050
3051 assign(op1, get_gpr_hw0(r1));
3052 op2 = i2;
3053 assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
3054 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3055 put_gpr_hw0(r1, mkexpr(result));
3056
3057 return "nihh";
3058}
3059
3060static HChar *
3061s390_irgen_NIHL(UChar r1, UShort i2)
3062{
3063 IRTemp op1 = newTemp(Ity_I16);
3064 UShort op2;
3065 IRTemp result = newTemp(Ity_I16);
3066
3067 assign(op1, get_gpr_hw1(r1));
3068 op2 = i2;
3069 assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
3070 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3071 put_gpr_hw1(r1, mkexpr(result));
3072
3073 return "nihl";
3074}
3075
3076static HChar *
3077s390_irgen_NILF(UChar r1, UInt i2)
3078{
3079 IRTemp op1 = newTemp(Ity_I32);
3080 UInt op2;
3081 IRTemp result = newTemp(Ity_I32);
3082
3083 assign(op1, get_gpr_w1(r1));
3084 op2 = i2;
3085 assign(result, binop(Iop_And32, mkexpr(op1), mkU32(op2)));
3086 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3087 put_gpr_w1(r1, mkexpr(result));
3088
3089 return "nilf";
3090}
3091
3092static HChar *
3093s390_irgen_NILH(UChar r1, UShort i2)
3094{
3095 IRTemp op1 = newTemp(Ity_I16);
3096 UShort op2;
3097 IRTemp result = newTemp(Ity_I16);
3098
3099 assign(op1, get_gpr_hw2(r1));
3100 op2 = i2;
3101 assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
3102 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3103 put_gpr_hw2(r1, mkexpr(result));
3104
3105 return "nilh";
3106}
3107
3108static HChar *
3109s390_irgen_NILL(UChar r1, UShort i2)
3110{
3111 IRTemp op1 = newTemp(Ity_I16);
3112 UShort op2;
3113 IRTemp result = newTemp(Ity_I16);
3114
3115 assign(op1, get_gpr_hw3(r1));
3116 op2 = i2;
3117 assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
3118 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3119 put_gpr_hw3(r1, mkexpr(result));
3120
3121 return "nill";
3122}
3123
3124static HChar *
3125s390_irgen_BASR(UChar r1, UChar r2)
3126{
3127 IRTemp target = newTemp(Ity_I64);
3128
3129 if (r2 == 0) {
3130 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 2ULL));
3131 } else {
3132 if (r1 != r2) {
3133 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 2ULL));
3134 call_function(get_gpr_dw0(r2));
3135 } else {
3136 assign(target, get_gpr_dw0(r2));
3137 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 2ULL));
3138 call_function(mkexpr(target));
3139 }
3140 }
3141
3142 return "basr";
3143}
3144
3145static HChar *
3146s390_irgen_BAS(UChar r1, IRTemp op2addr)
3147{
3148 IRTemp target = newTemp(Ity_I64);
3149
3150 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 4ULL));
3151 assign(target, mkexpr(op2addr));
3152 call_function(mkexpr(target));
3153
3154 return "bas";
3155}
3156
3157static HChar *
3158s390_irgen_BCR(UChar r1, UChar r2)
3159{
3160 IRTemp cond = newTemp(Ity_I32);
3161
sewardja52e37e2011-04-28 18:48:06 +00003162 if (r2 == 0 && (r1 >= 14)) { /* serialization */
3163 stmt(IRStmt_MBE(Imbe_Fence));
3164 }
3165
sewardj2019a972011-03-07 16:04:07 +00003166 if ((r2 == 0) || (r1 == 0)) {
3167 } else {
3168 if (r1 == 15) {
3169 return_from_function(get_gpr_dw0(r2));
3170 } else {
3171 assign(cond, s390_call_calculate_cond(r1));
3172 if_not_condition_goto_computed(binop(Iop_CmpEQ32, mkexpr(cond),
3173 mkU32(0)), get_gpr_dw0(r2));
3174 }
3175 }
sewardj7ee97522011-05-09 21:45:04 +00003176 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00003177 s390_disasm(ENC2(XMNM, GPR), S390_XMNM_BCR, r1, r2);
3178
3179 return "bcr";
3180}
3181
3182static HChar *
3183s390_irgen_BC(UChar r1, UChar x2, UChar b2, UShort d2, IRTemp op2addr)
3184{
3185 IRTemp cond = newTemp(Ity_I32);
3186
3187 if (r1 == 0) {
3188 } else {
3189 if (r1 == 15) {
3190 always_goto(mkexpr(op2addr));
3191 } else {
3192 assign(cond, s390_call_calculate_cond(r1));
3193 if_not_condition_goto_computed(binop(Iop_CmpEQ32, mkexpr(cond),
3194 mkU32(0)), mkexpr(op2addr));
3195 }
3196 }
sewardj7ee97522011-05-09 21:45:04 +00003197 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00003198 s390_disasm(ENC2(XMNM, UDXB), S390_XMNM_BC, r1, d2, x2, b2);
3199
3200 return "bc";
3201}
3202
3203static HChar *
3204s390_irgen_BCTR(UChar r1, UChar r2)
3205{
3206 put_gpr_w1(r1, binop(Iop_Sub32, get_gpr_w1(r1), mkU32(1)));
3207 if (r2 != 0) {
3208 if_not_condition_goto_computed(binop(Iop_CmpEQ32, get_gpr_w1(r1), mkU32(0)
3209 ), get_gpr_dw0(r2));
3210 }
3211
3212 return "bctr";
3213}
3214
3215static HChar *
3216s390_irgen_BCTGR(UChar r1, UChar r2)
3217{
3218 put_gpr_dw0(r1, binop(Iop_Sub64, get_gpr_dw0(r1), mkU64(1)));
3219 if (r2 != 0) {
3220 if_not_condition_goto_computed(binop(Iop_CmpEQ64, get_gpr_dw0(r1),
3221 mkU64(0)), get_gpr_dw0(r2));
3222 }
3223
3224 return "bctgr";
3225}
3226
3227static HChar *
3228s390_irgen_BCT(UChar r1, IRTemp op2addr)
3229{
3230 put_gpr_w1(r1, binop(Iop_Sub32, get_gpr_w1(r1), mkU32(1)));
3231 if_not_condition_goto_computed(binop(Iop_CmpEQ32, get_gpr_w1(r1), mkU32(0)),
3232 mkexpr(op2addr));
3233
3234 return "bct";
3235}
3236
3237static HChar *
3238s390_irgen_BCTG(UChar r1, IRTemp op2addr)
3239{
3240 put_gpr_dw0(r1, binop(Iop_Sub64, get_gpr_dw0(r1), mkU64(1)));
3241 if_not_condition_goto_computed(binop(Iop_CmpEQ64, get_gpr_dw0(r1), mkU64(0)),
3242 mkexpr(op2addr));
3243
3244 return "bctg";
3245}
3246
3247static HChar *
3248s390_irgen_BXH(UChar r1, UChar r3, IRTemp op2addr)
3249{
3250 IRTemp value = newTemp(Ity_I32);
3251
3252 assign(value, get_gpr_w1(r3 | 1));
3253 put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
3254 if_not_condition_goto_computed(binop(Iop_CmpLE32S, get_gpr_w1(r1),
3255 mkexpr(value)), mkexpr(op2addr));
3256
3257 return "bxh";
3258}
3259
3260static HChar *
3261s390_irgen_BXHG(UChar r1, UChar r3, IRTemp op2addr)
3262{
3263 IRTemp value = newTemp(Ity_I64);
3264
3265 assign(value, get_gpr_dw0(r3 | 1));
3266 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
3267 if_not_condition_goto_computed(binop(Iop_CmpLE64S, get_gpr_dw0(r1),
3268 mkexpr(value)), mkexpr(op2addr));
3269
3270 return "bxhg";
3271}
3272
3273static HChar *
3274s390_irgen_BXLE(UChar r1, UChar r3, IRTemp op2addr)
3275{
3276 IRTemp value = newTemp(Ity_I32);
3277
3278 assign(value, get_gpr_w1(r3 | 1));
3279 put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
3280 if_not_condition_goto_computed(binop(Iop_CmpLT32S, mkexpr(value),
3281 get_gpr_w1(r1)), mkexpr(op2addr));
3282
3283 return "bxle";
3284}
3285
3286static HChar *
3287s390_irgen_BXLEG(UChar r1, UChar r3, IRTemp op2addr)
3288{
3289 IRTemp value = newTemp(Ity_I64);
3290
3291 assign(value, get_gpr_dw0(r3 | 1));
3292 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
3293 if_not_condition_goto_computed(binop(Iop_CmpLT64S, mkexpr(value),
3294 get_gpr_dw0(r1)), mkexpr(op2addr));
3295
3296 return "bxleg";
3297}
3298
3299static HChar *
3300s390_irgen_BRAS(UChar r1, UShort i2)
3301{
3302 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 4ULL));
floriana64c2432011-07-16 02:11:50 +00003303 call_function_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
sewardj2019a972011-03-07 16:04:07 +00003304
3305 return "bras";
3306}
3307
3308static HChar *
3309s390_irgen_BRASL(UChar r1, UInt i2)
3310{
3311 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 6ULL));
floriana64c2432011-07-16 02:11:50 +00003312 call_function_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1));
sewardj2019a972011-03-07 16:04:07 +00003313
3314 return "brasl";
3315}
3316
3317static HChar *
3318s390_irgen_BRC(UChar r1, UShort i2)
3319{
3320 IRTemp cond = newTemp(Ity_I32);
3321
3322 if (r1 == 0) {
3323 } else {
3324 if (r1 == 15) {
floriana64c2432011-07-16 02:11:50 +00003325 always_goto_and_chase(
3326 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
sewardj2019a972011-03-07 16:04:07 +00003327 } else {
3328 assign(cond, s390_call_calculate_cond(r1));
3329 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3330 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3331
3332 }
3333 }
sewardj7ee97522011-05-09 21:45:04 +00003334 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00003335 s390_disasm(ENC2(XMNM, PCREL), S390_XMNM_BRC, r1, (Int)(Short)i2);
3336
3337 return "brc";
3338}
3339
3340static HChar *
3341s390_irgen_BRCL(UChar r1, UInt i2)
3342{
3343 IRTemp cond = newTemp(Ity_I32);
3344
3345 if (r1 == 0) {
3346 } else {
3347 if (r1 == 15) {
floriana64c2432011-07-16 02:11:50 +00003348 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1));
sewardj2019a972011-03-07 16:04:07 +00003349 } else {
3350 assign(cond, s390_call_calculate_cond(r1));
3351 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3352 guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1));
3353 }
3354 }
sewardj7ee97522011-05-09 21:45:04 +00003355 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00003356 s390_disasm(ENC2(XMNM, PCREL), S390_XMNM_BRCL, r1, i2);
3357
3358 return "brcl";
3359}
3360
3361static HChar *
3362s390_irgen_BRCT(UChar r1, UShort i2)
3363{
3364 put_gpr_w1(r1, binop(Iop_Sub32, get_gpr_w1(r1), mkU32(1)));
3365 if_condition_goto(binop(Iop_CmpNE32, get_gpr_w1(r1), mkU32(0)),
3366 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3367
3368 return "brct";
3369}
3370
3371static HChar *
3372s390_irgen_BRCTG(UChar r1, UShort i2)
3373{
3374 put_gpr_dw0(r1, binop(Iop_Sub64, get_gpr_dw0(r1), mkU64(1)));
3375 if_condition_goto(binop(Iop_CmpNE64, get_gpr_dw0(r1), mkU64(0)),
3376 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3377
3378 return "brctg";
3379}
3380
3381static HChar *
3382s390_irgen_BRXH(UChar r1, UChar r3, UShort i2)
3383{
3384 IRTemp value = newTemp(Ity_I32);
3385
3386 assign(value, get_gpr_w1(r3 | 1));
3387 put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
3388 if_condition_goto(binop(Iop_CmpLT32S, mkexpr(value), get_gpr_w1(r1)),
3389 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3390
3391 return "brxh";
3392}
3393
3394static HChar *
3395s390_irgen_BRXHG(UChar r1, UChar r3, UShort i2)
3396{
3397 IRTemp value = newTemp(Ity_I64);
3398
3399 assign(value, get_gpr_dw0(r3 | 1));
3400 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
3401 if_condition_goto(binop(Iop_CmpLT64S, mkexpr(value), get_gpr_dw0(r1)),
3402 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3403
3404 return "brxhg";
3405}
3406
3407static HChar *
3408s390_irgen_BRXLE(UChar r1, UChar r3, UShort i2)
3409{
3410 IRTemp value = newTemp(Ity_I32);
3411
3412 assign(value, get_gpr_w1(r3 | 1));
3413 put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
3414 if_condition_goto(binop(Iop_CmpLE32S, get_gpr_w1(r1), mkexpr(value)),
3415 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3416
3417 return "brxle";
3418}
3419
3420static HChar *
3421s390_irgen_BRXLG(UChar r1, UChar r3, UShort i2)
3422{
3423 IRTemp value = newTemp(Ity_I64);
3424
3425 assign(value, get_gpr_dw0(r3 | 1));
3426 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
3427 if_condition_goto(binop(Iop_CmpLE64S, get_gpr_dw0(r1), mkexpr(value)),
3428 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3429
3430 return "brxlg";
3431}
3432
3433static HChar *
3434s390_irgen_CR(UChar r1, UChar r2)
3435{
3436 IRTemp op1 = newTemp(Ity_I32);
3437 IRTemp op2 = newTemp(Ity_I32);
3438
3439 assign(op1, get_gpr_w1(r1));
3440 assign(op2, get_gpr_w1(r2));
3441 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3442
3443 return "cr";
3444}
3445
3446static HChar *
3447s390_irgen_CGR(UChar r1, UChar r2)
3448{
3449 IRTemp op1 = newTemp(Ity_I64);
3450 IRTemp op2 = newTemp(Ity_I64);
3451
3452 assign(op1, get_gpr_dw0(r1));
3453 assign(op2, get_gpr_dw0(r2));
3454 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3455
3456 return "cgr";
3457}
3458
3459static HChar *
3460s390_irgen_CGFR(UChar r1, UChar r2)
3461{
3462 IRTemp op1 = newTemp(Ity_I64);
3463 IRTemp op2 = newTemp(Ity_I64);
3464
3465 assign(op1, get_gpr_dw0(r1));
3466 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
3467 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3468
3469 return "cgfr";
3470}
3471
3472static HChar *
3473s390_irgen_C(UChar r1, IRTemp op2addr)
3474{
3475 IRTemp op1 = newTemp(Ity_I32);
3476 IRTemp op2 = newTemp(Ity_I32);
3477
3478 assign(op1, get_gpr_w1(r1));
3479 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3480 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3481
3482 return "c";
3483}
3484
3485static HChar *
3486s390_irgen_CY(UChar r1, IRTemp op2addr)
3487{
3488 IRTemp op1 = newTemp(Ity_I32);
3489 IRTemp op2 = newTemp(Ity_I32);
3490
3491 assign(op1, get_gpr_w1(r1));
3492 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3493 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3494
3495 return "cy";
3496}
3497
3498static HChar *
3499s390_irgen_CG(UChar r1, IRTemp op2addr)
3500{
3501 IRTemp op1 = newTemp(Ity_I64);
3502 IRTemp op2 = newTemp(Ity_I64);
3503
3504 assign(op1, get_gpr_dw0(r1));
3505 assign(op2, load(Ity_I64, mkexpr(op2addr)));
3506 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3507
3508 return "cg";
3509}
3510
3511static HChar *
3512s390_irgen_CGF(UChar r1, IRTemp op2addr)
3513{
3514 IRTemp op1 = newTemp(Ity_I64);
3515 IRTemp op2 = newTemp(Ity_I64);
3516
3517 assign(op1, get_gpr_dw0(r1));
3518 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
3519 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3520
3521 return "cgf";
3522}
3523
3524static HChar *
3525s390_irgen_CFI(UChar r1, UInt i2)
3526{
3527 IRTemp op1 = newTemp(Ity_I32);
3528 Int op2;
3529
3530 assign(op1, get_gpr_w1(r1));
3531 op2 = (Int)i2;
3532 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
3533 mkU32((UInt)op2)));
3534
3535 return "cfi";
3536}
3537
3538static HChar *
3539s390_irgen_CGFI(UChar r1, UInt i2)
3540{
3541 IRTemp op1 = newTemp(Ity_I64);
3542 Long op2;
3543
3544 assign(op1, get_gpr_dw0(r1));
3545 op2 = (Long)(Int)i2;
3546 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I64,
3547 mkU64((ULong)op2)));
3548
3549 return "cgfi";
3550}
3551
3552static HChar *
3553s390_irgen_CRL(UChar r1, UInt i2)
3554{
3555 IRTemp op1 = newTemp(Ity_I32);
3556 IRTemp op2 = newTemp(Ity_I32);
3557
3558 assign(op1, get_gpr_w1(r1));
3559 assign(op2, load(Ity_I32, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
3560 i2 << 1))));
3561 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3562
3563 return "crl";
3564}
3565
3566static HChar *
3567s390_irgen_CGRL(UChar r1, UInt i2)
3568{
3569 IRTemp op1 = newTemp(Ity_I64);
3570 IRTemp op2 = newTemp(Ity_I64);
3571
3572 assign(op1, get_gpr_dw0(r1));
3573 assign(op2, load(Ity_I64, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
3574 i2 << 1))));
3575 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3576
3577 return "cgrl";
3578}
3579
3580static HChar *
3581s390_irgen_CGFRL(UChar r1, UInt i2)
3582{
3583 IRTemp op1 = newTemp(Ity_I64);
3584 IRTemp op2 = newTemp(Ity_I64);
3585
3586 assign(op1, get_gpr_dw0(r1));
3587 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
3588 ((ULong)(Long)(Int)i2 << 1)))));
3589 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3590
3591 return "cgfrl";
3592}
3593
3594static HChar *
3595s390_irgen_CRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
3596{
3597 IRTemp op1 = newTemp(Ity_I32);
3598 IRTemp op2 = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00003599 IRTemp cond = newTemp(Ity_I32);
3600
3601 if (m3 == 0) {
3602 } else {
3603 if (m3 == 14) {
3604 always_goto(mkexpr(op4addr));
3605 } else {
3606 assign(op1, get_gpr_w1(r1));
3607 assign(op2, get_gpr_w1(r2));
florianff9613f2012-05-12 15:26:44 +00003608 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
3609 op1, op2));
sewardj2019a972011-03-07 16:04:07 +00003610 if_not_condition_goto_computed(binop(Iop_CmpEQ32, mkexpr(cond),
3611 mkU32(0)), mkexpr(op4addr));
3612 }
3613 }
3614
3615 return "crb";
3616}
3617
3618static HChar *
3619s390_irgen_CGRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
3620{
3621 IRTemp op1 = newTemp(Ity_I64);
3622 IRTemp op2 = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00003623 IRTemp cond = newTemp(Ity_I32);
3624
3625 if (m3 == 0) {
3626 } else {
3627 if (m3 == 14) {
3628 always_goto(mkexpr(op4addr));
3629 } else {
3630 assign(op1, get_gpr_dw0(r1));
3631 assign(op2, get_gpr_dw0(r2));
florianff9613f2012-05-12 15:26:44 +00003632 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
3633 op1, op2));
sewardj2019a972011-03-07 16:04:07 +00003634 if_not_condition_goto_computed(binop(Iop_CmpEQ32, mkexpr(cond),
3635 mkU32(0)), mkexpr(op4addr));
3636 }
3637 }
3638
3639 return "cgrb";
3640}
3641
3642static HChar *
3643s390_irgen_CRJ(UChar r1, UChar r2, UShort i4, UChar m3)
3644{
3645 IRTemp op1 = newTemp(Ity_I32);
3646 IRTemp op2 = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00003647 IRTemp cond = newTemp(Ity_I32);
3648
3649 if (m3 == 0) {
3650 } else {
3651 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00003652 always_goto_and_chase(
3653 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00003654 } else {
3655 assign(op1, get_gpr_w1(r1));
3656 assign(op2, get_gpr_w1(r2));
florianff9613f2012-05-12 15:26:44 +00003657 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
3658 op1, op2));
sewardj2019a972011-03-07 16:04:07 +00003659 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3660 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
3661
3662 }
3663 }
3664
3665 return "crj";
3666}
3667
3668static HChar *
3669s390_irgen_CGRJ(UChar r1, UChar r2, UShort i4, UChar m3)
3670{
3671 IRTemp op1 = newTemp(Ity_I64);
3672 IRTemp op2 = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00003673 IRTemp cond = newTemp(Ity_I32);
3674
3675 if (m3 == 0) {
3676 } else {
3677 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00003678 always_goto_and_chase(
3679 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00003680 } else {
3681 assign(op1, get_gpr_dw0(r1));
3682 assign(op2, get_gpr_dw0(r2));
florianff9613f2012-05-12 15:26:44 +00003683 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
3684 op1, op2));
sewardj2019a972011-03-07 16:04:07 +00003685 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3686 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
3687
3688 }
3689 }
3690
3691 return "cgrj";
3692}
3693
3694static HChar *
3695s390_irgen_CIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
3696{
3697 IRTemp op1 = newTemp(Ity_I32);
3698 Int op2;
sewardj2019a972011-03-07 16:04:07 +00003699 IRTemp cond = newTemp(Ity_I32);
3700
3701 if (m3 == 0) {
3702 } else {
3703 if (m3 == 14) {
3704 always_goto(mkexpr(op4addr));
3705 } else {
3706 assign(op1, get_gpr_w1(r1));
3707 op2 = (Int)(Char)i2;
florianff9613f2012-05-12 15:26:44 +00003708 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
3709 mktemp(Ity_I32, mkU32((UInt)op2))));
sewardj2019a972011-03-07 16:04:07 +00003710 if_not_condition_goto_computed(binop(Iop_CmpEQ32, mkexpr(cond),
3711 mkU32(0)), mkexpr(op4addr));
3712 }
3713 }
3714
3715 return "cib";
3716}
3717
3718static HChar *
3719s390_irgen_CGIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
3720{
3721 IRTemp op1 = newTemp(Ity_I64);
3722 Long op2;
sewardj2019a972011-03-07 16:04:07 +00003723 IRTemp cond = newTemp(Ity_I32);
3724
3725 if (m3 == 0) {
3726 } else {
3727 if (m3 == 14) {
3728 always_goto(mkexpr(op4addr));
3729 } else {
3730 assign(op1, get_gpr_dw0(r1));
3731 op2 = (Long)(Char)i2;
florianff9613f2012-05-12 15:26:44 +00003732 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
3733 mktemp(Ity_I64, mkU64((ULong)op2))));
sewardj2019a972011-03-07 16:04:07 +00003734 if_not_condition_goto_computed(binop(Iop_CmpEQ32, mkexpr(cond),
3735 mkU32(0)), mkexpr(op4addr));
3736 }
3737 }
3738
3739 return "cgib";
3740}
3741
3742static HChar *
3743s390_irgen_CIJ(UChar r1, UChar m3, UShort i4, UChar i2)
3744{
3745 IRTemp op1 = newTemp(Ity_I32);
3746 Int op2;
sewardj2019a972011-03-07 16:04:07 +00003747 IRTemp cond = newTemp(Ity_I32);
3748
3749 if (m3 == 0) {
3750 } else {
3751 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00003752 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00003753 } else {
3754 assign(op1, get_gpr_w1(r1));
3755 op2 = (Int)(Char)i2;
florianff9613f2012-05-12 15:26:44 +00003756 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
3757 mktemp(Ity_I32, mkU32((UInt)op2))));
sewardj2019a972011-03-07 16:04:07 +00003758 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3759 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
3760
3761 }
3762 }
3763
3764 return "cij";
3765}
3766
3767static HChar *
3768s390_irgen_CGIJ(UChar r1, UChar m3, UShort i4, UChar i2)
3769{
3770 IRTemp op1 = newTemp(Ity_I64);
3771 Long op2;
sewardj2019a972011-03-07 16:04:07 +00003772 IRTemp cond = newTemp(Ity_I32);
3773
3774 if (m3 == 0) {
3775 } else {
3776 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00003777 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00003778 } else {
3779 assign(op1, get_gpr_dw0(r1));
3780 op2 = (Long)(Char)i2;
florianff9613f2012-05-12 15:26:44 +00003781 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
3782 mktemp(Ity_I64, mkU64((ULong)op2))));
sewardj2019a972011-03-07 16:04:07 +00003783 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3784 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
3785
3786 }
3787 }
3788
3789 return "cgij";
3790}
3791
3792static HChar *
3793s390_irgen_CH(UChar r1, IRTemp op2addr)
3794{
3795 IRTemp op1 = newTemp(Ity_I32);
3796 IRTemp op2 = newTemp(Ity_I32);
3797
3798 assign(op1, get_gpr_w1(r1));
3799 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
3800 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3801
3802 return "ch";
3803}
3804
3805static HChar *
3806s390_irgen_CHY(UChar r1, IRTemp op2addr)
3807{
3808 IRTemp op1 = newTemp(Ity_I32);
3809 IRTemp op2 = newTemp(Ity_I32);
3810
3811 assign(op1, get_gpr_w1(r1));
3812 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
3813 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3814
3815 return "chy";
3816}
3817
3818static HChar *
3819s390_irgen_CGH(UChar r1, IRTemp op2addr)
3820{
3821 IRTemp op1 = newTemp(Ity_I64);
3822 IRTemp op2 = newTemp(Ity_I64);
3823
3824 assign(op1, get_gpr_dw0(r1));
3825 assign(op2, unop(Iop_16Sto64, load(Ity_I16, mkexpr(op2addr))));
3826 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3827
3828 return "cgh";
3829}
3830
3831static HChar *
3832s390_irgen_CHI(UChar r1, UShort i2)
3833{
3834 IRTemp op1 = newTemp(Ity_I32);
3835 Int op2;
3836
3837 assign(op1, get_gpr_w1(r1));
3838 op2 = (Int)(Short)i2;
3839 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
3840 mkU32((UInt)op2)));
3841
3842 return "chi";
3843}
3844
3845static HChar *
3846s390_irgen_CGHI(UChar r1, UShort i2)
3847{
3848 IRTemp op1 = newTemp(Ity_I64);
3849 Long op2;
3850
3851 assign(op1, get_gpr_dw0(r1));
3852 op2 = (Long)(Short)i2;
3853 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I64,
3854 mkU64((ULong)op2)));
3855
3856 return "cghi";
3857}
3858
3859static HChar *
3860s390_irgen_CHHSI(UShort i2, IRTemp op1addr)
3861{
3862 IRTemp op1 = newTemp(Ity_I16);
3863 Short op2;
3864
3865 assign(op1, load(Ity_I16, mkexpr(op1addr)));
3866 op2 = (Short)i2;
3867 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I16,
3868 mkU16((UShort)op2)));
3869
3870 return "chhsi";
3871}
3872
3873static HChar *
3874s390_irgen_CHSI(UShort i2, IRTemp op1addr)
3875{
3876 IRTemp op1 = newTemp(Ity_I32);
3877 Int op2;
3878
3879 assign(op1, load(Ity_I32, mkexpr(op1addr)));
3880 op2 = (Int)(Short)i2;
3881 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
3882 mkU32((UInt)op2)));
3883
3884 return "chsi";
3885}
3886
3887static HChar *
3888s390_irgen_CGHSI(UShort i2, IRTemp op1addr)
3889{
3890 IRTemp op1 = newTemp(Ity_I64);
3891 Long op2;
3892
3893 assign(op1, load(Ity_I64, mkexpr(op1addr)));
3894 op2 = (Long)(Short)i2;
3895 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I64,
3896 mkU64((ULong)op2)));
3897
3898 return "cghsi";
3899}
3900
3901static HChar *
3902s390_irgen_CHRL(UChar r1, UInt i2)
3903{
3904 IRTemp op1 = newTemp(Ity_I32);
3905 IRTemp op2 = newTemp(Ity_I32);
3906
3907 assign(op1, get_gpr_w1(r1));
3908 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
3909 ((ULong)(Long)(Int)i2 << 1)))));
3910 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3911
3912 return "chrl";
3913}
3914
3915static HChar *
3916s390_irgen_CGHRL(UChar r1, UInt i2)
3917{
3918 IRTemp op1 = newTemp(Ity_I64);
3919 IRTemp op2 = newTemp(Ity_I64);
3920
3921 assign(op1, get_gpr_dw0(r1));
3922 assign(op2, unop(Iop_16Sto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
3923 ((ULong)(Long)(Int)i2 << 1)))));
3924 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3925
3926 return "cghrl";
3927}
3928
3929static HChar *
3930s390_irgen_CHHR(UChar r1, UChar r2)
3931{
3932 IRTemp op1 = newTemp(Ity_I32);
3933 IRTemp op2 = newTemp(Ity_I32);
3934
3935 assign(op1, get_gpr_w0(r1));
3936 assign(op2, get_gpr_w0(r2));
3937 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3938
3939 return "chhr";
3940}
3941
3942static HChar *
3943s390_irgen_CHLR(UChar r1, UChar r2)
3944{
3945 IRTemp op1 = newTemp(Ity_I32);
3946 IRTemp op2 = newTemp(Ity_I32);
3947
3948 assign(op1, get_gpr_w0(r1));
3949 assign(op2, get_gpr_w1(r2));
3950 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3951
3952 return "chlr";
3953}
3954
3955static HChar *
3956s390_irgen_CHF(UChar r1, IRTemp op2addr)
3957{
3958 IRTemp op1 = newTemp(Ity_I32);
3959 IRTemp op2 = newTemp(Ity_I32);
3960
3961 assign(op1, get_gpr_w0(r1));
3962 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3963 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3964
3965 return "chf";
3966}
3967
3968static HChar *
3969s390_irgen_CIH(UChar r1, UInt i2)
3970{
3971 IRTemp op1 = newTemp(Ity_I32);
3972 Int op2;
3973
3974 assign(op1, get_gpr_w0(r1));
3975 op2 = (Int)i2;
3976 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
3977 mkU32((UInt)op2)));
3978
3979 return "cih";
3980}
3981
3982static HChar *
3983s390_irgen_CLR(UChar r1, UChar r2)
3984{
3985 IRTemp op1 = newTemp(Ity_I32);
3986 IRTemp op2 = newTemp(Ity_I32);
3987
3988 assign(op1, get_gpr_w1(r1));
3989 assign(op2, get_gpr_w1(r2));
3990 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
3991
3992 return "clr";
3993}
3994
3995static HChar *
3996s390_irgen_CLGR(UChar r1, UChar r2)
3997{
3998 IRTemp op1 = newTemp(Ity_I64);
3999 IRTemp op2 = newTemp(Ity_I64);
4000
4001 assign(op1, get_gpr_dw0(r1));
4002 assign(op2, get_gpr_dw0(r2));
4003 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4004
4005 return "clgr";
4006}
4007
4008static HChar *
4009s390_irgen_CLGFR(UChar r1, UChar r2)
4010{
4011 IRTemp op1 = newTemp(Ity_I64);
4012 IRTemp op2 = newTemp(Ity_I64);
4013
4014 assign(op1, get_gpr_dw0(r1));
4015 assign(op2, unop(Iop_32Uto64, get_gpr_w1(r2)));
4016 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4017
4018 return "clgfr";
4019}
4020
4021static HChar *
4022s390_irgen_CL(UChar r1, IRTemp op2addr)
4023{
4024 IRTemp op1 = newTemp(Ity_I32);
4025 IRTemp op2 = newTemp(Ity_I32);
4026
4027 assign(op1, get_gpr_w1(r1));
4028 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4029 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4030
4031 return "cl";
4032}
4033
4034static HChar *
4035s390_irgen_CLY(UChar r1, IRTemp op2addr)
4036{
4037 IRTemp op1 = newTemp(Ity_I32);
4038 IRTemp op2 = newTemp(Ity_I32);
4039
4040 assign(op1, get_gpr_w1(r1));
4041 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4042 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4043
4044 return "cly";
4045}
4046
4047static HChar *
4048s390_irgen_CLG(UChar r1, IRTemp op2addr)
4049{
4050 IRTemp op1 = newTemp(Ity_I64);
4051 IRTemp op2 = newTemp(Ity_I64);
4052
4053 assign(op1, get_gpr_dw0(r1));
4054 assign(op2, load(Ity_I64, mkexpr(op2addr)));
4055 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4056
4057 return "clg";
4058}
4059
4060static HChar *
4061s390_irgen_CLGF(UChar r1, IRTemp op2addr)
4062{
4063 IRTemp op1 = newTemp(Ity_I64);
4064 IRTemp op2 = newTemp(Ity_I64);
4065
4066 assign(op1, get_gpr_dw0(r1));
4067 assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
4068 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4069
4070 return "clgf";
4071}
4072
4073static HChar *
4074s390_irgen_CLFI(UChar r1, UInt i2)
4075{
4076 IRTemp op1 = newTemp(Ity_I32);
4077 UInt op2;
4078
4079 assign(op1, get_gpr_w1(r1));
4080 op2 = i2;
4081 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I32,
4082 mkU32(op2)));
4083
4084 return "clfi";
4085}
4086
4087static HChar *
4088s390_irgen_CLGFI(UChar r1, UInt i2)
4089{
4090 IRTemp op1 = newTemp(Ity_I64);
4091 ULong op2;
4092
4093 assign(op1, get_gpr_dw0(r1));
4094 op2 = (ULong)i2;
4095 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I64,
4096 mkU64(op2)));
4097
4098 return "clgfi";
4099}
4100
4101static HChar *
4102s390_irgen_CLI(UChar i2, IRTemp op1addr)
4103{
4104 IRTemp op1 = newTemp(Ity_I8);
4105 UChar op2;
4106
4107 assign(op1, load(Ity_I8, mkexpr(op1addr)));
4108 op2 = i2;
4109 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I8,
4110 mkU8(op2)));
4111
4112 return "cli";
4113}
4114
4115static HChar *
4116s390_irgen_CLIY(UChar i2, IRTemp op1addr)
4117{
4118 IRTemp op1 = newTemp(Ity_I8);
4119 UChar op2;
4120
4121 assign(op1, load(Ity_I8, mkexpr(op1addr)));
4122 op2 = i2;
4123 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I8,
4124 mkU8(op2)));
4125
4126 return "cliy";
4127}
4128
4129static HChar *
4130s390_irgen_CLFHSI(UShort i2, IRTemp op1addr)
4131{
4132 IRTemp op1 = newTemp(Ity_I32);
4133 UInt op2;
4134
4135 assign(op1, load(Ity_I32, mkexpr(op1addr)));
4136 op2 = (UInt)i2;
4137 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I32,
4138 mkU32(op2)));
4139
4140 return "clfhsi";
4141}
4142
4143static HChar *
4144s390_irgen_CLGHSI(UShort i2, IRTemp op1addr)
4145{
4146 IRTemp op1 = newTemp(Ity_I64);
4147 ULong op2;
4148
4149 assign(op1, load(Ity_I64, mkexpr(op1addr)));
4150 op2 = (ULong)i2;
4151 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I64,
4152 mkU64(op2)));
4153
4154 return "clghsi";
4155}
4156
4157static HChar *
4158s390_irgen_CLHHSI(UShort i2, IRTemp op1addr)
4159{
4160 IRTemp op1 = newTemp(Ity_I16);
4161 UShort op2;
4162
4163 assign(op1, load(Ity_I16, mkexpr(op1addr)));
4164 op2 = i2;
4165 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I16,
4166 mkU16(op2)));
4167
4168 return "clhhsi";
4169}
4170
4171static HChar *
4172s390_irgen_CLRL(UChar r1, UInt i2)
4173{
4174 IRTemp op1 = newTemp(Ity_I32);
4175 IRTemp op2 = newTemp(Ity_I32);
4176
4177 assign(op1, get_gpr_w1(r1));
4178 assign(op2, load(Ity_I32, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
4179 i2 << 1))));
4180 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4181
4182 return "clrl";
4183}
4184
4185static HChar *
4186s390_irgen_CLGRL(UChar r1, UInt i2)
4187{
4188 IRTemp op1 = newTemp(Ity_I64);
4189 IRTemp op2 = newTemp(Ity_I64);
4190
4191 assign(op1, get_gpr_dw0(r1));
4192 assign(op2, load(Ity_I64, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
4193 i2 << 1))));
4194 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4195
4196 return "clgrl";
4197}
4198
4199static HChar *
4200s390_irgen_CLGFRL(UChar r1, UInt i2)
4201{
4202 IRTemp op1 = newTemp(Ity_I64);
4203 IRTemp op2 = newTemp(Ity_I64);
4204
4205 assign(op1, get_gpr_dw0(r1));
4206 assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
4207 ((ULong)(Long)(Int)i2 << 1)))));
4208 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4209
4210 return "clgfrl";
4211}
4212
4213static HChar *
4214s390_irgen_CLHRL(UChar r1, UInt i2)
4215{
4216 IRTemp op1 = newTemp(Ity_I32);
4217 IRTemp op2 = newTemp(Ity_I32);
4218
4219 assign(op1, get_gpr_w1(r1));
4220 assign(op2, unop(Iop_16Uto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
4221 ((ULong)(Long)(Int)i2 << 1)))));
4222 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4223
4224 return "clhrl";
4225}
4226
4227static HChar *
4228s390_irgen_CLGHRL(UChar r1, UInt i2)
4229{
4230 IRTemp op1 = newTemp(Ity_I64);
4231 IRTemp op2 = newTemp(Ity_I64);
4232
4233 assign(op1, get_gpr_dw0(r1));
4234 assign(op2, unop(Iop_16Uto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
4235 ((ULong)(Long)(Int)i2 << 1)))));
4236 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4237
4238 return "clghrl";
4239}
4240
4241static HChar *
4242s390_irgen_CLRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
4243{
4244 IRTemp op1 = newTemp(Ity_I32);
4245 IRTemp op2 = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00004246 IRTemp cond = newTemp(Ity_I32);
4247
4248 if (m3 == 0) {
4249 } else {
4250 if (m3 == 14) {
4251 always_goto(mkexpr(op4addr));
4252 } else {
4253 assign(op1, get_gpr_w1(r1));
4254 assign(op2, get_gpr_w1(r2));
florianff9613f2012-05-12 15:26:44 +00004255 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4256 op1, op2));
sewardj2019a972011-03-07 16:04:07 +00004257 if_not_condition_goto_computed(binop(Iop_CmpEQ32, mkexpr(cond),
4258 mkU32(0)), mkexpr(op4addr));
4259 }
4260 }
4261
4262 return "clrb";
4263}
4264
4265static HChar *
4266s390_irgen_CLGRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
4267{
4268 IRTemp op1 = newTemp(Ity_I64);
4269 IRTemp op2 = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00004270 IRTemp cond = newTemp(Ity_I32);
4271
4272 if (m3 == 0) {
4273 } else {
4274 if (m3 == 14) {
4275 always_goto(mkexpr(op4addr));
4276 } else {
4277 assign(op1, get_gpr_dw0(r1));
4278 assign(op2, get_gpr_dw0(r2));
florianff9613f2012-05-12 15:26:44 +00004279 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4280 op1, op2));
sewardj2019a972011-03-07 16:04:07 +00004281 if_not_condition_goto_computed(binop(Iop_CmpEQ32, mkexpr(cond),
4282 mkU32(0)), mkexpr(op4addr));
4283 }
4284 }
4285
4286 return "clgrb";
4287}
4288
4289static HChar *
4290s390_irgen_CLRJ(UChar r1, UChar r2, UShort i4, UChar m3)
4291{
4292 IRTemp op1 = newTemp(Ity_I32);
4293 IRTemp op2 = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00004294 IRTemp cond = newTemp(Ity_I32);
4295
4296 if (m3 == 0) {
4297 } else {
4298 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004299 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004300 } else {
4301 assign(op1, get_gpr_w1(r1));
4302 assign(op2, get_gpr_w1(r2));
florianff9613f2012-05-12 15:26:44 +00004303 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4304 op1, op2));
sewardj2019a972011-03-07 16:04:07 +00004305 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4306 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4307
4308 }
4309 }
4310
4311 return "clrj";
4312}
4313
4314static HChar *
4315s390_irgen_CLGRJ(UChar r1, UChar r2, UShort i4, UChar m3)
4316{
4317 IRTemp op1 = newTemp(Ity_I64);
4318 IRTemp op2 = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00004319 IRTemp cond = newTemp(Ity_I32);
4320
4321 if (m3 == 0) {
4322 } else {
4323 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004324 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004325 } else {
4326 assign(op1, get_gpr_dw0(r1));
4327 assign(op2, get_gpr_dw0(r2));
florianff9613f2012-05-12 15:26:44 +00004328 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4329 op1, op2));
sewardj2019a972011-03-07 16:04:07 +00004330 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4331 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4332
4333 }
4334 }
4335
4336 return "clgrj";
4337}
4338
4339static HChar *
4340s390_irgen_CLIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
4341{
4342 IRTemp op1 = newTemp(Ity_I32);
4343 UInt op2;
sewardj2019a972011-03-07 16:04:07 +00004344 IRTemp cond = newTemp(Ity_I32);
4345
4346 if (m3 == 0) {
4347 } else {
4348 if (m3 == 14) {
4349 always_goto(mkexpr(op4addr));
4350 } else {
4351 assign(op1, get_gpr_w1(r1));
4352 op2 = (UInt)i2;
florianff9613f2012-05-12 15:26:44 +00004353 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4354 mktemp(Ity_I32, mkU32(op2))));
sewardj2019a972011-03-07 16:04:07 +00004355 if_not_condition_goto_computed(binop(Iop_CmpEQ32, mkexpr(cond),
4356 mkU32(0)), mkexpr(op4addr));
4357 }
4358 }
4359
4360 return "clib";
4361}
4362
4363static HChar *
4364s390_irgen_CLGIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
4365{
4366 IRTemp op1 = newTemp(Ity_I64);
4367 ULong op2;
sewardj2019a972011-03-07 16:04:07 +00004368 IRTemp cond = newTemp(Ity_I32);
4369
4370 if (m3 == 0) {
4371 } else {
4372 if (m3 == 14) {
4373 always_goto(mkexpr(op4addr));
4374 } else {
4375 assign(op1, get_gpr_dw0(r1));
4376 op2 = (ULong)i2;
florianff9613f2012-05-12 15:26:44 +00004377 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4378 mktemp(Ity_I64, mkU64(op2))));
sewardj2019a972011-03-07 16:04:07 +00004379 if_not_condition_goto_computed(binop(Iop_CmpEQ32, mkexpr(cond),
4380 mkU32(0)), mkexpr(op4addr));
4381 }
4382 }
4383
4384 return "clgib";
4385}
4386
4387static HChar *
4388s390_irgen_CLIJ(UChar r1, UChar m3, UShort i4, UChar i2)
4389{
4390 IRTemp op1 = newTemp(Ity_I32);
4391 UInt op2;
sewardj2019a972011-03-07 16:04:07 +00004392 IRTemp cond = newTemp(Ity_I32);
4393
4394 if (m3 == 0) {
4395 } else {
4396 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004397 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004398 } else {
4399 assign(op1, get_gpr_w1(r1));
4400 op2 = (UInt)i2;
florianff9613f2012-05-12 15:26:44 +00004401 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4402 mktemp(Ity_I32, mkU32(op2))));
sewardj2019a972011-03-07 16:04:07 +00004403 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4404 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4405
4406 }
4407 }
4408
4409 return "clij";
4410}
4411
4412static HChar *
4413s390_irgen_CLGIJ(UChar r1, UChar m3, UShort i4, UChar i2)
4414{
4415 IRTemp op1 = newTemp(Ity_I64);
4416 ULong op2;
sewardj2019a972011-03-07 16:04:07 +00004417 IRTemp cond = newTemp(Ity_I32);
4418
4419 if (m3 == 0) {
4420 } else {
4421 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004422 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004423 } else {
4424 assign(op1, get_gpr_dw0(r1));
4425 op2 = (ULong)i2;
florianff9613f2012-05-12 15:26:44 +00004426 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4427 mktemp(Ity_I64, mkU64(op2))));
sewardj2019a972011-03-07 16:04:07 +00004428 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4429 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4430
4431 }
4432 }
4433
4434 return "clgij";
4435}
4436
4437static HChar *
4438s390_irgen_CLM(UChar r1, UChar r3, IRTemp op2addr)
4439{
4440 IRTemp op1 = newTemp(Ity_I32);
4441 IRTemp op2 = newTemp(Ity_I32);
4442 IRTemp b0 = newTemp(Ity_I32);
4443 IRTemp b1 = newTemp(Ity_I32);
4444 IRTemp b2 = newTemp(Ity_I32);
4445 IRTemp b3 = newTemp(Ity_I32);
4446 IRTemp c0 = newTemp(Ity_I32);
4447 IRTemp c1 = newTemp(Ity_I32);
4448 IRTemp c2 = newTemp(Ity_I32);
4449 IRTemp c3 = newTemp(Ity_I32);
4450 UChar n;
4451
4452 n = 0;
4453 if ((r3 & 8) != 0) {
4454 assign(b0, unop(Iop_8Uto32, get_gpr_b4(r1)));
4455 assign(c0, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
4456 n = n + 1;
4457 } else {
4458 assign(b0, mkU32(0));
4459 assign(c0, mkU32(0));
4460 }
4461 if ((r3 & 4) != 0) {
4462 assign(b1, unop(Iop_8Uto32, get_gpr_b5(r1)));
4463 assign(c1, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4464 mkU64(n)))));
4465 n = n + 1;
4466 } else {
4467 assign(b1, mkU32(0));
4468 assign(c1, mkU32(0));
4469 }
4470 if ((r3 & 2) != 0) {
4471 assign(b2, unop(Iop_8Uto32, get_gpr_b6(r1)));
4472 assign(c2, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4473 mkU64(n)))));
4474 n = n + 1;
4475 } else {
4476 assign(b2, mkU32(0));
4477 assign(c2, mkU32(0));
4478 }
4479 if ((r3 & 1) != 0) {
4480 assign(b3, unop(Iop_8Uto32, get_gpr_b7(r1)));
4481 assign(c3, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4482 mkU64(n)))));
4483 n = n + 1;
4484 } else {
4485 assign(b3, mkU32(0));
4486 assign(c3, mkU32(0));
4487 }
4488 assign(op1, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4489 mkexpr(b0), mkU8(24)), binop(Iop_Shl32, mkexpr(b1), mkU8(16))),
4490 binop(Iop_Shl32, mkexpr(b2), mkU8(8))), mkexpr(b3)));
4491 assign(op2, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4492 mkexpr(c0), mkU8(24)), binop(Iop_Shl32, mkexpr(c1), mkU8(16))),
4493 binop(Iop_Shl32, mkexpr(c2), mkU8(8))), mkexpr(c3)));
4494 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4495
4496 return "clm";
4497}
4498
4499static HChar *
4500s390_irgen_CLMY(UChar r1, UChar r3, IRTemp op2addr)
4501{
4502 IRTemp op1 = newTemp(Ity_I32);
4503 IRTemp op2 = newTemp(Ity_I32);
4504 IRTemp b0 = newTemp(Ity_I32);
4505 IRTemp b1 = newTemp(Ity_I32);
4506 IRTemp b2 = newTemp(Ity_I32);
4507 IRTemp b3 = newTemp(Ity_I32);
4508 IRTemp c0 = newTemp(Ity_I32);
4509 IRTemp c1 = newTemp(Ity_I32);
4510 IRTemp c2 = newTemp(Ity_I32);
4511 IRTemp c3 = newTemp(Ity_I32);
4512 UChar n;
4513
4514 n = 0;
4515 if ((r3 & 8) != 0) {
4516 assign(b0, unop(Iop_8Uto32, get_gpr_b4(r1)));
4517 assign(c0, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
4518 n = n + 1;
4519 } else {
4520 assign(b0, mkU32(0));
4521 assign(c0, mkU32(0));
4522 }
4523 if ((r3 & 4) != 0) {
4524 assign(b1, unop(Iop_8Uto32, get_gpr_b5(r1)));
4525 assign(c1, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4526 mkU64(n)))));
4527 n = n + 1;
4528 } else {
4529 assign(b1, mkU32(0));
4530 assign(c1, mkU32(0));
4531 }
4532 if ((r3 & 2) != 0) {
4533 assign(b2, unop(Iop_8Uto32, get_gpr_b6(r1)));
4534 assign(c2, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4535 mkU64(n)))));
4536 n = n + 1;
4537 } else {
4538 assign(b2, mkU32(0));
4539 assign(c2, mkU32(0));
4540 }
4541 if ((r3 & 1) != 0) {
4542 assign(b3, unop(Iop_8Uto32, get_gpr_b7(r1)));
4543 assign(c3, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4544 mkU64(n)))));
4545 n = n + 1;
4546 } else {
4547 assign(b3, mkU32(0));
4548 assign(c3, mkU32(0));
4549 }
4550 assign(op1, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4551 mkexpr(b0), mkU8(24)), binop(Iop_Shl32, mkexpr(b1), mkU8(16))),
4552 binop(Iop_Shl32, mkexpr(b2), mkU8(8))), mkexpr(b3)));
4553 assign(op2, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4554 mkexpr(c0), mkU8(24)), binop(Iop_Shl32, mkexpr(c1), mkU8(16))),
4555 binop(Iop_Shl32, mkexpr(c2), mkU8(8))), mkexpr(c3)));
4556 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4557
4558 return "clmy";
4559}
4560
4561static HChar *
4562s390_irgen_CLMH(UChar r1, UChar r3, IRTemp op2addr)
4563{
4564 IRTemp op1 = newTemp(Ity_I32);
4565 IRTemp op2 = newTemp(Ity_I32);
4566 IRTemp b0 = newTemp(Ity_I32);
4567 IRTemp b1 = newTemp(Ity_I32);
4568 IRTemp b2 = newTemp(Ity_I32);
4569 IRTemp b3 = newTemp(Ity_I32);
4570 IRTemp c0 = newTemp(Ity_I32);
4571 IRTemp c1 = newTemp(Ity_I32);
4572 IRTemp c2 = newTemp(Ity_I32);
4573 IRTemp c3 = newTemp(Ity_I32);
4574 UChar n;
4575
4576 n = 0;
4577 if ((r3 & 8) != 0) {
4578 assign(b0, unop(Iop_8Uto32, get_gpr_b0(r1)));
4579 assign(c0, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
4580 n = n + 1;
4581 } else {
4582 assign(b0, mkU32(0));
4583 assign(c0, mkU32(0));
4584 }
4585 if ((r3 & 4) != 0) {
4586 assign(b1, unop(Iop_8Uto32, get_gpr_b1(r1)));
4587 assign(c1, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4588 mkU64(n)))));
4589 n = n + 1;
4590 } else {
4591 assign(b1, mkU32(0));
4592 assign(c1, mkU32(0));
4593 }
4594 if ((r3 & 2) != 0) {
4595 assign(b2, unop(Iop_8Uto32, get_gpr_b2(r1)));
4596 assign(c2, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4597 mkU64(n)))));
4598 n = n + 1;
4599 } else {
4600 assign(b2, mkU32(0));
4601 assign(c2, mkU32(0));
4602 }
4603 if ((r3 & 1) != 0) {
4604 assign(b3, unop(Iop_8Uto32, get_gpr_b3(r1)));
4605 assign(c3, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4606 mkU64(n)))));
4607 n = n + 1;
4608 } else {
4609 assign(b3, mkU32(0));
4610 assign(c3, mkU32(0));
4611 }
4612 assign(op1, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4613 mkexpr(b0), mkU8(24)), binop(Iop_Shl32, mkexpr(b1), mkU8(16))),
4614 binop(Iop_Shl32, mkexpr(b2), mkU8(8))), mkexpr(b3)));
4615 assign(op2, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4616 mkexpr(c0), mkU8(24)), binop(Iop_Shl32, mkexpr(c1), mkU8(16))),
4617 binop(Iop_Shl32, mkexpr(c2), mkU8(8))), mkexpr(c3)));
4618 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4619
4620 return "clmh";
4621}
4622
4623static HChar *
4624s390_irgen_CLHHR(UChar r1, UChar r2)
4625{
4626 IRTemp op1 = newTemp(Ity_I32);
4627 IRTemp op2 = newTemp(Ity_I32);
4628
4629 assign(op1, get_gpr_w0(r1));
4630 assign(op2, get_gpr_w0(r2));
4631 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4632
4633 return "clhhr";
4634}
4635
4636static HChar *
4637s390_irgen_CLHLR(UChar r1, UChar r2)
4638{
4639 IRTemp op1 = newTemp(Ity_I32);
4640 IRTemp op2 = newTemp(Ity_I32);
4641
4642 assign(op1, get_gpr_w0(r1));
4643 assign(op2, get_gpr_w1(r2));
4644 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4645
4646 return "clhlr";
4647}
4648
4649static HChar *
4650s390_irgen_CLHF(UChar r1, IRTemp op2addr)
4651{
4652 IRTemp op1 = newTemp(Ity_I32);
4653 IRTemp op2 = newTemp(Ity_I32);
4654
4655 assign(op1, get_gpr_w0(r1));
4656 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4657 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4658
4659 return "clhf";
4660}
4661
4662static HChar *
4663s390_irgen_CLIH(UChar r1, UInt i2)
4664{
4665 IRTemp op1 = newTemp(Ity_I32);
4666 UInt op2;
4667
4668 assign(op1, get_gpr_w0(r1));
4669 op2 = i2;
4670 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I32,
4671 mkU32(op2)));
4672
4673 return "clih";
4674}
4675
4676static HChar *
4677s390_irgen_CPYA(UChar r1, UChar r2)
4678{
4679 put_ar_w0(r1, get_ar_w0(r2));
sewardj7ee97522011-05-09 21:45:04 +00004680 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00004681 s390_disasm(ENC3(MNM, AR, AR), "cpya", r1, r2);
4682
4683 return "cpya";
4684}
4685
4686static HChar *
4687s390_irgen_XR(UChar r1, UChar r2)
4688{
4689 IRTemp op1 = newTemp(Ity_I32);
4690 IRTemp op2 = newTemp(Ity_I32);
4691 IRTemp result = newTemp(Ity_I32);
4692
4693 if (r1 == r2) {
4694 assign(result, mkU32(0));
4695 } else {
4696 assign(op1, get_gpr_w1(r1));
4697 assign(op2, get_gpr_w1(r2));
4698 assign(result, binop(Iop_Xor32, mkexpr(op1), mkexpr(op2)));
4699 }
4700 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4701 put_gpr_w1(r1, mkexpr(result));
4702
4703 return "xr";
4704}
4705
4706static HChar *
4707s390_irgen_XGR(UChar r1, UChar r2)
4708{
4709 IRTemp op1 = newTemp(Ity_I64);
4710 IRTemp op2 = newTemp(Ity_I64);
4711 IRTemp result = newTemp(Ity_I64);
4712
4713 if (r1 == r2) {
4714 assign(result, mkU64(0));
4715 } else {
4716 assign(op1, get_gpr_dw0(r1));
4717 assign(op2, get_gpr_dw0(r2));
4718 assign(result, binop(Iop_Xor64, mkexpr(op1), mkexpr(op2)));
4719 }
4720 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4721 put_gpr_dw0(r1, mkexpr(result));
4722
4723 return "xgr";
4724}
4725
4726static HChar *
4727s390_irgen_XRK(UChar r3, UChar r1, UChar r2)
4728{
4729 IRTemp op2 = newTemp(Ity_I32);
4730 IRTemp op3 = newTemp(Ity_I32);
4731 IRTemp result = newTemp(Ity_I32);
4732
4733 assign(op2, get_gpr_w1(r2));
4734 assign(op3, get_gpr_w1(r3));
4735 assign(result, binop(Iop_Xor32, mkexpr(op2), mkexpr(op3)));
4736 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4737 put_gpr_w1(r1, mkexpr(result));
4738
4739 return "xrk";
4740}
4741
4742static HChar *
4743s390_irgen_XGRK(UChar r3, UChar r1, UChar r2)
4744{
4745 IRTemp op2 = newTemp(Ity_I64);
4746 IRTemp op3 = newTemp(Ity_I64);
4747 IRTemp result = newTemp(Ity_I64);
4748
4749 assign(op2, get_gpr_dw0(r2));
4750 assign(op3, get_gpr_dw0(r3));
4751 assign(result, binop(Iop_Xor64, mkexpr(op2), mkexpr(op3)));
4752 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4753 put_gpr_dw0(r1, mkexpr(result));
4754
4755 return "xgrk";
4756}
4757
4758static HChar *
4759s390_irgen_X(UChar r1, IRTemp op2addr)
4760{
4761 IRTemp op1 = newTemp(Ity_I32);
4762 IRTemp op2 = newTemp(Ity_I32);
4763 IRTemp result = newTemp(Ity_I32);
4764
4765 assign(op1, get_gpr_w1(r1));
4766 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4767 assign(result, binop(Iop_Xor32, mkexpr(op1), mkexpr(op2)));
4768 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4769 put_gpr_w1(r1, mkexpr(result));
4770
4771 return "x";
4772}
4773
4774static HChar *
4775s390_irgen_XY(UChar r1, IRTemp op2addr)
4776{
4777 IRTemp op1 = newTemp(Ity_I32);
4778 IRTemp op2 = newTemp(Ity_I32);
4779 IRTemp result = newTemp(Ity_I32);
4780
4781 assign(op1, get_gpr_w1(r1));
4782 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4783 assign(result, binop(Iop_Xor32, mkexpr(op1), mkexpr(op2)));
4784 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4785 put_gpr_w1(r1, mkexpr(result));
4786
4787 return "xy";
4788}
4789
4790static HChar *
4791s390_irgen_XG(UChar r1, IRTemp op2addr)
4792{
4793 IRTemp op1 = newTemp(Ity_I64);
4794 IRTemp op2 = newTemp(Ity_I64);
4795 IRTemp result = newTemp(Ity_I64);
4796
4797 assign(op1, get_gpr_dw0(r1));
4798 assign(op2, load(Ity_I64, mkexpr(op2addr)));
4799 assign(result, binop(Iop_Xor64, mkexpr(op1), mkexpr(op2)));
4800 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4801 put_gpr_dw0(r1, mkexpr(result));
4802
4803 return "xg";
4804}
4805
4806static HChar *
4807s390_irgen_XI(UChar i2, IRTemp op1addr)
4808{
4809 IRTemp op1 = newTemp(Ity_I8);
4810 UChar op2;
4811 IRTemp result = newTemp(Ity_I8);
4812
4813 assign(op1, load(Ity_I8, mkexpr(op1addr)));
4814 op2 = i2;
4815 assign(result, binop(Iop_Xor8, mkexpr(op1), mkU8(op2)));
4816 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4817 store(mkexpr(op1addr), mkexpr(result));
4818
4819 return "xi";
4820}
4821
4822static HChar *
4823s390_irgen_XIY(UChar i2, IRTemp op1addr)
4824{
4825 IRTemp op1 = newTemp(Ity_I8);
4826 UChar op2;
4827 IRTemp result = newTemp(Ity_I8);
4828
4829 assign(op1, load(Ity_I8, mkexpr(op1addr)));
4830 op2 = i2;
4831 assign(result, binop(Iop_Xor8, mkexpr(op1), mkU8(op2)));
4832 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4833 store(mkexpr(op1addr), mkexpr(result));
4834
4835 return "xiy";
4836}
4837
4838static HChar *
4839s390_irgen_XIHF(UChar r1, UInt i2)
4840{
4841 IRTemp op1 = newTemp(Ity_I32);
4842 UInt op2;
4843 IRTemp result = newTemp(Ity_I32);
4844
4845 assign(op1, get_gpr_w0(r1));
4846 op2 = i2;
4847 assign(result, binop(Iop_Xor32, mkexpr(op1), mkU32(op2)));
4848 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4849 put_gpr_w0(r1, mkexpr(result));
4850
4851 return "xihf";
4852}
4853
4854static HChar *
4855s390_irgen_XILF(UChar r1, UInt i2)
4856{
4857 IRTemp op1 = newTemp(Ity_I32);
4858 UInt op2;
4859 IRTemp result = newTemp(Ity_I32);
4860
4861 assign(op1, get_gpr_w1(r1));
4862 op2 = i2;
4863 assign(result, binop(Iop_Xor32, mkexpr(op1), mkU32(op2)));
4864 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4865 put_gpr_w1(r1, mkexpr(result));
4866
4867 return "xilf";
4868}
4869
4870static HChar *
4871s390_irgen_EAR(UChar r1, UChar r2)
4872{
4873 put_gpr_w1(r1, get_ar_w0(r2));
sewardj7ee97522011-05-09 21:45:04 +00004874 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00004875 s390_disasm(ENC3(MNM, GPR, AR), "ear", r1, r2);
4876
4877 return "ear";
4878}
4879
4880static HChar *
4881s390_irgen_IC(UChar r1, IRTemp op2addr)
4882{
4883 put_gpr_b7(r1, load(Ity_I8, mkexpr(op2addr)));
4884
4885 return "ic";
4886}
4887
4888static HChar *
4889s390_irgen_ICY(UChar r1, IRTemp op2addr)
4890{
4891 put_gpr_b7(r1, load(Ity_I8, mkexpr(op2addr)));
4892
4893 return "icy";
4894}
4895
4896static HChar *
4897s390_irgen_ICM(UChar r1, UChar r3, IRTemp op2addr)
4898{
4899 UChar n;
4900 IRTemp result = newTemp(Ity_I32);
4901 UInt mask;
4902
4903 n = 0;
4904 mask = (UInt)r3;
4905 if ((mask & 8) != 0) {
4906 put_gpr_b4(r1, load(Ity_I8, mkexpr(op2addr)));
4907 n = n + 1;
4908 }
4909 if ((mask & 4) != 0) {
4910 put_gpr_b5(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
4911
4912 n = n + 1;
4913 }
4914 if ((mask & 2) != 0) {
4915 put_gpr_b6(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
4916
4917 n = n + 1;
4918 }
4919 if ((mask & 1) != 0) {
4920 put_gpr_b7(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
4921
4922 n = n + 1;
4923 }
4924 assign(result, get_gpr_w1(r1));
4925 s390_cc_thunk_putZZ(S390_CC_OP_INSERT_CHAR_MASK_32, result, mktemp(Ity_I32,
4926 mkU32(mask)));
4927
4928 return "icm";
4929}
4930
4931static HChar *
4932s390_irgen_ICMY(UChar r1, UChar r3, IRTemp op2addr)
4933{
4934 UChar n;
4935 IRTemp result = newTemp(Ity_I32);
4936 UInt mask;
4937
4938 n = 0;
4939 mask = (UInt)r3;
4940 if ((mask & 8) != 0) {
4941 put_gpr_b4(r1, load(Ity_I8, mkexpr(op2addr)));
4942 n = n + 1;
4943 }
4944 if ((mask & 4) != 0) {
4945 put_gpr_b5(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
4946
4947 n = n + 1;
4948 }
4949 if ((mask & 2) != 0) {
4950 put_gpr_b6(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
4951
4952 n = n + 1;
4953 }
4954 if ((mask & 1) != 0) {
4955 put_gpr_b7(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
4956
4957 n = n + 1;
4958 }
4959 assign(result, get_gpr_w1(r1));
4960 s390_cc_thunk_putZZ(S390_CC_OP_INSERT_CHAR_MASK_32, result, mktemp(Ity_I32,
4961 mkU32(mask)));
4962
4963 return "icmy";
4964}
4965
4966static HChar *
4967s390_irgen_ICMH(UChar r1, UChar r3, IRTemp op2addr)
4968{
4969 UChar n;
4970 IRTemp result = newTemp(Ity_I32);
4971 UInt mask;
4972
4973 n = 0;
4974 mask = (UInt)r3;
4975 if ((mask & 8) != 0) {
4976 put_gpr_b0(r1, load(Ity_I8, mkexpr(op2addr)));
4977 n = n + 1;
4978 }
4979 if ((mask & 4) != 0) {
4980 put_gpr_b1(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
4981
4982 n = n + 1;
4983 }
4984 if ((mask & 2) != 0) {
4985 put_gpr_b2(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
4986
4987 n = n + 1;
4988 }
4989 if ((mask & 1) != 0) {
4990 put_gpr_b3(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
4991
4992 n = n + 1;
4993 }
4994 assign(result, get_gpr_w0(r1));
4995 s390_cc_thunk_putZZ(S390_CC_OP_INSERT_CHAR_MASK_32, result, mktemp(Ity_I32,
4996 mkU32(mask)));
4997
4998 return "icmh";
4999}
5000
5001static HChar *
5002s390_irgen_IIHF(UChar r1, UInt i2)
5003{
5004 put_gpr_w0(r1, mkU32(i2));
5005
5006 return "iihf";
5007}
5008
5009static HChar *
5010s390_irgen_IIHH(UChar r1, UShort i2)
5011{
5012 put_gpr_hw0(r1, mkU16(i2));
5013
5014 return "iihh";
5015}
5016
5017static HChar *
5018s390_irgen_IIHL(UChar r1, UShort i2)
5019{
5020 put_gpr_hw1(r1, mkU16(i2));
5021
5022 return "iihl";
5023}
5024
5025static HChar *
5026s390_irgen_IILF(UChar r1, UInt i2)
5027{
5028 put_gpr_w1(r1, mkU32(i2));
5029
5030 return "iilf";
5031}
5032
5033static HChar *
5034s390_irgen_IILH(UChar r1, UShort i2)
5035{
5036 put_gpr_hw2(r1, mkU16(i2));
5037
5038 return "iilh";
5039}
5040
5041static HChar *
5042s390_irgen_IILL(UChar r1, UShort i2)
5043{
5044 put_gpr_hw3(r1, mkU16(i2));
5045
5046 return "iill";
5047}
5048
5049static HChar *
5050s390_irgen_LR(UChar r1, UChar r2)
5051{
5052 put_gpr_w1(r1, get_gpr_w1(r2));
5053
5054 return "lr";
5055}
5056
5057static HChar *
5058s390_irgen_LGR(UChar r1, UChar r2)
5059{
5060 put_gpr_dw0(r1, get_gpr_dw0(r2));
5061
5062 return "lgr";
5063}
5064
5065static HChar *
5066s390_irgen_LGFR(UChar r1, UChar r2)
5067{
5068 put_gpr_dw0(r1, unop(Iop_32Sto64, get_gpr_w1(r2)));
5069
5070 return "lgfr";
5071}
5072
5073static HChar *
5074s390_irgen_L(UChar r1, IRTemp op2addr)
5075{
5076 put_gpr_w1(r1, load(Ity_I32, mkexpr(op2addr)));
5077
5078 return "l";
5079}
5080
5081static HChar *
5082s390_irgen_LY(UChar r1, IRTemp op2addr)
5083{
5084 put_gpr_w1(r1, load(Ity_I32, mkexpr(op2addr)));
5085
5086 return "ly";
5087}
5088
5089static HChar *
5090s390_irgen_LG(UChar r1, IRTemp op2addr)
5091{
5092 put_gpr_dw0(r1, load(Ity_I64, mkexpr(op2addr)));
5093
5094 return "lg";
5095}
5096
5097static HChar *
5098s390_irgen_LGF(UChar r1, IRTemp op2addr)
5099{
5100 put_gpr_dw0(r1, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
5101
5102 return "lgf";
5103}
5104
5105static HChar *
5106s390_irgen_LGFI(UChar r1, UInt i2)
5107{
5108 put_gpr_dw0(r1, mkU64((ULong)(Long)(Int)i2));
5109
5110 return "lgfi";
5111}
5112
5113static HChar *
5114s390_irgen_LRL(UChar r1, UInt i2)
5115{
5116 put_gpr_w1(r1, load(Ity_I32, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
5117 i2 << 1))));
5118
5119 return "lrl";
5120}
5121
5122static HChar *
5123s390_irgen_LGRL(UChar r1, UInt i2)
5124{
5125 put_gpr_dw0(r1, load(Ity_I64, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
5126 i2 << 1))));
5127
5128 return "lgrl";
5129}
5130
5131static HChar *
5132s390_irgen_LGFRL(UChar r1, UInt i2)
5133{
5134 put_gpr_dw0(r1, unop(Iop_32Sto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
5135 ((ULong)(Long)(Int)i2 << 1)))));
5136
5137 return "lgfrl";
5138}
5139
5140static HChar *
5141s390_irgen_LA(UChar r1, IRTemp op2addr)
5142{
5143 put_gpr_dw0(r1, mkexpr(op2addr));
5144
5145 return "la";
5146}
5147
5148static HChar *
5149s390_irgen_LAY(UChar r1, IRTemp op2addr)
5150{
5151 put_gpr_dw0(r1, mkexpr(op2addr));
5152
5153 return "lay";
5154}
5155
5156static HChar *
5157s390_irgen_LAE(UChar r1, IRTemp op2addr)
5158{
5159 put_gpr_dw0(r1, mkexpr(op2addr));
5160
5161 return "lae";
5162}
5163
5164static HChar *
5165s390_irgen_LAEY(UChar r1, IRTemp op2addr)
5166{
5167 put_gpr_dw0(r1, mkexpr(op2addr));
5168
5169 return "laey";
5170}
5171
5172static HChar *
5173s390_irgen_LARL(UChar r1, UInt i2)
5174{
5175 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)));
5176
5177 return "larl";
5178}
5179
5180static HChar *
5181s390_irgen_LAA(UChar r1, UChar r3, IRTemp op2addr)
5182{
5183 IRTemp op2 = newTemp(Ity_I32);
5184 IRTemp op3 = newTemp(Ity_I32);
5185 IRTemp result = newTemp(Ity_I32);
5186
5187 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5188 assign(op3, get_gpr_w1(r3));
5189 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
5190 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
5191 store(mkexpr(op2addr), mkexpr(result));
5192 put_gpr_w1(r1, mkexpr(op2));
5193
5194 return "laa";
5195}
5196
5197static HChar *
5198s390_irgen_LAAG(UChar r1, UChar r3, IRTemp op2addr)
5199{
5200 IRTemp op2 = newTemp(Ity_I64);
5201 IRTemp op3 = newTemp(Ity_I64);
5202 IRTemp result = newTemp(Ity_I64);
5203
5204 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5205 assign(op3, get_gpr_dw0(r3));
5206 assign(result, binop(Iop_Add64, mkexpr(op2), mkexpr(op3)));
5207 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op2, op3);
5208 store(mkexpr(op2addr), mkexpr(result));
5209 put_gpr_dw0(r1, mkexpr(op2));
5210
5211 return "laag";
5212}
5213
5214static HChar *
5215s390_irgen_LAAL(UChar r1, UChar r3, IRTemp op2addr)
5216{
5217 IRTemp op2 = newTemp(Ity_I32);
5218 IRTemp op3 = newTemp(Ity_I32);
5219 IRTemp result = newTemp(Ity_I32);
5220
5221 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5222 assign(op3, get_gpr_w1(r3));
5223 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
5224 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
5225 store(mkexpr(op2addr), mkexpr(result));
5226 put_gpr_w1(r1, mkexpr(op2));
5227
5228 return "laal";
5229}
5230
5231static HChar *
5232s390_irgen_LAALG(UChar r1, UChar r3, IRTemp op2addr)
5233{
5234 IRTemp op2 = newTemp(Ity_I64);
5235 IRTemp op3 = newTemp(Ity_I64);
5236 IRTemp result = newTemp(Ity_I64);
5237
5238 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5239 assign(op3, get_gpr_dw0(r3));
5240 assign(result, binop(Iop_Add64, mkexpr(op2), mkexpr(op3)));
5241 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op2, op3);
5242 store(mkexpr(op2addr), mkexpr(result));
5243 put_gpr_dw0(r1, mkexpr(op2));
5244
5245 return "laalg";
5246}
5247
5248static HChar *
5249s390_irgen_LAN(UChar r1, UChar r3, IRTemp op2addr)
5250{
5251 IRTemp op2 = newTemp(Ity_I32);
5252 IRTemp op3 = newTemp(Ity_I32);
5253 IRTemp result = newTemp(Ity_I32);
5254
5255 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5256 assign(op3, get_gpr_w1(r3));
5257 assign(result, binop(Iop_And32, mkexpr(op2), mkexpr(op3)));
5258 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5259 store(mkexpr(op2addr), mkexpr(result));
5260 put_gpr_w1(r1, mkexpr(op2));
5261
5262 return "lan";
5263}
5264
5265static HChar *
5266s390_irgen_LANG(UChar r1, UChar r3, IRTemp op2addr)
5267{
5268 IRTemp op2 = newTemp(Ity_I64);
5269 IRTemp op3 = newTemp(Ity_I64);
5270 IRTemp result = newTemp(Ity_I64);
5271
5272 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5273 assign(op3, get_gpr_dw0(r3));
5274 assign(result, binop(Iop_And64, mkexpr(op2), mkexpr(op3)));
5275 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5276 store(mkexpr(op2addr), mkexpr(result));
5277 put_gpr_dw0(r1, mkexpr(op2));
5278
5279 return "lang";
5280}
5281
5282static HChar *
5283s390_irgen_LAX(UChar r1, UChar r3, IRTemp op2addr)
5284{
5285 IRTemp op2 = newTemp(Ity_I32);
5286 IRTemp op3 = newTemp(Ity_I32);
5287 IRTemp result = newTemp(Ity_I32);
5288
5289 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5290 assign(op3, get_gpr_w1(r3));
5291 assign(result, binop(Iop_Xor32, mkexpr(op2), mkexpr(op3)));
5292 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5293 store(mkexpr(op2addr), mkexpr(result));
5294 put_gpr_w1(r1, mkexpr(op2));
5295
5296 return "lax";
5297}
5298
5299static HChar *
5300s390_irgen_LAXG(UChar r1, UChar r3, IRTemp op2addr)
5301{
5302 IRTemp op2 = newTemp(Ity_I64);
5303 IRTemp op3 = newTemp(Ity_I64);
5304 IRTemp result = newTemp(Ity_I64);
5305
5306 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5307 assign(op3, get_gpr_dw0(r3));
5308 assign(result, binop(Iop_Xor64, mkexpr(op2), mkexpr(op3)));
5309 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5310 store(mkexpr(op2addr), mkexpr(result));
5311 put_gpr_dw0(r1, mkexpr(op2));
5312
5313 return "laxg";
5314}
5315
5316static HChar *
5317s390_irgen_LAO(UChar r1, UChar r3, IRTemp op2addr)
5318{
5319 IRTemp op2 = newTemp(Ity_I32);
5320 IRTemp op3 = newTemp(Ity_I32);
5321 IRTemp result = newTemp(Ity_I32);
5322
5323 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5324 assign(op3, get_gpr_w1(r3));
5325 assign(result, binop(Iop_Or32, mkexpr(op2), mkexpr(op3)));
5326 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5327 store(mkexpr(op2addr), mkexpr(result));
5328 put_gpr_w1(r1, mkexpr(op2));
5329
5330 return "lao";
5331}
5332
5333static HChar *
5334s390_irgen_LAOG(UChar r1, UChar r3, IRTemp op2addr)
5335{
5336 IRTemp op2 = newTemp(Ity_I64);
5337 IRTemp op3 = newTemp(Ity_I64);
5338 IRTemp result = newTemp(Ity_I64);
5339
5340 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5341 assign(op3, get_gpr_dw0(r3));
5342 assign(result, binop(Iop_Or64, mkexpr(op2), mkexpr(op3)));
5343 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5344 store(mkexpr(op2addr), mkexpr(result));
5345 put_gpr_dw0(r1, mkexpr(op2));
5346
5347 return "laog";
5348}
5349
5350static HChar *
5351s390_irgen_LTR(UChar r1, UChar r2)
5352{
5353 IRTemp op2 = newTemp(Ity_I32);
5354
5355 assign(op2, get_gpr_w1(r2));
5356 put_gpr_w1(r1, mkexpr(op2));
5357 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5358
5359 return "ltr";
5360}
5361
5362static HChar *
5363s390_irgen_LTGR(UChar r1, UChar r2)
5364{
5365 IRTemp op2 = newTemp(Ity_I64);
5366
5367 assign(op2, get_gpr_dw0(r2));
5368 put_gpr_dw0(r1, mkexpr(op2));
5369 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5370
5371 return "ltgr";
5372}
5373
5374static HChar *
5375s390_irgen_LTGFR(UChar r1, UChar r2)
5376{
5377 IRTemp op2 = newTemp(Ity_I64);
5378
5379 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
5380 put_gpr_dw0(r1, mkexpr(op2));
5381 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5382
5383 return "ltgfr";
5384}
5385
5386static HChar *
5387s390_irgen_LT(UChar r1, IRTemp op2addr)
5388{
5389 IRTemp op2 = newTemp(Ity_I32);
5390
5391 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5392 put_gpr_w1(r1, mkexpr(op2));
5393 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5394
5395 return "lt";
5396}
5397
5398static HChar *
5399s390_irgen_LTG(UChar r1, IRTemp op2addr)
5400{
5401 IRTemp op2 = newTemp(Ity_I64);
5402
5403 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5404 put_gpr_dw0(r1, mkexpr(op2));
5405 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5406
5407 return "ltg";
5408}
5409
5410static HChar *
5411s390_irgen_LTGF(UChar r1, IRTemp op2addr)
5412{
5413 IRTemp op2 = newTemp(Ity_I64);
5414
5415 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
5416 put_gpr_dw0(r1, mkexpr(op2));
5417 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5418
5419 return "ltgf";
5420}
5421
5422static HChar *
5423s390_irgen_LBR(UChar r1, UChar r2)
5424{
5425 put_gpr_w1(r1, unop(Iop_8Sto32, get_gpr_b7(r2)));
5426
5427 return "lbr";
5428}
5429
5430static HChar *
5431s390_irgen_LGBR(UChar r1, UChar r2)
5432{
5433 put_gpr_dw0(r1, unop(Iop_8Sto64, get_gpr_b7(r2)));
5434
5435 return "lgbr";
5436}
5437
5438static HChar *
5439s390_irgen_LB(UChar r1, IRTemp op2addr)
5440{
5441 put_gpr_w1(r1, unop(Iop_8Sto32, load(Ity_I8, mkexpr(op2addr))));
5442
5443 return "lb";
5444}
5445
5446static HChar *
5447s390_irgen_LGB(UChar r1, IRTemp op2addr)
5448{
5449 put_gpr_dw0(r1, unop(Iop_8Sto64, load(Ity_I8, mkexpr(op2addr))));
5450
5451 return "lgb";
5452}
5453
5454static HChar *
5455s390_irgen_LBH(UChar r1, IRTemp op2addr)
5456{
5457 put_gpr_w0(r1, unop(Iop_8Sto32, load(Ity_I8, mkexpr(op2addr))));
5458
5459 return "lbh";
5460}
5461
5462static HChar *
5463s390_irgen_LCR(UChar r1, UChar r2)
5464{
5465 Int op1;
5466 IRTemp op2 = newTemp(Ity_I32);
5467 IRTemp result = newTemp(Ity_I32);
5468
5469 op1 = 0;
5470 assign(op2, get_gpr_w1(r2));
5471 assign(result, binop(Iop_Sub32, mkU32((UInt)op1), mkexpr(op2)));
5472 put_gpr_w1(r1, mkexpr(result));
5473 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, mktemp(Ity_I32, mkU32((UInt)
5474 op1)), op2);
5475
5476 return "lcr";
5477}
5478
5479static HChar *
5480s390_irgen_LCGR(UChar r1, UChar r2)
5481{
5482 Long op1;
5483 IRTemp op2 = newTemp(Ity_I64);
5484 IRTemp result = newTemp(Ity_I64);
5485
5486 op1 = 0ULL;
5487 assign(op2, get_gpr_dw0(r2));
5488 assign(result, binop(Iop_Sub64, mkU64((ULong)op1), mkexpr(op2)));
5489 put_gpr_dw0(r1, mkexpr(result));
5490 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, mktemp(Ity_I64, mkU64((ULong)
5491 op1)), op2);
5492
5493 return "lcgr";
5494}
5495
5496static HChar *
5497s390_irgen_LCGFR(UChar r1, UChar r2)
5498{
5499 Long op1;
5500 IRTemp op2 = newTemp(Ity_I64);
5501 IRTemp result = newTemp(Ity_I64);
5502
5503 op1 = 0ULL;
5504 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
5505 assign(result, binop(Iop_Sub64, mkU64((ULong)op1), mkexpr(op2)));
5506 put_gpr_dw0(r1, mkexpr(result));
5507 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, mktemp(Ity_I64, mkU64((ULong)
5508 op1)), op2);
5509
5510 return "lcgfr";
5511}
5512
5513static HChar *
5514s390_irgen_LHR(UChar r1, UChar r2)
5515{
5516 put_gpr_w1(r1, unop(Iop_16Sto32, get_gpr_hw3(r2)));
5517
5518 return "lhr";
5519}
5520
5521static HChar *
5522s390_irgen_LGHR(UChar r1, UChar r2)
5523{
5524 put_gpr_dw0(r1, unop(Iop_16Sto64, get_gpr_hw3(r2)));
5525
5526 return "lghr";
5527}
5528
5529static HChar *
5530s390_irgen_LH(UChar r1, IRTemp op2addr)
5531{
5532 put_gpr_w1(r1, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
5533
5534 return "lh";
5535}
5536
5537static HChar *
5538s390_irgen_LHY(UChar r1, IRTemp op2addr)
5539{
5540 put_gpr_w1(r1, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
5541
5542 return "lhy";
5543}
5544
5545static HChar *
5546s390_irgen_LGH(UChar r1, IRTemp op2addr)
5547{
5548 put_gpr_dw0(r1, unop(Iop_16Sto64, load(Ity_I16, mkexpr(op2addr))));
5549
5550 return "lgh";
5551}
5552
5553static HChar *
5554s390_irgen_LHI(UChar r1, UShort i2)
5555{
5556 put_gpr_w1(r1, mkU32((UInt)(Int)(Short)i2));
5557
5558 return "lhi";
5559}
5560
5561static HChar *
5562s390_irgen_LGHI(UChar r1, UShort i2)
5563{
5564 put_gpr_dw0(r1, mkU64((ULong)(Long)(Short)i2));
5565
5566 return "lghi";
5567}
5568
5569static HChar *
5570s390_irgen_LHRL(UChar r1, UInt i2)
5571{
5572 put_gpr_w1(r1, unop(Iop_16Sto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
5573 ((ULong)(Long)(Int)i2 << 1)))));
5574
5575 return "lhrl";
5576}
5577
5578static HChar *
5579s390_irgen_LGHRL(UChar r1, UInt i2)
5580{
5581 put_gpr_dw0(r1, unop(Iop_16Sto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
5582 ((ULong)(Long)(Int)i2 << 1)))));
5583
5584 return "lghrl";
5585}
5586
5587static HChar *
5588s390_irgen_LHH(UChar r1, IRTemp op2addr)
5589{
5590 put_gpr_w0(r1, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
5591
5592 return "lhh";
5593}
5594
5595static HChar *
5596s390_irgen_LFH(UChar r1, IRTemp op2addr)
5597{
5598 put_gpr_w0(r1, load(Ity_I32, mkexpr(op2addr)));
5599
5600 return "lfh";
5601}
5602
5603static HChar *
5604s390_irgen_LLGFR(UChar r1, UChar r2)
5605{
5606 put_gpr_dw0(r1, unop(Iop_32Uto64, get_gpr_w1(r2)));
5607
5608 return "llgfr";
5609}
5610
5611static HChar *
5612s390_irgen_LLGF(UChar r1, IRTemp op2addr)
5613{
5614 put_gpr_dw0(r1, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
5615
5616 return "llgf";
5617}
5618
5619static HChar *
5620s390_irgen_LLGFRL(UChar r1, UInt i2)
5621{
5622 put_gpr_dw0(r1, unop(Iop_32Uto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
5623 ((ULong)(Long)(Int)i2 << 1)))));
5624
5625 return "llgfrl";
5626}
5627
5628static HChar *
5629s390_irgen_LLCR(UChar r1, UChar r2)
5630{
5631 put_gpr_w1(r1, unop(Iop_8Uto32, get_gpr_b7(r2)));
5632
5633 return "llcr";
5634}
5635
5636static HChar *
5637s390_irgen_LLGCR(UChar r1, UChar r2)
5638{
5639 put_gpr_dw0(r1, unop(Iop_8Uto64, get_gpr_b7(r2)));
5640
5641 return "llgcr";
5642}
5643
5644static HChar *
5645s390_irgen_LLC(UChar r1, IRTemp op2addr)
5646{
5647 put_gpr_w1(r1, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
5648
5649 return "llc";
5650}
5651
5652static HChar *
5653s390_irgen_LLGC(UChar r1, IRTemp op2addr)
5654{
5655 put_gpr_dw0(r1, unop(Iop_8Uto64, load(Ity_I8, mkexpr(op2addr))));
5656
5657 return "llgc";
5658}
5659
5660static HChar *
5661s390_irgen_LLCH(UChar r1, IRTemp op2addr)
5662{
5663 put_gpr_w0(r1, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
5664
5665 return "llch";
5666}
5667
5668static HChar *
5669s390_irgen_LLHR(UChar r1, UChar r2)
5670{
5671 put_gpr_w1(r1, unop(Iop_16Uto32, get_gpr_hw3(r2)));
5672
5673 return "llhr";
5674}
5675
5676static HChar *
5677s390_irgen_LLGHR(UChar r1, UChar r2)
5678{
5679 put_gpr_dw0(r1, unop(Iop_16Uto64, get_gpr_hw3(r2)));
5680
5681 return "llghr";
5682}
5683
5684static HChar *
5685s390_irgen_LLH(UChar r1, IRTemp op2addr)
5686{
5687 put_gpr_w1(r1, unop(Iop_16Uto32, load(Ity_I16, mkexpr(op2addr))));
5688
5689 return "llh";
5690}
5691
5692static HChar *
5693s390_irgen_LLGH(UChar r1, IRTemp op2addr)
5694{
5695 put_gpr_dw0(r1, unop(Iop_16Uto64, load(Ity_I16, mkexpr(op2addr))));
5696
5697 return "llgh";
5698}
5699
5700static HChar *
5701s390_irgen_LLHRL(UChar r1, UInt i2)
5702{
5703 put_gpr_w1(r1, unop(Iop_16Uto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
5704 ((ULong)(Long)(Int)i2 << 1)))));
5705
5706 return "llhrl";
5707}
5708
5709static HChar *
5710s390_irgen_LLGHRL(UChar r1, UInt i2)
5711{
5712 put_gpr_dw0(r1, unop(Iop_16Uto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
5713 ((ULong)(Long)(Int)i2 << 1)))));
5714
5715 return "llghrl";
5716}
5717
5718static HChar *
5719s390_irgen_LLHH(UChar r1, IRTemp op2addr)
5720{
5721 put_gpr_w0(r1, unop(Iop_16Uto32, load(Ity_I16, mkexpr(op2addr))));
5722
5723 return "llhh";
5724}
5725
5726static HChar *
5727s390_irgen_LLIHF(UChar r1, UInt i2)
5728{
5729 put_gpr_dw0(r1, mkU64(((ULong)i2) << 32));
5730
5731 return "llihf";
5732}
5733
5734static HChar *
5735s390_irgen_LLIHH(UChar r1, UShort i2)
5736{
5737 put_gpr_dw0(r1, mkU64(((ULong)i2) << 48));
5738
5739 return "llihh";
5740}
5741
5742static HChar *
5743s390_irgen_LLIHL(UChar r1, UShort i2)
5744{
5745 put_gpr_dw0(r1, mkU64(((ULong)i2) << 32));
5746
5747 return "llihl";
5748}
5749
5750static HChar *
5751s390_irgen_LLILF(UChar r1, UInt i2)
5752{
5753 put_gpr_dw0(r1, mkU64(i2));
5754
5755 return "llilf";
5756}
5757
5758static HChar *
5759s390_irgen_LLILH(UChar r1, UShort i2)
5760{
5761 put_gpr_dw0(r1, mkU64(((ULong)i2) << 16));
5762
5763 return "llilh";
5764}
5765
5766static HChar *
5767s390_irgen_LLILL(UChar r1, UShort i2)
5768{
5769 put_gpr_dw0(r1, mkU64(i2));
5770
5771 return "llill";
5772}
5773
5774static HChar *
5775s390_irgen_LLGTR(UChar r1, UChar r2)
5776{
5777 put_gpr_dw0(r1, unop(Iop_32Uto64, binop(Iop_And32, get_gpr_w1(r2),
5778 mkU32(2147483647))));
5779
5780 return "llgtr";
5781}
5782
5783static HChar *
5784s390_irgen_LLGT(UChar r1, IRTemp op2addr)
5785{
5786 put_gpr_dw0(r1, unop(Iop_32Uto64, binop(Iop_And32, load(Ity_I32,
5787 mkexpr(op2addr)), mkU32(2147483647))));
5788
5789 return "llgt";
5790}
5791
5792static HChar *
5793s390_irgen_LNR(UChar r1, UChar r2)
5794{
5795 IRTemp op2 = newTemp(Ity_I32);
5796 IRTemp result = newTemp(Ity_I32);
5797
5798 assign(op2, get_gpr_w1(r2));
5799 assign(result, mkite(binop(Iop_CmpLE32S, mkexpr(op2), mkU32(0)), mkexpr(op2),
5800 binop(Iop_Sub32, mkU32(0), mkexpr(op2))));
5801 put_gpr_w1(r1, mkexpr(result));
5802 s390_cc_thunk_putS(S390_CC_OP_BITWISE, result);
5803
5804 return "lnr";
5805}
5806
5807static HChar *
5808s390_irgen_LNGR(UChar r1, UChar r2)
5809{
5810 IRTemp op2 = newTemp(Ity_I64);
5811 IRTemp result = newTemp(Ity_I64);
5812
5813 assign(op2, get_gpr_dw0(r2));
5814 assign(result, mkite(binop(Iop_CmpLE64S, mkexpr(op2), mkU64(0)), mkexpr(op2),
5815 binop(Iop_Sub64, mkU64(0), mkexpr(op2))));
5816 put_gpr_dw0(r1, mkexpr(result));
5817 s390_cc_thunk_putS(S390_CC_OP_BITWISE, result);
5818
5819 return "lngr";
5820}
5821
5822static HChar *
5823s390_irgen_LNGFR(UChar r1, UChar r2 __attribute__((unused)))
5824{
5825 IRTemp op2 = newTemp(Ity_I64);
5826 IRTemp result = newTemp(Ity_I64);
5827
5828 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r1)));
5829 assign(result, mkite(binop(Iop_CmpLE64S, mkexpr(op2), mkU64(0)), mkexpr(op2),
5830 binop(Iop_Sub64, mkU64(0), mkexpr(op2))));
5831 put_gpr_dw0(r1, mkexpr(result));
5832 s390_cc_thunk_putS(S390_CC_OP_BITWISE, result);
5833
5834 return "lngfr";
5835}
5836
5837static HChar *
sewardjd7bde722011-04-05 13:19:33 +00005838s390_irgen_LOCR(UChar m3, UChar r1, UChar r2)
5839{
5840 if_condition_goto(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0)),
5841 guest_IA_next_instr);
5842 put_gpr_w1(r1, get_gpr_w1(r2));
florianf9e1ed72012-04-17 02:41:56 +00005843 dummy_put_IA();
sewardjd7bde722011-04-05 13:19:33 +00005844
5845 return "locr";
5846}
5847
5848static HChar *
5849s390_irgen_LOCGR(UChar m3, UChar r1, UChar r2)
5850{
5851 if_condition_goto(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0)),
5852 guest_IA_next_instr);
5853 put_gpr_dw0(r1, get_gpr_dw0(r2));
florianf9e1ed72012-04-17 02:41:56 +00005854 dummy_put_IA();
sewardjd7bde722011-04-05 13:19:33 +00005855
5856 return "locgr";
5857}
5858
5859static HChar *
5860s390_irgen_LOC(UChar r1, IRTemp op2addr)
5861{
5862 /* condition is checked in format handler */
5863 put_gpr_w1(r1, load(Ity_I32, mkexpr(op2addr)));
5864
5865 return "loc";
5866}
5867
5868static HChar *
5869s390_irgen_LOCG(UChar r1, IRTemp op2addr)
5870{
5871 /* condition is checked in format handler */
5872 put_gpr_dw0(r1, load(Ity_I64, mkexpr(op2addr)));
5873
5874 return "locg";
5875}
5876
5877static HChar *
sewardj2019a972011-03-07 16:04:07 +00005878s390_irgen_LPQ(UChar r1, IRTemp op2addr)
5879{
5880 put_gpr_dw0(r1, load(Ity_I64, mkexpr(op2addr)));
5881 put_gpr_dw0(r1 + 1, load(Ity_I64, binop(Iop_Add64, mkexpr(op2addr), mkU64(8))
5882 ));
5883
5884 return "lpq";
5885}
5886
5887static HChar *
5888s390_irgen_LPR(UChar r1, UChar r2)
5889{
5890 IRTemp op2 = newTemp(Ity_I32);
5891 IRTemp result = newTemp(Ity_I32);
5892
5893 assign(op2, get_gpr_w1(r2));
5894 assign(result, mkite(binop(Iop_CmpLT32S, mkexpr(op2), mkU32(0)),
5895 binop(Iop_Sub32, mkU32(0), mkexpr(op2)), mkexpr(op2)));
5896 put_gpr_w1(r1, mkexpr(result));
5897 s390_cc_thunk_putS(S390_CC_OP_LOAD_POSITIVE_32, op2);
5898
5899 return "lpr";
5900}
5901
5902static HChar *
5903s390_irgen_LPGR(UChar r1, UChar r2)
5904{
5905 IRTemp op2 = newTemp(Ity_I64);
5906 IRTemp result = newTemp(Ity_I64);
5907
5908 assign(op2, get_gpr_dw0(r2));
5909 assign(result, mkite(binop(Iop_CmpLT64S, mkexpr(op2), mkU64(0)),
5910 binop(Iop_Sub64, mkU64(0), mkexpr(op2)), mkexpr(op2)));
5911 put_gpr_dw0(r1, mkexpr(result));
5912 s390_cc_thunk_putS(S390_CC_OP_LOAD_POSITIVE_64, op2);
5913
5914 return "lpgr";
5915}
5916
5917static HChar *
5918s390_irgen_LPGFR(UChar r1, UChar r2)
5919{
5920 IRTemp op2 = newTemp(Ity_I64);
5921 IRTemp result = newTemp(Ity_I64);
5922
5923 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
5924 assign(result, mkite(binop(Iop_CmpLT64S, mkexpr(op2), mkU64(0)),
5925 binop(Iop_Sub64, mkU64(0), mkexpr(op2)), mkexpr(op2)));
5926 put_gpr_dw0(r1, mkexpr(result));
5927 s390_cc_thunk_putS(S390_CC_OP_LOAD_POSITIVE_64, op2);
5928
5929 return "lpgfr";
5930}
5931
5932static HChar *
5933s390_irgen_LRVR(UChar r1, UChar r2)
5934{
5935 IRTemp b0 = newTemp(Ity_I8);
5936 IRTemp b1 = newTemp(Ity_I8);
5937 IRTemp b2 = newTemp(Ity_I8);
5938 IRTemp b3 = newTemp(Ity_I8);
5939
5940 assign(b3, get_gpr_b7(r2));
5941 assign(b2, get_gpr_b6(r2));
5942 assign(b1, get_gpr_b5(r2));
5943 assign(b0, get_gpr_b4(r2));
5944 put_gpr_b4(r1, mkexpr(b3));
5945 put_gpr_b5(r1, mkexpr(b2));
5946 put_gpr_b6(r1, mkexpr(b1));
5947 put_gpr_b7(r1, mkexpr(b0));
5948
5949 return "lrvr";
5950}
5951
5952static HChar *
5953s390_irgen_LRVGR(UChar r1, UChar r2)
5954{
5955 IRTemp b0 = newTemp(Ity_I8);
5956 IRTemp b1 = newTemp(Ity_I8);
5957 IRTemp b2 = newTemp(Ity_I8);
5958 IRTemp b3 = newTemp(Ity_I8);
5959 IRTemp b4 = newTemp(Ity_I8);
5960 IRTemp b5 = newTemp(Ity_I8);
5961 IRTemp b6 = newTemp(Ity_I8);
5962 IRTemp b7 = newTemp(Ity_I8);
5963
5964 assign(b7, get_gpr_b7(r2));
5965 assign(b6, get_gpr_b6(r2));
5966 assign(b5, get_gpr_b5(r2));
5967 assign(b4, get_gpr_b4(r2));
5968 assign(b3, get_gpr_b3(r2));
5969 assign(b2, get_gpr_b2(r2));
5970 assign(b1, get_gpr_b1(r2));
5971 assign(b0, get_gpr_b0(r2));
5972 put_gpr_b0(r1, mkexpr(b7));
5973 put_gpr_b1(r1, mkexpr(b6));
5974 put_gpr_b2(r1, mkexpr(b5));
5975 put_gpr_b3(r1, mkexpr(b4));
5976 put_gpr_b4(r1, mkexpr(b3));
5977 put_gpr_b5(r1, mkexpr(b2));
5978 put_gpr_b6(r1, mkexpr(b1));
5979 put_gpr_b7(r1, mkexpr(b0));
5980
5981 return "lrvgr";
5982}
5983
5984static HChar *
5985s390_irgen_LRVH(UChar r1, IRTemp op2addr)
5986{
5987 IRTemp op2 = newTemp(Ity_I16);
5988
5989 assign(op2, load(Ity_I16, mkexpr(op2addr)));
5990 put_gpr_b6(r1, unop(Iop_16to8, mkexpr(op2)));
5991 put_gpr_b7(r1, unop(Iop_16HIto8, mkexpr(op2)));
5992
5993 return "lrvh";
5994}
5995
5996static HChar *
5997s390_irgen_LRV(UChar r1, IRTemp op2addr)
5998{
5999 IRTemp op2 = newTemp(Ity_I32);
6000
6001 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6002 put_gpr_b4(r1, unop(Iop_32to8, binop(Iop_And32, mkexpr(op2), mkU32(255))));
6003 put_gpr_b5(r1, unop(Iop_32to8, binop(Iop_And32, binop(Iop_Shr32, mkexpr(op2),
6004 mkU8(8)), mkU32(255))));
6005 put_gpr_b6(r1, unop(Iop_32to8, binop(Iop_And32, binop(Iop_Shr32, mkexpr(op2),
6006 mkU8(16)), mkU32(255))));
6007 put_gpr_b7(r1, unop(Iop_32to8, binop(Iop_And32, binop(Iop_Shr32, mkexpr(op2),
6008 mkU8(24)), mkU32(255))));
6009
6010 return "lrv";
6011}
6012
6013static HChar *
6014s390_irgen_LRVG(UChar r1, IRTemp op2addr)
6015{
6016 IRTemp op2 = newTemp(Ity_I64);
6017
6018 assign(op2, load(Ity_I64, mkexpr(op2addr)));
6019 put_gpr_b0(r1, unop(Iop_64to8, binop(Iop_And64, mkexpr(op2), mkU64(255))));
6020 put_gpr_b1(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6021 mkU8(8)), mkU64(255))));
6022 put_gpr_b2(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6023 mkU8(16)), mkU64(255))));
6024 put_gpr_b3(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6025 mkU8(24)), mkU64(255))));
6026 put_gpr_b4(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6027 mkU8(32)), mkU64(255))));
6028 put_gpr_b5(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6029 mkU8(40)), mkU64(255))));
6030 put_gpr_b6(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6031 mkU8(48)), mkU64(255))));
6032 put_gpr_b7(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6033 mkU8(56)), mkU64(255))));
6034
6035 return "lrvg";
6036}
6037
6038static HChar *
6039s390_irgen_MVHHI(UShort i2, IRTemp op1addr)
6040{
6041 store(mkexpr(op1addr), mkU16(i2));
6042
6043 return "mvhhi";
6044}
6045
6046static HChar *
6047s390_irgen_MVHI(UShort i2, IRTemp op1addr)
6048{
6049 store(mkexpr(op1addr), mkU32((UInt)(Int)(Short)i2));
6050
6051 return "mvhi";
6052}
6053
6054static HChar *
6055s390_irgen_MVGHI(UShort i2, IRTemp op1addr)
6056{
6057 store(mkexpr(op1addr), mkU64((ULong)(Long)(Short)i2));
6058
6059 return "mvghi";
6060}
6061
6062static HChar *
6063s390_irgen_MVI(UChar i2, IRTemp op1addr)
6064{
6065 store(mkexpr(op1addr), mkU8(i2));
6066
6067 return "mvi";
6068}
6069
6070static HChar *
6071s390_irgen_MVIY(UChar i2, IRTemp op1addr)
6072{
6073 store(mkexpr(op1addr), mkU8(i2));
6074
6075 return "mviy";
6076}
6077
6078static HChar *
6079s390_irgen_MR(UChar r1, UChar r2)
6080{
6081 IRTemp op1 = newTemp(Ity_I32);
6082 IRTemp op2 = newTemp(Ity_I32);
6083 IRTemp result = newTemp(Ity_I64);
6084
6085 assign(op1, get_gpr_w1(r1 + 1));
6086 assign(op2, get_gpr_w1(r2));
6087 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6088 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6089 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6090
6091 return "mr";
6092}
6093
6094static HChar *
6095s390_irgen_M(UChar r1, IRTemp op2addr)
6096{
6097 IRTemp op1 = newTemp(Ity_I32);
6098 IRTemp op2 = newTemp(Ity_I32);
6099 IRTemp result = newTemp(Ity_I64);
6100
6101 assign(op1, get_gpr_w1(r1 + 1));
6102 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6103 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6104 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6105 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6106
6107 return "m";
6108}
6109
6110static HChar *
6111s390_irgen_MFY(UChar r1, IRTemp op2addr)
6112{
6113 IRTemp op1 = newTemp(Ity_I32);
6114 IRTemp op2 = newTemp(Ity_I32);
6115 IRTemp result = newTemp(Ity_I64);
6116
6117 assign(op1, get_gpr_w1(r1 + 1));
6118 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6119 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6120 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6121 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6122
6123 return "mfy";
6124}
6125
6126static HChar *
6127s390_irgen_MH(UChar r1, IRTemp op2addr)
6128{
6129 IRTemp op1 = newTemp(Ity_I32);
6130 IRTemp op2 = newTemp(Ity_I16);
6131 IRTemp result = newTemp(Ity_I64);
6132
6133 assign(op1, get_gpr_w1(r1));
6134 assign(op2, load(Ity_I16, mkexpr(op2addr)));
6135 assign(result, binop(Iop_MullS32, mkexpr(op1), unop(Iop_16Sto32, mkexpr(op2))
6136 ));
6137 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6138
6139 return "mh";
6140}
6141
6142static HChar *
6143s390_irgen_MHY(UChar r1, IRTemp op2addr)
6144{
6145 IRTemp op1 = newTemp(Ity_I32);
6146 IRTemp op2 = newTemp(Ity_I16);
6147 IRTemp result = newTemp(Ity_I64);
6148
6149 assign(op1, get_gpr_w1(r1));
6150 assign(op2, load(Ity_I16, mkexpr(op2addr)));
6151 assign(result, binop(Iop_MullS32, mkexpr(op1), unop(Iop_16Sto32, mkexpr(op2))
6152 ));
6153 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6154
6155 return "mhy";
6156}
6157
6158static HChar *
6159s390_irgen_MHI(UChar r1, UShort i2)
6160{
6161 IRTemp op1 = newTemp(Ity_I32);
6162 Short op2;
6163 IRTemp result = newTemp(Ity_I64);
6164
6165 assign(op1, get_gpr_w1(r1));
6166 op2 = (Short)i2;
6167 assign(result, binop(Iop_MullS32, mkexpr(op1), unop(Iop_16Sto32,
6168 mkU16((UShort)op2))));
6169 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6170
6171 return "mhi";
6172}
6173
6174static HChar *
6175s390_irgen_MGHI(UChar r1, UShort i2)
6176{
6177 IRTemp op1 = newTemp(Ity_I64);
6178 Short op2;
6179 IRTemp result = newTemp(Ity_I128);
6180
6181 assign(op1, get_gpr_dw0(r1));
6182 op2 = (Short)i2;
6183 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_16Sto64,
6184 mkU16((UShort)op2))));
6185 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6186
6187 return "mghi";
6188}
6189
6190static HChar *
6191s390_irgen_MLR(UChar r1, UChar r2)
6192{
6193 IRTemp op1 = newTemp(Ity_I32);
6194 IRTemp op2 = newTemp(Ity_I32);
6195 IRTemp result = newTemp(Ity_I64);
6196
6197 assign(op1, get_gpr_w1(r1 + 1));
6198 assign(op2, get_gpr_w1(r2));
6199 assign(result, binop(Iop_MullU32, mkexpr(op1), mkexpr(op2)));
6200 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6201 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6202
6203 return "mlr";
6204}
6205
6206static HChar *
6207s390_irgen_MLGR(UChar r1, UChar r2)
6208{
6209 IRTemp op1 = newTemp(Ity_I64);
6210 IRTemp op2 = newTemp(Ity_I64);
6211 IRTemp result = newTemp(Ity_I128);
6212
6213 assign(op1, get_gpr_dw0(r1 + 1));
6214 assign(op2, get_gpr_dw0(r2));
6215 assign(result, binop(Iop_MullU64, mkexpr(op1), mkexpr(op2)));
6216 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result)));
6217 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result)));
6218
6219 return "mlgr";
6220}
6221
6222static HChar *
6223s390_irgen_ML(UChar r1, IRTemp op2addr)
6224{
6225 IRTemp op1 = newTemp(Ity_I32);
6226 IRTemp op2 = newTemp(Ity_I32);
6227 IRTemp result = newTemp(Ity_I64);
6228
6229 assign(op1, get_gpr_w1(r1 + 1));
6230 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6231 assign(result, binop(Iop_MullU32, mkexpr(op1), mkexpr(op2)));
6232 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6233 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6234
6235 return "ml";
6236}
6237
6238static HChar *
6239s390_irgen_MLG(UChar r1, IRTemp op2addr)
6240{
6241 IRTemp op1 = newTemp(Ity_I64);
6242 IRTemp op2 = newTemp(Ity_I64);
6243 IRTemp result = newTemp(Ity_I128);
6244
6245 assign(op1, get_gpr_dw0(r1 + 1));
6246 assign(op2, load(Ity_I64, mkexpr(op2addr)));
6247 assign(result, binop(Iop_MullU64, mkexpr(op1), mkexpr(op2)));
6248 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result)));
6249 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result)));
6250
6251 return "mlg";
6252}
6253
6254static HChar *
6255s390_irgen_MSR(UChar r1, UChar r2)
6256{
6257 IRTemp op1 = newTemp(Ity_I32);
6258 IRTemp op2 = newTemp(Ity_I32);
6259 IRTemp result = newTemp(Ity_I64);
6260
6261 assign(op1, get_gpr_w1(r1));
6262 assign(op2, get_gpr_w1(r2));
6263 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6264 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6265
6266 return "msr";
6267}
6268
6269static HChar *
6270s390_irgen_MSGR(UChar r1, UChar r2)
6271{
6272 IRTemp op1 = newTemp(Ity_I64);
6273 IRTemp op2 = newTemp(Ity_I64);
6274 IRTemp result = newTemp(Ity_I128);
6275
6276 assign(op1, get_gpr_dw0(r1));
6277 assign(op2, get_gpr_dw0(r2));
6278 assign(result, binop(Iop_MullS64, mkexpr(op1), mkexpr(op2)));
6279 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6280
6281 return "msgr";
6282}
6283
6284static HChar *
6285s390_irgen_MSGFR(UChar r1, UChar r2)
6286{
6287 IRTemp op1 = newTemp(Ity_I64);
6288 IRTemp op2 = newTemp(Ity_I32);
6289 IRTemp result = newTemp(Ity_I128);
6290
6291 assign(op1, get_gpr_dw0(r1));
6292 assign(op2, get_gpr_w1(r2));
6293 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_32Sto64, mkexpr(op2))
6294 ));
6295 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6296
6297 return "msgfr";
6298}
6299
6300static HChar *
6301s390_irgen_MS(UChar r1, IRTemp op2addr)
6302{
6303 IRTemp op1 = newTemp(Ity_I32);
6304 IRTemp op2 = newTemp(Ity_I32);
6305 IRTemp result = newTemp(Ity_I64);
6306
6307 assign(op1, get_gpr_w1(r1));
6308 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6309 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6310 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6311
6312 return "ms";
6313}
6314
6315static HChar *
6316s390_irgen_MSY(UChar r1, IRTemp op2addr)
6317{
6318 IRTemp op1 = newTemp(Ity_I32);
6319 IRTemp op2 = newTemp(Ity_I32);
6320 IRTemp result = newTemp(Ity_I64);
6321
6322 assign(op1, get_gpr_w1(r1));
6323 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6324 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6325 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6326
6327 return "msy";
6328}
6329
6330static HChar *
6331s390_irgen_MSG(UChar r1, IRTemp op2addr)
6332{
6333 IRTemp op1 = newTemp(Ity_I64);
6334 IRTemp op2 = newTemp(Ity_I64);
6335 IRTemp result = newTemp(Ity_I128);
6336
6337 assign(op1, get_gpr_dw0(r1));
6338 assign(op2, load(Ity_I64, mkexpr(op2addr)));
6339 assign(result, binop(Iop_MullS64, mkexpr(op1), mkexpr(op2)));
6340 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6341
6342 return "msg";
6343}
6344
6345static HChar *
6346s390_irgen_MSGF(UChar r1, IRTemp op2addr)
6347{
6348 IRTemp op1 = newTemp(Ity_I64);
6349 IRTemp op2 = newTemp(Ity_I32);
6350 IRTemp result = newTemp(Ity_I128);
6351
6352 assign(op1, get_gpr_dw0(r1));
6353 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6354 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_32Sto64, mkexpr(op2))
6355 ));
6356 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6357
6358 return "msgf";
6359}
6360
6361static HChar *
6362s390_irgen_MSFI(UChar r1, UInt i2)
6363{
6364 IRTemp op1 = newTemp(Ity_I32);
6365 Int op2;
6366 IRTemp result = newTemp(Ity_I64);
6367
6368 assign(op1, get_gpr_w1(r1));
6369 op2 = (Int)i2;
6370 assign(result, binop(Iop_MullS32, mkexpr(op1), mkU32((UInt)op2)));
6371 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6372
6373 return "msfi";
6374}
6375
6376static HChar *
6377s390_irgen_MSGFI(UChar r1, UInt i2)
6378{
6379 IRTemp op1 = newTemp(Ity_I64);
6380 Int op2;
6381 IRTemp result = newTemp(Ity_I128);
6382
6383 assign(op1, get_gpr_dw0(r1));
6384 op2 = (Int)i2;
6385 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_32Sto64, mkU32((UInt)
6386 op2))));
6387 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6388
6389 return "msgfi";
6390}
6391
6392static HChar *
6393s390_irgen_OR(UChar r1, UChar r2)
6394{
6395 IRTemp op1 = newTemp(Ity_I32);
6396 IRTemp op2 = newTemp(Ity_I32);
6397 IRTemp result = newTemp(Ity_I32);
6398
6399 assign(op1, get_gpr_w1(r1));
6400 assign(op2, get_gpr_w1(r2));
6401 assign(result, binop(Iop_Or32, mkexpr(op1), mkexpr(op2)));
6402 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6403 put_gpr_w1(r1, mkexpr(result));
6404
6405 return "or";
6406}
6407
6408static HChar *
6409s390_irgen_OGR(UChar r1, UChar r2)
6410{
6411 IRTemp op1 = newTemp(Ity_I64);
6412 IRTemp op2 = newTemp(Ity_I64);
6413 IRTemp result = newTemp(Ity_I64);
6414
6415 assign(op1, get_gpr_dw0(r1));
6416 assign(op2, get_gpr_dw0(r2));
6417 assign(result, binop(Iop_Or64, mkexpr(op1), mkexpr(op2)));
6418 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6419 put_gpr_dw0(r1, mkexpr(result));
6420
6421 return "ogr";
6422}
6423
6424static HChar *
6425s390_irgen_ORK(UChar r3, UChar r1, UChar r2)
6426{
6427 IRTemp op2 = newTemp(Ity_I32);
6428 IRTemp op3 = newTemp(Ity_I32);
6429 IRTemp result = newTemp(Ity_I32);
6430
6431 assign(op2, get_gpr_w1(r2));
6432 assign(op3, get_gpr_w1(r3));
6433 assign(result, binop(Iop_Or32, mkexpr(op2), mkexpr(op3)));
6434 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6435 put_gpr_w1(r1, mkexpr(result));
6436
6437 return "ork";
6438}
6439
6440static HChar *
6441s390_irgen_OGRK(UChar r3, UChar r1, UChar r2)
6442{
6443 IRTemp op2 = newTemp(Ity_I64);
6444 IRTemp op3 = newTemp(Ity_I64);
6445 IRTemp result = newTemp(Ity_I64);
6446
6447 assign(op2, get_gpr_dw0(r2));
6448 assign(op3, get_gpr_dw0(r3));
6449 assign(result, binop(Iop_Or64, mkexpr(op2), mkexpr(op3)));
6450 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6451 put_gpr_dw0(r1, mkexpr(result));
6452
6453 return "ogrk";
6454}
6455
6456static HChar *
6457s390_irgen_O(UChar r1, IRTemp op2addr)
6458{
6459 IRTemp op1 = newTemp(Ity_I32);
6460 IRTemp op2 = newTemp(Ity_I32);
6461 IRTemp result = newTemp(Ity_I32);
6462
6463 assign(op1, get_gpr_w1(r1));
6464 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6465 assign(result, binop(Iop_Or32, mkexpr(op1), mkexpr(op2)));
6466 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6467 put_gpr_w1(r1, mkexpr(result));
6468
6469 return "o";
6470}
6471
6472static HChar *
6473s390_irgen_OY(UChar r1, IRTemp op2addr)
6474{
6475 IRTemp op1 = newTemp(Ity_I32);
6476 IRTemp op2 = newTemp(Ity_I32);
6477 IRTemp result = newTemp(Ity_I32);
6478
6479 assign(op1, get_gpr_w1(r1));
6480 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6481 assign(result, binop(Iop_Or32, mkexpr(op1), mkexpr(op2)));
6482 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6483 put_gpr_w1(r1, mkexpr(result));
6484
6485 return "oy";
6486}
6487
6488static HChar *
6489s390_irgen_OG(UChar r1, IRTemp op2addr)
6490{
6491 IRTemp op1 = newTemp(Ity_I64);
6492 IRTemp op2 = newTemp(Ity_I64);
6493 IRTemp result = newTemp(Ity_I64);
6494
6495 assign(op1, get_gpr_dw0(r1));
6496 assign(op2, load(Ity_I64, mkexpr(op2addr)));
6497 assign(result, binop(Iop_Or64, mkexpr(op1), mkexpr(op2)));
6498 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6499 put_gpr_dw0(r1, mkexpr(result));
6500
6501 return "og";
6502}
6503
6504static HChar *
6505s390_irgen_OI(UChar i2, IRTemp op1addr)
6506{
6507 IRTemp op1 = newTemp(Ity_I8);
6508 UChar op2;
6509 IRTemp result = newTemp(Ity_I8);
6510
6511 assign(op1, load(Ity_I8, mkexpr(op1addr)));
6512 op2 = i2;
6513 assign(result, binop(Iop_Or8, mkexpr(op1), mkU8(op2)));
6514 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6515 store(mkexpr(op1addr), mkexpr(result));
6516
6517 return "oi";
6518}
6519
6520static HChar *
6521s390_irgen_OIY(UChar i2, IRTemp op1addr)
6522{
6523 IRTemp op1 = newTemp(Ity_I8);
6524 UChar op2;
6525 IRTemp result = newTemp(Ity_I8);
6526
6527 assign(op1, load(Ity_I8, mkexpr(op1addr)));
6528 op2 = i2;
6529 assign(result, binop(Iop_Or8, mkexpr(op1), mkU8(op2)));
6530 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6531 store(mkexpr(op1addr), mkexpr(result));
6532
6533 return "oiy";
6534}
6535
6536static HChar *
6537s390_irgen_OIHF(UChar r1, UInt i2)
6538{
6539 IRTemp op1 = newTemp(Ity_I32);
6540 UInt op2;
6541 IRTemp result = newTemp(Ity_I32);
6542
6543 assign(op1, get_gpr_w0(r1));
6544 op2 = i2;
6545 assign(result, binop(Iop_Or32, mkexpr(op1), mkU32(op2)));
6546 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6547 put_gpr_w0(r1, mkexpr(result));
6548
6549 return "oihf";
6550}
6551
6552static HChar *
6553s390_irgen_OIHH(UChar r1, UShort i2)
6554{
6555 IRTemp op1 = newTemp(Ity_I16);
6556 UShort op2;
6557 IRTemp result = newTemp(Ity_I16);
6558
6559 assign(op1, get_gpr_hw0(r1));
6560 op2 = i2;
6561 assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
6562 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6563 put_gpr_hw0(r1, mkexpr(result));
6564
6565 return "oihh";
6566}
6567
6568static HChar *
6569s390_irgen_OIHL(UChar r1, UShort i2)
6570{
6571 IRTemp op1 = newTemp(Ity_I16);
6572 UShort op2;
6573 IRTemp result = newTemp(Ity_I16);
6574
6575 assign(op1, get_gpr_hw1(r1));
6576 op2 = i2;
6577 assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
6578 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6579 put_gpr_hw1(r1, mkexpr(result));
6580
6581 return "oihl";
6582}
6583
6584static HChar *
6585s390_irgen_OILF(UChar r1, UInt i2)
6586{
6587 IRTemp op1 = newTemp(Ity_I32);
6588 UInt op2;
6589 IRTemp result = newTemp(Ity_I32);
6590
6591 assign(op1, get_gpr_w1(r1));
6592 op2 = i2;
6593 assign(result, binop(Iop_Or32, mkexpr(op1), mkU32(op2)));
6594 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6595 put_gpr_w1(r1, mkexpr(result));
6596
6597 return "oilf";
6598}
6599
6600static HChar *
6601s390_irgen_OILH(UChar r1, UShort i2)
6602{
6603 IRTemp op1 = newTemp(Ity_I16);
6604 UShort op2;
6605 IRTemp result = newTemp(Ity_I16);
6606
6607 assign(op1, get_gpr_hw2(r1));
6608 op2 = i2;
6609 assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
6610 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6611 put_gpr_hw2(r1, mkexpr(result));
6612
6613 return "oilh";
6614}
6615
6616static HChar *
6617s390_irgen_OILL(UChar r1, UShort i2)
6618{
6619 IRTemp op1 = newTemp(Ity_I16);
6620 UShort op2;
6621 IRTemp result = newTemp(Ity_I16);
6622
6623 assign(op1, get_gpr_hw3(r1));
6624 op2 = i2;
6625 assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
6626 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6627 put_gpr_hw3(r1, mkexpr(result));
6628
6629 return "oill";
6630}
6631
6632static HChar *
6633s390_irgen_PFD(void)
6634{
6635
6636 return "pfd";
6637}
6638
6639static HChar *
6640s390_irgen_PFDRL(void)
6641{
6642
6643 return "pfdrl";
6644}
6645
6646static HChar *
6647s390_irgen_RLL(UChar r1, UChar r3, IRTemp op2addr)
6648{
6649 IRTemp amount = newTemp(Ity_I64);
6650 IRTemp op = newTemp(Ity_I32);
6651
6652 assign(amount, binop(Iop_And64, mkexpr(op2addr), mkU64(31)));
6653 assign(op, get_gpr_w1(r3));
6654 put_gpr_w1(r1, binop(Iop_Or32, binop(Iop_Shl32, mkexpr(op), unop(Iop_64to8,
6655 mkexpr(amount))), binop(Iop_Shr32, mkexpr(op), unop(Iop_64to8,
6656 binop(Iop_Sub64, mkU64(32), mkexpr(amount))))));
6657
6658 return "rll";
6659}
6660
6661static HChar *
6662s390_irgen_RLLG(UChar r1, UChar r3, IRTemp op2addr)
6663{
6664 IRTemp amount = newTemp(Ity_I64);
6665 IRTemp op = newTemp(Ity_I64);
6666
6667 assign(amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
6668 assign(op, get_gpr_dw0(r3));
6669 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(op), unop(Iop_64to8,
6670 mkexpr(amount))), binop(Iop_Shr64, mkexpr(op), unop(Iop_64to8,
6671 binop(Iop_Sub64, mkU64(64), mkexpr(amount))))));
6672
6673 return "rllg";
6674}
6675
6676static HChar *
6677s390_irgen_RNSBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
6678{
6679 UChar from;
6680 UChar to;
6681 UChar rot;
6682 UChar t_bit;
6683 ULong mask;
6684 ULong maskc;
6685 IRTemp result = newTemp(Ity_I64);
6686 IRTemp op2 = newTemp(Ity_I64);
6687
6688 from = i3 & 63;
6689 to = i4 & 63;
6690 rot = i5 & 63;
6691 t_bit = i3 & 128;
6692 assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
6693 get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
6694 mkU8(64 - rot))));
6695 if (from <= to) {
6696 mask = ~0ULL;
6697 mask = (mask >> from) & (mask << (63 - to));
6698 maskc = ~mask;
6699 } else {
6700 maskc = ~0ULL;
6701 maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
6702 mask = ~maskc;
6703 }
6704 assign(result, binop(Iop_And64, binop(Iop_And64, get_gpr_dw0(r1), mkexpr(op2)
6705 ), mkU64(mask)));
6706 if (t_bit == 0) {
6707 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
6708 mkU64(maskc)), mkexpr(result)));
6709 }
6710 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6711
6712 return "rnsbg";
6713}
6714
6715static HChar *
6716s390_irgen_RXSBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
6717{
6718 UChar from;
6719 UChar to;
6720 UChar rot;
6721 UChar t_bit;
6722 ULong mask;
6723 ULong maskc;
6724 IRTemp result = newTemp(Ity_I64);
6725 IRTemp op2 = newTemp(Ity_I64);
6726
6727 from = i3 & 63;
6728 to = i4 & 63;
6729 rot = i5 & 63;
6730 t_bit = i3 & 128;
6731 assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
6732 get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
6733 mkU8(64 - rot))));
6734 if (from <= to) {
6735 mask = ~0ULL;
6736 mask = (mask >> from) & (mask << (63 - to));
6737 maskc = ~mask;
6738 } else {
6739 maskc = ~0ULL;
6740 maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
6741 mask = ~maskc;
6742 }
6743 assign(result, binop(Iop_And64, binop(Iop_Xor64, get_gpr_dw0(r1), mkexpr(op2)
6744 ), mkU64(mask)));
6745 if (t_bit == 0) {
6746 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
6747 mkU64(maskc)), mkexpr(result)));
6748 }
6749 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6750
6751 return "rxsbg";
6752}
6753
6754static HChar *
6755s390_irgen_ROSBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
6756{
6757 UChar from;
6758 UChar to;
6759 UChar rot;
6760 UChar t_bit;
6761 ULong mask;
6762 ULong maskc;
6763 IRTemp result = newTemp(Ity_I64);
6764 IRTemp op2 = newTemp(Ity_I64);
6765
6766 from = i3 & 63;
6767 to = i4 & 63;
6768 rot = i5 & 63;
6769 t_bit = i3 & 128;
6770 assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
6771 get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
6772 mkU8(64 - rot))));
6773 if (from <= to) {
6774 mask = ~0ULL;
6775 mask = (mask >> from) & (mask << (63 - to));
6776 maskc = ~mask;
6777 } else {
6778 maskc = ~0ULL;
6779 maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
6780 mask = ~maskc;
6781 }
6782 assign(result, binop(Iop_And64, binop(Iop_Or64, get_gpr_dw0(r1), mkexpr(op2)
6783 ), mkU64(mask)));
6784 if (t_bit == 0) {
6785 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
6786 mkU64(maskc)), mkexpr(result)));
6787 }
6788 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6789
6790 return "rosbg";
6791}
6792
6793static HChar *
6794s390_irgen_RISBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
6795{
6796 UChar from;
6797 UChar to;
6798 UChar rot;
6799 UChar z_bit;
6800 ULong mask;
6801 ULong maskc;
6802 IRTemp op2 = newTemp(Ity_I64);
6803 IRTemp result = newTemp(Ity_I64);
6804
6805 from = i3 & 63;
6806 to = i4 & 63;
6807 rot = i5 & 63;
6808 z_bit = i4 & 128;
6809 assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
6810 get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
6811 mkU8(64 - rot))));
6812 if (from <= to) {
6813 mask = ~0ULL;
6814 mask = (mask >> from) & (mask << (63 - to));
6815 maskc = ~mask;
6816 } else {
6817 maskc = ~0ULL;
6818 maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
6819 mask = ~maskc;
6820 }
6821 if (z_bit == 0) {
6822 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
6823 mkU64(maskc)), binop(Iop_And64, mkexpr(op2), mkU64(mask))));
6824 } else {
6825 put_gpr_dw0(r1, binop(Iop_And64, mkexpr(op2), mkU64(mask)));
6826 }
6827 assign(result, get_gpr_dw0(r1));
6828 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
6829
6830 return "risbg";
6831}
6832
6833static HChar *
6834s390_irgen_SAR(UChar r1, UChar r2)
6835{
6836 put_ar_w0(r1, get_gpr_w1(r2));
sewardj7ee97522011-05-09 21:45:04 +00006837 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00006838 s390_disasm(ENC3(MNM, AR, GPR), "sar", r1, r2);
6839
6840 return "sar";
6841}
6842
6843static HChar *
6844s390_irgen_SLDA(UChar r1, IRTemp op2addr)
6845{
6846 IRTemp p1 = newTemp(Ity_I64);
6847 IRTemp p2 = newTemp(Ity_I64);
6848 IRTemp op = newTemp(Ity_I64);
6849 IRTemp result = newTemp(Ity_I64);
florian417b22d2012-07-13 13:41:41 +00006850 ULong sign_mask;
sewardj2019a972011-03-07 16:04:07 +00006851 IRTemp shift_amount = newTemp(Ity_I64);
6852
6853 assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
6854 assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
6855 assign(op, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1), mkU8(32)), mkexpr(p2)
6856 ));
6857 sign_mask = 1ULL << 63;
6858 assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
6859 assign(result, binop(Iop_Or64, binop(Iop_And64, binop(Iop_Shl64, mkexpr(op),
florian417b22d2012-07-13 13:41:41 +00006860 unop(Iop_64to8, mkexpr(shift_amount))), mkU64(~sign_mask)),
6861 binop(Iop_And64, mkexpr(op), mkU64(sign_mask))));
sewardj2019a972011-03-07 16:04:07 +00006862 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6863 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6864 s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_64, op, shift_amount);
6865
6866 return "slda";
6867}
6868
6869static HChar *
6870s390_irgen_SLDL(UChar r1, IRTemp op2addr)
6871{
6872 IRTemp p1 = newTemp(Ity_I64);
6873 IRTemp p2 = newTemp(Ity_I64);
6874 IRTemp result = newTemp(Ity_I64);
6875
6876 assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
6877 assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
6878 assign(result, binop(Iop_Shl64, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1),
6879 mkU8(32)), mkexpr(p2)), unop(Iop_64to8, binop(Iop_And64,
6880 mkexpr(op2addr), mkU64(63)))));
6881 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6882 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6883
6884 return "sldl";
6885}
6886
6887static HChar *
6888s390_irgen_SLA(UChar r1, IRTemp op2addr)
6889{
6890 IRTemp uop = newTemp(Ity_I32);
6891 IRTemp result = newTemp(Ity_I32);
6892 UInt sign_mask;
6893 IRTemp shift_amount = newTemp(Ity_I64);
6894 IRTemp op = newTemp(Ity_I32);
6895
6896 assign(op, get_gpr_w1(r1));
6897 assign(uop, get_gpr_w1(r1));
6898 sign_mask = 2147483648U;
6899 assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
6900 assign(result, binop(Iop_Or32, binop(Iop_And32, binop(Iop_Shl32, mkexpr(uop),
6901 unop(Iop_64to8, mkexpr(shift_amount))), mkU32(~sign_mask)),
6902 binop(Iop_And32, mkexpr(uop), mkU32(sign_mask))));
6903 put_gpr_w1(r1, mkexpr(result));
6904 s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_32, op, shift_amount);
6905
6906 return "sla";
6907}
6908
6909static HChar *
6910s390_irgen_SLAK(UChar r1, UChar r3, IRTemp op2addr)
6911{
6912 IRTemp uop = newTemp(Ity_I32);
6913 IRTemp result = newTemp(Ity_I32);
6914 UInt sign_mask;
6915 IRTemp shift_amount = newTemp(Ity_I64);
6916 IRTemp op = newTemp(Ity_I32);
6917
6918 assign(op, get_gpr_w1(r3));
6919 assign(uop, get_gpr_w1(r3));
6920 sign_mask = 2147483648U;
6921 assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
6922 assign(result, binop(Iop_Or32, binop(Iop_And32, binop(Iop_Shl32, mkexpr(uop),
6923 unop(Iop_64to8, mkexpr(shift_amount))), mkU32(~sign_mask)),
6924 binop(Iop_And32, mkexpr(uop), mkU32(sign_mask))));
6925 put_gpr_w1(r1, mkexpr(result));
6926 s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_32, op, shift_amount);
6927
6928 return "slak";
6929}
6930
6931static HChar *
6932s390_irgen_SLAG(UChar r1, UChar r3, IRTemp op2addr)
6933{
6934 IRTemp uop = newTemp(Ity_I64);
6935 IRTemp result = newTemp(Ity_I64);
6936 ULong sign_mask;
6937 IRTemp shift_amount = newTemp(Ity_I64);
6938 IRTemp op = newTemp(Ity_I64);
6939
6940 assign(op, get_gpr_dw0(r3));
6941 assign(uop, get_gpr_dw0(r3));
6942 sign_mask = 9223372036854775808ULL;
6943 assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
6944 assign(result, binop(Iop_Or64, binop(Iop_And64, binop(Iop_Shl64, mkexpr(uop),
6945 unop(Iop_64to8, mkexpr(shift_amount))), mkU64(~sign_mask)),
6946 binop(Iop_And64, mkexpr(uop), mkU64(sign_mask))));
6947 put_gpr_dw0(r1, mkexpr(result));
6948 s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_64, op, shift_amount);
6949
6950 return "slag";
6951}
6952
6953static HChar *
6954s390_irgen_SLL(UChar r1, IRTemp op2addr)
6955{
6956 put_gpr_w1(r1, binop(Iop_Shl32, get_gpr_w1(r1), unop(Iop_64to8,
6957 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
6958
6959 return "sll";
6960}
6961
6962static HChar *
6963s390_irgen_SLLK(UChar r1, UChar r3, IRTemp op2addr)
6964{
6965 put_gpr_w1(r1, binop(Iop_Shl32, get_gpr_w1(r3), unop(Iop_64to8,
6966 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
6967
6968 return "sllk";
6969}
6970
6971static HChar *
6972s390_irgen_SLLG(UChar r1, UChar r3, IRTemp op2addr)
6973{
6974 put_gpr_dw0(r1, binop(Iop_Shl64, get_gpr_dw0(r3), unop(Iop_64to8,
6975 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
6976
6977 return "sllg";
6978}
6979
6980static HChar *
6981s390_irgen_SRDA(UChar r1, IRTemp op2addr)
6982{
6983 IRTemp p1 = newTemp(Ity_I64);
6984 IRTemp p2 = newTemp(Ity_I64);
6985 IRTemp result = newTemp(Ity_I64);
6986
6987 assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
6988 assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
6989 assign(result, binop(Iop_Sar64, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1),
6990 mkU8(32)), mkexpr(p2)), unop(Iop_64to8, binop(Iop_And64,
6991 mkexpr(op2addr), mkU64(63)))));
6992 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6993 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6994 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
6995
6996 return "srda";
6997}
6998
6999static HChar *
7000s390_irgen_SRDL(UChar r1, IRTemp op2addr)
7001{
7002 IRTemp p1 = newTemp(Ity_I64);
7003 IRTemp p2 = newTemp(Ity_I64);
7004 IRTemp result = newTemp(Ity_I64);
7005
7006 assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
7007 assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
7008 assign(result, binop(Iop_Shr64, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1),
7009 mkU8(32)), mkexpr(p2)), unop(Iop_64to8, binop(Iop_And64,
7010 mkexpr(op2addr), mkU64(63)))));
7011 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
7012 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
7013
7014 return "srdl";
7015}
7016
7017static HChar *
7018s390_irgen_SRA(UChar r1, IRTemp op2addr)
7019{
7020 IRTemp result = newTemp(Ity_I32);
7021 IRTemp op = newTemp(Ity_I32);
7022
7023 assign(op, get_gpr_w1(r1));
7024 assign(result, binop(Iop_Sar32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7025 mkexpr(op2addr), mkU64(63)))));
7026 put_gpr_w1(r1, mkexpr(result));
7027 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7028
7029 return "sra";
7030}
7031
7032static HChar *
7033s390_irgen_SRAK(UChar r1, UChar r3, IRTemp op2addr)
7034{
7035 IRTemp result = newTemp(Ity_I32);
7036 IRTemp op = newTemp(Ity_I32);
7037
7038 assign(op, get_gpr_w1(r3));
7039 assign(result, binop(Iop_Sar32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7040 mkexpr(op2addr), mkU64(63)))));
7041 put_gpr_w1(r1, mkexpr(result));
7042 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7043
7044 return "srak";
7045}
7046
7047static HChar *
7048s390_irgen_SRAG(UChar r1, UChar r3, IRTemp op2addr)
7049{
7050 IRTemp result = newTemp(Ity_I64);
7051 IRTemp op = newTemp(Ity_I64);
7052
7053 assign(op, get_gpr_dw0(r3));
7054 assign(result, binop(Iop_Sar64, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7055 mkexpr(op2addr), mkU64(63)))));
7056 put_gpr_dw0(r1, mkexpr(result));
7057 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7058
7059 return "srag";
7060}
7061
7062static HChar *
7063s390_irgen_SRL(UChar r1, IRTemp op2addr)
7064{
7065 IRTemp op = newTemp(Ity_I32);
7066
7067 assign(op, get_gpr_w1(r1));
7068 put_gpr_w1(r1, binop(Iop_Shr32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7069 mkexpr(op2addr), mkU64(63)))));
7070
7071 return "srl";
7072}
7073
7074static HChar *
7075s390_irgen_SRLK(UChar r1, UChar r3, IRTemp op2addr)
7076{
7077 IRTemp op = newTemp(Ity_I32);
7078
7079 assign(op, get_gpr_w1(r3));
7080 put_gpr_w1(r1, binop(Iop_Shr32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7081 mkexpr(op2addr), mkU64(63)))));
7082
7083 return "srlk";
7084}
7085
7086static HChar *
7087s390_irgen_SRLG(UChar r1, UChar r3, IRTemp op2addr)
7088{
7089 IRTemp op = newTemp(Ity_I64);
7090
7091 assign(op, get_gpr_dw0(r3));
7092 put_gpr_dw0(r1, binop(Iop_Shr64, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7093 mkexpr(op2addr), mkU64(63)))));
7094
7095 return "srlg";
7096}
7097
7098static HChar *
7099s390_irgen_ST(UChar r1, IRTemp op2addr)
7100{
7101 store(mkexpr(op2addr), get_gpr_w1(r1));
7102
7103 return "st";
7104}
7105
7106static HChar *
7107s390_irgen_STY(UChar r1, IRTemp op2addr)
7108{
7109 store(mkexpr(op2addr), get_gpr_w1(r1));
7110
7111 return "sty";
7112}
7113
7114static HChar *
7115s390_irgen_STG(UChar r1, IRTemp op2addr)
7116{
7117 store(mkexpr(op2addr), get_gpr_dw0(r1));
7118
7119 return "stg";
7120}
7121
7122static HChar *
7123s390_irgen_STRL(UChar r1, UInt i2)
7124{
7125 store(mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)),
7126 get_gpr_w1(r1));
7127
7128 return "strl";
7129}
7130
7131static HChar *
7132s390_irgen_STGRL(UChar r1, UInt i2)
7133{
7134 store(mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)),
7135 get_gpr_dw0(r1));
7136
7137 return "stgrl";
7138}
7139
7140static HChar *
7141s390_irgen_STC(UChar r1, IRTemp op2addr)
7142{
7143 store(mkexpr(op2addr), get_gpr_b7(r1));
7144
7145 return "stc";
7146}
7147
7148static HChar *
7149s390_irgen_STCY(UChar r1, IRTemp op2addr)
7150{
7151 store(mkexpr(op2addr), get_gpr_b7(r1));
7152
7153 return "stcy";
7154}
7155
7156static HChar *
7157s390_irgen_STCH(UChar r1, IRTemp op2addr)
7158{
7159 store(mkexpr(op2addr), get_gpr_b3(r1));
7160
7161 return "stch";
7162}
7163
7164static HChar *
7165s390_irgen_STCM(UChar r1, UChar r3, IRTemp op2addr)
7166{
7167 UChar mask;
7168 UChar n;
7169
7170 mask = (UChar)r3;
7171 n = 0;
7172 if ((mask & 8) != 0) {
7173 store(mkexpr(op2addr), get_gpr_b4(r1));
7174 n = n + 1;
7175 }
7176 if ((mask & 4) != 0) {
7177 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b5(r1));
7178 n = n + 1;
7179 }
7180 if ((mask & 2) != 0) {
7181 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b6(r1));
7182 n = n + 1;
7183 }
7184 if ((mask & 1) != 0) {
7185 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b7(r1));
7186 }
7187
7188 return "stcm";
7189}
7190
7191static HChar *
7192s390_irgen_STCMY(UChar r1, UChar r3, IRTemp op2addr)
7193{
7194 UChar mask;
7195 UChar n;
7196
7197 mask = (UChar)r3;
7198 n = 0;
7199 if ((mask & 8) != 0) {
7200 store(mkexpr(op2addr), get_gpr_b4(r1));
7201 n = n + 1;
7202 }
7203 if ((mask & 4) != 0) {
7204 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b5(r1));
7205 n = n + 1;
7206 }
7207 if ((mask & 2) != 0) {
7208 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b6(r1));
7209 n = n + 1;
7210 }
7211 if ((mask & 1) != 0) {
7212 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b7(r1));
7213 }
7214
7215 return "stcmy";
7216}
7217
7218static HChar *
7219s390_irgen_STCMH(UChar r1, UChar r3, IRTemp op2addr)
7220{
7221 UChar mask;
7222 UChar n;
7223
7224 mask = (UChar)r3;
7225 n = 0;
7226 if ((mask & 8) != 0) {
7227 store(mkexpr(op2addr), get_gpr_b0(r1));
7228 n = n + 1;
7229 }
7230 if ((mask & 4) != 0) {
7231 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b1(r1));
7232 n = n + 1;
7233 }
7234 if ((mask & 2) != 0) {
7235 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b2(r1));
7236 n = n + 1;
7237 }
7238 if ((mask & 1) != 0) {
7239 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b3(r1));
7240 }
7241
7242 return "stcmh";
7243}
7244
7245static HChar *
7246s390_irgen_STH(UChar r1, IRTemp op2addr)
7247{
7248 store(mkexpr(op2addr), get_gpr_hw3(r1));
7249
7250 return "sth";
7251}
7252
7253static HChar *
7254s390_irgen_STHY(UChar r1, IRTemp op2addr)
7255{
7256 store(mkexpr(op2addr), get_gpr_hw3(r1));
7257
7258 return "sthy";
7259}
7260
7261static HChar *
7262s390_irgen_STHRL(UChar r1, UInt i2)
7263{
7264 store(mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)),
7265 get_gpr_hw3(r1));
7266
7267 return "sthrl";
7268}
7269
7270static HChar *
7271s390_irgen_STHH(UChar r1, IRTemp op2addr)
7272{
7273 store(mkexpr(op2addr), get_gpr_hw1(r1));
7274
7275 return "sthh";
7276}
7277
7278static HChar *
7279s390_irgen_STFH(UChar r1, IRTemp op2addr)
7280{
7281 store(mkexpr(op2addr), get_gpr_w0(r1));
7282
7283 return "stfh";
7284}
7285
7286static HChar *
sewardjd7bde722011-04-05 13:19:33 +00007287s390_irgen_STOC(UChar r1, IRTemp op2addr)
7288{
7289 /* condition is checked in format handler */
7290 store(mkexpr(op2addr), get_gpr_w1(r1));
7291
7292 return "stoc";
7293}
7294
7295static HChar *
7296s390_irgen_STOCG(UChar r1, IRTemp op2addr)
7297{
7298 /* condition is checked in format handler */
7299 store(mkexpr(op2addr), get_gpr_dw0(r1));
7300
7301 return "stocg";
7302}
7303
7304static HChar *
sewardj2019a972011-03-07 16:04:07 +00007305s390_irgen_STPQ(UChar r1, IRTemp op2addr)
7306{
7307 store(mkexpr(op2addr), get_gpr_dw0(r1));
7308 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(8)), get_gpr_dw0(r1 + 1));
7309
7310 return "stpq";
7311}
7312
7313static HChar *
7314s390_irgen_STRVH(UChar r1, IRTemp op2addr)
7315{
7316 store(mkexpr(op2addr), get_gpr_b7(r1));
7317 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(1)), get_gpr_b6(r1));
7318
7319 return "strvh";
7320}
7321
7322static HChar *
7323s390_irgen_STRV(UChar r1, IRTemp op2addr)
7324{
7325 store(mkexpr(op2addr), get_gpr_b7(r1));
7326 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(1)), get_gpr_b6(r1));
7327 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(2)), get_gpr_b5(r1));
7328 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(3)), get_gpr_b4(r1));
7329
7330 return "strv";
7331}
7332
7333static HChar *
7334s390_irgen_STRVG(UChar r1, IRTemp op2addr)
7335{
7336 store(mkexpr(op2addr), get_gpr_b7(r1));
7337 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(1)), get_gpr_b6(r1));
7338 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(2)), get_gpr_b5(r1));
7339 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(3)), get_gpr_b4(r1));
7340 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(4)), get_gpr_b3(r1));
7341 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(5)), get_gpr_b2(r1));
7342 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(6)), get_gpr_b1(r1));
7343 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(7)), get_gpr_b0(r1));
7344
7345 return "strvg";
7346}
7347
7348static HChar *
7349s390_irgen_SR(UChar r1, UChar r2)
7350{
7351 IRTemp op1 = newTemp(Ity_I32);
7352 IRTemp op2 = newTemp(Ity_I32);
7353 IRTemp result = newTemp(Ity_I32);
7354
7355 assign(op1, get_gpr_w1(r1));
7356 assign(op2, get_gpr_w1(r2));
7357 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7358 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
7359 put_gpr_w1(r1, mkexpr(result));
7360
7361 return "sr";
7362}
7363
7364static HChar *
7365s390_irgen_SGR(UChar r1, UChar r2)
7366{
7367 IRTemp op1 = newTemp(Ity_I64);
7368 IRTemp op2 = newTemp(Ity_I64);
7369 IRTemp result = newTemp(Ity_I64);
7370
7371 assign(op1, get_gpr_dw0(r1));
7372 assign(op2, get_gpr_dw0(r2));
7373 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7374 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
7375 put_gpr_dw0(r1, mkexpr(result));
7376
7377 return "sgr";
7378}
7379
7380static HChar *
7381s390_irgen_SGFR(UChar r1, UChar r2)
7382{
7383 IRTemp op1 = newTemp(Ity_I64);
7384 IRTemp op2 = newTemp(Ity_I64);
7385 IRTemp result = newTemp(Ity_I64);
7386
7387 assign(op1, get_gpr_dw0(r1));
7388 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
7389 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7390 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
7391 put_gpr_dw0(r1, mkexpr(result));
7392
7393 return "sgfr";
7394}
7395
7396static HChar *
7397s390_irgen_SRK(UChar r3, UChar r1, UChar r2)
7398{
7399 IRTemp op2 = newTemp(Ity_I32);
7400 IRTemp op3 = newTemp(Ity_I32);
7401 IRTemp result = newTemp(Ity_I32);
7402
7403 assign(op2, get_gpr_w1(r2));
7404 assign(op3, get_gpr_w1(r3));
7405 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
7406 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op2, op3);
7407 put_gpr_w1(r1, mkexpr(result));
7408
7409 return "srk";
7410}
7411
7412static HChar *
7413s390_irgen_SGRK(UChar r3, UChar r1, UChar r2)
7414{
7415 IRTemp op2 = newTemp(Ity_I64);
7416 IRTemp op3 = newTemp(Ity_I64);
7417 IRTemp result = newTemp(Ity_I64);
7418
7419 assign(op2, get_gpr_dw0(r2));
7420 assign(op3, get_gpr_dw0(r3));
7421 assign(result, binop(Iop_Sub64, mkexpr(op2), mkexpr(op3)));
7422 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op2, op3);
7423 put_gpr_dw0(r1, mkexpr(result));
7424
7425 return "sgrk";
7426}
7427
7428static HChar *
7429s390_irgen_S(UChar r1, IRTemp op2addr)
7430{
7431 IRTemp op1 = newTemp(Ity_I32);
7432 IRTemp op2 = newTemp(Ity_I32);
7433 IRTemp result = newTemp(Ity_I32);
7434
7435 assign(op1, get_gpr_w1(r1));
7436 assign(op2, load(Ity_I32, mkexpr(op2addr)));
7437 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7438 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
7439 put_gpr_w1(r1, mkexpr(result));
7440
7441 return "s";
7442}
7443
7444static HChar *
7445s390_irgen_SY(UChar r1, IRTemp op2addr)
7446{
7447 IRTemp op1 = newTemp(Ity_I32);
7448 IRTemp op2 = newTemp(Ity_I32);
7449 IRTemp result = newTemp(Ity_I32);
7450
7451 assign(op1, get_gpr_w1(r1));
7452 assign(op2, load(Ity_I32, mkexpr(op2addr)));
7453 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7454 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
7455 put_gpr_w1(r1, mkexpr(result));
7456
7457 return "sy";
7458}
7459
7460static HChar *
7461s390_irgen_SG(UChar r1, IRTemp op2addr)
7462{
7463 IRTemp op1 = newTemp(Ity_I64);
7464 IRTemp op2 = newTemp(Ity_I64);
7465 IRTemp result = newTemp(Ity_I64);
7466
7467 assign(op1, get_gpr_dw0(r1));
7468 assign(op2, load(Ity_I64, mkexpr(op2addr)));
7469 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7470 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
7471 put_gpr_dw0(r1, mkexpr(result));
7472
7473 return "sg";
7474}
7475
7476static HChar *
7477s390_irgen_SGF(UChar r1, IRTemp op2addr)
7478{
7479 IRTemp op1 = newTemp(Ity_I64);
7480 IRTemp op2 = newTemp(Ity_I64);
7481 IRTemp result = newTemp(Ity_I64);
7482
7483 assign(op1, get_gpr_dw0(r1));
7484 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
7485 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7486 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
7487 put_gpr_dw0(r1, mkexpr(result));
7488
7489 return "sgf";
7490}
7491
7492static HChar *
7493s390_irgen_SH(UChar r1, IRTemp op2addr)
7494{
7495 IRTemp op1 = newTemp(Ity_I32);
7496 IRTemp op2 = newTemp(Ity_I32);
7497 IRTemp result = newTemp(Ity_I32);
7498
7499 assign(op1, get_gpr_w1(r1));
7500 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
7501 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7502 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
7503 put_gpr_w1(r1, mkexpr(result));
7504
7505 return "sh";
7506}
7507
7508static HChar *
7509s390_irgen_SHY(UChar r1, IRTemp op2addr)
7510{
7511 IRTemp op1 = newTemp(Ity_I32);
7512 IRTemp op2 = newTemp(Ity_I32);
7513 IRTemp result = newTemp(Ity_I32);
7514
7515 assign(op1, get_gpr_w1(r1));
7516 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
7517 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7518 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
7519 put_gpr_w1(r1, mkexpr(result));
7520
7521 return "shy";
7522}
7523
7524static HChar *
7525s390_irgen_SHHHR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
7526{
7527 IRTemp op2 = newTemp(Ity_I32);
7528 IRTemp op3 = newTemp(Ity_I32);
7529 IRTemp result = newTemp(Ity_I32);
7530
7531 assign(op2, get_gpr_w0(r1));
7532 assign(op3, get_gpr_w0(r2));
7533 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
7534 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op2, op3);
7535 put_gpr_w0(r1, mkexpr(result));
7536
7537 return "shhhr";
7538}
7539
7540static HChar *
7541s390_irgen_SHHLR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
7542{
7543 IRTemp op2 = newTemp(Ity_I32);
7544 IRTemp op3 = newTemp(Ity_I32);
7545 IRTemp result = newTemp(Ity_I32);
7546
7547 assign(op2, get_gpr_w0(r1));
7548 assign(op3, get_gpr_w1(r2));
7549 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
7550 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op2, op3);
7551 put_gpr_w0(r1, mkexpr(result));
7552
7553 return "shhlr";
7554}
7555
7556static HChar *
7557s390_irgen_SLR(UChar r1, UChar r2)
7558{
7559 IRTemp op1 = newTemp(Ity_I32);
7560 IRTemp op2 = newTemp(Ity_I32);
7561 IRTemp result = newTemp(Ity_I32);
7562
7563 assign(op1, get_gpr_w1(r1));
7564 assign(op2, get_gpr_w1(r2));
7565 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7566 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, op2);
7567 put_gpr_w1(r1, mkexpr(result));
7568
7569 return "slr";
7570}
7571
7572static HChar *
7573s390_irgen_SLGR(UChar r1, UChar r2)
7574{
7575 IRTemp op1 = newTemp(Ity_I64);
7576 IRTemp op2 = newTemp(Ity_I64);
7577 IRTemp result = newTemp(Ity_I64);
7578
7579 assign(op1, get_gpr_dw0(r1));
7580 assign(op2, get_gpr_dw0(r2));
7581 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7582 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
7583 put_gpr_dw0(r1, mkexpr(result));
7584
7585 return "slgr";
7586}
7587
7588static HChar *
7589s390_irgen_SLGFR(UChar r1, UChar r2)
7590{
7591 IRTemp op1 = newTemp(Ity_I64);
7592 IRTemp op2 = newTemp(Ity_I64);
7593 IRTemp result = newTemp(Ity_I64);
7594
7595 assign(op1, get_gpr_dw0(r1));
7596 assign(op2, unop(Iop_32Uto64, get_gpr_w1(r2)));
7597 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7598 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
7599 put_gpr_dw0(r1, mkexpr(result));
7600
7601 return "slgfr";
7602}
7603
7604static HChar *
7605s390_irgen_SLRK(UChar r3, UChar r1, UChar r2)
7606{
7607 IRTemp op2 = newTemp(Ity_I32);
7608 IRTemp op3 = newTemp(Ity_I32);
7609 IRTemp result = newTemp(Ity_I32);
7610
7611 assign(op2, get_gpr_w1(r2));
7612 assign(op3, get_gpr_w1(r3));
7613 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
7614 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op2, op3);
7615 put_gpr_w1(r1, mkexpr(result));
7616
7617 return "slrk";
7618}
7619
7620static HChar *
7621s390_irgen_SLGRK(UChar r3, UChar r1, UChar r2)
7622{
7623 IRTemp op2 = newTemp(Ity_I64);
7624 IRTemp op3 = newTemp(Ity_I64);
7625 IRTemp result = newTemp(Ity_I64);
7626
7627 assign(op2, get_gpr_dw0(r2));
7628 assign(op3, get_gpr_dw0(r3));
7629 assign(result, binop(Iop_Sub64, mkexpr(op2), mkexpr(op3)));
7630 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op2, op3);
7631 put_gpr_dw0(r1, mkexpr(result));
7632
7633 return "slgrk";
7634}
7635
7636static HChar *
7637s390_irgen_SL(UChar r1, IRTemp op2addr)
7638{
7639 IRTemp op1 = newTemp(Ity_I32);
7640 IRTemp op2 = newTemp(Ity_I32);
7641 IRTemp result = newTemp(Ity_I32);
7642
7643 assign(op1, get_gpr_w1(r1));
7644 assign(op2, load(Ity_I32, mkexpr(op2addr)));
7645 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7646 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, op2);
7647 put_gpr_w1(r1, mkexpr(result));
7648
7649 return "sl";
7650}
7651
7652static HChar *
7653s390_irgen_SLY(UChar r1, IRTemp op2addr)
7654{
7655 IRTemp op1 = newTemp(Ity_I32);
7656 IRTemp op2 = newTemp(Ity_I32);
7657 IRTemp result = newTemp(Ity_I32);
7658
7659 assign(op1, get_gpr_w1(r1));
7660 assign(op2, load(Ity_I32, mkexpr(op2addr)));
7661 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7662 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, op2);
7663 put_gpr_w1(r1, mkexpr(result));
7664
7665 return "sly";
7666}
7667
7668static HChar *
7669s390_irgen_SLG(UChar r1, IRTemp op2addr)
7670{
7671 IRTemp op1 = newTemp(Ity_I64);
7672 IRTemp op2 = newTemp(Ity_I64);
7673 IRTemp result = newTemp(Ity_I64);
7674
7675 assign(op1, get_gpr_dw0(r1));
7676 assign(op2, load(Ity_I64, mkexpr(op2addr)));
7677 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7678 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
7679 put_gpr_dw0(r1, mkexpr(result));
7680
7681 return "slg";
7682}
7683
7684static HChar *
7685s390_irgen_SLGF(UChar r1, IRTemp op2addr)
7686{
7687 IRTemp op1 = newTemp(Ity_I64);
7688 IRTemp op2 = newTemp(Ity_I64);
7689 IRTemp result = newTemp(Ity_I64);
7690
7691 assign(op1, get_gpr_dw0(r1));
7692 assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
7693 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7694 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
7695 put_gpr_dw0(r1, mkexpr(result));
7696
7697 return "slgf";
7698}
7699
7700static HChar *
7701s390_irgen_SLFI(UChar r1, UInt i2)
7702{
7703 IRTemp op1 = newTemp(Ity_I32);
7704 UInt op2;
7705 IRTemp result = newTemp(Ity_I32);
7706
7707 assign(op1, get_gpr_w1(r1));
7708 op2 = i2;
7709 assign(result, binop(Iop_Sub32, mkexpr(op1), mkU32(op2)));
7710 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, mktemp(Ity_I32,
7711 mkU32(op2)));
7712 put_gpr_w1(r1, mkexpr(result));
7713
7714 return "slfi";
7715}
7716
7717static HChar *
7718s390_irgen_SLGFI(UChar r1, UInt i2)
7719{
7720 IRTemp op1 = newTemp(Ity_I64);
7721 ULong op2;
7722 IRTemp result = newTemp(Ity_I64);
7723
7724 assign(op1, get_gpr_dw0(r1));
7725 op2 = (ULong)i2;
7726 assign(result, binop(Iop_Sub64, mkexpr(op1), mkU64(op2)));
7727 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, mktemp(Ity_I64,
7728 mkU64(op2)));
7729 put_gpr_dw0(r1, mkexpr(result));
7730
7731 return "slgfi";
7732}
7733
7734static HChar *
7735s390_irgen_SLHHHR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
7736{
7737 IRTemp op2 = newTemp(Ity_I32);
7738 IRTemp op3 = newTemp(Ity_I32);
7739 IRTemp result = newTemp(Ity_I32);
7740
7741 assign(op2, get_gpr_w0(r1));
7742 assign(op3, get_gpr_w0(r2));
7743 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
7744 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op2, op3);
7745 put_gpr_w0(r1, mkexpr(result));
7746
7747 return "slhhhr";
7748}
7749
7750static HChar *
7751s390_irgen_SLHHLR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
7752{
7753 IRTemp op2 = newTemp(Ity_I32);
7754 IRTemp op3 = newTemp(Ity_I32);
7755 IRTemp result = newTemp(Ity_I32);
7756
7757 assign(op2, get_gpr_w0(r1));
7758 assign(op3, get_gpr_w1(r2));
7759 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
7760 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op2, op3);
7761 put_gpr_w0(r1, mkexpr(result));
7762
7763 return "slhhlr";
7764}
7765
7766static HChar *
7767s390_irgen_SLBR(UChar r1, UChar r2)
7768{
7769 IRTemp op1 = newTemp(Ity_I32);
7770 IRTemp op2 = newTemp(Ity_I32);
7771 IRTemp result = newTemp(Ity_I32);
7772 IRTemp borrow_in = newTemp(Ity_I32);
7773
7774 assign(op1, get_gpr_w1(r1));
7775 assign(op2, get_gpr_w1(r2));
7776 assign(borrow_in, binop(Iop_Sub32, mkU32(1), binop(Iop_Shr32,
7777 s390_call_calculate_cc(), mkU8(1))));
7778 assign(result, binop(Iop_Sub32, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)),
7779 mkexpr(borrow_in)));
7780 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_32, op1, op2, borrow_in);
7781 put_gpr_w1(r1, mkexpr(result));
7782
7783 return "slbr";
7784}
7785
7786static HChar *
7787s390_irgen_SLBGR(UChar r1, UChar r2)
7788{
7789 IRTemp op1 = newTemp(Ity_I64);
7790 IRTemp op2 = newTemp(Ity_I64);
7791 IRTemp result = newTemp(Ity_I64);
7792 IRTemp borrow_in = newTemp(Ity_I64);
7793
7794 assign(op1, get_gpr_dw0(r1));
7795 assign(op2, get_gpr_dw0(r2));
7796 assign(borrow_in, unop(Iop_32Uto64, binop(Iop_Sub32, mkU32(1),
7797 binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)))));
7798 assign(result, binop(Iop_Sub64, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)),
7799 mkexpr(borrow_in)));
7800 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_64, op1, op2, borrow_in);
7801 put_gpr_dw0(r1, mkexpr(result));
7802
7803 return "slbgr";
7804}
7805
7806static HChar *
7807s390_irgen_SLB(UChar r1, IRTemp op2addr)
7808{
7809 IRTemp op1 = newTemp(Ity_I32);
7810 IRTemp op2 = newTemp(Ity_I32);
7811 IRTemp result = newTemp(Ity_I32);
7812 IRTemp borrow_in = newTemp(Ity_I32);
7813
7814 assign(op1, get_gpr_w1(r1));
7815 assign(op2, load(Ity_I32, mkexpr(op2addr)));
7816 assign(borrow_in, binop(Iop_Sub32, mkU32(1), binop(Iop_Shr32,
7817 s390_call_calculate_cc(), mkU8(1))));
7818 assign(result, binop(Iop_Sub32, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)),
7819 mkexpr(borrow_in)));
7820 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_32, op1, op2, borrow_in);
7821 put_gpr_w1(r1, mkexpr(result));
7822
7823 return "slb";
7824}
7825
7826static HChar *
7827s390_irgen_SLBG(UChar r1, IRTemp op2addr)
7828{
7829 IRTemp op1 = newTemp(Ity_I64);
7830 IRTemp op2 = newTemp(Ity_I64);
7831 IRTemp result = newTemp(Ity_I64);
7832 IRTemp borrow_in = newTemp(Ity_I64);
7833
7834 assign(op1, get_gpr_dw0(r1));
7835 assign(op2, load(Ity_I64, mkexpr(op2addr)));
7836 assign(borrow_in, unop(Iop_32Uto64, binop(Iop_Sub32, mkU32(1),
7837 binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)))));
7838 assign(result, binop(Iop_Sub64, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)),
7839 mkexpr(borrow_in)));
7840 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_64, op1, op2, borrow_in);
7841 put_gpr_dw0(r1, mkexpr(result));
7842
7843 return "slbg";
7844}
7845
7846static HChar *
7847s390_irgen_SVC(UChar i)
7848{
7849 IRTemp sysno = newTemp(Ity_I64);
7850
7851 if (i != 0) {
7852 assign(sysno, mkU64(i));
7853 } else {
7854 assign(sysno, unop(Iop_32Uto64, get_gpr_w1(1)));
7855 }
7856 system_call(mkexpr(sysno));
7857
7858 return "svc";
7859}
7860
7861static HChar *
sewardj2019a972011-03-07 16:04:07 +00007862s390_irgen_TM(UChar i2, IRTemp op1addr)
7863{
7864 UChar mask;
7865 IRTemp value = newTemp(Ity_I8);
7866
7867 mask = i2;
7868 assign(value, load(Ity_I8, mkexpr(op1addr)));
7869 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_8, value, mktemp(Ity_I8,
7870 mkU8(mask)));
7871
7872 return "tm";
7873}
7874
7875static HChar *
7876s390_irgen_TMY(UChar i2, IRTemp op1addr)
7877{
7878 UChar mask;
7879 IRTemp value = newTemp(Ity_I8);
7880
7881 mask = i2;
7882 assign(value, load(Ity_I8, mkexpr(op1addr)));
7883 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_8, value, mktemp(Ity_I8,
7884 mkU8(mask)));
7885
7886 return "tmy";
7887}
7888
7889static HChar *
7890s390_irgen_TMHH(UChar r1, UShort i2)
7891{
7892 UShort mask;
7893 IRTemp value = newTemp(Ity_I16);
7894
7895 mask = i2;
7896 assign(value, get_gpr_hw0(r1));
7897 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
7898 mkU16(mask)));
7899
7900 return "tmhh";
7901}
7902
7903static HChar *
7904s390_irgen_TMHL(UChar r1, UShort i2)
7905{
7906 UShort mask;
7907 IRTemp value = newTemp(Ity_I16);
7908
7909 mask = i2;
7910 assign(value, get_gpr_hw1(r1));
7911 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
7912 mkU16(mask)));
7913
7914 return "tmhl";
7915}
7916
7917static HChar *
7918s390_irgen_TMLH(UChar r1, UShort i2)
7919{
7920 UShort mask;
7921 IRTemp value = newTemp(Ity_I16);
7922
7923 mask = i2;
7924 assign(value, get_gpr_hw2(r1));
7925 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
7926 mkU16(mask)));
7927
7928 return "tmlh";
7929}
7930
7931static HChar *
7932s390_irgen_TMLL(UChar r1, UShort i2)
7933{
7934 UShort mask;
7935 IRTemp value = newTemp(Ity_I16);
7936
7937 mask = i2;
7938 assign(value, get_gpr_hw3(r1));
7939 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
7940 mkU16(mask)));
7941
7942 return "tmll";
7943}
7944
7945static HChar *
7946s390_irgen_EFPC(UChar r1)
7947{
7948 put_gpr_w1(r1, get_fpc_w0());
7949
7950 return "efpc";
7951}
7952
7953static HChar *
7954s390_irgen_LER(UChar r1, UChar r2)
7955{
7956 put_fpr_w0(r1, get_fpr_w0(r2));
7957
7958 return "ler";
7959}
7960
7961static HChar *
7962s390_irgen_LDR(UChar r1, UChar r2)
7963{
7964 put_fpr_dw0(r1, get_fpr_dw0(r2));
7965
7966 return "ldr";
7967}
7968
7969static HChar *
7970s390_irgen_LXR(UChar r1, UChar r2)
7971{
7972 put_fpr_dw0(r1, get_fpr_dw0(r2));
7973 put_fpr_dw0(r1 + 2, get_fpr_dw0(r2 + 2));
7974
7975 return "lxr";
7976}
7977
7978static HChar *
7979s390_irgen_LE(UChar r1, IRTemp op2addr)
7980{
7981 put_fpr_w0(r1, load(Ity_F32, mkexpr(op2addr)));
7982
7983 return "le";
7984}
7985
7986static HChar *
7987s390_irgen_LD(UChar r1, IRTemp op2addr)
7988{
7989 put_fpr_dw0(r1, load(Ity_F64, mkexpr(op2addr)));
7990
7991 return "ld";
7992}
7993
7994static HChar *
7995s390_irgen_LEY(UChar r1, IRTemp op2addr)
7996{
7997 put_fpr_w0(r1, load(Ity_F32, mkexpr(op2addr)));
7998
7999 return "ley";
8000}
8001
8002static HChar *
8003s390_irgen_LDY(UChar r1, IRTemp op2addr)
8004{
8005 put_fpr_dw0(r1, load(Ity_F64, mkexpr(op2addr)));
8006
8007 return "ldy";
8008}
8009
8010static HChar *
8011s390_irgen_LFPC(IRTemp op2addr)
8012{
8013 put_fpc_w0(load(Ity_I32, mkexpr(op2addr)));
8014
8015 return "lfpc";
8016}
8017
8018static HChar *
8019s390_irgen_LZER(UChar r1)
8020{
8021 put_fpr_w0(r1, mkF32i(0x0));
8022
8023 return "lzer";
8024}
8025
8026static HChar *
8027s390_irgen_LZDR(UChar r1)
8028{
8029 put_fpr_dw0(r1, mkF64i(0x0));
8030
8031 return "lzdr";
8032}
8033
8034static HChar *
8035s390_irgen_LZXR(UChar r1)
8036{
8037 put_fpr_dw0(r1, mkF64i(0x0));
8038 put_fpr_dw0(r1 + 2, mkF64i(0x0));
8039
8040 return "lzxr";
8041}
8042
8043static HChar *
8044s390_irgen_SRNM(IRTemp op2addr)
8045{
8046 UInt mask;
8047
8048 mask = 3;
8049 put_fpc_w0(binop(Iop_Or32, binop(Iop_And32, get_fpc_w0(), mkU32(~mask)),
8050 binop(Iop_And32, unop(Iop_64to32, mkexpr(op2addr)), mkU32(mask)))
8051 );
8052
8053 return "srnm";
8054}
8055
8056static HChar *
8057s390_irgen_SFPC(UChar r1)
8058{
8059 put_fpc_w0(get_gpr_w1(r1));
8060
8061 return "sfpc";
8062}
8063
8064static HChar *
8065s390_irgen_STE(UChar r1, IRTemp op2addr)
8066{
8067 store(mkexpr(op2addr), get_fpr_w0(r1));
8068
8069 return "ste";
8070}
8071
8072static HChar *
8073s390_irgen_STD(UChar r1, IRTemp op2addr)
8074{
8075 store(mkexpr(op2addr), get_fpr_dw0(r1));
8076
8077 return "std";
8078}
8079
8080static HChar *
8081s390_irgen_STEY(UChar r1, IRTemp op2addr)
8082{
8083 store(mkexpr(op2addr), get_fpr_w0(r1));
8084
8085 return "stey";
8086}
8087
8088static HChar *
8089s390_irgen_STDY(UChar r1, IRTemp op2addr)
8090{
8091 store(mkexpr(op2addr), get_fpr_dw0(r1));
8092
8093 return "stdy";
8094}
8095
8096static HChar *
8097s390_irgen_STFPC(IRTemp op2addr)
8098{
8099 store(mkexpr(op2addr), get_fpc_w0());
8100
8101 return "stfpc";
8102}
8103
8104static HChar *
8105s390_irgen_AEBR(UChar r1, UChar r2)
8106{
8107 IRTemp op1 = newTemp(Ity_F32);
8108 IRTemp op2 = newTemp(Ity_F32);
8109 IRTemp result = newTemp(Ity_F32);
8110
8111 assign(op1, get_fpr_w0(r1));
8112 assign(op2, get_fpr_w0(r2));
8113 assign(result, triop(Iop_AddF32, mkU32(Irrm_NEAREST), mkexpr(op1),
8114 mkexpr(op2)));
8115 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
8116 put_fpr_w0(r1, mkexpr(result));
8117
8118 return "aebr";
8119}
8120
8121static HChar *
8122s390_irgen_ADBR(UChar r1, UChar r2)
8123{
8124 IRTemp op1 = newTemp(Ity_F64);
8125 IRTemp op2 = newTemp(Ity_F64);
8126 IRTemp result = newTemp(Ity_F64);
8127
8128 assign(op1, get_fpr_dw0(r1));
8129 assign(op2, get_fpr_dw0(r2));
8130 assign(result, triop(Iop_AddF64, mkU32(Irrm_NEAREST), mkexpr(op1),
8131 mkexpr(op2)));
8132 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
8133 put_fpr_dw0(r1, mkexpr(result));
8134
8135 return "adbr";
8136}
8137
8138static HChar *
8139s390_irgen_AEB(UChar r1, IRTemp op2addr)
8140{
8141 IRTemp op1 = newTemp(Ity_F32);
8142 IRTemp op2 = newTemp(Ity_F32);
8143 IRTemp result = newTemp(Ity_F32);
8144
8145 assign(op1, get_fpr_w0(r1));
8146 assign(op2, load(Ity_F32, mkexpr(op2addr)));
8147 assign(result, triop(Iop_AddF32, mkU32(Irrm_NEAREST), mkexpr(op1),
8148 mkexpr(op2)));
8149 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
8150 put_fpr_w0(r1, mkexpr(result));
8151
8152 return "aeb";
8153}
8154
8155static HChar *
8156s390_irgen_ADB(UChar r1, IRTemp op2addr)
8157{
8158 IRTemp op1 = newTemp(Ity_F64);
8159 IRTemp op2 = newTemp(Ity_F64);
8160 IRTemp result = newTemp(Ity_F64);
8161
8162 assign(op1, get_fpr_dw0(r1));
8163 assign(op2, load(Ity_F64, mkexpr(op2addr)));
8164 assign(result, triop(Iop_AddF64, mkU32(Irrm_NEAREST), mkexpr(op1),
8165 mkexpr(op2)));
8166 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
8167 put_fpr_dw0(r1, mkexpr(result));
8168
8169 return "adb";
8170}
8171
8172static HChar *
8173s390_irgen_CEFBR(UChar r1, UChar r2)
8174{
8175 IRTemp op2 = newTemp(Ity_I32);
8176
8177 assign(op2, get_gpr_w1(r2));
8178 put_fpr_w0(r1, binop(Iop_I32StoF32, mkU32(Irrm_NEAREST), mkexpr(op2)));
8179
8180 return "cefbr";
8181}
8182
8183static HChar *
8184s390_irgen_CDFBR(UChar r1, UChar r2)
8185{
8186 IRTemp op2 = newTemp(Ity_I32);
8187
8188 assign(op2, get_gpr_w1(r2));
8189 put_fpr_dw0(r1, unop(Iop_I32StoF64, mkexpr(op2)));
8190
8191 return "cdfbr";
8192}
8193
8194static HChar *
8195s390_irgen_CEGBR(UChar r1, UChar r2)
8196{
8197 IRTemp op2 = newTemp(Ity_I64);
8198
8199 assign(op2, get_gpr_dw0(r2));
8200 put_fpr_w0(r1, binop(Iop_I64StoF32, mkU32(Irrm_NEAREST), mkexpr(op2)));
8201
8202 return "cegbr";
8203}
8204
8205static HChar *
8206s390_irgen_CDGBR(UChar r1, UChar r2)
8207{
8208 IRTemp op2 = newTemp(Ity_I64);
8209
8210 assign(op2, get_gpr_dw0(r2));
8211 put_fpr_dw0(r1, binop(Iop_I64StoF64, mkU32(Irrm_NEAREST), mkexpr(op2)));
8212
8213 return "cdgbr";
8214}
8215
8216static HChar *
8217s390_irgen_CFEBR(UChar r3, UChar r1, UChar r2)
8218{
8219 IRTemp op = newTemp(Ity_F32);
8220 IRTemp result = newTemp(Ity_I32);
8221
8222 assign(op, get_fpr_w0(r2));
8223 assign(result, binop(Iop_F32toI32S, mkU32(encode_rounding_mode(r3)),
8224 mkexpr(op)));
8225 put_gpr_w1(r1, mkexpr(result));
8226 s390_cc_thunk_putF(S390_CC_OP_BFP_32_TO_INT_32, op);
8227
8228 return "cfebr";
8229}
8230
8231static HChar *
8232s390_irgen_CFDBR(UChar r3, UChar r1, UChar r2)
8233{
8234 IRTemp op = newTemp(Ity_F64);
8235 IRTemp result = newTemp(Ity_I32);
8236
8237 assign(op, get_fpr_dw0(r2));
8238 assign(result, binop(Iop_F64toI32S, mkU32(encode_rounding_mode(r3)),
8239 mkexpr(op)));
8240 put_gpr_w1(r1, mkexpr(result));
8241 s390_cc_thunk_putF(S390_CC_OP_BFP_64_TO_INT_32, op);
8242
8243 return "cfdbr";
8244}
8245
8246static HChar *
8247s390_irgen_CGEBR(UChar r3, UChar r1, UChar r2)
8248{
8249 IRTemp op = newTemp(Ity_F32);
8250 IRTemp result = newTemp(Ity_I64);
8251
8252 assign(op, get_fpr_w0(r2));
8253 assign(result, binop(Iop_F32toI64S, mkU32(encode_rounding_mode(r3)),
8254 mkexpr(op)));
8255 put_gpr_dw0(r1, mkexpr(result));
8256 s390_cc_thunk_putF(S390_CC_OP_BFP_32_TO_INT_64, op);
8257
8258 return "cgebr";
8259}
8260
8261static HChar *
8262s390_irgen_CGDBR(UChar r3, UChar r1, UChar r2)
8263{
8264 IRTemp op = newTemp(Ity_F64);
8265 IRTemp result = newTemp(Ity_I64);
8266
8267 assign(op, get_fpr_dw0(r2));
8268 assign(result, binop(Iop_F64toI64S, mkU32(encode_rounding_mode(r3)),
8269 mkexpr(op)));
8270 put_gpr_dw0(r1, mkexpr(result));
8271 s390_cc_thunk_putF(S390_CC_OP_BFP_64_TO_INT_64, op);
8272
8273 return "cgdbr";
8274}
8275
8276static HChar *
8277s390_irgen_DEBR(UChar r1, UChar r2)
8278{
8279 IRTemp op1 = newTemp(Ity_F32);
8280 IRTemp op2 = newTemp(Ity_F32);
8281 IRTemp result = newTemp(Ity_F32);
8282
8283 assign(op1, get_fpr_w0(r1));
8284 assign(op2, get_fpr_w0(r2));
8285 assign(result, triop(Iop_DivF32, mkU32(Irrm_NEAREST), mkexpr(op1),
8286 mkexpr(op2)));
8287 put_fpr_w0(r1, mkexpr(result));
8288
8289 return "debr";
8290}
8291
8292static HChar *
8293s390_irgen_DDBR(UChar r1, UChar r2)
8294{
8295 IRTemp op1 = newTemp(Ity_F64);
8296 IRTemp op2 = newTemp(Ity_F64);
8297 IRTemp result = newTemp(Ity_F64);
8298
8299 assign(op1, get_fpr_dw0(r1));
8300 assign(op2, get_fpr_dw0(r2));
8301 assign(result, triop(Iop_DivF64, mkU32(Irrm_NEAREST), mkexpr(op1),
8302 mkexpr(op2)));
8303 put_fpr_dw0(r1, mkexpr(result));
8304
8305 return "ddbr";
8306}
8307
8308static HChar *
8309s390_irgen_DEB(UChar r1, IRTemp op2addr)
8310{
8311 IRTemp op1 = newTemp(Ity_F32);
8312 IRTemp op2 = newTemp(Ity_F32);
8313 IRTemp result = newTemp(Ity_F32);
8314
8315 assign(op1, get_fpr_w0(r1));
8316 assign(op2, load(Ity_F32, mkexpr(op2addr)));
8317 assign(result, triop(Iop_DivF32, mkU32(Irrm_NEAREST), mkexpr(op1),
8318 mkexpr(op2)));
8319 put_fpr_w0(r1, mkexpr(result));
8320
8321 return "deb";
8322}
8323
8324static HChar *
8325s390_irgen_DDB(UChar r1, IRTemp op2addr)
8326{
8327 IRTemp op1 = newTemp(Ity_F64);
8328 IRTemp op2 = newTemp(Ity_F64);
8329 IRTemp result = newTemp(Ity_F64);
8330
8331 assign(op1, get_fpr_dw0(r1));
8332 assign(op2, load(Ity_F64, mkexpr(op2addr)));
8333 assign(result, triop(Iop_DivF64, mkU32(Irrm_NEAREST), mkexpr(op1),
8334 mkexpr(op2)));
8335 put_fpr_dw0(r1, mkexpr(result));
8336
8337 return "ddb";
8338}
8339
8340static HChar *
8341s390_irgen_LTEBR(UChar r1, UChar r2)
8342{
8343 IRTemp result = newTemp(Ity_F32);
8344
8345 assign(result, get_fpr_w0(r2));
8346 put_fpr_w0(r1, mkexpr(result));
8347 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
8348
8349 return "ltebr";
8350}
8351
8352static HChar *
8353s390_irgen_LTDBR(UChar r1, UChar r2)
8354{
8355 IRTemp result = newTemp(Ity_F64);
8356
8357 assign(result, get_fpr_dw0(r2));
8358 put_fpr_dw0(r1, mkexpr(result));
8359 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
8360
8361 return "ltdbr";
8362}
8363
8364static HChar *
8365s390_irgen_LCEBR(UChar r1, UChar r2)
8366{
8367 IRTemp result = newTemp(Ity_F32);
8368
8369 assign(result, unop(Iop_NegF32, get_fpr_w0(r2)));
8370 put_fpr_w0(r1, mkexpr(result));
8371 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
8372
8373 return "lcebr";
8374}
8375
8376static HChar *
8377s390_irgen_LCDBR(UChar r1, UChar r2)
8378{
8379 IRTemp result = newTemp(Ity_F64);
8380
8381 assign(result, unop(Iop_NegF64, get_fpr_dw0(r2)));
8382 put_fpr_dw0(r1, mkexpr(result));
8383 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
8384
8385 return "lcdbr";
8386}
8387
8388static HChar *
8389s390_irgen_LDEBR(UChar r1, UChar r2)
8390{
8391 IRTemp op = newTemp(Ity_F32);
8392
8393 assign(op, get_fpr_w0(r2));
8394 put_fpr_dw0(r1, unop(Iop_F32toF64, mkexpr(op)));
8395
8396 return "ldebr";
8397}
8398
8399static HChar *
8400s390_irgen_LDEB(UChar r1, IRTemp op2addr)
8401{
8402 IRTemp op = newTemp(Ity_F32);
8403
8404 assign(op, load(Ity_F32, mkexpr(op2addr)));
8405 put_fpr_dw0(r1, unop(Iop_F32toF64, mkexpr(op)));
8406
8407 return "ldeb";
8408}
8409
8410static HChar *
8411s390_irgen_LEDBR(UChar r1, UChar r2)
8412{
8413 IRTemp op = newTemp(Ity_F64);
8414
8415 assign(op, get_fpr_dw0(r2));
8416 put_fpr_w0(r1, binop(Iop_F64toF32, mkU32(Irrm_NEAREST), mkexpr(op)));
8417
8418 return "ledbr";
8419}
8420
8421static HChar *
8422s390_irgen_MEEBR(UChar r1, UChar r2)
8423{
8424 IRTemp op1 = newTemp(Ity_F32);
8425 IRTemp op2 = newTemp(Ity_F32);
8426 IRTemp result = newTemp(Ity_F32);
8427
8428 assign(op1, get_fpr_w0(r1));
8429 assign(op2, get_fpr_w0(r2));
8430 assign(result, triop(Iop_MulF32, mkU32(Irrm_NEAREST), mkexpr(op1),
8431 mkexpr(op2)));
8432 put_fpr_w0(r1, mkexpr(result));
8433
8434 return "meebr";
8435}
8436
8437static HChar *
8438s390_irgen_MDBR(UChar r1, UChar r2)
8439{
8440 IRTemp op1 = newTemp(Ity_F64);
8441 IRTemp op2 = newTemp(Ity_F64);
8442 IRTemp result = newTemp(Ity_F64);
8443
8444 assign(op1, get_fpr_dw0(r1));
8445 assign(op2, get_fpr_dw0(r2));
8446 assign(result, triop(Iop_MulF64, mkU32(Irrm_NEAREST), mkexpr(op1),
8447 mkexpr(op2)));
8448 put_fpr_dw0(r1, mkexpr(result));
8449
8450 return "mdbr";
8451}
8452
8453static HChar *
8454s390_irgen_MEEB(UChar r1, IRTemp op2addr)
8455{
8456 IRTemp op1 = newTemp(Ity_F32);
8457 IRTemp op2 = newTemp(Ity_F32);
8458 IRTemp result = newTemp(Ity_F32);
8459
8460 assign(op1, get_fpr_w0(r1));
8461 assign(op2, load(Ity_F32, mkexpr(op2addr)));
8462 assign(result, triop(Iop_MulF32, mkU32(Irrm_NEAREST), mkexpr(op1),
8463 mkexpr(op2)));
8464 put_fpr_w0(r1, mkexpr(result));
8465
8466 return "meeb";
8467}
8468
8469static HChar *
8470s390_irgen_MDB(UChar r1, IRTemp op2addr)
8471{
8472 IRTemp op1 = newTemp(Ity_F64);
8473 IRTemp op2 = newTemp(Ity_F64);
8474 IRTemp result = newTemp(Ity_F64);
8475
8476 assign(op1, get_fpr_dw0(r1));
8477 assign(op2, load(Ity_F64, mkexpr(op2addr)));
8478 assign(result, triop(Iop_MulF64, mkU32(Irrm_NEAREST), mkexpr(op1),
8479 mkexpr(op2)));
8480 put_fpr_dw0(r1, mkexpr(result));
8481
8482 return "mdb";
8483}
8484
8485static HChar *
8486s390_irgen_SEBR(UChar r1, UChar r2)
8487{
8488 IRTemp op1 = newTemp(Ity_F32);
8489 IRTemp op2 = newTemp(Ity_F32);
8490 IRTemp result = newTemp(Ity_F32);
8491
8492 assign(op1, get_fpr_w0(r1));
8493 assign(op2, get_fpr_w0(r2));
8494 assign(result, triop(Iop_SubF32, mkU32(Irrm_NEAREST), mkexpr(op1),
8495 mkexpr(op2)));
8496 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
8497 put_fpr_w0(r1, mkexpr(result));
8498
8499 return "sebr";
8500}
8501
8502static HChar *
8503s390_irgen_SDBR(UChar r1, UChar r2)
8504{
8505 IRTemp op1 = newTemp(Ity_F64);
8506 IRTemp op2 = newTemp(Ity_F64);
8507 IRTemp result = newTemp(Ity_F64);
8508
8509 assign(op1, get_fpr_dw0(r1));
8510 assign(op2, get_fpr_dw0(r2));
8511 assign(result, triop(Iop_SubF64, mkU32(Irrm_NEAREST), mkexpr(op1),
8512 mkexpr(op2)));
8513 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
8514 put_fpr_dw0(r1, mkexpr(result));
8515
8516 return "sdbr";
8517}
8518
8519static HChar *
8520s390_irgen_SEB(UChar r1, IRTemp op2addr)
8521{
8522 IRTemp op1 = newTemp(Ity_F32);
8523 IRTemp op2 = newTemp(Ity_F32);
8524 IRTemp result = newTemp(Ity_F32);
8525
8526 assign(op1, get_fpr_w0(r1));
8527 assign(op2, load(Ity_F32, mkexpr(op2addr)));
8528 assign(result, triop(Iop_SubF32, mkU32(Irrm_NEAREST), mkexpr(op1),
8529 mkexpr(op2)));
8530 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
8531 put_fpr_w0(r1, mkexpr(result));
8532
8533 return "seb";
8534}
8535
8536static HChar *
8537s390_irgen_SDB(UChar r1, IRTemp op2addr)
8538{
8539 IRTemp op1 = newTemp(Ity_F64);
8540 IRTemp op2 = newTemp(Ity_F64);
8541 IRTemp result = newTemp(Ity_F64);
8542
8543 assign(op1, get_fpr_dw0(r1));
8544 assign(op2, load(Ity_F64, mkexpr(op2addr)));
8545 assign(result, triop(Iop_SubF64, mkU32(Irrm_NEAREST), mkexpr(op1),
8546 mkexpr(op2)));
8547 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
8548 put_fpr_dw0(r1, mkexpr(result));
8549
8550 return "sdb";
8551}
8552
8553
8554static HChar *
8555s390_irgen_CLC(UChar length, IRTemp start1, IRTemp start2)
8556{
florian79e839e2012-05-05 02:20:30 +00008557 IRTemp len = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00008558
florian79e839e2012-05-05 02:20:30 +00008559 assign(len, mkU64(length));
8560 s390_irgen_CLC_EX(len, start1, start2);
florian8844a632012-04-13 04:04:06 +00008561 dummy_put_IA();
sewardj2019a972011-03-07 16:04:07 +00008562
8563 return "clc";
8564}
8565
8566static HChar *
florianb0c9a132011-09-08 15:37:39 +00008567s390_irgen_CLCL(UChar r1, UChar r2)
8568{
8569 IRTemp addr1 = newTemp(Ity_I64);
8570 IRTemp addr2 = newTemp(Ity_I64);
8571 IRTemp addr1_load = newTemp(Ity_I64);
8572 IRTemp addr2_load = newTemp(Ity_I64);
8573 IRTemp len1 = newTemp(Ity_I32);
8574 IRTemp len2 = newTemp(Ity_I32);
8575 IRTemp r1p1 = newTemp(Ity_I32); /* contents of r1 + 1 */
8576 IRTemp r2p1 = newTemp(Ity_I32); /* contents of r2 + 1 */
8577 IRTemp single1 = newTemp(Ity_I8);
8578 IRTemp single2 = newTemp(Ity_I8);
8579 IRTemp pad = newTemp(Ity_I8);
8580
8581 assign(addr1, get_gpr_dw0(r1));
8582 assign(r1p1, get_gpr_w1(r1 + 1));
8583 assign(len1, binop(Iop_And32, mkexpr(r1p1), mkU32(0x00ffffff)));
8584 assign(addr2, get_gpr_dw0(r2));
8585 assign(r2p1, get_gpr_w1(r2 + 1));
8586 assign(len2, binop(Iop_And32, mkexpr(r2p1), mkU32(0x00ffffff)));
8587 assign(pad, get_gpr_b4(r2 + 1));
8588
8589 /* len1 == 0 and len2 == 0? Exit */
8590 s390_cc_set(0);
8591 if_condition_goto(binop(Iop_CmpEQ32, binop(Iop_Or32, mkexpr(len1),
8592 mkexpr(len2)), mkU32(0)),
8593 guest_IA_next_instr);
8594
8595 /* Because mkite evaluates both the then-clause and the else-clause
8596 we cannot load directly from addr1 here. If len1 is 0, then adddr1
8597 may be NULL and loading from there would segfault. So we provide a
8598 valid dummy address in that case. Loading from there does no harm and
8599 the value will be discarded at runtime. */
8600 assign(addr1_load,
8601 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
8602 mkU64(guest_IA_curr_instr), mkexpr(addr1)));
8603 assign(single1,
8604 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
8605 mkexpr(pad), load(Ity_I8, mkexpr(addr1_load))));
8606
8607 assign(addr2_load,
8608 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
8609 mkU64(guest_IA_curr_instr), mkexpr(addr2)));
8610 assign(single2,
8611 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
8612 mkexpr(pad), load(Ity_I8, mkexpr(addr2_load))));
8613
8614 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, single1, single2, False);
8615 /* Fields differ ? */
8616 if_condition_goto(binop(Iop_CmpNE8, mkexpr(single1), mkexpr(single2)),
8617 guest_IA_next_instr);
8618
8619 /* Update len1 and addr1, unless len1 == 0. */
8620 put_gpr_dw0(r1,
8621 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
8622 mkexpr(addr1),
8623 binop(Iop_Add64, mkexpr(addr1), mkU64(1))));
8624
8625 /* When updating len1 we must not modify bits (r1+1)[0:39] */
8626 put_gpr_w1(r1 + 1,
8627 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
8628 binop(Iop_And32, mkexpr(r1p1), mkU32(0xFF000000u)),
8629 binop(Iop_Sub32, mkexpr(r1p1), mkU32(1))));
8630
8631 /* Update len2 and addr2, unless len2 == 0. */
8632 put_gpr_dw0(r2,
8633 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
8634 mkexpr(addr2),
8635 binop(Iop_Add64, mkexpr(addr2), mkU64(1))));
8636
8637 /* When updating len2 we must not modify bits (r2+1)[0:39] */
8638 put_gpr_w1(r2 + 1,
8639 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
8640 binop(Iop_And32, mkexpr(r2p1), mkU32(0xFF000000u)),
8641 binop(Iop_Sub32, mkexpr(r2p1), mkU32(1))));
8642
8643 always_goto_and_chase(guest_IA_curr_instr);
8644
8645 return "clcl";
8646}
8647
8648static HChar *
sewardj2019a972011-03-07 16:04:07 +00008649s390_irgen_CLCLE(UChar r1, UChar r3, IRTemp pad2)
8650{
8651 IRTemp addr1, addr3, addr1_load, addr3_load, len1, len3, single1, single3;
8652
8653 addr1 = newTemp(Ity_I64);
8654 addr3 = newTemp(Ity_I64);
8655 addr1_load = newTemp(Ity_I64);
8656 addr3_load = newTemp(Ity_I64);
8657 len1 = newTemp(Ity_I64);
8658 len3 = newTemp(Ity_I64);
8659 single1 = newTemp(Ity_I8);
8660 single3 = newTemp(Ity_I8);
8661
8662 assign(addr1, get_gpr_dw0(r1));
8663 assign(len1, get_gpr_dw0(r1 + 1));
8664 assign(addr3, get_gpr_dw0(r3));
8665 assign(len3, get_gpr_dw0(r3 + 1));
8666
8667 /* len1 == 0 and len3 == 0? Exit */
8668 s390_cc_set(0);
8669 if_condition_goto(binop(Iop_CmpEQ64,binop(Iop_Or64, mkexpr(len1),
8670 mkexpr(len3)), mkU64(0)),
8671 guest_IA_next_instr);
8672
8673 /* A mux requires both ways to be possible. This is a way to prevent clcle
8674 from reading from addr1 if it should read from the pad. Since the pad
8675 has no address, just read from the instruction, we discard that anyway */
8676 assign(addr1_load,
florian6ad49522011-09-09 02:38:55 +00008677 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
8678 mkU64(guest_IA_curr_instr), mkexpr(addr1)));
sewardj2019a972011-03-07 16:04:07 +00008679
8680 /* same for addr3 */
8681 assign(addr3_load,
florian6ad49522011-09-09 02:38:55 +00008682 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
8683 mkU64(guest_IA_curr_instr), mkexpr(addr3)));
sewardj2019a972011-03-07 16:04:07 +00008684
8685 assign(single1,
florian6ad49522011-09-09 02:38:55 +00008686 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
8687 unop(Iop_64to8, mkexpr(pad2)),
8688 load(Ity_I8, mkexpr(addr1_load))));
sewardj2019a972011-03-07 16:04:07 +00008689
8690 assign(single3,
florian6ad49522011-09-09 02:38:55 +00008691 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
8692 unop(Iop_64to8, mkexpr(pad2)),
8693 load(Ity_I8, mkexpr(addr3_load))));
sewardj2019a972011-03-07 16:04:07 +00008694
8695 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, single1, single3, False);
8696 /* Both fields differ ? */
8697 if_condition_goto(binop(Iop_CmpNE8, mkexpr(single1), mkexpr(single3)),
8698 guest_IA_next_instr);
8699
8700 /* If a length in 0 we must not change this length and the address */
8701 put_gpr_dw0(r1,
florian6ad49522011-09-09 02:38:55 +00008702 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
8703 mkexpr(addr1),
8704 binop(Iop_Add64, mkexpr(addr1), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +00008705
8706 put_gpr_dw0(r1 + 1,
florian6ad49522011-09-09 02:38:55 +00008707 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
8708 mkU64(0), binop(Iop_Sub64, mkexpr(len1), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +00008709
8710 put_gpr_dw0(r3,
florian6ad49522011-09-09 02:38:55 +00008711 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
8712 mkexpr(addr3),
8713 binop(Iop_Add64, mkexpr(addr3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +00008714
8715 put_gpr_dw0(r3 + 1,
florian6ad49522011-09-09 02:38:55 +00008716 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
8717 mkU64(0), binop(Iop_Sub64, mkexpr(len3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +00008718
8719 /* The architecture requires that we exit with CC3 after a machine specific
8720 amount of bytes. We do that if len1+len3 % 4096 == 0 */
8721 s390_cc_set(3);
8722 if_condition_goto(binop(Iop_CmpEQ64,
8723 binop(Iop_And64,
8724 binop(Iop_Add64, mkexpr(len1), mkexpr(len3)),
8725 mkU64(0xfff)),
8726 mkU64(0)),
8727 guest_IA_next_instr);
8728
floriana64c2432011-07-16 02:11:50 +00008729 always_goto_and_chase(guest_IA_curr_instr);
sewardj2019a972011-03-07 16:04:07 +00008730
8731 return "clcle";
8732}
floriana64c2432011-07-16 02:11:50 +00008733
florianb0bf6602012-05-05 00:01:16 +00008734
sewardj2019a972011-03-07 16:04:07 +00008735static void
8736s390_irgen_XC_EX(IRTemp length, IRTemp start1, IRTemp start2)
8737{
florianb0bf6602012-05-05 00:01:16 +00008738 s390_irgen_xonc(Iop_Xor8, length, start1, start2);
8739}
sewardj2019a972011-03-07 16:04:07 +00008740
sewardj2019a972011-03-07 16:04:07 +00008741
florianb0bf6602012-05-05 00:01:16 +00008742static void
8743s390_irgen_NC_EX(IRTemp length, IRTemp start1, IRTemp start2)
8744{
8745 s390_irgen_xonc(Iop_And8, length, start1, start2);
8746}
sewardj2019a972011-03-07 16:04:07 +00008747
sewardj2019a972011-03-07 16:04:07 +00008748
florianb0bf6602012-05-05 00:01:16 +00008749static void
8750s390_irgen_OC_EX(IRTemp length, IRTemp start1, IRTemp start2)
8751{
8752 s390_irgen_xonc(Iop_Or8, length, start1, start2);
sewardj2019a972011-03-07 16:04:07 +00008753}
8754
8755
8756static void
8757s390_irgen_CLC_EX(IRTemp length, IRTemp start1, IRTemp start2)
8758{
8759 IRTemp current1 = newTemp(Ity_I8);
8760 IRTemp current2 = newTemp(Ity_I8);
8761 IRTemp counter = newTemp(Ity_I64);
8762
8763 assign(counter, get_counter_dw0());
8764 put_counter_dw0(mkU64(0));
8765
8766 assign(current1, load(Ity_I8, binop(Iop_Add64, mkexpr(start1),
8767 mkexpr(counter))));
8768 assign(current2, load(Ity_I8, binop(Iop_Add64, mkexpr(start2),
8769 mkexpr(counter))));
8770 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, current1, current2,
8771 False);
8772
8773 /* Both fields differ ? */
8774 if_condition_goto(binop(Iop_CmpNE8, mkexpr(current1), mkexpr(current2)),
8775 guest_IA_next_instr);
8776
8777 /* Check for end of field */
8778 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
8779 if_condition_goto(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)),
8780 guest_IA_curr_instr);
8781 put_counter_dw0(mkU64(0));
8782}
8783
8784static void
8785s390_irgen_MVC_EX(IRTemp length, IRTemp start1, IRTemp start2)
8786{
8787 IRTemp counter = newTemp(Ity_I64);
8788
8789 assign(counter, get_counter_dw0());
8790
8791 store(binop(Iop_Add64, mkexpr(start1), mkexpr(counter)),
8792 load(Ity_I8, binop(Iop_Add64, mkexpr(start2), mkexpr(counter))));
8793
8794 /* Check for end of field */
8795 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
8796 if_condition_goto(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)),
8797 guest_IA_curr_instr);
8798 put_counter_dw0(mkU64(0));
8799}
8800
florianf87d4fb2012-05-05 02:55:24 +00008801static void
8802s390_irgen_TR_EX(IRTemp length, IRTemp start1, IRTemp start2)
8803{
8804 IRTemp op = newTemp(Ity_I8);
8805 IRTemp op1 = newTemp(Ity_I8);
8806 IRTemp result = newTemp(Ity_I64);
8807 IRTemp counter = newTemp(Ity_I64);
8808
8809 assign(counter, get_counter_dw0());
8810
8811 assign(op, load(Ity_I8, binop(Iop_Add64, mkexpr(start1), mkexpr(counter))));
8812
8813 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)), mkexpr(start2)));
8814
8815 assign(op1, load(Ity_I8, mkexpr(result)));
8816 store(binop(Iop_Add64, mkexpr(start1), mkexpr(counter)), mkexpr(op1));
8817
8818 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
8819 if_condition_goto(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)),
8820 guest_IA_curr_instr);
8821 put_counter_dw0(mkU64(0));
8822}
sewardj2019a972011-03-07 16:04:07 +00008823
8824
8825static void
8826s390_irgen_EX_SS(UChar r, IRTemp addr2,
8827void (*irgen)(IRTemp length, IRTemp start1, IRTemp start2), int lensize)
8828{
8829 struct SS {
8830 unsigned int op : 8;
8831 unsigned int l : 8;
8832 unsigned int b1 : 4;
8833 unsigned int d1 : 12;
8834 unsigned int b2 : 4;
8835 unsigned int d2 : 12;
8836 };
8837 union {
8838 struct SS dec;
8839 unsigned long bytes;
8840 } ss;
8841 IRTemp cond;
8842 IRDirty *d;
8843 IRTemp torun;
8844
8845 IRTemp start1 = newTemp(Ity_I64);
8846 IRTemp start2 = newTemp(Ity_I64);
8847 IRTemp len = newTemp(lensize == 64 ? Ity_I64 : Ity_I32);
8848 cond = newTemp(Ity_I1);
8849 torun = newTemp(Ity_I64);
8850
8851 assign(torun, load(Ity_I64, mkexpr(addr2)));
8852 /* Start with a check that the saved code is still correct */
8853 assign(cond, binop(Iop_CmpNE64, mkexpr(torun), mkU64(last_execute_target)));
8854 /* If not, save the new value */
8855 d = unsafeIRDirty_0_N (0, "s390x_dirtyhelper_EX", &s390x_dirtyhelper_EX,
8856 mkIRExprVec_1(mkexpr(torun)));
8857 d->guard = mkexpr(cond);
8858 stmt(IRStmt_Dirty(d));
8859
8860 /* and restart */
florian428dfdd2012-03-27 03:09:49 +00008861 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TISTART),
8862 mkU64(guest_IA_curr_instr)));
8863 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TILEN), mkU64(4)));
florian8844a632012-04-13 04:04:06 +00008864 stmt(IRStmt_Exit(mkexpr(cond), Ijk_TInval, IRConst_U64(guest_IA_curr_instr),
8865 S390X_GUEST_OFFSET(guest_IA)));
sewardj2019a972011-03-07 16:04:07 +00008866
8867 ss.bytes = last_execute_target;
8868 assign(start1, binop(Iop_Add64, mkU64(ss.dec.d1),
8869 ss.dec.b1 != 0 ? get_gpr_dw0(ss.dec.b1) : mkU64(0)));
8870 assign(start2, binop(Iop_Add64, mkU64(ss.dec.d2),
8871 ss.dec.b2 != 0 ? get_gpr_dw0(ss.dec.b2) : mkU64(0)));
8872 assign(len, unop(lensize == 64 ? Iop_8Uto64 : Iop_8Uto32, binop(Iop_Or8,
8873 r != 0 ? get_gpr_b7(r): mkU8(0), mkU8(ss.dec.l))));
8874 irgen(len, start1, start2);
florian8844a632012-04-13 04:04:06 +00008875 dummy_put_IA();
8876
sewardj2019a972011-03-07 16:04:07 +00008877 last_execute_target = 0;
8878}
8879
8880static HChar *
8881s390_irgen_EX(UChar r1, IRTemp addr2)
8882{
8883 switch(last_execute_target & 0xff00000000000000ULL) {
8884 case 0:
8885 {
8886 /* no code information yet */
8887 IRDirty *d;
8888
8889 /* so safe the code... */
8890 d = unsafeIRDirty_0_N (0, "s390x_dirtyhelper_EX", &s390x_dirtyhelper_EX,
8891 mkIRExprVec_1(load(Ity_I64, mkexpr(addr2))));
8892 stmt(IRStmt_Dirty(d));
8893 /* and restart */
florian428dfdd2012-03-27 03:09:49 +00008894 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TISTART),
8895 mkU64(guest_IA_curr_instr)));
8896 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TILEN), mkU64(4)));
florian8844a632012-04-13 04:04:06 +00008897 stmt(IRStmt_Exit(IRExpr_Const(IRConst_U1(True)), Ijk_TInval,
8898 IRConst_U64(guest_IA_curr_instr),
8899 S390X_GUEST_OFFSET(guest_IA)));
sewardj2019a972011-03-07 16:04:07 +00008900 /* we know that this will be invalidated */
florianf9e1ed72012-04-17 02:41:56 +00008901 put_IA(mkaddr_expr(guest_IA_next_instr));
sewardj2019a972011-03-07 16:04:07 +00008902 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +00008903 dis_res->jk_StopHere = Ijk_TInval;
sewardj2019a972011-03-07 16:04:07 +00008904 break;
8905 }
8906
8907 case 0xd200000000000000ULL:
8908 /* special case MVC */
8909 s390_irgen_EX_SS(r1, addr2, s390_irgen_MVC_EX, 64);
8910 return "mvc via ex";
8911
8912 case 0xd500000000000000ULL:
8913 /* special case CLC */
8914 s390_irgen_EX_SS(r1, addr2, s390_irgen_CLC_EX, 64);
8915 return "clc via ex";
8916
8917 case 0xd700000000000000ULL:
8918 /* special case XC */
8919 s390_irgen_EX_SS(r1, addr2, s390_irgen_XC_EX, 32);
8920 return "xc via ex";
8921
florianb0bf6602012-05-05 00:01:16 +00008922 case 0xd600000000000000ULL:
8923 /* special case OC */
8924 s390_irgen_EX_SS(r1, addr2, s390_irgen_OC_EX, 32);
8925 return "oc via ex";
8926
8927 case 0xd400000000000000ULL:
8928 /* special case NC */
8929 s390_irgen_EX_SS(r1, addr2, s390_irgen_NC_EX, 32);
8930 return "nc via ex";
sewardj2019a972011-03-07 16:04:07 +00008931
florianf87d4fb2012-05-05 02:55:24 +00008932 case 0xdc00000000000000ULL:
8933 /* special case TR */
8934 s390_irgen_EX_SS(r1, addr2, s390_irgen_TR_EX, 64);
8935 return "tr via ex";
8936
sewardj2019a972011-03-07 16:04:07 +00008937 default:
8938 {
8939 /* everything else will get a self checking prefix that also checks the
8940 register content */
8941 IRDirty *d;
8942 UChar *bytes;
8943 IRTemp cond;
8944 IRTemp orperand;
8945 IRTemp torun;
8946
8947 cond = newTemp(Ity_I1);
8948 orperand = newTemp(Ity_I64);
8949 torun = newTemp(Ity_I64);
8950
8951 if (r1 == 0)
8952 assign(orperand, mkU64(0));
8953 else
8954 assign(orperand, unop(Iop_8Uto64,get_gpr_b7(r1)));
8955 /* This code is going to be translated */
8956 assign(torun, binop(Iop_Or64, load(Ity_I64, mkexpr(addr2)),
8957 binop(Iop_Shl64, mkexpr(orperand), mkU8(48))));
8958
8959 /* Start with a check that saved code is still correct */
8960 assign(cond, binop(Iop_CmpNE64, mkexpr(torun),
8961 mkU64(last_execute_target)));
8962 /* If not, save the new value */
8963 d = unsafeIRDirty_0_N (0, "s390x_dirtyhelper_EX", &s390x_dirtyhelper_EX,
8964 mkIRExprVec_1(mkexpr(torun)));
8965 d->guard = mkexpr(cond);
8966 stmt(IRStmt_Dirty(d));
8967
8968 /* and restart */
florian428dfdd2012-03-27 03:09:49 +00008969 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TISTART), mkU64(guest_IA_curr_instr)));
8970 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TILEN), mkU64(4)));
florian8844a632012-04-13 04:04:06 +00008971 stmt(IRStmt_Exit(mkexpr(cond), Ijk_TInval,
8972 IRConst_U64(guest_IA_curr_instr),
8973 S390X_GUEST_OFFSET(guest_IA)));
sewardj2019a972011-03-07 16:04:07 +00008974
8975 /* Now comes the actual translation */
8976 bytes = (UChar *) &last_execute_target;
8977 s390_decode_and_irgen(bytes, ((((bytes[0] >> 6) + 1) >> 1) + 1) << 1,
8978 dis_res);
sewardj7ee97522011-05-09 21:45:04 +00008979 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00008980 vex_printf(" which was executed by\n");
8981 /* dont make useless translations in the next execute */
8982 last_execute_target = 0;
florianf9e1ed72012-04-17 02:41:56 +00008983 dummy_put_IA();
sewardj2019a972011-03-07 16:04:07 +00008984 }
8985 }
8986 return "ex";
8987}
8988
8989static HChar *
8990s390_irgen_EXRL(UChar r1, UInt offset)
8991{
8992 IRTemp addr = newTemp(Ity_I64);
8993 /* we might save one round trip because we know the target */
8994 if (!last_execute_target)
8995 last_execute_target = *(ULong *)(HWord)
8996 (guest_IA_curr_instr + offset * 2UL);
8997 assign(addr, mkU64(guest_IA_curr_instr + offset * 2UL));
8998 s390_irgen_EX(r1, addr);
8999 return "exrl";
9000}
9001
9002static HChar *
9003s390_irgen_IPM(UChar r1)
9004{
9005 // As long as we dont support SPM, lets just assume 0 as program mask
9006 put_gpr_b4(r1, unop(Iop_32to8, binop(Iop_Or32, mkU32(0 /* program mask */),
9007 binop(Iop_Shl32, s390_call_calculate_cc(), mkU8(4)))));
9008
9009 return "ipm";
9010}
9011
9012
9013static HChar *
9014s390_irgen_SRST(UChar r1, UChar r2)
9015{
9016 IRTemp address = newTemp(Ity_I64);
9017 IRTemp next = newTemp(Ity_I64);
9018 IRTemp delim = newTemp(Ity_I8);
9019 IRTemp counter = newTemp(Ity_I64);
9020 IRTemp byte = newTemp(Ity_I8);
9021
9022 assign(address, get_gpr_dw0(r2));
9023 assign(next, get_gpr_dw0(r1));
9024
9025 assign(counter, get_counter_dw0());
9026 put_counter_dw0(mkU64(0));
9027
9028 // start = next? CC=2 and out r1 and r2 unchanged
9029 s390_cc_set(2);
9030 put_gpr_dw0(r2, binop(Iop_Sub64, mkexpr(address), mkexpr(counter)));
9031 if_condition_goto(binop(Iop_CmpEQ64, mkexpr(address), mkexpr(next)),
9032 guest_IA_next_instr);
9033
9034 assign(byte, load(Ity_I8, mkexpr(address)));
9035 assign(delim, get_gpr_b7(0));
9036
9037 // byte = delim? CC=1, R1=address
9038 s390_cc_set(1);
9039 put_gpr_dw0(r1, mkexpr(address));
9040 if_condition_goto(binop(Iop_CmpEQ8, mkexpr(delim), mkexpr(byte)),
9041 guest_IA_next_instr);
9042
9043 // else: all equal, no end yet, loop
9044 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
9045 put_gpr_dw0(r1, mkexpr(next));
9046 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(address), mkU64(1)));
florian8844a632012-04-13 04:04:06 +00009047 stmt(IRStmt_Exit(binop(Iop_CmpNE64, mkexpr(counter), mkU64(255)),
9048 Ijk_Boring, IRConst_U64(guest_IA_curr_instr),
9049 S390X_GUEST_OFFSET(guest_IA)));
sewardj2019a972011-03-07 16:04:07 +00009050 // >= 256 bytes done CC=3
9051 s390_cc_set(3);
9052 put_counter_dw0(mkU64(0));
florian8844a632012-04-13 04:04:06 +00009053 dummy_put_IA();
sewardj2019a972011-03-07 16:04:07 +00009054
9055 return "srst";
9056}
9057
9058static HChar *
9059s390_irgen_CLST(UChar r1, UChar r2)
9060{
9061 IRTemp address1 = newTemp(Ity_I64);
9062 IRTemp address2 = newTemp(Ity_I64);
9063 IRTemp end = newTemp(Ity_I8);
9064 IRTemp counter = newTemp(Ity_I64);
9065 IRTemp byte1 = newTemp(Ity_I8);
9066 IRTemp byte2 = newTemp(Ity_I8);
9067
9068 assign(address1, get_gpr_dw0(r1));
9069 assign(address2, get_gpr_dw0(r2));
9070 assign(end, get_gpr_b7(0));
9071 assign(counter, get_counter_dw0());
9072 put_counter_dw0(mkU64(0));
9073 assign(byte1, load(Ity_I8, mkexpr(address1)));
9074 assign(byte2, load(Ity_I8, mkexpr(address2)));
9075
9076 // end in both? all equal, reset r1 and r2 to start values
9077 s390_cc_set(0);
9078 put_gpr_dw0(r1, binop(Iop_Sub64, mkexpr(address1), mkexpr(counter)));
9079 put_gpr_dw0(r2, binop(Iop_Sub64, mkexpr(address2), mkexpr(counter)));
9080 if_condition_goto(binop(Iop_CmpEQ8, mkU8(0),
9081 binop(Iop_Or8,
9082 binop(Iop_Xor8, mkexpr(byte1), mkexpr(end)),
9083 binop(Iop_Xor8, mkexpr(byte2), mkexpr(end)))),
9084 guest_IA_next_instr);
9085
9086 put_gpr_dw0(r1, mkexpr(address1));
9087 put_gpr_dw0(r2, mkexpr(address2));
9088
9089 // End found in string1
9090 s390_cc_set(1);
9091 if_condition_goto(binop(Iop_CmpEQ8, mkexpr(end), mkexpr(byte1)),
9092 guest_IA_next_instr);
9093
9094 // End found in string2
9095 s390_cc_set(2);
9096 if_condition_goto(binop(Iop_CmpEQ8, mkexpr(end), mkexpr(byte2)),
9097 guest_IA_next_instr);
9098
9099 // string1 < string2
9100 s390_cc_set(1);
9101 if_condition_goto(binop(Iop_CmpLT32U, unop(Iop_8Uto32, mkexpr(byte1)),
9102 unop(Iop_8Uto32, mkexpr(byte2))),
9103 guest_IA_next_instr);
9104
9105 // string2 < string1
9106 s390_cc_set(2);
9107 if_condition_goto(binop(Iop_CmpLT32U, unop(Iop_8Uto32, mkexpr(byte2)),
9108 unop(Iop_8Uto32, mkexpr(byte1))),
9109 guest_IA_next_instr);
9110
9111 // else: all equal, no end yet, loop
9112 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
9113 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), mkU64(1)));
9114 put_gpr_dw0(r2, binop(Iop_Add64, get_gpr_dw0(r2), mkU64(1)));
florian8844a632012-04-13 04:04:06 +00009115 stmt(IRStmt_Exit(binop(Iop_CmpNE64, mkexpr(counter), mkU64(255)),
9116 Ijk_Boring, IRConst_U64(guest_IA_curr_instr),
9117 S390X_GUEST_OFFSET(guest_IA)));
sewardj2019a972011-03-07 16:04:07 +00009118 // >= 256 bytes done CC=3
9119 s390_cc_set(3);
9120 put_counter_dw0(mkU64(0));
florian8844a632012-04-13 04:04:06 +00009121 dummy_put_IA();
sewardj2019a972011-03-07 16:04:07 +00009122
9123 return "clst";
9124}
9125
9126static void
9127s390_irgen_load_multiple_32bit(UChar r1, UChar r3, IRTemp op2addr)
9128{
9129 UChar reg;
9130 IRTemp addr = newTemp(Ity_I64);
9131
9132 assign(addr, mkexpr(op2addr));
9133 reg = r1;
9134 do {
9135 IRTemp old = addr;
9136
9137 reg %= 16;
9138 put_gpr_w1(reg, load(Ity_I32, mkexpr(addr)));
9139 addr = newTemp(Ity_I64);
9140 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
9141 reg++;
9142 } while (reg != (r3 + 1));
9143}
9144
9145static HChar *
9146s390_irgen_LM(UChar r1, UChar r3, IRTemp op2addr)
9147{
9148 s390_irgen_load_multiple_32bit(r1, r3, op2addr);
9149
9150 return "lm";
9151}
9152
9153static HChar *
9154s390_irgen_LMY(UChar r1, UChar r3, IRTemp op2addr)
9155{
9156 s390_irgen_load_multiple_32bit(r1, r3, op2addr);
9157
9158 return "lmy";
9159}
9160
9161static HChar *
9162s390_irgen_LMH(UChar r1, UChar r3, IRTemp op2addr)
9163{
9164 UChar reg;
9165 IRTemp addr = newTemp(Ity_I64);
9166
9167 assign(addr, mkexpr(op2addr));
9168 reg = r1;
9169 do {
9170 IRTemp old = addr;
9171
9172 reg %= 16;
9173 put_gpr_w0(reg, load(Ity_I32, mkexpr(addr)));
9174 addr = newTemp(Ity_I64);
9175 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
9176 reg++;
9177 } while (reg != (r3 + 1));
9178
9179 return "lmh";
9180}
9181
9182static HChar *
9183s390_irgen_LMG(UChar r1, UChar r3, IRTemp op2addr)
9184{
9185 UChar reg;
9186 IRTemp addr = newTemp(Ity_I64);
9187
9188 assign(addr, mkexpr(op2addr));
9189 reg = r1;
9190 do {
9191 IRTemp old = addr;
9192
9193 reg %= 16;
9194 put_gpr_dw0(reg, load(Ity_I64, mkexpr(addr)));
9195 addr = newTemp(Ity_I64);
9196 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(8)));
9197 reg++;
9198 } while (reg != (r3 + 1));
9199
9200 return "lmg";
9201}
9202
9203static void
9204s390_irgen_store_multiple_32bit(UChar r1, UChar r3, IRTemp op2addr)
9205{
9206 UChar reg;
9207 IRTemp addr = newTemp(Ity_I64);
9208
9209 assign(addr, mkexpr(op2addr));
9210 reg = r1;
9211 do {
9212 IRTemp old = addr;
9213
9214 reg %= 16;
9215 store(mkexpr(addr), get_gpr_w1(reg));
9216 addr = newTemp(Ity_I64);
9217 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
9218 reg++;
9219 } while( reg != (r3 + 1));
9220}
9221
9222static HChar *
9223s390_irgen_STM(UChar r1, UChar r3, IRTemp op2addr)
9224{
9225 s390_irgen_store_multiple_32bit(r1, r3, op2addr);
9226
9227 return "stm";
9228}
9229
9230static HChar *
9231s390_irgen_STMY(UChar r1, UChar r3, IRTemp op2addr)
9232{
9233 s390_irgen_store_multiple_32bit(r1, r3, op2addr);
9234
9235 return "stmy";
9236}
9237
9238static HChar *
9239s390_irgen_STMH(UChar r1, UChar r3, IRTemp op2addr)
9240{
9241 UChar reg;
9242 IRTemp addr = newTemp(Ity_I64);
9243
9244 assign(addr, mkexpr(op2addr));
9245 reg = r1;
9246 do {
9247 IRTemp old = addr;
9248
9249 reg %= 16;
9250 store(mkexpr(addr), get_gpr_w0(reg));
9251 addr = newTemp(Ity_I64);
9252 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
9253 reg++;
9254 } while( reg != (r3 + 1));
9255
9256 return "stmh";
9257}
9258
9259static HChar *
9260s390_irgen_STMG(UChar r1, UChar r3, IRTemp op2addr)
9261{
9262 UChar reg;
9263 IRTemp addr = newTemp(Ity_I64);
9264
9265 assign(addr, mkexpr(op2addr));
9266 reg = r1;
9267 do {
9268 IRTemp old = addr;
9269
9270 reg %= 16;
9271 store(mkexpr(addr), get_gpr_dw0(reg));
9272 addr = newTemp(Ity_I64);
9273 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(8)));
9274 reg++;
9275 } while( reg != (r3 + 1));
9276
9277 return "stmg";
9278}
9279
9280static void
florianb0bf6602012-05-05 00:01:16 +00009281s390_irgen_xonc(IROp op, IRTemp length, IRTemp start1, IRTemp start2)
sewardj2019a972011-03-07 16:04:07 +00009282{
9283 IRTemp old1 = newTemp(Ity_I8);
9284 IRTemp old2 = newTemp(Ity_I8);
9285 IRTemp new1 = newTemp(Ity_I8);
9286 IRTemp counter = newTemp(Ity_I32);
9287 IRTemp addr1 = newTemp(Ity_I64);
9288
9289 assign(counter, get_counter_w0());
9290
9291 assign(addr1, binop(Iop_Add64, mkexpr(start1),
9292 unop(Iop_32Uto64, mkexpr(counter))));
9293
9294 assign(old1, load(Ity_I8, mkexpr(addr1)));
9295 assign(old2, load(Ity_I8, binop(Iop_Add64, mkexpr(start2),
9296 unop(Iop_32Uto64,mkexpr(counter)))));
9297 assign(new1, binop(op, mkexpr(old1), mkexpr(old2)));
9298
9299 /* Special case: xc is used to zero memory */
sewardj2019a972011-03-07 16:04:07 +00009300 if (op == Iop_Xor8) {
9301 store(mkexpr(addr1),
florian6ad49522011-09-09 02:38:55 +00009302 mkite(binop(Iop_CmpEQ64, mkexpr(start1), mkexpr(start2)),
9303 mkU8(0), mkexpr(new1)));
sewardj2019a972011-03-07 16:04:07 +00009304 } else
9305 store(mkexpr(addr1), mkexpr(new1));
9306 put_counter_w1(binop(Iop_Or32, unop(Iop_8Uto32, mkexpr(new1)),
9307 get_counter_w1()));
9308
9309 /* Check for end of field */
9310 put_counter_w0(binop(Iop_Add32, mkexpr(counter), mkU32(1)));
florianb0bf6602012-05-05 00:01:16 +00009311 if_condition_goto(binop(Iop_CmpNE32, mkexpr(counter), mkexpr(length)),
sewardj2019a972011-03-07 16:04:07 +00009312 guest_IA_curr_instr);
9313 s390_cc_thunk_put1(S390_CC_OP_BITWISE, mktemp(Ity_I32, get_counter_w1()),
9314 False);
9315 put_counter_dw0(mkU64(0));
9316}
9317
9318static HChar *
9319s390_irgen_XC(UChar length, IRTemp start1, IRTemp start2)
9320{
florianb0bf6602012-05-05 00:01:16 +00009321 IRTemp len = newTemp(Ity_I32);
9322
9323 assign(len, mkU32(length));
9324 s390_irgen_xonc(Iop_Xor8, len, start1, start2);
florian79e839e2012-05-05 02:20:30 +00009325 dummy_put_IA();
sewardj2019a972011-03-07 16:04:07 +00009326
9327 return "xc";
9328}
9329
sewardjb63967e2011-03-24 08:50:04 +00009330static void
9331s390_irgen_XC_sameloc(UChar length, UChar b, UShort d)
9332{
9333 IRTemp counter = newTemp(Ity_I32);
9334 IRTemp start = newTemp(Ity_I64);
9335 IRTemp addr = newTemp(Ity_I64);
9336
9337 assign(start,
9338 binop(Iop_Add64, mkU64(d), b != 0 ? get_gpr_dw0(b) : mkU64(0)));
9339
9340 if (length < 8) {
9341 UInt i;
9342
9343 for (i = 0; i <= length; ++i) {
9344 store(binop(Iop_Add64, mkexpr(start), mkU64(i)), mkU8(0));
9345 }
9346 } else {
9347 assign(counter, get_counter_w0());
9348
9349 assign(addr, binop(Iop_Add64, mkexpr(start),
9350 unop(Iop_32Uto64, mkexpr(counter))));
9351
9352 store(mkexpr(addr), mkU8(0));
9353
9354 /* Check for end of field */
9355 put_counter_w0(binop(Iop_Add32, mkexpr(counter), mkU32(1)));
9356 if_condition_goto(binop(Iop_CmpNE32, mkexpr(counter), mkU32(length)),
9357 guest_IA_curr_instr);
9358
9359 /* Reset counter */
9360 put_counter_dw0(mkU64(0));
9361 }
9362
9363 s390_cc_thunk_put1(S390_CC_OP_BITWISE, mktemp(Ity_I32, mkU32(0)), False);
florianf9e1ed72012-04-17 02:41:56 +00009364 dummy_put_IA();
sewardjb63967e2011-03-24 08:50:04 +00009365
sewardj7ee97522011-05-09 21:45:04 +00009366 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardjb63967e2011-03-24 08:50:04 +00009367 s390_disasm(ENC3(MNM, UDLB, UDXB), "xc", d, length, b, d, 0, b);
9368}
9369
sewardj2019a972011-03-07 16:04:07 +00009370static HChar *
9371s390_irgen_NC(UChar length, IRTemp start1, IRTemp start2)
9372{
florianb0bf6602012-05-05 00:01:16 +00009373 IRTemp len = newTemp(Ity_I32);
9374
9375 assign(len, mkU32(length));
9376 s390_irgen_xonc(Iop_And8, len, start1, start2);
florian79e839e2012-05-05 02:20:30 +00009377 dummy_put_IA();
sewardj2019a972011-03-07 16:04:07 +00009378
9379 return "nc";
9380}
9381
9382static HChar *
9383s390_irgen_OC(UChar length, IRTemp start1, IRTemp start2)
9384{
florianb0bf6602012-05-05 00:01:16 +00009385 IRTemp len = newTemp(Ity_I32);
9386
9387 assign(len, mkU32(length));
9388 s390_irgen_xonc(Iop_Or8, len, start1, start2);
florian79e839e2012-05-05 02:20:30 +00009389 dummy_put_IA();
sewardj2019a972011-03-07 16:04:07 +00009390
9391 return "oc";
9392}
9393
9394
9395static HChar *
9396s390_irgen_MVC(UChar length, IRTemp start1, IRTemp start2)
9397{
florian79e839e2012-05-05 02:20:30 +00009398 IRTemp len = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00009399
florian79e839e2012-05-05 02:20:30 +00009400 assign(len, mkU64(length));
9401 s390_irgen_MVC_EX(len, start1, start2);
florian8844a632012-04-13 04:04:06 +00009402 dummy_put_IA();
sewardj2019a972011-03-07 16:04:07 +00009403
9404 return "mvc";
9405}
9406
9407static HChar *
florianb0c9a132011-09-08 15:37:39 +00009408s390_irgen_MVCL(UChar r1, UChar r2)
9409{
9410 IRTemp addr1 = newTemp(Ity_I64);
9411 IRTemp addr2 = newTemp(Ity_I64);
9412 IRTemp addr2_load = newTemp(Ity_I64);
9413 IRTemp r1p1 = newTemp(Ity_I32); /* contents of r1 + 1 */
9414 IRTemp r2p1 = newTemp(Ity_I32); /* contents of r2 + 1 */
9415 IRTemp len1 = newTemp(Ity_I32);
9416 IRTemp len2 = newTemp(Ity_I32);
9417 IRTemp pad = newTemp(Ity_I8);
9418 IRTemp single = newTemp(Ity_I8);
9419
9420 assign(addr1, get_gpr_dw0(r1));
9421 assign(r1p1, get_gpr_w1(r1 + 1));
9422 assign(len1, binop(Iop_And32, mkexpr(r1p1), mkU32(0x00ffffff)));
9423 assign(addr2, get_gpr_dw0(r2));
9424 assign(r2p1, get_gpr_w1(r2 + 1));
9425 assign(len2, binop(Iop_And32, mkexpr(r2p1), mkU32(0x00ffffff)));
9426 assign(pad, get_gpr_b4(r2 + 1));
9427
9428 /* len1 == 0 ? */
9429 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len2, False);
9430 if_condition_goto(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
9431 guest_IA_next_instr);
9432
9433 /* Check for destructive overlap:
9434 addr1 > addr2 && addr2 + len1 > addr1 && (addr2 + len2) > addr1 */
9435 s390_cc_set(3);
9436 IRTemp cond1 = newTemp(Ity_I32);
9437 assign(cond1, unop(Iop_1Uto32,
9438 binop(Iop_CmpLT64U, mkexpr(addr2), mkexpr(addr1))));
9439 IRTemp cond2 = newTemp(Ity_I32);
9440 assign(cond2, unop(Iop_1Uto32,
9441 binop(Iop_CmpLT64U, mkexpr(addr1),
9442 binop(Iop_Add64, mkexpr(addr2),
9443 unop(Iop_32Uto64, mkexpr(len1))))));
9444 IRTemp cond3 = newTemp(Ity_I32);
9445 assign(cond3, unop(Iop_1Uto32,
9446 binop(Iop_CmpLT64U,
9447 mkexpr(addr1),
9448 binop(Iop_Add64, mkexpr(addr2),
9449 unop(Iop_32Uto64, mkexpr(len2))))));
9450
9451 if_condition_goto(binop(Iop_CmpEQ32,
9452 binop(Iop_And32,
9453 binop(Iop_And32, mkexpr(cond1), mkexpr(cond2)),
9454 mkexpr(cond3)),
9455 mkU32(1)),
9456 guest_IA_next_instr);
9457
9458 /* See s390_irgen_CLCL for explanation why we cannot load directly
9459 and need two steps. */
9460 assign(addr2_load,
9461 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
9462 mkU64(guest_IA_curr_instr), mkexpr(addr2)));
9463 assign(single,
9464 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
9465 mkexpr(pad), load(Ity_I8, mkexpr(addr2_load))));
9466
9467 store(mkexpr(addr1), mkexpr(single));
9468
9469 /* Update addr1 and len1 */
9470 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkU64(1)));
9471 put_gpr_w1(r1 + 1, binop(Iop_Sub32, mkexpr(r1p1), mkU32(1)));
9472
9473 /* Update addr2 and len2 */
9474 put_gpr_dw0(r2,
9475 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
9476 mkexpr(addr2),
9477 binop(Iop_Add64, mkexpr(addr2), mkU64(1))));
9478
9479 /* When updating len2 we must not modify bits (r2+1)[0:39] */
9480 put_gpr_w1(r2 + 1,
9481 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
9482 binop(Iop_And32, mkexpr(r2p1), mkU32(0xFF000000u)),
9483 binop(Iop_Sub32, mkexpr(r2p1), mkU32(1))));
9484
9485 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len2, False);
9486 if_condition_goto(binop(Iop_CmpNE32, mkexpr(len1), mkU32(1)),
9487 guest_IA_curr_instr);
9488
9489 return "mvcl";
9490}
9491
9492
9493static HChar *
sewardj2019a972011-03-07 16:04:07 +00009494s390_irgen_MVCLE(UChar r1, UChar r3, IRTemp pad2)
9495{
9496 IRTemp addr1, addr3, addr3_load, len1, len3, single;
9497
9498 addr1 = newTemp(Ity_I64);
9499 addr3 = newTemp(Ity_I64);
9500 addr3_load = newTemp(Ity_I64);
9501 len1 = newTemp(Ity_I64);
9502 len3 = newTemp(Ity_I64);
9503 single = newTemp(Ity_I8);
9504
9505 assign(addr1, get_gpr_dw0(r1));
9506 assign(len1, get_gpr_dw0(r1 + 1));
9507 assign(addr3, get_gpr_dw0(r3));
9508 assign(len3, get_gpr_dw0(r3 + 1));
9509
9510 // len1 == 0 ?
9511 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len3, False);
9512 if_condition_goto(binop(Iop_CmpEQ64,mkexpr(len1), mkU64(0)),
9513 guest_IA_next_instr);
9514
9515 /* This is a hack to prevent mvcle from reading from addr3 if it
9516 should read from the pad. Since the pad has no address, just
9517 read from the instruction, we discard that anyway */
9518 assign(addr3_load,
florian6ad49522011-09-09 02:38:55 +00009519 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
9520 mkU64(guest_IA_curr_instr), mkexpr(addr3)));
sewardj2019a972011-03-07 16:04:07 +00009521
9522 assign(single,
florian6ad49522011-09-09 02:38:55 +00009523 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
9524 unop(Iop_64to8, mkexpr(pad2)),
9525 load(Ity_I8, mkexpr(addr3_load))));
sewardj2019a972011-03-07 16:04:07 +00009526 store(mkexpr(addr1), mkexpr(single));
9527
9528 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkU64(1)));
9529
9530 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkU64(1)));
9531
9532 put_gpr_dw0(r3,
florian6ad49522011-09-09 02:38:55 +00009533 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
9534 mkexpr(addr3),
9535 binop(Iop_Add64, mkexpr(addr3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +00009536
9537 put_gpr_dw0(r3 + 1,
florian6ad49522011-09-09 02:38:55 +00009538 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
9539 mkU64(0), binop(Iop_Sub64, mkexpr(len3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +00009540
9541 /* We should set CC=3 (faked by overflow add) and leave after
9542 a maximum of ~4096 bytes have been processed. This is simpler:
9543 we leave whenever (len1 % 4096) == 0 */
9544 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_ADD_64, mktemp(Ity_I64, mkU64(-1ULL)),
sewardj2019a972011-03-07 16:04:07 +00009545 mktemp(Ity_I64, mkU64(-1ULL)), False);
9546 if_condition_goto(binop(Iop_CmpEQ64,
9547 binop(Iop_And64, mkexpr(len1), mkU64(0xfff)),
9548 mkU64(0)),
9549 guest_IA_next_instr);
9550
9551 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len3, False);
9552 if_condition_goto(binop(Iop_CmpNE64, mkexpr(len1), mkU64(1)),
9553 guest_IA_curr_instr);
9554
9555 return "mvcle";
9556}
9557
9558static HChar *
9559s390_irgen_MVST(UChar r1, UChar r2)
9560{
9561 IRTemp addr1 = newTemp(Ity_I64);
9562 IRTemp addr2 = newTemp(Ity_I64);
9563 IRTemp end = newTemp(Ity_I8);
9564 IRTemp byte = newTemp(Ity_I8);
9565 IRTemp counter = newTemp(Ity_I64);
9566
9567 assign(addr1, get_gpr_dw0(r1));
9568 assign(addr2, get_gpr_dw0(r2));
9569 assign(counter, get_counter_dw0());
9570 assign(end, get_gpr_b7(0));
9571 assign(byte, load(Ity_I8, binop(Iop_Add64, mkexpr(addr2),mkexpr(counter))));
9572 store(binop(Iop_Add64,mkexpr(addr1),mkexpr(counter)), mkexpr(byte));
9573
9574 // We use unlimited as cpu-determined number
9575 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
9576 if_condition_goto(binop(Iop_CmpNE8, mkexpr(end), mkexpr(byte)),
9577 guest_IA_curr_instr);
9578
9579 // and always set cc=1 at the end + update r1
9580 s390_cc_set(1);
9581 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(counter)));
9582 put_counter_dw0(mkU64(0));
florian8844a632012-04-13 04:04:06 +00009583 dummy_put_IA();
sewardj2019a972011-03-07 16:04:07 +00009584
9585 return "mvst";
9586}
9587
9588static void
9589s390_irgen_divide_64to32(IROp op, UChar r1, IRTemp op2)
9590{
9591 IRTemp op1 = newTemp(Ity_I64);
9592 IRTemp result = newTemp(Ity_I64);
9593
9594 assign(op1, binop(Iop_32HLto64,
9595 get_gpr_w1(r1), // high 32 bits
9596 get_gpr_w1(r1 + 1))); // low 32 bits
9597 assign(result, binop(op, mkexpr(op1), mkexpr(op2)));
9598 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result))); // remainder
9599 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result))); // quotient
9600}
9601
9602static void
9603s390_irgen_divide_128to64(IROp op, UChar r1, IRTemp op2)
9604{
9605 IRTemp op1 = newTemp(Ity_I128);
9606 IRTemp result = newTemp(Ity_I128);
9607
9608 assign(op1, binop(Iop_64HLto128,
9609 get_gpr_dw0(r1), // high 64 bits
9610 get_gpr_dw0(r1 + 1))); // low 64 bits
9611 assign(result, binop(op, mkexpr(op1), mkexpr(op2)));
9612 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result))); // remainder
9613 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result))); // quotient
9614}
9615
9616static void
9617s390_irgen_divide_64to64(IROp op, UChar r1, IRTemp op2)
9618{
9619 IRTemp op1 = newTemp(Ity_I64);
9620 IRTemp result = newTemp(Ity_I128);
9621
9622 assign(op1, get_gpr_dw0(r1 + 1));
9623 assign(result, binop(op, mkexpr(op1), mkexpr(op2)));
9624 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result))); // remainder
9625 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result))); // quotient
9626}
9627
9628static HChar *
9629s390_irgen_DR(UChar r1, UChar r2)
9630{
9631 IRTemp op2 = newTemp(Ity_I32);
9632
9633 assign(op2, get_gpr_w1(r2));
9634
9635 s390_irgen_divide_64to32(Iop_DivModS64to32, r1, op2);
9636
9637 return "dr";
9638}
9639
9640static HChar *
9641s390_irgen_D(UChar r1, IRTemp op2addr)
9642{
9643 IRTemp op2 = newTemp(Ity_I32);
9644
9645 assign(op2, load(Ity_I32, mkexpr(op2addr)));
9646
9647 s390_irgen_divide_64to32(Iop_DivModS64to32, r1, op2);
9648
9649 return "d";
9650}
9651
9652static HChar *
9653s390_irgen_DLR(UChar r1, UChar r2)
9654{
9655 IRTemp op2 = newTemp(Ity_I32);
9656
9657 assign(op2, get_gpr_w1(r2));
9658
9659 s390_irgen_divide_64to32(Iop_DivModU64to32, r1, op2);
9660
9661 return "dr";
9662}
9663
9664static HChar *
9665s390_irgen_DL(UChar r1, IRTemp op2addr)
9666{
9667 IRTemp op2 = newTemp(Ity_I32);
9668
9669 assign(op2, load(Ity_I32, mkexpr(op2addr)));
9670
9671 s390_irgen_divide_64to32(Iop_DivModU64to32, r1, op2);
9672
9673 return "dl";
9674}
9675
9676static HChar *
9677s390_irgen_DLG(UChar r1, IRTemp op2addr)
9678{
9679 IRTemp op2 = newTemp(Ity_I64);
9680
9681 assign(op2, load(Ity_I64, mkexpr(op2addr)));
9682
9683 s390_irgen_divide_128to64(Iop_DivModU128to64, r1, op2);
9684
9685 return "dlg";
9686}
9687
9688static HChar *
9689s390_irgen_DLGR(UChar r1, UChar r2)
9690{
9691 IRTemp op2 = newTemp(Ity_I64);
9692
9693 assign(op2, get_gpr_dw0(r2));
9694
9695 s390_irgen_divide_128to64(Iop_DivModU128to64, r1, op2);
9696
9697 return "dlgr";
9698}
9699
9700static HChar *
9701s390_irgen_DSGR(UChar r1, UChar r2)
9702{
9703 IRTemp op2 = newTemp(Ity_I64);
9704
9705 assign(op2, get_gpr_dw0(r2));
9706
9707 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
9708
9709 return "dsgr";
9710}
9711
9712static HChar *
9713s390_irgen_DSG(UChar r1, IRTemp op2addr)
9714{
9715 IRTemp op2 = newTemp(Ity_I64);
9716
9717 assign(op2, load(Ity_I64, mkexpr(op2addr)));
9718
9719 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
9720
9721 return "dsg";
9722}
9723
9724static HChar *
9725s390_irgen_DSGFR(UChar r1, UChar r2)
9726{
9727 IRTemp op2 = newTemp(Ity_I64);
9728
9729 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
9730
9731 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
9732
9733 return "dsgfr";
9734}
9735
9736static HChar *
9737s390_irgen_DSGF(UChar r1, IRTemp op2addr)
9738{
9739 IRTemp op2 = newTemp(Ity_I64);
9740
9741 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
9742
9743 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
9744
9745 return "dsgf";
9746}
9747
9748static void
9749s390_irgen_load_ar_multiple(UChar r1, UChar r3, IRTemp op2addr)
9750{
9751 UChar reg;
9752 IRTemp addr = newTemp(Ity_I64);
9753
9754 assign(addr, mkexpr(op2addr));
9755 reg = r1;
9756 do {
9757 IRTemp old = addr;
9758
9759 reg %= 16;
9760 put_ar_w0(reg, load(Ity_I32, mkexpr(addr)));
9761 addr = newTemp(Ity_I64);
9762 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
9763 reg++;
9764 } while (reg != (r3 + 1));
9765}
9766
9767static HChar *
9768s390_irgen_LAM(UChar r1, UChar r3, IRTemp op2addr)
9769{
9770 s390_irgen_load_ar_multiple(r1, r3, op2addr);
9771
9772 return "lam";
9773}
9774
9775static HChar *
9776s390_irgen_LAMY(UChar r1, UChar r3, IRTemp op2addr)
9777{
9778 s390_irgen_load_ar_multiple(r1, r3, op2addr);
9779
9780 return "lamy";
9781}
9782
9783static void
9784s390_irgen_store_ar_multiple(UChar r1, UChar r3, IRTemp op2addr)
9785{
9786 UChar reg;
9787 IRTemp addr = newTemp(Ity_I64);
9788
9789 assign(addr, mkexpr(op2addr));
9790 reg = r1;
9791 do {
9792 IRTemp old = addr;
9793
9794 reg %= 16;
9795 store(mkexpr(addr), get_ar_w0(reg));
9796 addr = newTemp(Ity_I64);
9797 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
9798 reg++;
9799 } while (reg != (r3 + 1));
9800}
9801
9802static HChar *
9803s390_irgen_STAM(UChar r1, UChar r3, IRTemp op2addr)
9804{
9805 s390_irgen_store_ar_multiple(r1, r3, op2addr);
9806
9807 return "stam";
9808}
9809
9810static HChar *
9811s390_irgen_STAMY(UChar r1, UChar r3, IRTemp op2addr)
9812{
9813 s390_irgen_store_ar_multiple(r1, r3, op2addr);
9814
9815 return "stamy";
9816}
9817
9818
9819/* Implementation for 32-bit compare-and-swap */
9820static void
9821s390_irgen_cas_32(UChar r1, UChar r3, IRTemp op2addr)
9822{
9823 IRCAS *cas;
9824 IRTemp op1 = newTemp(Ity_I32);
9825 IRTemp old_mem = newTemp(Ity_I32);
9826 IRTemp op3 = newTemp(Ity_I32);
9827 IRTemp result = newTemp(Ity_I32);
9828 IRTemp nequal = newTemp(Ity_I1);
9829
9830 assign(op1, get_gpr_w1(r1));
9831 assign(op3, get_gpr_w1(r3));
9832
9833 /* The first and second operands are compared. If they are equal,
9834 the third operand is stored at the second- operand location. */
9835 cas = mkIRCAS(IRTemp_INVALID, old_mem,
9836 Iend_BE, mkexpr(op2addr),
9837 NULL, mkexpr(op1), /* expected value */
9838 NULL, mkexpr(op3) /* new value */);
9839 stmt(IRStmt_CAS(cas));
9840
9841 /* Set CC. Operands compared equal -> 0, else 1. */
9842 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(old_mem)));
9843 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
9844
9845 /* If operands were equal (cc == 0) just store the old value op1 in r1.
9846 Otherwise, store the old_value from memory in r1 and yield. */
9847 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
9848 put_gpr_w1(r1, mkite(mkexpr(nequal), mkexpr(old_mem), mkexpr(op1)));
florian8844a632012-04-13 04:04:06 +00009849 stmt(IRStmt_Exit(mkexpr(nequal), Ijk_Yield,
9850 IRConst_U64(guest_IA_next_instr),
9851 S390X_GUEST_OFFSET(guest_IA)));
sewardj2019a972011-03-07 16:04:07 +00009852}
9853
9854static HChar *
9855s390_irgen_CS(UChar r1, UChar r3, IRTemp op2addr)
9856{
9857 s390_irgen_cas_32(r1, r3, op2addr);
9858
9859 return "cs";
9860}
9861
9862static HChar *
9863s390_irgen_CSY(UChar r1, UChar r3, IRTemp op2addr)
9864{
9865 s390_irgen_cas_32(r1, r3, op2addr);
9866
9867 return "csy";
9868}
9869
9870static HChar *
9871s390_irgen_CSG(UChar r1, UChar r3, IRTemp op2addr)
9872{
9873 IRCAS *cas;
9874 IRTemp op1 = newTemp(Ity_I64);
9875 IRTemp old_mem = newTemp(Ity_I64);
9876 IRTemp op3 = newTemp(Ity_I64);
9877 IRTemp result = newTemp(Ity_I64);
9878 IRTemp nequal = newTemp(Ity_I1);
9879
9880 assign(op1, get_gpr_dw0(r1));
9881 assign(op3, get_gpr_dw0(r3));
9882
9883 /* The first and second operands are compared. If they are equal,
9884 the third operand is stored at the second- operand location. */
9885 cas = mkIRCAS(IRTemp_INVALID, old_mem,
9886 Iend_BE, mkexpr(op2addr),
9887 NULL, mkexpr(op1), /* expected value */
9888 NULL, mkexpr(op3) /* new value */);
9889 stmt(IRStmt_CAS(cas));
9890
9891 /* Set CC. Operands compared equal -> 0, else 1. */
9892 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(old_mem)));
9893 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
9894
9895 /* If operands were equal (cc == 0) just store the old value op1 in r1.
9896 Otherwise, store the old_value from memory in r1 and yield. */
9897 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
9898 put_gpr_dw0(r1, mkite(mkexpr(nequal), mkexpr(old_mem), mkexpr(op1)));
florian8844a632012-04-13 04:04:06 +00009899 stmt(IRStmt_Exit(mkexpr(nequal), Ijk_Yield,
9900 IRConst_U64(guest_IA_next_instr),
9901 S390X_GUEST_OFFSET(guest_IA)));
sewardj2019a972011-03-07 16:04:07 +00009902
9903 return "csg";
9904}
9905
florian448cbba2012-06-06 02:26:01 +00009906/* Implementation for 32-bit compare-double-and-swap */
9907static void
9908s390_irgen_cdas_32(UChar r1, UChar r3, IRTemp op2addr)
9909{
9910 IRCAS *cas;
9911 IRTemp op1_high = newTemp(Ity_I32);
9912 IRTemp op1_low = newTemp(Ity_I32);
9913 IRTemp old_mem_high = newTemp(Ity_I32);
9914 IRTemp old_mem_low = newTemp(Ity_I32);
9915 IRTemp op3_high = newTemp(Ity_I32);
9916 IRTemp op3_low = newTemp(Ity_I32);
9917 IRTemp result = newTemp(Ity_I32);
9918 IRTemp nequal = newTemp(Ity_I1);
9919
9920 assign(op1_high, get_gpr_w1(r1));
9921 assign(op1_low, get_gpr_w1(r1+1));
9922 assign(op3_high, get_gpr_w1(r3));
9923 assign(op3_low, get_gpr_w1(r3+1));
9924
9925 /* The first and second operands are compared. If they are equal,
9926 the third operand is stored at the second-operand location. */
9927 cas = mkIRCAS(old_mem_high, old_mem_low,
9928 Iend_BE, mkexpr(op2addr),
9929 mkexpr(op1_high), mkexpr(op1_low), /* expected value */
9930 mkexpr(op3_high), mkexpr(op3_low) /* new value */);
9931 stmt(IRStmt_CAS(cas));
9932
9933 /* Set CC. Operands compared equal -> 0, else 1. */
9934 assign(result, unop(Iop_1Uto32,
9935 binop(Iop_CmpNE32,
9936 binop(Iop_Or32,
9937 binop(Iop_Xor32, mkexpr(op1_high), mkexpr(old_mem_high)),
9938 binop(Iop_Xor32, mkexpr(op1_low), mkexpr(old_mem_low))),
9939 mkU32(0))));
9940
9941 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
9942
9943 /* If operands were equal (cc == 0) just store the old value op1 in r1.
9944 Otherwise, store the old_value from memory in r1 and yield. */
9945 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
9946 put_gpr_w1(r1, mkite(mkexpr(nequal), mkexpr(old_mem_high), mkexpr(op1_high)));
9947 put_gpr_w1(r1+1, mkite(mkexpr(nequal), mkexpr(old_mem_low), mkexpr(op1_low)));
9948 stmt(IRStmt_Exit(mkexpr(nequal), Ijk_Yield,
9949 IRConst_U64(guest_IA_next_instr),
9950 S390X_GUEST_OFFSET(guest_IA)));
9951}
9952
9953static HChar *
9954s390_irgen_CDS(UChar r1, UChar r3, IRTemp op2addr)
9955{
9956 s390_irgen_cdas_32(r1, r3, op2addr);
9957
9958 return "cds";
9959}
9960
9961static HChar *
9962s390_irgen_CDSY(UChar r1, UChar r3, IRTemp op2addr)
9963{
9964 s390_irgen_cdas_32(r1, r3, op2addr);
9965
9966 return "cdsy";
9967}
9968
9969static HChar *
9970s390_irgen_CDSG(UChar r1, UChar r3, IRTemp op2addr)
9971{
9972 IRCAS *cas;
9973 IRTemp op1_high = newTemp(Ity_I64);
9974 IRTemp op1_low = newTemp(Ity_I64);
9975 IRTemp old_mem_high = newTemp(Ity_I64);
9976 IRTemp old_mem_low = newTemp(Ity_I64);
9977 IRTemp op3_high = newTemp(Ity_I64);
9978 IRTemp op3_low = newTemp(Ity_I64);
9979 IRTemp result = newTemp(Ity_I64);
9980 IRTemp nequal = newTemp(Ity_I1);
9981
9982 assign(op1_high, get_gpr_dw0(r1));
9983 assign(op1_low, get_gpr_dw0(r1+1));
9984 assign(op3_high, get_gpr_dw0(r3));
9985 assign(op3_low, get_gpr_dw0(r3+1));
9986
9987 /* The first and second operands are compared. If they are equal,
9988 the third operand is stored at the second-operand location. */
9989 cas = mkIRCAS(old_mem_high, old_mem_low,
9990 Iend_BE, mkexpr(op2addr),
9991 mkexpr(op1_high), mkexpr(op1_low), /* expected value */
9992 mkexpr(op3_high), mkexpr(op3_low) /* new value */);
9993 stmt(IRStmt_CAS(cas));
9994
9995 /* Set CC. Operands compared equal -> 0, else 1. */
9996 assign(result, unop(Iop_1Uto64,
9997 binop(Iop_CmpNE64,
9998 binop(Iop_Or64,
9999 binop(Iop_Xor64, mkexpr(op1_high), mkexpr(old_mem_high)),
10000 binop(Iop_Xor64, mkexpr(op1_low), mkexpr(old_mem_low))),
10001 mkU64(0))));
10002
10003 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
10004
10005 /* If operands were equal (cc == 0) just store the old value op1 in r1.
10006 Otherwise, store the old_value from memory in r1 and yield. */
10007 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
10008 put_gpr_dw0(r1, mkite(mkexpr(nequal), mkexpr(old_mem_high), mkexpr(op1_high)));
10009 put_gpr_dw0(r1+1, mkite(mkexpr(nequal), mkexpr(old_mem_low), mkexpr(op1_low)));
10010 stmt(IRStmt_Exit(mkexpr(nequal), Ijk_Yield,
10011 IRConst_U64(guest_IA_next_instr),
10012 S390X_GUEST_OFFSET(guest_IA)));
10013 return "cdsg";
10014}
10015
sewardj2019a972011-03-07 16:04:07 +000010016
10017/* Binary floating point */
10018
10019static HChar *
10020s390_irgen_AXBR(UChar r1, UChar r2)
10021{
10022 IRTemp op1 = newTemp(Ity_F128);
10023 IRTemp op2 = newTemp(Ity_F128);
10024 IRTemp result = newTemp(Ity_F128);
10025
10026 assign(op1, get_fpr_pair(r1));
10027 assign(op2, get_fpr_pair(r2));
10028 assign(result, triop(Iop_AddF128, mkU32(Irrm_NEAREST), mkexpr(op1),
10029 mkexpr(op2)));
10030 put_fpr_pair(r1, mkexpr(result));
10031
10032 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
10033
10034 return "axbr";
10035}
10036
10037/* The result of a Iop_CmdFxx operation is a condition code. It is
10038 encoded using the values defined in type IRCmpFxxResult.
10039 Before we can store the condition code into the guest state (or do
10040 anything else with it for that matter) we need to convert it to
10041 the encoding that s390 uses. This is what this function does.
10042
10043 s390 VEX b6 b2 b0 cc.1 cc.0
10044 0 0x40 EQ 1 0 0 0 0
10045 1 0x01 LT 0 0 1 0 1
10046 2 0x00 GT 0 0 0 1 0
10047 3 0x45 Unordered 1 1 1 1 1
10048
10049 The following bits from the VEX encoding are interesting:
10050 b0, b2, b6 with b0 being the LSB. We observe:
10051
10052 cc.0 = b0;
10053 cc.1 = b2 | (~b0 & ~b6)
10054
10055 with cc being the s390 condition code.
10056*/
10057static IRExpr *
10058convert_vex_fpcc_to_s390(IRTemp vex_cc)
10059{
10060 IRTemp cc0 = newTemp(Ity_I32);
10061 IRTemp cc1 = newTemp(Ity_I32);
10062 IRTemp b0 = newTemp(Ity_I32);
10063 IRTemp b2 = newTemp(Ity_I32);
10064 IRTemp b6 = newTemp(Ity_I32);
10065
10066 assign(b0, binop(Iop_And32, mkexpr(vex_cc), mkU32(1)));
10067 assign(b2, binop(Iop_And32, binop(Iop_Shr32, mkexpr(vex_cc), mkU8(2)),
10068 mkU32(1)));
10069 assign(b6, binop(Iop_And32, binop(Iop_Shr32, mkexpr(vex_cc), mkU8(6)),
10070 mkU32(1)));
10071
10072 assign(cc0, mkexpr(b0));
10073 assign(cc1, binop(Iop_Or32, mkexpr(b2),
10074 binop(Iop_And32,
10075 binop(Iop_Sub32, mkU32(1), mkexpr(b0)), /* ~b0 */
10076 binop(Iop_Sub32, mkU32(1), mkexpr(b6)) /* ~b6 */
10077 )));
10078
10079 return binop(Iop_Or32, mkexpr(cc0), binop(Iop_Shl32, mkexpr(cc1), mkU8(1)));
10080}
10081
10082static HChar *
10083s390_irgen_CEBR(UChar r1, UChar r2)
10084{
10085 IRTemp op1 = newTemp(Ity_F32);
10086 IRTemp op2 = newTemp(Ity_F32);
10087 IRTemp cc_vex = newTemp(Ity_I32);
10088 IRTemp cc_s390 = newTemp(Ity_I32);
10089
10090 assign(op1, get_fpr_w0(r1));
10091 assign(op2, get_fpr_w0(r2));
10092 assign(cc_vex, binop(Iop_CmpF32, mkexpr(op1), mkexpr(op2)));
10093
10094 assign(cc_s390, convert_vex_fpcc_to_s390(cc_vex));
10095 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
10096
10097 return "cebr";
10098}
10099
10100static HChar *
10101s390_irgen_CDBR(UChar r1, UChar r2)
10102{
10103 IRTemp op1 = newTemp(Ity_F64);
10104 IRTemp op2 = newTemp(Ity_F64);
10105 IRTemp cc_vex = newTemp(Ity_I32);
10106 IRTemp cc_s390 = newTemp(Ity_I32);
10107
10108 assign(op1, get_fpr_dw0(r1));
10109 assign(op2, get_fpr_dw0(r2));
10110 assign(cc_vex, binop(Iop_CmpF64, mkexpr(op1), mkexpr(op2)));
10111
10112 assign(cc_s390, convert_vex_fpcc_to_s390(cc_vex));
10113 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
10114
10115 return "cdbr";
10116}
10117
10118static HChar *
10119s390_irgen_CXBR(UChar r1, UChar r2)
10120{
10121 IRTemp op1 = newTemp(Ity_F128);
10122 IRTemp op2 = newTemp(Ity_F128);
10123 IRTemp cc_vex = newTemp(Ity_I32);
10124 IRTemp cc_s390 = newTemp(Ity_I32);
10125
10126 assign(op1, get_fpr_pair(r1));
10127 assign(op2, get_fpr_pair(r2));
10128 assign(cc_vex, binop(Iop_CmpF128, mkexpr(op1), mkexpr(op2)));
10129
10130 assign(cc_s390, convert_vex_fpcc_to_s390(cc_vex));
10131 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
10132
10133 return "cxbr";
10134}
10135
10136static HChar *
10137s390_irgen_CEB(UChar r1, IRTemp op2addr)
10138{
10139 IRTemp op1 = newTemp(Ity_F32);
10140 IRTemp op2 = newTemp(Ity_F32);
10141 IRTemp cc_vex = newTemp(Ity_I32);
10142 IRTemp cc_s390 = newTemp(Ity_I32);
10143
10144 assign(op1, get_fpr_w0(r1));
10145 assign(op2, load(Ity_F32, mkexpr(op2addr)));
10146 assign(cc_vex, binop(Iop_CmpF32, mkexpr(op1), mkexpr(op2)));
10147
10148 assign(cc_s390, convert_vex_fpcc_to_s390(cc_vex));
10149 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
10150
10151 return "ceb";
10152}
10153
10154static HChar *
10155s390_irgen_CDB(UChar r1, IRTemp op2addr)
10156{
10157 IRTemp op1 = newTemp(Ity_F64);
10158 IRTemp op2 = newTemp(Ity_F64);
10159 IRTemp cc_vex = newTemp(Ity_I32);
10160 IRTemp cc_s390 = newTemp(Ity_I32);
10161
10162 assign(op1, get_fpr_dw0(r1));
10163 assign(op2, load(Ity_F64, mkexpr(op2addr)));
10164 assign(cc_vex, binop(Iop_CmpF64, mkexpr(op1), mkexpr(op2)));
10165
10166 assign(cc_s390, convert_vex_fpcc_to_s390(cc_vex));
10167 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
10168
10169 return "cdb";
10170}
10171
10172static HChar *
10173s390_irgen_CXFBR(UChar r1, UChar r2)
10174{
10175 IRTemp op2 = newTemp(Ity_I32);
10176
10177 assign(op2, get_gpr_w1(r2));
10178 put_fpr_pair(r1, unop(Iop_I32StoF128, mkexpr(op2)));
10179
10180 return "cxfbr";
10181}
10182
10183static HChar *
10184s390_irgen_CXGBR(UChar r1, UChar r2)
10185{
10186 IRTemp op2 = newTemp(Ity_I64);
10187
10188 assign(op2, get_gpr_dw0(r2));
10189 put_fpr_pair(r1, unop(Iop_I64StoF128, mkexpr(op2)));
10190
10191 return "cxgbr";
10192}
10193
10194static HChar *
10195s390_irgen_CFXBR(UChar r3, UChar r1, UChar r2)
10196{
10197 IRTemp op = newTemp(Ity_F128);
10198 IRTemp result = newTemp(Ity_I32);
10199
10200 assign(op, get_fpr_pair(r2));
10201 assign(result, binop(Iop_F128toI32S, mkU32(encode_rounding_mode(r3)),
10202 mkexpr(op)));
10203 put_gpr_w1(r1, mkexpr(result));
10204 s390_cc_thunk_put1f128(S390_CC_OP_BFP_128_TO_INT_32, op);
10205
10206 return "cfxbr";
10207}
10208
10209static HChar *
10210s390_irgen_CGXBR(UChar r3, UChar r1, UChar r2)
10211{
10212 IRTemp op = newTemp(Ity_F128);
10213 IRTemp result = newTemp(Ity_I64);
10214
10215 assign(op, get_fpr_pair(r2));
10216 assign(result, binop(Iop_F128toI64S, mkU32(encode_rounding_mode(r3)),
10217 mkexpr(op)));
10218 put_gpr_dw0(r1, mkexpr(result));
10219 s390_cc_thunk_put1f128(S390_CC_OP_BFP_128_TO_INT_64, op);
10220
10221 return "cgxbr";
10222}
10223
10224static HChar *
10225s390_irgen_DXBR(UChar r1, UChar r2)
10226{
10227 IRTemp op1 = newTemp(Ity_F128);
10228 IRTemp op2 = newTemp(Ity_F128);
10229 IRTemp result = newTemp(Ity_F128);
10230
10231 assign(op1, get_fpr_pair(r1));
10232 assign(op2, get_fpr_pair(r2));
10233 assign(result, triop(Iop_DivF128, mkU32(Irrm_NEAREST), mkexpr(op1),
10234 mkexpr(op2)));
10235 put_fpr_pair(r1, mkexpr(result));
10236
10237 return "dxbr";
10238}
10239
10240static HChar *
10241s390_irgen_LTXBR(UChar r1, UChar r2)
10242{
10243 IRTemp result = newTemp(Ity_F128);
10244
10245 assign(result, get_fpr_pair(r2));
10246 put_fpr_pair(r1, mkexpr(result));
10247 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
10248
10249 return "ltxbr";
10250}
10251
10252static HChar *
10253s390_irgen_LCXBR(UChar r1, UChar r2)
10254{
10255 IRTemp result = newTemp(Ity_F128);
10256
10257 assign(result, unop(Iop_NegF128, get_fpr_pair(r2)));
10258 put_fpr_pair(r1, mkexpr(result));
10259 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
10260
10261 return "lcxbr";
10262}
10263
10264static HChar *
10265s390_irgen_LXDBR(UChar r1, UChar r2)
10266{
10267 IRTemp op = newTemp(Ity_F64);
10268
10269 assign(op, get_fpr_dw0(r2));
10270 put_fpr_pair(r1, unop(Iop_F64toF128, mkexpr(op)));
10271
10272 return "lxdbr";
10273}
10274
10275static HChar *
10276s390_irgen_LXEBR(UChar r1, UChar r2)
10277{
10278 IRTemp op = newTemp(Ity_F32);
10279
10280 assign(op, get_fpr_w0(r2));
10281 put_fpr_pair(r1, unop(Iop_F32toF128, mkexpr(op)));
10282
10283 return "lxebr";
10284}
10285
10286static HChar *
10287s390_irgen_LXDB(UChar r1, IRTemp op2addr)
10288{
10289 IRTemp op = newTemp(Ity_F64);
10290
10291 assign(op, load(Ity_F64, mkexpr(op2addr)));
10292 put_fpr_pair(r1, unop(Iop_F64toF128, mkexpr(op)));
10293
10294 return "lxdb";
10295}
10296
10297static HChar *
10298s390_irgen_LXEB(UChar r1, IRTemp op2addr)
10299{
10300 IRTemp op = newTemp(Ity_F32);
10301
10302 assign(op, load(Ity_F32, mkexpr(op2addr)));
10303 put_fpr_pair(r1, unop(Iop_F32toF128, mkexpr(op)));
10304
10305 return "lxeb";
10306}
10307
10308static HChar *
10309s390_irgen_LNEBR(UChar r1, UChar r2)
10310{
10311 IRTemp result = newTemp(Ity_F32);
10312
10313 assign(result, unop(Iop_NegF32, unop(Iop_AbsF32, get_fpr_w0(r2))));
10314 put_fpr_w0(r1, mkexpr(result));
10315 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_32, result);
10316
10317 return "lnebr";
10318}
10319
10320static HChar *
10321s390_irgen_LNDBR(UChar r1, UChar r2)
10322{
10323 IRTemp result = newTemp(Ity_F64);
10324
10325 assign(result, unop(Iop_NegF64, unop(Iop_AbsF64, get_fpr_dw0(r2))));
10326 put_fpr_dw0(r1, mkexpr(result));
10327 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_64, result);
10328
10329 return "lndbr";
10330}
10331
10332static HChar *
10333s390_irgen_LNXBR(UChar r1, UChar r2)
10334{
10335 IRTemp result = newTemp(Ity_F128);
10336
10337 assign(result, unop(Iop_NegF128, unop(Iop_AbsF128, get_fpr_pair(r2))));
10338 put_fpr_pair(r1, mkexpr(result));
10339 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
10340
10341 return "lnxbr";
10342}
10343
10344static HChar *
10345s390_irgen_LPEBR(UChar r1, UChar r2)
10346{
10347 IRTemp result = newTemp(Ity_F32);
10348
10349 assign(result, unop(Iop_AbsF32, get_fpr_w0(r2)));
10350 put_fpr_w0(r1, mkexpr(result));
10351 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_32, result);
10352
10353 return "lpebr";
10354}
10355
10356static HChar *
10357s390_irgen_LPDBR(UChar r1, UChar r2)
10358{
10359 IRTemp result = newTemp(Ity_F64);
10360
10361 assign(result, unop(Iop_AbsF64, get_fpr_dw0(r2)));
10362 put_fpr_dw0(r1, mkexpr(result));
10363 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_64, result);
10364
10365 return "lpdbr";
10366}
10367
10368static HChar *
10369s390_irgen_LPXBR(UChar r1, UChar r2)
10370{
10371 IRTemp result = newTemp(Ity_F128);
10372
10373 assign(result, unop(Iop_AbsF128, get_fpr_pair(r2)));
10374 put_fpr_pair(r1, mkexpr(result));
10375 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
10376
10377 return "lpxbr";
10378}
10379
10380static HChar *
10381s390_irgen_LDXBR(UChar r1, UChar r2)
10382{
10383 IRTemp result = newTemp(Ity_F64);
10384
10385 assign(result, binop(Iop_F128toF64, mkU32(Irrm_NEAREST), get_fpr_pair(r2)));
10386 put_fpr_dw0(r1, mkexpr(result));
10387
10388 return "ldxbr";
10389}
10390
10391static HChar *
10392s390_irgen_LEXBR(UChar r1, UChar r2)
10393{
10394 IRTemp result = newTemp(Ity_F32);
10395
10396 assign(result, binop(Iop_F128toF32, mkU32(Irrm_NEAREST), get_fpr_pair(r2)));
10397 put_fpr_w0(r1, mkexpr(result));
10398
10399 return "lexbr";
10400}
10401
10402static HChar *
10403s390_irgen_MXBR(UChar r1, UChar r2)
10404{
10405 IRTemp op1 = newTemp(Ity_F128);
10406 IRTemp op2 = newTemp(Ity_F128);
10407 IRTemp result = newTemp(Ity_F128);
10408
10409 assign(op1, get_fpr_pair(r1));
10410 assign(op2, get_fpr_pair(r2));
10411 assign(result, triop(Iop_MulF128, mkU32(Irrm_NEAREST), mkexpr(op1),
10412 mkexpr(op2)));
10413 put_fpr_pair(r1, mkexpr(result));
10414
10415 return "mxbr";
10416}
10417
10418static HChar *
10419s390_irgen_MAEBR(UChar r1, UChar r3, UChar r2)
10420{
10421 put_fpr_w0(r1, qop(Iop_MAddF32, mkU32(Irrm_NEAREST),
10422 get_fpr_w0(r1), get_fpr_w0(r2), get_fpr_w0(r3)));
10423
10424 return "maebr";
10425}
10426
10427static HChar *
10428s390_irgen_MADBR(UChar r1, UChar r3, UChar r2)
10429{
10430 put_fpr_dw0(r1, qop(Iop_MAddF64, mkU32(Irrm_NEAREST),
10431 get_fpr_dw0(r1), get_fpr_dw0(r2), get_fpr_dw0(r3)));
10432
10433 return "madbr";
10434}
10435
10436static HChar *
10437s390_irgen_MAEB(UChar r3, IRTemp op2addr, UChar r1)
10438{
10439 IRExpr *op2 = load(Ity_F32, mkexpr(op2addr));
10440
10441 put_fpr_w0(r1, qop(Iop_MAddF32, mkU32(Irrm_NEAREST),
10442 get_fpr_w0(r1), op2, get_fpr_w0(r3)));
10443
10444 return "maeb";
10445}
10446
10447static HChar *
10448s390_irgen_MADB(UChar r3, IRTemp op2addr, UChar r1)
10449{
10450 IRExpr *op2 = load(Ity_F64, mkexpr(op2addr));
10451
10452 put_fpr_dw0(r1, qop(Iop_MAddF64, mkU32(Irrm_NEAREST),
10453 get_fpr_dw0(r1), op2, get_fpr_dw0(r3)));
10454
10455 return "madb";
10456}
10457
10458static HChar *
10459s390_irgen_MSEBR(UChar r1, UChar r3, UChar r2)
10460{
10461 put_fpr_w0(r1, qop(Iop_MSubF32, mkU32(Irrm_NEAREST),
10462 get_fpr_w0(r1), get_fpr_w0(r2), get_fpr_w0(r3)));
10463
10464 return "msebr";
10465}
10466
10467static HChar *
10468s390_irgen_MSDBR(UChar r1, UChar r3, UChar r2)
10469{
10470 put_fpr_dw0(r1, qop(Iop_MSubF64, mkU32(Irrm_NEAREST),
10471 get_fpr_dw0(r1), get_fpr_dw0(r2), get_fpr_dw0(r3)));
10472
10473 return "msdbr";
10474}
10475
10476static HChar *
10477s390_irgen_MSEB(UChar r3, IRTemp op2addr, UChar r1)
10478{
10479 IRExpr *op2 = load(Ity_F32, mkexpr(op2addr));
10480
10481 put_fpr_w0(r1, qop(Iop_MSubF32, mkU32(Irrm_NEAREST),
10482 get_fpr_w0(r1), op2, get_fpr_w0(r3)));
10483
10484 return "mseb";
10485}
10486
10487static HChar *
10488s390_irgen_MSDB(UChar r3, IRTemp op2addr, UChar r1)
10489{
10490 IRExpr *op2 = load(Ity_F64, mkexpr(op2addr));
10491
10492 put_fpr_dw0(r1, qop(Iop_MSubF64, mkU32(Irrm_NEAREST),
10493 get_fpr_dw0(r1), op2, get_fpr_dw0(r3)));
10494
10495 return "msdb";
10496}
10497
10498static HChar *
10499s390_irgen_SQEBR(UChar r1, UChar r2)
10500{
10501 IRTemp result = newTemp(Ity_F32);
10502
10503 assign(result, binop(Iop_SqrtF32, mkU32(Irrm_NEAREST), get_fpr_w0(r2)));
10504 put_fpr_w0(r1, mkexpr(result));
10505
10506 return "sqebr";
10507}
10508
10509static HChar *
10510s390_irgen_SQDBR(UChar r1, UChar r2)
10511{
10512 IRTemp result = newTemp(Ity_F64);
10513
10514 assign(result, binop(Iop_SqrtF64, mkU32(Irrm_NEAREST), get_fpr_dw0(r2)));
10515 put_fpr_dw0(r1, mkexpr(result));
10516
10517 return "sqdbr";
10518}
10519
10520static HChar *
10521s390_irgen_SQXBR(UChar r1, UChar r2)
10522{
10523 IRTemp result = newTemp(Ity_F128);
10524
10525 assign(result, binop(Iop_SqrtF128, mkU32(Irrm_NEAREST), get_fpr_pair(r2)));
10526 put_fpr_pair(r1, mkexpr(result));
10527
10528 return "sqxbr";
10529}
10530
10531static HChar *
10532s390_irgen_SQEB(UChar r1, IRTemp op2addr)
10533{
10534 IRTemp op = newTemp(Ity_F32);
10535
10536 assign(op, load(Ity_F32, mkexpr(op2addr)));
10537 put_fpr_w0(r1, binop(Iop_SqrtF32, mkU32(Irrm_NEAREST), mkexpr(op)));
10538
10539 return "sqeb";
10540}
10541
10542static HChar *
10543s390_irgen_SQDB(UChar r1, IRTemp op2addr)
10544{
10545 IRTemp op = newTemp(Ity_F64);
10546
10547 assign(op, load(Ity_F64, mkexpr(op2addr)));
10548 put_fpr_dw0(r1, binop(Iop_SqrtF64, mkU32(Irrm_NEAREST), mkexpr(op)));
10549
10550 return "sqdb";
10551}
10552
10553static HChar *
10554s390_irgen_SXBR(UChar r1, UChar r2)
10555{
10556 IRTemp op1 = newTemp(Ity_F128);
10557 IRTemp op2 = newTemp(Ity_F128);
10558 IRTemp result = newTemp(Ity_F128);
10559
10560 assign(op1, get_fpr_pair(r1));
10561 assign(op2, get_fpr_pair(r2));
10562 assign(result, triop(Iop_SubF128, mkU32(Irrm_NEAREST), mkexpr(op1),
10563 mkexpr(op2)));
10564 put_fpr_pair(r1, mkexpr(result));
10565 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
10566
10567 return "sxbr";
10568}
10569
10570static HChar *
10571s390_irgen_TCEB(UChar r1, IRTemp op2addr)
10572{
10573 IRTemp value = newTemp(Ity_F32);
10574
10575 assign(value, get_fpr_w0(r1));
10576
10577 s390_cc_thunk_putFZ(S390_CC_OP_BFP_TDC_32, value, op2addr);
10578
10579 return "tceb";
10580}
10581
10582static HChar *
10583s390_irgen_TCDB(UChar r1, IRTemp op2addr)
10584{
10585 IRTemp value = newTemp(Ity_F64);
10586
10587 assign(value, get_fpr_dw0(r1));
10588
10589 s390_cc_thunk_putFZ(S390_CC_OP_BFP_TDC_64, value, op2addr);
10590
10591 return "tcdb";
10592}
10593
10594static HChar *
10595s390_irgen_TCXB(UChar r1, IRTemp op2addr)
10596{
10597 IRTemp value = newTemp(Ity_F128);
10598
10599 assign(value, get_fpr_pair(r1));
10600
10601 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_TDC_128, value, op2addr);
10602
10603 return "tcxb";
10604}
10605
10606static HChar *
10607s390_irgen_LCDFR(UChar r1, UChar r2)
10608{
10609 IRTemp result = newTemp(Ity_F64);
10610
10611 assign(result, unop(Iop_NegF64, get_fpr_dw0(r2)));
10612 put_fpr_dw0(r1, mkexpr(result));
10613
10614 return "lcdfr";
10615}
10616
10617static HChar *
10618s390_irgen_LNDFR(UChar r1, UChar r2)
10619{
10620 IRTemp result = newTemp(Ity_F64);
10621
10622 assign(result, unop(Iop_NegF64, unop(Iop_AbsF64, get_fpr_dw0(r2))));
10623 put_fpr_dw0(r1, mkexpr(result));
10624
10625 return "lndfr";
10626}
10627
10628static HChar *
10629s390_irgen_LPDFR(UChar r1, UChar r2)
10630{
10631 IRTemp result = newTemp(Ity_F64);
10632
10633 assign(result, unop(Iop_AbsF64, get_fpr_dw0(r2)));
10634 put_fpr_dw0(r1, mkexpr(result));
10635
10636 return "lpdfr";
10637}
10638
10639static HChar *
10640s390_irgen_LDGR(UChar r1, UChar r2)
10641{
10642 put_fpr_dw0(r1, unop(Iop_ReinterpI64asF64, get_gpr_dw0(r2)));
10643
10644 return "ldgr";
10645}
10646
10647static HChar *
10648s390_irgen_LGDR(UChar r1, UChar r2)
10649{
10650 put_gpr_dw0(r1, unop(Iop_ReinterpF64asI64, get_fpr_dw0(r2)));
10651
10652 return "lgdr";
10653}
10654
10655
10656static HChar *
10657s390_irgen_CPSDR(UChar r3, UChar r1, UChar r2)
10658{
10659 IRTemp sign = newTemp(Ity_I64);
10660 IRTemp value = newTemp(Ity_I64);
10661
10662 assign(sign, binop(Iop_And64, unop(Iop_ReinterpF64asI64, get_fpr_dw0(r3)),
10663 mkU64(1ULL << 63)));
10664 assign(value, binop(Iop_And64, unop(Iop_ReinterpF64asI64, get_fpr_dw0(r2)),
10665 mkU64((1ULL << 63) - 1)));
10666 put_fpr_dw0(r1, unop(Iop_ReinterpI64asF64, binop(Iop_Or64, mkexpr(value),
10667 mkexpr(sign))));
10668
10669 return "cpsdr";
10670}
10671
10672
sewardj2019a972011-03-07 16:04:07 +000010673static IRExpr *
10674s390_call_cvb(IRExpr *in)
10675{
10676 IRExpr **args, *call;
10677
10678 args = mkIRExprVec_1(in);
10679 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
10680 "s390_do_cvb", &s390_do_cvb, args);
10681
10682 /* Nothing is excluded from definedness checking. */
10683 call->Iex.CCall.cee->mcx_mask = 0;
10684
10685 return call;
10686}
10687
10688static HChar *
10689s390_irgen_CVB(UChar r1, IRTemp op2addr)
10690{
10691 put_gpr_w1(r1, s390_call_cvb(load(Ity_I64, mkexpr(op2addr))));
10692
10693 return "cvb";
10694}
10695
10696static HChar *
10697s390_irgen_CVBY(UChar r1, IRTemp op2addr)
10698{
10699 put_gpr_w1(r1, s390_call_cvb(load(Ity_I64, mkexpr(op2addr))));
10700
10701 return "cvby";
10702}
10703
10704
sewardj2019a972011-03-07 16:04:07 +000010705static IRExpr *
10706s390_call_cvd(IRExpr *in)
10707{
10708 IRExpr **args, *call;
10709
10710 args = mkIRExprVec_1(in);
10711 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
10712 "s390_do_cvd", &s390_do_cvd, args);
10713
10714 /* Nothing is excluded from definedness checking. */
10715 call->Iex.CCall.cee->mcx_mask = 0;
10716
10717 return call;
10718}
10719
10720static HChar *
10721s390_irgen_CVD(UChar r1, IRTemp op2addr)
10722{
10723 store(mkexpr(op2addr), s390_call_cvd(get_gpr_w1(r1)));
10724
10725 return "cvd";
10726}
10727
10728static HChar *
10729s390_irgen_CVDY(UChar r1, IRTemp op2addr)
10730{
10731 store(mkexpr(op2addr), s390_call_cvd(get_gpr_w1(r1)));
10732
10733 return "cvdy";
10734}
10735
10736static HChar *
10737s390_irgen_FLOGR(UChar r1, UChar r2)
10738{
10739 IRTemp input = newTemp(Ity_I64);
10740 IRTemp not_zero = newTemp(Ity_I64);
10741 IRTemp tmpnum = newTemp(Ity_I64);
10742 IRTemp num = newTemp(Ity_I64);
10743 IRTemp shift_amount = newTemp(Ity_I8);
10744
10745 /* We use the "count leading zeroes" operator because the number of
10746 leading zeroes is identical with the bit position of the first '1' bit.
10747 However, that operator does not work when the input value is zero.
10748 Therefore, we set the LSB of the input value to 1 and use Clz64 on
10749 the modified value. If input == 0, then the result is 64. Otherwise,
10750 the result of Clz64 is what we want. */
10751
10752 assign(input, get_gpr_dw0(r2));
10753 assign(not_zero, binop(Iop_Or64, mkexpr(input), mkU64(1)));
10754 assign(tmpnum, unop(Iop_Clz64, mkexpr(not_zero)));
10755
10756 /* num = (input == 0) ? 64 : tmpnum */
10757 assign(num, mkite(binop(Iop_CmpEQ64, mkexpr(input), mkU64(0)),
10758 /* == 0 */ mkU64(64),
10759 /* != 0 */ mkexpr(tmpnum)));
10760
10761 put_gpr_dw0(r1, mkexpr(num));
10762
10763 /* Set the leftmost '1' bit of the input value to zero. The general scheme
10764 is to first shift the input value by NUM + 1 bits to the left which
10765 causes the leftmost '1' bit to disappear. Then we shift logically to
10766 the right by NUM + 1 bits. Because the semantics of Iop_Shl64 and
10767 Iop_Shr64 are undefined if the shift-amount is greater than or equal to
10768 the width of the value-to-be-shifted, we need to special case
10769 NUM + 1 >= 64. This is equivalent to INPUT != 0 && INPUT != 1.
10770 For both such INPUT values the result will be 0. */
10771
10772 assign(shift_amount, unop(Iop_64to8, binop(Iop_Add64, mkexpr(num),
10773 mkU64(1))));
10774
10775 put_gpr_dw0(r1 + 1,
florian6ad49522011-09-09 02:38:55 +000010776 mkite(binop(Iop_CmpLE64U, mkexpr(input), mkU64(1)),
10777 /* == 0 || == 1*/ mkU64(0),
10778 /* otherwise */
10779 binop(Iop_Shr64,
10780 binop(Iop_Shl64, mkexpr(input),
10781 mkexpr(shift_amount)),
10782 mkexpr(shift_amount))));
sewardj2019a972011-03-07 16:04:07 +000010783
10784 /* Compare the original value as an unsigned integer with 0. */
10785 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, input,
10786 mktemp(Ity_I64, mkU64(0)), False);
10787
10788 return "flogr";
10789}
10790
sewardj1e5fea62011-05-17 16:18:36 +000010791static HChar *
10792s390_irgen_STCK(IRTemp op2addr)
10793{
10794 IRDirty *d;
10795 IRTemp cc = newTemp(Ity_I64);
10796
10797 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STCK",
10798 &s390x_dirtyhelper_STCK,
10799 mkIRExprVec_1(mkexpr(op2addr)));
10800 d->mFx = Ifx_Write;
10801 d->mAddr = mkexpr(op2addr);
10802 d->mSize = 8;
10803 stmt(IRStmt_Dirty(d));
10804 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
10805 mkexpr(cc), mkU64(0), mkU64(0));
10806 return "stck";
10807}
10808
10809static HChar *
10810s390_irgen_STCKF(IRTemp op2addr)
10811{
10812 IRDirty *d;
10813 IRTemp cc = newTemp(Ity_I64);
10814
10815 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STCKF",
10816 &s390x_dirtyhelper_STCKF,
10817 mkIRExprVec_1(mkexpr(op2addr)));
10818 d->mFx = Ifx_Write;
10819 d->mAddr = mkexpr(op2addr);
10820 d->mSize = 8;
10821 stmt(IRStmt_Dirty(d));
10822 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
10823 mkexpr(cc), mkU64(0), mkU64(0));
10824 return "stckf";
10825}
10826
10827static HChar *
10828s390_irgen_STCKE(IRTemp op2addr)
10829{
10830 IRDirty *d;
10831 IRTemp cc = newTemp(Ity_I64);
10832
10833 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STCKE",
10834 &s390x_dirtyhelper_STCKE,
10835 mkIRExprVec_1(mkexpr(op2addr)));
10836 d->mFx = Ifx_Write;
10837 d->mAddr = mkexpr(op2addr);
10838 d->mSize = 16;
10839 stmt(IRStmt_Dirty(d));
10840 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
10841 mkexpr(cc), mkU64(0), mkU64(0));
10842 return "stcke";
10843}
10844
florian933065d2011-07-11 01:48:02 +000010845static HChar *
10846s390_irgen_STFLE(IRTemp op2addr)
10847{
10848 IRDirty *d;
10849 IRTemp cc = newTemp(Ity_I64);
10850
10851 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STFLE",
10852 &s390x_dirtyhelper_STFLE,
10853 mkIRExprVec_1(mkexpr(op2addr)));
10854
10855 d->needsBBP = 1; /* Need to pass pointer to guest state to helper */
10856
sewardjc9069f22012-06-01 16:09:50 +000010857 d->nFxState = 1;
10858 vex_bzero(&d->fxState, sizeof(d->fxState));
10859
florian933065d2011-07-11 01:48:02 +000010860 d->fxState[0].fx = Ifx_Modify; /* read then write */
10861 d->fxState[0].offset = S390X_GUEST_OFFSET(guest_r0);
10862 d->fxState[0].size = sizeof(ULong);
florian933065d2011-07-11 01:48:02 +000010863
10864 d->mAddr = mkexpr(op2addr);
10865 /* Pretend all double words are written */
10866 d->mSize = S390_NUM_FACILITY_DW * sizeof(ULong);
10867 d->mFx = Ifx_Write;
10868
10869 stmt(IRStmt_Dirty(d));
10870
10871 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET), mkexpr(cc), mkU64(0), mkU64(0));
10872
10873 return "stfle";
10874}
10875
floriana4384a32011-08-11 16:58:45 +000010876static HChar *
10877s390_irgen_CKSM(UChar r1,UChar r2)
10878{
10879 IRTemp addr = newTemp(Ity_I64);
10880 IRTemp op = newTemp(Ity_I32);
10881 IRTemp len = newTemp(Ity_I64);
10882 IRTemp oldval = newTemp(Ity_I32);
10883 IRTemp mask = newTemp(Ity_I32);
10884 IRTemp newop = newTemp(Ity_I32);
10885 IRTemp result = newTemp(Ity_I32);
10886 IRTemp result1 = newTemp(Ity_I32);
10887 IRTemp inc = newTemp(Ity_I64);
10888
10889 assign(oldval, get_gpr_w1(r1));
10890 assign(addr, get_gpr_dw0(r2));
10891 assign(len, get_gpr_dw0(r2+1));
10892
10893 /* Condition code is always zero. */
10894 s390_cc_set(0);
10895
10896 /* If length is zero, there is no need to calculate the checksum */
10897 if_condition_goto(binop(Iop_CmpEQ64, mkexpr(len), mkU64(0)),
10898 guest_IA_next_instr);
10899
10900 /* Assiging the increment variable to adjust address and length
10901 later on. */
10902 assign(inc, mkite(binop(Iop_CmpLT64U, mkexpr(len), mkU64(4)),
10903 mkexpr(len), mkU64(4)));
10904
10905 /* If length < 4 the final 4-byte 2nd operand value is computed by
10906 appending the remaining bytes to the right with 0. This is done
10907 by AND'ing the 4 bytes loaded from memory with an appropriate
10908 mask. If length >= 4, that mask is simply 0xffffffff. */
10909
10910 assign(mask, mkite(binop(Iop_CmpLT64U, mkexpr(len), mkU64(4)),
10911 /* Mask computation when len < 4:
10912 0xffffffff << (32 - (len % 4)*8) */
10913 binop(Iop_Shl32, mkU32(0xffffffff),
10914 unop(Iop_32to8,
10915 binop(Iop_Sub32, mkU32(32),
10916 binop(Iop_Shl32,
10917 unop(Iop_64to32,
10918 binop(Iop_And64,
10919 mkexpr(len), mkU64(3))),
10920 mkU8(3))))),
10921 mkU32(0xffffffff)));
10922
10923 assign(op, load(Ity_I32, mkexpr(addr)));
10924 assign(newop, binop(Iop_And32, mkexpr(op), mkexpr(mask)));
10925 assign(result, binop(Iop_Add32, mkexpr(newop), mkexpr(oldval)));
10926
10927 /* Checking for carry */
10928 assign(result1, mkite(binop(Iop_CmpLT32U, mkexpr(result), mkexpr(newop)),
10929 binop(Iop_Add32, mkexpr(result), mkU32(1)),
10930 mkexpr(result)));
10931
10932 put_gpr_w1(r1, mkexpr(result1));
10933 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr), mkexpr(inc)));
10934 put_gpr_dw0(r2+1, binop(Iop_Sub64, mkexpr(len), mkexpr(inc)));
10935
10936 if_condition_goto(binop(Iop_CmpNE64, mkexpr(len), mkU64(0)),
10937 guest_IA_curr_instr);
10938
10939 return "cksm";
10940}
10941
florian9af37692012-01-15 21:01:16 +000010942static HChar *
10943s390_irgen_TROO(UChar m3, UChar r1, UChar r2)
10944{
10945 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
10946 src_addr = newTemp(Ity_I64);
10947 des_addr = newTemp(Ity_I64);
10948 tab_addr = newTemp(Ity_I64);
10949 test_byte = newTemp(Ity_I8);
10950 src_len = newTemp(Ity_I64);
10951
10952 assign(src_addr, get_gpr_dw0(r2));
10953 assign(des_addr, get_gpr_dw0(r1));
10954 assign(tab_addr, get_gpr_dw0(1));
florian53518532012-01-18 14:00:31 +000010955 assign(src_len, get_gpr_dw0(r1+1));
florian9af37692012-01-15 21:01:16 +000010956 assign(test_byte, get_gpr_b7(0));
10957
10958 IRTemp op = newTemp(Ity_I8);
10959 IRTemp op1 = newTemp(Ity_I8);
10960 IRTemp result = newTemp(Ity_I64);
10961
10962 /* End of source string? We're done; proceed to next insn */
10963 s390_cc_set(0);
10964 if_condition_goto(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)),
10965 guest_IA_next_instr);
10966
10967 /* Load character from source string, index translation table and
10968 store translated character in op1. */
10969 assign(op, load(Ity_I8, mkexpr(src_addr)));
10970
10971 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)),
10972 mkexpr(tab_addr)));
10973 assign(op1, load(Ity_I8, mkexpr(result)));
10974
10975 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
10976 s390_cc_set(1);
10977 if_condition_goto(binop(Iop_CmpEQ8, mkexpr(op1), mkexpr(test_byte)),
10978 guest_IA_next_instr);
10979 }
10980 store(get_gpr_dw0(r1), mkexpr(op1));
10981
10982 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(1)));
10983 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(1)));
10984 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(1)));
10985
10986 always_goto_and_chase(guest_IA_curr_instr);
10987
10988 return "troo";
10989}
10990
florian730448f2012-02-04 17:07:07 +000010991static HChar *
10992s390_irgen_TRTO(UChar m3, UChar r1, UChar r2)
10993{
10994 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
10995 src_addr = newTemp(Ity_I64);
10996 des_addr = newTemp(Ity_I64);
10997 tab_addr = newTemp(Ity_I64);
10998 test_byte = newTemp(Ity_I8);
10999 src_len = newTemp(Ity_I64);
11000
11001 assign(src_addr, get_gpr_dw0(r2));
11002 assign(des_addr, get_gpr_dw0(r1));
11003 assign(tab_addr, get_gpr_dw0(1));
11004 assign(src_len, get_gpr_dw0(r1+1));
11005 assign(test_byte, get_gpr_b7(0));
11006
11007 IRTemp op = newTemp(Ity_I16);
11008 IRTemp op1 = newTemp(Ity_I8);
11009 IRTemp result = newTemp(Ity_I64);
11010
11011 /* End of source string? We're done; proceed to next insn */
11012 s390_cc_set(0);
11013 if_condition_goto(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)),
11014 guest_IA_next_instr);
11015
11016 /* Load character from source string, index translation table and
11017 store translated character in op1. */
11018 assign(op, load(Ity_I16, mkexpr(src_addr)));
11019
11020 assign(result, binop(Iop_Add64, unop(Iop_16Uto64, mkexpr(op)),
11021 mkexpr(tab_addr)));
11022
11023 assign(op1, load(Ity_I8, mkexpr(result)));
11024
11025 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
11026 s390_cc_set(1);
11027 if_condition_goto(binop(Iop_CmpEQ8, mkexpr(op1), mkexpr(test_byte)),
11028 guest_IA_next_instr);
11029 }
11030 store(get_gpr_dw0(r1), mkexpr(op1));
11031
11032 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(2)));
11033 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(1)));
11034 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(2)));
11035
11036 always_goto_and_chase(guest_IA_curr_instr);
11037
11038 return "trto";
11039}
11040
11041static HChar *
11042s390_irgen_TROT(UChar m3, UChar r1, UChar r2)
11043{
11044 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
11045 src_addr = newTemp(Ity_I64);
11046 des_addr = newTemp(Ity_I64);
11047 tab_addr = newTemp(Ity_I64);
11048 test_byte = newTemp(Ity_I16);
11049 src_len = newTemp(Ity_I64);
11050
11051 assign(src_addr, get_gpr_dw0(r2));
11052 assign(des_addr, get_gpr_dw0(r1));
11053 assign(tab_addr, get_gpr_dw0(1));
11054 assign(src_len, get_gpr_dw0(r1+1));
11055 assign(test_byte, get_gpr_hw3(0));
11056
11057 IRTemp op = newTemp(Ity_I8);
11058 IRTemp op1 = newTemp(Ity_I16);
11059 IRTemp result = newTemp(Ity_I64);
11060
11061 /* End of source string? We're done; proceed to next insn */
11062 s390_cc_set(0);
11063 if_condition_goto(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)),
11064 guest_IA_next_instr);
11065
11066 /* Load character from source string, index translation table and
11067 store translated character in op1. */
11068 assign(op, binop(Iop_Shl8, load(Ity_I8, mkexpr(src_addr)), mkU8(1)));
11069
11070 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)),
11071 mkexpr(tab_addr)));
11072 assign(op1, load(Ity_I16, mkexpr(result)));
11073
11074 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
11075 s390_cc_set(1);
11076 if_condition_goto(binop(Iop_CmpEQ16, mkexpr(op1), mkexpr(test_byte)),
11077 guest_IA_next_instr);
11078 }
11079 store(get_gpr_dw0(r1), mkexpr(op1));
11080
11081 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(1)));
11082 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(2)));
11083 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(1)));
11084
11085 always_goto_and_chase(guest_IA_curr_instr);
11086
11087 return "trot";
11088}
11089
11090static HChar *
11091s390_irgen_TRTT(UChar m3, UChar r1, UChar r2)
11092{
11093 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
11094 src_addr = newTemp(Ity_I64);
11095 des_addr = newTemp(Ity_I64);
11096 tab_addr = newTemp(Ity_I64);
11097 test_byte = newTemp(Ity_I16);
11098 src_len = newTemp(Ity_I64);
11099
11100 assign(src_addr, get_gpr_dw0(r2));
11101 assign(des_addr, get_gpr_dw0(r1));
11102 assign(tab_addr, get_gpr_dw0(1));
11103 assign(src_len, get_gpr_dw0(r1+1));
11104 assign(test_byte, get_gpr_hw3(0));
11105
11106 IRTemp op = newTemp(Ity_I16);
11107 IRTemp op1 = newTemp(Ity_I16);
11108 IRTemp result = newTemp(Ity_I64);
11109
11110 /* End of source string? We're done; proceed to next insn */
11111 s390_cc_set(0);
11112 if_condition_goto(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)),
11113 guest_IA_next_instr);
11114
11115 /* Load character from source string, index translation table and
11116 store translated character in op1. */
11117 assign(op, binop(Iop_Shl16, load(Ity_I16, mkexpr(src_addr)), mkU8(1)));
11118
11119 assign(result, binop(Iop_Add64, unop(Iop_16Uto64, mkexpr(op)),
11120 mkexpr(tab_addr)));
11121 assign(op1, load(Ity_I16, mkexpr(result)));
11122
11123 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
11124 s390_cc_set(1);
11125 if_condition_goto(binop(Iop_CmpEQ16, mkexpr(op1), mkexpr(test_byte)),
11126 guest_IA_next_instr);
11127 }
11128
11129 store(get_gpr_dw0(r1), mkexpr(op1));
11130
11131 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(2)));
11132 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(2)));
11133 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(2)));
11134
11135 always_goto_and_chase(guest_IA_curr_instr);
11136
11137 return "trtt";
11138}
11139
11140static HChar *
11141s390_irgen_TR(UChar length, IRTemp start1, IRTemp start2)
11142{
florianf87d4fb2012-05-05 02:55:24 +000011143 IRTemp len = newTemp(Ity_I64);
florian730448f2012-02-04 17:07:07 +000011144
florianf87d4fb2012-05-05 02:55:24 +000011145 assign(len, mkU64(length));
11146 s390_irgen_TR_EX(len, start1, start2);
florian8844a632012-04-13 04:04:06 +000011147 dummy_put_IA();
florian730448f2012-02-04 17:07:07 +000011148
11149 return "tr";
11150}
11151
11152static HChar *
11153s390_irgen_TRE(UChar r1,UChar r2)
11154{
11155 IRTemp src_addr, tab_addr, src_len, test_byte;
11156 src_addr = newTemp(Ity_I64);
11157 tab_addr = newTemp(Ity_I64);
11158 src_len = newTemp(Ity_I64);
11159 test_byte = newTemp(Ity_I8);
11160
11161 assign(src_addr, get_gpr_dw0(r1));
11162 assign(src_len, get_gpr_dw0(r1+1));
11163 assign(tab_addr, get_gpr_dw0(r2));
11164 assign(test_byte, get_gpr_b7(0));
11165
11166 IRTemp op = newTemp(Ity_I8);
11167 IRTemp op1 = newTemp(Ity_I8);
11168 IRTemp result = newTemp(Ity_I64);
11169
11170 /* End of source string? We're done; proceed to next insn */
11171 s390_cc_set(0);
11172 if_condition_goto(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)),
11173 guest_IA_next_instr);
11174
11175 /* Load character from source string and compare with test byte */
11176 assign(op, load(Ity_I8, mkexpr(src_addr)));
11177
11178 s390_cc_set(1);
11179 if_condition_goto(binop(Iop_CmpEQ8, mkexpr(op), mkexpr(test_byte)),
11180 guest_IA_next_instr);
11181
11182 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)),
11183 mkexpr(tab_addr)));
11184
11185 assign(op1, load(Ity_I8, mkexpr(result)));
11186
11187 store(get_gpr_dw0(r1), mkexpr(op1));
11188 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(src_addr), mkU64(1)));
11189 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(1)));
11190
11191 always_goto(mkU64(guest_IA_curr_instr));
11192
11193 return "tre";
11194}
11195
floriana4384a32011-08-11 16:58:45 +000011196
sewardj2019a972011-03-07 16:04:07 +000011197/*------------------------------------------------------------*/
11198/*--- Build IR for special instructions ---*/
11199/*------------------------------------------------------------*/
11200
florianb4df7682011-07-05 02:09:01 +000011201static void
sewardj2019a972011-03-07 16:04:07 +000011202s390_irgen_client_request(void)
11203{
11204 if (0)
11205 vex_printf("%%R3 = client_request ( %%R2 )\n");
11206
florianf9e1ed72012-04-17 02:41:56 +000011207 Addr64 next = guest_IA_curr_instr + S390_SPECIAL_OP_PREAMBLE_SIZE
11208 + S390_SPECIAL_OP_SIZE;
sewardj2019a972011-03-07 16:04:07 +000011209
florianf9e1ed72012-04-17 02:41:56 +000011210 dis_res->jk_StopHere = Ijk_ClientReq;
sewardj2019a972011-03-07 16:04:07 +000011211 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +000011212
11213 put_IA(mkaddr_expr(next));
sewardj2019a972011-03-07 16:04:07 +000011214}
11215
florianb4df7682011-07-05 02:09:01 +000011216static void
sewardj2019a972011-03-07 16:04:07 +000011217s390_irgen_guest_NRADDR(void)
11218{
11219 if (0)
11220 vex_printf("%%R3 = guest_NRADDR\n");
11221
floriane88b3c92011-07-05 02:48:39 +000011222 put_gpr_dw0(3, IRExpr_Get(S390X_GUEST_OFFSET(guest_NRADDR), Ity_I64));
sewardj2019a972011-03-07 16:04:07 +000011223}
11224
florianb4df7682011-07-05 02:09:01 +000011225static void
sewardj2019a972011-03-07 16:04:07 +000011226s390_irgen_call_noredir(void)
11227{
florianf9e1ed72012-04-17 02:41:56 +000011228 Addr64 next = guest_IA_curr_instr + S390_SPECIAL_OP_PREAMBLE_SIZE
11229 + S390_SPECIAL_OP_SIZE;
11230
sewardj2019a972011-03-07 16:04:07 +000011231 /* Continue after special op */
florianf9e1ed72012-04-17 02:41:56 +000011232 put_gpr_dw0(14, mkaddr_expr(next));
sewardj2019a972011-03-07 16:04:07 +000011233
11234 /* The address is in REG1, all parameters are in the right (guest) places */
florianf9e1ed72012-04-17 02:41:56 +000011235 put_IA(get_gpr_dw0(1));
sewardj2019a972011-03-07 16:04:07 +000011236
11237 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +000011238 dis_res->jk_StopHere = Ijk_NoRedir;
sewardj2019a972011-03-07 16:04:07 +000011239}
11240
11241/* Force proper alignment for the structures below. */
11242#pragma pack(1)
11243
11244
11245static s390_decode_t
11246s390_decode_2byte_and_irgen(UChar *bytes)
11247{
11248 typedef union {
11249 struct {
11250 unsigned int op : 16;
11251 } E;
11252 struct {
11253 unsigned int op : 8;
11254 unsigned int i : 8;
11255 } I;
11256 struct {
11257 unsigned int op : 8;
11258 unsigned int r1 : 4;
11259 unsigned int r2 : 4;
11260 } RR;
11261 } formats;
11262 union {
11263 formats fmt;
11264 UShort value;
11265 } ovl;
11266
11267 vassert(sizeof(formats) == 2);
11268
11269 ((char *)(&ovl.value))[0] = bytes[0];
11270 ((char *)(&ovl.value))[1] = bytes[1];
11271
11272 switch (ovl.value & 0xffff) {
florian30e89012011-08-08 18:22:58 +000011273 case 0x0000: /* invalid opcode */
11274 s390_format_RR_RR(s390_irgen_00, 0, 0); goto ok;
sewardj2019a972011-03-07 16:04:07 +000011275 case 0x0101: /* PR */ goto unimplemented;
11276 case 0x0102: /* UPT */ goto unimplemented;
11277 case 0x0104: /* PTFF */ goto unimplemented;
11278 case 0x0107: /* SCKPF */ goto unimplemented;
11279 case 0x010a: /* PFPO */ goto unimplemented;
11280 case 0x010b: /* TAM */ goto unimplemented;
11281 case 0x010c: /* SAM24 */ goto unimplemented;
11282 case 0x010d: /* SAM31 */ goto unimplemented;
11283 case 0x010e: /* SAM64 */ goto unimplemented;
11284 case 0x01ff: /* TRAP2 */ goto unimplemented;
11285 }
11286
11287 switch ((ovl.value & 0xff00) >> 8) {
11288 case 0x04: /* SPM */ goto unimplemented;
11289 case 0x05: /* BALR */ goto unimplemented;
11290 case 0x06: s390_format_RR_RR(s390_irgen_BCTR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
11291 goto ok;
11292 case 0x07: s390_format_RR(s390_irgen_BCR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
11293 goto ok;
11294 case 0x0a: s390_format_I(s390_irgen_SVC, ovl.fmt.I.i); goto ok;
11295 case 0x0b: /* BSM */ goto unimplemented;
11296 case 0x0c: /* BASSM */ goto unimplemented;
11297 case 0x0d: s390_format_RR_RR(s390_irgen_BASR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
11298 goto ok;
florianb0c9a132011-09-08 15:37:39 +000011299 case 0x0e: s390_format_RR(s390_irgen_MVCL, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
11300 goto ok;
11301 case 0x0f: s390_format_RR(s390_irgen_CLCL, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
11302 goto ok;
sewardj2019a972011-03-07 16:04:07 +000011303 case 0x10: s390_format_RR_RR(s390_irgen_LPR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
11304 goto ok;
11305 case 0x11: s390_format_RR_RR(s390_irgen_LNR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
11306 goto ok;
11307 case 0x12: s390_format_RR_RR(s390_irgen_LTR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
11308 goto ok;
11309 case 0x13: s390_format_RR_RR(s390_irgen_LCR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
11310 goto ok;
11311 case 0x14: s390_format_RR_RR(s390_irgen_NR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
11312 goto ok;
11313 case 0x15: s390_format_RR_RR(s390_irgen_CLR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
11314 goto ok;
11315 case 0x16: s390_format_RR_RR(s390_irgen_OR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
11316 goto ok;
11317 case 0x17: s390_format_RR_RR(s390_irgen_XR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
11318 goto ok;
11319 case 0x18: s390_format_RR_RR(s390_irgen_LR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
11320 goto ok;
11321 case 0x19: s390_format_RR_RR(s390_irgen_CR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
11322 goto ok;
11323 case 0x1a: s390_format_RR_RR(s390_irgen_AR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
11324 goto ok;
11325 case 0x1b: s390_format_RR_RR(s390_irgen_SR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
11326 goto ok;
11327 case 0x1c: s390_format_RR_RR(s390_irgen_MR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
11328 goto ok;
11329 case 0x1d: s390_format_RR_RR(s390_irgen_DR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
11330 goto ok;
11331 case 0x1e: s390_format_RR_RR(s390_irgen_ALR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
11332 goto ok;
11333 case 0x1f: s390_format_RR_RR(s390_irgen_SLR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
11334 goto ok;
11335 case 0x20: /* LPDR */ goto unimplemented;
11336 case 0x21: /* LNDR */ goto unimplemented;
11337 case 0x22: /* LTDR */ goto unimplemented;
11338 case 0x23: /* LCDR */ goto unimplemented;
11339 case 0x24: /* HDR */ goto unimplemented;
11340 case 0x25: /* LDXR */ goto unimplemented;
11341 case 0x26: /* MXR */ goto unimplemented;
11342 case 0x27: /* MXDR */ goto unimplemented;
11343 case 0x28: s390_format_RR_FF(s390_irgen_LDR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
11344 goto ok;
11345 case 0x29: /* CDR */ goto unimplemented;
11346 case 0x2a: /* ADR */ goto unimplemented;
11347 case 0x2b: /* SDR */ goto unimplemented;
11348 case 0x2c: /* MDR */ goto unimplemented;
11349 case 0x2d: /* DDR */ goto unimplemented;
11350 case 0x2e: /* AWR */ goto unimplemented;
11351 case 0x2f: /* SWR */ goto unimplemented;
11352 case 0x30: /* LPER */ goto unimplemented;
11353 case 0x31: /* LNER */ goto unimplemented;
11354 case 0x32: /* LTER */ goto unimplemented;
11355 case 0x33: /* LCER */ goto unimplemented;
11356 case 0x34: /* HER */ goto unimplemented;
11357 case 0x35: /* LEDR */ goto unimplemented;
11358 case 0x36: /* AXR */ goto unimplemented;
11359 case 0x37: /* SXR */ goto unimplemented;
11360 case 0x38: s390_format_RR_FF(s390_irgen_LER, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
11361 goto ok;
11362 case 0x39: /* CER */ goto unimplemented;
11363 case 0x3a: /* AER */ goto unimplemented;
11364 case 0x3b: /* SER */ goto unimplemented;
11365 case 0x3c: /* MDER */ goto unimplemented;
11366 case 0x3d: /* DER */ goto unimplemented;
11367 case 0x3e: /* AUR */ goto unimplemented;
11368 case 0x3f: /* SUR */ goto unimplemented;
11369 }
11370
11371 return S390_DECODE_UNKNOWN_INSN;
11372
11373ok:
11374 return S390_DECODE_OK;
11375
11376unimplemented:
11377 return S390_DECODE_UNIMPLEMENTED_INSN;
11378}
11379
11380static s390_decode_t
11381s390_decode_4byte_and_irgen(UChar *bytes)
11382{
11383 typedef union {
11384 struct {
11385 unsigned int op1 : 8;
11386 unsigned int r1 : 4;
11387 unsigned int op2 : 4;
11388 unsigned int i2 : 16;
11389 } RI;
11390 struct {
11391 unsigned int op : 16;
11392 unsigned int : 8;
11393 unsigned int r1 : 4;
11394 unsigned int r2 : 4;
11395 } RRE;
11396 struct {
11397 unsigned int op : 16;
11398 unsigned int r1 : 4;
11399 unsigned int : 4;
11400 unsigned int r3 : 4;
11401 unsigned int r2 : 4;
11402 } RRF;
11403 struct {
11404 unsigned int op : 16;
11405 unsigned int r3 : 4;
11406 unsigned int m4 : 4;
11407 unsigned int r1 : 4;
11408 unsigned int r2 : 4;
11409 } RRF2;
11410 struct {
11411 unsigned int op : 16;
11412 unsigned int r3 : 4;
11413 unsigned int : 4;
11414 unsigned int r1 : 4;
11415 unsigned int r2 : 4;
11416 } RRF3;
11417 struct {
11418 unsigned int op : 16;
11419 unsigned int r3 : 4;
11420 unsigned int : 4;
11421 unsigned int r1 : 4;
11422 unsigned int r2 : 4;
11423 } RRR;
11424 struct {
11425 unsigned int op : 16;
11426 unsigned int r3 : 4;
11427 unsigned int : 4;
11428 unsigned int r1 : 4;
11429 unsigned int r2 : 4;
11430 } RRF4;
11431 struct {
11432 unsigned int op : 8;
11433 unsigned int r1 : 4;
11434 unsigned int r3 : 4;
11435 unsigned int b2 : 4;
11436 unsigned int d2 : 12;
11437 } RS;
11438 struct {
11439 unsigned int op : 8;
11440 unsigned int r1 : 4;
11441 unsigned int r3 : 4;
11442 unsigned int i2 : 16;
11443 } RSI;
11444 struct {
11445 unsigned int op : 8;
11446 unsigned int r1 : 4;
11447 unsigned int x2 : 4;
11448 unsigned int b2 : 4;
11449 unsigned int d2 : 12;
11450 } RX;
11451 struct {
11452 unsigned int op : 16;
11453 unsigned int b2 : 4;
11454 unsigned int d2 : 12;
11455 } S;
11456 struct {
11457 unsigned int op : 8;
11458 unsigned int i2 : 8;
11459 unsigned int b1 : 4;
11460 unsigned int d1 : 12;
11461 } SI;
11462 } formats;
11463 union {
11464 formats fmt;
11465 UInt value;
11466 } ovl;
11467
11468 vassert(sizeof(formats) == 4);
11469
11470 ((char *)(&ovl.value))[0] = bytes[0];
11471 ((char *)(&ovl.value))[1] = bytes[1];
11472 ((char *)(&ovl.value))[2] = bytes[2];
11473 ((char *)(&ovl.value))[3] = bytes[3];
11474
11475 switch ((ovl.value & 0xff0f0000) >> 16) {
11476 case 0xa500: s390_format_RI_RU(s390_irgen_IIHH, ovl.fmt.RI.r1,
11477 ovl.fmt.RI.i2); goto ok;
11478 case 0xa501: s390_format_RI_RU(s390_irgen_IIHL, ovl.fmt.RI.r1,
11479 ovl.fmt.RI.i2); goto ok;
11480 case 0xa502: s390_format_RI_RU(s390_irgen_IILH, ovl.fmt.RI.r1,
11481 ovl.fmt.RI.i2); goto ok;
11482 case 0xa503: s390_format_RI_RU(s390_irgen_IILL, ovl.fmt.RI.r1,
11483 ovl.fmt.RI.i2); goto ok;
11484 case 0xa504: s390_format_RI_RU(s390_irgen_NIHH, ovl.fmt.RI.r1,
11485 ovl.fmt.RI.i2); goto ok;
11486 case 0xa505: s390_format_RI_RU(s390_irgen_NIHL, ovl.fmt.RI.r1,
11487 ovl.fmt.RI.i2); goto ok;
11488 case 0xa506: s390_format_RI_RU(s390_irgen_NILH, ovl.fmt.RI.r1,
11489 ovl.fmt.RI.i2); goto ok;
11490 case 0xa507: s390_format_RI_RU(s390_irgen_NILL, ovl.fmt.RI.r1,
11491 ovl.fmt.RI.i2); goto ok;
11492 case 0xa508: s390_format_RI_RU(s390_irgen_OIHH, ovl.fmt.RI.r1,
11493 ovl.fmt.RI.i2); goto ok;
11494 case 0xa509: s390_format_RI_RU(s390_irgen_OIHL, ovl.fmt.RI.r1,
11495 ovl.fmt.RI.i2); goto ok;
11496 case 0xa50a: s390_format_RI_RU(s390_irgen_OILH, ovl.fmt.RI.r1,
11497 ovl.fmt.RI.i2); goto ok;
11498 case 0xa50b: s390_format_RI_RU(s390_irgen_OILL, ovl.fmt.RI.r1,
11499 ovl.fmt.RI.i2); goto ok;
11500 case 0xa50c: s390_format_RI_RU(s390_irgen_LLIHH, ovl.fmt.RI.r1,
11501 ovl.fmt.RI.i2); goto ok;
11502 case 0xa50d: s390_format_RI_RU(s390_irgen_LLIHL, ovl.fmt.RI.r1,
11503 ovl.fmt.RI.i2); goto ok;
11504 case 0xa50e: s390_format_RI_RU(s390_irgen_LLILH, ovl.fmt.RI.r1,
11505 ovl.fmt.RI.i2); goto ok;
11506 case 0xa50f: s390_format_RI_RU(s390_irgen_LLILL, ovl.fmt.RI.r1,
11507 ovl.fmt.RI.i2); goto ok;
11508 case 0xa700: s390_format_RI_RU(s390_irgen_TMLH, ovl.fmt.RI.r1,
11509 ovl.fmt.RI.i2); goto ok;
11510 case 0xa701: s390_format_RI_RU(s390_irgen_TMLL, ovl.fmt.RI.r1,
11511 ovl.fmt.RI.i2); goto ok;
11512 case 0xa702: s390_format_RI_RU(s390_irgen_TMHH, ovl.fmt.RI.r1,
11513 ovl.fmt.RI.i2); goto ok;
11514 case 0xa703: s390_format_RI_RU(s390_irgen_TMHL, ovl.fmt.RI.r1,
11515 ovl.fmt.RI.i2); goto ok;
11516 case 0xa704: s390_format_RI(s390_irgen_BRC, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
11517 goto ok;
11518 case 0xa705: s390_format_RI_RP(s390_irgen_BRAS, ovl.fmt.RI.r1,
11519 ovl.fmt.RI.i2); goto ok;
11520 case 0xa706: s390_format_RI_RP(s390_irgen_BRCT, ovl.fmt.RI.r1,
11521 ovl.fmt.RI.i2); goto ok;
11522 case 0xa707: s390_format_RI_RP(s390_irgen_BRCTG, ovl.fmt.RI.r1,
11523 ovl.fmt.RI.i2); goto ok;
11524 case 0xa708: s390_format_RI_RI(s390_irgen_LHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
11525 goto ok;
11526 case 0xa709: s390_format_RI_RI(s390_irgen_LGHI, ovl.fmt.RI.r1,
11527 ovl.fmt.RI.i2); goto ok;
11528 case 0xa70a: s390_format_RI_RI(s390_irgen_AHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
11529 goto ok;
11530 case 0xa70b: s390_format_RI_RI(s390_irgen_AGHI, ovl.fmt.RI.r1,
11531 ovl.fmt.RI.i2); goto ok;
11532 case 0xa70c: s390_format_RI_RI(s390_irgen_MHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
11533 goto ok;
11534 case 0xa70d: s390_format_RI_RI(s390_irgen_MGHI, ovl.fmt.RI.r1,
11535 ovl.fmt.RI.i2); goto ok;
11536 case 0xa70e: s390_format_RI_RI(s390_irgen_CHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
11537 goto ok;
11538 case 0xa70f: s390_format_RI_RI(s390_irgen_CGHI, ovl.fmt.RI.r1,
11539 ovl.fmt.RI.i2); goto ok;
11540 }
11541
11542 switch ((ovl.value & 0xffff0000) >> 16) {
11543 case 0x8000: /* SSM */ goto unimplemented;
11544 case 0x8200: /* LPSW */ goto unimplemented;
florian7700fc92012-01-16 17:25:55 +000011545 case 0x9300: /* TS */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000011546 case 0xb202: /* STIDP */ goto unimplemented;
11547 case 0xb204: /* SCK */ goto unimplemented;
florian7700fc92012-01-16 17:25:55 +000011548 case 0xb205: s390_format_S_RD(s390_irgen_STCK, ovl.fmt.S.b2, ovl.fmt.S.d2);
11549 goto ok;
sewardj2019a972011-03-07 16:04:07 +000011550 case 0xb206: /* SCKC */ goto unimplemented;
11551 case 0xb207: /* STCKC */ goto unimplemented;
11552 case 0xb208: /* SPT */ goto unimplemented;
11553 case 0xb209: /* STPT */ goto unimplemented;
11554 case 0xb20a: /* SPKA */ goto unimplemented;
11555 case 0xb20b: /* IPK */ goto unimplemented;
11556 case 0xb20d: /* PTLB */ goto unimplemented;
11557 case 0xb210: /* SPX */ goto unimplemented;
11558 case 0xb211: /* STPX */ goto unimplemented;
11559 case 0xb212: /* STAP */ goto unimplemented;
11560 case 0xb214: /* SIE */ goto unimplemented;
11561 case 0xb218: /* PC */ goto unimplemented;
11562 case 0xb219: /* SAC */ goto unimplemented;
11563 case 0xb21a: /* CFC */ goto unimplemented;
11564 case 0xb221: /* IPTE */ goto unimplemented;
11565 case 0xb222: s390_format_RRE_R0(s390_irgen_IPM, ovl.fmt.RRE.r1); goto ok;
11566 case 0xb223: /* IVSK */ goto unimplemented;
11567 case 0xb224: /* IAC */ goto unimplemented;
11568 case 0xb225: /* SSAR */ goto unimplemented;
11569 case 0xb226: /* EPAR */ goto unimplemented;
11570 case 0xb227: /* ESAR */ goto unimplemented;
11571 case 0xb228: /* PT */ goto unimplemented;
11572 case 0xb229: /* ISKE */ goto unimplemented;
11573 case 0xb22a: /* RRBE */ goto unimplemented;
11574 case 0xb22b: /* SSKE */ goto unimplemented;
11575 case 0xb22c: /* TB */ goto unimplemented;
11576 case 0xb22d: /* DXR */ goto unimplemented;
11577 case 0xb22e: /* PGIN */ goto unimplemented;
11578 case 0xb22f: /* PGOUT */ goto unimplemented;
11579 case 0xb230: /* CSCH */ goto unimplemented;
11580 case 0xb231: /* HSCH */ goto unimplemented;
11581 case 0xb232: /* MSCH */ goto unimplemented;
11582 case 0xb233: /* SSCH */ goto unimplemented;
11583 case 0xb234: /* STSCH */ goto unimplemented;
11584 case 0xb235: /* TSCH */ goto unimplemented;
11585 case 0xb236: /* TPI */ goto unimplemented;
11586 case 0xb237: /* SAL */ goto unimplemented;
11587 case 0xb238: /* RSCH */ goto unimplemented;
11588 case 0xb239: /* STCRW */ goto unimplemented;
11589 case 0xb23a: /* STCPS */ goto unimplemented;
11590 case 0xb23b: /* RCHP */ goto unimplemented;
11591 case 0xb23c: /* SCHM */ goto unimplemented;
11592 case 0xb240: /* BAKR */ goto unimplemented;
floriana4384a32011-08-11 16:58:45 +000011593 case 0xb241: s390_format_RRE(s390_irgen_CKSM, ovl.fmt.RRE.r1,
11594 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000011595 case 0xb244: /* SQDR */ goto unimplemented;
11596 case 0xb245: /* SQER */ goto unimplemented;
11597 case 0xb246: /* STURA */ goto unimplemented;
11598 case 0xb247: /* MSTA */ goto unimplemented;
11599 case 0xb248: /* PALB */ goto unimplemented;
11600 case 0xb249: /* EREG */ goto unimplemented;
11601 case 0xb24a: /* ESTA */ goto unimplemented;
11602 case 0xb24b: /* LURA */ goto unimplemented;
11603 case 0xb24c: /* TAR */ goto unimplemented;
11604 case 0xb24d: s390_format_RRE(s390_irgen_CPYA, ovl.fmt.RRE.r1,
11605 ovl.fmt.RRE.r2); goto ok;
11606 case 0xb24e: s390_format_RRE(s390_irgen_SAR, ovl.fmt.RRE.r1, ovl.fmt.RRE.r2);
11607 goto ok;
11608 case 0xb24f: s390_format_RRE(s390_irgen_EAR, ovl.fmt.RRE.r1, ovl.fmt.RRE.r2);
11609 goto ok;
11610 case 0xb250: /* CSP */ goto unimplemented;
11611 case 0xb252: s390_format_RRE_RR(s390_irgen_MSR, ovl.fmt.RRE.r1,
11612 ovl.fmt.RRE.r2); goto ok;
11613 case 0xb254: /* MVPG */ goto unimplemented;
11614 case 0xb255: s390_format_RRE_RR(s390_irgen_MVST, ovl.fmt.RRE.r1,
11615 ovl.fmt.RRE.r2); goto ok;
11616 case 0xb257: /* CUSE */ goto unimplemented;
11617 case 0xb258: /* BSG */ goto unimplemented;
11618 case 0xb25a: /* BSA */ goto unimplemented;
11619 case 0xb25d: s390_format_RRE_RR(s390_irgen_CLST, ovl.fmt.RRE.r1,
11620 ovl.fmt.RRE.r2); goto ok;
11621 case 0xb25e: s390_format_RRE_RR(s390_irgen_SRST, ovl.fmt.RRE.r1,
11622 ovl.fmt.RRE.r2); goto ok;
11623 case 0xb263: /* CMPSC */ goto unimplemented;
11624 case 0xb274: /* SIGA */ goto unimplemented;
11625 case 0xb276: /* XSCH */ goto unimplemented;
11626 case 0xb277: /* RP */ goto unimplemented;
sewardj1e5fea62011-05-17 16:18:36 +000011627 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 +000011628 case 0xb279: /* SACF */ goto unimplemented;
sewardj1e5fea62011-05-17 16:18:36 +000011629 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 +000011630 case 0xb27d: /* STSI */ goto unimplemented;
11631 case 0xb299: s390_format_S_RD(s390_irgen_SRNM, ovl.fmt.S.b2, ovl.fmt.S.d2);
11632 goto ok;
11633 case 0xb29c: s390_format_S_RD(s390_irgen_STFPC, ovl.fmt.S.b2, ovl.fmt.S.d2);
11634 goto ok;
11635 case 0xb29d: s390_format_S_RD(s390_irgen_LFPC, ovl.fmt.S.b2, ovl.fmt.S.d2);
11636 goto ok;
florian730448f2012-02-04 17:07:07 +000011637 case 0xb2a5: s390_format_RRE_FF(s390_irgen_TRE, ovl.fmt.RRE.r1, ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000011638 case 0xb2a6: /* CU21 */ goto unimplemented;
11639 case 0xb2a7: /* CU12 */ goto unimplemented;
florian933065d2011-07-11 01:48:02 +000011640 case 0xb2b0: s390_format_S_RD(s390_irgen_STFLE, ovl.fmt.S.b2, ovl.fmt.S.d2);
11641 goto ok;
sewardj2019a972011-03-07 16:04:07 +000011642 case 0xb2b1: /* STFL */ goto unimplemented;
11643 case 0xb2b2: /* LPSWE */ goto unimplemented;
11644 case 0xb2b8: /* SRNMB */ goto unimplemented;
11645 case 0xb2b9: /* SRNMT */ goto unimplemented;
11646 case 0xb2bd: /* LFAS */ goto unimplemented;
11647 case 0xb2ff: /* TRAP4 */ goto unimplemented;
11648 case 0xb300: s390_format_RRE_FF(s390_irgen_LPEBR, ovl.fmt.RRE.r1,
11649 ovl.fmt.RRE.r2); goto ok;
11650 case 0xb301: s390_format_RRE_FF(s390_irgen_LNEBR, ovl.fmt.RRE.r1,
11651 ovl.fmt.RRE.r2); goto ok;
11652 case 0xb302: s390_format_RRE_FF(s390_irgen_LTEBR, ovl.fmt.RRE.r1,
11653 ovl.fmt.RRE.r2); goto ok;
11654 case 0xb303: s390_format_RRE_FF(s390_irgen_LCEBR, ovl.fmt.RRE.r1,
11655 ovl.fmt.RRE.r2); goto ok;
11656 case 0xb304: s390_format_RRE_FF(s390_irgen_LDEBR, ovl.fmt.RRE.r1,
11657 ovl.fmt.RRE.r2); goto ok;
11658 case 0xb305: s390_format_RRE_FF(s390_irgen_LXDBR, ovl.fmt.RRE.r1,
11659 ovl.fmt.RRE.r2); goto ok;
11660 case 0xb306: s390_format_RRE_FF(s390_irgen_LXEBR, ovl.fmt.RRE.r1,
11661 ovl.fmt.RRE.r2); goto ok;
11662 case 0xb307: /* MXDBR */ goto unimplemented;
11663 case 0xb308: /* KEBR */ goto unimplemented;
11664 case 0xb309: s390_format_RRE_FF(s390_irgen_CEBR, ovl.fmt.RRE.r1,
11665 ovl.fmt.RRE.r2); goto ok;
11666 case 0xb30a: s390_format_RRE_FF(s390_irgen_AEBR, ovl.fmt.RRE.r1,
11667 ovl.fmt.RRE.r2); goto ok;
11668 case 0xb30b: s390_format_RRE_FF(s390_irgen_SEBR, ovl.fmt.RRE.r1,
11669 ovl.fmt.RRE.r2); goto ok;
11670 case 0xb30c: /* MDEBR */ goto unimplemented;
11671 case 0xb30d: s390_format_RRE_FF(s390_irgen_DEBR, ovl.fmt.RRE.r1,
11672 ovl.fmt.RRE.r2); goto ok;
11673 case 0xb30e: s390_format_RRF_F0FF(s390_irgen_MAEBR, ovl.fmt.RRF.r1,
11674 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
11675 case 0xb30f: s390_format_RRF_F0FF(s390_irgen_MSEBR, ovl.fmt.RRF.r1,
11676 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
11677 case 0xb310: s390_format_RRE_FF(s390_irgen_LPDBR, ovl.fmt.RRE.r1,
11678 ovl.fmt.RRE.r2); goto ok;
11679 case 0xb311: s390_format_RRE_FF(s390_irgen_LNDBR, ovl.fmt.RRE.r1,
11680 ovl.fmt.RRE.r2); goto ok;
11681 case 0xb312: s390_format_RRE_FF(s390_irgen_LTDBR, ovl.fmt.RRE.r1,
11682 ovl.fmt.RRE.r2); goto ok;
11683 case 0xb313: s390_format_RRE_FF(s390_irgen_LCDBR, ovl.fmt.RRE.r1,
11684 ovl.fmt.RRE.r2); goto ok;
11685 case 0xb314: s390_format_RRE_FF(s390_irgen_SQEBR, ovl.fmt.RRE.r1,
11686 ovl.fmt.RRE.r2); goto ok;
11687 case 0xb315: s390_format_RRE_FF(s390_irgen_SQDBR, ovl.fmt.RRE.r1,
11688 ovl.fmt.RRE.r2); goto ok;
11689 case 0xb316: s390_format_RRE_FF(s390_irgen_SQXBR, ovl.fmt.RRE.r1,
11690 ovl.fmt.RRE.r2); goto ok;
11691 case 0xb317: s390_format_RRE_FF(s390_irgen_MEEBR, ovl.fmt.RRE.r1,
11692 ovl.fmt.RRE.r2); goto ok;
11693 case 0xb318: /* KDBR */ goto unimplemented;
11694 case 0xb319: s390_format_RRE_FF(s390_irgen_CDBR, ovl.fmt.RRE.r1,
11695 ovl.fmt.RRE.r2); goto ok;
11696 case 0xb31a: s390_format_RRE_FF(s390_irgen_ADBR, ovl.fmt.RRE.r1,
11697 ovl.fmt.RRE.r2); goto ok;
11698 case 0xb31b: s390_format_RRE_FF(s390_irgen_SDBR, ovl.fmt.RRE.r1,
11699 ovl.fmt.RRE.r2); goto ok;
11700 case 0xb31c: s390_format_RRE_FF(s390_irgen_MDBR, ovl.fmt.RRE.r1,
11701 ovl.fmt.RRE.r2); goto ok;
11702 case 0xb31d: s390_format_RRE_FF(s390_irgen_DDBR, ovl.fmt.RRE.r1,
11703 ovl.fmt.RRE.r2); goto ok;
11704 case 0xb31e: s390_format_RRF_F0FF(s390_irgen_MADBR, ovl.fmt.RRF.r1,
11705 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
11706 case 0xb31f: s390_format_RRF_F0FF(s390_irgen_MSDBR, ovl.fmt.RRF.r1,
11707 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
11708 case 0xb324: /* LDER */ goto unimplemented;
11709 case 0xb325: /* LXDR */ goto unimplemented;
11710 case 0xb326: /* LXER */ goto unimplemented;
11711 case 0xb32e: /* MAER */ goto unimplemented;
11712 case 0xb32f: /* MSER */ goto unimplemented;
11713 case 0xb336: /* SQXR */ goto unimplemented;
11714 case 0xb337: /* MEER */ goto unimplemented;
11715 case 0xb338: /* MAYLR */ goto unimplemented;
11716 case 0xb339: /* MYLR */ goto unimplemented;
11717 case 0xb33a: /* MAYR */ goto unimplemented;
11718 case 0xb33b: /* MYR */ goto unimplemented;
11719 case 0xb33c: /* MAYHR */ goto unimplemented;
11720 case 0xb33d: /* MYHR */ goto unimplemented;
11721 case 0xb33e: /* MADR */ goto unimplemented;
11722 case 0xb33f: /* MSDR */ goto unimplemented;
11723 case 0xb340: s390_format_RRE_FF(s390_irgen_LPXBR, ovl.fmt.RRE.r1,
11724 ovl.fmt.RRE.r2); goto ok;
11725 case 0xb341: s390_format_RRE_FF(s390_irgen_LNXBR, ovl.fmt.RRE.r1,
11726 ovl.fmt.RRE.r2); goto ok;
11727 case 0xb342: s390_format_RRE_FF(s390_irgen_LTXBR, ovl.fmt.RRE.r1,
11728 ovl.fmt.RRE.r2); goto ok;
11729 case 0xb343: s390_format_RRE_FF(s390_irgen_LCXBR, ovl.fmt.RRE.r1,
11730 ovl.fmt.RRE.r2); goto ok;
11731 case 0xb344: s390_format_RRE_FF(s390_irgen_LEDBR, ovl.fmt.RRE.r1,
11732 ovl.fmt.RRE.r2); goto ok;
11733 case 0xb345: s390_format_RRE_FF(s390_irgen_LDXBR, ovl.fmt.RRE.r1,
11734 ovl.fmt.RRE.r2); goto ok;
11735 case 0xb346: s390_format_RRE_FF(s390_irgen_LEXBR, ovl.fmt.RRE.r1,
11736 ovl.fmt.RRE.r2); goto ok;
11737 case 0xb347: /* FIXBR */ goto unimplemented;
11738 case 0xb348: /* KXBR */ goto unimplemented;
11739 case 0xb349: s390_format_RRE_FF(s390_irgen_CXBR, ovl.fmt.RRE.r1,
11740 ovl.fmt.RRE.r2); goto ok;
11741 case 0xb34a: s390_format_RRE_FF(s390_irgen_AXBR, ovl.fmt.RRE.r1,
11742 ovl.fmt.RRE.r2); goto ok;
11743 case 0xb34b: s390_format_RRE_FF(s390_irgen_SXBR, ovl.fmt.RRE.r1,
11744 ovl.fmt.RRE.r2); goto ok;
11745 case 0xb34c: s390_format_RRE_FF(s390_irgen_MXBR, ovl.fmt.RRE.r1,
11746 ovl.fmt.RRE.r2); goto ok;
11747 case 0xb34d: s390_format_RRE_FF(s390_irgen_DXBR, ovl.fmt.RRE.r1,
11748 ovl.fmt.RRE.r2); goto ok;
11749 case 0xb350: /* TBEDR */ goto unimplemented;
11750 case 0xb351: /* TBDR */ goto unimplemented;
11751 case 0xb353: /* DIEBR */ goto unimplemented;
11752 case 0xb357: /* FIEBR */ goto unimplemented;
11753 case 0xb358: /* THDER */ goto unimplemented;
11754 case 0xb359: /* THDR */ goto unimplemented;
11755 case 0xb35b: /* DIDBR */ goto unimplemented;
11756 case 0xb35f: /* FIDBR */ goto unimplemented;
11757 case 0xb360: /* LPXR */ goto unimplemented;
11758 case 0xb361: /* LNXR */ goto unimplemented;
11759 case 0xb362: /* LTXR */ goto unimplemented;
11760 case 0xb363: /* LCXR */ goto unimplemented;
11761 case 0xb365: s390_format_RRE_FF(s390_irgen_LXR, ovl.fmt.RRE.r1,
11762 ovl.fmt.RRE.r2); goto ok;
11763 case 0xb366: /* LEXR */ goto unimplemented;
11764 case 0xb367: /* FIXR */ goto unimplemented;
11765 case 0xb369: /* CXR */ goto unimplemented;
11766 case 0xb370: s390_format_RRE_FF(s390_irgen_LPDFR, ovl.fmt.RRE.r1,
11767 ovl.fmt.RRE.r2); goto ok;
11768 case 0xb371: s390_format_RRE_FF(s390_irgen_LNDFR, ovl.fmt.RRE.r1,
11769 ovl.fmt.RRE.r2); goto ok;
11770 case 0xb372: s390_format_RRF_F0FF2(s390_irgen_CPSDR, ovl.fmt.RRF3.r3,
11771 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
11772 goto ok;
11773 case 0xb373: s390_format_RRE_FF(s390_irgen_LCDFR, ovl.fmt.RRE.r1,
11774 ovl.fmt.RRE.r2); goto ok;
11775 case 0xb374: s390_format_RRE_F0(s390_irgen_LZER, ovl.fmt.RRE.r1); goto ok;
11776 case 0xb375: s390_format_RRE_F0(s390_irgen_LZDR, ovl.fmt.RRE.r1); goto ok;
11777 case 0xb376: s390_format_RRE_F0(s390_irgen_LZXR, ovl.fmt.RRE.r1); goto ok;
11778 case 0xb377: /* FIER */ goto unimplemented;
11779 case 0xb37f: /* FIDR */ goto unimplemented;
11780 case 0xb384: s390_format_RRE_R0(s390_irgen_SFPC, ovl.fmt.RRE.r1); goto ok;
11781 case 0xb385: /* SFASR */ goto unimplemented;
11782 case 0xb38c: s390_format_RRE_R0(s390_irgen_EFPC, ovl.fmt.RRE.r1); goto ok;
11783 case 0xb390: /* CELFBR */ goto unimplemented;
11784 case 0xb391: /* CDLFBR */ goto unimplemented;
11785 case 0xb392: /* CXLFBR */ goto unimplemented;
11786 case 0xb394: s390_format_RRE_FR(s390_irgen_CEFBR, ovl.fmt.RRE.r1,
11787 ovl.fmt.RRE.r2); goto ok;
11788 case 0xb395: s390_format_RRE_FR(s390_irgen_CDFBR, ovl.fmt.RRE.r1,
11789 ovl.fmt.RRE.r2); goto ok;
11790 case 0xb396: s390_format_RRE_FR(s390_irgen_CXFBR, ovl.fmt.RRE.r1,
11791 ovl.fmt.RRE.r2); goto ok;
11792 case 0xb398: s390_format_RRF_U0RF(s390_irgen_CFEBR, ovl.fmt.RRF3.r3,
11793 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
11794 goto ok;
11795 case 0xb399: s390_format_RRF_U0RF(s390_irgen_CFDBR, ovl.fmt.RRF3.r3,
11796 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
11797 goto ok;
11798 case 0xb39a: s390_format_RRF_U0RF(s390_irgen_CFXBR, ovl.fmt.RRF3.r3,
11799 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
11800 goto ok;
11801 case 0xb3a0: /* CELGBR */ goto unimplemented;
11802 case 0xb3a1: /* CDLGBR */ goto unimplemented;
11803 case 0xb3a2: /* CXLGBR */ goto unimplemented;
11804 case 0xb3a4: s390_format_RRE_FR(s390_irgen_CEGBR, ovl.fmt.RRE.r1,
11805 ovl.fmt.RRE.r2); goto ok;
11806 case 0xb3a5: s390_format_RRE_FR(s390_irgen_CDGBR, ovl.fmt.RRE.r1,
11807 ovl.fmt.RRE.r2); goto ok;
11808 case 0xb3a6: s390_format_RRE_FR(s390_irgen_CXGBR, ovl.fmt.RRE.r1,
11809 ovl.fmt.RRE.r2); goto ok;
11810 case 0xb3a8: s390_format_RRF_U0RF(s390_irgen_CGEBR, ovl.fmt.RRF3.r3,
11811 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
11812 goto ok;
11813 case 0xb3a9: s390_format_RRF_U0RF(s390_irgen_CGDBR, ovl.fmt.RRF3.r3,
11814 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
11815 goto ok;
11816 case 0xb3aa: s390_format_RRF_U0RF(s390_irgen_CGXBR, ovl.fmt.RRF3.r3,
11817 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
11818 goto ok;
11819 case 0xb3b4: /* CEFR */ goto unimplemented;
11820 case 0xb3b5: /* CDFR */ goto unimplemented;
11821 case 0xb3b6: /* CXFR */ goto unimplemented;
11822 case 0xb3b8: /* CFER */ goto unimplemented;
11823 case 0xb3b9: /* CFDR */ goto unimplemented;
11824 case 0xb3ba: /* CFXR */ goto unimplemented;
11825 case 0xb3c1: s390_format_RRE_FR(s390_irgen_LDGR, ovl.fmt.RRE.r1,
11826 ovl.fmt.RRE.r2); goto ok;
11827 case 0xb3c4: /* CEGR */ goto unimplemented;
11828 case 0xb3c5: /* CDGR */ goto unimplemented;
11829 case 0xb3c6: /* CXGR */ goto unimplemented;
11830 case 0xb3c8: /* CGER */ goto unimplemented;
11831 case 0xb3c9: /* CGDR */ goto unimplemented;
11832 case 0xb3ca: /* CGXR */ goto unimplemented;
11833 case 0xb3cd: s390_format_RRE_RF(s390_irgen_LGDR, ovl.fmt.RRE.r1,
11834 ovl.fmt.RRE.r2); goto ok;
11835 case 0xb3d0: /* MDTR */ goto unimplemented;
11836 case 0xb3d1: /* DDTR */ goto unimplemented;
11837 case 0xb3d2: /* ADTR */ goto unimplemented;
11838 case 0xb3d3: /* SDTR */ goto unimplemented;
11839 case 0xb3d4: /* LDETR */ goto unimplemented;
11840 case 0xb3d5: /* LEDTR */ goto unimplemented;
11841 case 0xb3d6: /* LTDTR */ goto unimplemented;
11842 case 0xb3d7: /* FIDTR */ goto unimplemented;
11843 case 0xb3d8: /* MXTR */ goto unimplemented;
11844 case 0xb3d9: /* DXTR */ goto unimplemented;
11845 case 0xb3da: /* AXTR */ goto unimplemented;
11846 case 0xb3db: /* SXTR */ goto unimplemented;
11847 case 0xb3dc: /* LXDTR */ goto unimplemented;
11848 case 0xb3dd: /* LDXTR */ goto unimplemented;
11849 case 0xb3de: /* LTXTR */ goto unimplemented;
11850 case 0xb3df: /* FIXTR */ goto unimplemented;
11851 case 0xb3e0: /* KDTR */ goto unimplemented;
11852 case 0xb3e1: /* CGDTR */ goto unimplemented;
11853 case 0xb3e2: /* CUDTR */ goto unimplemented;
11854 case 0xb3e3: /* CSDTR */ goto unimplemented;
11855 case 0xb3e4: /* CDTR */ goto unimplemented;
11856 case 0xb3e5: /* EEDTR */ goto unimplemented;
11857 case 0xb3e7: /* ESDTR */ goto unimplemented;
11858 case 0xb3e8: /* KXTR */ goto unimplemented;
11859 case 0xb3e9: /* CGXTR */ goto unimplemented;
11860 case 0xb3ea: /* CUXTR */ goto unimplemented;
11861 case 0xb3eb: /* CSXTR */ goto unimplemented;
11862 case 0xb3ec: /* CXTR */ goto unimplemented;
11863 case 0xb3ed: /* EEXTR */ goto unimplemented;
11864 case 0xb3ef: /* ESXTR */ goto unimplemented;
11865 case 0xb3f1: /* CDGTR */ goto unimplemented;
11866 case 0xb3f2: /* CDUTR */ goto unimplemented;
11867 case 0xb3f3: /* CDSTR */ goto unimplemented;
11868 case 0xb3f4: /* CEDTR */ goto unimplemented;
11869 case 0xb3f5: /* QADTR */ goto unimplemented;
11870 case 0xb3f6: /* IEDTR */ goto unimplemented;
11871 case 0xb3f7: /* RRDTR */ goto unimplemented;
11872 case 0xb3f9: /* CXGTR */ goto unimplemented;
11873 case 0xb3fa: /* CXUTR */ goto unimplemented;
11874 case 0xb3fb: /* CXSTR */ goto unimplemented;
11875 case 0xb3fc: /* CEXTR */ goto unimplemented;
11876 case 0xb3fd: /* QAXTR */ goto unimplemented;
11877 case 0xb3fe: /* IEXTR */ goto unimplemented;
11878 case 0xb3ff: /* RRXTR */ goto unimplemented;
11879 case 0xb900: s390_format_RRE_RR(s390_irgen_LPGR, ovl.fmt.RRE.r1,
11880 ovl.fmt.RRE.r2); goto ok;
11881 case 0xb901: s390_format_RRE_RR(s390_irgen_LNGR, ovl.fmt.RRE.r1,
11882 ovl.fmt.RRE.r2); goto ok;
11883 case 0xb902: s390_format_RRE_RR(s390_irgen_LTGR, ovl.fmt.RRE.r1,
11884 ovl.fmt.RRE.r2); goto ok;
11885 case 0xb903: s390_format_RRE_RR(s390_irgen_LCGR, ovl.fmt.RRE.r1,
11886 ovl.fmt.RRE.r2); goto ok;
11887 case 0xb904: s390_format_RRE_RR(s390_irgen_LGR, ovl.fmt.RRE.r1,
11888 ovl.fmt.RRE.r2); goto ok;
11889 case 0xb905: /* LURAG */ goto unimplemented;
11890 case 0xb906: s390_format_RRE_RR(s390_irgen_LGBR, ovl.fmt.RRE.r1,
11891 ovl.fmt.RRE.r2); goto ok;
11892 case 0xb907: s390_format_RRE_RR(s390_irgen_LGHR, ovl.fmt.RRE.r1,
11893 ovl.fmt.RRE.r2); goto ok;
11894 case 0xb908: s390_format_RRE_RR(s390_irgen_AGR, ovl.fmt.RRE.r1,
11895 ovl.fmt.RRE.r2); goto ok;
11896 case 0xb909: s390_format_RRE_RR(s390_irgen_SGR, ovl.fmt.RRE.r1,
11897 ovl.fmt.RRE.r2); goto ok;
11898 case 0xb90a: s390_format_RRE_RR(s390_irgen_ALGR, ovl.fmt.RRE.r1,
11899 ovl.fmt.RRE.r2); goto ok;
11900 case 0xb90b: s390_format_RRE_RR(s390_irgen_SLGR, ovl.fmt.RRE.r1,
11901 ovl.fmt.RRE.r2); goto ok;
11902 case 0xb90c: s390_format_RRE_RR(s390_irgen_MSGR, ovl.fmt.RRE.r1,
11903 ovl.fmt.RRE.r2); goto ok;
11904 case 0xb90d: s390_format_RRE_RR(s390_irgen_DSGR, ovl.fmt.RRE.r1,
11905 ovl.fmt.RRE.r2); goto ok;
11906 case 0xb90e: /* EREGG */ goto unimplemented;
11907 case 0xb90f: s390_format_RRE_RR(s390_irgen_LRVGR, ovl.fmt.RRE.r1,
11908 ovl.fmt.RRE.r2); goto ok;
11909 case 0xb910: s390_format_RRE_RR(s390_irgen_LPGFR, ovl.fmt.RRE.r1,
11910 ovl.fmt.RRE.r2); goto ok;
11911 case 0xb911: s390_format_RRE_RR(s390_irgen_LNGFR, ovl.fmt.RRE.r1,
11912 ovl.fmt.RRE.r2); goto ok;
11913 case 0xb912: s390_format_RRE_RR(s390_irgen_LTGFR, ovl.fmt.RRE.r1,
11914 ovl.fmt.RRE.r2); goto ok;
11915 case 0xb913: s390_format_RRE_RR(s390_irgen_LCGFR, ovl.fmt.RRE.r1,
11916 ovl.fmt.RRE.r2); goto ok;
11917 case 0xb914: s390_format_RRE_RR(s390_irgen_LGFR, ovl.fmt.RRE.r1,
11918 ovl.fmt.RRE.r2); goto ok;
11919 case 0xb916: s390_format_RRE_RR(s390_irgen_LLGFR, ovl.fmt.RRE.r1,
11920 ovl.fmt.RRE.r2); goto ok;
11921 case 0xb917: s390_format_RRE_RR(s390_irgen_LLGTR, ovl.fmt.RRE.r1,
11922 ovl.fmt.RRE.r2); goto ok;
11923 case 0xb918: s390_format_RRE_RR(s390_irgen_AGFR, ovl.fmt.RRE.r1,
11924 ovl.fmt.RRE.r2); goto ok;
11925 case 0xb919: s390_format_RRE_RR(s390_irgen_SGFR, ovl.fmt.RRE.r1,
11926 ovl.fmt.RRE.r2); goto ok;
11927 case 0xb91a: s390_format_RRE_RR(s390_irgen_ALGFR, ovl.fmt.RRE.r1,
11928 ovl.fmt.RRE.r2); goto ok;
11929 case 0xb91b: s390_format_RRE_RR(s390_irgen_SLGFR, ovl.fmt.RRE.r1,
11930 ovl.fmt.RRE.r2); goto ok;
11931 case 0xb91c: s390_format_RRE_RR(s390_irgen_MSGFR, ovl.fmt.RRE.r1,
11932 ovl.fmt.RRE.r2); goto ok;
11933 case 0xb91d: s390_format_RRE_RR(s390_irgen_DSGFR, ovl.fmt.RRE.r1,
11934 ovl.fmt.RRE.r2); goto ok;
11935 case 0xb91e: /* KMAC */ goto unimplemented;
11936 case 0xb91f: s390_format_RRE_RR(s390_irgen_LRVR, ovl.fmt.RRE.r1,
11937 ovl.fmt.RRE.r2); goto ok;
11938 case 0xb920: s390_format_RRE_RR(s390_irgen_CGR, ovl.fmt.RRE.r1,
11939 ovl.fmt.RRE.r2); goto ok;
11940 case 0xb921: s390_format_RRE_RR(s390_irgen_CLGR, ovl.fmt.RRE.r1,
11941 ovl.fmt.RRE.r2); goto ok;
11942 case 0xb925: /* STURG */ goto unimplemented;
11943 case 0xb926: s390_format_RRE_RR(s390_irgen_LBR, ovl.fmt.RRE.r1,
11944 ovl.fmt.RRE.r2); goto ok;
11945 case 0xb927: s390_format_RRE_RR(s390_irgen_LHR, ovl.fmt.RRE.r1,
11946 ovl.fmt.RRE.r2); goto ok;
11947 case 0xb928: /* PCKMO */ goto unimplemented;
11948 case 0xb92b: /* KMO */ goto unimplemented;
11949 case 0xb92c: /* PCC */ goto unimplemented;
11950 case 0xb92d: /* KMCTR */ goto unimplemented;
11951 case 0xb92e: /* KM */ goto unimplemented;
11952 case 0xb92f: /* KMC */ goto unimplemented;
11953 case 0xb930: s390_format_RRE_RR(s390_irgen_CGFR, ovl.fmt.RRE.r1,
11954 ovl.fmt.RRE.r2); goto ok;
11955 case 0xb931: s390_format_RRE_RR(s390_irgen_CLGFR, ovl.fmt.RRE.r1,
11956 ovl.fmt.RRE.r2); goto ok;
11957 case 0xb93e: /* KIMD */ goto unimplemented;
11958 case 0xb93f: /* KLMD */ goto unimplemented;
11959 case 0xb941: /* CFDTR */ goto unimplemented;
11960 case 0xb942: /* CLGDTR */ goto unimplemented;
11961 case 0xb943: /* CLFDTR */ goto unimplemented;
11962 case 0xb946: s390_format_RRE_RR(s390_irgen_BCTGR, ovl.fmt.RRE.r1,
11963 ovl.fmt.RRE.r2); goto ok;
11964 case 0xb949: /* CFXTR */ goto unimplemented;
11965 case 0xb94a: /* CLGXTR */ goto unimplemented;
11966 case 0xb94b: /* CLFXTR */ goto unimplemented;
11967 case 0xb951: /* CDFTR */ goto unimplemented;
11968 case 0xb952: /* CDLGTR */ goto unimplemented;
11969 case 0xb953: /* CDLFTR */ goto unimplemented;
11970 case 0xb959: /* CXFTR */ goto unimplemented;
11971 case 0xb95a: /* CXLGTR */ goto unimplemented;
11972 case 0xb95b: /* CXLFTR */ goto unimplemented;
11973 case 0xb960: /* CGRT */ goto unimplemented;
11974 case 0xb961: /* CLGRT */ goto unimplemented;
11975 case 0xb972: /* CRT */ goto unimplemented;
11976 case 0xb973: /* CLRT */ goto unimplemented;
11977 case 0xb980: s390_format_RRE_RR(s390_irgen_NGR, ovl.fmt.RRE.r1,
11978 ovl.fmt.RRE.r2); goto ok;
11979 case 0xb981: s390_format_RRE_RR(s390_irgen_OGR, ovl.fmt.RRE.r1,
11980 ovl.fmt.RRE.r2); goto ok;
11981 case 0xb982: s390_format_RRE_RR(s390_irgen_XGR, ovl.fmt.RRE.r1,
11982 ovl.fmt.RRE.r2); goto ok;
11983 case 0xb983: s390_format_RRE_RR(s390_irgen_FLOGR, ovl.fmt.RRE.r1,
11984 ovl.fmt.RRE.r2); goto ok;
11985 case 0xb984: s390_format_RRE_RR(s390_irgen_LLGCR, ovl.fmt.RRE.r1,
11986 ovl.fmt.RRE.r2); goto ok;
11987 case 0xb985: s390_format_RRE_RR(s390_irgen_LLGHR, ovl.fmt.RRE.r1,
11988 ovl.fmt.RRE.r2); goto ok;
11989 case 0xb986: s390_format_RRE_RR(s390_irgen_MLGR, ovl.fmt.RRE.r1,
11990 ovl.fmt.RRE.r2); goto ok;
11991 case 0xb987: s390_format_RRE_RR(s390_irgen_DLGR, ovl.fmt.RRE.r1,
11992 ovl.fmt.RRE.r2); goto ok;
11993 case 0xb988: s390_format_RRE_RR(s390_irgen_ALCGR, ovl.fmt.RRE.r1,
11994 ovl.fmt.RRE.r2); goto ok;
11995 case 0xb989: s390_format_RRE_RR(s390_irgen_SLBGR, ovl.fmt.RRE.r1,
11996 ovl.fmt.RRE.r2); goto ok;
11997 case 0xb98a: /* CSPG */ goto unimplemented;
11998 case 0xb98d: /* EPSW */ goto unimplemented;
11999 case 0xb98e: /* IDTE */ goto unimplemented;
florian730448f2012-02-04 17:07:07 +000012000 case 0xb990: s390_format_RRF_M0RERE(s390_irgen_TRTT, ovl.fmt.RRF3.r3,
12001 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
12002 case 0xb991: s390_format_RRF_M0RERE(s390_irgen_TRTO, ovl.fmt.RRF3.r3,
12003 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
12004 case 0xb992: s390_format_RRF_M0RERE(s390_irgen_TROT, ovl.fmt.RRF3.r3,
12005 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
florian9af37692012-01-15 21:01:16 +000012006 case 0xb993: s390_format_RRF_M0RERE(s390_irgen_TROO, ovl.fmt.RRF3.r3,
12007 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000012008 case 0xb994: s390_format_RRE_RR(s390_irgen_LLCR, ovl.fmt.RRE.r1,
12009 ovl.fmt.RRE.r2); goto ok;
12010 case 0xb995: s390_format_RRE_RR(s390_irgen_LLHR, ovl.fmt.RRE.r1,
12011 ovl.fmt.RRE.r2); goto ok;
12012 case 0xb996: s390_format_RRE_RR(s390_irgen_MLR, ovl.fmt.RRE.r1,
12013 ovl.fmt.RRE.r2); goto ok;
12014 case 0xb997: s390_format_RRE_RR(s390_irgen_DLR, ovl.fmt.RRE.r1,
12015 ovl.fmt.RRE.r2); goto ok;
12016 case 0xb998: s390_format_RRE_RR(s390_irgen_ALCR, ovl.fmt.RRE.r1,
12017 ovl.fmt.RRE.r2); goto ok;
12018 case 0xb999: s390_format_RRE_RR(s390_irgen_SLBR, ovl.fmt.RRE.r1,
12019 ovl.fmt.RRE.r2); goto ok;
12020 case 0xb99a: /* EPAIR */ goto unimplemented;
12021 case 0xb99b: /* ESAIR */ goto unimplemented;
12022 case 0xb99d: /* ESEA */ goto unimplemented;
12023 case 0xb99e: /* PTI */ goto unimplemented;
12024 case 0xb99f: /* SSAIR */ goto unimplemented;
12025 case 0xb9a2: /* PTF */ goto unimplemented;
12026 case 0xb9aa: /* LPTEA */ goto unimplemented;
12027 case 0xb9ae: /* RRBM */ goto unimplemented;
12028 case 0xb9af: /* PFMF */ goto unimplemented;
12029 case 0xb9b0: /* CU14 */ goto unimplemented;
12030 case 0xb9b1: /* CU24 */ goto unimplemented;
12031 case 0xb9b2: /* CU41 */ goto unimplemented;
12032 case 0xb9b3: /* CU42 */ goto unimplemented;
12033 case 0xb9bd: /* TRTRE */ goto unimplemented;
12034 case 0xb9be: /* SRSTU */ goto unimplemented;
12035 case 0xb9bf: /* TRTE */ goto unimplemented;
12036 case 0xb9c8: s390_format_RRF_R0RR2(s390_irgen_AHHHR, ovl.fmt.RRF4.r3,
12037 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12038 goto ok;
12039 case 0xb9c9: s390_format_RRF_R0RR2(s390_irgen_SHHHR, ovl.fmt.RRF4.r3,
12040 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12041 goto ok;
12042 case 0xb9ca: s390_format_RRF_R0RR2(s390_irgen_ALHHHR, ovl.fmt.RRF4.r3,
12043 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12044 goto ok;
12045 case 0xb9cb: s390_format_RRF_R0RR2(s390_irgen_SLHHHR, ovl.fmt.RRF4.r3,
12046 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12047 goto ok;
12048 case 0xb9cd: s390_format_RRE_RR(s390_irgen_CHHR, ovl.fmt.RRE.r1,
12049 ovl.fmt.RRE.r2); goto ok;
12050 case 0xb9cf: s390_format_RRE_RR(s390_irgen_CLHHR, ovl.fmt.RRE.r1,
12051 ovl.fmt.RRE.r2); goto ok;
12052 case 0xb9d8: s390_format_RRF_R0RR2(s390_irgen_AHHLR, ovl.fmt.RRF4.r3,
12053 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12054 goto ok;
12055 case 0xb9d9: s390_format_RRF_R0RR2(s390_irgen_SHHLR, ovl.fmt.RRF4.r3,
12056 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12057 goto ok;
12058 case 0xb9da: s390_format_RRF_R0RR2(s390_irgen_ALHHLR, ovl.fmt.RRF4.r3,
12059 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12060 goto ok;
12061 case 0xb9db: s390_format_RRF_R0RR2(s390_irgen_SLHHLR, ovl.fmt.RRF4.r3,
12062 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12063 goto ok;
12064 case 0xb9dd: s390_format_RRE_RR(s390_irgen_CHLR, ovl.fmt.RRE.r1,
12065 ovl.fmt.RRE.r2); goto ok;
12066 case 0xb9df: s390_format_RRE_RR(s390_irgen_CLHLR, ovl.fmt.RRE.r1,
12067 ovl.fmt.RRE.r2); goto ok;
12068 case 0xb9e1: /* POPCNT */ goto unimplemented;
sewardjd7bde722011-04-05 13:19:33 +000012069 case 0xb9e2: s390_format_RRF_U0RR(s390_irgen_LOCGR, ovl.fmt.RRF3.r3,
12070 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2,
12071 S390_XMNM_LOCGR); goto ok;
sewardj2019a972011-03-07 16:04:07 +000012072 case 0xb9e4: s390_format_RRF_R0RR2(s390_irgen_NGRK, ovl.fmt.RRF4.r3,
12073 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12074 goto ok;
12075 case 0xb9e6: s390_format_RRF_R0RR2(s390_irgen_OGRK, ovl.fmt.RRF4.r3,
12076 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12077 goto ok;
12078 case 0xb9e7: s390_format_RRF_R0RR2(s390_irgen_XGRK, ovl.fmt.RRF4.r3,
12079 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12080 goto ok;
12081 case 0xb9e8: s390_format_RRF_R0RR2(s390_irgen_AGRK, ovl.fmt.RRF4.r3,
12082 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12083 goto ok;
12084 case 0xb9e9: s390_format_RRF_R0RR2(s390_irgen_SGRK, ovl.fmt.RRF4.r3,
12085 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12086 goto ok;
12087 case 0xb9ea: s390_format_RRF_R0RR2(s390_irgen_ALGRK, ovl.fmt.RRF4.r3,
12088 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12089 goto ok;
12090 case 0xb9eb: s390_format_RRF_R0RR2(s390_irgen_SLGRK, ovl.fmt.RRF4.r3,
12091 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12092 goto ok;
sewardjd7bde722011-04-05 13:19:33 +000012093 case 0xb9f2: s390_format_RRF_U0RR(s390_irgen_LOCR, ovl.fmt.RRF3.r3,
12094 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2,
12095 S390_XMNM_LOCR); goto ok;
sewardj2019a972011-03-07 16:04:07 +000012096 case 0xb9f4: s390_format_RRF_R0RR2(s390_irgen_NRK, ovl.fmt.RRF4.r3,
12097 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12098 goto ok;
12099 case 0xb9f6: s390_format_RRF_R0RR2(s390_irgen_ORK, ovl.fmt.RRF4.r3,
12100 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12101 goto ok;
12102 case 0xb9f7: s390_format_RRF_R0RR2(s390_irgen_XRK, ovl.fmt.RRF4.r3,
12103 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12104 goto ok;
12105 case 0xb9f8: s390_format_RRF_R0RR2(s390_irgen_ARK, ovl.fmt.RRF4.r3,
12106 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12107 goto ok;
12108 case 0xb9f9: s390_format_RRF_R0RR2(s390_irgen_SRK, ovl.fmt.RRF4.r3,
12109 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12110 goto ok;
12111 case 0xb9fa: s390_format_RRF_R0RR2(s390_irgen_ALRK, ovl.fmt.RRF4.r3,
12112 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12113 goto ok;
12114 case 0xb9fb: s390_format_RRF_R0RR2(s390_irgen_SLRK, ovl.fmt.RRF4.r3,
12115 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12116 goto ok;
12117 }
12118
12119 switch ((ovl.value & 0xff000000) >> 24) {
12120 case 0x40: s390_format_RX_RRRD(s390_irgen_STH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12121 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12122 case 0x41: s390_format_RX_RRRD(s390_irgen_LA, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12123 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12124 case 0x42: s390_format_RX_RRRD(s390_irgen_STC, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12125 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12126 case 0x43: s390_format_RX_RRRD(s390_irgen_IC, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12127 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12128 case 0x44: s390_format_RX_RRRD(s390_irgen_EX, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12129 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12130 case 0x45: /* BAL */ goto unimplemented;
12131 case 0x46: s390_format_RX_RRRD(s390_irgen_BCT, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12132 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12133 case 0x47: s390_format_RX(s390_irgen_BC, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12134 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12135 case 0x48: s390_format_RX_RRRD(s390_irgen_LH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12136 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12137 case 0x49: s390_format_RX_RRRD(s390_irgen_CH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12138 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12139 case 0x4a: s390_format_RX_RRRD(s390_irgen_AH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12140 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12141 case 0x4b: s390_format_RX_RRRD(s390_irgen_SH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12142 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12143 case 0x4c: s390_format_RX_RRRD(s390_irgen_MH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12144 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12145 case 0x4d: s390_format_RX_RRRD(s390_irgen_BAS, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12146 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12147 case 0x4e: s390_format_RX_RRRD(s390_irgen_CVD, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12148 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12149 case 0x4f: s390_format_RX_RRRD(s390_irgen_CVB, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12150 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12151 case 0x50: s390_format_RX_RRRD(s390_irgen_ST, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12152 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12153 case 0x51: s390_format_RX_RRRD(s390_irgen_LAE, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12154 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12155 case 0x54: s390_format_RX_RRRD(s390_irgen_N, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12156 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12157 case 0x55: s390_format_RX_RRRD(s390_irgen_CL, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12158 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12159 case 0x56: s390_format_RX_RRRD(s390_irgen_O, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12160 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12161 case 0x57: s390_format_RX_RRRD(s390_irgen_X, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12162 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12163 case 0x58: s390_format_RX_RRRD(s390_irgen_L, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12164 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12165 case 0x59: s390_format_RX_RRRD(s390_irgen_C, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12166 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12167 case 0x5a: s390_format_RX_RRRD(s390_irgen_A, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12168 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12169 case 0x5b: s390_format_RX_RRRD(s390_irgen_S, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12170 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12171 case 0x5c: s390_format_RX_RRRD(s390_irgen_M, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12172 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12173 case 0x5d: s390_format_RX_RRRD(s390_irgen_D, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12174 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12175 case 0x5e: s390_format_RX_RRRD(s390_irgen_AL, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12176 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12177 case 0x5f: s390_format_RX_RRRD(s390_irgen_SL, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12178 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12179 case 0x60: s390_format_RX_FRRD(s390_irgen_STD, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12180 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12181 case 0x67: /* MXD */ goto unimplemented;
12182 case 0x68: s390_format_RX_FRRD(s390_irgen_LD, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12183 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12184 case 0x69: /* CD */ goto unimplemented;
12185 case 0x6a: /* AD */ goto unimplemented;
12186 case 0x6b: /* SD */ goto unimplemented;
12187 case 0x6c: /* MD */ goto unimplemented;
12188 case 0x6d: /* DD */ goto unimplemented;
12189 case 0x6e: /* AW */ goto unimplemented;
12190 case 0x6f: /* SW */ goto unimplemented;
12191 case 0x70: s390_format_RX_FRRD(s390_irgen_STE, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12192 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12193 case 0x71: s390_format_RX_RRRD(s390_irgen_MS, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12194 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12195 case 0x78: s390_format_RX_FRRD(s390_irgen_LE, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12196 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12197 case 0x79: /* CE */ goto unimplemented;
12198 case 0x7a: /* AE */ goto unimplemented;
12199 case 0x7b: /* SE */ goto unimplemented;
12200 case 0x7c: /* MDE */ goto unimplemented;
12201 case 0x7d: /* DE */ goto unimplemented;
12202 case 0x7e: /* AU */ goto unimplemented;
12203 case 0x7f: /* SU */ goto unimplemented;
12204 case 0x83: /* DIAG */ goto unimplemented;
12205 case 0x84: s390_format_RSI_RRP(s390_irgen_BRXH, ovl.fmt.RSI.r1,
12206 ovl.fmt.RSI.r3, ovl.fmt.RSI.i2); goto ok;
12207 case 0x85: s390_format_RSI_RRP(s390_irgen_BRXLE, ovl.fmt.RSI.r1,
12208 ovl.fmt.RSI.r3, ovl.fmt.RSI.i2); goto ok;
12209 case 0x86: s390_format_RS_RRRD(s390_irgen_BXH, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
12210 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
12211 case 0x87: s390_format_RS_RRRD(s390_irgen_BXLE, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
12212 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
12213 case 0x88: s390_format_RS_R0RD(s390_irgen_SRL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
12214 ovl.fmt.RS.d2); goto ok;
12215 case 0x89: s390_format_RS_R0RD(s390_irgen_SLL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
12216 ovl.fmt.RS.d2); goto ok;
12217 case 0x8a: s390_format_RS_R0RD(s390_irgen_SRA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
12218 ovl.fmt.RS.d2); goto ok;
12219 case 0x8b: s390_format_RS_R0RD(s390_irgen_SLA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
12220 ovl.fmt.RS.d2); goto ok;
12221 case 0x8c: s390_format_RS_R0RD(s390_irgen_SRDL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
12222 ovl.fmt.RS.d2); goto ok;
12223 case 0x8d: s390_format_RS_R0RD(s390_irgen_SLDL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
12224 ovl.fmt.RS.d2); goto ok;
12225 case 0x8e: s390_format_RS_R0RD(s390_irgen_SRDA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
12226 ovl.fmt.RS.d2); goto ok;
12227 case 0x8f: s390_format_RS_R0RD(s390_irgen_SLDA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
12228 ovl.fmt.RS.d2); goto ok;
12229 case 0x90: s390_format_RS_RRRD(s390_irgen_STM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
12230 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
12231 case 0x91: s390_format_SI_URD(s390_irgen_TM, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
12232 ovl.fmt.SI.d1); goto ok;
12233 case 0x92: s390_format_SI_URD(s390_irgen_MVI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
12234 ovl.fmt.SI.d1); goto ok;
12235 case 0x94: s390_format_SI_URD(s390_irgen_NI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
12236 ovl.fmt.SI.d1); goto ok;
12237 case 0x95: s390_format_SI_URD(s390_irgen_CLI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
12238 ovl.fmt.SI.d1); goto ok;
12239 case 0x96: s390_format_SI_URD(s390_irgen_OI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
12240 ovl.fmt.SI.d1); goto ok;
12241 case 0x97: s390_format_SI_URD(s390_irgen_XI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
12242 ovl.fmt.SI.d1); goto ok;
12243 case 0x98: s390_format_RS_RRRD(s390_irgen_LM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
12244 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
12245 case 0x99: /* TRACE */ goto unimplemented;
12246 case 0x9a: s390_format_RS_AARD(s390_irgen_LAM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
12247 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
12248 case 0x9b: s390_format_RS_AARD(s390_irgen_STAM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
12249 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
12250 case 0xa8: s390_format_RS_RRRD(s390_irgen_MVCLE, ovl.fmt.RS.r1,
12251 ovl.fmt.RS.r3, ovl.fmt.RS.b2, ovl.fmt.RS.d2);
12252 goto ok;
12253 case 0xa9: s390_format_RS_RRRD(s390_irgen_CLCLE, ovl.fmt.RS.r1,
12254 ovl.fmt.RS.r3, ovl.fmt.RS.b2, ovl.fmt.RS.d2);
12255 goto ok;
12256 case 0xac: /* STNSM */ goto unimplemented;
12257 case 0xad: /* STOSM */ goto unimplemented;
12258 case 0xae: /* SIGP */ goto unimplemented;
12259 case 0xaf: /* MC */ goto unimplemented;
12260 case 0xb1: /* LRA */ goto unimplemented;
12261 case 0xb6: /* STCTL */ goto unimplemented;
12262 case 0xb7: /* LCTL */ goto unimplemented;
12263 case 0xba: s390_format_RS_RRRD(s390_irgen_CS, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
12264 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
florian448cbba2012-06-06 02:26:01 +000012265 case 0xbb: s390_format_RS_RRRD(s390_irgen_CDS, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
12266 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000012267 case 0xbd: s390_format_RS_RURD(s390_irgen_CLM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
12268 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
12269 case 0xbe: s390_format_RS_RURD(s390_irgen_STCM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
12270 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
12271 case 0xbf: s390_format_RS_RURD(s390_irgen_ICM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
12272 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
12273 }
12274
12275 return S390_DECODE_UNKNOWN_INSN;
12276
12277ok:
12278 return S390_DECODE_OK;
12279
12280unimplemented:
12281 return S390_DECODE_UNIMPLEMENTED_INSN;
12282}
12283
12284static s390_decode_t
12285s390_decode_6byte_and_irgen(UChar *bytes)
12286{
12287 typedef union {
12288 struct {
12289 unsigned int op1 : 8;
12290 unsigned int r1 : 4;
12291 unsigned int r3 : 4;
12292 unsigned int i2 : 16;
12293 unsigned int : 8;
12294 unsigned int op2 : 8;
12295 } RIE;
12296 struct {
12297 unsigned int op1 : 8;
12298 unsigned int r1 : 4;
12299 unsigned int r2 : 4;
12300 unsigned int i3 : 8;
12301 unsigned int i4 : 8;
12302 unsigned int i5 : 8;
12303 unsigned int op2 : 8;
12304 } RIE_RRUUU;
12305 struct {
12306 unsigned int op1 : 8;
12307 unsigned int r1 : 4;
12308 unsigned int : 4;
12309 unsigned int i2 : 16;
12310 unsigned int m3 : 4;
12311 unsigned int : 4;
12312 unsigned int op2 : 8;
12313 } RIEv1;
12314 struct {
12315 unsigned int op1 : 8;
12316 unsigned int r1 : 4;
12317 unsigned int r2 : 4;
12318 unsigned int i4 : 16;
12319 unsigned int m3 : 4;
12320 unsigned int : 4;
12321 unsigned int op2 : 8;
12322 } RIE_RRPU;
12323 struct {
12324 unsigned int op1 : 8;
12325 unsigned int r1 : 4;
12326 unsigned int m3 : 4;
12327 unsigned int i4 : 16;
12328 unsigned int i2 : 8;
12329 unsigned int op2 : 8;
12330 } RIEv3;
12331 struct {
12332 unsigned int op1 : 8;
12333 unsigned int r1 : 4;
12334 unsigned int op2 : 4;
12335 unsigned int i2 : 32;
12336 } RIL;
12337 struct {
12338 unsigned int op1 : 8;
12339 unsigned int r1 : 4;
12340 unsigned int m3 : 4;
12341 unsigned int b4 : 4;
12342 unsigned int d4 : 12;
12343 unsigned int i2 : 8;
12344 unsigned int op2 : 8;
12345 } RIS;
12346 struct {
12347 unsigned int op1 : 8;
12348 unsigned int r1 : 4;
12349 unsigned int r2 : 4;
12350 unsigned int b4 : 4;
12351 unsigned int d4 : 12;
12352 unsigned int m3 : 4;
12353 unsigned int : 4;
12354 unsigned int op2 : 8;
12355 } RRS;
12356 struct {
12357 unsigned int op1 : 8;
12358 unsigned int l1 : 4;
12359 unsigned int : 4;
12360 unsigned int b1 : 4;
12361 unsigned int d1 : 12;
12362 unsigned int : 8;
12363 unsigned int op2 : 8;
12364 } RSL;
12365 struct {
12366 unsigned int op1 : 8;
12367 unsigned int r1 : 4;
12368 unsigned int r3 : 4;
12369 unsigned int b2 : 4;
12370 unsigned int dl2 : 12;
12371 unsigned int dh2 : 8;
12372 unsigned int op2 : 8;
12373 } RSY;
12374 struct {
12375 unsigned int op1 : 8;
12376 unsigned int r1 : 4;
12377 unsigned int x2 : 4;
12378 unsigned int b2 : 4;
12379 unsigned int d2 : 12;
12380 unsigned int : 8;
12381 unsigned int op2 : 8;
12382 } RXE;
12383 struct {
12384 unsigned int op1 : 8;
12385 unsigned int r3 : 4;
12386 unsigned int x2 : 4;
12387 unsigned int b2 : 4;
12388 unsigned int d2 : 12;
12389 unsigned int r1 : 4;
12390 unsigned int : 4;
12391 unsigned int op2 : 8;
12392 } RXF;
12393 struct {
12394 unsigned int op1 : 8;
12395 unsigned int r1 : 4;
12396 unsigned int x2 : 4;
12397 unsigned int b2 : 4;
12398 unsigned int dl2 : 12;
12399 unsigned int dh2 : 8;
12400 unsigned int op2 : 8;
12401 } RXY;
12402 struct {
12403 unsigned int op1 : 8;
12404 unsigned int i2 : 8;
12405 unsigned int b1 : 4;
12406 unsigned int dl1 : 12;
12407 unsigned int dh1 : 8;
12408 unsigned int op2 : 8;
12409 } SIY;
12410 struct {
12411 unsigned int op : 8;
12412 unsigned int l : 8;
12413 unsigned int b1 : 4;
12414 unsigned int d1 : 12;
12415 unsigned int b2 : 4;
12416 unsigned int d2 : 12;
12417 } SS;
12418 struct {
12419 unsigned int op : 8;
12420 unsigned int l1 : 4;
12421 unsigned int l2 : 4;
12422 unsigned int b1 : 4;
12423 unsigned int d1 : 12;
12424 unsigned int b2 : 4;
12425 unsigned int d2 : 12;
12426 } SS_LLRDRD;
12427 struct {
12428 unsigned int op : 8;
12429 unsigned int r1 : 4;
12430 unsigned int r3 : 4;
12431 unsigned int b2 : 4;
12432 unsigned int d2 : 12;
12433 unsigned int b4 : 4;
12434 unsigned int d4 : 12;
12435 } SS_RRRDRD2;
12436 struct {
12437 unsigned int op : 16;
12438 unsigned int b1 : 4;
12439 unsigned int d1 : 12;
12440 unsigned int b2 : 4;
12441 unsigned int d2 : 12;
12442 } SSE;
12443 struct {
12444 unsigned int op1 : 8;
12445 unsigned int r3 : 4;
12446 unsigned int op2 : 4;
12447 unsigned int b1 : 4;
12448 unsigned int d1 : 12;
12449 unsigned int b2 : 4;
12450 unsigned int d2 : 12;
12451 } SSF;
12452 struct {
12453 unsigned int op : 16;
12454 unsigned int b1 : 4;
12455 unsigned int d1 : 12;
12456 unsigned int i2 : 16;
12457 } SIL;
12458 } formats;
12459 union {
12460 formats fmt;
12461 ULong value;
12462 } ovl;
12463
12464 vassert(sizeof(formats) == 6);
12465
12466 ((char *)(&ovl.value))[0] = bytes[0];
12467 ((char *)(&ovl.value))[1] = bytes[1];
12468 ((char *)(&ovl.value))[2] = bytes[2];
12469 ((char *)(&ovl.value))[3] = bytes[3];
12470 ((char *)(&ovl.value))[4] = bytes[4];
12471 ((char *)(&ovl.value))[5] = bytes[5];
12472 ((char *)(&ovl.value))[6] = 0x0;
12473 ((char *)(&ovl.value))[7] = 0x0;
12474
12475 switch ((ovl.value >> 16) & 0xff00000000ffULL) {
12476 case 0xe30000000002ULL: s390_format_RXY_RRRD(s390_irgen_LTG, ovl.fmt.RXY.r1,
12477 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12478 ovl.fmt.RXY.dl2,
12479 ovl.fmt.RXY.dh2); goto ok;
12480 case 0xe30000000003ULL: /* LRAG */ goto unimplemented;
12481 case 0xe30000000004ULL: s390_format_RXY_RRRD(s390_irgen_LG, ovl.fmt.RXY.r1,
12482 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12483 ovl.fmt.RXY.dl2,
12484 ovl.fmt.RXY.dh2); goto ok;
12485 case 0xe30000000006ULL: s390_format_RXY_RRRD(s390_irgen_CVBY, ovl.fmt.RXY.r1,
12486 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12487 ovl.fmt.RXY.dl2,
12488 ovl.fmt.RXY.dh2); goto ok;
12489 case 0xe30000000008ULL: s390_format_RXY_RRRD(s390_irgen_AG, ovl.fmt.RXY.r1,
12490 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12491 ovl.fmt.RXY.dl2,
12492 ovl.fmt.RXY.dh2); goto ok;
12493 case 0xe30000000009ULL: s390_format_RXY_RRRD(s390_irgen_SG, ovl.fmt.RXY.r1,
12494 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12495 ovl.fmt.RXY.dl2,
12496 ovl.fmt.RXY.dh2); goto ok;
12497 case 0xe3000000000aULL: s390_format_RXY_RRRD(s390_irgen_ALG, ovl.fmt.RXY.r1,
12498 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12499 ovl.fmt.RXY.dl2,
12500 ovl.fmt.RXY.dh2); goto ok;
12501 case 0xe3000000000bULL: s390_format_RXY_RRRD(s390_irgen_SLG, ovl.fmt.RXY.r1,
12502 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12503 ovl.fmt.RXY.dl2,
12504 ovl.fmt.RXY.dh2); goto ok;
12505 case 0xe3000000000cULL: s390_format_RXY_RRRD(s390_irgen_MSG, ovl.fmt.RXY.r1,
12506 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12507 ovl.fmt.RXY.dl2,
12508 ovl.fmt.RXY.dh2); goto ok;
12509 case 0xe3000000000dULL: s390_format_RXY_RRRD(s390_irgen_DSG, ovl.fmt.RXY.r1,
12510 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12511 ovl.fmt.RXY.dl2,
12512 ovl.fmt.RXY.dh2); goto ok;
12513 case 0xe3000000000eULL: /* CVBG */ goto unimplemented;
12514 case 0xe3000000000fULL: s390_format_RXY_RRRD(s390_irgen_LRVG, ovl.fmt.RXY.r1,
12515 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12516 ovl.fmt.RXY.dl2,
12517 ovl.fmt.RXY.dh2); goto ok;
12518 case 0xe30000000012ULL: s390_format_RXY_RRRD(s390_irgen_LT, ovl.fmt.RXY.r1,
12519 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12520 ovl.fmt.RXY.dl2,
12521 ovl.fmt.RXY.dh2); goto ok;
12522 case 0xe30000000013ULL: /* LRAY */ goto unimplemented;
12523 case 0xe30000000014ULL: s390_format_RXY_RRRD(s390_irgen_LGF, ovl.fmt.RXY.r1,
12524 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12525 ovl.fmt.RXY.dl2,
12526 ovl.fmt.RXY.dh2); goto ok;
12527 case 0xe30000000015ULL: s390_format_RXY_RRRD(s390_irgen_LGH, ovl.fmt.RXY.r1,
12528 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12529 ovl.fmt.RXY.dl2,
12530 ovl.fmt.RXY.dh2); goto ok;
12531 case 0xe30000000016ULL: s390_format_RXY_RRRD(s390_irgen_LLGF, ovl.fmt.RXY.r1,
12532 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12533 ovl.fmt.RXY.dl2,
12534 ovl.fmt.RXY.dh2); goto ok;
12535 case 0xe30000000017ULL: s390_format_RXY_RRRD(s390_irgen_LLGT, ovl.fmt.RXY.r1,
12536 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12537 ovl.fmt.RXY.dl2,
12538 ovl.fmt.RXY.dh2); goto ok;
12539 case 0xe30000000018ULL: s390_format_RXY_RRRD(s390_irgen_AGF, ovl.fmt.RXY.r1,
12540 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12541 ovl.fmt.RXY.dl2,
12542 ovl.fmt.RXY.dh2); goto ok;
12543 case 0xe30000000019ULL: s390_format_RXY_RRRD(s390_irgen_SGF, ovl.fmt.RXY.r1,
12544 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12545 ovl.fmt.RXY.dl2,
12546 ovl.fmt.RXY.dh2); goto ok;
12547 case 0xe3000000001aULL: s390_format_RXY_RRRD(s390_irgen_ALGF, ovl.fmt.RXY.r1,
12548 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12549 ovl.fmt.RXY.dl2,
12550 ovl.fmt.RXY.dh2); goto ok;
12551 case 0xe3000000001bULL: s390_format_RXY_RRRD(s390_irgen_SLGF, ovl.fmt.RXY.r1,
12552 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12553 ovl.fmt.RXY.dl2,
12554 ovl.fmt.RXY.dh2); goto ok;
12555 case 0xe3000000001cULL: s390_format_RXY_RRRD(s390_irgen_MSGF, ovl.fmt.RXY.r1,
12556 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12557 ovl.fmt.RXY.dl2,
12558 ovl.fmt.RXY.dh2); goto ok;
12559 case 0xe3000000001dULL: s390_format_RXY_RRRD(s390_irgen_DSGF, ovl.fmt.RXY.r1,
12560 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12561 ovl.fmt.RXY.dl2,
12562 ovl.fmt.RXY.dh2); goto ok;
12563 case 0xe3000000001eULL: s390_format_RXY_RRRD(s390_irgen_LRV, ovl.fmt.RXY.r1,
12564 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12565 ovl.fmt.RXY.dl2,
12566 ovl.fmt.RXY.dh2); goto ok;
12567 case 0xe3000000001fULL: s390_format_RXY_RRRD(s390_irgen_LRVH, ovl.fmt.RXY.r1,
12568 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12569 ovl.fmt.RXY.dl2,
12570 ovl.fmt.RXY.dh2); goto ok;
12571 case 0xe30000000020ULL: s390_format_RXY_RRRD(s390_irgen_CG, ovl.fmt.RXY.r1,
12572 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12573 ovl.fmt.RXY.dl2,
12574 ovl.fmt.RXY.dh2); goto ok;
12575 case 0xe30000000021ULL: s390_format_RXY_RRRD(s390_irgen_CLG, ovl.fmt.RXY.r1,
12576 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12577 ovl.fmt.RXY.dl2,
12578 ovl.fmt.RXY.dh2); goto ok;
12579 case 0xe30000000024ULL: s390_format_RXY_RRRD(s390_irgen_STG, ovl.fmt.RXY.r1,
12580 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12581 ovl.fmt.RXY.dl2,
12582 ovl.fmt.RXY.dh2); goto ok;
12583 case 0xe30000000026ULL: s390_format_RXY_RRRD(s390_irgen_CVDY, ovl.fmt.RXY.r1,
12584 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12585 ovl.fmt.RXY.dl2,
12586 ovl.fmt.RXY.dh2); goto ok;
12587 case 0xe3000000002eULL: /* CVDG */ goto unimplemented;
12588 case 0xe3000000002fULL: s390_format_RXY_RRRD(s390_irgen_STRVG,
12589 ovl.fmt.RXY.r1, ovl.fmt.RXY.x2,
12590 ovl.fmt.RXY.b2, ovl.fmt.RXY.dl2,
12591 ovl.fmt.RXY.dh2); goto ok;
12592 case 0xe30000000030ULL: s390_format_RXY_RRRD(s390_irgen_CGF, ovl.fmt.RXY.r1,
12593 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12594 ovl.fmt.RXY.dl2,
12595 ovl.fmt.RXY.dh2); goto ok;
12596 case 0xe30000000031ULL: s390_format_RXY_RRRD(s390_irgen_CLGF, ovl.fmt.RXY.r1,
12597 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12598 ovl.fmt.RXY.dl2,
12599 ovl.fmt.RXY.dh2); goto ok;
12600 case 0xe30000000032ULL: s390_format_RXY_RRRD(s390_irgen_LTGF, ovl.fmt.RXY.r1,
12601 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12602 ovl.fmt.RXY.dl2,
12603 ovl.fmt.RXY.dh2); goto ok;
12604 case 0xe30000000034ULL: s390_format_RXY_RRRD(s390_irgen_CGH, ovl.fmt.RXY.r1,
12605 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12606 ovl.fmt.RXY.dl2,
12607 ovl.fmt.RXY.dh2); goto ok;
12608 case 0xe30000000036ULL: s390_format_RXY_URRD(s390_irgen_PFD, ovl.fmt.RXY.r1,
12609 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12610 ovl.fmt.RXY.dl2,
12611 ovl.fmt.RXY.dh2); goto ok;
12612 case 0xe3000000003eULL: s390_format_RXY_RRRD(s390_irgen_STRV, ovl.fmt.RXY.r1,
12613 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12614 ovl.fmt.RXY.dl2,
12615 ovl.fmt.RXY.dh2); goto ok;
12616 case 0xe3000000003fULL: s390_format_RXY_RRRD(s390_irgen_STRVH,
12617 ovl.fmt.RXY.r1, ovl.fmt.RXY.x2,
12618 ovl.fmt.RXY.b2, ovl.fmt.RXY.dl2,
12619 ovl.fmt.RXY.dh2); goto ok;
12620 case 0xe30000000046ULL: s390_format_RXY_RRRD(s390_irgen_BCTG, ovl.fmt.RXY.r1,
12621 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12622 ovl.fmt.RXY.dl2,
12623 ovl.fmt.RXY.dh2); goto ok;
12624 case 0xe30000000050ULL: s390_format_RXY_RRRD(s390_irgen_STY, ovl.fmt.RXY.r1,
12625 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12626 ovl.fmt.RXY.dl2,
12627 ovl.fmt.RXY.dh2); goto ok;
12628 case 0xe30000000051ULL: s390_format_RXY_RRRD(s390_irgen_MSY, ovl.fmt.RXY.r1,
12629 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12630 ovl.fmt.RXY.dl2,
12631 ovl.fmt.RXY.dh2); goto ok;
12632 case 0xe30000000054ULL: s390_format_RXY_RRRD(s390_irgen_NY, ovl.fmt.RXY.r1,
12633 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12634 ovl.fmt.RXY.dl2,
12635 ovl.fmt.RXY.dh2); goto ok;
12636 case 0xe30000000055ULL: s390_format_RXY_RRRD(s390_irgen_CLY, ovl.fmt.RXY.r1,
12637 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12638 ovl.fmt.RXY.dl2,
12639 ovl.fmt.RXY.dh2); goto ok;
12640 case 0xe30000000056ULL: s390_format_RXY_RRRD(s390_irgen_OY, ovl.fmt.RXY.r1,
12641 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12642 ovl.fmt.RXY.dl2,
12643 ovl.fmt.RXY.dh2); goto ok;
12644 case 0xe30000000057ULL: s390_format_RXY_RRRD(s390_irgen_XY, ovl.fmt.RXY.r1,
12645 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12646 ovl.fmt.RXY.dl2,
12647 ovl.fmt.RXY.dh2); goto ok;
12648 case 0xe30000000058ULL: s390_format_RXY_RRRD(s390_irgen_LY, ovl.fmt.RXY.r1,
12649 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12650 ovl.fmt.RXY.dl2,
12651 ovl.fmt.RXY.dh2); goto ok;
12652 case 0xe30000000059ULL: s390_format_RXY_RRRD(s390_irgen_CY, ovl.fmt.RXY.r1,
12653 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12654 ovl.fmt.RXY.dl2,
12655 ovl.fmt.RXY.dh2); goto ok;
12656 case 0xe3000000005aULL: s390_format_RXY_RRRD(s390_irgen_AY, ovl.fmt.RXY.r1,
12657 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12658 ovl.fmt.RXY.dl2,
12659 ovl.fmt.RXY.dh2); goto ok;
12660 case 0xe3000000005bULL: s390_format_RXY_RRRD(s390_irgen_SY, ovl.fmt.RXY.r1,
12661 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12662 ovl.fmt.RXY.dl2,
12663 ovl.fmt.RXY.dh2); goto ok;
12664 case 0xe3000000005cULL: s390_format_RXY_RRRD(s390_irgen_MFY, ovl.fmt.RXY.r1,
12665 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12666 ovl.fmt.RXY.dl2,
12667 ovl.fmt.RXY.dh2); goto ok;
12668 case 0xe3000000005eULL: s390_format_RXY_RRRD(s390_irgen_ALY, ovl.fmt.RXY.r1,
12669 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12670 ovl.fmt.RXY.dl2,
12671 ovl.fmt.RXY.dh2); goto ok;
12672 case 0xe3000000005fULL: s390_format_RXY_RRRD(s390_irgen_SLY, ovl.fmt.RXY.r1,
12673 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12674 ovl.fmt.RXY.dl2,
12675 ovl.fmt.RXY.dh2); goto ok;
12676 case 0xe30000000070ULL: s390_format_RXY_RRRD(s390_irgen_STHY, ovl.fmt.RXY.r1,
12677 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12678 ovl.fmt.RXY.dl2,
12679 ovl.fmt.RXY.dh2); goto ok;
12680 case 0xe30000000071ULL: s390_format_RXY_RRRD(s390_irgen_LAY, ovl.fmt.RXY.r1,
12681 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12682 ovl.fmt.RXY.dl2,
12683 ovl.fmt.RXY.dh2); goto ok;
12684 case 0xe30000000072ULL: s390_format_RXY_RRRD(s390_irgen_STCY, ovl.fmt.RXY.r1,
12685 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12686 ovl.fmt.RXY.dl2,
12687 ovl.fmt.RXY.dh2); goto ok;
12688 case 0xe30000000073ULL: s390_format_RXY_RRRD(s390_irgen_ICY, ovl.fmt.RXY.r1,
12689 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12690 ovl.fmt.RXY.dl2,
12691 ovl.fmt.RXY.dh2); goto ok;
12692 case 0xe30000000075ULL: s390_format_RXY_RRRD(s390_irgen_LAEY, ovl.fmt.RXY.r1,
12693 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12694 ovl.fmt.RXY.dl2,
12695 ovl.fmt.RXY.dh2); goto ok;
12696 case 0xe30000000076ULL: s390_format_RXY_RRRD(s390_irgen_LB, ovl.fmt.RXY.r1,
12697 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12698 ovl.fmt.RXY.dl2,
12699 ovl.fmt.RXY.dh2); goto ok;
12700 case 0xe30000000077ULL: s390_format_RXY_RRRD(s390_irgen_LGB, ovl.fmt.RXY.r1,
12701 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12702 ovl.fmt.RXY.dl2,
12703 ovl.fmt.RXY.dh2); goto ok;
12704 case 0xe30000000078ULL: s390_format_RXY_RRRD(s390_irgen_LHY, ovl.fmt.RXY.r1,
12705 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12706 ovl.fmt.RXY.dl2,
12707 ovl.fmt.RXY.dh2); goto ok;
12708 case 0xe30000000079ULL: s390_format_RXY_RRRD(s390_irgen_CHY, ovl.fmt.RXY.r1,
12709 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12710 ovl.fmt.RXY.dl2,
12711 ovl.fmt.RXY.dh2); goto ok;
12712 case 0xe3000000007aULL: s390_format_RXY_RRRD(s390_irgen_AHY, ovl.fmt.RXY.r1,
12713 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12714 ovl.fmt.RXY.dl2,
12715 ovl.fmt.RXY.dh2); goto ok;
12716 case 0xe3000000007bULL: s390_format_RXY_RRRD(s390_irgen_SHY, ovl.fmt.RXY.r1,
12717 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12718 ovl.fmt.RXY.dl2,
12719 ovl.fmt.RXY.dh2); goto ok;
12720 case 0xe3000000007cULL: s390_format_RXY_RRRD(s390_irgen_MHY, ovl.fmt.RXY.r1,
12721 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12722 ovl.fmt.RXY.dl2,
12723 ovl.fmt.RXY.dh2); goto ok;
12724 case 0xe30000000080ULL: s390_format_RXY_RRRD(s390_irgen_NG, ovl.fmt.RXY.r1,
12725 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12726 ovl.fmt.RXY.dl2,
12727 ovl.fmt.RXY.dh2); goto ok;
12728 case 0xe30000000081ULL: s390_format_RXY_RRRD(s390_irgen_OG, ovl.fmt.RXY.r1,
12729 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12730 ovl.fmt.RXY.dl2,
12731 ovl.fmt.RXY.dh2); goto ok;
12732 case 0xe30000000082ULL: s390_format_RXY_RRRD(s390_irgen_XG, ovl.fmt.RXY.r1,
12733 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12734 ovl.fmt.RXY.dl2,
12735 ovl.fmt.RXY.dh2); goto ok;
12736 case 0xe30000000086ULL: s390_format_RXY_RRRD(s390_irgen_MLG, ovl.fmt.RXY.r1,
12737 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12738 ovl.fmt.RXY.dl2,
12739 ovl.fmt.RXY.dh2); goto ok;
12740 case 0xe30000000087ULL: s390_format_RXY_RRRD(s390_irgen_DLG, ovl.fmt.RXY.r1,
12741 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12742 ovl.fmt.RXY.dl2,
12743 ovl.fmt.RXY.dh2); goto ok;
12744 case 0xe30000000088ULL: s390_format_RXY_RRRD(s390_irgen_ALCG, ovl.fmt.RXY.r1,
12745 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12746 ovl.fmt.RXY.dl2,
12747 ovl.fmt.RXY.dh2); goto ok;
12748 case 0xe30000000089ULL: s390_format_RXY_RRRD(s390_irgen_SLBG, ovl.fmt.RXY.r1,
12749 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12750 ovl.fmt.RXY.dl2,
12751 ovl.fmt.RXY.dh2); goto ok;
12752 case 0xe3000000008eULL: s390_format_RXY_RRRD(s390_irgen_STPQ, ovl.fmt.RXY.r1,
12753 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12754 ovl.fmt.RXY.dl2,
12755 ovl.fmt.RXY.dh2); goto ok;
12756 case 0xe3000000008fULL: s390_format_RXY_RRRD(s390_irgen_LPQ, ovl.fmt.RXY.r1,
12757 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12758 ovl.fmt.RXY.dl2,
12759 ovl.fmt.RXY.dh2); goto ok;
12760 case 0xe30000000090ULL: s390_format_RXY_RRRD(s390_irgen_LLGC, ovl.fmt.RXY.r1,
12761 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12762 ovl.fmt.RXY.dl2,
12763 ovl.fmt.RXY.dh2); goto ok;
12764 case 0xe30000000091ULL: s390_format_RXY_RRRD(s390_irgen_LLGH, ovl.fmt.RXY.r1,
12765 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12766 ovl.fmt.RXY.dl2,
12767 ovl.fmt.RXY.dh2); goto ok;
12768 case 0xe30000000094ULL: s390_format_RXY_RRRD(s390_irgen_LLC, ovl.fmt.RXY.r1,
12769 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12770 ovl.fmt.RXY.dl2,
12771 ovl.fmt.RXY.dh2); goto ok;
12772 case 0xe30000000095ULL: s390_format_RXY_RRRD(s390_irgen_LLH, ovl.fmt.RXY.r1,
12773 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12774 ovl.fmt.RXY.dl2,
12775 ovl.fmt.RXY.dh2); goto ok;
12776 case 0xe30000000096ULL: s390_format_RXY_RRRD(s390_irgen_ML, ovl.fmt.RXY.r1,
12777 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12778 ovl.fmt.RXY.dl2,
12779 ovl.fmt.RXY.dh2); goto ok;
12780 case 0xe30000000097ULL: s390_format_RXY_RRRD(s390_irgen_DL, ovl.fmt.RXY.r1,
12781 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12782 ovl.fmt.RXY.dl2,
12783 ovl.fmt.RXY.dh2); goto ok;
12784 case 0xe30000000098ULL: s390_format_RXY_RRRD(s390_irgen_ALC, ovl.fmt.RXY.r1,
12785 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12786 ovl.fmt.RXY.dl2,
12787 ovl.fmt.RXY.dh2); goto ok;
12788 case 0xe30000000099ULL: s390_format_RXY_RRRD(s390_irgen_SLB, ovl.fmt.RXY.r1,
12789 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12790 ovl.fmt.RXY.dl2,
12791 ovl.fmt.RXY.dh2); goto ok;
12792 case 0xe300000000c0ULL: s390_format_RXY_RRRD(s390_irgen_LBH, ovl.fmt.RXY.r1,
12793 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12794 ovl.fmt.RXY.dl2,
12795 ovl.fmt.RXY.dh2); goto ok;
12796 case 0xe300000000c2ULL: s390_format_RXY_RRRD(s390_irgen_LLCH, ovl.fmt.RXY.r1,
12797 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12798 ovl.fmt.RXY.dl2,
12799 ovl.fmt.RXY.dh2); goto ok;
12800 case 0xe300000000c3ULL: s390_format_RXY_RRRD(s390_irgen_STCH, ovl.fmt.RXY.r1,
12801 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12802 ovl.fmt.RXY.dl2,
12803 ovl.fmt.RXY.dh2); goto ok;
12804 case 0xe300000000c4ULL: s390_format_RXY_RRRD(s390_irgen_LHH, ovl.fmt.RXY.r1,
12805 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12806 ovl.fmt.RXY.dl2,
12807 ovl.fmt.RXY.dh2); goto ok;
12808 case 0xe300000000c6ULL: s390_format_RXY_RRRD(s390_irgen_LLHH, ovl.fmt.RXY.r1,
12809 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12810 ovl.fmt.RXY.dl2,
12811 ovl.fmt.RXY.dh2); goto ok;
12812 case 0xe300000000c7ULL: s390_format_RXY_RRRD(s390_irgen_STHH, ovl.fmt.RXY.r1,
12813 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12814 ovl.fmt.RXY.dl2,
12815 ovl.fmt.RXY.dh2); goto ok;
12816 case 0xe300000000caULL: s390_format_RXY_RRRD(s390_irgen_LFH, ovl.fmt.RXY.r1,
12817 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12818 ovl.fmt.RXY.dl2,
12819 ovl.fmt.RXY.dh2); goto ok;
12820 case 0xe300000000cbULL: s390_format_RXY_RRRD(s390_irgen_STFH, ovl.fmt.RXY.r1,
12821 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12822 ovl.fmt.RXY.dl2,
12823 ovl.fmt.RXY.dh2); goto ok;
12824 case 0xe300000000cdULL: s390_format_RXY_RRRD(s390_irgen_CHF, ovl.fmt.RXY.r1,
12825 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12826 ovl.fmt.RXY.dl2,
12827 ovl.fmt.RXY.dh2); goto ok;
12828 case 0xe300000000cfULL: s390_format_RXY_RRRD(s390_irgen_CLHF, ovl.fmt.RXY.r1,
12829 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12830 ovl.fmt.RXY.dl2,
12831 ovl.fmt.RXY.dh2); goto ok;
12832 case 0xeb0000000004ULL: s390_format_RSY_RRRD(s390_irgen_LMG, ovl.fmt.RSY.r1,
12833 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
12834 ovl.fmt.RSY.dl2,
12835 ovl.fmt.RSY.dh2); goto ok;
12836 case 0xeb000000000aULL: s390_format_RSY_RRRD(s390_irgen_SRAG, ovl.fmt.RSY.r1,
12837 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
12838 ovl.fmt.RSY.dl2,
12839 ovl.fmt.RSY.dh2); goto ok;
12840 case 0xeb000000000bULL: s390_format_RSY_RRRD(s390_irgen_SLAG, ovl.fmt.RSY.r1,
12841 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
12842 ovl.fmt.RSY.dl2,
12843 ovl.fmt.RSY.dh2); goto ok;
12844 case 0xeb000000000cULL: s390_format_RSY_RRRD(s390_irgen_SRLG, ovl.fmt.RSY.r1,
12845 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
12846 ovl.fmt.RSY.dl2,
12847 ovl.fmt.RSY.dh2); goto ok;
12848 case 0xeb000000000dULL: s390_format_RSY_RRRD(s390_irgen_SLLG, ovl.fmt.RSY.r1,
12849 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
12850 ovl.fmt.RSY.dl2,
12851 ovl.fmt.RSY.dh2); goto ok;
12852 case 0xeb000000000fULL: /* TRACG */ goto unimplemented;
12853 case 0xeb0000000014ULL: s390_format_RSY_RRRD(s390_irgen_CSY, ovl.fmt.RSY.r1,
12854 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
12855 ovl.fmt.RSY.dl2,
12856 ovl.fmt.RSY.dh2); goto ok;
12857 case 0xeb000000001cULL: s390_format_RSY_RRRD(s390_irgen_RLLG, ovl.fmt.RSY.r1,
12858 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
12859 ovl.fmt.RSY.dl2,
12860 ovl.fmt.RSY.dh2); goto ok;
12861 case 0xeb000000001dULL: s390_format_RSY_RRRD(s390_irgen_RLL, ovl.fmt.RSY.r1,
12862 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
12863 ovl.fmt.RSY.dl2,
12864 ovl.fmt.RSY.dh2); goto ok;
12865 case 0xeb0000000020ULL: s390_format_RSY_RURD(s390_irgen_CLMH, ovl.fmt.RSY.r1,
12866 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
12867 ovl.fmt.RSY.dl2,
12868 ovl.fmt.RSY.dh2); goto ok;
12869 case 0xeb0000000021ULL: s390_format_RSY_RURD(s390_irgen_CLMY, ovl.fmt.RSY.r1,
12870 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
12871 ovl.fmt.RSY.dl2,
12872 ovl.fmt.RSY.dh2); goto ok;
12873 case 0xeb0000000024ULL: s390_format_RSY_RRRD(s390_irgen_STMG, ovl.fmt.RSY.r1,
12874 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
12875 ovl.fmt.RSY.dl2,
12876 ovl.fmt.RSY.dh2); goto ok;
12877 case 0xeb0000000025ULL: /* STCTG */ goto unimplemented;
12878 case 0xeb0000000026ULL: s390_format_RSY_RRRD(s390_irgen_STMH, ovl.fmt.RSY.r1,
12879 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
12880 ovl.fmt.RSY.dl2,
12881 ovl.fmt.RSY.dh2); goto ok;
12882 case 0xeb000000002cULL: s390_format_RSY_RURD(s390_irgen_STCMH,
12883 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
12884 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
12885 ovl.fmt.RSY.dh2); goto ok;
12886 case 0xeb000000002dULL: s390_format_RSY_RURD(s390_irgen_STCMY,
12887 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
12888 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
12889 ovl.fmt.RSY.dh2); goto ok;
12890 case 0xeb000000002fULL: /* LCTLG */ goto unimplemented;
12891 case 0xeb0000000030ULL: s390_format_RSY_RRRD(s390_irgen_CSG, ovl.fmt.RSY.r1,
12892 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
12893 ovl.fmt.RSY.dl2,
12894 ovl.fmt.RSY.dh2); goto ok;
florian448cbba2012-06-06 02:26:01 +000012895 case 0xeb0000000031ULL: s390_format_RSY_RRRD(s390_irgen_CDSY, ovl.fmt.RSY.r1,
12896 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
12897 ovl.fmt.RSY.dl2,
12898 ovl.fmt.RSY.dh2); goto ok;
12899 case 0xeb000000003eULL: s390_format_RSY_RRRD(s390_irgen_CDSG, ovl.fmt.RSY.r1,
12900 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
12901 ovl.fmt.RSY.dl2,
12902 ovl.fmt.RSY.dh2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000012903 case 0xeb0000000044ULL: s390_format_RSY_RRRD(s390_irgen_BXHG, ovl.fmt.RSY.r1,
12904 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
12905 ovl.fmt.RSY.dl2,
12906 ovl.fmt.RSY.dh2); goto ok;
12907 case 0xeb0000000045ULL: s390_format_RSY_RRRD(s390_irgen_BXLEG,
12908 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
12909 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
12910 ovl.fmt.RSY.dh2); goto ok;
12911 case 0xeb000000004cULL: /* ECAG */ goto unimplemented;
12912 case 0xeb0000000051ULL: s390_format_SIY_URD(s390_irgen_TMY, ovl.fmt.SIY.i2,
12913 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
12914 ovl.fmt.SIY.dh1); goto ok;
12915 case 0xeb0000000052ULL: s390_format_SIY_URD(s390_irgen_MVIY, ovl.fmt.SIY.i2,
12916 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
12917 ovl.fmt.SIY.dh1); goto ok;
12918 case 0xeb0000000054ULL: s390_format_SIY_URD(s390_irgen_NIY, ovl.fmt.SIY.i2,
12919 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
12920 ovl.fmt.SIY.dh1); goto ok;
12921 case 0xeb0000000055ULL: s390_format_SIY_URD(s390_irgen_CLIY, ovl.fmt.SIY.i2,
12922 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
12923 ovl.fmt.SIY.dh1); goto ok;
12924 case 0xeb0000000056ULL: s390_format_SIY_URD(s390_irgen_OIY, ovl.fmt.SIY.i2,
12925 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
12926 ovl.fmt.SIY.dh1); goto ok;
12927 case 0xeb0000000057ULL: s390_format_SIY_URD(s390_irgen_XIY, ovl.fmt.SIY.i2,
12928 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
12929 ovl.fmt.SIY.dh1); goto ok;
12930 case 0xeb000000006aULL: s390_format_SIY_IRD(s390_irgen_ASI, ovl.fmt.SIY.i2,
12931 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
12932 ovl.fmt.SIY.dh1); goto ok;
12933 case 0xeb000000006eULL: s390_format_SIY_IRD(s390_irgen_ALSI, ovl.fmt.SIY.i2,
12934 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
12935 ovl.fmt.SIY.dh1); goto ok;
12936 case 0xeb000000007aULL: s390_format_SIY_IRD(s390_irgen_AGSI, ovl.fmt.SIY.i2,
12937 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
12938 ovl.fmt.SIY.dh1); goto ok;
12939 case 0xeb000000007eULL: s390_format_SIY_IRD(s390_irgen_ALGSI, ovl.fmt.SIY.i2,
12940 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
12941 ovl.fmt.SIY.dh1); goto ok;
12942 case 0xeb0000000080ULL: s390_format_RSY_RURD(s390_irgen_ICMH, ovl.fmt.RSY.r1,
12943 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
12944 ovl.fmt.RSY.dl2,
12945 ovl.fmt.RSY.dh2); goto ok;
12946 case 0xeb0000000081ULL: s390_format_RSY_RURD(s390_irgen_ICMY, ovl.fmt.RSY.r1,
12947 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
12948 ovl.fmt.RSY.dl2,
12949 ovl.fmt.RSY.dh2); goto ok;
12950 case 0xeb000000008eULL: /* MVCLU */ goto unimplemented;
12951 case 0xeb000000008fULL: /* CLCLU */ goto unimplemented;
12952 case 0xeb0000000090ULL: s390_format_RSY_RRRD(s390_irgen_STMY, ovl.fmt.RSY.r1,
12953 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
12954 ovl.fmt.RSY.dl2,
12955 ovl.fmt.RSY.dh2); goto ok;
12956 case 0xeb0000000096ULL: s390_format_RSY_RRRD(s390_irgen_LMH, ovl.fmt.RSY.r1,
12957 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
12958 ovl.fmt.RSY.dl2,
12959 ovl.fmt.RSY.dh2); goto ok;
12960 case 0xeb0000000098ULL: s390_format_RSY_RRRD(s390_irgen_LMY, ovl.fmt.RSY.r1,
12961 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
12962 ovl.fmt.RSY.dl2,
12963 ovl.fmt.RSY.dh2); goto ok;
12964 case 0xeb000000009aULL: s390_format_RSY_AARD(s390_irgen_LAMY, ovl.fmt.RSY.r1,
12965 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
12966 ovl.fmt.RSY.dl2,
12967 ovl.fmt.RSY.dh2); goto ok;
12968 case 0xeb000000009bULL: s390_format_RSY_AARD(s390_irgen_STAMY,
12969 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
12970 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
12971 ovl.fmt.RSY.dh2); goto ok;
12972 case 0xeb00000000c0ULL: /* TP */ goto unimplemented;
12973 case 0xeb00000000dcULL: s390_format_RSY_RRRD(s390_irgen_SRAK, ovl.fmt.RSY.r1,
12974 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
12975 ovl.fmt.RSY.dl2,
12976 ovl.fmt.RSY.dh2); goto ok;
12977 case 0xeb00000000ddULL: s390_format_RSY_RRRD(s390_irgen_SLAK, ovl.fmt.RSY.r1,
12978 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
12979 ovl.fmt.RSY.dl2,
12980 ovl.fmt.RSY.dh2); goto ok;
12981 case 0xeb00000000deULL: s390_format_RSY_RRRD(s390_irgen_SRLK, ovl.fmt.RSY.r1,
12982 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
12983 ovl.fmt.RSY.dl2,
12984 ovl.fmt.RSY.dh2); goto ok;
12985 case 0xeb00000000dfULL: s390_format_RSY_RRRD(s390_irgen_SLLK, ovl.fmt.RSY.r1,
12986 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
12987 ovl.fmt.RSY.dl2,
12988 ovl.fmt.RSY.dh2); goto ok;
sewardjd7bde722011-04-05 13:19:33 +000012989 case 0xeb00000000e2ULL: s390_format_RSY_RDRM(s390_irgen_LOCG, ovl.fmt.RSY.r1,
12990 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
12991 ovl.fmt.RSY.dl2,
12992 ovl.fmt.RSY.dh2,
12993 S390_XMNM_LOCG); goto ok;
12994 case 0xeb00000000e3ULL: s390_format_RSY_RDRM(s390_irgen_STOCG,
12995 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
12996 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
12997 ovl.fmt.RSY.dh2,
12998 S390_XMNM_STOCG); goto ok;
sewardj2019a972011-03-07 16:04:07 +000012999 case 0xeb00000000e4ULL: s390_format_RSY_RRRD(s390_irgen_LANG, ovl.fmt.RSY.r1,
13000 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13001 ovl.fmt.RSY.dl2,
13002 ovl.fmt.RSY.dh2); goto ok;
13003 case 0xeb00000000e6ULL: s390_format_RSY_RRRD(s390_irgen_LAOG, ovl.fmt.RSY.r1,
13004 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13005 ovl.fmt.RSY.dl2,
13006 ovl.fmt.RSY.dh2); goto ok;
13007 case 0xeb00000000e7ULL: s390_format_RSY_RRRD(s390_irgen_LAXG, ovl.fmt.RSY.r1,
13008 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13009 ovl.fmt.RSY.dl2,
13010 ovl.fmt.RSY.dh2); goto ok;
13011 case 0xeb00000000e8ULL: s390_format_RSY_RRRD(s390_irgen_LAAG, ovl.fmt.RSY.r1,
13012 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13013 ovl.fmt.RSY.dl2,
13014 ovl.fmt.RSY.dh2); goto ok;
13015 case 0xeb00000000eaULL: s390_format_RSY_RRRD(s390_irgen_LAALG,
13016 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
13017 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
13018 ovl.fmt.RSY.dh2); goto ok;
sewardjd7bde722011-04-05 13:19:33 +000013019 case 0xeb00000000f2ULL: s390_format_RSY_RDRM(s390_irgen_LOC, ovl.fmt.RSY.r1,
13020 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13021 ovl.fmt.RSY.dl2,
13022 ovl.fmt.RSY.dh2, S390_XMNM_LOC);
13023 goto ok;
13024 case 0xeb00000000f3ULL: s390_format_RSY_RDRM(s390_irgen_STOC, ovl.fmt.RSY.r1,
13025 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13026 ovl.fmt.RSY.dl2,
13027 ovl.fmt.RSY.dh2,
13028 S390_XMNM_STOC); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013029 case 0xeb00000000f4ULL: s390_format_RSY_RRRD(s390_irgen_LAN, ovl.fmt.RSY.r1,
13030 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13031 ovl.fmt.RSY.dl2,
13032 ovl.fmt.RSY.dh2); goto ok;
13033 case 0xeb00000000f6ULL: s390_format_RSY_RRRD(s390_irgen_LAO, ovl.fmt.RSY.r1,
13034 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13035 ovl.fmt.RSY.dl2,
13036 ovl.fmt.RSY.dh2); goto ok;
13037 case 0xeb00000000f7ULL: s390_format_RSY_RRRD(s390_irgen_LAX, ovl.fmt.RSY.r1,
13038 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13039 ovl.fmt.RSY.dl2,
13040 ovl.fmt.RSY.dh2); goto ok;
13041 case 0xeb00000000f8ULL: s390_format_RSY_RRRD(s390_irgen_LAA, ovl.fmt.RSY.r1,
13042 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13043 ovl.fmt.RSY.dl2,
13044 ovl.fmt.RSY.dh2); goto ok;
13045 case 0xeb00000000faULL: s390_format_RSY_RRRD(s390_irgen_LAAL, ovl.fmt.RSY.r1,
13046 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13047 ovl.fmt.RSY.dl2,
13048 ovl.fmt.RSY.dh2); goto ok;
13049 case 0xec0000000044ULL: s390_format_RIE_RRP(s390_irgen_BRXHG, ovl.fmt.RIE.r1,
13050 ovl.fmt.RIE.r3, ovl.fmt.RIE.i2);
13051 goto ok;
13052 case 0xec0000000045ULL: s390_format_RIE_RRP(s390_irgen_BRXLG, ovl.fmt.RIE.r1,
13053 ovl.fmt.RIE.r3, ovl.fmt.RIE.i2);
13054 goto ok;
13055 case 0xec0000000051ULL: /* RISBLG */ goto unimplemented;
13056 case 0xec0000000054ULL: s390_format_RIE_RRUUU(s390_irgen_RNSBG,
13057 ovl.fmt.RIE_RRUUU.r1,
13058 ovl.fmt.RIE_RRUUU.r2,
13059 ovl.fmt.RIE_RRUUU.i3,
13060 ovl.fmt.RIE_RRUUU.i4,
13061 ovl.fmt.RIE_RRUUU.i5);
13062 goto ok;
13063 case 0xec0000000055ULL: s390_format_RIE_RRUUU(s390_irgen_RISBG,
13064 ovl.fmt.RIE_RRUUU.r1,
13065 ovl.fmt.RIE_RRUUU.r2,
13066 ovl.fmt.RIE_RRUUU.i3,
13067 ovl.fmt.RIE_RRUUU.i4,
13068 ovl.fmt.RIE_RRUUU.i5);
13069 goto ok;
13070 case 0xec0000000056ULL: s390_format_RIE_RRUUU(s390_irgen_ROSBG,
13071 ovl.fmt.RIE_RRUUU.r1,
13072 ovl.fmt.RIE_RRUUU.r2,
13073 ovl.fmt.RIE_RRUUU.i3,
13074 ovl.fmt.RIE_RRUUU.i4,
13075 ovl.fmt.RIE_RRUUU.i5);
13076 goto ok;
13077 case 0xec0000000057ULL: s390_format_RIE_RRUUU(s390_irgen_RXSBG,
13078 ovl.fmt.RIE_RRUUU.r1,
13079 ovl.fmt.RIE_RRUUU.r2,
13080 ovl.fmt.RIE_RRUUU.i3,
13081 ovl.fmt.RIE_RRUUU.i4,
13082 ovl.fmt.RIE_RRUUU.i5);
13083 goto ok;
13084 case 0xec000000005dULL: /* RISBHG */ goto unimplemented;
13085 case 0xec0000000064ULL: s390_format_RIE_RRPU(s390_irgen_CGRJ,
13086 ovl.fmt.RIE_RRPU.r1,
13087 ovl.fmt.RIE_RRPU.r2,
13088 ovl.fmt.RIE_RRPU.i4,
13089 ovl.fmt.RIE_RRPU.m3); goto ok;
13090 case 0xec0000000065ULL: s390_format_RIE_RRPU(s390_irgen_CLGRJ,
13091 ovl.fmt.RIE_RRPU.r1,
13092 ovl.fmt.RIE_RRPU.r2,
13093 ovl.fmt.RIE_RRPU.i4,
13094 ovl.fmt.RIE_RRPU.m3); goto ok;
13095 case 0xec0000000070ULL: /* CGIT */ goto unimplemented;
13096 case 0xec0000000071ULL: /* CLGIT */ goto unimplemented;
13097 case 0xec0000000072ULL: /* CIT */ goto unimplemented;
13098 case 0xec0000000073ULL: /* CLFIT */ goto unimplemented;
13099 case 0xec0000000076ULL: s390_format_RIE_RRPU(s390_irgen_CRJ,
13100 ovl.fmt.RIE_RRPU.r1,
13101 ovl.fmt.RIE_RRPU.r2,
13102 ovl.fmt.RIE_RRPU.i4,
13103 ovl.fmt.RIE_RRPU.m3); goto ok;
13104 case 0xec0000000077ULL: s390_format_RIE_RRPU(s390_irgen_CLRJ,
13105 ovl.fmt.RIE_RRPU.r1,
13106 ovl.fmt.RIE_RRPU.r2,
13107 ovl.fmt.RIE_RRPU.i4,
13108 ovl.fmt.RIE_RRPU.m3); goto ok;
13109 case 0xec000000007cULL: s390_format_RIE_RUPI(s390_irgen_CGIJ,
13110 ovl.fmt.RIEv3.r1,
13111 ovl.fmt.RIEv3.m3,
13112 ovl.fmt.RIEv3.i4,
13113 ovl.fmt.RIEv3.i2); goto ok;
13114 case 0xec000000007dULL: s390_format_RIE_RUPU(s390_irgen_CLGIJ,
13115 ovl.fmt.RIEv3.r1,
13116 ovl.fmt.RIEv3.m3,
13117 ovl.fmt.RIEv3.i4,
13118 ovl.fmt.RIEv3.i2); goto ok;
13119 case 0xec000000007eULL: s390_format_RIE_RUPI(s390_irgen_CIJ,
13120 ovl.fmt.RIEv3.r1,
13121 ovl.fmt.RIEv3.m3,
13122 ovl.fmt.RIEv3.i4,
13123 ovl.fmt.RIEv3.i2); goto ok;
13124 case 0xec000000007fULL: s390_format_RIE_RUPU(s390_irgen_CLIJ,
13125 ovl.fmt.RIEv3.r1,
13126 ovl.fmt.RIEv3.m3,
13127 ovl.fmt.RIEv3.i4,
13128 ovl.fmt.RIEv3.i2); goto ok;
13129 case 0xec00000000d8ULL: s390_format_RIE_RRI0(s390_irgen_AHIK, ovl.fmt.RIE.r1,
13130 ovl.fmt.RIE.r3, ovl.fmt.RIE.i2);
13131 goto ok;
13132 case 0xec00000000d9ULL: s390_format_RIE_RRI0(s390_irgen_AGHIK,
13133 ovl.fmt.RIE.r1, ovl.fmt.RIE.r3,
13134 ovl.fmt.RIE.i2); goto ok;
13135 case 0xec00000000daULL: s390_format_RIE_RRI0(s390_irgen_ALHSIK,
13136 ovl.fmt.RIE.r1, ovl.fmt.RIE.r3,
13137 ovl.fmt.RIE.i2); goto ok;
13138 case 0xec00000000dbULL: s390_format_RIE_RRI0(s390_irgen_ALGHSIK,
13139 ovl.fmt.RIE.r1, ovl.fmt.RIE.r3,
13140 ovl.fmt.RIE.i2); goto ok;
13141 case 0xec00000000e4ULL: s390_format_RRS(s390_irgen_CGRB, ovl.fmt.RRS.r1,
13142 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
13143 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
13144 goto ok;
13145 case 0xec00000000e5ULL: s390_format_RRS(s390_irgen_CLGRB, ovl.fmt.RRS.r1,
13146 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
13147 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
13148 goto ok;
13149 case 0xec00000000f6ULL: s390_format_RRS(s390_irgen_CRB, ovl.fmt.RRS.r1,
13150 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
13151 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
13152 goto ok;
13153 case 0xec00000000f7ULL: s390_format_RRS(s390_irgen_CLRB, ovl.fmt.RRS.r1,
13154 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
13155 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
13156 goto ok;
13157 case 0xec00000000fcULL: s390_format_RIS_RURDI(s390_irgen_CGIB,
13158 ovl.fmt.RIS.r1, ovl.fmt.RIS.m3,
13159 ovl.fmt.RIS.b4, ovl.fmt.RIS.d4,
13160 ovl.fmt.RIS.i2); goto ok;
13161 case 0xec00000000fdULL: s390_format_RIS_RURDU(s390_irgen_CLGIB,
13162 ovl.fmt.RIS.r1, ovl.fmt.RIS.m3,
13163 ovl.fmt.RIS.b4, ovl.fmt.RIS.d4,
13164 ovl.fmt.RIS.i2); goto ok;
13165 case 0xec00000000feULL: s390_format_RIS_RURDI(s390_irgen_CIB, ovl.fmt.RIS.r1,
13166 ovl.fmt.RIS.m3, ovl.fmt.RIS.b4,
13167 ovl.fmt.RIS.d4,
13168 ovl.fmt.RIS.i2); goto ok;
13169 case 0xec00000000ffULL: s390_format_RIS_RURDU(s390_irgen_CLIB,
13170 ovl.fmt.RIS.r1, ovl.fmt.RIS.m3,
13171 ovl.fmt.RIS.b4, ovl.fmt.RIS.d4,
13172 ovl.fmt.RIS.i2); goto ok;
13173 case 0xed0000000004ULL: s390_format_RXE_FRRD(s390_irgen_LDEB, ovl.fmt.RXE.r1,
13174 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
13175 ovl.fmt.RXE.d2); goto ok;
13176 case 0xed0000000005ULL: s390_format_RXE_FRRD(s390_irgen_LXDB, ovl.fmt.RXE.r1,
13177 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
13178 ovl.fmt.RXE.d2); goto ok;
13179 case 0xed0000000006ULL: s390_format_RXE_FRRD(s390_irgen_LXEB, ovl.fmt.RXE.r1,
13180 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
13181 ovl.fmt.RXE.d2); goto ok;
13182 case 0xed0000000007ULL: /* MXDB */ goto unimplemented;
13183 case 0xed0000000008ULL: /* KEB */ goto unimplemented;
13184 case 0xed0000000009ULL: s390_format_RXE_FRRD(s390_irgen_CEB, ovl.fmt.RXE.r1,
13185 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
13186 ovl.fmt.RXE.d2); goto ok;
13187 case 0xed000000000aULL: s390_format_RXE_FRRD(s390_irgen_AEB, ovl.fmt.RXE.r1,
13188 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
13189 ovl.fmt.RXE.d2); goto ok;
13190 case 0xed000000000bULL: s390_format_RXE_FRRD(s390_irgen_SEB, ovl.fmt.RXE.r1,
13191 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
13192 ovl.fmt.RXE.d2); goto ok;
13193 case 0xed000000000cULL: /* MDEB */ goto unimplemented;
13194 case 0xed000000000dULL: s390_format_RXE_FRRD(s390_irgen_DEB, ovl.fmt.RXE.r1,
13195 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
13196 ovl.fmt.RXE.d2); goto ok;
13197 case 0xed000000000eULL: s390_format_RXF_FRRDF(s390_irgen_MAEB,
13198 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
13199 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
13200 ovl.fmt.RXF.r1); goto ok;
13201 case 0xed000000000fULL: s390_format_RXF_FRRDF(s390_irgen_MSEB,
13202 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
13203 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
13204 ovl.fmt.RXF.r1); goto ok;
13205 case 0xed0000000010ULL: s390_format_RXE_FRRD(s390_irgen_TCEB, ovl.fmt.RXE.r1,
13206 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
13207 ovl.fmt.RXE.d2); goto ok;
13208 case 0xed0000000011ULL: s390_format_RXE_FRRD(s390_irgen_TCDB, ovl.fmt.RXE.r1,
13209 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
13210 ovl.fmt.RXE.d2); goto ok;
13211 case 0xed0000000012ULL: s390_format_RXE_FRRD(s390_irgen_TCXB, ovl.fmt.RXE.r1,
13212 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
13213 ovl.fmt.RXE.d2); goto ok;
13214 case 0xed0000000014ULL: s390_format_RXE_FRRD(s390_irgen_SQEB, ovl.fmt.RXE.r1,
13215 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
13216 ovl.fmt.RXE.d2); goto ok;
13217 case 0xed0000000015ULL: s390_format_RXE_FRRD(s390_irgen_SQDB, ovl.fmt.RXE.r1,
13218 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
13219 ovl.fmt.RXE.d2); goto ok;
13220 case 0xed0000000017ULL: s390_format_RXE_FRRD(s390_irgen_MEEB, ovl.fmt.RXE.r1,
13221 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
13222 ovl.fmt.RXE.d2); goto ok;
13223 case 0xed0000000018ULL: /* KDB */ goto unimplemented;
13224 case 0xed0000000019ULL: s390_format_RXE_FRRD(s390_irgen_CDB, ovl.fmt.RXE.r1,
13225 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
13226 ovl.fmt.RXE.d2); goto ok;
13227 case 0xed000000001aULL: s390_format_RXE_FRRD(s390_irgen_ADB, ovl.fmt.RXE.r1,
13228 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
13229 ovl.fmt.RXE.d2); goto ok;
13230 case 0xed000000001bULL: s390_format_RXE_FRRD(s390_irgen_SDB, ovl.fmt.RXE.r1,
13231 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
13232 ovl.fmt.RXE.d2); goto ok;
13233 case 0xed000000001cULL: s390_format_RXE_FRRD(s390_irgen_MDB, ovl.fmt.RXE.r1,
13234 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
13235 ovl.fmt.RXE.d2); goto ok;
13236 case 0xed000000001dULL: s390_format_RXE_FRRD(s390_irgen_DDB, ovl.fmt.RXE.r1,
13237 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
13238 ovl.fmt.RXE.d2); goto ok;
13239 case 0xed000000001eULL: s390_format_RXF_FRRDF(s390_irgen_MADB,
13240 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
13241 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
13242 ovl.fmt.RXF.r1); goto ok;
13243 case 0xed000000001fULL: s390_format_RXF_FRRDF(s390_irgen_MSDB,
13244 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
13245 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
13246 ovl.fmt.RXF.r1); goto ok;
13247 case 0xed0000000024ULL: /* LDE */ goto unimplemented;
13248 case 0xed0000000025ULL: /* LXD */ goto unimplemented;
13249 case 0xed0000000026ULL: /* LXE */ goto unimplemented;
13250 case 0xed000000002eULL: /* MAE */ goto unimplemented;
13251 case 0xed000000002fULL: /* MSE */ goto unimplemented;
13252 case 0xed0000000034ULL: /* SQE */ goto unimplemented;
13253 case 0xed0000000035ULL: /* SQD */ goto unimplemented;
13254 case 0xed0000000037ULL: /* MEE */ goto unimplemented;
13255 case 0xed0000000038ULL: /* MAYL */ goto unimplemented;
13256 case 0xed0000000039ULL: /* MYL */ goto unimplemented;
13257 case 0xed000000003aULL: /* MAY */ goto unimplemented;
13258 case 0xed000000003bULL: /* MY */ goto unimplemented;
13259 case 0xed000000003cULL: /* MAYH */ goto unimplemented;
13260 case 0xed000000003dULL: /* MYH */ goto unimplemented;
13261 case 0xed000000003eULL: /* MAD */ goto unimplemented;
13262 case 0xed000000003fULL: /* MSD */ goto unimplemented;
13263 case 0xed0000000040ULL: /* SLDT */ goto unimplemented;
13264 case 0xed0000000041ULL: /* SRDT */ goto unimplemented;
13265 case 0xed0000000048ULL: /* SLXT */ goto unimplemented;
13266 case 0xed0000000049ULL: /* SRXT */ goto unimplemented;
13267 case 0xed0000000050ULL: /* TDCET */ goto unimplemented;
13268 case 0xed0000000051ULL: /* TDGET */ goto unimplemented;
13269 case 0xed0000000054ULL: /* TDCDT */ goto unimplemented;
13270 case 0xed0000000055ULL: /* TDGDT */ goto unimplemented;
13271 case 0xed0000000058ULL: /* TDCXT */ goto unimplemented;
13272 case 0xed0000000059ULL: /* TDGXT */ goto unimplemented;
13273 case 0xed0000000064ULL: s390_format_RXY_FRRD(s390_irgen_LEY, ovl.fmt.RXY.r1,
13274 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13275 ovl.fmt.RXY.dl2,
13276 ovl.fmt.RXY.dh2); goto ok;
13277 case 0xed0000000065ULL: s390_format_RXY_FRRD(s390_irgen_LDY, ovl.fmt.RXY.r1,
13278 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13279 ovl.fmt.RXY.dl2,
13280 ovl.fmt.RXY.dh2); goto ok;
13281 case 0xed0000000066ULL: s390_format_RXY_FRRD(s390_irgen_STEY, ovl.fmt.RXY.r1,
13282 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13283 ovl.fmt.RXY.dl2,
13284 ovl.fmt.RXY.dh2); goto ok;
13285 case 0xed0000000067ULL: s390_format_RXY_FRRD(s390_irgen_STDY, ovl.fmt.RXY.r1,
13286 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13287 ovl.fmt.RXY.dl2,
13288 ovl.fmt.RXY.dh2); goto ok;
13289 }
13290
13291 switch (((ovl.value >> 16) & 0xff0f00000000ULL) >> 32) {
13292 case 0xc000ULL: s390_format_RIL_RP(s390_irgen_LARL, ovl.fmt.RIL.r1,
13293 ovl.fmt.RIL.i2); goto ok;
13294 case 0xc001ULL: s390_format_RIL_RI(s390_irgen_LGFI, ovl.fmt.RIL.r1,
13295 ovl.fmt.RIL.i2); goto ok;
13296 case 0xc004ULL: s390_format_RIL(s390_irgen_BRCL, ovl.fmt.RIL.r1,
13297 ovl.fmt.RIL.i2); goto ok;
13298 case 0xc005ULL: s390_format_RIL_RP(s390_irgen_BRASL, ovl.fmt.RIL.r1,
13299 ovl.fmt.RIL.i2); goto ok;
13300 case 0xc006ULL: s390_format_RIL_RU(s390_irgen_XIHF, ovl.fmt.RIL.r1,
13301 ovl.fmt.RIL.i2); goto ok;
13302 case 0xc007ULL: s390_format_RIL_RU(s390_irgen_XILF, ovl.fmt.RIL.r1,
13303 ovl.fmt.RIL.i2); goto ok;
13304 case 0xc008ULL: s390_format_RIL_RU(s390_irgen_IIHF, ovl.fmt.RIL.r1,
13305 ovl.fmt.RIL.i2); goto ok;
13306 case 0xc009ULL: s390_format_RIL_RU(s390_irgen_IILF, ovl.fmt.RIL.r1,
13307 ovl.fmt.RIL.i2); goto ok;
13308 case 0xc00aULL: s390_format_RIL_RU(s390_irgen_NIHF, ovl.fmt.RIL.r1,
13309 ovl.fmt.RIL.i2); goto ok;
13310 case 0xc00bULL: s390_format_RIL_RU(s390_irgen_NILF, ovl.fmt.RIL.r1,
13311 ovl.fmt.RIL.i2); goto ok;
13312 case 0xc00cULL: s390_format_RIL_RU(s390_irgen_OIHF, ovl.fmt.RIL.r1,
13313 ovl.fmt.RIL.i2); goto ok;
13314 case 0xc00dULL: s390_format_RIL_RU(s390_irgen_OILF, ovl.fmt.RIL.r1,
13315 ovl.fmt.RIL.i2); goto ok;
13316 case 0xc00eULL: s390_format_RIL_RU(s390_irgen_LLIHF, ovl.fmt.RIL.r1,
13317 ovl.fmt.RIL.i2); goto ok;
13318 case 0xc00fULL: s390_format_RIL_RU(s390_irgen_LLILF, ovl.fmt.RIL.r1,
13319 ovl.fmt.RIL.i2); goto ok;
13320 case 0xc200ULL: s390_format_RIL_RI(s390_irgen_MSGFI, ovl.fmt.RIL.r1,
13321 ovl.fmt.RIL.i2); goto ok;
13322 case 0xc201ULL: s390_format_RIL_RI(s390_irgen_MSFI, ovl.fmt.RIL.r1,
13323 ovl.fmt.RIL.i2); goto ok;
13324 case 0xc204ULL: s390_format_RIL_RU(s390_irgen_SLGFI, ovl.fmt.RIL.r1,
13325 ovl.fmt.RIL.i2); goto ok;
13326 case 0xc205ULL: s390_format_RIL_RU(s390_irgen_SLFI, ovl.fmt.RIL.r1,
13327 ovl.fmt.RIL.i2); goto ok;
13328 case 0xc208ULL: s390_format_RIL_RI(s390_irgen_AGFI, ovl.fmt.RIL.r1,
13329 ovl.fmt.RIL.i2); goto ok;
13330 case 0xc209ULL: s390_format_RIL_RI(s390_irgen_AFI, ovl.fmt.RIL.r1,
13331 ovl.fmt.RIL.i2); goto ok;
13332 case 0xc20aULL: s390_format_RIL_RU(s390_irgen_ALGFI, ovl.fmt.RIL.r1,
13333 ovl.fmt.RIL.i2); goto ok;
13334 case 0xc20bULL: s390_format_RIL_RU(s390_irgen_ALFI, ovl.fmt.RIL.r1,
13335 ovl.fmt.RIL.i2); goto ok;
13336 case 0xc20cULL: s390_format_RIL_RI(s390_irgen_CGFI, ovl.fmt.RIL.r1,
13337 ovl.fmt.RIL.i2); goto ok;
13338 case 0xc20dULL: s390_format_RIL_RI(s390_irgen_CFI, ovl.fmt.RIL.r1,
13339 ovl.fmt.RIL.i2); goto ok;
13340 case 0xc20eULL: s390_format_RIL_RU(s390_irgen_CLGFI, ovl.fmt.RIL.r1,
13341 ovl.fmt.RIL.i2); goto ok;
13342 case 0xc20fULL: s390_format_RIL_RU(s390_irgen_CLFI, ovl.fmt.RIL.r1,
13343 ovl.fmt.RIL.i2); goto ok;
13344 case 0xc402ULL: s390_format_RIL_RP(s390_irgen_LLHRL, ovl.fmt.RIL.r1,
13345 ovl.fmt.RIL.i2); goto ok;
13346 case 0xc404ULL: s390_format_RIL_RP(s390_irgen_LGHRL, ovl.fmt.RIL.r1,
13347 ovl.fmt.RIL.i2); goto ok;
13348 case 0xc405ULL: s390_format_RIL_RP(s390_irgen_LHRL, ovl.fmt.RIL.r1,
13349 ovl.fmt.RIL.i2); goto ok;
13350 case 0xc406ULL: s390_format_RIL_RP(s390_irgen_LLGHRL, ovl.fmt.RIL.r1,
13351 ovl.fmt.RIL.i2); goto ok;
13352 case 0xc407ULL: s390_format_RIL_RP(s390_irgen_STHRL, ovl.fmt.RIL.r1,
13353 ovl.fmt.RIL.i2); goto ok;
13354 case 0xc408ULL: s390_format_RIL_RP(s390_irgen_LGRL, ovl.fmt.RIL.r1,
13355 ovl.fmt.RIL.i2); goto ok;
13356 case 0xc40bULL: s390_format_RIL_RP(s390_irgen_STGRL, ovl.fmt.RIL.r1,
13357 ovl.fmt.RIL.i2); goto ok;
13358 case 0xc40cULL: s390_format_RIL_RP(s390_irgen_LGFRL, ovl.fmt.RIL.r1,
13359 ovl.fmt.RIL.i2); goto ok;
13360 case 0xc40dULL: s390_format_RIL_RP(s390_irgen_LRL, ovl.fmt.RIL.r1,
13361 ovl.fmt.RIL.i2); goto ok;
13362 case 0xc40eULL: s390_format_RIL_RP(s390_irgen_LLGFRL, ovl.fmt.RIL.r1,
13363 ovl.fmt.RIL.i2); goto ok;
13364 case 0xc40fULL: s390_format_RIL_RP(s390_irgen_STRL, ovl.fmt.RIL.r1,
13365 ovl.fmt.RIL.i2); goto ok;
13366 case 0xc600ULL: s390_format_RIL_RP(s390_irgen_EXRL, ovl.fmt.RIL.r1,
13367 ovl.fmt.RIL.i2); goto ok;
13368 case 0xc602ULL: s390_format_RIL_UP(s390_irgen_PFDRL, ovl.fmt.RIL.r1,
13369 ovl.fmt.RIL.i2); goto ok;
13370 case 0xc604ULL: s390_format_RIL_RP(s390_irgen_CGHRL, ovl.fmt.RIL.r1,
13371 ovl.fmt.RIL.i2); goto ok;
13372 case 0xc605ULL: s390_format_RIL_RP(s390_irgen_CHRL, ovl.fmt.RIL.r1,
13373 ovl.fmt.RIL.i2); goto ok;
13374 case 0xc606ULL: s390_format_RIL_RP(s390_irgen_CLGHRL, ovl.fmt.RIL.r1,
13375 ovl.fmt.RIL.i2); goto ok;
13376 case 0xc607ULL: s390_format_RIL_RP(s390_irgen_CLHRL, ovl.fmt.RIL.r1,
13377 ovl.fmt.RIL.i2); goto ok;
13378 case 0xc608ULL: s390_format_RIL_RP(s390_irgen_CGRL, ovl.fmt.RIL.r1,
13379 ovl.fmt.RIL.i2); goto ok;
13380 case 0xc60aULL: s390_format_RIL_RP(s390_irgen_CLGRL, ovl.fmt.RIL.r1,
13381 ovl.fmt.RIL.i2); goto ok;
13382 case 0xc60cULL: s390_format_RIL_RP(s390_irgen_CGFRL, ovl.fmt.RIL.r1,
13383 ovl.fmt.RIL.i2); goto ok;
13384 case 0xc60dULL: s390_format_RIL_RP(s390_irgen_CRL, ovl.fmt.RIL.r1,
13385 ovl.fmt.RIL.i2); goto ok;
13386 case 0xc60eULL: s390_format_RIL_RP(s390_irgen_CLGFRL, ovl.fmt.RIL.r1,
13387 ovl.fmt.RIL.i2); goto ok;
13388 case 0xc60fULL: s390_format_RIL_RP(s390_irgen_CLRL, ovl.fmt.RIL.r1,
13389 ovl.fmt.RIL.i2); goto ok;
13390 case 0xc800ULL: /* MVCOS */ goto unimplemented;
13391 case 0xc801ULL: /* ECTG */ goto unimplemented;
13392 case 0xc802ULL: /* CSST */ goto unimplemented;
13393 case 0xc804ULL: /* LPD */ goto unimplemented;
13394 case 0xc805ULL: /* LPDG */ goto unimplemented;
13395 case 0xcc06ULL: /* BRCTH */ goto unimplemented;
13396 case 0xcc08ULL: s390_format_RIL_RI(s390_irgen_AIH, ovl.fmt.RIL.r1,
13397 ovl.fmt.RIL.i2); goto ok;
13398 case 0xcc0aULL: s390_format_RIL_RI(s390_irgen_ALSIH, ovl.fmt.RIL.r1,
13399 ovl.fmt.RIL.i2); goto ok;
13400 case 0xcc0bULL: s390_format_RIL_RI(s390_irgen_ALSIHN, ovl.fmt.RIL.r1,
13401 ovl.fmt.RIL.i2); goto ok;
13402 case 0xcc0dULL: s390_format_RIL_RI(s390_irgen_CIH, ovl.fmt.RIL.r1,
13403 ovl.fmt.RIL.i2); goto ok;
13404 case 0xcc0fULL: s390_format_RIL_RU(s390_irgen_CLIH, ovl.fmt.RIL.r1,
13405 ovl.fmt.RIL.i2); goto ok;
13406 }
13407
13408 switch (((ovl.value >> 16) & 0xff0000000000ULL) >> 40) {
13409 case 0xd0ULL: /* TRTR */ goto unimplemented;
13410 case 0xd1ULL: /* MVN */ goto unimplemented;
13411 case 0xd2ULL: s390_format_SS_L0RDRD(s390_irgen_MVC, ovl.fmt.SS.l,
13412 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
13413 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
13414 case 0xd3ULL: /* MVZ */ goto unimplemented;
13415 case 0xd4ULL: s390_format_SS_L0RDRD(s390_irgen_NC, ovl.fmt.SS.l,
13416 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
13417 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
13418 case 0xd5ULL: s390_format_SS_L0RDRD(s390_irgen_CLC, ovl.fmt.SS.l,
13419 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
13420 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
13421 case 0xd6ULL: s390_format_SS_L0RDRD(s390_irgen_OC, ovl.fmt.SS.l,
13422 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
13423 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
sewardjb63967e2011-03-24 08:50:04 +000013424 case 0xd7ULL:
13425 if (ovl.fmt.SS.b1 == ovl.fmt.SS.b2 && ovl.fmt.SS.d1 == ovl.fmt.SS.d2)
13426 s390_irgen_XC_sameloc(ovl.fmt.SS.l, ovl.fmt.SS.b1, ovl.fmt.SS.d1);
13427 else
13428 s390_format_SS_L0RDRD(s390_irgen_XC, ovl.fmt.SS.l,
13429 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
13430 ovl.fmt.SS.b2, ovl.fmt.SS.d2);
13431 goto ok;
sewardj2019a972011-03-07 16:04:07 +000013432 case 0xd9ULL: /* MVCK */ goto unimplemented;
13433 case 0xdaULL: /* MVCP */ goto unimplemented;
13434 case 0xdbULL: /* MVCS */ goto unimplemented;
florian730448f2012-02-04 17:07:07 +000013435 case 0xdcULL: s390_format_SS_L0RDRD(s390_irgen_TR, ovl.fmt.SS.l,
13436 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
13437 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013438 case 0xddULL: /* TRT */ goto unimplemented;
13439 case 0xdeULL: /* ED */ goto unimplemented;
13440 case 0xdfULL: /* EDMK */ goto unimplemented;
13441 case 0xe1ULL: /* PKU */ goto unimplemented;
13442 case 0xe2ULL: /* UNPKU */ goto unimplemented;
13443 case 0xe8ULL: /* MVCIN */ goto unimplemented;
13444 case 0xe9ULL: /* PKA */ goto unimplemented;
13445 case 0xeaULL: /* UNPKA */ goto unimplemented;
13446 case 0xeeULL: /* PLO */ goto unimplemented;
13447 case 0xefULL: /* LMD */ goto unimplemented;
13448 case 0xf0ULL: /* SRP */ goto unimplemented;
13449 case 0xf1ULL: /* MVO */ goto unimplemented;
13450 case 0xf2ULL: /* PACK */ goto unimplemented;
13451 case 0xf3ULL: /* UNPK */ goto unimplemented;
13452 case 0xf8ULL: /* ZAP */ goto unimplemented;
13453 case 0xf9ULL: /* CP */ goto unimplemented;
13454 case 0xfaULL: /* AP */ goto unimplemented;
13455 case 0xfbULL: /* SP */ goto unimplemented;
13456 case 0xfcULL: /* MP */ goto unimplemented;
13457 case 0xfdULL: /* DP */ goto unimplemented;
13458 }
13459
13460 switch (((ovl.value >> 16) & 0xffff00000000ULL) >> 32) {
13461 case 0xe500ULL: /* LASP */ goto unimplemented;
13462 case 0xe501ULL: /* TPROT */ goto unimplemented;
13463 case 0xe502ULL: /* STRAG */ goto unimplemented;
13464 case 0xe50eULL: /* MVCSK */ goto unimplemented;
13465 case 0xe50fULL: /* MVCDK */ goto unimplemented;
13466 case 0xe544ULL: s390_format_SIL_RDI(s390_irgen_MVHHI, ovl.fmt.SIL.b1,
13467 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
13468 goto ok;
13469 case 0xe548ULL: s390_format_SIL_RDI(s390_irgen_MVGHI, ovl.fmt.SIL.b1,
13470 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
13471 goto ok;
13472 case 0xe54cULL: s390_format_SIL_RDI(s390_irgen_MVHI, ovl.fmt.SIL.b1,
13473 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
13474 goto ok;
13475 case 0xe554ULL: s390_format_SIL_RDI(s390_irgen_CHHSI, ovl.fmt.SIL.b1,
13476 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
13477 goto ok;
13478 case 0xe555ULL: s390_format_SIL_RDU(s390_irgen_CLHHSI, ovl.fmt.SIL.b1,
13479 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
13480 goto ok;
13481 case 0xe558ULL: s390_format_SIL_RDI(s390_irgen_CGHSI, ovl.fmt.SIL.b1,
13482 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
13483 goto ok;
13484 case 0xe559ULL: s390_format_SIL_RDU(s390_irgen_CLGHSI, ovl.fmt.SIL.b1,
13485 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
13486 goto ok;
13487 case 0xe55cULL: s390_format_SIL_RDI(s390_irgen_CHSI, ovl.fmt.SIL.b1,
13488 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
13489 goto ok;
13490 case 0xe55dULL: s390_format_SIL_RDU(s390_irgen_CLFHSI, ovl.fmt.SIL.b1,
13491 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
13492 goto ok;
13493 }
13494
13495 return S390_DECODE_UNKNOWN_INSN;
13496
13497ok:
13498 return S390_DECODE_OK;
13499
13500unimplemented:
13501 return S390_DECODE_UNIMPLEMENTED_INSN;
13502}
13503
13504/* Handle "special" instructions. */
13505static s390_decode_t
13506s390_decode_special_and_irgen(UChar *bytes)
13507{
13508 s390_decode_t status = S390_DECODE_OK;
13509
13510 /* Got a "Special" instruction preamble. Which one is it? */
13511 if (bytes[0] == 0x18 && bytes[1] == 0x22 /* lr %r2, %r2 */) {
13512 s390_irgen_client_request();
13513 } else if (bytes[0] == 0x18 && bytes[1] == 0x33 /* lr %r3, %r3 */) {
13514 s390_irgen_guest_NRADDR();
13515 } else if (bytes[0] == 0x18 && bytes[1] == 0x44 /* lr %r4, %r4 */) {
13516 s390_irgen_call_noredir();
13517 } else {
13518 /* We don't know what it is. */
13519 return S390_DECODE_UNKNOWN_SPECIAL_INSN;
13520 }
13521
13522 dis_res->len = S390_SPECIAL_OP_PREAMBLE_SIZE + S390_SPECIAL_OP_SIZE;
13523
13524 return status;
13525}
13526
13527
13528/* Function returns # bytes that were decoded or 0 in case of failure */
florianb4df7682011-07-05 02:09:01 +000013529static UInt
sewardj2019a972011-03-07 16:04:07 +000013530s390_decode_and_irgen(UChar *bytes, UInt insn_length, DisResult *dres)
13531{
13532 s390_decode_t status;
13533
13534 dis_res = dres;
13535
13536 /* Spot the 8-byte preamble: 18ff lr r15,r15
13537 1811 lr r1,r1
13538 1822 lr r2,r2
13539 1833 lr r3,r3 */
13540 if (bytes[ 0] == 0x18 && bytes[ 1] == 0xff && bytes[ 2] == 0x18 &&
13541 bytes[ 3] == 0x11 && bytes[ 4] == 0x18 && bytes[ 5] == 0x22 &&
13542 bytes[ 6] == 0x18 && bytes[ 7] == 0x33) {
13543
13544 /* Handle special instruction that follows that preamble. */
13545 if (0) vex_printf("special function handling...\n");
florian2c8ed942011-08-01 22:07:51 +000013546
13547 insn_length = S390_SPECIAL_OP_PREAMBLE_SIZE + S390_SPECIAL_OP_SIZE;
13548 guest_IA_next_instr = guest_IA_curr_instr + insn_length;
13549
13550 status =
13551 s390_decode_special_and_irgen(bytes + S390_SPECIAL_OP_PREAMBLE_SIZE);
sewardj2019a972011-03-07 16:04:07 +000013552 } else {
13553 /* Handle normal instructions. */
13554 switch (insn_length) {
13555 case 2:
13556 status = s390_decode_2byte_and_irgen(bytes);
13557 break;
13558
13559 case 4:
13560 status = s390_decode_4byte_and_irgen(bytes);
13561 break;
13562
13563 case 6:
13564 status = s390_decode_6byte_and_irgen(bytes);
13565 break;
13566
13567 default:
13568 status = S390_DECODE_ERROR;
13569 break;
13570 }
13571 }
florian5fcbba22011-07-27 20:40:22 +000013572 /* If next instruction is execute, stop here */
florianf9e1ed72012-04-17 02:41:56 +000013573 if (dis_res->whatNext == Dis_Continue && bytes[insn_length] == 0x44) {
13574 put_IA(mkaddr_expr(guest_IA_next_instr));
sewardj2019a972011-03-07 16:04:07 +000013575 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +000013576 dis_res->jk_StopHere = Ijk_Boring;
sewardj2019a972011-03-07 16:04:07 +000013577 }
13578
13579 if (status == S390_DECODE_OK) return insn_length; /* OK */
13580
13581 /* Decoding failed somehow */
13582 vex_printf("vex s390->IR: ");
13583 switch (status) {
13584 case S390_DECODE_UNKNOWN_INSN:
13585 vex_printf("unknown insn: ");
13586 break;
13587
13588 case S390_DECODE_UNIMPLEMENTED_INSN:
13589 vex_printf("unimplemented insn: ");
13590 break;
13591
13592 case S390_DECODE_UNKNOWN_SPECIAL_INSN:
13593 vex_printf("unimplemented special insn: ");
13594 break;
13595
13596 default:
13597 case S390_DECODE_ERROR:
13598 vex_printf("decoding error: ");
13599 break;
13600 }
13601
13602 vex_printf("%02x%02x", bytes[0], bytes[1]);
13603 if (insn_length > 2) {
13604 vex_printf(" %02x%02x", bytes[2], bytes[3]);
13605 }
13606 if (insn_length > 4) {
13607 vex_printf(" %02x%02x", bytes[4], bytes[5]);
13608 }
13609 vex_printf("\n");
13610
13611 return 0; /* Failed */
13612}
13613
13614
sewardj2019a972011-03-07 16:04:07 +000013615/* Disassemble a single instruction INSN into IR. */
13616static DisResult
florian420c5012011-07-22 02:12:28 +000013617disInstr_S390_WRK(UChar *insn)
sewardj2019a972011-03-07 16:04:07 +000013618{
13619 UChar byte;
13620 UInt insn_length;
13621 DisResult dres;
13622
13623 /* ---------------------------------------------------- */
13624 /* --- Compute instruction length -- */
13625 /* ---------------------------------------------------- */
13626
13627 /* Get the first byte of the insn. */
13628 byte = insn[0];
13629
13630 /* The leftmost two bits (0:1) encode the length of the insn in bytes.
13631 00 -> 2 bytes, 01 -> 4 bytes, 10 -> 4 bytes, 11 -> 6 bytes. */
13632 insn_length = ((((byte >> 6) + 1) >> 1) + 1) << 1;
13633
13634 guest_IA_next_instr = guest_IA_curr_instr + insn_length;
13635
13636 /* ---------------------------------------------------- */
13637 /* --- Initialise the DisResult data -- */
13638 /* ---------------------------------------------------- */
13639 dres.whatNext = Dis_Continue;
13640 dres.len = insn_length;
13641 dres.continueAt = 0;
florian8844a632012-04-13 04:04:06 +000013642 dres.jk_StopHere = Ijk_INVALID;
sewardj2019a972011-03-07 16:04:07 +000013643
floriana99f20e2011-07-17 14:16:41 +000013644 /* fixs390: consider chasing of conditional jumps */
13645
sewardj2019a972011-03-07 16:04:07 +000013646 /* Normal and special instruction handling starts here. */
13647 if (s390_decode_and_irgen(insn, insn_length, &dres) == 0) {
13648 /* All decode failures end up here. The decoder has already issued an
13649 error message.
13650 Tell the dispatcher that this insn cannot be decoded, and so has
florian8844a632012-04-13 04:04:06 +000013651 not been executed, and (is currently) the next to be executed. */
florian65b5b3f2012-04-22 02:51:27 +000013652 put_IA(mkaddr_expr(guest_IA_next_instr));
sewardj2019a972011-03-07 16:04:07 +000013653
florian8844a632012-04-13 04:04:06 +000013654 dres.whatNext = Dis_StopHere;
13655 dres.jk_StopHere = Ijk_NoDecode;
13656 dres.continueAt = 0;
13657 dres.len = 0;
13658 } else {
13659 /* Decode success */
13660 switch (dres.whatNext) {
13661 case Dis_Continue:
florian8559e412012-04-19 14:23:48 +000013662 put_IA(mkaddr_expr(guest_IA_next_instr));
florian8844a632012-04-13 04:04:06 +000013663 break;
13664 case Dis_ResteerU:
13665 case Dis_ResteerC:
13666 put_IA(mkaddr_expr(dres.continueAt));
13667 break;
13668 case Dis_StopHere:
13669 break;
13670 default:
13671 vassert(0);
13672 }
sewardj2019a972011-03-07 16:04:07 +000013673 }
13674
13675 return dres;
13676}
13677
13678
13679/*------------------------------------------------------------*/
13680/*--- Top-level fn ---*/
13681/*------------------------------------------------------------*/
13682
13683/* Disassemble a single instruction into IR. The instruction
13684 is located in host memory at &guest_code[delta]. */
13685
13686DisResult
13687disInstr_S390(IRSB *irsb_IN,
sewardj2019a972011-03-07 16:04:07 +000013688 Bool (*resteerOkFn)(void *, Addr64),
13689 Bool resteerCisOk,
13690 void *callback_opaque,
13691 UChar *guest_code,
13692 Long delta,
13693 Addr64 guest_IP,
13694 VexArch guest_arch,
13695 VexArchInfo *archinfo,
13696 VexAbiInfo *abiinfo,
13697 Bool host_bigendian)
13698{
13699 vassert(guest_arch == VexArchS390X);
13700
13701 /* The instruction decoder requires a big-endian machine. */
13702 vassert(host_bigendian == True);
13703
13704 /* Set globals (see top of this file) */
13705 guest_IA_curr_instr = guest_IP;
sewardj2019a972011-03-07 16:04:07 +000013706 irsb = irsb_IN;
florian420c5012011-07-22 02:12:28 +000013707 resteer_fn = resteerOkFn;
13708 resteer_data = callback_opaque;
sewardj2019a972011-03-07 16:04:07 +000013709
florian420c5012011-07-22 02:12:28 +000013710 return disInstr_S390_WRK(guest_code + delta);
sewardj2019a972011-03-07 16:04:07 +000013711}
13712
13713/*---------------------------------------------------------------*/
13714/*--- end guest_s390_toIR.c ---*/
13715/*---------------------------------------------------------------*/