blob: 1b12254d49b24f31fee7169825da1ac6c2ee6052 [file] [log] [blame]
sewardj2019a972011-03-07 16:04:07 +00001/* -*- mode: C; c-basic-offset: 3; -*- */
2
3/*---------------------------------------------------------------*/
4/*--- begin guest_s390_toIR.c ---*/
5/*---------------------------------------------------------------*/
6
7/*
8 This file is part of Valgrind, a dynamic binary instrumentation
9 framework.
10
11 Copyright IBM Corp. 2010-2011
12
13 This program is free software; you can redistribute it and/or
14 modify it under the terms of the GNU General Public License as
15 published by the Free Software Foundation; either version 2 of the
16 License, or (at your option) any later version.
17
18 This program is distributed in the hope that it will be useful, but
19 WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 General Public License for more details.
22
23 You should have received a copy of the GNU General Public License
24 along with this program; if not, write to the Free Software
25 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
26 02110-1301, USA.
27
28 The GNU General Public License is contained in the file COPYING.
29*/
30
31/* Contributed by Florian Krohm and Christian Borntraeger */
32
33/* Translates s390 code to IR. */
34
35#include "libvex_basictypes.h"
36#include "libvex_ir.h"
sewardj2019a972011-03-07 16:04:07 +000037#include "libvex.h" /* needed for bb_to_IR.h */
florian933065d2011-07-11 01:48:02 +000038#include "libvex_s390x_common.h"
sewardj2019a972011-03-07 16:04:07 +000039#include "main_util.h" /* vassert */
40#include "main_globals.h" /* vex_traceflags */
41#include "guest_generic_bb_to_IR.h" /* DisResult */
42#include "guest_s390_defs.h" /* prototypes for this file's functions */
43#include "host_s390_disasm.h"
44#include "host_s390_defs.h" /* S390_ROUND_xyzzy */
45
sewardj2019a972011-03-07 16:04:07 +000046
47/*------------------------------------------------------------*/
florianb4df7682011-07-05 02:09:01 +000048/*--- Forward declarations ---*/
49/*------------------------------------------------------------*/
50static UInt s390_decode_and_irgen(UChar *, UInt, DisResult *);
florianb0bf6602012-05-05 00:01:16 +000051static void s390_irgen_xonc(IROp, IRTemp, IRTemp, IRTemp);
florian79e839e2012-05-05 02:20:30 +000052static void s390_irgen_CLC_EX(IRTemp, IRTemp, IRTemp);
florianb4df7682011-07-05 02:09:01 +000053
54
55/*------------------------------------------------------------*/
sewardj2019a972011-03-07 16:04:07 +000056/*--- Globals ---*/
57/*------------------------------------------------------------*/
58
59/* The IRSB* into which we're generating code. */
60static IRSB *irsb;
61
62/* The guest address for the instruction currently being
63 translated. */
64static Addr64 guest_IA_curr_instr;
65
66/* The guest address for the instruction following the current instruction. */
67static Addr64 guest_IA_next_instr;
68
69/* Result of disassembly step. */
70static DisResult *dis_res;
71
floriana64c2432011-07-16 02:11:50 +000072/* Resteer function and callback data */
73static Bool (*resteer_fn)(void *, Addr64);
74static void *resteer_data;
75
sewardj2019a972011-03-07 16:04:07 +000076/* The last seen execute target instruction */
77ULong last_execute_target;
78
79/* The possible outcomes of a decoding operation */
80typedef enum {
81 S390_DECODE_OK,
82 S390_DECODE_UNKNOWN_INSN,
83 S390_DECODE_UNIMPLEMENTED_INSN,
84 S390_DECODE_UNKNOWN_SPECIAL_INSN,
85 S390_DECODE_ERROR
86} s390_decode_t;
87
florian428dfdd2012-03-27 03:09:49 +000088
sewardj2019a972011-03-07 16:04:07 +000089/*------------------------------------------------------------*/
90/*--- Helpers for constructing IR. ---*/
91/*------------------------------------------------------------*/
92
93/* Sign extend a value with the given number of bits. This is a
94 macro because it allows us to overload the type of the value.
95 Note that VALUE must have a signed type! */
96#undef sign_extend
97#define sign_extend(value,num_bits) \
98(((value) << (sizeof(__typeof__(value)) * 8 - (num_bits))) >> \
99 (sizeof(__typeof__(value)) * 8 - (num_bits)))
100
101
102/* Add a statement to the current irsb. */
103static __inline__ void
104stmt(IRStmt *st)
105{
106 addStmtToIRSB(irsb, st);
107}
108
109/* Allocate a new temporary of the given type. */
110static __inline__ IRTemp
111newTemp(IRType type)
112{
113 vassert(isPlausibleIRType(type));
114
115 return newIRTemp(irsb->tyenv, type);
116}
117
118/* Create an expression node for a temporary */
119static __inline__ IRExpr *
120mkexpr(IRTemp tmp)
121{
122 return IRExpr_RdTmp(tmp);
123}
124
florian8844a632012-04-13 04:04:06 +0000125/* Generate an expression node for an address. */
126static __inline__ IRExpr *
127mkaddr_expr(Addr64 addr)
128{
129 return IRExpr_Const(IRConst_U64(addr));
130}
131
sewardj2019a972011-03-07 16:04:07 +0000132/* Add a statement that assigns to a temporary */
133static __inline__ void
134assign(IRTemp dst, IRExpr *expr)
135{
136 stmt(IRStmt_WrTmp(dst, expr));
137}
138
florian8844a632012-04-13 04:04:06 +0000139/* Write an address into the guest_IA */
140static __inline__ void
141put_IA(IRExpr *address)
142{
143 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_IA), address));
144}
145
sewardj2019a972011-03-07 16:04:07 +0000146/* Create a temporary of the given type and assign the expression to it */
147static __inline__ IRTemp
148mktemp(IRType type, IRExpr *expr)
149{
150 IRTemp temp = newTemp(type);
151
152 assign(temp, expr);
153
154 return temp;
155}
156
157/* Create a unary expression */
158static __inline__ IRExpr *
159unop(IROp kind, IRExpr *op)
160{
161 return IRExpr_Unop(kind, op);
162}
163
164/* Create a binary expression */
165static __inline__ IRExpr *
166binop(IROp kind, IRExpr *op1, IRExpr *op2)
167{
168 return IRExpr_Binop(kind, op1, op2);
169}
170
171/* Create a ternary expression */
172static __inline__ IRExpr *
173triop(IROp kind, IRExpr *op1, IRExpr *op2, IRExpr *op3)
174{
175 return IRExpr_Triop(kind, op1, op2, op3);
176}
177
178/* Create a quaternary expression */
179static __inline__ IRExpr *
180qop(IROp kind, IRExpr *op1, IRExpr *op2, IRExpr *op3, IRExpr *op4)
181{
182 return IRExpr_Qop(kind, op1, op2, op3, op4);
183}
184
185/* Create an expression node for an 8-bit integer constant */
186static __inline__ IRExpr *
187mkU8(UInt value)
188{
189 vassert(value < 256);
190
191 return IRExpr_Const(IRConst_U8((UChar)value));
192}
193
194/* Create an expression node for a 16-bit integer constant */
195static __inline__ IRExpr *
196mkU16(UInt value)
197{
198 vassert(value < 65536);
199
200 return IRExpr_Const(IRConst_U16((UShort)value));
201}
202
203/* Create an expression node for a 32-bit integer constant */
204static __inline__ IRExpr *
205mkU32(UInt value)
206{
207 return IRExpr_Const(IRConst_U32(value));
208}
209
210/* Create an expression node for a 64-bit integer constant */
211static __inline__ IRExpr *
212mkU64(ULong value)
213{
214 return IRExpr_Const(IRConst_U64(value));
215}
216
217/* Create an expression node for a 32-bit floating point constant
218 whose value is given by a bit pattern. */
219static __inline__ IRExpr *
220mkF32i(UInt value)
221{
222 return IRExpr_Const(IRConst_F32i(value));
223}
224
225/* Create an expression node for a 32-bit floating point constant
226 whose value is given by a bit pattern. */
227static __inline__ IRExpr *
228mkF64i(ULong value)
229{
230 return IRExpr_Const(IRConst_F64i(value));
231}
232
233/* Little helper function for my sanity. ITE = if-then-else */
234static IRExpr *
235mkite(IRExpr *condition, IRExpr *iftrue, IRExpr *iffalse)
236{
237 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
238
239 return IRExpr_Mux0X(unop(Iop_1Uto8, condition), iffalse, iftrue);
240}
241
242/* Add a statement that stores DATA at ADDR. This is a big-endian machine. */
243static void __inline__
244store(IRExpr *addr, IRExpr *data)
245{
246 stmt(IRStmt_Store(Iend_BE, addr, data));
247}
248
249/* Create an expression that loads a TYPE sized value from ADDR.
250 This is a big-endian machine. */
251static __inline__ IRExpr *
252load(IRType type, IRExpr *addr)
253{
254 return IRExpr_Load(Iend_BE, type, addr);
255}
256
257/* Function call */
258static void
259call_function(IRExpr *callee_address)
260{
florian8844a632012-04-13 04:04:06 +0000261 put_IA(callee_address);
sewardj2019a972011-03-07 16:04:07 +0000262
florian8844a632012-04-13 04:04:06 +0000263 dis_res->whatNext = Dis_StopHere;
264 dis_res->jk_StopHere = Ijk_Call;
sewardj2019a972011-03-07 16:04:07 +0000265}
266
floriana64c2432011-07-16 02:11:50 +0000267/* Function call with known target. */
268static void
269call_function_and_chase(Addr64 callee_address)
270{
271 if (resteer_fn(resteer_data, callee_address)) {
272 dis_res->whatNext = Dis_ResteerU;
273 dis_res->continueAt = callee_address;
274 } else {
florian8844a632012-04-13 04:04:06 +0000275 put_IA(mkaddr_expr(callee_address));
276
floriana64c2432011-07-16 02:11:50 +0000277 dis_res->whatNext = Dis_StopHere;
florian8844a632012-04-13 04:04:06 +0000278 dis_res->jk_StopHere = Ijk_Call;
floriana64c2432011-07-16 02:11:50 +0000279 }
280}
281
sewardj2019a972011-03-07 16:04:07 +0000282/* Function return sequence */
283static void
284return_from_function(IRExpr *return_address)
285{
florian8844a632012-04-13 04:04:06 +0000286 put_IA(return_address);
sewardj2019a972011-03-07 16:04:07 +0000287
florian8844a632012-04-13 04:04:06 +0000288 dis_res->whatNext = Dis_StopHere;
289 dis_res->jk_StopHere = Ijk_Ret;
sewardj2019a972011-03-07 16:04:07 +0000290}
291
292/* A conditional branch whose target is not known at instrumentation time.
293
294 if (condition) goto computed_target;
295
296 Needs to be represented as:
297
298 if (! condition) goto next_instruction;
299 goto computed_target;
sewardj2019a972011-03-07 16:04:07 +0000300*/
301static void
florianf321da72012-07-21 20:32:57 +0000302if_condition_goto_computed(IRExpr *condition, IRExpr *target)
sewardj2019a972011-03-07 16:04:07 +0000303{
304 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
305
florianf321da72012-07-21 20:32:57 +0000306 condition = unop(Iop_Not1, condition);
307
florian8844a632012-04-13 04:04:06 +0000308 stmt(IRStmt_Exit(condition, Ijk_Boring, IRConst_U64(guest_IA_next_instr),
309 S390X_GUEST_OFFSET(guest_IA)));
sewardj2019a972011-03-07 16:04:07 +0000310
florian8844a632012-04-13 04:04:06 +0000311 put_IA(target);
sewardj2019a972011-03-07 16:04:07 +0000312
florian8844a632012-04-13 04:04:06 +0000313 dis_res->whatNext = Dis_StopHere;
314 dis_res->jk_StopHere = Ijk_Boring;
sewardj2019a972011-03-07 16:04:07 +0000315}
316
317/* A conditional branch whose target is known at instrumentation time. */
318static void
319if_condition_goto(IRExpr *condition, Addr64 target)
320{
321 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
322
florian8844a632012-04-13 04:04:06 +0000323 stmt(IRStmt_Exit(condition, Ijk_Boring, IRConst_U64(target),
324 S390X_GUEST_OFFSET(guest_IA)));
325
florian7346c7a2012-04-13 21:14:24 +0000326 put_IA(mkaddr_expr(guest_IA_next_instr));
florian8844a632012-04-13 04:04:06 +0000327
328 dis_res->whatNext = Dis_StopHere;
329 dis_res->jk_StopHere = Ijk_Boring;
sewardj2019a972011-03-07 16:04:07 +0000330}
331
332/* An unconditional branch. Target may or may not be known at instrumentation
333 time. */
334static void
335always_goto(IRExpr *target)
336{
florian8844a632012-04-13 04:04:06 +0000337 put_IA(target);
sewardj2019a972011-03-07 16:04:07 +0000338
florian8844a632012-04-13 04:04:06 +0000339 dis_res->whatNext = Dis_StopHere;
340 dis_res->jk_StopHere = Ijk_Boring;
sewardj2019a972011-03-07 16:04:07 +0000341}
342
florian8844a632012-04-13 04:04:06 +0000343
floriana64c2432011-07-16 02:11:50 +0000344/* An unconditional branch to a known target. */
345static void
346always_goto_and_chase(Addr64 target)
347{
348 if (resteer_fn(resteer_data, target)) {
florian8844a632012-04-13 04:04:06 +0000349 /* Follow into the target */
floriana64c2432011-07-16 02:11:50 +0000350 dis_res->whatNext = Dis_ResteerU;
351 dis_res->continueAt = target;
352 } else {
florian8844a632012-04-13 04:04:06 +0000353 put_IA(mkaddr_expr(target));
354
355 dis_res->whatNext = Dis_StopHere;
356 dis_res->jk_StopHere = Ijk_Boring;
floriana64c2432011-07-16 02:11:50 +0000357 }
358}
359
sewardj2019a972011-03-07 16:04:07 +0000360/* A system call */
361static void
362system_call(IRExpr *sysno)
363{
364 /* Store the system call number in the pseudo register. */
florian428dfdd2012-03-27 03:09:49 +0000365 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_SYSNO), sysno));
sewardj2019a972011-03-07 16:04:07 +0000366
sewardj69007022011-04-28 20:13:45 +0000367 /* Store the current IA into guest_IP_AT_SYSCALL. libvex_ir.h says so. */
florian428dfdd2012-03-27 03:09:49 +0000368 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_IP_AT_SYSCALL),
369 mkU64(guest_IA_curr_instr)));
sewardj2019a972011-03-07 16:04:07 +0000370
florian8844a632012-04-13 04:04:06 +0000371 put_IA(mkaddr_expr(guest_IA_next_instr));
372
sewardj2019a972011-03-07 16:04:07 +0000373 /* It's important that all ArchRegs carry their up-to-date value
374 at this point. So we declare an end-of-block here, which
375 forces any TempRegs caching ArchRegs to be flushed. */
florian8844a632012-04-13 04:04:06 +0000376 dis_res->whatNext = Dis_StopHere;
377 dis_res->jk_StopHere = Ijk_Sys_syscall;
sewardj2019a972011-03-07 16:04:07 +0000378}
379
florian6820ba52012-07-26 02:01:50 +0000380/* A side exit that branches back to the current insn if CONDITION is
381 true. Does not set DisResult. */
382static void
383iterate_if(IRExpr *condition)
384{
385 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
386
387 stmt(IRStmt_Exit(condition, Ijk_Boring, IRConst_U64(guest_IA_curr_instr),
388 S390X_GUEST_OFFSET(guest_IA)));
389}
390
391/* A side exit that branches back to the current insn.
392 Does not set DisResult. */
393static __inline__ void
394iterate(void)
395{
396 iterate_if(IRExpr_Const(IRConst_U1(True)));
397}
398
399/* A side exit that branches back to the insn immediately following the
400 current insn if CONDITION is true. Does not set DisResult. */
401static void
402next_insn_if(IRExpr *condition)
403{
404 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
405
406 stmt(IRStmt_Exit(condition, Ijk_Boring, IRConst_U64(guest_IA_next_instr),
407 S390X_GUEST_OFFSET(guest_IA)));
408}
409
410/* Convenience function to restart the current insn */
411static void
412restart_if(IRExpr *condition)
413{
414 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
415
416 stmt(IRStmt_Exit(condition, Ijk_TInval, IRConst_U64(guest_IA_curr_instr),
417 S390X_GUEST_OFFSET(guest_IA)));
418}
419
420/* Convenience function to yield to thread scheduler */
421static void
422yield_if(IRExpr *condition)
423{
424 stmt(IRStmt_Exit(condition, Ijk_Yield, IRConst_U64(guest_IA_next_instr),
425 S390X_GUEST_OFFSET(guest_IA)));
426}
427
sewardj2019a972011-03-07 16:04:07 +0000428/* Encode the s390 rounding mode as it appears in the m3/m4 fields of certain
429 instructions to VEX's IRRoundingMode. */
430static IRRoundingMode
431encode_rounding_mode(UChar mode)
432{
433 switch (mode) {
434 case S390_ROUND_NEAREST_EVEN: return Irrm_NEAREST;
435 case S390_ROUND_ZERO: return Irrm_ZERO;
436 case S390_ROUND_POSINF: return Irrm_PosINF;
437 case S390_ROUND_NEGINF: return Irrm_NegINF;
438 }
439 vpanic("encode_rounding_mode");
440}
441
442static __inline__ IRExpr *get_fpr_dw0(UInt);
443static __inline__ void put_fpr_dw0(UInt, IRExpr *);
444
445/* Read a floating point register pair and combine their contents into a
446 128-bit value */
447static IRExpr *
448get_fpr_pair(UInt archreg)
449{
450 IRExpr *high = get_fpr_dw0(archreg);
451 IRExpr *low = get_fpr_dw0(archreg + 2);
452
453 return binop(Iop_F64HLtoF128, high, low);
454}
455
456/* Write a 128-bit floating point value into a register pair. */
457static void
458put_fpr_pair(UInt archreg, IRExpr *expr)
459{
460 IRExpr *high = unop(Iop_F128HItoF64, expr);
461 IRExpr *low = unop(Iop_F128LOtoF64, expr);
462
463 put_fpr_dw0(archreg, high);
464 put_fpr_dw0(archreg + 2, low);
465}
466
467
sewardj2019a972011-03-07 16:04:07 +0000468/*------------------------------------------------------------*/
469/*--- Build the flags thunk. ---*/
470/*------------------------------------------------------------*/
471
472/* Completely fill the flags thunk. We're always filling all fields.
473 Apparently, that is better for redundant PUT elimination. */
474static void
475s390_cc_thunk_fill(IRExpr *op, IRExpr *dep1, IRExpr *dep2, IRExpr *ndep)
476{
477 UInt op_off, dep1_off, dep2_off, ndep_off;
478
florian428dfdd2012-03-27 03:09:49 +0000479 op_off = S390X_GUEST_OFFSET(guest_CC_OP);
480 dep1_off = S390X_GUEST_OFFSET(guest_CC_DEP1);
481 dep2_off = S390X_GUEST_OFFSET(guest_CC_DEP2);
482 ndep_off = S390X_GUEST_OFFSET(guest_CC_NDEP);
sewardj2019a972011-03-07 16:04:07 +0000483
484 stmt(IRStmt_Put(op_off, op));
485 stmt(IRStmt_Put(dep1_off, dep1));
486 stmt(IRStmt_Put(dep2_off, dep2));
487 stmt(IRStmt_Put(ndep_off, ndep));
488}
489
490
491/* Create an expression for V and widen the result to 64 bit. */
492static IRExpr *
493s390_cc_widen(IRTemp v, Bool sign_extend)
494{
495 IRExpr *expr;
496
497 expr = mkexpr(v);
498
499 switch (typeOfIRTemp(irsb->tyenv, v)) {
500 case Ity_I64:
501 break;
502 case Ity_I32:
503 expr = unop(sign_extend ? Iop_32Sto64 : Iop_32Uto64, expr);
504 break;
505 case Ity_I16:
506 expr = unop(sign_extend ? Iop_16Sto64 : Iop_16Uto64, expr);
507 break;
508 case Ity_I8:
509 expr = unop(sign_extend ? Iop_8Sto64 : Iop_8Uto64, expr);
510 break;
511 default:
512 vpanic("s390_cc_widen");
513 }
514
515 return expr;
516}
517
518static void
519s390_cc_thunk_put1(UInt opc, IRTemp d1, Bool sign_extend)
520{
521 IRExpr *op, *dep1, *dep2, *ndep;
522
523 op = mkU64(opc);
524 dep1 = s390_cc_widen(d1, sign_extend);
525 dep2 = mkU64(0);
526 ndep = mkU64(0);
527
528 s390_cc_thunk_fill(op, dep1, dep2, ndep);
529}
530
531
532static void
533s390_cc_thunk_put2(UInt opc, IRTemp d1, IRTemp d2, Bool sign_extend)
534{
535 IRExpr *op, *dep1, *dep2, *ndep;
536
537 op = mkU64(opc);
538 dep1 = s390_cc_widen(d1, sign_extend);
539 dep2 = s390_cc_widen(d2, sign_extend);
540 ndep = mkU64(0);
541
542 s390_cc_thunk_fill(op, dep1, dep2, ndep);
543}
544
545
546/* memcheck believes that the NDEP field in the flags thunk is always
547 defined. But for some flag computations (e.g. add with carry) that is
548 just not true. We therefore need to convey to memcheck that the value
549 of the ndep field does matter and therefore we make the DEP2 field
550 depend on it:
551
552 DEP2 = original_DEP2 ^ NDEP
553
554 In s390_calculate_cc we exploit that (a^b)^b == a
555 I.e. we xor the DEP2 value with the NDEP value to recover the
556 original_DEP2 value. */
557static void
558s390_cc_thunk_put3(UInt opc, IRTemp d1, IRTemp d2, IRTemp nd, Bool sign_extend)
559{
560 IRExpr *op, *dep1, *dep2, *ndep, *dep2x;
561
562 op = mkU64(opc);
563 dep1 = s390_cc_widen(d1, sign_extend);
564 dep2 = s390_cc_widen(d2, sign_extend);
565 ndep = s390_cc_widen(nd, sign_extend);
566
567 dep2x = binop(Iop_Xor64, dep2, ndep);
568
569 s390_cc_thunk_fill(op, dep1, dep2x, ndep);
570}
571
572
573/* Write one floating point value into the flags thunk */
574static void
575s390_cc_thunk_put1f(UInt opc, IRTemp d1)
576{
577 IRExpr *op, *dep1, *dep2, *ndep;
578
579 op = mkU64(opc);
580 dep1 = mkexpr(d1);
581 dep2 = mkU64(0);
582 ndep = mkU64(0);
583
584 s390_cc_thunk_fill(op, dep1, dep2, ndep);
585}
586
587
588/* Write a floating point value and an integer into the flags thunk. The
589 integer value is zero-extended first. */
590static void
591s390_cc_thunk_putFZ(UInt opc, IRTemp d1, IRTemp d2)
592{
593 IRExpr *op, *dep1, *dep2, *ndep;
594
595 op = mkU64(opc);
596 dep1 = mkexpr(d1);
597 dep2 = s390_cc_widen(d2, False);
598 ndep = mkU64(0);
599
600 s390_cc_thunk_fill(op, dep1, dep2, ndep);
601}
602
603
604/* Write a 128-bit floating point value into the flags thunk. This is
605 done by splitting the value into two 64-bits values. */
606static void
607s390_cc_thunk_put1f128(UInt opc, IRTemp d1)
608{
609 IRExpr *op, *hi, *lo, *ndep;
610
611 op = mkU64(opc);
612 hi = unop(Iop_F128HItoF64, mkexpr(d1));
613 lo = unop(Iop_F128LOtoF64, mkexpr(d1));
614 ndep = mkU64(0);
615
616 s390_cc_thunk_fill(op, hi, lo, ndep);
617}
618
619
620/* Write a 128-bit floating point value and an integer into the flags thunk.
621 The integer value is zero-extended first. */
622static void
623s390_cc_thunk_put1f128Z(UInt opc, IRTemp d1, IRTemp nd)
624{
625 IRExpr *op, *hi, *lo, *lox, *ndep;
626
627 op = mkU64(opc);
628 hi = unop(Iop_F128HItoF64, mkexpr(d1));
629 lo = unop(Iop_ReinterpF64asI64, unop(Iop_F128LOtoF64, mkexpr(d1)));
630 ndep = s390_cc_widen(nd, False);
631
632 lox = binop(Iop_Xor64, lo, ndep); /* convey dependency */
633
634 s390_cc_thunk_fill(op, hi, lox, ndep);
635}
636
637
638static void
639s390_cc_set(UInt val)
640{
641 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
642 mkU64(val), mkU64(0), mkU64(0));
643}
644
645/* Build IR to calculate the condition code from flags thunk.
646 Returns an expression of type Ity_I32 */
647static IRExpr *
648s390_call_calculate_cc(void)
649{
650 IRExpr **args, *call, *op, *dep1, *dep2, *ndep;
651
florian428dfdd2012-03-27 03:09:49 +0000652 op = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_OP), Ity_I64);
653 dep1 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP1), Ity_I64);
654 dep2 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP2), Ity_I64);
655 ndep = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_NDEP), Ity_I64);
sewardj2019a972011-03-07 16:04:07 +0000656
657 args = mkIRExprVec_4(op, dep1, dep2, ndep);
658 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
659 "s390_calculate_cc", &s390_calculate_cc, args);
660
661 /* Exclude OP and NDEP from definedness checking. We're only
662 interested in DEP1 and DEP2. */
663 call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<3);
664
665 return call;
666}
667
668/* Build IR to calculate the internal condition code for a "compare and branch"
669 insn. Returns an expression of type Ity_I32 */
670static IRExpr *
florianff9613f2012-05-12 15:26:44 +0000671s390_call_calculate_icc(UInt m, UInt opc, IRTemp op1, IRTemp op2)
sewardj2019a972011-03-07 16:04:07 +0000672{
florianff9613f2012-05-12 15:26:44 +0000673 IRExpr **args, *call, *op, *dep1, *dep2, *mask;
sewardj2019a972011-03-07 16:04:07 +0000674
florianff9613f2012-05-12 15:26:44 +0000675 switch (opc) {
676 case S390_CC_OP_SIGNED_COMPARE:
677 dep1 = s390_cc_widen(op1, True);
678 dep2 = s390_cc_widen(op2, True);
679 break;
680
681 case S390_CC_OP_UNSIGNED_COMPARE:
682 dep1 = s390_cc_widen(op1, False);
683 dep2 = s390_cc_widen(op2, False);
684 break;
685
686 default:
687 vpanic("s390_call_calculate_icc");
688 }
689
690 mask = mkU64(m);
sewardj2019a972011-03-07 16:04:07 +0000691 op = mkU64(opc);
sewardj2019a972011-03-07 16:04:07 +0000692
florianff9613f2012-05-12 15:26:44 +0000693 args = mkIRExprVec_5(mask, op, dep1, dep2, mkU64(0) /* unused */);
sewardj2019a972011-03-07 16:04:07 +0000694 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
florianff9613f2012-05-12 15:26:44 +0000695 "s390_calculate_cond", &s390_calculate_cond, args);
sewardj2019a972011-03-07 16:04:07 +0000696
florianff9613f2012-05-12 15:26:44 +0000697 /* Exclude the requested condition, OP and NDEP from definedness
698 checking. We're only interested in DEP1 and DEP2. */
699 call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<1) | (1<<4);
sewardj2019a972011-03-07 16:04:07 +0000700
701 return call;
702}
703
704/* Build IR to calculate the condition code from flags thunk.
705 Returns an expression of type Ity_I32 */
706static IRExpr *
707s390_call_calculate_cond(UInt m)
708{
709 IRExpr **args, *call, *op, *dep1, *dep2, *ndep, *mask;
710
711 mask = mkU64(m);
florian428dfdd2012-03-27 03:09:49 +0000712 op = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_OP), Ity_I64);
713 dep1 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP1), Ity_I64);
714 dep2 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP2), Ity_I64);
715 ndep = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_NDEP), Ity_I64);
sewardj2019a972011-03-07 16:04:07 +0000716
717 args = mkIRExprVec_5(mask, op, dep1, dep2, ndep);
718 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
719 "s390_calculate_cond", &s390_calculate_cond, args);
720
721 /* Exclude the requested condition, OP and NDEP from definedness
722 checking. We're only interested in DEP1 and DEP2. */
723 call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<1) | (1<<4);
724
725 return call;
726}
727
728#define s390_cc_thunk_putZ(op,dep1) s390_cc_thunk_put1(op,dep1,False)
729#define s390_cc_thunk_putS(op,dep1) s390_cc_thunk_put1(op,dep1,True)
730#define s390_cc_thunk_putF(op,dep1) s390_cc_thunk_put1f(op,dep1)
731#define s390_cc_thunk_putZZ(op,dep1,dep2) s390_cc_thunk_put2(op,dep1,dep2,False)
732#define s390_cc_thunk_putSS(op,dep1,dep2) s390_cc_thunk_put2(op,dep1,dep2,True)
733#define s390_cc_thunk_putFF(op,dep1,dep2) s390_cc_thunk_put2f(op,dep1,dep2)
734#define s390_cc_thunk_putZZZ(op,dep1,dep2,ndep) \
735 s390_cc_thunk_put3(op,dep1,dep2,ndep,False)
736#define s390_cc_thunk_putSSS(op,dep1,dep2,ndep) \
737 s390_cc_thunk_put3(op,dep1,dep2,ndep,True)
sewardj2019a972011-03-07 16:04:07 +0000738
739
sewardj2019a972011-03-07 16:04:07 +0000740
741
742/*------------------------------------------------------------*/
743/*--- Guest register access ---*/
744/*------------------------------------------------------------*/
745
746
747/*------------------------------------------------------------*/
748/*--- ar registers ---*/
749/*------------------------------------------------------------*/
750
751/* Return the guest state offset of a ar register. */
752static UInt
753ar_offset(UInt archreg)
754{
755 static const UInt offset[16] = {
floriane88b3c92011-07-05 02:48:39 +0000756 S390X_GUEST_OFFSET(guest_a0),
757 S390X_GUEST_OFFSET(guest_a1),
758 S390X_GUEST_OFFSET(guest_a2),
759 S390X_GUEST_OFFSET(guest_a3),
760 S390X_GUEST_OFFSET(guest_a4),
761 S390X_GUEST_OFFSET(guest_a5),
762 S390X_GUEST_OFFSET(guest_a6),
763 S390X_GUEST_OFFSET(guest_a7),
764 S390X_GUEST_OFFSET(guest_a8),
765 S390X_GUEST_OFFSET(guest_a9),
766 S390X_GUEST_OFFSET(guest_a10),
767 S390X_GUEST_OFFSET(guest_a11),
768 S390X_GUEST_OFFSET(guest_a12),
769 S390X_GUEST_OFFSET(guest_a13),
770 S390X_GUEST_OFFSET(guest_a14),
771 S390X_GUEST_OFFSET(guest_a15),
sewardj2019a972011-03-07 16:04:07 +0000772 };
773
774 vassert(archreg < 16);
775
776 return offset[archreg];
777}
778
779
780/* Return the guest state offset of word #0 of a ar register. */
781static __inline__ UInt
782ar_w0_offset(UInt archreg)
783{
784 return ar_offset(archreg) + 0;
785}
786
787/* Write word #0 of a ar to the guest state. */
788static __inline__ void
789put_ar_w0(UInt archreg, IRExpr *expr)
790{
791 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
792
793 stmt(IRStmt_Put(ar_w0_offset(archreg), expr));
794}
795
796/* Read word #0 of a ar register. */
797static __inline__ IRExpr *
798get_ar_w0(UInt archreg)
799{
800 return IRExpr_Get(ar_w0_offset(archreg), Ity_I32);
801}
802
803
804/*------------------------------------------------------------*/
805/*--- fpr registers ---*/
806/*------------------------------------------------------------*/
807
808/* Return the guest state offset of a fpr register. */
809static UInt
810fpr_offset(UInt archreg)
811{
812 static const UInt offset[16] = {
floriane88b3c92011-07-05 02:48:39 +0000813 S390X_GUEST_OFFSET(guest_f0),
814 S390X_GUEST_OFFSET(guest_f1),
815 S390X_GUEST_OFFSET(guest_f2),
816 S390X_GUEST_OFFSET(guest_f3),
817 S390X_GUEST_OFFSET(guest_f4),
818 S390X_GUEST_OFFSET(guest_f5),
819 S390X_GUEST_OFFSET(guest_f6),
820 S390X_GUEST_OFFSET(guest_f7),
821 S390X_GUEST_OFFSET(guest_f8),
822 S390X_GUEST_OFFSET(guest_f9),
823 S390X_GUEST_OFFSET(guest_f10),
824 S390X_GUEST_OFFSET(guest_f11),
825 S390X_GUEST_OFFSET(guest_f12),
826 S390X_GUEST_OFFSET(guest_f13),
827 S390X_GUEST_OFFSET(guest_f14),
828 S390X_GUEST_OFFSET(guest_f15),
sewardj2019a972011-03-07 16:04:07 +0000829 };
830
831 vassert(archreg < 16);
832
833 return offset[archreg];
834}
835
836
837/* Return the guest state offset of word #0 of a fpr register. */
838static __inline__ UInt
839fpr_w0_offset(UInt archreg)
840{
841 return fpr_offset(archreg) + 0;
842}
843
844/* Write word #0 of a fpr to the guest state. */
845static __inline__ void
846put_fpr_w0(UInt archreg, IRExpr *expr)
847{
848 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_F32);
849
850 stmt(IRStmt_Put(fpr_w0_offset(archreg), expr));
851}
852
853/* Read word #0 of a fpr register. */
854static __inline__ IRExpr *
855get_fpr_w0(UInt archreg)
856{
857 return IRExpr_Get(fpr_w0_offset(archreg), Ity_F32);
858}
859
860/* Return the guest state offset of double word #0 of a fpr register. */
861static __inline__ UInt
862fpr_dw0_offset(UInt archreg)
863{
864 return fpr_offset(archreg) + 0;
865}
866
867/* Write double word #0 of a fpr to the guest state. */
868static __inline__ void
869put_fpr_dw0(UInt archreg, IRExpr *expr)
870{
871 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_F64);
872
873 stmt(IRStmt_Put(fpr_dw0_offset(archreg), expr));
874}
875
876/* Read double word #0 of a fpr register. */
877static __inline__ IRExpr *
878get_fpr_dw0(UInt archreg)
879{
880 return IRExpr_Get(fpr_dw0_offset(archreg), Ity_F64);
881}
882
883
884/*------------------------------------------------------------*/
885/*--- gpr registers ---*/
886/*------------------------------------------------------------*/
887
888/* Return the guest state offset of a gpr register. */
889static UInt
890gpr_offset(UInt archreg)
891{
892 static const UInt offset[16] = {
floriane88b3c92011-07-05 02:48:39 +0000893 S390X_GUEST_OFFSET(guest_r0),
894 S390X_GUEST_OFFSET(guest_r1),
895 S390X_GUEST_OFFSET(guest_r2),
896 S390X_GUEST_OFFSET(guest_r3),
897 S390X_GUEST_OFFSET(guest_r4),
898 S390X_GUEST_OFFSET(guest_r5),
899 S390X_GUEST_OFFSET(guest_r6),
900 S390X_GUEST_OFFSET(guest_r7),
901 S390X_GUEST_OFFSET(guest_r8),
902 S390X_GUEST_OFFSET(guest_r9),
903 S390X_GUEST_OFFSET(guest_r10),
904 S390X_GUEST_OFFSET(guest_r11),
905 S390X_GUEST_OFFSET(guest_r12),
906 S390X_GUEST_OFFSET(guest_r13),
907 S390X_GUEST_OFFSET(guest_r14),
908 S390X_GUEST_OFFSET(guest_r15),
sewardj2019a972011-03-07 16:04:07 +0000909 };
910
911 vassert(archreg < 16);
912
913 return offset[archreg];
914}
915
916
917/* Return the guest state offset of word #0 of a gpr register. */
918static __inline__ UInt
919gpr_w0_offset(UInt archreg)
920{
921 return gpr_offset(archreg) + 0;
922}
923
924/* Write word #0 of a gpr to the guest state. */
925static __inline__ void
926put_gpr_w0(UInt archreg, IRExpr *expr)
927{
928 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
929
930 stmt(IRStmt_Put(gpr_w0_offset(archreg), expr));
931}
932
933/* Read word #0 of a gpr register. */
934static __inline__ IRExpr *
935get_gpr_w0(UInt archreg)
936{
937 return IRExpr_Get(gpr_w0_offset(archreg), Ity_I32);
938}
939
940/* Return the guest state offset of double word #0 of a gpr register. */
941static __inline__ UInt
942gpr_dw0_offset(UInt archreg)
943{
944 return gpr_offset(archreg) + 0;
945}
946
947/* Write double word #0 of a gpr to the guest state. */
948static __inline__ void
949put_gpr_dw0(UInt archreg, IRExpr *expr)
950{
951 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I64);
952
953 stmt(IRStmt_Put(gpr_dw0_offset(archreg), expr));
954}
955
956/* Read double word #0 of a gpr register. */
957static __inline__ IRExpr *
958get_gpr_dw0(UInt archreg)
959{
960 return IRExpr_Get(gpr_dw0_offset(archreg), Ity_I64);
961}
962
963/* Return the guest state offset of half word #1 of a gpr register. */
964static __inline__ UInt
965gpr_hw1_offset(UInt archreg)
966{
967 return gpr_offset(archreg) + 2;
968}
969
970/* Write half word #1 of a gpr to the guest state. */
971static __inline__ void
972put_gpr_hw1(UInt archreg, IRExpr *expr)
973{
974 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
975
976 stmt(IRStmt_Put(gpr_hw1_offset(archreg), expr));
977}
978
979/* Read half word #1 of a gpr register. */
980static __inline__ IRExpr *
981get_gpr_hw1(UInt archreg)
982{
983 return IRExpr_Get(gpr_hw1_offset(archreg), Ity_I16);
984}
985
986/* Return the guest state offset of byte #6 of a gpr register. */
987static __inline__ UInt
988gpr_b6_offset(UInt archreg)
989{
990 return gpr_offset(archreg) + 6;
991}
992
993/* Write byte #6 of a gpr to the guest state. */
994static __inline__ void
995put_gpr_b6(UInt archreg, IRExpr *expr)
996{
997 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
998
999 stmt(IRStmt_Put(gpr_b6_offset(archreg), expr));
1000}
1001
1002/* Read byte #6 of a gpr register. */
1003static __inline__ IRExpr *
1004get_gpr_b6(UInt archreg)
1005{
1006 return IRExpr_Get(gpr_b6_offset(archreg), Ity_I8);
1007}
1008
1009/* Return the guest state offset of byte #3 of a gpr register. */
1010static __inline__ UInt
1011gpr_b3_offset(UInt archreg)
1012{
1013 return gpr_offset(archreg) + 3;
1014}
1015
1016/* Write byte #3 of a gpr to the guest state. */
1017static __inline__ void
1018put_gpr_b3(UInt archreg, IRExpr *expr)
1019{
1020 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1021
1022 stmt(IRStmt_Put(gpr_b3_offset(archreg), expr));
1023}
1024
1025/* Read byte #3 of a gpr register. */
1026static __inline__ IRExpr *
1027get_gpr_b3(UInt archreg)
1028{
1029 return IRExpr_Get(gpr_b3_offset(archreg), Ity_I8);
1030}
1031
1032/* Return the guest state offset of byte #0 of a gpr register. */
1033static __inline__ UInt
1034gpr_b0_offset(UInt archreg)
1035{
1036 return gpr_offset(archreg) + 0;
1037}
1038
1039/* Write byte #0 of a gpr to the guest state. */
1040static __inline__ void
1041put_gpr_b0(UInt archreg, IRExpr *expr)
1042{
1043 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1044
1045 stmt(IRStmt_Put(gpr_b0_offset(archreg), expr));
1046}
1047
1048/* Read byte #0 of a gpr register. */
1049static __inline__ IRExpr *
1050get_gpr_b0(UInt archreg)
1051{
1052 return IRExpr_Get(gpr_b0_offset(archreg), Ity_I8);
1053}
1054
1055/* Return the guest state offset of word #1 of a gpr register. */
1056static __inline__ UInt
1057gpr_w1_offset(UInt archreg)
1058{
1059 return gpr_offset(archreg) + 4;
1060}
1061
1062/* Write word #1 of a gpr to the guest state. */
1063static __inline__ void
1064put_gpr_w1(UInt archreg, IRExpr *expr)
1065{
1066 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1067
1068 stmt(IRStmt_Put(gpr_w1_offset(archreg), expr));
1069}
1070
1071/* Read word #1 of a gpr register. */
1072static __inline__ IRExpr *
1073get_gpr_w1(UInt archreg)
1074{
1075 return IRExpr_Get(gpr_w1_offset(archreg), Ity_I32);
1076}
1077
1078/* Return the guest state offset of half word #3 of a gpr register. */
1079static __inline__ UInt
1080gpr_hw3_offset(UInt archreg)
1081{
1082 return gpr_offset(archreg) + 6;
1083}
1084
1085/* Write half word #3 of a gpr to the guest state. */
1086static __inline__ void
1087put_gpr_hw3(UInt archreg, IRExpr *expr)
1088{
1089 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1090
1091 stmt(IRStmt_Put(gpr_hw3_offset(archreg), expr));
1092}
1093
1094/* Read half word #3 of a gpr register. */
1095static __inline__ IRExpr *
1096get_gpr_hw3(UInt archreg)
1097{
1098 return IRExpr_Get(gpr_hw3_offset(archreg), Ity_I16);
1099}
1100
1101/* Return the guest state offset of byte #7 of a gpr register. */
1102static __inline__ UInt
1103gpr_b7_offset(UInt archreg)
1104{
1105 return gpr_offset(archreg) + 7;
1106}
1107
1108/* Write byte #7 of a gpr to the guest state. */
1109static __inline__ void
1110put_gpr_b7(UInt archreg, IRExpr *expr)
1111{
1112 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1113
1114 stmt(IRStmt_Put(gpr_b7_offset(archreg), expr));
1115}
1116
1117/* Read byte #7 of a gpr register. */
1118static __inline__ IRExpr *
1119get_gpr_b7(UInt archreg)
1120{
1121 return IRExpr_Get(gpr_b7_offset(archreg), Ity_I8);
1122}
1123
1124/* Return the guest state offset of half word #0 of a gpr register. */
1125static __inline__ UInt
1126gpr_hw0_offset(UInt archreg)
1127{
1128 return gpr_offset(archreg) + 0;
1129}
1130
1131/* Write half word #0 of a gpr to the guest state. */
1132static __inline__ void
1133put_gpr_hw0(UInt archreg, IRExpr *expr)
1134{
1135 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1136
1137 stmt(IRStmt_Put(gpr_hw0_offset(archreg), expr));
1138}
1139
1140/* Read half word #0 of a gpr register. */
1141static __inline__ IRExpr *
1142get_gpr_hw0(UInt archreg)
1143{
1144 return IRExpr_Get(gpr_hw0_offset(archreg), Ity_I16);
1145}
1146
1147/* Return the guest state offset of byte #4 of a gpr register. */
1148static __inline__ UInt
1149gpr_b4_offset(UInt archreg)
1150{
1151 return gpr_offset(archreg) + 4;
1152}
1153
1154/* Write byte #4 of a gpr to the guest state. */
1155static __inline__ void
1156put_gpr_b4(UInt archreg, IRExpr *expr)
1157{
1158 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1159
1160 stmt(IRStmt_Put(gpr_b4_offset(archreg), expr));
1161}
1162
1163/* Read byte #4 of a gpr register. */
1164static __inline__ IRExpr *
1165get_gpr_b4(UInt archreg)
1166{
1167 return IRExpr_Get(gpr_b4_offset(archreg), Ity_I8);
1168}
1169
1170/* Return the guest state offset of byte #1 of a gpr register. */
1171static __inline__ UInt
1172gpr_b1_offset(UInt archreg)
1173{
1174 return gpr_offset(archreg) + 1;
1175}
1176
1177/* Write byte #1 of a gpr to the guest state. */
1178static __inline__ void
1179put_gpr_b1(UInt archreg, IRExpr *expr)
1180{
1181 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1182
1183 stmt(IRStmt_Put(gpr_b1_offset(archreg), expr));
1184}
1185
1186/* Read byte #1 of a gpr register. */
1187static __inline__ IRExpr *
1188get_gpr_b1(UInt archreg)
1189{
1190 return IRExpr_Get(gpr_b1_offset(archreg), Ity_I8);
1191}
1192
1193/* Return the guest state offset of half word #2 of a gpr register. */
1194static __inline__ UInt
1195gpr_hw2_offset(UInt archreg)
1196{
1197 return gpr_offset(archreg) + 4;
1198}
1199
1200/* Write half word #2 of a gpr to the guest state. */
1201static __inline__ void
1202put_gpr_hw2(UInt archreg, IRExpr *expr)
1203{
1204 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1205
1206 stmt(IRStmt_Put(gpr_hw2_offset(archreg), expr));
1207}
1208
1209/* Read half word #2 of a gpr register. */
1210static __inline__ IRExpr *
1211get_gpr_hw2(UInt archreg)
1212{
1213 return IRExpr_Get(gpr_hw2_offset(archreg), Ity_I16);
1214}
1215
1216/* Return the guest state offset of byte #5 of a gpr register. */
1217static __inline__ UInt
1218gpr_b5_offset(UInt archreg)
1219{
1220 return gpr_offset(archreg) + 5;
1221}
1222
1223/* Write byte #5 of a gpr to the guest state. */
1224static __inline__ void
1225put_gpr_b5(UInt archreg, IRExpr *expr)
1226{
1227 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1228
1229 stmt(IRStmt_Put(gpr_b5_offset(archreg), expr));
1230}
1231
1232/* Read byte #5 of a gpr register. */
1233static __inline__ IRExpr *
1234get_gpr_b5(UInt archreg)
1235{
1236 return IRExpr_Get(gpr_b5_offset(archreg), Ity_I8);
1237}
1238
1239/* Return the guest state offset of byte #2 of a gpr register. */
1240static __inline__ UInt
1241gpr_b2_offset(UInt archreg)
1242{
1243 return gpr_offset(archreg) + 2;
1244}
1245
1246/* Write byte #2 of a gpr to the guest state. */
1247static __inline__ void
1248put_gpr_b2(UInt archreg, IRExpr *expr)
1249{
1250 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1251
1252 stmt(IRStmt_Put(gpr_b2_offset(archreg), expr));
1253}
1254
1255/* Read byte #2 of a gpr register. */
1256static __inline__ IRExpr *
1257get_gpr_b2(UInt archreg)
1258{
1259 return IRExpr_Get(gpr_b2_offset(archreg), Ity_I8);
1260}
1261
1262/* Return the guest state offset of the counter register. */
1263static UInt
1264counter_offset(void)
1265{
floriane88b3c92011-07-05 02:48:39 +00001266 return S390X_GUEST_OFFSET(guest_counter);
sewardj2019a972011-03-07 16:04:07 +00001267}
1268
1269/* Return the guest state offset of double word #0 of the counter register. */
1270static __inline__ UInt
1271counter_dw0_offset(void)
1272{
1273 return counter_offset() + 0;
1274}
1275
1276/* Write double word #0 of the counter to the guest state. */
1277static __inline__ void
1278put_counter_dw0(IRExpr *expr)
1279{
1280 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I64);
1281
1282 stmt(IRStmt_Put(counter_dw0_offset(), expr));
1283}
1284
1285/* Read double word #0 of the counter register. */
1286static __inline__ IRExpr *
1287get_counter_dw0(void)
1288{
1289 return IRExpr_Get(counter_dw0_offset(), Ity_I64);
1290}
1291
1292/* Return the guest state offset of word #0 of the counter register. */
1293static __inline__ UInt
1294counter_w0_offset(void)
1295{
1296 return counter_offset() + 0;
1297}
1298
1299/* Return the guest state offset of word #1 of the counter register. */
1300static __inline__ UInt
1301counter_w1_offset(void)
1302{
1303 return counter_offset() + 4;
1304}
1305
1306/* Write word #0 of the counter to the guest state. */
1307static __inline__ void
1308put_counter_w0(IRExpr *expr)
1309{
1310 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1311
1312 stmt(IRStmt_Put(counter_w0_offset(), expr));
1313}
1314
1315/* Read word #0 of the counter register. */
1316static __inline__ IRExpr *
1317get_counter_w0(void)
1318{
1319 return IRExpr_Get(counter_w0_offset(), Ity_I32);
1320}
1321
1322/* Write word #1 of the counter to the guest state. */
1323static __inline__ void
1324put_counter_w1(IRExpr *expr)
1325{
1326 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1327
1328 stmt(IRStmt_Put(counter_w1_offset(), expr));
1329}
1330
1331/* Read word #1 of the counter register. */
1332static __inline__ IRExpr *
1333get_counter_w1(void)
1334{
1335 return IRExpr_Get(counter_w1_offset(), Ity_I32);
1336}
1337
1338/* Return the guest state offset of the fpc register. */
1339static UInt
1340fpc_offset(void)
1341{
floriane88b3c92011-07-05 02:48:39 +00001342 return S390X_GUEST_OFFSET(guest_fpc);
sewardj2019a972011-03-07 16:04:07 +00001343}
1344
1345/* Return the guest state offset of word #0 of the fpc register. */
1346static __inline__ UInt
1347fpc_w0_offset(void)
1348{
1349 return fpc_offset() + 0;
1350}
1351
1352/* Write word #0 of the fpc to the guest state. */
1353static __inline__ void
1354put_fpc_w0(IRExpr *expr)
1355{
1356 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1357
1358 stmt(IRStmt_Put(fpc_w0_offset(), expr));
1359}
1360
1361/* Read word #0 of the fpc register. */
1362static __inline__ IRExpr *
1363get_fpc_w0(void)
1364{
1365 return IRExpr_Get(fpc_w0_offset(), Ity_I32);
1366}
1367
1368
1369/*------------------------------------------------------------*/
1370/*--- Build IR for formats ---*/
1371/*------------------------------------------------------------*/
1372static void
1373s390_format_I(HChar *(*irgen)(UChar i),
1374 UChar i)
1375{
1376 HChar *mnm = irgen(i);
1377
sewardj7ee97522011-05-09 21:45:04 +00001378 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001379 s390_disasm(ENC2(MNM, UINT), mnm, i);
1380}
1381
1382static void
1383s390_format_RI(HChar *(*irgen)(UChar r1, UShort i2),
1384 UChar r1, UShort i2)
1385{
1386 irgen(r1, i2);
1387}
1388
1389static void
1390s390_format_RI_RU(HChar *(*irgen)(UChar r1, UShort i2),
1391 UChar r1, UShort i2)
1392{
1393 HChar *mnm = irgen(r1, i2);
1394
sewardj7ee97522011-05-09 21:45:04 +00001395 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001396 s390_disasm(ENC3(MNM, GPR, UINT), mnm, r1, i2);
1397}
1398
1399static void
1400s390_format_RI_RI(HChar *(*irgen)(UChar r1, UShort i2),
1401 UChar r1, UShort i2)
1402{
1403 HChar *mnm = irgen(r1, i2);
1404
sewardj7ee97522011-05-09 21:45:04 +00001405 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001406 s390_disasm(ENC3(MNM, GPR, INT), mnm, r1, (Int)(Short)i2);
1407}
1408
1409static void
1410s390_format_RI_RP(HChar *(*irgen)(UChar r1, UShort i2),
1411 UChar r1, UShort i2)
1412{
1413 HChar *mnm = irgen(r1, i2);
1414
sewardj7ee97522011-05-09 21:45:04 +00001415 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001416 s390_disasm(ENC3(MNM, GPR, PCREL), mnm, r1, (Int)(Short)i2);
1417}
1418
1419static void
1420s390_format_RIE_RRP(HChar *(*irgen)(UChar r1, UChar r3, UShort i2),
1421 UChar r1, UChar r3, UShort i2)
1422{
1423 HChar *mnm = irgen(r1, r3, i2);
1424
sewardj7ee97522011-05-09 21:45:04 +00001425 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001426 s390_disasm(ENC4(MNM, GPR, GPR, PCREL), mnm, r1, r3, (Int)(Short)i2);
1427}
1428
1429static void
1430s390_format_RIE_RRI0(HChar *(*irgen)(UChar r1, UChar r3, UShort i2),
1431 UChar r1, UChar r3, UShort i2)
1432{
1433 HChar *mnm = irgen(r1, r3, i2);
1434
sewardj7ee97522011-05-09 21:45:04 +00001435 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001436 s390_disasm(ENC4(MNM, GPR, GPR, INT), mnm, r1, r3, (Int)(Short)i2);
1437}
1438
1439static void
1440s390_format_RIE_RRUUU(HChar *(*irgen)(UChar r1, UChar r2, UChar i3, UChar i4,
1441 UChar i5),
1442 UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
1443{
1444 HChar *mnm = irgen(r1, r2, i3, i4, i5);
1445
sewardj7ee97522011-05-09 21:45:04 +00001446 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001447 s390_disasm(ENC6(MNM, GPR, GPR, UINT, UINT, UINT), mnm, r1, r2, i3, i4,
1448 i5);
1449}
1450
1451static void
1452s390_format_RIE_RRPU(HChar *(*irgen)(UChar r1, UChar r2, UShort i4, UChar m3),
1453 UChar r1, UChar r2, UShort i4, UChar m3)
1454{
1455 HChar *mnm = irgen(r1, r2, i4, m3);
1456
sewardj7ee97522011-05-09 21:45:04 +00001457 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001458 s390_disasm(ENC5(XMNM, GPR, GPR, CABM, PCREL), S390_XMNM_CAB, mnm, m3, r1,
1459 r2, m3, (Int)(Short)i4);
1460}
1461
1462static void
1463s390_format_RIE_RUPU(HChar *(*irgen)(UChar r1, UChar m3, UShort i4, UChar i2),
1464 UChar r1, UChar m3, UShort i4, UChar i2)
1465{
1466 HChar *mnm = irgen(r1, m3, i4, i2);
1467
sewardj7ee97522011-05-09 21:45:04 +00001468 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001469 s390_disasm(ENC5(XMNM, GPR, UINT, CABM, PCREL), S390_XMNM_CAB, mnm, m3,
1470 r1, i2, m3, (Int)(Short)i4);
1471}
1472
1473static void
1474s390_format_RIE_RUPI(HChar *(*irgen)(UChar r1, UChar m3, UShort i4, UChar i2),
1475 UChar r1, UChar m3, UShort i4, UChar i2)
1476{
1477 HChar *mnm = irgen(r1, m3, i4, 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(ENC5(XMNM, GPR, INT, CABM, PCREL), S390_XMNM_CAB, mnm, m3, r1,
1481 (Int)(Char)i2, m3, (Int)(Short)i4);
1482}
1483
1484static void
1485s390_format_RIL(HChar *(*irgen)(UChar r1, UInt i2),
1486 UChar r1, UInt i2)
1487{
1488 irgen(r1, i2);
1489}
1490
1491static void
1492s390_format_RIL_RU(HChar *(*irgen)(UChar r1, UInt i2),
1493 UChar r1, UInt i2)
1494{
1495 HChar *mnm = irgen(r1, i2);
1496
sewardj7ee97522011-05-09 21:45:04 +00001497 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001498 s390_disasm(ENC3(MNM, GPR, UINT), mnm, r1, i2);
1499}
1500
1501static void
1502s390_format_RIL_RI(HChar *(*irgen)(UChar r1, UInt i2),
1503 UChar r1, UInt i2)
1504{
1505 HChar *mnm = irgen(r1, i2);
1506
sewardj7ee97522011-05-09 21:45:04 +00001507 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001508 s390_disasm(ENC3(MNM, GPR, INT), mnm, r1, i2);
1509}
1510
1511static void
1512s390_format_RIL_RP(HChar *(*irgen)(UChar r1, UInt i2),
1513 UChar r1, UInt i2)
1514{
1515 HChar *mnm = irgen(r1, i2);
1516
sewardj7ee97522011-05-09 21:45:04 +00001517 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001518 s390_disasm(ENC3(MNM, GPR, PCREL), mnm, r1, i2);
1519}
1520
1521static void
1522s390_format_RIL_UP(HChar *(*irgen)(void),
1523 UChar r1, UInt i2)
1524{
1525 HChar *mnm = irgen();
1526
sewardj7ee97522011-05-09 21:45:04 +00001527 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001528 s390_disasm(ENC3(MNM, UINT, PCREL), mnm, r1, i2);
1529}
1530
1531static void
1532s390_format_RIS_RURDI(HChar *(*irgen)(UChar r1, UChar m3, UChar i2,
1533 IRTemp op4addr),
1534 UChar r1, UChar m3, UChar b4, UShort d4, UChar i2)
1535{
1536 HChar *mnm;
1537 IRTemp op4addr = newTemp(Ity_I64);
1538
1539 assign(op4addr, binop(Iop_Add64, mkU64(d4), b4 != 0 ? get_gpr_dw0(b4) :
1540 mkU64(0)));
1541
1542 mnm = irgen(r1, m3, i2, op4addr);
1543
sewardj7ee97522011-05-09 21:45:04 +00001544 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001545 s390_disasm(ENC5(XMNM, GPR, INT, CABM, UDXB), S390_XMNM_CAB, mnm, m3, r1,
1546 (Int)(Char)i2, m3, d4, 0, b4);
1547}
1548
1549static void
1550s390_format_RIS_RURDU(HChar *(*irgen)(UChar r1, UChar m3, UChar i2,
1551 IRTemp op4addr),
1552 UChar r1, UChar m3, UChar b4, UShort d4, UChar i2)
1553{
1554 HChar *mnm;
1555 IRTemp op4addr = newTemp(Ity_I64);
1556
1557 assign(op4addr, binop(Iop_Add64, mkU64(d4), b4 != 0 ? get_gpr_dw0(b4) :
1558 mkU64(0)));
1559
1560 mnm = irgen(r1, m3, i2, op4addr);
1561
sewardj7ee97522011-05-09 21:45:04 +00001562 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001563 s390_disasm(ENC5(XMNM, GPR, UINT, CABM, UDXB), S390_XMNM_CAB, mnm, m3, r1,
1564 i2, m3, d4, 0, b4);
1565}
1566
1567static void
1568s390_format_RR(HChar *(*irgen)(UChar r1, UChar r2),
1569 UChar r1, UChar r2)
1570{
1571 irgen(r1, r2);
1572}
1573
1574static void
1575s390_format_RR_RR(HChar *(*irgen)(UChar r1, UChar r2),
1576 UChar r1, UChar r2)
1577{
1578 HChar *mnm = irgen(r1, r2);
1579
sewardj7ee97522011-05-09 21:45:04 +00001580 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001581 s390_disasm(ENC3(MNM, GPR, GPR), mnm, r1, r2);
1582}
1583
1584static void
1585s390_format_RR_FF(HChar *(*irgen)(UChar r1, UChar r2),
1586 UChar r1, UChar r2)
1587{
1588 HChar *mnm = irgen(r1, r2);
1589
sewardj7ee97522011-05-09 21:45:04 +00001590 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001591 s390_disasm(ENC3(MNM, FPR, FPR), mnm, r1, r2);
1592}
1593
1594static void
1595s390_format_RRE(HChar *(*irgen)(UChar r1, UChar r2),
1596 UChar r1, UChar r2)
1597{
1598 irgen(r1, r2);
1599}
1600
1601static void
1602s390_format_RRE_RR(HChar *(*irgen)(UChar r1, UChar r2),
1603 UChar r1, UChar r2)
1604{
1605 HChar *mnm = irgen(r1, r2);
1606
sewardj7ee97522011-05-09 21:45:04 +00001607 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001608 s390_disasm(ENC3(MNM, GPR, GPR), mnm, r1, r2);
1609}
1610
1611static void
1612s390_format_RRE_FF(HChar *(*irgen)(UChar r1, UChar r2),
1613 UChar r1, UChar r2)
1614{
1615 HChar *mnm = irgen(r1, r2);
1616
sewardj7ee97522011-05-09 21:45:04 +00001617 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001618 s390_disasm(ENC3(MNM, FPR, FPR), mnm, r1, r2);
1619}
1620
1621static void
1622s390_format_RRE_RF(HChar *(*irgen)(UChar, UChar),
1623 UChar r1, UChar r2)
1624{
1625 HChar *mnm = irgen(r1, r2);
1626
sewardj7ee97522011-05-09 21:45:04 +00001627 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001628 s390_disasm(ENC3(MNM, GPR, FPR), mnm, r1, r2);
1629}
1630
1631static void
1632s390_format_RRE_FR(HChar *(*irgen)(UChar r1, UChar r2),
1633 UChar r1, UChar r2)
1634{
1635 HChar *mnm = irgen(r1, r2);
1636
sewardj7ee97522011-05-09 21:45:04 +00001637 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001638 s390_disasm(ENC3(MNM, FPR, GPR), mnm, r1, r2);
1639}
1640
1641static void
1642s390_format_RRE_R0(HChar *(*irgen)(UChar r1),
1643 UChar r1)
1644{
1645 HChar *mnm = irgen(r1);
1646
sewardj7ee97522011-05-09 21:45:04 +00001647 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001648 s390_disasm(ENC2(MNM, GPR), mnm, r1);
1649}
1650
1651static void
1652s390_format_RRE_F0(HChar *(*irgen)(UChar r1),
1653 UChar r1)
1654{
1655 HChar *mnm = irgen(r1);
1656
sewardj7ee97522011-05-09 21:45:04 +00001657 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001658 s390_disasm(ENC2(MNM, FPR), mnm, r1);
1659}
1660
1661static void
florian9af37692012-01-15 21:01:16 +00001662s390_format_RRF_M0RERE(HChar *(*irgen)(UChar m3, UChar r1, UChar r2),
1663 UChar m3, UChar r1, UChar r2)
1664{
florianfed3ea32012-07-19 14:54:03 +00001665 HChar *mnm = irgen(m3, r1, r2);
florian9af37692012-01-15 21:01:16 +00001666
1667 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
florianfed3ea32012-07-19 14:54:03 +00001668 s390_disasm(ENC4(MNM, GPR, GPR, UINT), mnm, r1, r2, m3);
florian9af37692012-01-15 21:01:16 +00001669}
1670
1671static void
sewardj2019a972011-03-07 16:04:07 +00001672s390_format_RRF_F0FF(HChar *(*irgen)(UChar, UChar, UChar),
1673 UChar r1, UChar r3, UChar r2)
1674{
1675 HChar *mnm = irgen(r1, r3, r2);
1676
sewardj7ee97522011-05-09 21:45:04 +00001677 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001678 s390_disasm(ENC4(MNM, FPR, FPR, FPR), mnm, r1, r3, r2);
1679}
1680
1681static void
sewardjd7bde722011-04-05 13:19:33 +00001682s390_format_RRF_U0RR(HChar *(*irgen)(UChar m3, UChar r1, UChar r2),
1683 UChar m3, UChar r1, UChar r2, Int xmnm_kind)
1684{
1685 irgen(m3, r1, r2);
1686
sewardj7ee97522011-05-09 21:45:04 +00001687 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardjd7bde722011-04-05 13:19:33 +00001688 s390_disasm(ENC3(XMNM, GPR, GPR), xmnm_kind, m3, r1, r2);
1689}
1690
1691static void
sewardj2019a972011-03-07 16:04:07 +00001692s390_format_RRF_U0RF(HChar *(*irgen)(UChar r3, UChar r1, UChar r2),
1693 UChar r3, UChar r1, UChar r2)
1694{
1695 HChar *mnm = irgen(r3, r1, r2);
1696
sewardj7ee97522011-05-09 21:45:04 +00001697 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001698 s390_disasm(ENC4(MNM, GPR, UINT, FPR), mnm, r1, r3, r2);
1699}
1700
1701static void
1702s390_format_RRF_F0FF2(HChar *(*irgen)(UChar, UChar, UChar),
1703 UChar r3, UChar r1, UChar r2)
1704{
1705 HChar *mnm = irgen(r3, r1, r2);
1706
sewardj7ee97522011-05-09 21:45:04 +00001707 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001708 s390_disasm(ENC4(MNM, FPR, FPR, FPR), mnm, r1, r3, r2);
1709}
1710
1711static void
1712s390_format_RRF_R0RR2(HChar *(*irgen)(UChar r3, UChar r1, UChar r2),
1713 UChar r3, UChar r1, UChar r2)
1714{
1715 HChar *mnm = irgen(r3, r1, r2);
1716
sewardj7ee97522011-05-09 21:45:04 +00001717 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001718 s390_disasm(ENC4(MNM, GPR, GPR, GPR), mnm, r1, r2, r3);
1719}
1720
1721static void
1722s390_format_RRS(HChar *(*irgen)(UChar r1, UChar r2, UChar m3, IRTemp op4addr),
1723 UChar r1, UChar r2, UChar b4, UShort d4, UChar m3)
1724{
1725 HChar *mnm;
1726 IRTemp op4addr = newTemp(Ity_I64);
1727
1728 assign(op4addr, binop(Iop_Add64, mkU64(d4), b4 != 0 ? get_gpr_dw0(b4) :
1729 mkU64(0)));
1730
1731 mnm = irgen(r1, r2, m3, op4addr);
1732
sewardj7ee97522011-05-09 21:45:04 +00001733 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001734 s390_disasm(ENC5(XMNM, GPR, GPR, CABM, UDXB), S390_XMNM_CAB, mnm, m3, r1,
1735 r2, m3, d4, 0, b4);
1736}
1737
1738static void
1739s390_format_RS_R0RD(HChar *(*irgen)(UChar r1, IRTemp op2addr),
1740 UChar r1, UChar b2, UShort d2)
1741{
1742 HChar *mnm;
1743 IRTemp op2addr = newTemp(Ity_I64);
1744
1745 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
1746 mkU64(0)));
1747
1748 mnm = irgen(r1, op2addr);
1749
sewardj7ee97522011-05-09 21:45:04 +00001750 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001751 s390_disasm(ENC3(MNM, GPR, UDXB), mnm, r1, d2, 0, b2);
1752}
1753
1754static void
1755s390_format_RS_RRRD(HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
1756 UChar r1, UChar r3, UChar b2, UShort d2)
1757{
1758 HChar *mnm;
1759 IRTemp op2addr = newTemp(Ity_I64);
1760
1761 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
1762 mkU64(0)));
1763
1764 mnm = irgen(r1, r3, op2addr);
1765
sewardj7ee97522011-05-09 21:45:04 +00001766 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001767 s390_disasm(ENC4(MNM, GPR, GPR, UDXB), mnm, r1, r3, d2, 0, b2);
1768}
1769
1770static void
1771s390_format_RS_RURD(HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
1772 UChar r1, UChar r3, UChar b2, UShort d2)
1773{
1774 HChar *mnm;
1775 IRTemp op2addr = newTemp(Ity_I64);
1776
1777 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
1778 mkU64(0)));
1779
1780 mnm = irgen(r1, r3, op2addr);
1781
sewardj7ee97522011-05-09 21:45:04 +00001782 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001783 s390_disasm(ENC4(MNM, GPR, UINT, UDXB), mnm, r1, r3, d2, 0, b2);
1784}
1785
1786static void
1787s390_format_RS_AARD(HChar *(*irgen)(UChar, UChar, IRTemp),
1788 UChar r1, UChar r3, UChar b2, UShort d2)
1789{
1790 HChar *mnm;
1791 IRTemp op2addr = newTemp(Ity_I64);
1792
1793 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
1794 mkU64(0)));
1795
1796 mnm = irgen(r1, r3, op2addr);
1797
sewardj7ee97522011-05-09 21:45:04 +00001798 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001799 s390_disasm(ENC4(MNM, AR, AR, UDXB), mnm, r1, r3, d2, 0, b2);
1800}
1801
1802static void
1803s390_format_RSI_RRP(HChar *(*irgen)(UChar r1, UChar r3, UShort i2),
1804 UChar r1, UChar r3, UShort i2)
1805{
1806 HChar *mnm = irgen(r1, r3, i2);
1807
sewardj7ee97522011-05-09 21:45:04 +00001808 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001809 s390_disasm(ENC4(MNM, GPR, GPR, PCREL), mnm, r1, r3, (Int)(Short)i2);
1810}
1811
1812static void
1813s390_format_RSY_RRRD(HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
1814 UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2)
1815{
1816 HChar *mnm;
1817 IRTemp op2addr = newTemp(Ity_I64);
1818 IRTemp d2 = newTemp(Ity_I64);
1819
1820 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
1821 assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
1822 mkU64(0)));
1823
1824 mnm = irgen(r1, r3, op2addr);
1825
sewardj7ee97522011-05-09 21:45:04 +00001826 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001827 s390_disasm(ENC4(MNM, GPR, GPR, SDXB), mnm, r1, r3, dh2, dl2, 0, b2);
1828}
1829
1830static void
1831s390_format_RSY_AARD(HChar *(*irgen)(UChar, UChar, IRTemp),
1832 UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2)
1833{
1834 HChar *mnm;
1835 IRTemp op2addr = newTemp(Ity_I64);
1836 IRTemp d2 = newTemp(Ity_I64);
1837
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 mnm = irgen(r1, r3, op2addr);
1843
sewardj7ee97522011-05-09 21:45:04 +00001844 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001845 s390_disasm(ENC4(MNM, AR, AR, SDXB), mnm, r1, r3, dh2, dl2, 0, b2);
1846}
1847
1848static void
1849s390_format_RSY_RURD(HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
1850 UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2)
1851{
1852 HChar *mnm;
1853 IRTemp op2addr = newTemp(Ity_I64);
1854 IRTemp d2 = newTemp(Ity_I64);
1855
1856 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
1857 assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
1858 mkU64(0)));
1859
1860 mnm = irgen(r1, r3, op2addr);
1861
sewardj7ee97522011-05-09 21:45:04 +00001862 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001863 s390_disasm(ENC4(MNM, GPR, UINT, SDXB), mnm, r1, r3, dh2, dl2, 0, b2);
1864}
1865
1866static void
sewardjd7bde722011-04-05 13:19:33 +00001867s390_format_RSY_RDRM(HChar *(*irgen)(UChar r1, IRTemp op2addr),
1868 UChar r1, UChar m3, UChar b2, UShort dl2, UChar dh2,
1869 Int xmnm_kind)
1870{
1871 IRTemp op2addr = newTemp(Ity_I64);
1872 IRTemp d2 = newTemp(Ity_I64);
1873
florian6820ba52012-07-26 02:01:50 +00001874 next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0)));
1875
sewardjd7bde722011-04-05 13:19:33 +00001876 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
1877 assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
1878 mkU64(0)));
1879
1880 irgen(r1, op2addr);
florian6820ba52012-07-26 02:01:50 +00001881
1882 vassert(dis_res->whatNext == Dis_Continue);
sewardjd7bde722011-04-05 13:19:33 +00001883
sewardj7ee97522011-05-09 21:45:04 +00001884 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardjd7bde722011-04-05 13:19:33 +00001885 s390_disasm(ENC3(XMNM, GPR, SDXB), xmnm_kind, m3, r1, dh2, dl2, 0, b2);
1886}
1887
1888static void
sewardj2019a972011-03-07 16:04:07 +00001889s390_format_RX(HChar *(*irgen)(UChar r1, UChar x2, UChar b2, UShort d2,
1890 IRTemp op2addr),
1891 UChar r1, UChar x2, UChar b2, UShort d2)
1892{
1893 IRTemp op2addr = newTemp(Ity_I64);
1894
1895 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
1896 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
1897 mkU64(0)));
1898
1899 irgen(r1, x2, b2, d2, op2addr);
1900}
1901
1902static void
1903s390_format_RX_RRRD(HChar *(*irgen)(UChar r1, IRTemp op2addr),
1904 UChar r1, UChar x2, UChar b2, UShort d2)
1905{
1906 HChar *mnm;
1907 IRTemp op2addr = newTemp(Ity_I64);
1908
1909 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
1910 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
1911 mkU64(0)));
1912
1913 mnm = irgen(r1, op2addr);
1914
sewardj7ee97522011-05-09 21:45:04 +00001915 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001916 s390_disasm(ENC3(MNM, GPR, UDXB), mnm, r1, d2, x2, b2);
1917}
1918
1919static void
1920s390_format_RX_FRRD(HChar *(*irgen)(UChar r1, IRTemp op2addr),
1921 UChar r1, UChar x2, UChar b2, UShort d2)
1922{
1923 HChar *mnm;
1924 IRTemp op2addr = newTemp(Ity_I64);
1925
1926 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
1927 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
1928 mkU64(0)));
1929
1930 mnm = irgen(r1, op2addr);
1931
sewardj7ee97522011-05-09 21:45:04 +00001932 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001933 s390_disasm(ENC3(MNM, FPR, UDXB), mnm, r1, d2, x2, b2);
1934}
1935
1936static void
1937s390_format_RXE_FRRD(HChar *(*irgen)(UChar r1, IRTemp op2addr),
1938 UChar r1, UChar x2, UChar b2, UShort d2)
1939{
1940 HChar *mnm;
1941 IRTemp op2addr = newTemp(Ity_I64);
1942
1943 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
1944 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
1945 mkU64(0)));
1946
1947 mnm = irgen(r1, op2addr);
1948
sewardj7ee97522011-05-09 21:45:04 +00001949 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001950 s390_disasm(ENC3(MNM, FPR, UDXB), mnm, r1, d2, x2, b2);
1951}
1952
1953static void
1954s390_format_RXF_FRRDF(HChar *(*irgen)(UChar, IRTemp, UChar),
1955 UChar r3, UChar x2, UChar b2, UShort d2, UChar r1)
1956{
1957 HChar *mnm;
1958 IRTemp op2addr = newTemp(Ity_I64);
1959
1960 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
1961 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
1962 mkU64(0)));
1963
1964 mnm = irgen(r3, op2addr, r1);
1965
sewardj7ee97522011-05-09 21:45:04 +00001966 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001967 s390_disasm(ENC4(MNM, FPR, FPR, UDXB), mnm, r1, r3, d2, x2, b2);
1968}
1969
1970static void
1971s390_format_RXY_RRRD(HChar *(*irgen)(UChar r1, IRTemp op2addr),
1972 UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
1973{
1974 HChar *mnm;
1975 IRTemp op2addr = newTemp(Ity_I64);
1976 IRTemp d2 = newTemp(Ity_I64);
1977
1978 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
1979 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkexpr(d2),
1980 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
1981 mkU64(0)));
1982
1983 mnm = irgen(r1, op2addr);
1984
sewardj7ee97522011-05-09 21:45:04 +00001985 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001986 s390_disasm(ENC3(MNM, GPR, SDXB), mnm, r1, dh2, dl2, x2, b2);
1987}
1988
1989static void
1990s390_format_RXY_FRRD(HChar *(*irgen)(UChar r1, IRTemp op2addr),
1991 UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
1992{
1993 HChar *mnm;
1994 IRTemp op2addr = newTemp(Ity_I64);
1995 IRTemp d2 = newTemp(Ity_I64);
1996
1997 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
1998 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkexpr(d2),
1999 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2000 mkU64(0)));
2001
2002 mnm = irgen(r1, op2addr);
2003
sewardj7ee97522011-05-09 21:45:04 +00002004 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002005 s390_disasm(ENC3(MNM, FPR, SDXB), mnm, r1, dh2, dl2, x2, b2);
2006}
2007
2008static void
2009s390_format_RXY_URRD(HChar *(*irgen)(void),
2010 UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
2011{
2012 HChar *mnm;
2013 IRTemp op2addr = newTemp(Ity_I64);
2014 IRTemp d2 = newTemp(Ity_I64);
2015
2016 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2017 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkexpr(d2),
2018 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2019 mkU64(0)));
2020
2021 mnm = irgen();
2022
sewardj7ee97522011-05-09 21:45:04 +00002023 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002024 s390_disasm(ENC3(MNM, UINT, SDXB), mnm, r1, dh2, dl2, x2, b2);
2025}
2026
2027static void
2028s390_format_S_RD(HChar *(*irgen)(IRTemp op2addr),
2029 UChar b2, UShort d2)
2030{
2031 HChar *mnm;
2032 IRTemp op2addr = newTemp(Ity_I64);
2033
2034 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2035 mkU64(0)));
2036
2037 mnm = irgen(op2addr);
2038
sewardj7ee97522011-05-09 21:45:04 +00002039 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002040 s390_disasm(ENC2(MNM, UDXB), mnm, d2, 0, b2);
2041}
2042
2043static void
2044s390_format_SI_URD(HChar *(*irgen)(UChar i2, IRTemp op1addr),
2045 UChar i2, UChar b1, UShort d1)
2046{
2047 HChar *mnm;
2048 IRTemp op1addr = newTemp(Ity_I64);
2049
2050 assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
2051 mkU64(0)));
2052
2053 mnm = irgen(i2, op1addr);
2054
sewardj7ee97522011-05-09 21:45:04 +00002055 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002056 s390_disasm(ENC3(MNM, UDXB, UINT), mnm, d1, 0, b1, i2);
2057}
2058
2059static void
2060s390_format_SIY_URD(HChar *(*irgen)(UChar i2, IRTemp op1addr),
2061 UChar i2, UChar b1, UShort dl1, UChar dh1)
2062{
2063 HChar *mnm;
2064 IRTemp op1addr = newTemp(Ity_I64);
2065 IRTemp d1 = newTemp(Ity_I64);
2066
2067 assign(d1, mkU64(((ULong)(Long)(Char)dh1 << 12) | ((ULong)dl1)));
2068 assign(op1addr, binop(Iop_Add64, mkexpr(d1), b1 != 0 ? get_gpr_dw0(b1) :
2069 mkU64(0)));
2070
2071 mnm = irgen(i2, op1addr);
2072
sewardj7ee97522011-05-09 21:45:04 +00002073 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002074 s390_disasm(ENC3(MNM, SDXB, UINT), mnm, dh1, dl1, 0, b1, i2);
2075}
2076
2077static void
2078s390_format_SIY_IRD(HChar *(*irgen)(UChar i2, IRTemp op1addr),
2079 UChar i2, UChar b1, UShort dl1, UChar dh1)
2080{
2081 HChar *mnm;
2082 IRTemp op1addr = newTemp(Ity_I64);
2083 IRTemp d1 = newTemp(Ity_I64);
2084
2085 assign(d1, mkU64(((ULong)(Long)(Char)dh1 << 12) | ((ULong)dl1)));
2086 assign(op1addr, binop(Iop_Add64, mkexpr(d1), b1 != 0 ? get_gpr_dw0(b1) :
2087 mkU64(0)));
2088
2089 mnm = irgen(i2, op1addr);
2090
sewardj7ee97522011-05-09 21:45:04 +00002091 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002092 s390_disasm(ENC3(MNM, SDXB, INT), mnm, dh1, dl1, 0, b1, (Int)(Char)i2);
2093}
2094
2095static void
2096s390_format_SS_L0RDRD(HChar *(*irgen)(UChar, IRTemp, IRTemp),
2097 UChar l, UChar b1, UShort d1, UChar b2, UShort d2)
2098{
2099 HChar *mnm;
2100 IRTemp op1addr = newTemp(Ity_I64);
2101 IRTemp op2addr = newTemp(Ity_I64);
2102
2103 assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
2104 mkU64(0)));
2105 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2106 mkU64(0)));
2107
2108 mnm = irgen(l, op1addr, op2addr);
2109
sewardj7ee97522011-05-09 21:45:04 +00002110 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002111 s390_disasm(ENC3(MNM, UDLB, UDXB), mnm, d1, l, b1, d2, 0, b2);
2112}
2113
2114static void
2115s390_format_SIL_RDI(HChar *(*irgen)(UShort i2, IRTemp op1addr),
2116 UChar b1, UShort d1, UShort i2)
2117{
2118 HChar *mnm;
2119 IRTemp op1addr = newTemp(Ity_I64);
2120
2121 assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
2122 mkU64(0)));
2123
2124 mnm = irgen(i2, op1addr);
2125
sewardj7ee97522011-05-09 21:45:04 +00002126 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002127 s390_disasm(ENC3(MNM, UDXB, INT), mnm, d1, 0, b1, (Int)(Short)i2);
2128}
2129
2130static void
2131s390_format_SIL_RDU(HChar *(*irgen)(UShort i2, IRTemp op1addr),
2132 UChar b1, UShort d1, UShort i2)
2133{
2134 HChar *mnm;
2135 IRTemp op1addr = newTemp(Ity_I64);
2136
2137 assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
2138 mkU64(0)));
2139
2140 mnm = irgen(i2, op1addr);
2141
sewardj7ee97522011-05-09 21:45:04 +00002142 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002143 s390_disasm(ENC3(MNM, UDXB, UINT), mnm, d1, 0, b1, i2);
2144}
2145
2146
2147
2148/*------------------------------------------------------------*/
2149/*--- Build IR for opcodes ---*/
2150/*------------------------------------------------------------*/
2151
2152static HChar *
2153s390_irgen_AR(UChar r1, UChar r2)
2154{
2155 IRTemp op1 = newTemp(Ity_I32);
2156 IRTemp op2 = newTemp(Ity_I32);
2157 IRTemp result = newTemp(Ity_I32);
2158
2159 assign(op1, get_gpr_w1(r1));
2160 assign(op2, get_gpr_w1(r2));
2161 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2162 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2163 put_gpr_w1(r1, mkexpr(result));
2164
2165 return "ar";
2166}
2167
2168static HChar *
2169s390_irgen_AGR(UChar r1, UChar r2)
2170{
2171 IRTemp op1 = newTemp(Ity_I64);
2172 IRTemp op2 = newTemp(Ity_I64);
2173 IRTemp result = newTemp(Ity_I64);
2174
2175 assign(op1, get_gpr_dw0(r1));
2176 assign(op2, get_gpr_dw0(r2));
2177 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2178 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
2179 put_gpr_dw0(r1, mkexpr(result));
2180
2181 return "agr";
2182}
2183
2184static HChar *
2185s390_irgen_AGFR(UChar r1, UChar r2)
2186{
2187 IRTemp op1 = newTemp(Ity_I64);
2188 IRTemp op2 = newTemp(Ity_I64);
2189 IRTemp result = newTemp(Ity_I64);
2190
2191 assign(op1, get_gpr_dw0(r1));
2192 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
2193 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2194 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
2195 put_gpr_dw0(r1, mkexpr(result));
2196
2197 return "agfr";
2198}
2199
2200static HChar *
2201s390_irgen_ARK(UChar r3, UChar r1, UChar r2)
2202{
2203 IRTemp op2 = newTemp(Ity_I32);
2204 IRTemp op3 = newTemp(Ity_I32);
2205 IRTemp result = newTemp(Ity_I32);
2206
2207 assign(op2, get_gpr_w1(r2));
2208 assign(op3, get_gpr_w1(r3));
2209 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2210 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
2211 put_gpr_w1(r1, mkexpr(result));
2212
2213 return "ark";
2214}
2215
2216static HChar *
2217s390_irgen_AGRK(UChar r3, UChar r1, UChar r2)
2218{
2219 IRTemp op2 = newTemp(Ity_I64);
2220 IRTemp op3 = newTemp(Ity_I64);
2221 IRTemp result = newTemp(Ity_I64);
2222
2223 assign(op2, get_gpr_dw0(r2));
2224 assign(op3, get_gpr_dw0(r3));
2225 assign(result, binop(Iop_Add64, mkexpr(op2), mkexpr(op3)));
2226 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op2, op3);
2227 put_gpr_dw0(r1, mkexpr(result));
2228
2229 return "agrk";
2230}
2231
2232static HChar *
2233s390_irgen_A(UChar r1, IRTemp op2addr)
2234{
2235 IRTemp op1 = newTemp(Ity_I32);
2236 IRTemp op2 = newTemp(Ity_I32);
2237 IRTemp result = newTemp(Ity_I32);
2238
2239 assign(op1, get_gpr_w1(r1));
2240 assign(op2, load(Ity_I32, mkexpr(op2addr)));
2241 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2242 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2243 put_gpr_w1(r1, mkexpr(result));
2244
2245 return "a";
2246}
2247
2248static HChar *
2249s390_irgen_AY(UChar r1, IRTemp op2addr)
2250{
2251 IRTemp op1 = newTemp(Ity_I32);
2252 IRTemp op2 = newTemp(Ity_I32);
2253 IRTemp result = newTemp(Ity_I32);
2254
2255 assign(op1, get_gpr_w1(r1));
2256 assign(op2, load(Ity_I32, mkexpr(op2addr)));
2257 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2258 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2259 put_gpr_w1(r1, mkexpr(result));
2260
2261 return "ay";
2262}
2263
2264static HChar *
2265s390_irgen_AG(UChar r1, IRTemp op2addr)
2266{
2267 IRTemp op1 = newTemp(Ity_I64);
2268 IRTemp op2 = newTemp(Ity_I64);
2269 IRTemp result = newTemp(Ity_I64);
2270
2271 assign(op1, get_gpr_dw0(r1));
2272 assign(op2, load(Ity_I64, mkexpr(op2addr)));
2273 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2274 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
2275 put_gpr_dw0(r1, mkexpr(result));
2276
2277 return "ag";
2278}
2279
2280static HChar *
2281s390_irgen_AGF(UChar r1, IRTemp op2addr)
2282{
2283 IRTemp op1 = newTemp(Ity_I64);
2284 IRTemp op2 = newTemp(Ity_I64);
2285 IRTemp result = newTemp(Ity_I64);
2286
2287 assign(op1, get_gpr_dw0(r1));
2288 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
2289 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2290 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
2291 put_gpr_dw0(r1, mkexpr(result));
2292
2293 return "agf";
2294}
2295
2296static HChar *
2297s390_irgen_AFI(UChar r1, UInt i2)
2298{
2299 IRTemp op1 = newTemp(Ity_I32);
2300 Int op2;
2301 IRTemp result = newTemp(Ity_I32);
2302
2303 assign(op1, get_gpr_w1(r1));
2304 op2 = (Int)i2;
2305 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
2306 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
2307 mkU32((UInt)op2)));
2308 put_gpr_w1(r1, mkexpr(result));
2309
2310 return "afi";
2311}
2312
2313static HChar *
2314s390_irgen_AGFI(UChar r1, UInt i2)
2315{
2316 IRTemp op1 = newTemp(Ity_I64);
2317 Long op2;
2318 IRTemp result = newTemp(Ity_I64);
2319
2320 assign(op1, get_gpr_dw0(r1));
2321 op2 = (Long)(Int)i2;
2322 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64((ULong)op2)));
2323 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, mktemp(Ity_I64,
2324 mkU64((ULong)op2)));
2325 put_gpr_dw0(r1, mkexpr(result));
2326
2327 return "agfi";
2328}
2329
2330static HChar *
2331s390_irgen_AHIK(UChar r1, UChar r3, UShort i2)
2332{
2333 Int op2;
2334 IRTemp op3 = newTemp(Ity_I32);
2335 IRTemp result = newTemp(Ity_I32);
2336
2337 op2 = (Int)(Short)i2;
2338 assign(op3, get_gpr_w1(r3));
2339 assign(result, binop(Iop_Add32, mkU32((UInt)op2), mkexpr(op3)));
2340 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, mktemp(Ity_I32, mkU32((UInt)
2341 op2)), op3);
2342 put_gpr_w1(r1, mkexpr(result));
2343
2344 return "ahik";
2345}
2346
2347static HChar *
2348s390_irgen_AGHIK(UChar r1, UChar r3, UShort i2)
2349{
2350 Long op2;
2351 IRTemp op3 = newTemp(Ity_I64);
2352 IRTemp result = newTemp(Ity_I64);
2353
2354 op2 = (Long)(Short)i2;
2355 assign(op3, get_gpr_dw0(r3));
2356 assign(result, binop(Iop_Add64, mkU64((ULong)op2), mkexpr(op3)));
2357 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, mktemp(Ity_I64, mkU64((ULong)
2358 op2)), op3);
2359 put_gpr_dw0(r1, mkexpr(result));
2360
2361 return "aghik";
2362}
2363
2364static HChar *
2365s390_irgen_ASI(UChar i2, IRTemp op1addr)
2366{
2367 IRTemp op1 = newTemp(Ity_I32);
2368 Int op2;
2369 IRTemp result = newTemp(Ity_I32);
2370
2371 assign(op1, load(Ity_I32, mkexpr(op1addr)));
2372 op2 = (Int)(Char)i2;
2373 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
2374 store(mkexpr(op1addr), mkexpr(result));
2375 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
2376 mkU32((UInt)op2)));
2377
2378 return "asi";
2379}
2380
2381static HChar *
2382s390_irgen_AGSI(UChar i2, IRTemp op1addr)
2383{
2384 IRTemp op1 = newTemp(Ity_I64);
2385 Long op2;
2386 IRTemp result = newTemp(Ity_I64);
2387
2388 assign(op1, load(Ity_I64, mkexpr(op1addr)));
2389 op2 = (Long)(Char)i2;
2390 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64((ULong)op2)));
2391 store(mkexpr(op1addr), mkexpr(result));
2392 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, mktemp(Ity_I64,
2393 mkU64((ULong)op2)));
2394
2395 return "agsi";
2396}
2397
2398static HChar *
2399s390_irgen_AH(UChar r1, IRTemp op2addr)
2400{
2401 IRTemp op1 = newTemp(Ity_I32);
2402 IRTemp op2 = newTemp(Ity_I32);
2403 IRTemp result = newTemp(Ity_I32);
2404
2405 assign(op1, get_gpr_w1(r1));
2406 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
2407 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2408 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2409 put_gpr_w1(r1, mkexpr(result));
2410
2411 return "ah";
2412}
2413
2414static HChar *
2415s390_irgen_AHY(UChar r1, IRTemp op2addr)
2416{
2417 IRTemp op1 = newTemp(Ity_I32);
2418 IRTemp op2 = newTemp(Ity_I32);
2419 IRTemp result = newTemp(Ity_I32);
2420
2421 assign(op1, get_gpr_w1(r1));
2422 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
2423 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2424 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2425 put_gpr_w1(r1, mkexpr(result));
2426
2427 return "ahy";
2428}
2429
2430static HChar *
2431s390_irgen_AHI(UChar r1, UShort i2)
2432{
2433 IRTemp op1 = newTemp(Ity_I32);
2434 Int op2;
2435 IRTemp result = newTemp(Ity_I32);
2436
2437 assign(op1, get_gpr_w1(r1));
2438 op2 = (Int)(Short)i2;
2439 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
2440 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
2441 mkU32((UInt)op2)));
2442 put_gpr_w1(r1, mkexpr(result));
2443
2444 return "ahi";
2445}
2446
2447static HChar *
2448s390_irgen_AGHI(UChar r1, UShort i2)
2449{
2450 IRTemp op1 = newTemp(Ity_I64);
2451 Long op2;
2452 IRTemp result = newTemp(Ity_I64);
2453
2454 assign(op1, get_gpr_dw0(r1));
2455 op2 = (Long)(Short)i2;
2456 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64((ULong)op2)));
2457 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, mktemp(Ity_I64,
2458 mkU64((ULong)op2)));
2459 put_gpr_dw0(r1, mkexpr(result));
2460
2461 return "aghi";
2462}
2463
2464static HChar *
2465s390_irgen_AHHHR(UChar r3, UChar r1, UChar r2)
2466{
2467 IRTemp op2 = newTemp(Ity_I32);
2468 IRTemp op3 = newTemp(Ity_I32);
2469 IRTemp result = newTemp(Ity_I32);
2470
2471 assign(op2, get_gpr_w0(r2));
2472 assign(op3, get_gpr_w0(r3));
2473 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2474 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
2475 put_gpr_w0(r1, mkexpr(result));
2476
2477 return "ahhhr";
2478}
2479
2480static HChar *
2481s390_irgen_AHHLR(UChar r3, UChar r1, UChar r2)
2482{
2483 IRTemp op2 = newTemp(Ity_I32);
2484 IRTemp op3 = newTemp(Ity_I32);
2485 IRTemp result = newTemp(Ity_I32);
2486
2487 assign(op2, get_gpr_w0(r2));
2488 assign(op3, get_gpr_w1(r3));
2489 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2490 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
2491 put_gpr_w0(r1, mkexpr(result));
2492
2493 return "ahhlr";
2494}
2495
2496static HChar *
2497s390_irgen_AIH(UChar r1, UInt i2)
2498{
2499 IRTemp op1 = newTemp(Ity_I32);
2500 Int op2;
2501 IRTemp result = newTemp(Ity_I32);
2502
2503 assign(op1, get_gpr_w0(r1));
2504 op2 = (Int)i2;
2505 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
2506 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
2507 mkU32((UInt)op2)));
2508 put_gpr_w0(r1, mkexpr(result));
2509
2510 return "aih";
2511}
2512
2513static HChar *
2514s390_irgen_ALR(UChar r1, UChar r2)
2515{
2516 IRTemp op1 = newTemp(Ity_I32);
2517 IRTemp op2 = newTemp(Ity_I32);
2518 IRTemp result = newTemp(Ity_I32);
2519
2520 assign(op1, get_gpr_w1(r1));
2521 assign(op2, get_gpr_w1(r2));
2522 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2523 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, op2);
2524 put_gpr_w1(r1, mkexpr(result));
2525
2526 return "alr";
2527}
2528
2529static HChar *
2530s390_irgen_ALGR(UChar r1, UChar r2)
2531{
2532 IRTemp op1 = newTemp(Ity_I64);
2533 IRTemp op2 = newTemp(Ity_I64);
2534 IRTemp result = newTemp(Ity_I64);
2535
2536 assign(op1, get_gpr_dw0(r1));
2537 assign(op2, get_gpr_dw0(r2));
2538 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2539 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
2540 put_gpr_dw0(r1, mkexpr(result));
2541
2542 return "algr";
2543}
2544
2545static HChar *
2546s390_irgen_ALGFR(UChar r1, UChar r2)
2547{
2548 IRTemp op1 = newTemp(Ity_I64);
2549 IRTemp op2 = newTemp(Ity_I64);
2550 IRTemp result = newTemp(Ity_I64);
2551
2552 assign(op1, get_gpr_dw0(r1));
2553 assign(op2, unop(Iop_32Uto64, get_gpr_w1(r2)));
2554 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2555 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
2556 put_gpr_dw0(r1, mkexpr(result));
2557
2558 return "algfr";
2559}
2560
2561static HChar *
2562s390_irgen_ALRK(UChar r3, UChar r1, UChar r2)
2563{
2564 IRTemp op2 = newTemp(Ity_I32);
2565 IRTemp op3 = newTemp(Ity_I32);
2566 IRTemp result = newTemp(Ity_I32);
2567
2568 assign(op2, get_gpr_w1(r2));
2569 assign(op3, get_gpr_w1(r3));
2570 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2571 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
2572 put_gpr_w1(r1, mkexpr(result));
2573
2574 return "alrk";
2575}
2576
2577static HChar *
2578s390_irgen_ALGRK(UChar r3, UChar r1, UChar r2)
2579{
2580 IRTemp op2 = newTemp(Ity_I64);
2581 IRTemp op3 = newTemp(Ity_I64);
2582 IRTemp result = newTemp(Ity_I64);
2583
2584 assign(op2, get_gpr_dw0(r2));
2585 assign(op3, get_gpr_dw0(r3));
2586 assign(result, binop(Iop_Add64, mkexpr(op2), mkexpr(op3)));
2587 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op2, op3);
2588 put_gpr_dw0(r1, mkexpr(result));
2589
2590 return "algrk";
2591}
2592
2593static HChar *
2594s390_irgen_AL(UChar r1, IRTemp op2addr)
2595{
2596 IRTemp op1 = newTemp(Ity_I32);
2597 IRTemp op2 = newTemp(Ity_I32);
2598 IRTemp result = newTemp(Ity_I32);
2599
2600 assign(op1, get_gpr_w1(r1));
2601 assign(op2, load(Ity_I32, mkexpr(op2addr)));
2602 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2603 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, op2);
2604 put_gpr_w1(r1, mkexpr(result));
2605
2606 return "al";
2607}
2608
2609static HChar *
2610s390_irgen_ALY(UChar r1, IRTemp op2addr)
2611{
2612 IRTemp op1 = newTemp(Ity_I32);
2613 IRTemp op2 = newTemp(Ity_I32);
2614 IRTemp result = newTemp(Ity_I32);
2615
2616 assign(op1, get_gpr_w1(r1));
2617 assign(op2, load(Ity_I32, mkexpr(op2addr)));
2618 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2619 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, op2);
2620 put_gpr_w1(r1, mkexpr(result));
2621
2622 return "aly";
2623}
2624
2625static HChar *
2626s390_irgen_ALG(UChar r1, IRTemp op2addr)
2627{
2628 IRTemp op1 = newTemp(Ity_I64);
2629 IRTemp op2 = newTemp(Ity_I64);
2630 IRTemp result = newTemp(Ity_I64);
2631
2632 assign(op1, get_gpr_dw0(r1));
2633 assign(op2, load(Ity_I64, mkexpr(op2addr)));
2634 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2635 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
2636 put_gpr_dw0(r1, mkexpr(result));
2637
2638 return "alg";
2639}
2640
2641static HChar *
2642s390_irgen_ALGF(UChar r1, IRTemp op2addr)
2643{
2644 IRTemp op1 = newTemp(Ity_I64);
2645 IRTemp op2 = newTemp(Ity_I64);
2646 IRTemp result = newTemp(Ity_I64);
2647
2648 assign(op1, get_gpr_dw0(r1));
2649 assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
2650 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2651 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
2652 put_gpr_dw0(r1, mkexpr(result));
2653
2654 return "algf";
2655}
2656
2657static HChar *
2658s390_irgen_ALFI(UChar r1, UInt i2)
2659{
2660 IRTemp op1 = newTemp(Ity_I32);
2661 UInt op2;
2662 IRTemp result = newTemp(Ity_I32);
2663
2664 assign(op1, get_gpr_w1(r1));
2665 op2 = i2;
2666 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
2667 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, mktemp(Ity_I32,
2668 mkU32(op2)));
2669 put_gpr_w1(r1, mkexpr(result));
2670
2671 return "alfi";
2672}
2673
2674static HChar *
2675s390_irgen_ALGFI(UChar r1, UInt i2)
2676{
2677 IRTemp op1 = newTemp(Ity_I64);
2678 ULong op2;
2679 IRTemp result = newTemp(Ity_I64);
2680
2681 assign(op1, get_gpr_dw0(r1));
2682 op2 = (ULong)i2;
2683 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64(op2)));
2684 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, mktemp(Ity_I64,
2685 mkU64(op2)));
2686 put_gpr_dw0(r1, mkexpr(result));
2687
2688 return "algfi";
2689}
2690
2691static HChar *
2692s390_irgen_ALHHHR(UChar r3, UChar r1, UChar r2)
2693{
2694 IRTemp op2 = newTemp(Ity_I32);
2695 IRTemp op3 = newTemp(Ity_I32);
2696 IRTemp result = newTemp(Ity_I32);
2697
2698 assign(op2, get_gpr_w0(r2));
2699 assign(op3, get_gpr_w0(r3));
2700 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2701 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
2702 put_gpr_w0(r1, mkexpr(result));
2703
2704 return "alhhhr";
2705}
2706
2707static HChar *
2708s390_irgen_ALHHLR(UChar r3, UChar r1, UChar r2)
2709{
2710 IRTemp op2 = newTemp(Ity_I32);
2711 IRTemp op3 = newTemp(Ity_I32);
2712 IRTemp result = newTemp(Ity_I32);
2713
2714 assign(op2, get_gpr_w0(r2));
2715 assign(op3, get_gpr_w1(r3));
2716 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2717 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
2718 put_gpr_w0(r1, mkexpr(result));
2719
2720 return "alhhlr";
2721}
2722
2723static HChar *
2724s390_irgen_ALCR(UChar r1, UChar r2)
2725{
2726 IRTemp op1 = newTemp(Ity_I32);
2727 IRTemp op2 = newTemp(Ity_I32);
2728 IRTemp result = newTemp(Ity_I32);
2729 IRTemp carry_in = newTemp(Ity_I32);
2730
2731 assign(op1, get_gpr_w1(r1));
2732 assign(op2, get_gpr_w1(r2));
2733 assign(carry_in, binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)));
2734 assign(result, binop(Iop_Add32, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)),
2735 mkexpr(carry_in)));
2736 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_32, op1, op2, carry_in);
2737 put_gpr_w1(r1, mkexpr(result));
2738
2739 return "alcr";
2740}
2741
2742static HChar *
2743s390_irgen_ALCGR(UChar r1, UChar r2)
2744{
2745 IRTemp op1 = newTemp(Ity_I64);
2746 IRTemp op2 = newTemp(Ity_I64);
2747 IRTemp result = newTemp(Ity_I64);
2748 IRTemp carry_in = newTemp(Ity_I64);
2749
2750 assign(op1, get_gpr_dw0(r1));
2751 assign(op2, get_gpr_dw0(r2));
2752 assign(carry_in, unop(Iop_32Uto64, binop(Iop_Shr32, s390_call_calculate_cc(),
2753 mkU8(1))));
2754 assign(result, binop(Iop_Add64, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)),
2755 mkexpr(carry_in)));
2756 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_64, op1, op2, carry_in);
2757 put_gpr_dw0(r1, mkexpr(result));
2758
2759 return "alcgr";
2760}
2761
2762static HChar *
2763s390_irgen_ALC(UChar r1, IRTemp op2addr)
2764{
2765 IRTemp op1 = newTemp(Ity_I32);
2766 IRTemp op2 = newTemp(Ity_I32);
2767 IRTemp result = newTemp(Ity_I32);
2768 IRTemp carry_in = newTemp(Ity_I32);
2769
2770 assign(op1, get_gpr_w1(r1));
2771 assign(op2, load(Ity_I32, mkexpr(op2addr)));
2772 assign(carry_in, binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)));
2773 assign(result, binop(Iop_Add32, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)),
2774 mkexpr(carry_in)));
2775 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_32, op1, op2, carry_in);
2776 put_gpr_w1(r1, mkexpr(result));
2777
2778 return "alc";
2779}
2780
2781static HChar *
2782s390_irgen_ALCG(UChar r1, IRTemp op2addr)
2783{
2784 IRTemp op1 = newTemp(Ity_I64);
2785 IRTemp op2 = newTemp(Ity_I64);
2786 IRTemp result = newTemp(Ity_I64);
2787 IRTemp carry_in = newTemp(Ity_I64);
2788
2789 assign(op1, get_gpr_dw0(r1));
2790 assign(op2, load(Ity_I64, mkexpr(op2addr)));
2791 assign(carry_in, unop(Iop_32Uto64, binop(Iop_Shr32, s390_call_calculate_cc(),
2792 mkU8(1))));
2793 assign(result, binop(Iop_Add64, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)),
2794 mkexpr(carry_in)));
2795 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_64, op1, op2, carry_in);
2796 put_gpr_dw0(r1, mkexpr(result));
2797
2798 return "alcg";
2799}
2800
2801static HChar *
2802s390_irgen_ALSI(UChar i2, IRTemp op1addr)
2803{
2804 IRTemp op1 = newTemp(Ity_I32);
2805 UInt op2;
2806 IRTemp result = newTemp(Ity_I32);
2807
2808 assign(op1, load(Ity_I32, mkexpr(op1addr)));
2809 op2 = (UInt)(Int)(Char)i2;
2810 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
2811 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, mktemp(Ity_I32,
2812 mkU32(op2)));
2813 store(mkexpr(op1addr), mkexpr(result));
2814
2815 return "alsi";
2816}
2817
2818static HChar *
2819s390_irgen_ALGSI(UChar i2, IRTemp op1addr)
2820{
2821 IRTemp op1 = newTemp(Ity_I64);
2822 ULong op2;
2823 IRTemp result = newTemp(Ity_I64);
2824
2825 assign(op1, load(Ity_I64, mkexpr(op1addr)));
2826 op2 = (ULong)(Long)(Char)i2;
2827 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64(op2)));
2828 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, mktemp(Ity_I64,
2829 mkU64(op2)));
2830 store(mkexpr(op1addr), mkexpr(result));
2831
2832 return "algsi";
2833}
2834
2835static HChar *
2836s390_irgen_ALHSIK(UChar r1, UChar r3, UShort i2)
2837{
2838 UInt op2;
2839 IRTemp op3 = newTemp(Ity_I32);
2840 IRTemp result = newTemp(Ity_I32);
2841
2842 op2 = (UInt)(Int)(Short)i2;
2843 assign(op3, get_gpr_w1(r3));
2844 assign(result, binop(Iop_Add32, mkU32(op2), mkexpr(op3)));
2845 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, mktemp(Ity_I32, mkU32(op2)),
2846 op3);
2847 put_gpr_w1(r1, mkexpr(result));
2848
2849 return "alhsik";
2850}
2851
2852static HChar *
2853s390_irgen_ALGHSIK(UChar r1, UChar r3, UShort i2)
2854{
2855 ULong op2;
2856 IRTemp op3 = newTemp(Ity_I64);
2857 IRTemp result = newTemp(Ity_I64);
2858
2859 op2 = (ULong)(Long)(Short)i2;
2860 assign(op3, get_gpr_dw0(r3));
2861 assign(result, binop(Iop_Add64, mkU64(op2), mkexpr(op3)));
2862 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, mktemp(Ity_I64, mkU64(op2)),
2863 op3);
2864 put_gpr_dw0(r1, mkexpr(result));
2865
2866 return "alghsik";
2867}
2868
2869static HChar *
2870s390_irgen_ALSIH(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 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, mktemp(Ity_I32,
2880 mkU32(op2)));
2881 put_gpr_w0(r1, mkexpr(result));
2882
2883 return "alsih";
2884}
2885
2886static HChar *
2887s390_irgen_ALSIHN(UChar r1, UInt i2)
2888{
2889 IRTemp op1 = newTemp(Ity_I32);
2890 UInt op2;
2891 IRTemp result = newTemp(Ity_I32);
2892
2893 assign(op1, get_gpr_w0(r1));
2894 op2 = i2;
2895 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
2896 put_gpr_w0(r1, mkexpr(result));
2897
2898 return "alsihn";
2899}
2900
2901static HChar *
2902s390_irgen_NR(UChar r1, UChar r2)
2903{
2904 IRTemp op1 = newTemp(Ity_I32);
2905 IRTemp op2 = newTemp(Ity_I32);
2906 IRTemp result = newTemp(Ity_I32);
2907
2908 assign(op1, get_gpr_w1(r1));
2909 assign(op2, get_gpr_w1(r2));
2910 assign(result, binop(Iop_And32, mkexpr(op1), mkexpr(op2)));
2911 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
2912 put_gpr_w1(r1, mkexpr(result));
2913
2914 return "nr";
2915}
2916
2917static HChar *
2918s390_irgen_NGR(UChar r1, UChar r2)
2919{
2920 IRTemp op1 = newTemp(Ity_I64);
2921 IRTemp op2 = newTemp(Ity_I64);
2922 IRTemp result = newTemp(Ity_I64);
2923
2924 assign(op1, get_gpr_dw0(r1));
2925 assign(op2, get_gpr_dw0(r2));
2926 assign(result, binop(Iop_And64, mkexpr(op1), mkexpr(op2)));
2927 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
2928 put_gpr_dw0(r1, mkexpr(result));
2929
2930 return "ngr";
2931}
2932
2933static HChar *
2934s390_irgen_NRK(UChar r3, UChar r1, UChar r2)
2935{
2936 IRTemp op2 = newTemp(Ity_I32);
2937 IRTemp op3 = newTemp(Ity_I32);
2938 IRTemp result = newTemp(Ity_I32);
2939
2940 assign(op2, get_gpr_w1(r2));
2941 assign(op3, get_gpr_w1(r3));
2942 assign(result, binop(Iop_And32, mkexpr(op2), mkexpr(op3)));
2943 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
2944 put_gpr_w1(r1, mkexpr(result));
2945
2946 return "nrk";
2947}
2948
2949static HChar *
2950s390_irgen_NGRK(UChar r3, UChar r1, UChar r2)
2951{
2952 IRTemp op2 = newTemp(Ity_I64);
2953 IRTemp op3 = newTemp(Ity_I64);
2954 IRTemp result = newTemp(Ity_I64);
2955
2956 assign(op2, get_gpr_dw0(r2));
2957 assign(op3, get_gpr_dw0(r3));
2958 assign(result, binop(Iop_And64, mkexpr(op2), mkexpr(op3)));
2959 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
2960 put_gpr_dw0(r1, mkexpr(result));
2961
2962 return "ngrk";
2963}
2964
2965static HChar *
2966s390_irgen_N(UChar r1, IRTemp op2addr)
2967{
2968 IRTemp op1 = newTemp(Ity_I32);
2969 IRTemp op2 = newTemp(Ity_I32);
2970 IRTemp result = newTemp(Ity_I32);
2971
2972 assign(op1, get_gpr_w1(r1));
2973 assign(op2, load(Ity_I32, mkexpr(op2addr)));
2974 assign(result, binop(Iop_And32, mkexpr(op1), mkexpr(op2)));
2975 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
2976 put_gpr_w1(r1, mkexpr(result));
2977
2978 return "n";
2979}
2980
2981static HChar *
2982s390_irgen_NY(UChar r1, IRTemp op2addr)
2983{
2984 IRTemp op1 = newTemp(Ity_I32);
2985 IRTemp op2 = newTemp(Ity_I32);
2986 IRTemp result = newTemp(Ity_I32);
2987
2988 assign(op1, get_gpr_w1(r1));
2989 assign(op2, load(Ity_I32, mkexpr(op2addr)));
2990 assign(result, binop(Iop_And32, mkexpr(op1), mkexpr(op2)));
2991 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
2992 put_gpr_w1(r1, mkexpr(result));
2993
2994 return "ny";
2995}
2996
2997static HChar *
2998s390_irgen_NG(UChar r1, IRTemp op2addr)
2999{
3000 IRTemp op1 = newTemp(Ity_I64);
3001 IRTemp op2 = newTemp(Ity_I64);
3002 IRTemp result = newTemp(Ity_I64);
3003
3004 assign(op1, get_gpr_dw0(r1));
3005 assign(op2, load(Ity_I64, mkexpr(op2addr)));
3006 assign(result, binop(Iop_And64, mkexpr(op1), mkexpr(op2)));
3007 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3008 put_gpr_dw0(r1, mkexpr(result));
3009
3010 return "ng";
3011}
3012
3013static HChar *
3014s390_irgen_NI(UChar i2, IRTemp op1addr)
3015{
3016 IRTemp op1 = newTemp(Ity_I8);
3017 UChar op2;
3018 IRTemp result = newTemp(Ity_I8);
3019
3020 assign(op1, load(Ity_I8, mkexpr(op1addr)));
3021 op2 = i2;
3022 assign(result, binop(Iop_And8, mkexpr(op1), mkU8(op2)));
3023 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3024 store(mkexpr(op1addr), mkexpr(result));
3025
3026 return "ni";
3027}
3028
3029static HChar *
3030s390_irgen_NIY(UChar i2, IRTemp op1addr)
3031{
3032 IRTemp op1 = newTemp(Ity_I8);
3033 UChar op2;
3034 IRTemp result = newTemp(Ity_I8);
3035
3036 assign(op1, load(Ity_I8, mkexpr(op1addr)));
3037 op2 = i2;
3038 assign(result, binop(Iop_And8, mkexpr(op1), mkU8(op2)));
3039 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3040 store(mkexpr(op1addr), mkexpr(result));
3041
3042 return "niy";
3043}
3044
3045static HChar *
3046s390_irgen_NIHF(UChar r1, UInt i2)
3047{
3048 IRTemp op1 = newTemp(Ity_I32);
3049 UInt op2;
3050 IRTemp result = newTemp(Ity_I32);
3051
3052 assign(op1, get_gpr_w0(r1));
3053 op2 = i2;
3054 assign(result, binop(Iop_And32, mkexpr(op1), mkU32(op2)));
3055 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3056 put_gpr_w0(r1, mkexpr(result));
3057
3058 return "nihf";
3059}
3060
3061static HChar *
3062s390_irgen_NIHH(UChar r1, UShort i2)
3063{
3064 IRTemp op1 = newTemp(Ity_I16);
3065 UShort op2;
3066 IRTemp result = newTemp(Ity_I16);
3067
3068 assign(op1, get_gpr_hw0(r1));
3069 op2 = i2;
3070 assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
3071 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3072 put_gpr_hw0(r1, mkexpr(result));
3073
3074 return "nihh";
3075}
3076
3077static HChar *
3078s390_irgen_NIHL(UChar r1, UShort i2)
3079{
3080 IRTemp op1 = newTemp(Ity_I16);
3081 UShort op2;
3082 IRTemp result = newTemp(Ity_I16);
3083
3084 assign(op1, get_gpr_hw1(r1));
3085 op2 = i2;
3086 assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
3087 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3088 put_gpr_hw1(r1, mkexpr(result));
3089
3090 return "nihl";
3091}
3092
3093static HChar *
3094s390_irgen_NILF(UChar r1, UInt i2)
3095{
3096 IRTemp op1 = newTemp(Ity_I32);
3097 UInt op2;
3098 IRTemp result = newTemp(Ity_I32);
3099
3100 assign(op1, get_gpr_w1(r1));
3101 op2 = i2;
3102 assign(result, binop(Iop_And32, mkexpr(op1), mkU32(op2)));
3103 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3104 put_gpr_w1(r1, mkexpr(result));
3105
3106 return "nilf";
3107}
3108
3109static HChar *
3110s390_irgen_NILH(UChar r1, UShort i2)
3111{
3112 IRTemp op1 = newTemp(Ity_I16);
3113 UShort op2;
3114 IRTemp result = newTemp(Ity_I16);
3115
3116 assign(op1, get_gpr_hw2(r1));
3117 op2 = i2;
3118 assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
3119 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3120 put_gpr_hw2(r1, mkexpr(result));
3121
3122 return "nilh";
3123}
3124
3125static HChar *
3126s390_irgen_NILL(UChar r1, UShort i2)
3127{
3128 IRTemp op1 = newTemp(Ity_I16);
3129 UShort op2;
3130 IRTemp result = newTemp(Ity_I16);
3131
3132 assign(op1, get_gpr_hw3(r1));
3133 op2 = i2;
3134 assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
3135 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3136 put_gpr_hw3(r1, mkexpr(result));
3137
3138 return "nill";
3139}
3140
3141static HChar *
3142s390_irgen_BASR(UChar r1, UChar r2)
3143{
3144 IRTemp target = newTemp(Ity_I64);
3145
3146 if (r2 == 0) {
3147 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 2ULL));
3148 } else {
3149 if (r1 != r2) {
3150 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 2ULL));
3151 call_function(get_gpr_dw0(r2));
3152 } else {
3153 assign(target, get_gpr_dw0(r2));
3154 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 2ULL));
3155 call_function(mkexpr(target));
3156 }
3157 }
3158
3159 return "basr";
3160}
3161
3162static HChar *
3163s390_irgen_BAS(UChar r1, IRTemp op2addr)
3164{
3165 IRTemp target = newTemp(Ity_I64);
3166
3167 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 4ULL));
3168 assign(target, mkexpr(op2addr));
3169 call_function(mkexpr(target));
3170
3171 return "bas";
3172}
3173
3174static HChar *
3175s390_irgen_BCR(UChar r1, UChar r2)
3176{
3177 IRTemp cond = newTemp(Ity_I32);
3178
sewardja52e37e2011-04-28 18:48:06 +00003179 if (r2 == 0 && (r1 >= 14)) { /* serialization */
3180 stmt(IRStmt_MBE(Imbe_Fence));
3181 }
3182
sewardj2019a972011-03-07 16:04:07 +00003183 if ((r2 == 0) || (r1 == 0)) {
3184 } else {
3185 if (r1 == 15) {
3186 return_from_function(get_gpr_dw0(r2));
3187 } else {
3188 assign(cond, s390_call_calculate_cond(r1));
florianf321da72012-07-21 20:32:57 +00003189 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3190 get_gpr_dw0(r2));
sewardj2019a972011-03-07 16:04:07 +00003191 }
3192 }
sewardj7ee97522011-05-09 21:45:04 +00003193 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00003194 s390_disasm(ENC2(XMNM, GPR), S390_XMNM_BCR, r1, r2);
3195
3196 return "bcr";
3197}
3198
3199static HChar *
3200s390_irgen_BC(UChar r1, UChar x2, UChar b2, UShort d2, IRTemp op2addr)
3201{
3202 IRTemp cond = newTemp(Ity_I32);
3203
3204 if (r1 == 0) {
3205 } else {
3206 if (r1 == 15) {
3207 always_goto(mkexpr(op2addr));
3208 } else {
3209 assign(cond, s390_call_calculate_cond(r1));
florianf321da72012-07-21 20:32:57 +00003210 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3211 mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003212 }
3213 }
sewardj7ee97522011-05-09 21:45:04 +00003214 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00003215 s390_disasm(ENC2(XMNM, UDXB), S390_XMNM_BC, r1, d2, x2, b2);
3216
3217 return "bc";
3218}
3219
3220static HChar *
3221s390_irgen_BCTR(UChar r1, UChar r2)
3222{
3223 put_gpr_w1(r1, binop(Iop_Sub32, get_gpr_w1(r1), mkU32(1)));
3224 if (r2 != 0) {
florianf321da72012-07-21 20:32:57 +00003225 if_condition_goto_computed(binop(Iop_CmpNE32, get_gpr_w1(r1), mkU32(0)),
3226 get_gpr_dw0(r2));
sewardj2019a972011-03-07 16:04:07 +00003227 }
3228
3229 return "bctr";
3230}
3231
3232static HChar *
3233s390_irgen_BCTGR(UChar r1, UChar r2)
3234{
3235 put_gpr_dw0(r1, binop(Iop_Sub64, get_gpr_dw0(r1), mkU64(1)));
3236 if (r2 != 0) {
florianf321da72012-07-21 20:32:57 +00003237 if_condition_goto_computed(binop(Iop_CmpNE64, get_gpr_dw0(r1), mkU64(0)),
3238 get_gpr_dw0(r2));
sewardj2019a972011-03-07 16:04:07 +00003239 }
3240
3241 return "bctgr";
3242}
3243
3244static HChar *
3245s390_irgen_BCT(UChar r1, IRTemp op2addr)
3246{
3247 put_gpr_w1(r1, binop(Iop_Sub32, get_gpr_w1(r1), mkU32(1)));
florianf321da72012-07-21 20:32:57 +00003248 if_condition_goto_computed(binop(Iop_CmpNE32, get_gpr_w1(r1), mkU32(0)),
3249 mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003250
3251 return "bct";
3252}
3253
3254static HChar *
3255s390_irgen_BCTG(UChar r1, IRTemp op2addr)
3256{
3257 put_gpr_dw0(r1, binop(Iop_Sub64, get_gpr_dw0(r1), mkU64(1)));
florianf321da72012-07-21 20:32:57 +00003258 if_condition_goto_computed(binop(Iop_CmpNE64, get_gpr_dw0(r1), mkU64(0)),
3259 mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003260
3261 return "bctg";
3262}
3263
3264static HChar *
3265s390_irgen_BXH(UChar r1, UChar r3, IRTemp op2addr)
3266{
3267 IRTemp value = newTemp(Ity_I32);
3268
3269 assign(value, get_gpr_w1(r3 | 1));
3270 put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
florianf321da72012-07-21 20:32:57 +00003271 if_condition_goto_computed(binop(Iop_CmpLT32S, mkexpr(value),
3272 get_gpr_w1(r1)), mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003273
3274 return "bxh";
3275}
3276
3277static HChar *
3278s390_irgen_BXHG(UChar r1, UChar r3, IRTemp op2addr)
3279{
3280 IRTemp value = newTemp(Ity_I64);
3281
3282 assign(value, get_gpr_dw0(r3 | 1));
3283 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
florianf321da72012-07-21 20:32:57 +00003284 if_condition_goto_computed(binop(Iop_CmpLT64S, mkexpr(value),
3285 get_gpr_dw0(r1)), mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003286
3287 return "bxhg";
3288}
3289
3290static HChar *
3291s390_irgen_BXLE(UChar r1, UChar r3, IRTemp op2addr)
3292{
3293 IRTemp value = newTemp(Ity_I32);
3294
3295 assign(value, get_gpr_w1(r3 | 1));
3296 put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
florianf321da72012-07-21 20:32:57 +00003297 if_condition_goto_computed(binop(Iop_CmpLE32S, get_gpr_w1(r1),
3298 mkexpr(value)), mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003299
3300 return "bxle";
3301}
3302
3303static HChar *
3304s390_irgen_BXLEG(UChar r1, UChar r3, IRTemp op2addr)
3305{
3306 IRTemp value = newTemp(Ity_I64);
3307
3308 assign(value, get_gpr_dw0(r3 | 1));
3309 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
florianf321da72012-07-21 20:32:57 +00003310 if_condition_goto_computed(binop(Iop_CmpLE64S, get_gpr_dw0(r1),
3311 mkexpr(value)), mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003312
3313 return "bxleg";
3314}
3315
3316static HChar *
3317s390_irgen_BRAS(UChar r1, UShort i2)
3318{
3319 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 4ULL));
floriana64c2432011-07-16 02:11:50 +00003320 call_function_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
sewardj2019a972011-03-07 16:04:07 +00003321
3322 return "bras";
3323}
3324
3325static HChar *
3326s390_irgen_BRASL(UChar r1, UInt i2)
3327{
3328 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 6ULL));
floriana64c2432011-07-16 02:11:50 +00003329 call_function_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1));
sewardj2019a972011-03-07 16:04:07 +00003330
3331 return "brasl";
3332}
3333
3334static HChar *
3335s390_irgen_BRC(UChar r1, UShort i2)
3336{
3337 IRTemp cond = newTemp(Ity_I32);
3338
3339 if (r1 == 0) {
3340 } else {
3341 if (r1 == 15) {
floriana64c2432011-07-16 02:11:50 +00003342 always_goto_and_chase(
3343 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
sewardj2019a972011-03-07 16:04:07 +00003344 } else {
3345 assign(cond, s390_call_calculate_cond(r1));
3346 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3347 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3348
3349 }
3350 }
sewardj7ee97522011-05-09 21:45:04 +00003351 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00003352 s390_disasm(ENC2(XMNM, PCREL), S390_XMNM_BRC, r1, (Int)(Short)i2);
3353
3354 return "brc";
3355}
3356
3357static HChar *
3358s390_irgen_BRCL(UChar r1, UInt i2)
3359{
3360 IRTemp cond = newTemp(Ity_I32);
3361
3362 if (r1 == 0) {
3363 } else {
3364 if (r1 == 15) {
floriana64c2432011-07-16 02:11:50 +00003365 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1));
sewardj2019a972011-03-07 16:04:07 +00003366 } else {
3367 assign(cond, s390_call_calculate_cond(r1));
3368 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3369 guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1));
3370 }
3371 }
sewardj7ee97522011-05-09 21:45:04 +00003372 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00003373 s390_disasm(ENC2(XMNM, PCREL), S390_XMNM_BRCL, r1, i2);
3374
3375 return "brcl";
3376}
3377
3378static HChar *
3379s390_irgen_BRCT(UChar r1, UShort i2)
3380{
3381 put_gpr_w1(r1, binop(Iop_Sub32, get_gpr_w1(r1), mkU32(1)));
3382 if_condition_goto(binop(Iop_CmpNE32, get_gpr_w1(r1), mkU32(0)),
3383 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3384
3385 return "brct";
3386}
3387
3388static HChar *
3389s390_irgen_BRCTG(UChar r1, UShort i2)
3390{
3391 put_gpr_dw0(r1, binop(Iop_Sub64, get_gpr_dw0(r1), mkU64(1)));
3392 if_condition_goto(binop(Iop_CmpNE64, get_gpr_dw0(r1), mkU64(0)),
3393 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3394
3395 return "brctg";
3396}
3397
3398static HChar *
3399s390_irgen_BRXH(UChar r1, UChar r3, UShort i2)
3400{
3401 IRTemp value = newTemp(Ity_I32);
3402
3403 assign(value, get_gpr_w1(r3 | 1));
3404 put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
3405 if_condition_goto(binop(Iop_CmpLT32S, mkexpr(value), get_gpr_w1(r1)),
3406 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3407
3408 return "brxh";
3409}
3410
3411static HChar *
3412s390_irgen_BRXHG(UChar r1, UChar r3, UShort i2)
3413{
3414 IRTemp value = newTemp(Ity_I64);
3415
3416 assign(value, get_gpr_dw0(r3 | 1));
3417 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
3418 if_condition_goto(binop(Iop_CmpLT64S, mkexpr(value), get_gpr_dw0(r1)),
3419 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3420
3421 return "brxhg";
3422}
3423
3424static HChar *
3425s390_irgen_BRXLE(UChar r1, UChar r3, UShort i2)
3426{
3427 IRTemp value = newTemp(Ity_I32);
3428
3429 assign(value, get_gpr_w1(r3 | 1));
3430 put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
3431 if_condition_goto(binop(Iop_CmpLE32S, get_gpr_w1(r1), mkexpr(value)),
3432 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3433
3434 return "brxle";
3435}
3436
3437static HChar *
3438s390_irgen_BRXLG(UChar r1, UChar r3, UShort i2)
3439{
3440 IRTemp value = newTemp(Ity_I64);
3441
3442 assign(value, get_gpr_dw0(r3 | 1));
3443 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
3444 if_condition_goto(binop(Iop_CmpLE64S, get_gpr_dw0(r1), mkexpr(value)),
3445 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3446
3447 return "brxlg";
3448}
3449
3450static HChar *
3451s390_irgen_CR(UChar r1, UChar r2)
3452{
3453 IRTemp op1 = newTemp(Ity_I32);
3454 IRTemp op2 = newTemp(Ity_I32);
3455
3456 assign(op1, get_gpr_w1(r1));
3457 assign(op2, get_gpr_w1(r2));
3458 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3459
3460 return "cr";
3461}
3462
3463static HChar *
3464s390_irgen_CGR(UChar r1, UChar r2)
3465{
3466 IRTemp op1 = newTemp(Ity_I64);
3467 IRTemp op2 = newTemp(Ity_I64);
3468
3469 assign(op1, get_gpr_dw0(r1));
3470 assign(op2, get_gpr_dw0(r2));
3471 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3472
3473 return "cgr";
3474}
3475
3476static HChar *
3477s390_irgen_CGFR(UChar r1, UChar r2)
3478{
3479 IRTemp op1 = newTemp(Ity_I64);
3480 IRTemp op2 = newTemp(Ity_I64);
3481
3482 assign(op1, get_gpr_dw0(r1));
3483 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
3484 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3485
3486 return "cgfr";
3487}
3488
3489static HChar *
3490s390_irgen_C(UChar r1, IRTemp op2addr)
3491{
3492 IRTemp op1 = newTemp(Ity_I32);
3493 IRTemp op2 = newTemp(Ity_I32);
3494
3495 assign(op1, get_gpr_w1(r1));
3496 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3497 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3498
3499 return "c";
3500}
3501
3502static HChar *
3503s390_irgen_CY(UChar r1, IRTemp op2addr)
3504{
3505 IRTemp op1 = newTemp(Ity_I32);
3506 IRTemp op2 = newTemp(Ity_I32);
3507
3508 assign(op1, get_gpr_w1(r1));
3509 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3510 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3511
3512 return "cy";
3513}
3514
3515static HChar *
3516s390_irgen_CG(UChar r1, IRTemp op2addr)
3517{
3518 IRTemp op1 = newTemp(Ity_I64);
3519 IRTemp op2 = newTemp(Ity_I64);
3520
3521 assign(op1, get_gpr_dw0(r1));
3522 assign(op2, load(Ity_I64, mkexpr(op2addr)));
3523 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3524
3525 return "cg";
3526}
3527
3528static HChar *
3529s390_irgen_CGF(UChar r1, IRTemp op2addr)
3530{
3531 IRTemp op1 = newTemp(Ity_I64);
3532 IRTemp op2 = newTemp(Ity_I64);
3533
3534 assign(op1, get_gpr_dw0(r1));
3535 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
3536 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3537
3538 return "cgf";
3539}
3540
3541static HChar *
3542s390_irgen_CFI(UChar r1, UInt i2)
3543{
3544 IRTemp op1 = newTemp(Ity_I32);
3545 Int op2;
3546
3547 assign(op1, get_gpr_w1(r1));
3548 op2 = (Int)i2;
3549 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
3550 mkU32((UInt)op2)));
3551
3552 return "cfi";
3553}
3554
3555static HChar *
3556s390_irgen_CGFI(UChar r1, UInt i2)
3557{
3558 IRTemp op1 = newTemp(Ity_I64);
3559 Long op2;
3560
3561 assign(op1, get_gpr_dw0(r1));
3562 op2 = (Long)(Int)i2;
3563 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I64,
3564 mkU64((ULong)op2)));
3565
3566 return "cgfi";
3567}
3568
3569static HChar *
3570s390_irgen_CRL(UChar r1, UInt i2)
3571{
3572 IRTemp op1 = newTemp(Ity_I32);
3573 IRTemp op2 = newTemp(Ity_I32);
3574
3575 assign(op1, get_gpr_w1(r1));
3576 assign(op2, load(Ity_I32, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
3577 i2 << 1))));
3578 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3579
3580 return "crl";
3581}
3582
3583static HChar *
3584s390_irgen_CGRL(UChar r1, UInt i2)
3585{
3586 IRTemp op1 = newTemp(Ity_I64);
3587 IRTemp op2 = newTemp(Ity_I64);
3588
3589 assign(op1, get_gpr_dw0(r1));
3590 assign(op2, load(Ity_I64, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
3591 i2 << 1))));
3592 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3593
3594 return "cgrl";
3595}
3596
3597static HChar *
3598s390_irgen_CGFRL(UChar r1, UInt i2)
3599{
3600 IRTemp op1 = newTemp(Ity_I64);
3601 IRTemp op2 = newTemp(Ity_I64);
3602
3603 assign(op1, get_gpr_dw0(r1));
3604 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
3605 ((ULong)(Long)(Int)i2 << 1)))));
3606 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3607
3608 return "cgfrl";
3609}
3610
3611static HChar *
3612s390_irgen_CRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
3613{
3614 IRTemp op1 = newTemp(Ity_I32);
3615 IRTemp op2 = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00003616 IRTemp cond = newTemp(Ity_I32);
3617
3618 if (m3 == 0) {
3619 } else {
3620 if (m3 == 14) {
3621 always_goto(mkexpr(op4addr));
3622 } else {
3623 assign(op1, get_gpr_w1(r1));
3624 assign(op2, get_gpr_w1(r2));
florianff9613f2012-05-12 15:26:44 +00003625 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
3626 op1, op2));
florianf321da72012-07-21 20:32:57 +00003627 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond),
3628 mkU32(0)), mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00003629 }
3630 }
3631
3632 return "crb";
3633}
3634
3635static HChar *
3636s390_irgen_CGRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
3637{
3638 IRTemp op1 = newTemp(Ity_I64);
3639 IRTemp op2 = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00003640 IRTemp cond = newTemp(Ity_I32);
3641
3642 if (m3 == 0) {
3643 } else {
3644 if (m3 == 14) {
3645 always_goto(mkexpr(op4addr));
3646 } else {
3647 assign(op1, get_gpr_dw0(r1));
3648 assign(op2, get_gpr_dw0(r2));
florianff9613f2012-05-12 15:26:44 +00003649 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
3650 op1, op2));
florianf321da72012-07-21 20:32:57 +00003651 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond),
3652 mkU32(0)), mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00003653 }
3654 }
3655
3656 return "cgrb";
3657}
3658
3659static HChar *
3660s390_irgen_CRJ(UChar r1, UChar r2, UShort i4, UChar m3)
3661{
3662 IRTemp op1 = newTemp(Ity_I32);
3663 IRTemp op2 = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00003664 IRTemp cond = newTemp(Ity_I32);
3665
3666 if (m3 == 0) {
3667 } else {
3668 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00003669 always_goto_and_chase(
3670 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00003671 } else {
3672 assign(op1, get_gpr_w1(r1));
3673 assign(op2, get_gpr_w1(r2));
florianff9613f2012-05-12 15:26:44 +00003674 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
3675 op1, op2));
sewardj2019a972011-03-07 16:04:07 +00003676 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3677 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
3678
3679 }
3680 }
3681
3682 return "crj";
3683}
3684
3685static HChar *
3686s390_irgen_CGRJ(UChar r1, UChar r2, UShort i4, UChar m3)
3687{
3688 IRTemp op1 = newTemp(Ity_I64);
3689 IRTemp op2 = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00003690 IRTemp cond = newTemp(Ity_I32);
3691
3692 if (m3 == 0) {
3693 } else {
3694 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00003695 always_goto_and_chase(
3696 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00003697 } else {
3698 assign(op1, get_gpr_dw0(r1));
3699 assign(op2, get_gpr_dw0(r2));
florianff9613f2012-05-12 15:26:44 +00003700 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
3701 op1, op2));
sewardj2019a972011-03-07 16:04:07 +00003702 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3703 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
3704
3705 }
3706 }
3707
3708 return "cgrj";
3709}
3710
3711static HChar *
3712s390_irgen_CIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
3713{
3714 IRTemp op1 = newTemp(Ity_I32);
3715 Int op2;
sewardj2019a972011-03-07 16:04:07 +00003716 IRTemp cond = newTemp(Ity_I32);
3717
3718 if (m3 == 0) {
3719 } else {
3720 if (m3 == 14) {
3721 always_goto(mkexpr(op4addr));
3722 } else {
3723 assign(op1, get_gpr_w1(r1));
3724 op2 = (Int)(Char)i2;
florianff9613f2012-05-12 15:26:44 +00003725 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
3726 mktemp(Ity_I32, mkU32((UInt)op2))));
florianf321da72012-07-21 20:32:57 +00003727 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3728 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00003729 }
3730 }
3731
3732 return "cib";
3733}
3734
3735static HChar *
3736s390_irgen_CGIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
3737{
3738 IRTemp op1 = newTemp(Ity_I64);
3739 Long op2;
sewardj2019a972011-03-07 16:04:07 +00003740 IRTemp cond = newTemp(Ity_I32);
3741
3742 if (m3 == 0) {
3743 } else {
3744 if (m3 == 14) {
3745 always_goto(mkexpr(op4addr));
3746 } else {
3747 assign(op1, get_gpr_dw0(r1));
3748 op2 = (Long)(Char)i2;
florianff9613f2012-05-12 15:26:44 +00003749 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
3750 mktemp(Ity_I64, mkU64((ULong)op2))));
florianf321da72012-07-21 20:32:57 +00003751 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3752 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00003753 }
3754 }
3755
3756 return "cgib";
3757}
3758
3759static HChar *
3760s390_irgen_CIJ(UChar r1, UChar m3, UShort i4, UChar i2)
3761{
3762 IRTemp op1 = newTemp(Ity_I32);
3763 Int op2;
sewardj2019a972011-03-07 16:04:07 +00003764 IRTemp cond = newTemp(Ity_I32);
3765
3766 if (m3 == 0) {
3767 } else {
3768 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00003769 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00003770 } else {
3771 assign(op1, get_gpr_w1(r1));
3772 op2 = (Int)(Char)i2;
florianff9613f2012-05-12 15:26:44 +00003773 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
3774 mktemp(Ity_I32, mkU32((UInt)op2))));
sewardj2019a972011-03-07 16:04:07 +00003775 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3776 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
3777
3778 }
3779 }
3780
3781 return "cij";
3782}
3783
3784static HChar *
3785s390_irgen_CGIJ(UChar r1, UChar m3, UShort i4, UChar i2)
3786{
3787 IRTemp op1 = newTemp(Ity_I64);
3788 Long op2;
sewardj2019a972011-03-07 16:04:07 +00003789 IRTemp cond = newTemp(Ity_I32);
3790
3791 if (m3 == 0) {
3792 } else {
3793 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00003794 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00003795 } else {
3796 assign(op1, get_gpr_dw0(r1));
3797 op2 = (Long)(Char)i2;
florianff9613f2012-05-12 15:26:44 +00003798 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
3799 mktemp(Ity_I64, mkU64((ULong)op2))));
sewardj2019a972011-03-07 16:04:07 +00003800 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3801 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
3802
3803 }
3804 }
3805
3806 return "cgij";
3807}
3808
3809static HChar *
3810s390_irgen_CH(UChar r1, IRTemp op2addr)
3811{
3812 IRTemp op1 = newTemp(Ity_I32);
3813 IRTemp op2 = newTemp(Ity_I32);
3814
3815 assign(op1, get_gpr_w1(r1));
3816 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
3817 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3818
3819 return "ch";
3820}
3821
3822static HChar *
3823s390_irgen_CHY(UChar r1, IRTemp op2addr)
3824{
3825 IRTemp op1 = newTemp(Ity_I32);
3826 IRTemp op2 = newTemp(Ity_I32);
3827
3828 assign(op1, get_gpr_w1(r1));
3829 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
3830 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3831
3832 return "chy";
3833}
3834
3835static HChar *
3836s390_irgen_CGH(UChar r1, IRTemp op2addr)
3837{
3838 IRTemp op1 = newTemp(Ity_I64);
3839 IRTemp op2 = newTemp(Ity_I64);
3840
3841 assign(op1, get_gpr_dw0(r1));
3842 assign(op2, unop(Iop_16Sto64, load(Ity_I16, mkexpr(op2addr))));
3843 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3844
3845 return "cgh";
3846}
3847
3848static HChar *
3849s390_irgen_CHI(UChar r1, UShort i2)
3850{
3851 IRTemp op1 = newTemp(Ity_I32);
3852 Int op2;
3853
3854 assign(op1, get_gpr_w1(r1));
3855 op2 = (Int)(Short)i2;
3856 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
3857 mkU32((UInt)op2)));
3858
3859 return "chi";
3860}
3861
3862static HChar *
3863s390_irgen_CGHI(UChar r1, UShort i2)
3864{
3865 IRTemp op1 = newTemp(Ity_I64);
3866 Long op2;
3867
3868 assign(op1, get_gpr_dw0(r1));
3869 op2 = (Long)(Short)i2;
3870 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I64,
3871 mkU64((ULong)op2)));
3872
3873 return "cghi";
3874}
3875
3876static HChar *
3877s390_irgen_CHHSI(UShort i2, IRTemp op1addr)
3878{
3879 IRTemp op1 = newTemp(Ity_I16);
3880 Short op2;
3881
3882 assign(op1, load(Ity_I16, mkexpr(op1addr)));
3883 op2 = (Short)i2;
3884 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I16,
3885 mkU16((UShort)op2)));
3886
3887 return "chhsi";
3888}
3889
3890static HChar *
3891s390_irgen_CHSI(UShort i2, IRTemp op1addr)
3892{
3893 IRTemp op1 = newTemp(Ity_I32);
3894 Int op2;
3895
3896 assign(op1, load(Ity_I32, mkexpr(op1addr)));
3897 op2 = (Int)(Short)i2;
3898 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
3899 mkU32((UInt)op2)));
3900
3901 return "chsi";
3902}
3903
3904static HChar *
3905s390_irgen_CGHSI(UShort i2, IRTemp op1addr)
3906{
3907 IRTemp op1 = newTemp(Ity_I64);
3908 Long op2;
3909
3910 assign(op1, load(Ity_I64, mkexpr(op1addr)));
3911 op2 = (Long)(Short)i2;
3912 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I64,
3913 mkU64((ULong)op2)));
3914
3915 return "cghsi";
3916}
3917
3918static HChar *
3919s390_irgen_CHRL(UChar r1, UInt i2)
3920{
3921 IRTemp op1 = newTemp(Ity_I32);
3922 IRTemp op2 = newTemp(Ity_I32);
3923
3924 assign(op1, get_gpr_w1(r1));
3925 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
3926 ((ULong)(Long)(Int)i2 << 1)))));
3927 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3928
3929 return "chrl";
3930}
3931
3932static HChar *
3933s390_irgen_CGHRL(UChar r1, UInt i2)
3934{
3935 IRTemp op1 = newTemp(Ity_I64);
3936 IRTemp op2 = newTemp(Ity_I64);
3937
3938 assign(op1, get_gpr_dw0(r1));
3939 assign(op2, unop(Iop_16Sto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
3940 ((ULong)(Long)(Int)i2 << 1)))));
3941 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3942
3943 return "cghrl";
3944}
3945
3946static HChar *
3947s390_irgen_CHHR(UChar r1, UChar r2)
3948{
3949 IRTemp op1 = newTemp(Ity_I32);
3950 IRTemp op2 = newTemp(Ity_I32);
3951
3952 assign(op1, get_gpr_w0(r1));
3953 assign(op2, get_gpr_w0(r2));
3954 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3955
3956 return "chhr";
3957}
3958
3959static HChar *
3960s390_irgen_CHLR(UChar r1, UChar r2)
3961{
3962 IRTemp op1 = newTemp(Ity_I32);
3963 IRTemp op2 = newTemp(Ity_I32);
3964
3965 assign(op1, get_gpr_w0(r1));
3966 assign(op2, get_gpr_w1(r2));
3967 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3968
3969 return "chlr";
3970}
3971
3972static HChar *
3973s390_irgen_CHF(UChar r1, IRTemp op2addr)
3974{
3975 IRTemp op1 = newTemp(Ity_I32);
3976 IRTemp op2 = newTemp(Ity_I32);
3977
3978 assign(op1, get_gpr_w0(r1));
3979 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3980 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3981
3982 return "chf";
3983}
3984
3985static HChar *
3986s390_irgen_CIH(UChar r1, UInt i2)
3987{
3988 IRTemp op1 = newTemp(Ity_I32);
3989 Int op2;
3990
3991 assign(op1, get_gpr_w0(r1));
3992 op2 = (Int)i2;
3993 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
3994 mkU32((UInt)op2)));
3995
3996 return "cih";
3997}
3998
3999static HChar *
4000s390_irgen_CLR(UChar r1, UChar r2)
4001{
4002 IRTemp op1 = newTemp(Ity_I32);
4003 IRTemp op2 = newTemp(Ity_I32);
4004
4005 assign(op1, get_gpr_w1(r1));
4006 assign(op2, get_gpr_w1(r2));
4007 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4008
4009 return "clr";
4010}
4011
4012static HChar *
4013s390_irgen_CLGR(UChar r1, UChar r2)
4014{
4015 IRTemp op1 = newTemp(Ity_I64);
4016 IRTemp op2 = newTemp(Ity_I64);
4017
4018 assign(op1, get_gpr_dw0(r1));
4019 assign(op2, get_gpr_dw0(r2));
4020 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4021
4022 return "clgr";
4023}
4024
4025static HChar *
4026s390_irgen_CLGFR(UChar r1, UChar r2)
4027{
4028 IRTemp op1 = newTemp(Ity_I64);
4029 IRTemp op2 = newTemp(Ity_I64);
4030
4031 assign(op1, get_gpr_dw0(r1));
4032 assign(op2, unop(Iop_32Uto64, get_gpr_w1(r2)));
4033 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4034
4035 return "clgfr";
4036}
4037
4038static HChar *
4039s390_irgen_CL(UChar r1, IRTemp op2addr)
4040{
4041 IRTemp op1 = newTemp(Ity_I32);
4042 IRTemp op2 = newTemp(Ity_I32);
4043
4044 assign(op1, get_gpr_w1(r1));
4045 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4046 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4047
4048 return "cl";
4049}
4050
4051static HChar *
4052s390_irgen_CLY(UChar r1, IRTemp op2addr)
4053{
4054 IRTemp op1 = newTemp(Ity_I32);
4055 IRTemp op2 = newTemp(Ity_I32);
4056
4057 assign(op1, get_gpr_w1(r1));
4058 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4059 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4060
4061 return "cly";
4062}
4063
4064static HChar *
4065s390_irgen_CLG(UChar r1, IRTemp op2addr)
4066{
4067 IRTemp op1 = newTemp(Ity_I64);
4068 IRTemp op2 = newTemp(Ity_I64);
4069
4070 assign(op1, get_gpr_dw0(r1));
4071 assign(op2, load(Ity_I64, mkexpr(op2addr)));
4072 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4073
4074 return "clg";
4075}
4076
4077static HChar *
4078s390_irgen_CLGF(UChar r1, IRTemp op2addr)
4079{
4080 IRTemp op1 = newTemp(Ity_I64);
4081 IRTemp op2 = newTemp(Ity_I64);
4082
4083 assign(op1, get_gpr_dw0(r1));
4084 assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
4085 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4086
4087 return "clgf";
4088}
4089
4090static HChar *
4091s390_irgen_CLFI(UChar r1, UInt i2)
4092{
4093 IRTemp op1 = newTemp(Ity_I32);
4094 UInt op2;
4095
4096 assign(op1, get_gpr_w1(r1));
4097 op2 = i2;
4098 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I32,
4099 mkU32(op2)));
4100
4101 return "clfi";
4102}
4103
4104static HChar *
4105s390_irgen_CLGFI(UChar r1, UInt i2)
4106{
4107 IRTemp op1 = newTemp(Ity_I64);
4108 ULong op2;
4109
4110 assign(op1, get_gpr_dw0(r1));
4111 op2 = (ULong)i2;
4112 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I64,
4113 mkU64(op2)));
4114
4115 return "clgfi";
4116}
4117
4118static HChar *
4119s390_irgen_CLI(UChar i2, IRTemp op1addr)
4120{
4121 IRTemp op1 = newTemp(Ity_I8);
4122 UChar op2;
4123
4124 assign(op1, load(Ity_I8, mkexpr(op1addr)));
4125 op2 = i2;
4126 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I8,
4127 mkU8(op2)));
4128
4129 return "cli";
4130}
4131
4132static HChar *
4133s390_irgen_CLIY(UChar i2, IRTemp op1addr)
4134{
4135 IRTemp op1 = newTemp(Ity_I8);
4136 UChar op2;
4137
4138 assign(op1, load(Ity_I8, mkexpr(op1addr)));
4139 op2 = i2;
4140 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I8,
4141 mkU8(op2)));
4142
4143 return "cliy";
4144}
4145
4146static HChar *
4147s390_irgen_CLFHSI(UShort i2, IRTemp op1addr)
4148{
4149 IRTemp op1 = newTemp(Ity_I32);
4150 UInt op2;
4151
4152 assign(op1, load(Ity_I32, mkexpr(op1addr)));
4153 op2 = (UInt)i2;
4154 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I32,
4155 mkU32(op2)));
4156
4157 return "clfhsi";
4158}
4159
4160static HChar *
4161s390_irgen_CLGHSI(UShort i2, IRTemp op1addr)
4162{
4163 IRTemp op1 = newTemp(Ity_I64);
4164 ULong op2;
4165
4166 assign(op1, load(Ity_I64, mkexpr(op1addr)));
4167 op2 = (ULong)i2;
4168 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I64,
4169 mkU64(op2)));
4170
4171 return "clghsi";
4172}
4173
4174static HChar *
4175s390_irgen_CLHHSI(UShort i2, IRTemp op1addr)
4176{
4177 IRTemp op1 = newTemp(Ity_I16);
4178 UShort op2;
4179
4180 assign(op1, load(Ity_I16, mkexpr(op1addr)));
4181 op2 = i2;
4182 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I16,
4183 mkU16(op2)));
4184
4185 return "clhhsi";
4186}
4187
4188static HChar *
4189s390_irgen_CLRL(UChar r1, UInt i2)
4190{
4191 IRTemp op1 = newTemp(Ity_I32);
4192 IRTemp op2 = newTemp(Ity_I32);
4193
4194 assign(op1, get_gpr_w1(r1));
4195 assign(op2, load(Ity_I32, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
4196 i2 << 1))));
4197 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4198
4199 return "clrl";
4200}
4201
4202static HChar *
4203s390_irgen_CLGRL(UChar r1, UInt i2)
4204{
4205 IRTemp op1 = newTemp(Ity_I64);
4206 IRTemp op2 = newTemp(Ity_I64);
4207
4208 assign(op1, get_gpr_dw0(r1));
4209 assign(op2, load(Ity_I64, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
4210 i2 << 1))));
4211 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4212
4213 return "clgrl";
4214}
4215
4216static HChar *
4217s390_irgen_CLGFRL(UChar r1, UInt i2)
4218{
4219 IRTemp op1 = newTemp(Ity_I64);
4220 IRTemp op2 = newTemp(Ity_I64);
4221
4222 assign(op1, get_gpr_dw0(r1));
4223 assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
4224 ((ULong)(Long)(Int)i2 << 1)))));
4225 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4226
4227 return "clgfrl";
4228}
4229
4230static HChar *
4231s390_irgen_CLHRL(UChar r1, UInt i2)
4232{
4233 IRTemp op1 = newTemp(Ity_I32);
4234 IRTemp op2 = newTemp(Ity_I32);
4235
4236 assign(op1, get_gpr_w1(r1));
4237 assign(op2, unop(Iop_16Uto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
4238 ((ULong)(Long)(Int)i2 << 1)))));
4239 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4240
4241 return "clhrl";
4242}
4243
4244static HChar *
4245s390_irgen_CLGHRL(UChar r1, UInt i2)
4246{
4247 IRTemp op1 = newTemp(Ity_I64);
4248 IRTemp op2 = newTemp(Ity_I64);
4249
4250 assign(op1, get_gpr_dw0(r1));
4251 assign(op2, unop(Iop_16Uto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
4252 ((ULong)(Long)(Int)i2 << 1)))));
4253 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4254
4255 return "clghrl";
4256}
4257
4258static HChar *
4259s390_irgen_CLRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
4260{
4261 IRTemp op1 = newTemp(Ity_I32);
4262 IRTemp op2 = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00004263 IRTemp cond = newTemp(Ity_I32);
4264
4265 if (m3 == 0) {
4266 } else {
4267 if (m3 == 14) {
4268 always_goto(mkexpr(op4addr));
4269 } else {
4270 assign(op1, get_gpr_w1(r1));
4271 assign(op2, get_gpr_w1(r2));
florianff9613f2012-05-12 15:26:44 +00004272 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4273 op1, op2));
florianf321da72012-07-21 20:32:57 +00004274 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4275 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004276 }
4277 }
4278
4279 return "clrb";
4280}
4281
4282static HChar *
4283s390_irgen_CLGRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
4284{
4285 IRTemp op1 = newTemp(Ity_I64);
4286 IRTemp op2 = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00004287 IRTemp cond = newTemp(Ity_I32);
4288
4289 if (m3 == 0) {
4290 } else {
4291 if (m3 == 14) {
4292 always_goto(mkexpr(op4addr));
4293 } else {
4294 assign(op1, get_gpr_dw0(r1));
4295 assign(op2, get_gpr_dw0(r2));
florianff9613f2012-05-12 15:26:44 +00004296 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4297 op1, op2));
florianf321da72012-07-21 20:32:57 +00004298 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4299 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004300 }
4301 }
4302
4303 return "clgrb";
4304}
4305
4306static HChar *
4307s390_irgen_CLRJ(UChar r1, UChar r2, UShort i4, UChar m3)
4308{
4309 IRTemp op1 = newTemp(Ity_I32);
4310 IRTemp op2 = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00004311 IRTemp cond = newTemp(Ity_I32);
4312
4313 if (m3 == 0) {
4314 } else {
4315 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004316 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004317 } else {
4318 assign(op1, get_gpr_w1(r1));
4319 assign(op2, get_gpr_w1(r2));
florianff9613f2012-05-12 15:26:44 +00004320 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4321 op1, op2));
sewardj2019a972011-03-07 16:04:07 +00004322 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4323 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4324
4325 }
4326 }
4327
4328 return "clrj";
4329}
4330
4331static HChar *
4332s390_irgen_CLGRJ(UChar r1, UChar r2, UShort i4, UChar m3)
4333{
4334 IRTemp op1 = newTemp(Ity_I64);
4335 IRTemp op2 = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00004336 IRTemp cond = newTemp(Ity_I32);
4337
4338 if (m3 == 0) {
4339 } else {
4340 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004341 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004342 } else {
4343 assign(op1, get_gpr_dw0(r1));
4344 assign(op2, get_gpr_dw0(r2));
florianff9613f2012-05-12 15:26:44 +00004345 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4346 op1, op2));
sewardj2019a972011-03-07 16:04:07 +00004347 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4348 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4349
4350 }
4351 }
4352
4353 return "clgrj";
4354}
4355
4356static HChar *
4357s390_irgen_CLIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
4358{
4359 IRTemp op1 = newTemp(Ity_I32);
4360 UInt op2;
sewardj2019a972011-03-07 16:04:07 +00004361 IRTemp cond = newTemp(Ity_I32);
4362
4363 if (m3 == 0) {
4364 } else {
4365 if (m3 == 14) {
4366 always_goto(mkexpr(op4addr));
4367 } else {
4368 assign(op1, get_gpr_w1(r1));
4369 op2 = (UInt)i2;
florianff9613f2012-05-12 15:26:44 +00004370 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4371 mktemp(Ity_I32, mkU32(op2))));
florianf321da72012-07-21 20:32:57 +00004372 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4373 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004374 }
4375 }
4376
4377 return "clib";
4378}
4379
4380static HChar *
4381s390_irgen_CLGIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
4382{
4383 IRTemp op1 = newTemp(Ity_I64);
4384 ULong op2;
sewardj2019a972011-03-07 16:04:07 +00004385 IRTemp cond = newTemp(Ity_I32);
4386
4387 if (m3 == 0) {
4388 } else {
4389 if (m3 == 14) {
4390 always_goto(mkexpr(op4addr));
4391 } else {
4392 assign(op1, get_gpr_dw0(r1));
4393 op2 = (ULong)i2;
florianff9613f2012-05-12 15:26:44 +00004394 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4395 mktemp(Ity_I64, mkU64(op2))));
florianf321da72012-07-21 20:32:57 +00004396 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4397 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004398 }
4399 }
4400
4401 return "clgib";
4402}
4403
4404static HChar *
4405s390_irgen_CLIJ(UChar r1, UChar m3, UShort i4, UChar i2)
4406{
4407 IRTemp op1 = newTemp(Ity_I32);
4408 UInt op2;
sewardj2019a972011-03-07 16:04:07 +00004409 IRTemp cond = newTemp(Ity_I32);
4410
4411 if (m3 == 0) {
4412 } else {
4413 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004414 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004415 } else {
4416 assign(op1, get_gpr_w1(r1));
4417 op2 = (UInt)i2;
florianff9613f2012-05-12 15:26:44 +00004418 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4419 mktemp(Ity_I32, mkU32(op2))));
sewardj2019a972011-03-07 16:04:07 +00004420 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4421 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4422
4423 }
4424 }
4425
4426 return "clij";
4427}
4428
4429static HChar *
4430s390_irgen_CLGIJ(UChar r1, UChar m3, UShort i4, UChar i2)
4431{
4432 IRTemp op1 = newTemp(Ity_I64);
4433 ULong op2;
sewardj2019a972011-03-07 16:04:07 +00004434 IRTemp cond = newTemp(Ity_I32);
4435
4436 if (m3 == 0) {
4437 } else {
4438 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004439 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004440 } else {
4441 assign(op1, get_gpr_dw0(r1));
4442 op2 = (ULong)i2;
florianff9613f2012-05-12 15:26:44 +00004443 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4444 mktemp(Ity_I64, mkU64(op2))));
sewardj2019a972011-03-07 16:04:07 +00004445 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4446 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4447
4448 }
4449 }
4450
4451 return "clgij";
4452}
4453
4454static HChar *
4455s390_irgen_CLM(UChar r1, UChar r3, IRTemp op2addr)
4456{
4457 IRTemp op1 = newTemp(Ity_I32);
4458 IRTemp op2 = newTemp(Ity_I32);
4459 IRTemp b0 = newTemp(Ity_I32);
4460 IRTemp b1 = newTemp(Ity_I32);
4461 IRTemp b2 = newTemp(Ity_I32);
4462 IRTemp b3 = newTemp(Ity_I32);
4463 IRTemp c0 = newTemp(Ity_I32);
4464 IRTemp c1 = newTemp(Ity_I32);
4465 IRTemp c2 = newTemp(Ity_I32);
4466 IRTemp c3 = newTemp(Ity_I32);
4467 UChar n;
4468
4469 n = 0;
4470 if ((r3 & 8) != 0) {
4471 assign(b0, unop(Iop_8Uto32, get_gpr_b4(r1)));
4472 assign(c0, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
4473 n = n + 1;
4474 } else {
4475 assign(b0, mkU32(0));
4476 assign(c0, mkU32(0));
4477 }
4478 if ((r3 & 4) != 0) {
4479 assign(b1, unop(Iop_8Uto32, get_gpr_b5(r1)));
4480 assign(c1, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4481 mkU64(n)))));
4482 n = n + 1;
4483 } else {
4484 assign(b1, mkU32(0));
4485 assign(c1, mkU32(0));
4486 }
4487 if ((r3 & 2) != 0) {
4488 assign(b2, unop(Iop_8Uto32, get_gpr_b6(r1)));
4489 assign(c2, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4490 mkU64(n)))));
4491 n = n + 1;
4492 } else {
4493 assign(b2, mkU32(0));
4494 assign(c2, mkU32(0));
4495 }
4496 if ((r3 & 1) != 0) {
4497 assign(b3, unop(Iop_8Uto32, get_gpr_b7(r1)));
4498 assign(c3, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4499 mkU64(n)))));
4500 n = n + 1;
4501 } else {
4502 assign(b3, mkU32(0));
4503 assign(c3, mkU32(0));
4504 }
4505 assign(op1, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4506 mkexpr(b0), mkU8(24)), binop(Iop_Shl32, mkexpr(b1), mkU8(16))),
4507 binop(Iop_Shl32, mkexpr(b2), mkU8(8))), mkexpr(b3)));
4508 assign(op2, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4509 mkexpr(c0), mkU8(24)), binop(Iop_Shl32, mkexpr(c1), mkU8(16))),
4510 binop(Iop_Shl32, mkexpr(c2), mkU8(8))), mkexpr(c3)));
4511 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4512
4513 return "clm";
4514}
4515
4516static HChar *
4517s390_irgen_CLMY(UChar r1, UChar r3, IRTemp op2addr)
4518{
4519 IRTemp op1 = newTemp(Ity_I32);
4520 IRTemp op2 = newTemp(Ity_I32);
4521 IRTemp b0 = newTemp(Ity_I32);
4522 IRTemp b1 = newTemp(Ity_I32);
4523 IRTemp b2 = newTemp(Ity_I32);
4524 IRTemp b3 = newTemp(Ity_I32);
4525 IRTemp c0 = newTemp(Ity_I32);
4526 IRTemp c1 = newTemp(Ity_I32);
4527 IRTemp c2 = newTemp(Ity_I32);
4528 IRTemp c3 = newTemp(Ity_I32);
4529 UChar n;
4530
4531 n = 0;
4532 if ((r3 & 8) != 0) {
4533 assign(b0, unop(Iop_8Uto32, get_gpr_b4(r1)));
4534 assign(c0, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
4535 n = n + 1;
4536 } else {
4537 assign(b0, mkU32(0));
4538 assign(c0, mkU32(0));
4539 }
4540 if ((r3 & 4) != 0) {
4541 assign(b1, unop(Iop_8Uto32, get_gpr_b5(r1)));
4542 assign(c1, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4543 mkU64(n)))));
4544 n = n + 1;
4545 } else {
4546 assign(b1, mkU32(0));
4547 assign(c1, mkU32(0));
4548 }
4549 if ((r3 & 2) != 0) {
4550 assign(b2, unop(Iop_8Uto32, get_gpr_b6(r1)));
4551 assign(c2, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4552 mkU64(n)))));
4553 n = n + 1;
4554 } else {
4555 assign(b2, mkU32(0));
4556 assign(c2, mkU32(0));
4557 }
4558 if ((r3 & 1) != 0) {
4559 assign(b3, unop(Iop_8Uto32, get_gpr_b7(r1)));
4560 assign(c3, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4561 mkU64(n)))));
4562 n = n + 1;
4563 } else {
4564 assign(b3, mkU32(0));
4565 assign(c3, mkU32(0));
4566 }
4567 assign(op1, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4568 mkexpr(b0), mkU8(24)), binop(Iop_Shl32, mkexpr(b1), mkU8(16))),
4569 binop(Iop_Shl32, mkexpr(b2), mkU8(8))), mkexpr(b3)));
4570 assign(op2, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4571 mkexpr(c0), mkU8(24)), binop(Iop_Shl32, mkexpr(c1), mkU8(16))),
4572 binop(Iop_Shl32, mkexpr(c2), mkU8(8))), mkexpr(c3)));
4573 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4574
4575 return "clmy";
4576}
4577
4578static HChar *
4579s390_irgen_CLMH(UChar r1, UChar r3, IRTemp op2addr)
4580{
4581 IRTemp op1 = newTemp(Ity_I32);
4582 IRTemp op2 = newTemp(Ity_I32);
4583 IRTemp b0 = newTemp(Ity_I32);
4584 IRTemp b1 = newTemp(Ity_I32);
4585 IRTemp b2 = newTemp(Ity_I32);
4586 IRTemp b3 = newTemp(Ity_I32);
4587 IRTemp c0 = newTemp(Ity_I32);
4588 IRTemp c1 = newTemp(Ity_I32);
4589 IRTemp c2 = newTemp(Ity_I32);
4590 IRTemp c3 = newTemp(Ity_I32);
4591 UChar n;
4592
4593 n = 0;
4594 if ((r3 & 8) != 0) {
4595 assign(b0, unop(Iop_8Uto32, get_gpr_b0(r1)));
4596 assign(c0, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
4597 n = n + 1;
4598 } else {
4599 assign(b0, mkU32(0));
4600 assign(c0, mkU32(0));
4601 }
4602 if ((r3 & 4) != 0) {
4603 assign(b1, unop(Iop_8Uto32, get_gpr_b1(r1)));
4604 assign(c1, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4605 mkU64(n)))));
4606 n = n + 1;
4607 } else {
4608 assign(b1, mkU32(0));
4609 assign(c1, mkU32(0));
4610 }
4611 if ((r3 & 2) != 0) {
4612 assign(b2, unop(Iop_8Uto32, get_gpr_b2(r1)));
4613 assign(c2, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4614 mkU64(n)))));
4615 n = n + 1;
4616 } else {
4617 assign(b2, mkU32(0));
4618 assign(c2, mkU32(0));
4619 }
4620 if ((r3 & 1) != 0) {
4621 assign(b3, unop(Iop_8Uto32, get_gpr_b3(r1)));
4622 assign(c3, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4623 mkU64(n)))));
4624 n = n + 1;
4625 } else {
4626 assign(b3, mkU32(0));
4627 assign(c3, mkU32(0));
4628 }
4629 assign(op1, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4630 mkexpr(b0), mkU8(24)), binop(Iop_Shl32, mkexpr(b1), mkU8(16))),
4631 binop(Iop_Shl32, mkexpr(b2), mkU8(8))), mkexpr(b3)));
4632 assign(op2, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4633 mkexpr(c0), mkU8(24)), binop(Iop_Shl32, mkexpr(c1), mkU8(16))),
4634 binop(Iop_Shl32, mkexpr(c2), mkU8(8))), mkexpr(c3)));
4635 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4636
4637 return "clmh";
4638}
4639
4640static HChar *
4641s390_irgen_CLHHR(UChar r1, UChar r2)
4642{
4643 IRTemp op1 = newTemp(Ity_I32);
4644 IRTemp op2 = newTemp(Ity_I32);
4645
4646 assign(op1, get_gpr_w0(r1));
4647 assign(op2, get_gpr_w0(r2));
4648 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4649
4650 return "clhhr";
4651}
4652
4653static HChar *
4654s390_irgen_CLHLR(UChar r1, UChar r2)
4655{
4656 IRTemp op1 = newTemp(Ity_I32);
4657 IRTemp op2 = newTemp(Ity_I32);
4658
4659 assign(op1, get_gpr_w0(r1));
4660 assign(op2, get_gpr_w1(r2));
4661 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4662
4663 return "clhlr";
4664}
4665
4666static HChar *
4667s390_irgen_CLHF(UChar r1, IRTemp op2addr)
4668{
4669 IRTemp op1 = newTemp(Ity_I32);
4670 IRTemp op2 = newTemp(Ity_I32);
4671
4672 assign(op1, get_gpr_w0(r1));
4673 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4674 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4675
4676 return "clhf";
4677}
4678
4679static HChar *
4680s390_irgen_CLIH(UChar r1, UInt i2)
4681{
4682 IRTemp op1 = newTemp(Ity_I32);
4683 UInt op2;
4684
4685 assign(op1, get_gpr_w0(r1));
4686 op2 = i2;
4687 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I32,
4688 mkU32(op2)));
4689
4690 return "clih";
4691}
4692
4693static HChar *
4694s390_irgen_CPYA(UChar r1, UChar r2)
4695{
4696 put_ar_w0(r1, get_ar_w0(r2));
sewardj7ee97522011-05-09 21:45:04 +00004697 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00004698 s390_disasm(ENC3(MNM, AR, AR), "cpya", r1, r2);
4699
4700 return "cpya";
4701}
4702
4703static HChar *
4704s390_irgen_XR(UChar r1, UChar r2)
4705{
4706 IRTemp op1 = newTemp(Ity_I32);
4707 IRTemp op2 = newTemp(Ity_I32);
4708 IRTemp result = newTemp(Ity_I32);
4709
4710 if (r1 == r2) {
4711 assign(result, mkU32(0));
4712 } else {
4713 assign(op1, get_gpr_w1(r1));
4714 assign(op2, get_gpr_w1(r2));
4715 assign(result, binop(Iop_Xor32, mkexpr(op1), mkexpr(op2)));
4716 }
4717 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4718 put_gpr_w1(r1, mkexpr(result));
4719
4720 return "xr";
4721}
4722
4723static HChar *
4724s390_irgen_XGR(UChar r1, UChar r2)
4725{
4726 IRTemp op1 = newTemp(Ity_I64);
4727 IRTemp op2 = newTemp(Ity_I64);
4728 IRTemp result = newTemp(Ity_I64);
4729
4730 if (r1 == r2) {
4731 assign(result, mkU64(0));
4732 } else {
4733 assign(op1, get_gpr_dw0(r1));
4734 assign(op2, get_gpr_dw0(r2));
4735 assign(result, binop(Iop_Xor64, mkexpr(op1), mkexpr(op2)));
4736 }
4737 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4738 put_gpr_dw0(r1, mkexpr(result));
4739
4740 return "xgr";
4741}
4742
4743static HChar *
4744s390_irgen_XRK(UChar r3, UChar r1, UChar r2)
4745{
4746 IRTemp op2 = newTemp(Ity_I32);
4747 IRTemp op3 = newTemp(Ity_I32);
4748 IRTemp result = newTemp(Ity_I32);
4749
4750 assign(op2, get_gpr_w1(r2));
4751 assign(op3, get_gpr_w1(r3));
4752 assign(result, binop(Iop_Xor32, mkexpr(op2), mkexpr(op3)));
4753 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4754 put_gpr_w1(r1, mkexpr(result));
4755
4756 return "xrk";
4757}
4758
4759static HChar *
4760s390_irgen_XGRK(UChar r3, UChar r1, UChar r2)
4761{
4762 IRTemp op2 = newTemp(Ity_I64);
4763 IRTemp op3 = newTemp(Ity_I64);
4764 IRTemp result = newTemp(Ity_I64);
4765
4766 assign(op2, get_gpr_dw0(r2));
4767 assign(op3, get_gpr_dw0(r3));
4768 assign(result, binop(Iop_Xor64, mkexpr(op2), mkexpr(op3)));
4769 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4770 put_gpr_dw0(r1, mkexpr(result));
4771
4772 return "xgrk";
4773}
4774
4775static HChar *
4776s390_irgen_X(UChar r1, IRTemp op2addr)
4777{
4778 IRTemp op1 = newTemp(Ity_I32);
4779 IRTemp op2 = newTemp(Ity_I32);
4780 IRTemp result = newTemp(Ity_I32);
4781
4782 assign(op1, get_gpr_w1(r1));
4783 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4784 assign(result, binop(Iop_Xor32, mkexpr(op1), mkexpr(op2)));
4785 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4786 put_gpr_w1(r1, mkexpr(result));
4787
4788 return "x";
4789}
4790
4791static HChar *
4792s390_irgen_XY(UChar r1, IRTemp op2addr)
4793{
4794 IRTemp op1 = newTemp(Ity_I32);
4795 IRTemp op2 = newTemp(Ity_I32);
4796 IRTemp result = newTemp(Ity_I32);
4797
4798 assign(op1, get_gpr_w1(r1));
4799 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4800 assign(result, binop(Iop_Xor32, mkexpr(op1), mkexpr(op2)));
4801 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4802 put_gpr_w1(r1, mkexpr(result));
4803
4804 return "xy";
4805}
4806
4807static HChar *
4808s390_irgen_XG(UChar r1, IRTemp op2addr)
4809{
4810 IRTemp op1 = newTemp(Ity_I64);
4811 IRTemp op2 = newTemp(Ity_I64);
4812 IRTemp result = newTemp(Ity_I64);
4813
4814 assign(op1, get_gpr_dw0(r1));
4815 assign(op2, load(Ity_I64, mkexpr(op2addr)));
4816 assign(result, binop(Iop_Xor64, mkexpr(op1), mkexpr(op2)));
4817 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4818 put_gpr_dw0(r1, mkexpr(result));
4819
4820 return "xg";
4821}
4822
4823static HChar *
4824s390_irgen_XI(UChar i2, IRTemp op1addr)
4825{
4826 IRTemp op1 = newTemp(Ity_I8);
4827 UChar op2;
4828 IRTemp result = newTemp(Ity_I8);
4829
4830 assign(op1, load(Ity_I8, mkexpr(op1addr)));
4831 op2 = i2;
4832 assign(result, binop(Iop_Xor8, mkexpr(op1), mkU8(op2)));
4833 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4834 store(mkexpr(op1addr), mkexpr(result));
4835
4836 return "xi";
4837}
4838
4839static HChar *
4840s390_irgen_XIY(UChar i2, IRTemp op1addr)
4841{
4842 IRTemp op1 = newTemp(Ity_I8);
4843 UChar op2;
4844 IRTemp result = newTemp(Ity_I8);
4845
4846 assign(op1, load(Ity_I8, mkexpr(op1addr)));
4847 op2 = i2;
4848 assign(result, binop(Iop_Xor8, mkexpr(op1), mkU8(op2)));
4849 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4850 store(mkexpr(op1addr), mkexpr(result));
4851
4852 return "xiy";
4853}
4854
4855static HChar *
4856s390_irgen_XIHF(UChar r1, UInt i2)
4857{
4858 IRTemp op1 = newTemp(Ity_I32);
4859 UInt op2;
4860 IRTemp result = newTemp(Ity_I32);
4861
4862 assign(op1, get_gpr_w0(r1));
4863 op2 = i2;
4864 assign(result, binop(Iop_Xor32, mkexpr(op1), mkU32(op2)));
4865 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4866 put_gpr_w0(r1, mkexpr(result));
4867
4868 return "xihf";
4869}
4870
4871static HChar *
4872s390_irgen_XILF(UChar r1, UInt i2)
4873{
4874 IRTemp op1 = newTemp(Ity_I32);
4875 UInt op2;
4876 IRTemp result = newTemp(Ity_I32);
4877
4878 assign(op1, get_gpr_w1(r1));
4879 op2 = i2;
4880 assign(result, binop(Iop_Xor32, mkexpr(op1), mkU32(op2)));
4881 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4882 put_gpr_w1(r1, mkexpr(result));
4883
4884 return "xilf";
4885}
4886
4887static HChar *
4888s390_irgen_EAR(UChar r1, UChar r2)
4889{
4890 put_gpr_w1(r1, get_ar_w0(r2));
sewardj7ee97522011-05-09 21:45:04 +00004891 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00004892 s390_disasm(ENC3(MNM, GPR, AR), "ear", r1, r2);
4893
4894 return "ear";
4895}
4896
4897static HChar *
4898s390_irgen_IC(UChar r1, IRTemp op2addr)
4899{
4900 put_gpr_b7(r1, load(Ity_I8, mkexpr(op2addr)));
4901
4902 return "ic";
4903}
4904
4905static HChar *
4906s390_irgen_ICY(UChar r1, IRTemp op2addr)
4907{
4908 put_gpr_b7(r1, load(Ity_I8, mkexpr(op2addr)));
4909
4910 return "icy";
4911}
4912
4913static HChar *
4914s390_irgen_ICM(UChar r1, UChar r3, IRTemp op2addr)
4915{
4916 UChar n;
4917 IRTemp result = newTemp(Ity_I32);
4918 UInt mask;
4919
4920 n = 0;
4921 mask = (UInt)r3;
4922 if ((mask & 8) != 0) {
4923 put_gpr_b4(r1, load(Ity_I8, mkexpr(op2addr)));
4924 n = n + 1;
4925 }
4926 if ((mask & 4) != 0) {
4927 put_gpr_b5(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
4928
4929 n = n + 1;
4930 }
4931 if ((mask & 2) != 0) {
4932 put_gpr_b6(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
4933
4934 n = n + 1;
4935 }
4936 if ((mask & 1) != 0) {
4937 put_gpr_b7(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
4938
4939 n = n + 1;
4940 }
4941 assign(result, get_gpr_w1(r1));
4942 s390_cc_thunk_putZZ(S390_CC_OP_INSERT_CHAR_MASK_32, result, mktemp(Ity_I32,
4943 mkU32(mask)));
4944
4945 return "icm";
4946}
4947
4948static HChar *
4949s390_irgen_ICMY(UChar r1, UChar r3, IRTemp op2addr)
4950{
4951 UChar n;
4952 IRTemp result = newTemp(Ity_I32);
4953 UInt mask;
4954
4955 n = 0;
4956 mask = (UInt)r3;
4957 if ((mask & 8) != 0) {
4958 put_gpr_b4(r1, load(Ity_I8, mkexpr(op2addr)));
4959 n = n + 1;
4960 }
4961 if ((mask & 4) != 0) {
4962 put_gpr_b5(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
4963
4964 n = n + 1;
4965 }
4966 if ((mask & 2) != 0) {
4967 put_gpr_b6(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
4968
4969 n = n + 1;
4970 }
4971 if ((mask & 1) != 0) {
4972 put_gpr_b7(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
4973
4974 n = n + 1;
4975 }
4976 assign(result, get_gpr_w1(r1));
4977 s390_cc_thunk_putZZ(S390_CC_OP_INSERT_CHAR_MASK_32, result, mktemp(Ity_I32,
4978 mkU32(mask)));
4979
4980 return "icmy";
4981}
4982
4983static HChar *
4984s390_irgen_ICMH(UChar r1, UChar r3, IRTemp op2addr)
4985{
4986 UChar n;
4987 IRTemp result = newTemp(Ity_I32);
4988 UInt mask;
4989
4990 n = 0;
4991 mask = (UInt)r3;
4992 if ((mask & 8) != 0) {
4993 put_gpr_b0(r1, load(Ity_I8, mkexpr(op2addr)));
4994 n = n + 1;
4995 }
4996 if ((mask & 4) != 0) {
4997 put_gpr_b1(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
4998
4999 n = n + 1;
5000 }
5001 if ((mask & 2) != 0) {
5002 put_gpr_b2(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5003
5004 n = n + 1;
5005 }
5006 if ((mask & 1) != 0) {
5007 put_gpr_b3(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5008
5009 n = n + 1;
5010 }
5011 assign(result, get_gpr_w0(r1));
5012 s390_cc_thunk_putZZ(S390_CC_OP_INSERT_CHAR_MASK_32, result, mktemp(Ity_I32,
5013 mkU32(mask)));
5014
5015 return "icmh";
5016}
5017
5018static HChar *
5019s390_irgen_IIHF(UChar r1, UInt i2)
5020{
5021 put_gpr_w0(r1, mkU32(i2));
5022
5023 return "iihf";
5024}
5025
5026static HChar *
5027s390_irgen_IIHH(UChar r1, UShort i2)
5028{
5029 put_gpr_hw0(r1, mkU16(i2));
5030
5031 return "iihh";
5032}
5033
5034static HChar *
5035s390_irgen_IIHL(UChar r1, UShort i2)
5036{
5037 put_gpr_hw1(r1, mkU16(i2));
5038
5039 return "iihl";
5040}
5041
5042static HChar *
5043s390_irgen_IILF(UChar r1, UInt i2)
5044{
5045 put_gpr_w1(r1, mkU32(i2));
5046
5047 return "iilf";
5048}
5049
5050static HChar *
5051s390_irgen_IILH(UChar r1, UShort i2)
5052{
5053 put_gpr_hw2(r1, mkU16(i2));
5054
5055 return "iilh";
5056}
5057
5058static HChar *
5059s390_irgen_IILL(UChar r1, UShort i2)
5060{
5061 put_gpr_hw3(r1, mkU16(i2));
5062
5063 return "iill";
5064}
5065
5066static HChar *
5067s390_irgen_LR(UChar r1, UChar r2)
5068{
5069 put_gpr_w1(r1, get_gpr_w1(r2));
5070
5071 return "lr";
5072}
5073
5074static HChar *
5075s390_irgen_LGR(UChar r1, UChar r2)
5076{
5077 put_gpr_dw0(r1, get_gpr_dw0(r2));
5078
5079 return "lgr";
5080}
5081
5082static HChar *
5083s390_irgen_LGFR(UChar r1, UChar r2)
5084{
5085 put_gpr_dw0(r1, unop(Iop_32Sto64, get_gpr_w1(r2)));
5086
5087 return "lgfr";
5088}
5089
5090static HChar *
5091s390_irgen_L(UChar r1, IRTemp op2addr)
5092{
5093 put_gpr_w1(r1, load(Ity_I32, mkexpr(op2addr)));
5094
5095 return "l";
5096}
5097
5098static HChar *
5099s390_irgen_LY(UChar r1, IRTemp op2addr)
5100{
5101 put_gpr_w1(r1, load(Ity_I32, mkexpr(op2addr)));
5102
5103 return "ly";
5104}
5105
5106static HChar *
5107s390_irgen_LG(UChar r1, IRTemp op2addr)
5108{
5109 put_gpr_dw0(r1, load(Ity_I64, mkexpr(op2addr)));
5110
5111 return "lg";
5112}
5113
5114static HChar *
5115s390_irgen_LGF(UChar r1, IRTemp op2addr)
5116{
5117 put_gpr_dw0(r1, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
5118
5119 return "lgf";
5120}
5121
5122static HChar *
5123s390_irgen_LGFI(UChar r1, UInt i2)
5124{
5125 put_gpr_dw0(r1, mkU64((ULong)(Long)(Int)i2));
5126
5127 return "lgfi";
5128}
5129
5130static HChar *
5131s390_irgen_LRL(UChar r1, UInt i2)
5132{
5133 put_gpr_w1(r1, load(Ity_I32, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
5134 i2 << 1))));
5135
5136 return "lrl";
5137}
5138
5139static HChar *
5140s390_irgen_LGRL(UChar r1, UInt i2)
5141{
5142 put_gpr_dw0(r1, load(Ity_I64, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
5143 i2 << 1))));
5144
5145 return "lgrl";
5146}
5147
5148static HChar *
5149s390_irgen_LGFRL(UChar r1, UInt i2)
5150{
5151 put_gpr_dw0(r1, unop(Iop_32Sto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
5152 ((ULong)(Long)(Int)i2 << 1)))));
5153
5154 return "lgfrl";
5155}
5156
5157static HChar *
5158s390_irgen_LA(UChar r1, IRTemp op2addr)
5159{
5160 put_gpr_dw0(r1, mkexpr(op2addr));
5161
5162 return "la";
5163}
5164
5165static HChar *
5166s390_irgen_LAY(UChar r1, IRTemp op2addr)
5167{
5168 put_gpr_dw0(r1, mkexpr(op2addr));
5169
5170 return "lay";
5171}
5172
5173static HChar *
5174s390_irgen_LAE(UChar r1, IRTemp op2addr)
5175{
5176 put_gpr_dw0(r1, mkexpr(op2addr));
5177
5178 return "lae";
5179}
5180
5181static HChar *
5182s390_irgen_LAEY(UChar r1, IRTemp op2addr)
5183{
5184 put_gpr_dw0(r1, mkexpr(op2addr));
5185
5186 return "laey";
5187}
5188
5189static HChar *
5190s390_irgen_LARL(UChar r1, UInt i2)
5191{
5192 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)));
5193
5194 return "larl";
5195}
5196
5197static HChar *
5198s390_irgen_LAA(UChar r1, UChar r3, IRTemp op2addr)
5199{
5200 IRTemp op2 = newTemp(Ity_I32);
5201 IRTemp op3 = newTemp(Ity_I32);
5202 IRTemp result = newTemp(Ity_I32);
5203
5204 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5205 assign(op3, get_gpr_w1(r3));
5206 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
5207 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
5208 store(mkexpr(op2addr), mkexpr(result));
5209 put_gpr_w1(r1, mkexpr(op2));
5210
5211 return "laa";
5212}
5213
5214static HChar *
5215s390_irgen_LAAG(UChar r1, UChar r3, IRTemp op2addr)
5216{
5217 IRTemp op2 = newTemp(Ity_I64);
5218 IRTemp op3 = newTemp(Ity_I64);
5219 IRTemp result = newTemp(Ity_I64);
5220
5221 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5222 assign(op3, get_gpr_dw0(r3));
5223 assign(result, binop(Iop_Add64, mkexpr(op2), mkexpr(op3)));
5224 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op2, op3);
5225 store(mkexpr(op2addr), mkexpr(result));
5226 put_gpr_dw0(r1, mkexpr(op2));
5227
5228 return "laag";
5229}
5230
5231static HChar *
5232s390_irgen_LAAL(UChar r1, UChar r3, IRTemp op2addr)
5233{
5234 IRTemp op2 = newTemp(Ity_I32);
5235 IRTemp op3 = newTemp(Ity_I32);
5236 IRTemp result = newTemp(Ity_I32);
5237
5238 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5239 assign(op3, get_gpr_w1(r3));
5240 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
5241 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
5242 store(mkexpr(op2addr), mkexpr(result));
5243 put_gpr_w1(r1, mkexpr(op2));
5244
5245 return "laal";
5246}
5247
5248static HChar *
5249s390_irgen_LAALG(UChar r1, UChar r3, IRTemp op2addr)
5250{
5251 IRTemp op2 = newTemp(Ity_I64);
5252 IRTemp op3 = newTemp(Ity_I64);
5253 IRTemp result = newTemp(Ity_I64);
5254
5255 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5256 assign(op3, get_gpr_dw0(r3));
5257 assign(result, binop(Iop_Add64, mkexpr(op2), mkexpr(op3)));
5258 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op2, op3);
5259 store(mkexpr(op2addr), mkexpr(result));
5260 put_gpr_dw0(r1, mkexpr(op2));
5261
5262 return "laalg";
5263}
5264
5265static HChar *
5266s390_irgen_LAN(UChar r1, UChar r3, IRTemp op2addr)
5267{
5268 IRTemp op2 = newTemp(Ity_I32);
5269 IRTemp op3 = newTemp(Ity_I32);
5270 IRTemp result = newTemp(Ity_I32);
5271
5272 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5273 assign(op3, get_gpr_w1(r3));
5274 assign(result, binop(Iop_And32, mkexpr(op2), mkexpr(op3)));
5275 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5276 store(mkexpr(op2addr), mkexpr(result));
5277 put_gpr_w1(r1, mkexpr(op2));
5278
5279 return "lan";
5280}
5281
5282static HChar *
5283s390_irgen_LANG(UChar r1, UChar r3, IRTemp op2addr)
5284{
5285 IRTemp op2 = newTemp(Ity_I64);
5286 IRTemp op3 = newTemp(Ity_I64);
5287 IRTemp result = newTemp(Ity_I64);
5288
5289 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5290 assign(op3, get_gpr_dw0(r3));
5291 assign(result, binop(Iop_And64, mkexpr(op2), mkexpr(op3)));
5292 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5293 store(mkexpr(op2addr), mkexpr(result));
5294 put_gpr_dw0(r1, mkexpr(op2));
5295
5296 return "lang";
5297}
5298
5299static HChar *
5300s390_irgen_LAX(UChar r1, UChar r3, IRTemp op2addr)
5301{
5302 IRTemp op2 = newTemp(Ity_I32);
5303 IRTemp op3 = newTemp(Ity_I32);
5304 IRTemp result = newTemp(Ity_I32);
5305
5306 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5307 assign(op3, get_gpr_w1(r3));
5308 assign(result, binop(Iop_Xor32, mkexpr(op2), mkexpr(op3)));
5309 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5310 store(mkexpr(op2addr), mkexpr(result));
5311 put_gpr_w1(r1, mkexpr(op2));
5312
5313 return "lax";
5314}
5315
5316static HChar *
5317s390_irgen_LAXG(UChar r1, UChar r3, IRTemp op2addr)
5318{
5319 IRTemp op2 = newTemp(Ity_I64);
5320 IRTemp op3 = newTemp(Ity_I64);
5321 IRTemp result = newTemp(Ity_I64);
5322
5323 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5324 assign(op3, get_gpr_dw0(r3));
5325 assign(result, binop(Iop_Xor64, mkexpr(op2), mkexpr(op3)));
5326 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5327 store(mkexpr(op2addr), mkexpr(result));
5328 put_gpr_dw0(r1, mkexpr(op2));
5329
5330 return "laxg";
5331}
5332
5333static HChar *
5334s390_irgen_LAO(UChar r1, UChar r3, IRTemp op2addr)
5335{
5336 IRTemp op2 = newTemp(Ity_I32);
5337 IRTemp op3 = newTemp(Ity_I32);
5338 IRTemp result = newTemp(Ity_I32);
5339
5340 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5341 assign(op3, get_gpr_w1(r3));
5342 assign(result, binop(Iop_Or32, mkexpr(op2), mkexpr(op3)));
5343 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5344 store(mkexpr(op2addr), mkexpr(result));
5345 put_gpr_w1(r1, mkexpr(op2));
5346
5347 return "lao";
5348}
5349
5350static HChar *
5351s390_irgen_LAOG(UChar r1, UChar r3, IRTemp op2addr)
5352{
5353 IRTemp op2 = newTemp(Ity_I64);
5354 IRTemp op3 = newTemp(Ity_I64);
5355 IRTemp result = newTemp(Ity_I64);
5356
5357 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5358 assign(op3, get_gpr_dw0(r3));
5359 assign(result, binop(Iop_Or64, mkexpr(op2), mkexpr(op3)));
5360 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5361 store(mkexpr(op2addr), mkexpr(result));
5362 put_gpr_dw0(r1, mkexpr(op2));
5363
5364 return "laog";
5365}
5366
5367static HChar *
5368s390_irgen_LTR(UChar r1, UChar r2)
5369{
5370 IRTemp op2 = newTemp(Ity_I32);
5371
5372 assign(op2, get_gpr_w1(r2));
5373 put_gpr_w1(r1, mkexpr(op2));
5374 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5375
5376 return "ltr";
5377}
5378
5379static HChar *
5380s390_irgen_LTGR(UChar r1, UChar r2)
5381{
5382 IRTemp op2 = newTemp(Ity_I64);
5383
5384 assign(op2, get_gpr_dw0(r2));
5385 put_gpr_dw0(r1, mkexpr(op2));
5386 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5387
5388 return "ltgr";
5389}
5390
5391static HChar *
5392s390_irgen_LTGFR(UChar r1, UChar r2)
5393{
5394 IRTemp op2 = newTemp(Ity_I64);
5395
5396 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
5397 put_gpr_dw0(r1, mkexpr(op2));
5398 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5399
5400 return "ltgfr";
5401}
5402
5403static HChar *
5404s390_irgen_LT(UChar r1, IRTemp op2addr)
5405{
5406 IRTemp op2 = newTemp(Ity_I32);
5407
5408 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5409 put_gpr_w1(r1, mkexpr(op2));
5410 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5411
5412 return "lt";
5413}
5414
5415static HChar *
5416s390_irgen_LTG(UChar r1, IRTemp op2addr)
5417{
5418 IRTemp op2 = newTemp(Ity_I64);
5419
5420 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5421 put_gpr_dw0(r1, mkexpr(op2));
5422 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5423
5424 return "ltg";
5425}
5426
5427static HChar *
5428s390_irgen_LTGF(UChar r1, IRTemp op2addr)
5429{
5430 IRTemp op2 = newTemp(Ity_I64);
5431
5432 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
5433 put_gpr_dw0(r1, mkexpr(op2));
5434 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5435
5436 return "ltgf";
5437}
5438
5439static HChar *
5440s390_irgen_LBR(UChar r1, UChar r2)
5441{
5442 put_gpr_w1(r1, unop(Iop_8Sto32, get_gpr_b7(r2)));
5443
5444 return "lbr";
5445}
5446
5447static HChar *
5448s390_irgen_LGBR(UChar r1, UChar r2)
5449{
5450 put_gpr_dw0(r1, unop(Iop_8Sto64, get_gpr_b7(r2)));
5451
5452 return "lgbr";
5453}
5454
5455static HChar *
5456s390_irgen_LB(UChar r1, IRTemp op2addr)
5457{
5458 put_gpr_w1(r1, unop(Iop_8Sto32, load(Ity_I8, mkexpr(op2addr))));
5459
5460 return "lb";
5461}
5462
5463static HChar *
5464s390_irgen_LGB(UChar r1, IRTemp op2addr)
5465{
5466 put_gpr_dw0(r1, unop(Iop_8Sto64, load(Ity_I8, mkexpr(op2addr))));
5467
5468 return "lgb";
5469}
5470
5471static HChar *
5472s390_irgen_LBH(UChar r1, IRTemp op2addr)
5473{
5474 put_gpr_w0(r1, unop(Iop_8Sto32, load(Ity_I8, mkexpr(op2addr))));
5475
5476 return "lbh";
5477}
5478
5479static HChar *
5480s390_irgen_LCR(UChar r1, UChar r2)
5481{
5482 Int op1;
5483 IRTemp op2 = newTemp(Ity_I32);
5484 IRTemp result = newTemp(Ity_I32);
5485
5486 op1 = 0;
5487 assign(op2, get_gpr_w1(r2));
5488 assign(result, binop(Iop_Sub32, mkU32((UInt)op1), mkexpr(op2)));
5489 put_gpr_w1(r1, mkexpr(result));
5490 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, mktemp(Ity_I32, mkU32((UInt)
5491 op1)), op2);
5492
5493 return "lcr";
5494}
5495
5496static HChar *
5497s390_irgen_LCGR(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, get_gpr_dw0(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 "lcgr";
5511}
5512
5513static HChar *
5514s390_irgen_LCGFR(UChar r1, UChar r2)
5515{
5516 Long op1;
5517 IRTemp op2 = newTemp(Ity_I64);
5518 IRTemp result = newTemp(Ity_I64);
5519
5520 op1 = 0ULL;
5521 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
5522 assign(result, binop(Iop_Sub64, mkU64((ULong)op1), mkexpr(op2)));
5523 put_gpr_dw0(r1, mkexpr(result));
5524 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, mktemp(Ity_I64, mkU64((ULong)
5525 op1)), op2);
5526
5527 return "lcgfr";
5528}
5529
5530static HChar *
5531s390_irgen_LHR(UChar r1, UChar r2)
5532{
5533 put_gpr_w1(r1, unop(Iop_16Sto32, get_gpr_hw3(r2)));
5534
5535 return "lhr";
5536}
5537
5538static HChar *
5539s390_irgen_LGHR(UChar r1, UChar r2)
5540{
5541 put_gpr_dw0(r1, unop(Iop_16Sto64, get_gpr_hw3(r2)));
5542
5543 return "lghr";
5544}
5545
5546static HChar *
5547s390_irgen_LH(UChar r1, IRTemp op2addr)
5548{
5549 put_gpr_w1(r1, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
5550
5551 return "lh";
5552}
5553
5554static HChar *
5555s390_irgen_LHY(UChar r1, IRTemp op2addr)
5556{
5557 put_gpr_w1(r1, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
5558
5559 return "lhy";
5560}
5561
5562static HChar *
5563s390_irgen_LGH(UChar r1, IRTemp op2addr)
5564{
5565 put_gpr_dw0(r1, unop(Iop_16Sto64, load(Ity_I16, mkexpr(op2addr))));
5566
5567 return "lgh";
5568}
5569
5570static HChar *
5571s390_irgen_LHI(UChar r1, UShort i2)
5572{
5573 put_gpr_w1(r1, mkU32((UInt)(Int)(Short)i2));
5574
5575 return "lhi";
5576}
5577
5578static HChar *
5579s390_irgen_LGHI(UChar r1, UShort i2)
5580{
5581 put_gpr_dw0(r1, mkU64((ULong)(Long)(Short)i2));
5582
5583 return "lghi";
5584}
5585
5586static HChar *
5587s390_irgen_LHRL(UChar r1, UInt i2)
5588{
5589 put_gpr_w1(r1, unop(Iop_16Sto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
5590 ((ULong)(Long)(Int)i2 << 1)))));
5591
5592 return "lhrl";
5593}
5594
5595static HChar *
5596s390_irgen_LGHRL(UChar r1, UInt i2)
5597{
5598 put_gpr_dw0(r1, unop(Iop_16Sto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
5599 ((ULong)(Long)(Int)i2 << 1)))));
5600
5601 return "lghrl";
5602}
5603
5604static HChar *
5605s390_irgen_LHH(UChar r1, IRTemp op2addr)
5606{
5607 put_gpr_w0(r1, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
5608
5609 return "lhh";
5610}
5611
5612static HChar *
5613s390_irgen_LFH(UChar r1, IRTemp op2addr)
5614{
5615 put_gpr_w0(r1, load(Ity_I32, mkexpr(op2addr)));
5616
5617 return "lfh";
5618}
5619
5620static HChar *
5621s390_irgen_LLGFR(UChar r1, UChar r2)
5622{
5623 put_gpr_dw0(r1, unop(Iop_32Uto64, get_gpr_w1(r2)));
5624
5625 return "llgfr";
5626}
5627
5628static HChar *
5629s390_irgen_LLGF(UChar r1, IRTemp op2addr)
5630{
5631 put_gpr_dw0(r1, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
5632
5633 return "llgf";
5634}
5635
5636static HChar *
5637s390_irgen_LLGFRL(UChar r1, UInt i2)
5638{
5639 put_gpr_dw0(r1, unop(Iop_32Uto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
5640 ((ULong)(Long)(Int)i2 << 1)))));
5641
5642 return "llgfrl";
5643}
5644
5645static HChar *
5646s390_irgen_LLCR(UChar r1, UChar r2)
5647{
5648 put_gpr_w1(r1, unop(Iop_8Uto32, get_gpr_b7(r2)));
5649
5650 return "llcr";
5651}
5652
5653static HChar *
5654s390_irgen_LLGCR(UChar r1, UChar r2)
5655{
5656 put_gpr_dw0(r1, unop(Iop_8Uto64, get_gpr_b7(r2)));
5657
5658 return "llgcr";
5659}
5660
5661static HChar *
5662s390_irgen_LLC(UChar r1, IRTemp op2addr)
5663{
5664 put_gpr_w1(r1, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
5665
5666 return "llc";
5667}
5668
5669static HChar *
5670s390_irgen_LLGC(UChar r1, IRTemp op2addr)
5671{
5672 put_gpr_dw0(r1, unop(Iop_8Uto64, load(Ity_I8, mkexpr(op2addr))));
5673
5674 return "llgc";
5675}
5676
5677static HChar *
5678s390_irgen_LLCH(UChar r1, IRTemp op2addr)
5679{
5680 put_gpr_w0(r1, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
5681
5682 return "llch";
5683}
5684
5685static HChar *
5686s390_irgen_LLHR(UChar r1, UChar r2)
5687{
5688 put_gpr_w1(r1, unop(Iop_16Uto32, get_gpr_hw3(r2)));
5689
5690 return "llhr";
5691}
5692
5693static HChar *
5694s390_irgen_LLGHR(UChar r1, UChar r2)
5695{
5696 put_gpr_dw0(r1, unop(Iop_16Uto64, get_gpr_hw3(r2)));
5697
5698 return "llghr";
5699}
5700
5701static HChar *
5702s390_irgen_LLH(UChar r1, IRTemp op2addr)
5703{
5704 put_gpr_w1(r1, unop(Iop_16Uto32, load(Ity_I16, mkexpr(op2addr))));
5705
5706 return "llh";
5707}
5708
5709static HChar *
5710s390_irgen_LLGH(UChar r1, IRTemp op2addr)
5711{
5712 put_gpr_dw0(r1, unop(Iop_16Uto64, load(Ity_I16, mkexpr(op2addr))));
5713
5714 return "llgh";
5715}
5716
5717static HChar *
5718s390_irgen_LLHRL(UChar r1, UInt i2)
5719{
5720 put_gpr_w1(r1, unop(Iop_16Uto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
5721 ((ULong)(Long)(Int)i2 << 1)))));
5722
5723 return "llhrl";
5724}
5725
5726static HChar *
5727s390_irgen_LLGHRL(UChar r1, UInt i2)
5728{
5729 put_gpr_dw0(r1, unop(Iop_16Uto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
5730 ((ULong)(Long)(Int)i2 << 1)))));
5731
5732 return "llghrl";
5733}
5734
5735static HChar *
5736s390_irgen_LLHH(UChar r1, IRTemp op2addr)
5737{
5738 put_gpr_w0(r1, unop(Iop_16Uto32, load(Ity_I16, mkexpr(op2addr))));
5739
5740 return "llhh";
5741}
5742
5743static HChar *
5744s390_irgen_LLIHF(UChar r1, UInt i2)
5745{
5746 put_gpr_dw0(r1, mkU64(((ULong)i2) << 32));
5747
5748 return "llihf";
5749}
5750
5751static HChar *
5752s390_irgen_LLIHH(UChar r1, UShort i2)
5753{
5754 put_gpr_dw0(r1, mkU64(((ULong)i2) << 48));
5755
5756 return "llihh";
5757}
5758
5759static HChar *
5760s390_irgen_LLIHL(UChar r1, UShort i2)
5761{
5762 put_gpr_dw0(r1, mkU64(((ULong)i2) << 32));
5763
5764 return "llihl";
5765}
5766
5767static HChar *
5768s390_irgen_LLILF(UChar r1, UInt i2)
5769{
5770 put_gpr_dw0(r1, mkU64(i2));
5771
5772 return "llilf";
5773}
5774
5775static HChar *
5776s390_irgen_LLILH(UChar r1, UShort i2)
5777{
5778 put_gpr_dw0(r1, mkU64(((ULong)i2) << 16));
5779
5780 return "llilh";
5781}
5782
5783static HChar *
5784s390_irgen_LLILL(UChar r1, UShort i2)
5785{
5786 put_gpr_dw0(r1, mkU64(i2));
5787
5788 return "llill";
5789}
5790
5791static HChar *
5792s390_irgen_LLGTR(UChar r1, UChar r2)
5793{
5794 put_gpr_dw0(r1, unop(Iop_32Uto64, binop(Iop_And32, get_gpr_w1(r2),
5795 mkU32(2147483647))));
5796
5797 return "llgtr";
5798}
5799
5800static HChar *
5801s390_irgen_LLGT(UChar r1, IRTemp op2addr)
5802{
5803 put_gpr_dw0(r1, unop(Iop_32Uto64, binop(Iop_And32, load(Ity_I32,
5804 mkexpr(op2addr)), mkU32(2147483647))));
5805
5806 return "llgt";
5807}
5808
5809static HChar *
5810s390_irgen_LNR(UChar r1, UChar r2)
5811{
5812 IRTemp op2 = newTemp(Ity_I32);
5813 IRTemp result = newTemp(Ity_I32);
5814
5815 assign(op2, get_gpr_w1(r2));
5816 assign(result, mkite(binop(Iop_CmpLE32S, mkexpr(op2), mkU32(0)), mkexpr(op2),
5817 binop(Iop_Sub32, mkU32(0), mkexpr(op2))));
5818 put_gpr_w1(r1, mkexpr(result));
5819 s390_cc_thunk_putS(S390_CC_OP_BITWISE, result);
5820
5821 return "lnr";
5822}
5823
5824static HChar *
5825s390_irgen_LNGR(UChar r1, UChar r2)
5826{
5827 IRTemp op2 = newTemp(Ity_I64);
5828 IRTemp result = newTemp(Ity_I64);
5829
5830 assign(op2, get_gpr_dw0(r2));
5831 assign(result, mkite(binop(Iop_CmpLE64S, mkexpr(op2), mkU64(0)), mkexpr(op2),
5832 binop(Iop_Sub64, mkU64(0), mkexpr(op2))));
5833 put_gpr_dw0(r1, mkexpr(result));
5834 s390_cc_thunk_putS(S390_CC_OP_BITWISE, result);
5835
5836 return "lngr";
5837}
5838
5839static HChar *
5840s390_irgen_LNGFR(UChar r1, UChar r2 __attribute__((unused)))
5841{
5842 IRTemp op2 = newTemp(Ity_I64);
5843 IRTemp result = newTemp(Ity_I64);
5844
5845 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r1)));
5846 assign(result, mkite(binop(Iop_CmpLE64S, mkexpr(op2), mkU64(0)), mkexpr(op2),
5847 binop(Iop_Sub64, mkU64(0), mkexpr(op2))));
5848 put_gpr_dw0(r1, mkexpr(result));
5849 s390_cc_thunk_putS(S390_CC_OP_BITWISE, result);
5850
5851 return "lngfr";
5852}
5853
5854static HChar *
sewardjd7bde722011-04-05 13:19:33 +00005855s390_irgen_LOCR(UChar m3, UChar r1, UChar r2)
5856{
florian6820ba52012-07-26 02:01:50 +00005857 next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0)));
sewardjd7bde722011-04-05 13:19:33 +00005858 put_gpr_w1(r1, get_gpr_w1(r2));
5859
5860 return "locr";
5861}
5862
5863static HChar *
5864s390_irgen_LOCGR(UChar m3, UChar r1, UChar r2)
5865{
florian6820ba52012-07-26 02:01:50 +00005866 next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0)));
sewardjd7bde722011-04-05 13:19:33 +00005867 put_gpr_dw0(r1, get_gpr_dw0(r2));
5868
5869 return "locgr";
5870}
5871
5872static HChar *
5873s390_irgen_LOC(UChar r1, IRTemp op2addr)
5874{
5875 /* condition is checked in format handler */
5876 put_gpr_w1(r1, load(Ity_I32, mkexpr(op2addr)));
5877
5878 return "loc";
5879}
5880
5881static HChar *
5882s390_irgen_LOCG(UChar r1, IRTemp op2addr)
5883{
5884 /* condition is checked in format handler */
5885 put_gpr_dw0(r1, load(Ity_I64, mkexpr(op2addr)));
5886
5887 return "locg";
5888}
5889
5890static HChar *
sewardj2019a972011-03-07 16:04:07 +00005891s390_irgen_LPQ(UChar r1, IRTemp op2addr)
5892{
5893 put_gpr_dw0(r1, load(Ity_I64, mkexpr(op2addr)));
5894 put_gpr_dw0(r1 + 1, load(Ity_I64, binop(Iop_Add64, mkexpr(op2addr), mkU64(8))
5895 ));
5896
5897 return "lpq";
5898}
5899
5900static HChar *
5901s390_irgen_LPR(UChar r1, UChar r2)
5902{
5903 IRTemp op2 = newTemp(Ity_I32);
5904 IRTemp result = newTemp(Ity_I32);
5905
5906 assign(op2, get_gpr_w1(r2));
5907 assign(result, mkite(binop(Iop_CmpLT32S, mkexpr(op2), mkU32(0)),
5908 binop(Iop_Sub32, mkU32(0), mkexpr(op2)), mkexpr(op2)));
5909 put_gpr_w1(r1, mkexpr(result));
5910 s390_cc_thunk_putS(S390_CC_OP_LOAD_POSITIVE_32, op2);
5911
5912 return "lpr";
5913}
5914
5915static HChar *
5916s390_irgen_LPGR(UChar r1, UChar r2)
5917{
5918 IRTemp op2 = newTemp(Ity_I64);
5919 IRTemp result = newTemp(Ity_I64);
5920
5921 assign(op2, get_gpr_dw0(r2));
5922 assign(result, mkite(binop(Iop_CmpLT64S, mkexpr(op2), mkU64(0)),
5923 binop(Iop_Sub64, mkU64(0), mkexpr(op2)), mkexpr(op2)));
5924 put_gpr_dw0(r1, mkexpr(result));
5925 s390_cc_thunk_putS(S390_CC_OP_LOAD_POSITIVE_64, op2);
5926
5927 return "lpgr";
5928}
5929
5930static HChar *
5931s390_irgen_LPGFR(UChar r1, UChar r2)
5932{
5933 IRTemp op2 = newTemp(Ity_I64);
5934 IRTemp result = newTemp(Ity_I64);
5935
5936 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
5937 assign(result, mkite(binop(Iop_CmpLT64S, mkexpr(op2), mkU64(0)),
5938 binop(Iop_Sub64, mkU64(0), mkexpr(op2)), mkexpr(op2)));
5939 put_gpr_dw0(r1, mkexpr(result));
5940 s390_cc_thunk_putS(S390_CC_OP_LOAD_POSITIVE_64, op2);
5941
5942 return "lpgfr";
5943}
5944
5945static HChar *
5946s390_irgen_LRVR(UChar r1, UChar r2)
5947{
5948 IRTemp b0 = newTemp(Ity_I8);
5949 IRTemp b1 = newTemp(Ity_I8);
5950 IRTemp b2 = newTemp(Ity_I8);
5951 IRTemp b3 = newTemp(Ity_I8);
5952
5953 assign(b3, get_gpr_b7(r2));
5954 assign(b2, get_gpr_b6(r2));
5955 assign(b1, get_gpr_b5(r2));
5956 assign(b0, get_gpr_b4(r2));
5957 put_gpr_b4(r1, mkexpr(b3));
5958 put_gpr_b5(r1, mkexpr(b2));
5959 put_gpr_b6(r1, mkexpr(b1));
5960 put_gpr_b7(r1, mkexpr(b0));
5961
5962 return "lrvr";
5963}
5964
5965static HChar *
5966s390_irgen_LRVGR(UChar r1, UChar r2)
5967{
5968 IRTemp b0 = newTemp(Ity_I8);
5969 IRTemp b1 = newTemp(Ity_I8);
5970 IRTemp b2 = newTemp(Ity_I8);
5971 IRTemp b3 = newTemp(Ity_I8);
5972 IRTemp b4 = newTemp(Ity_I8);
5973 IRTemp b5 = newTemp(Ity_I8);
5974 IRTemp b6 = newTemp(Ity_I8);
5975 IRTemp b7 = newTemp(Ity_I8);
5976
5977 assign(b7, get_gpr_b7(r2));
5978 assign(b6, get_gpr_b6(r2));
5979 assign(b5, get_gpr_b5(r2));
5980 assign(b4, get_gpr_b4(r2));
5981 assign(b3, get_gpr_b3(r2));
5982 assign(b2, get_gpr_b2(r2));
5983 assign(b1, get_gpr_b1(r2));
5984 assign(b0, get_gpr_b0(r2));
5985 put_gpr_b0(r1, mkexpr(b7));
5986 put_gpr_b1(r1, mkexpr(b6));
5987 put_gpr_b2(r1, mkexpr(b5));
5988 put_gpr_b3(r1, mkexpr(b4));
5989 put_gpr_b4(r1, mkexpr(b3));
5990 put_gpr_b5(r1, mkexpr(b2));
5991 put_gpr_b6(r1, mkexpr(b1));
5992 put_gpr_b7(r1, mkexpr(b0));
5993
5994 return "lrvgr";
5995}
5996
5997static HChar *
5998s390_irgen_LRVH(UChar r1, IRTemp op2addr)
5999{
6000 IRTemp op2 = newTemp(Ity_I16);
6001
6002 assign(op2, load(Ity_I16, mkexpr(op2addr)));
6003 put_gpr_b6(r1, unop(Iop_16to8, mkexpr(op2)));
6004 put_gpr_b7(r1, unop(Iop_16HIto8, mkexpr(op2)));
6005
6006 return "lrvh";
6007}
6008
6009static HChar *
6010s390_irgen_LRV(UChar r1, IRTemp op2addr)
6011{
6012 IRTemp op2 = newTemp(Ity_I32);
6013
6014 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6015 put_gpr_b4(r1, unop(Iop_32to8, binop(Iop_And32, mkexpr(op2), mkU32(255))));
6016 put_gpr_b5(r1, unop(Iop_32to8, binop(Iop_And32, binop(Iop_Shr32, mkexpr(op2),
6017 mkU8(8)), mkU32(255))));
6018 put_gpr_b6(r1, unop(Iop_32to8, binop(Iop_And32, binop(Iop_Shr32, mkexpr(op2),
6019 mkU8(16)), mkU32(255))));
6020 put_gpr_b7(r1, unop(Iop_32to8, binop(Iop_And32, binop(Iop_Shr32, mkexpr(op2),
6021 mkU8(24)), mkU32(255))));
6022
6023 return "lrv";
6024}
6025
6026static HChar *
6027s390_irgen_LRVG(UChar r1, IRTemp op2addr)
6028{
6029 IRTemp op2 = newTemp(Ity_I64);
6030
6031 assign(op2, load(Ity_I64, mkexpr(op2addr)));
6032 put_gpr_b0(r1, unop(Iop_64to8, binop(Iop_And64, mkexpr(op2), mkU64(255))));
6033 put_gpr_b1(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6034 mkU8(8)), mkU64(255))));
6035 put_gpr_b2(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6036 mkU8(16)), mkU64(255))));
6037 put_gpr_b3(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6038 mkU8(24)), mkU64(255))));
6039 put_gpr_b4(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6040 mkU8(32)), mkU64(255))));
6041 put_gpr_b5(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6042 mkU8(40)), mkU64(255))));
6043 put_gpr_b6(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6044 mkU8(48)), mkU64(255))));
6045 put_gpr_b7(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6046 mkU8(56)), mkU64(255))));
6047
6048 return "lrvg";
6049}
6050
6051static HChar *
6052s390_irgen_MVHHI(UShort i2, IRTemp op1addr)
6053{
6054 store(mkexpr(op1addr), mkU16(i2));
6055
6056 return "mvhhi";
6057}
6058
6059static HChar *
6060s390_irgen_MVHI(UShort i2, IRTemp op1addr)
6061{
6062 store(mkexpr(op1addr), mkU32((UInt)(Int)(Short)i2));
6063
6064 return "mvhi";
6065}
6066
6067static HChar *
6068s390_irgen_MVGHI(UShort i2, IRTemp op1addr)
6069{
6070 store(mkexpr(op1addr), mkU64((ULong)(Long)(Short)i2));
6071
6072 return "mvghi";
6073}
6074
6075static HChar *
6076s390_irgen_MVI(UChar i2, IRTemp op1addr)
6077{
6078 store(mkexpr(op1addr), mkU8(i2));
6079
6080 return "mvi";
6081}
6082
6083static HChar *
6084s390_irgen_MVIY(UChar i2, IRTemp op1addr)
6085{
6086 store(mkexpr(op1addr), mkU8(i2));
6087
6088 return "mviy";
6089}
6090
6091static HChar *
6092s390_irgen_MR(UChar r1, UChar r2)
6093{
6094 IRTemp op1 = newTemp(Ity_I32);
6095 IRTemp op2 = newTemp(Ity_I32);
6096 IRTemp result = newTemp(Ity_I64);
6097
6098 assign(op1, get_gpr_w1(r1 + 1));
6099 assign(op2, get_gpr_w1(r2));
6100 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6101 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6102 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6103
6104 return "mr";
6105}
6106
6107static HChar *
6108s390_irgen_M(UChar r1, IRTemp op2addr)
6109{
6110 IRTemp op1 = newTemp(Ity_I32);
6111 IRTemp op2 = newTemp(Ity_I32);
6112 IRTemp result = newTemp(Ity_I64);
6113
6114 assign(op1, get_gpr_w1(r1 + 1));
6115 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6116 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6117 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6118 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6119
6120 return "m";
6121}
6122
6123static HChar *
6124s390_irgen_MFY(UChar r1, IRTemp op2addr)
6125{
6126 IRTemp op1 = newTemp(Ity_I32);
6127 IRTemp op2 = newTemp(Ity_I32);
6128 IRTemp result = newTemp(Ity_I64);
6129
6130 assign(op1, get_gpr_w1(r1 + 1));
6131 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6132 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6133 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6134 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6135
6136 return "mfy";
6137}
6138
6139static HChar *
6140s390_irgen_MH(UChar r1, IRTemp op2addr)
6141{
6142 IRTemp op1 = newTemp(Ity_I32);
6143 IRTemp op2 = newTemp(Ity_I16);
6144 IRTemp result = newTemp(Ity_I64);
6145
6146 assign(op1, get_gpr_w1(r1));
6147 assign(op2, load(Ity_I16, mkexpr(op2addr)));
6148 assign(result, binop(Iop_MullS32, mkexpr(op1), unop(Iop_16Sto32, mkexpr(op2))
6149 ));
6150 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6151
6152 return "mh";
6153}
6154
6155static HChar *
6156s390_irgen_MHY(UChar r1, IRTemp op2addr)
6157{
6158 IRTemp op1 = newTemp(Ity_I32);
6159 IRTemp op2 = newTemp(Ity_I16);
6160 IRTemp result = newTemp(Ity_I64);
6161
6162 assign(op1, get_gpr_w1(r1));
6163 assign(op2, load(Ity_I16, mkexpr(op2addr)));
6164 assign(result, binop(Iop_MullS32, mkexpr(op1), unop(Iop_16Sto32, mkexpr(op2))
6165 ));
6166 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6167
6168 return "mhy";
6169}
6170
6171static HChar *
6172s390_irgen_MHI(UChar r1, UShort i2)
6173{
6174 IRTemp op1 = newTemp(Ity_I32);
6175 Short op2;
6176 IRTemp result = newTemp(Ity_I64);
6177
6178 assign(op1, get_gpr_w1(r1));
6179 op2 = (Short)i2;
6180 assign(result, binop(Iop_MullS32, mkexpr(op1), unop(Iop_16Sto32,
6181 mkU16((UShort)op2))));
6182 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6183
6184 return "mhi";
6185}
6186
6187static HChar *
6188s390_irgen_MGHI(UChar r1, UShort i2)
6189{
6190 IRTemp op1 = newTemp(Ity_I64);
6191 Short op2;
6192 IRTemp result = newTemp(Ity_I128);
6193
6194 assign(op1, get_gpr_dw0(r1));
6195 op2 = (Short)i2;
6196 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_16Sto64,
6197 mkU16((UShort)op2))));
6198 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6199
6200 return "mghi";
6201}
6202
6203static HChar *
6204s390_irgen_MLR(UChar r1, UChar r2)
6205{
6206 IRTemp op1 = newTemp(Ity_I32);
6207 IRTemp op2 = newTemp(Ity_I32);
6208 IRTemp result = newTemp(Ity_I64);
6209
6210 assign(op1, get_gpr_w1(r1 + 1));
6211 assign(op2, get_gpr_w1(r2));
6212 assign(result, binop(Iop_MullU32, mkexpr(op1), mkexpr(op2)));
6213 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6214 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6215
6216 return "mlr";
6217}
6218
6219static HChar *
6220s390_irgen_MLGR(UChar r1, UChar r2)
6221{
6222 IRTemp op1 = newTemp(Ity_I64);
6223 IRTemp op2 = newTemp(Ity_I64);
6224 IRTemp result = newTemp(Ity_I128);
6225
6226 assign(op1, get_gpr_dw0(r1 + 1));
6227 assign(op2, get_gpr_dw0(r2));
6228 assign(result, binop(Iop_MullU64, mkexpr(op1), mkexpr(op2)));
6229 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result)));
6230 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result)));
6231
6232 return "mlgr";
6233}
6234
6235static HChar *
6236s390_irgen_ML(UChar r1, IRTemp op2addr)
6237{
6238 IRTemp op1 = newTemp(Ity_I32);
6239 IRTemp op2 = newTemp(Ity_I32);
6240 IRTemp result = newTemp(Ity_I64);
6241
6242 assign(op1, get_gpr_w1(r1 + 1));
6243 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6244 assign(result, binop(Iop_MullU32, mkexpr(op1), mkexpr(op2)));
6245 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6246 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6247
6248 return "ml";
6249}
6250
6251static HChar *
6252s390_irgen_MLG(UChar r1, IRTemp op2addr)
6253{
6254 IRTemp op1 = newTemp(Ity_I64);
6255 IRTemp op2 = newTemp(Ity_I64);
6256 IRTemp result = newTemp(Ity_I128);
6257
6258 assign(op1, get_gpr_dw0(r1 + 1));
6259 assign(op2, load(Ity_I64, mkexpr(op2addr)));
6260 assign(result, binop(Iop_MullU64, mkexpr(op1), mkexpr(op2)));
6261 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result)));
6262 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result)));
6263
6264 return "mlg";
6265}
6266
6267static HChar *
6268s390_irgen_MSR(UChar r1, UChar r2)
6269{
6270 IRTemp op1 = newTemp(Ity_I32);
6271 IRTemp op2 = newTemp(Ity_I32);
6272 IRTemp result = newTemp(Ity_I64);
6273
6274 assign(op1, get_gpr_w1(r1));
6275 assign(op2, get_gpr_w1(r2));
6276 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6277 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6278
6279 return "msr";
6280}
6281
6282static HChar *
6283s390_irgen_MSGR(UChar r1, UChar r2)
6284{
6285 IRTemp op1 = newTemp(Ity_I64);
6286 IRTemp op2 = newTemp(Ity_I64);
6287 IRTemp result = newTemp(Ity_I128);
6288
6289 assign(op1, get_gpr_dw0(r1));
6290 assign(op2, get_gpr_dw0(r2));
6291 assign(result, binop(Iop_MullS64, mkexpr(op1), mkexpr(op2)));
6292 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6293
6294 return "msgr";
6295}
6296
6297static HChar *
6298s390_irgen_MSGFR(UChar r1, UChar r2)
6299{
6300 IRTemp op1 = newTemp(Ity_I64);
6301 IRTemp op2 = newTemp(Ity_I32);
6302 IRTemp result = newTemp(Ity_I128);
6303
6304 assign(op1, get_gpr_dw0(r1));
6305 assign(op2, get_gpr_w1(r2));
6306 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_32Sto64, mkexpr(op2))
6307 ));
6308 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6309
6310 return "msgfr";
6311}
6312
6313static HChar *
6314s390_irgen_MS(UChar r1, IRTemp op2addr)
6315{
6316 IRTemp op1 = newTemp(Ity_I32);
6317 IRTemp op2 = newTemp(Ity_I32);
6318 IRTemp result = newTemp(Ity_I64);
6319
6320 assign(op1, get_gpr_w1(r1));
6321 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6322 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6323 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6324
6325 return "ms";
6326}
6327
6328static HChar *
6329s390_irgen_MSY(UChar r1, IRTemp op2addr)
6330{
6331 IRTemp op1 = newTemp(Ity_I32);
6332 IRTemp op2 = newTemp(Ity_I32);
6333 IRTemp result = newTemp(Ity_I64);
6334
6335 assign(op1, get_gpr_w1(r1));
6336 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6337 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6338 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6339
6340 return "msy";
6341}
6342
6343static HChar *
6344s390_irgen_MSG(UChar r1, IRTemp op2addr)
6345{
6346 IRTemp op1 = newTemp(Ity_I64);
6347 IRTemp op2 = newTemp(Ity_I64);
6348 IRTemp result = newTemp(Ity_I128);
6349
6350 assign(op1, get_gpr_dw0(r1));
6351 assign(op2, load(Ity_I64, mkexpr(op2addr)));
6352 assign(result, binop(Iop_MullS64, mkexpr(op1), mkexpr(op2)));
6353 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6354
6355 return "msg";
6356}
6357
6358static HChar *
6359s390_irgen_MSGF(UChar r1, IRTemp op2addr)
6360{
6361 IRTemp op1 = newTemp(Ity_I64);
6362 IRTemp op2 = newTemp(Ity_I32);
6363 IRTemp result = newTemp(Ity_I128);
6364
6365 assign(op1, get_gpr_dw0(r1));
6366 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6367 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_32Sto64, mkexpr(op2))
6368 ));
6369 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6370
6371 return "msgf";
6372}
6373
6374static HChar *
6375s390_irgen_MSFI(UChar r1, UInt i2)
6376{
6377 IRTemp op1 = newTemp(Ity_I32);
6378 Int op2;
6379 IRTemp result = newTemp(Ity_I64);
6380
6381 assign(op1, get_gpr_w1(r1));
6382 op2 = (Int)i2;
6383 assign(result, binop(Iop_MullS32, mkexpr(op1), mkU32((UInt)op2)));
6384 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6385
6386 return "msfi";
6387}
6388
6389static HChar *
6390s390_irgen_MSGFI(UChar r1, UInt i2)
6391{
6392 IRTemp op1 = newTemp(Ity_I64);
6393 Int op2;
6394 IRTemp result = newTemp(Ity_I128);
6395
6396 assign(op1, get_gpr_dw0(r1));
6397 op2 = (Int)i2;
6398 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_32Sto64, mkU32((UInt)
6399 op2))));
6400 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6401
6402 return "msgfi";
6403}
6404
6405static HChar *
6406s390_irgen_OR(UChar r1, UChar r2)
6407{
6408 IRTemp op1 = newTemp(Ity_I32);
6409 IRTemp op2 = newTemp(Ity_I32);
6410 IRTemp result = newTemp(Ity_I32);
6411
6412 assign(op1, get_gpr_w1(r1));
6413 assign(op2, get_gpr_w1(r2));
6414 assign(result, binop(Iop_Or32, mkexpr(op1), mkexpr(op2)));
6415 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6416 put_gpr_w1(r1, mkexpr(result));
6417
6418 return "or";
6419}
6420
6421static HChar *
6422s390_irgen_OGR(UChar r1, UChar r2)
6423{
6424 IRTemp op1 = newTemp(Ity_I64);
6425 IRTemp op2 = newTemp(Ity_I64);
6426 IRTemp result = newTemp(Ity_I64);
6427
6428 assign(op1, get_gpr_dw0(r1));
6429 assign(op2, get_gpr_dw0(r2));
6430 assign(result, binop(Iop_Or64, mkexpr(op1), mkexpr(op2)));
6431 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6432 put_gpr_dw0(r1, mkexpr(result));
6433
6434 return "ogr";
6435}
6436
6437static HChar *
6438s390_irgen_ORK(UChar r3, UChar r1, UChar r2)
6439{
6440 IRTemp op2 = newTemp(Ity_I32);
6441 IRTemp op3 = newTemp(Ity_I32);
6442 IRTemp result = newTemp(Ity_I32);
6443
6444 assign(op2, get_gpr_w1(r2));
6445 assign(op3, get_gpr_w1(r3));
6446 assign(result, binop(Iop_Or32, mkexpr(op2), mkexpr(op3)));
6447 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6448 put_gpr_w1(r1, mkexpr(result));
6449
6450 return "ork";
6451}
6452
6453static HChar *
6454s390_irgen_OGRK(UChar r3, UChar r1, UChar r2)
6455{
6456 IRTemp op2 = newTemp(Ity_I64);
6457 IRTemp op3 = newTemp(Ity_I64);
6458 IRTemp result = newTemp(Ity_I64);
6459
6460 assign(op2, get_gpr_dw0(r2));
6461 assign(op3, get_gpr_dw0(r3));
6462 assign(result, binop(Iop_Or64, mkexpr(op2), mkexpr(op3)));
6463 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6464 put_gpr_dw0(r1, mkexpr(result));
6465
6466 return "ogrk";
6467}
6468
6469static HChar *
6470s390_irgen_O(UChar r1, IRTemp op2addr)
6471{
6472 IRTemp op1 = newTemp(Ity_I32);
6473 IRTemp op2 = newTemp(Ity_I32);
6474 IRTemp result = newTemp(Ity_I32);
6475
6476 assign(op1, get_gpr_w1(r1));
6477 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6478 assign(result, binop(Iop_Or32, mkexpr(op1), mkexpr(op2)));
6479 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6480 put_gpr_w1(r1, mkexpr(result));
6481
6482 return "o";
6483}
6484
6485static HChar *
6486s390_irgen_OY(UChar r1, IRTemp op2addr)
6487{
6488 IRTemp op1 = newTemp(Ity_I32);
6489 IRTemp op2 = newTemp(Ity_I32);
6490 IRTemp result = newTemp(Ity_I32);
6491
6492 assign(op1, get_gpr_w1(r1));
6493 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6494 assign(result, binop(Iop_Or32, mkexpr(op1), mkexpr(op2)));
6495 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6496 put_gpr_w1(r1, mkexpr(result));
6497
6498 return "oy";
6499}
6500
6501static HChar *
6502s390_irgen_OG(UChar r1, IRTemp op2addr)
6503{
6504 IRTemp op1 = newTemp(Ity_I64);
6505 IRTemp op2 = newTemp(Ity_I64);
6506 IRTemp result = newTemp(Ity_I64);
6507
6508 assign(op1, get_gpr_dw0(r1));
6509 assign(op2, load(Ity_I64, mkexpr(op2addr)));
6510 assign(result, binop(Iop_Or64, mkexpr(op1), mkexpr(op2)));
6511 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6512 put_gpr_dw0(r1, mkexpr(result));
6513
6514 return "og";
6515}
6516
6517static HChar *
6518s390_irgen_OI(UChar i2, IRTemp op1addr)
6519{
6520 IRTemp op1 = newTemp(Ity_I8);
6521 UChar op2;
6522 IRTemp result = newTemp(Ity_I8);
6523
6524 assign(op1, load(Ity_I8, mkexpr(op1addr)));
6525 op2 = i2;
6526 assign(result, binop(Iop_Or8, mkexpr(op1), mkU8(op2)));
6527 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6528 store(mkexpr(op1addr), mkexpr(result));
6529
6530 return "oi";
6531}
6532
6533static HChar *
6534s390_irgen_OIY(UChar i2, IRTemp op1addr)
6535{
6536 IRTemp op1 = newTemp(Ity_I8);
6537 UChar op2;
6538 IRTemp result = newTemp(Ity_I8);
6539
6540 assign(op1, load(Ity_I8, mkexpr(op1addr)));
6541 op2 = i2;
6542 assign(result, binop(Iop_Or8, mkexpr(op1), mkU8(op2)));
6543 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6544 store(mkexpr(op1addr), mkexpr(result));
6545
6546 return "oiy";
6547}
6548
6549static HChar *
6550s390_irgen_OIHF(UChar r1, UInt i2)
6551{
6552 IRTemp op1 = newTemp(Ity_I32);
6553 UInt op2;
6554 IRTemp result = newTemp(Ity_I32);
6555
6556 assign(op1, get_gpr_w0(r1));
6557 op2 = i2;
6558 assign(result, binop(Iop_Or32, mkexpr(op1), mkU32(op2)));
6559 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6560 put_gpr_w0(r1, mkexpr(result));
6561
6562 return "oihf";
6563}
6564
6565static HChar *
6566s390_irgen_OIHH(UChar r1, UShort i2)
6567{
6568 IRTemp op1 = newTemp(Ity_I16);
6569 UShort op2;
6570 IRTemp result = newTemp(Ity_I16);
6571
6572 assign(op1, get_gpr_hw0(r1));
6573 op2 = i2;
6574 assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
6575 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6576 put_gpr_hw0(r1, mkexpr(result));
6577
6578 return "oihh";
6579}
6580
6581static HChar *
6582s390_irgen_OIHL(UChar r1, UShort i2)
6583{
6584 IRTemp op1 = newTemp(Ity_I16);
6585 UShort op2;
6586 IRTemp result = newTemp(Ity_I16);
6587
6588 assign(op1, get_gpr_hw1(r1));
6589 op2 = i2;
6590 assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
6591 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6592 put_gpr_hw1(r1, mkexpr(result));
6593
6594 return "oihl";
6595}
6596
6597static HChar *
6598s390_irgen_OILF(UChar r1, UInt i2)
6599{
6600 IRTemp op1 = newTemp(Ity_I32);
6601 UInt op2;
6602 IRTemp result = newTemp(Ity_I32);
6603
6604 assign(op1, get_gpr_w1(r1));
6605 op2 = i2;
6606 assign(result, binop(Iop_Or32, mkexpr(op1), mkU32(op2)));
6607 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6608 put_gpr_w1(r1, mkexpr(result));
6609
6610 return "oilf";
6611}
6612
6613static HChar *
6614s390_irgen_OILH(UChar r1, UShort i2)
6615{
6616 IRTemp op1 = newTemp(Ity_I16);
6617 UShort op2;
6618 IRTemp result = newTemp(Ity_I16);
6619
6620 assign(op1, get_gpr_hw2(r1));
6621 op2 = i2;
6622 assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
6623 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6624 put_gpr_hw2(r1, mkexpr(result));
6625
6626 return "oilh";
6627}
6628
6629static HChar *
6630s390_irgen_OILL(UChar r1, UShort i2)
6631{
6632 IRTemp op1 = newTemp(Ity_I16);
6633 UShort op2;
6634 IRTemp result = newTemp(Ity_I16);
6635
6636 assign(op1, get_gpr_hw3(r1));
6637 op2 = i2;
6638 assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
6639 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6640 put_gpr_hw3(r1, mkexpr(result));
6641
6642 return "oill";
6643}
6644
6645static HChar *
6646s390_irgen_PFD(void)
6647{
6648
6649 return "pfd";
6650}
6651
6652static HChar *
6653s390_irgen_PFDRL(void)
6654{
6655
6656 return "pfdrl";
6657}
6658
6659static HChar *
6660s390_irgen_RLL(UChar r1, UChar r3, IRTemp op2addr)
6661{
6662 IRTemp amount = newTemp(Ity_I64);
6663 IRTemp op = newTemp(Ity_I32);
6664
6665 assign(amount, binop(Iop_And64, mkexpr(op2addr), mkU64(31)));
6666 assign(op, get_gpr_w1(r3));
6667 put_gpr_w1(r1, binop(Iop_Or32, binop(Iop_Shl32, mkexpr(op), unop(Iop_64to8,
6668 mkexpr(amount))), binop(Iop_Shr32, mkexpr(op), unop(Iop_64to8,
6669 binop(Iop_Sub64, mkU64(32), mkexpr(amount))))));
6670
6671 return "rll";
6672}
6673
6674static HChar *
6675s390_irgen_RLLG(UChar r1, UChar r3, IRTemp op2addr)
6676{
6677 IRTemp amount = newTemp(Ity_I64);
6678 IRTemp op = newTemp(Ity_I64);
6679
6680 assign(amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
6681 assign(op, get_gpr_dw0(r3));
6682 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(op), unop(Iop_64to8,
6683 mkexpr(amount))), binop(Iop_Shr64, mkexpr(op), unop(Iop_64to8,
6684 binop(Iop_Sub64, mkU64(64), mkexpr(amount))))));
6685
6686 return "rllg";
6687}
6688
6689static HChar *
6690s390_irgen_RNSBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
6691{
6692 UChar from;
6693 UChar to;
6694 UChar rot;
6695 UChar t_bit;
6696 ULong mask;
6697 ULong maskc;
6698 IRTemp result = newTemp(Ity_I64);
6699 IRTemp op2 = newTemp(Ity_I64);
6700
6701 from = i3 & 63;
6702 to = i4 & 63;
6703 rot = i5 & 63;
6704 t_bit = i3 & 128;
6705 assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
6706 get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
6707 mkU8(64 - rot))));
6708 if (from <= to) {
6709 mask = ~0ULL;
6710 mask = (mask >> from) & (mask << (63 - to));
6711 maskc = ~mask;
6712 } else {
6713 maskc = ~0ULL;
6714 maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
6715 mask = ~maskc;
6716 }
6717 assign(result, binop(Iop_And64, binop(Iop_And64, get_gpr_dw0(r1), mkexpr(op2)
6718 ), mkU64(mask)));
6719 if (t_bit == 0) {
6720 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
6721 mkU64(maskc)), mkexpr(result)));
6722 }
6723 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6724
6725 return "rnsbg";
6726}
6727
6728static HChar *
6729s390_irgen_RXSBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
6730{
6731 UChar from;
6732 UChar to;
6733 UChar rot;
6734 UChar t_bit;
6735 ULong mask;
6736 ULong maskc;
6737 IRTemp result = newTemp(Ity_I64);
6738 IRTemp op2 = newTemp(Ity_I64);
6739
6740 from = i3 & 63;
6741 to = i4 & 63;
6742 rot = i5 & 63;
6743 t_bit = i3 & 128;
6744 assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
6745 get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
6746 mkU8(64 - rot))));
6747 if (from <= to) {
6748 mask = ~0ULL;
6749 mask = (mask >> from) & (mask << (63 - to));
6750 maskc = ~mask;
6751 } else {
6752 maskc = ~0ULL;
6753 maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
6754 mask = ~maskc;
6755 }
6756 assign(result, binop(Iop_And64, binop(Iop_Xor64, get_gpr_dw0(r1), mkexpr(op2)
6757 ), mkU64(mask)));
6758 if (t_bit == 0) {
6759 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
6760 mkU64(maskc)), mkexpr(result)));
6761 }
6762 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6763
6764 return "rxsbg";
6765}
6766
6767static HChar *
6768s390_irgen_ROSBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
6769{
6770 UChar from;
6771 UChar to;
6772 UChar rot;
6773 UChar t_bit;
6774 ULong mask;
6775 ULong maskc;
6776 IRTemp result = newTemp(Ity_I64);
6777 IRTemp op2 = newTemp(Ity_I64);
6778
6779 from = i3 & 63;
6780 to = i4 & 63;
6781 rot = i5 & 63;
6782 t_bit = i3 & 128;
6783 assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
6784 get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
6785 mkU8(64 - rot))));
6786 if (from <= to) {
6787 mask = ~0ULL;
6788 mask = (mask >> from) & (mask << (63 - to));
6789 maskc = ~mask;
6790 } else {
6791 maskc = ~0ULL;
6792 maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
6793 mask = ~maskc;
6794 }
6795 assign(result, binop(Iop_And64, binop(Iop_Or64, get_gpr_dw0(r1), mkexpr(op2)
6796 ), mkU64(mask)));
6797 if (t_bit == 0) {
6798 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
6799 mkU64(maskc)), mkexpr(result)));
6800 }
6801 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6802
6803 return "rosbg";
6804}
6805
6806static HChar *
6807s390_irgen_RISBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
6808{
6809 UChar from;
6810 UChar to;
6811 UChar rot;
6812 UChar z_bit;
6813 ULong mask;
6814 ULong maskc;
6815 IRTemp op2 = newTemp(Ity_I64);
6816 IRTemp result = newTemp(Ity_I64);
6817
6818 from = i3 & 63;
6819 to = i4 & 63;
6820 rot = i5 & 63;
6821 z_bit = i4 & 128;
6822 assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
6823 get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
6824 mkU8(64 - rot))));
6825 if (from <= to) {
6826 mask = ~0ULL;
6827 mask = (mask >> from) & (mask << (63 - to));
6828 maskc = ~mask;
6829 } else {
6830 maskc = ~0ULL;
6831 maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
6832 mask = ~maskc;
6833 }
6834 if (z_bit == 0) {
6835 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
6836 mkU64(maskc)), binop(Iop_And64, mkexpr(op2), mkU64(mask))));
6837 } else {
6838 put_gpr_dw0(r1, binop(Iop_And64, mkexpr(op2), mkU64(mask)));
6839 }
6840 assign(result, get_gpr_dw0(r1));
6841 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
6842
6843 return "risbg";
6844}
6845
6846static HChar *
6847s390_irgen_SAR(UChar r1, UChar r2)
6848{
6849 put_ar_w0(r1, get_gpr_w1(r2));
sewardj7ee97522011-05-09 21:45:04 +00006850 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00006851 s390_disasm(ENC3(MNM, AR, GPR), "sar", r1, r2);
6852
6853 return "sar";
6854}
6855
6856static HChar *
6857s390_irgen_SLDA(UChar r1, IRTemp op2addr)
6858{
6859 IRTemp p1 = newTemp(Ity_I64);
6860 IRTemp p2 = newTemp(Ity_I64);
6861 IRTemp op = newTemp(Ity_I64);
6862 IRTemp result = newTemp(Ity_I64);
florian417b22d2012-07-13 13:41:41 +00006863 ULong sign_mask;
sewardj2019a972011-03-07 16:04:07 +00006864 IRTemp shift_amount = newTemp(Ity_I64);
6865
6866 assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
6867 assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
6868 assign(op, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1), mkU8(32)), mkexpr(p2)
6869 ));
6870 sign_mask = 1ULL << 63;
6871 assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
6872 assign(result, binop(Iop_Or64, binop(Iop_And64, binop(Iop_Shl64, mkexpr(op),
florian417b22d2012-07-13 13:41:41 +00006873 unop(Iop_64to8, mkexpr(shift_amount))), mkU64(~sign_mask)),
6874 binop(Iop_And64, mkexpr(op), mkU64(sign_mask))));
sewardj2019a972011-03-07 16:04:07 +00006875 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6876 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6877 s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_64, op, shift_amount);
6878
6879 return "slda";
6880}
6881
6882static HChar *
6883s390_irgen_SLDL(UChar r1, IRTemp op2addr)
6884{
6885 IRTemp p1 = newTemp(Ity_I64);
6886 IRTemp p2 = newTemp(Ity_I64);
6887 IRTemp result = newTemp(Ity_I64);
6888
6889 assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
6890 assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
6891 assign(result, binop(Iop_Shl64, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1),
6892 mkU8(32)), mkexpr(p2)), unop(Iop_64to8, binop(Iop_And64,
6893 mkexpr(op2addr), mkU64(63)))));
6894 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6895 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6896
6897 return "sldl";
6898}
6899
6900static HChar *
6901s390_irgen_SLA(UChar r1, IRTemp op2addr)
6902{
6903 IRTemp uop = newTemp(Ity_I32);
6904 IRTemp result = newTemp(Ity_I32);
6905 UInt sign_mask;
6906 IRTemp shift_amount = newTemp(Ity_I64);
6907 IRTemp op = newTemp(Ity_I32);
6908
6909 assign(op, get_gpr_w1(r1));
6910 assign(uop, get_gpr_w1(r1));
6911 sign_mask = 2147483648U;
6912 assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
6913 assign(result, binop(Iop_Or32, binop(Iop_And32, binop(Iop_Shl32, mkexpr(uop),
6914 unop(Iop_64to8, mkexpr(shift_amount))), mkU32(~sign_mask)),
6915 binop(Iop_And32, mkexpr(uop), mkU32(sign_mask))));
6916 put_gpr_w1(r1, mkexpr(result));
6917 s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_32, op, shift_amount);
6918
6919 return "sla";
6920}
6921
6922static HChar *
6923s390_irgen_SLAK(UChar r1, UChar r3, IRTemp op2addr)
6924{
6925 IRTemp uop = newTemp(Ity_I32);
6926 IRTemp result = newTemp(Ity_I32);
6927 UInt sign_mask;
6928 IRTemp shift_amount = newTemp(Ity_I64);
6929 IRTemp op = newTemp(Ity_I32);
6930
6931 assign(op, get_gpr_w1(r3));
6932 assign(uop, get_gpr_w1(r3));
6933 sign_mask = 2147483648U;
6934 assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
6935 assign(result, binop(Iop_Or32, binop(Iop_And32, binop(Iop_Shl32, mkexpr(uop),
6936 unop(Iop_64to8, mkexpr(shift_amount))), mkU32(~sign_mask)),
6937 binop(Iop_And32, mkexpr(uop), mkU32(sign_mask))));
6938 put_gpr_w1(r1, mkexpr(result));
6939 s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_32, op, shift_amount);
6940
6941 return "slak";
6942}
6943
6944static HChar *
6945s390_irgen_SLAG(UChar r1, UChar r3, IRTemp op2addr)
6946{
6947 IRTemp uop = newTemp(Ity_I64);
6948 IRTemp result = newTemp(Ity_I64);
6949 ULong sign_mask;
6950 IRTemp shift_amount = newTemp(Ity_I64);
6951 IRTemp op = newTemp(Ity_I64);
6952
6953 assign(op, get_gpr_dw0(r3));
6954 assign(uop, get_gpr_dw0(r3));
6955 sign_mask = 9223372036854775808ULL;
6956 assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
6957 assign(result, binop(Iop_Or64, binop(Iop_And64, binop(Iop_Shl64, mkexpr(uop),
6958 unop(Iop_64to8, mkexpr(shift_amount))), mkU64(~sign_mask)),
6959 binop(Iop_And64, mkexpr(uop), mkU64(sign_mask))));
6960 put_gpr_dw0(r1, mkexpr(result));
6961 s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_64, op, shift_amount);
6962
6963 return "slag";
6964}
6965
6966static HChar *
6967s390_irgen_SLL(UChar r1, IRTemp op2addr)
6968{
6969 put_gpr_w1(r1, binop(Iop_Shl32, get_gpr_w1(r1), unop(Iop_64to8,
6970 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
6971
6972 return "sll";
6973}
6974
6975static HChar *
6976s390_irgen_SLLK(UChar r1, UChar r3, IRTemp op2addr)
6977{
6978 put_gpr_w1(r1, binop(Iop_Shl32, get_gpr_w1(r3), unop(Iop_64to8,
6979 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
6980
6981 return "sllk";
6982}
6983
6984static HChar *
6985s390_irgen_SLLG(UChar r1, UChar r3, IRTemp op2addr)
6986{
6987 put_gpr_dw0(r1, binop(Iop_Shl64, get_gpr_dw0(r3), unop(Iop_64to8,
6988 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
6989
6990 return "sllg";
6991}
6992
6993static HChar *
6994s390_irgen_SRDA(UChar r1, IRTemp op2addr)
6995{
6996 IRTemp p1 = newTemp(Ity_I64);
6997 IRTemp p2 = newTemp(Ity_I64);
6998 IRTemp result = newTemp(Ity_I64);
6999
7000 assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
7001 assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
7002 assign(result, binop(Iop_Sar64, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1),
7003 mkU8(32)), mkexpr(p2)), unop(Iop_64to8, binop(Iop_And64,
7004 mkexpr(op2addr), mkU64(63)))));
7005 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
7006 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
7007 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7008
7009 return "srda";
7010}
7011
7012static HChar *
7013s390_irgen_SRDL(UChar r1, IRTemp op2addr)
7014{
7015 IRTemp p1 = newTemp(Ity_I64);
7016 IRTemp p2 = newTemp(Ity_I64);
7017 IRTemp result = newTemp(Ity_I64);
7018
7019 assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
7020 assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
7021 assign(result, binop(Iop_Shr64, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1),
7022 mkU8(32)), mkexpr(p2)), unop(Iop_64to8, binop(Iop_And64,
7023 mkexpr(op2addr), mkU64(63)))));
7024 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
7025 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
7026
7027 return "srdl";
7028}
7029
7030static HChar *
7031s390_irgen_SRA(UChar r1, IRTemp op2addr)
7032{
7033 IRTemp result = newTemp(Ity_I32);
7034 IRTemp op = newTemp(Ity_I32);
7035
7036 assign(op, get_gpr_w1(r1));
7037 assign(result, binop(Iop_Sar32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7038 mkexpr(op2addr), mkU64(63)))));
7039 put_gpr_w1(r1, mkexpr(result));
7040 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7041
7042 return "sra";
7043}
7044
7045static HChar *
7046s390_irgen_SRAK(UChar r1, UChar r3, IRTemp op2addr)
7047{
7048 IRTemp result = newTemp(Ity_I32);
7049 IRTemp op = newTemp(Ity_I32);
7050
7051 assign(op, get_gpr_w1(r3));
7052 assign(result, binop(Iop_Sar32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7053 mkexpr(op2addr), mkU64(63)))));
7054 put_gpr_w1(r1, mkexpr(result));
7055 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7056
7057 return "srak";
7058}
7059
7060static HChar *
7061s390_irgen_SRAG(UChar r1, UChar r3, IRTemp op2addr)
7062{
7063 IRTemp result = newTemp(Ity_I64);
7064 IRTemp op = newTemp(Ity_I64);
7065
7066 assign(op, get_gpr_dw0(r3));
7067 assign(result, binop(Iop_Sar64, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7068 mkexpr(op2addr), mkU64(63)))));
7069 put_gpr_dw0(r1, mkexpr(result));
7070 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7071
7072 return "srag";
7073}
7074
7075static HChar *
7076s390_irgen_SRL(UChar r1, IRTemp op2addr)
7077{
7078 IRTemp op = newTemp(Ity_I32);
7079
7080 assign(op, get_gpr_w1(r1));
7081 put_gpr_w1(r1, binop(Iop_Shr32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7082 mkexpr(op2addr), mkU64(63)))));
7083
7084 return "srl";
7085}
7086
7087static HChar *
7088s390_irgen_SRLK(UChar r1, UChar r3, IRTemp op2addr)
7089{
7090 IRTemp op = newTemp(Ity_I32);
7091
7092 assign(op, get_gpr_w1(r3));
7093 put_gpr_w1(r1, binop(Iop_Shr32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7094 mkexpr(op2addr), mkU64(63)))));
7095
7096 return "srlk";
7097}
7098
7099static HChar *
7100s390_irgen_SRLG(UChar r1, UChar r3, IRTemp op2addr)
7101{
7102 IRTemp op = newTemp(Ity_I64);
7103
7104 assign(op, get_gpr_dw0(r3));
7105 put_gpr_dw0(r1, binop(Iop_Shr64, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7106 mkexpr(op2addr), mkU64(63)))));
7107
7108 return "srlg";
7109}
7110
7111static HChar *
7112s390_irgen_ST(UChar r1, IRTemp op2addr)
7113{
7114 store(mkexpr(op2addr), get_gpr_w1(r1));
7115
7116 return "st";
7117}
7118
7119static HChar *
7120s390_irgen_STY(UChar r1, IRTemp op2addr)
7121{
7122 store(mkexpr(op2addr), get_gpr_w1(r1));
7123
7124 return "sty";
7125}
7126
7127static HChar *
7128s390_irgen_STG(UChar r1, IRTemp op2addr)
7129{
7130 store(mkexpr(op2addr), get_gpr_dw0(r1));
7131
7132 return "stg";
7133}
7134
7135static HChar *
7136s390_irgen_STRL(UChar r1, UInt i2)
7137{
7138 store(mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)),
7139 get_gpr_w1(r1));
7140
7141 return "strl";
7142}
7143
7144static HChar *
7145s390_irgen_STGRL(UChar r1, UInt i2)
7146{
7147 store(mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)),
7148 get_gpr_dw0(r1));
7149
7150 return "stgrl";
7151}
7152
7153static HChar *
7154s390_irgen_STC(UChar r1, IRTemp op2addr)
7155{
7156 store(mkexpr(op2addr), get_gpr_b7(r1));
7157
7158 return "stc";
7159}
7160
7161static HChar *
7162s390_irgen_STCY(UChar r1, IRTemp op2addr)
7163{
7164 store(mkexpr(op2addr), get_gpr_b7(r1));
7165
7166 return "stcy";
7167}
7168
7169static HChar *
7170s390_irgen_STCH(UChar r1, IRTemp op2addr)
7171{
7172 store(mkexpr(op2addr), get_gpr_b3(r1));
7173
7174 return "stch";
7175}
7176
7177static HChar *
7178s390_irgen_STCM(UChar r1, UChar r3, IRTemp op2addr)
7179{
7180 UChar mask;
7181 UChar n;
7182
7183 mask = (UChar)r3;
7184 n = 0;
7185 if ((mask & 8) != 0) {
7186 store(mkexpr(op2addr), get_gpr_b4(r1));
7187 n = n + 1;
7188 }
7189 if ((mask & 4) != 0) {
7190 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b5(r1));
7191 n = n + 1;
7192 }
7193 if ((mask & 2) != 0) {
7194 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b6(r1));
7195 n = n + 1;
7196 }
7197 if ((mask & 1) != 0) {
7198 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b7(r1));
7199 }
7200
7201 return "stcm";
7202}
7203
7204static HChar *
7205s390_irgen_STCMY(UChar r1, UChar r3, IRTemp op2addr)
7206{
7207 UChar mask;
7208 UChar n;
7209
7210 mask = (UChar)r3;
7211 n = 0;
7212 if ((mask & 8) != 0) {
7213 store(mkexpr(op2addr), get_gpr_b4(r1));
7214 n = n + 1;
7215 }
7216 if ((mask & 4) != 0) {
7217 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b5(r1));
7218 n = n + 1;
7219 }
7220 if ((mask & 2) != 0) {
7221 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b6(r1));
7222 n = n + 1;
7223 }
7224 if ((mask & 1) != 0) {
7225 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b7(r1));
7226 }
7227
7228 return "stcmy";
7229}
7230
7231static HChar *
7232s390_irgen_STCMH(UChar r1, UChar r3, IRTemp op2addr)
7233{
7234 UChar mask;
7235 UChar n;
7236
7237 mask = (UChar)r3;
7238 n = 0;
7239 if ((mask & 8) != 0) {
7240 store(mkexpr(op2addr), get_gpr_b0(r1));
7241 n = n + 1;
7242 }
7243 if ((mask & 4) != 0) {
7244 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b1(r1));
7245 n = n + 1;
7246 }
7247 if ((mask & 2) != 0) {
7248 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b2(r1));
7249 n = n + 1;
7250 }
7251 if ((mask & 1) != 0) {
7252 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b3(r1));
7253 }
7254
7255 return "stcmh";
7256}
7257
7258static HChar *
7259s390_irgen_STH(UChar r1, IRTemp op2addr)
7260{
7261 store(mkexpr(op2addr), get_gpr_hw3(r1));
7262
7263 return "sth";
7264}
7265
7266static HChar *
7267s390_irgen_STHY(UChar r1, IRTemp op2addr)
7268{
7269 store(mkexpr(op2addr), get_gpr_hw3(r1));
7270
7271 return "sthy";
7272}
7273
7274static HChar *
7275s390_irgen_STHRL(UChar r1, UInt i2)
7276{
7277 store(mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)),
7278 get_gpr_hw3(r1));
7279
7280 return "sthrl";
7281}
7282
7283static HChar *
7284s390_irgen_STHH(UChar r1, IRTemp op2addr)
7285{
7286 store(mkexpr(op2addr), get_gpr_hw1(r1));
7287
7288 return "sthh";
7289}
7290
7291static HChar *
7292s390_irgen_STFH(UChar r1, IRTemp op2addr)
7293{
7294 store(mkexpr(op2addr), get_gpr_w0(r1));
7295
7296 return "stfh";
7297}
7298
7299static HChar *
sewardjd7bde722011-04-05 13:19:33 +00007300s390_irgen_STOC(UChar r1, IRTemp op2addr)
7301{
7302 /* condition is checked in format handler */
7303 store(mkexpr(op2addr), get_gpr_w1(r1));
7304
7305 return "stoc";
7306}
7307
7308static HChar *
7309s390_irgen_STOCG(UChar r1, IRTemp op2addr)
7310{
7311 /* condition is checked in format handler */
7312 store(mkexpr(op2addr), get_gpr_dw0(r1));
7313
7314 return "stocg";
7315}
7316
7317static HChar *
sewardj2019a972011-03-07 16:04:07 +00007318s390_irgen_STPQ(UChar r1, IRTemp op2addr)
7319{
7320 store(mkexpr(op2addr), get_gpr_dw0(r1));
7321 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(8)), get_gpr_dw0(r1 + 1));
7322
7323 return "stpq";
7324}
7325
7326static HChar *
7327s390_irgen_STRVH(UChar r1, IRTemp op2addr)
7328{
7329 store(mkexpr(op2addr), get_gpr_b7(r1));
7330 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(1)), get_gpr_b6(r1));
7331
7332 return "strvh";
7333}
7334
7335static HChar *
7336s390_irgen_STRV(UChar r1, IRTemp op2addr)
7337{
7338 store(mkexpr(op2addr), get_gpr_b7(r1));
7339 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(1)), get_gpr_b6(r1));
7340 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(2)), get_gpr_b5(r1));
7341 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(3)), get_gpr_b4(r1));
7342
7343 return "strv";
7344}
7345
7346static HChar *
7347s390_irgen_STRVG(UChar r1, IRTemp op2addr)
7348{
7349 store(mkexpr(op2addr), get_gpr_b7(r1));
7350 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(1)), get_gpr_b6(r1));
7351 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(2)), get_gpr_b5(r1));
7352 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(3)), get_gpr_b4(r1));
7353 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(4)), get_gpr_b3(r1));
7354 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(5)), get_gpr_b2(r1));
7355 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(6)), get_gpr_b1(r1));
7356 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(7)), get_gpr_b0(r1));
7357
7358 return "strvg";
7359}
7360
7361static HChar *
7362s390_irgen_SR(UChar r1, UChar r2)
7363{
7364 IRTemp op1 = newTemp(Ity_I32);
7365 IRTemp op2 = newTemp(Ity_I32);
7366 IRTemp result = newTemp(Ity_I32);
7367
7368 assign(op1, get_gpr_w1(r1));
7369 assign(op2, get_gpr_w1(r2));
7370 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7371 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
7372 put_gpr_w1(r1, mkexpr(result));
7373
7374 return "sr";
7375}
7376
7377static HChar *
7378s390_irgen_SGR(UChar r1, UChar r2)
7379{
7380 IRTemp op1 = newTemp(Ity_I64);
7381 IRTemp op2 = newTemp(Ity_I64);
7382 IRTemp result = newTemp(Ity_I64);
7383
7384 assign(op1, get_gpr_dw0(r1));
7385 assign(op2, get_gpr_dw0(r2));
7386 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7387 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
7388 put_gpr_dw0(r1, mkexpr(result));
7389
7390 return "sgr";
7391}
7392
7393static HChar *
7394s390_irgen_SGFR(UChar r1, UChar r2)
7395{
7396 IRTemp op1 = newTemp(Ity_I64);
7397 IRTemp op2 = newTemp(Ity_I64);
7398 IRTemp result = newTemp(Ity_I64);
7399
7400 assign(op1, get_gpr_dw0(r1));
7401 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
7402 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7403 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
7404 put_gpr_dw0(r1, mkexpr(result));
7405
7406 return "sgfr";
7407}
7408
7409static HChar *
7410s390_irgen_SRK(UChar r3, UChar r1, UChar r2)
7411{
7412 IRTemp op2 = newTemp(Ity_I32);
7413 IRTemp op3 = newTemp(Ity_I32);
7414 IRTemp result = newTemp(Ity_I32);
7415
7416 assign(op2, get_gpr_w1(r2));
7417 assign(op3, get_gpr_w1(r3));
7418 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
7419 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op2, op3);
7420 put_gpr_w1(r1, mkexpr(result));
7421
7422 return "srk";
7423}
7424
7425static HChar *
7426s390_irgen_SGRK(UChar r3, UChar r1, UChar r2)
7427{
7428 IRTemp op2 = newTemp(Ity_I64);
7429 IRTemp op3 = newTemp(Ity_I64);
7430 IRTemp result = newTemp(Ity_I64);
7431
7432 assign(op2, get_gpr_dw0(r2));
7433 assign(op3, get_gpr_dw0(r3));
7434 assign(result, binop(Iop_Sub64, mkexpr(op2), mkexpr(op3)));
7435 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op2, op3);
7436 put_gpr_dw0(r1, mkexpr(result));
7437
7438 return "sgrk";
7439}
7440
7441static HChar *
7442s390_irgen_S(UChar r1, IRTemp op2addr)
7443{
7444 IRTemp op1 = newTemp(Ity_I32);
7445 IRTemp op2 = newTemp(Ity_I32);
7446 IRTemp result = newTemp(Ity_I32);
7447
7448 assign(op1, get_gpr_w1(r1));
7449 assign(op2, load(Ity_I32, mkexpr(op2addr)));
7450 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7451 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
7452 put_gpr_w1(r1, mkexpr(result));
7453
7454 return "s";
7455}
7456
7457static HChar *
7458s390_irgen_SY(UChar r1, IRTemp op2addr)
7459{
7460 IRTemp op1 = newTemp(Ity_I32);
7461 IRTemp op2 = newTemp(Ity_I32);
7462 IRTemp result = newTemp(Ity_I32);
7463
7464 assign(op1, get_gpr_w1(r1));
7465 assign(op2, load(Ity_I32, mkexpr(op2addr)));
7466 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7467 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
7468 put_gpr_w1(r1, mkexpr(result));
7469
7470 return "sy";
7471}
7472
7473static HChar *
7474s390_irgen_SG(UChar r1, IRTemp op2addr)
7475{
7476 IRTemp op1 = newTemp(Ity_I64);
7477 IRTemp op2 = newTemp(Ity_I64);
7478 IRTemp result = newTemp(Ity_I64);
7479
7480 assign(op1, get_gpr_dw0(r1));
7481 assign(op2, load(Ity_I64, mkexpr(op2addr)));
7482 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7483 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
7484 put_gpr_dw0(r1, mkexpr(result));
7485
7486 return "sg";
7487}
7488
7489static HChar *
7490s390_irgen_SGF(UChar r1, IRTemp op2addr)
7491{
7492 IRTemp op1 = newTemp(Ity_I64);
7493 IRTemp op2 = newTemp(Ity_I64);
7494 IRTemp result = newTemp(Ity_I64);
7495
7496 assign(op1, get_gpr_dw0(r1));
7497 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
7498 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7499 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
7500 put_gpr_dw0(r1, mkexpr(result));
7501
7502 return "sgf";
7503}
7504
7505static HChar *
7506s390_irgen_SH(UChar r1, IRTemp op2addr)
7507{
7508 IRTemp op1 = newTemp(Ity_I32);
7509 IRTemp op2 = newTemp(Ity_I32);
7510 IRTemp result = newTemp(Ity_I32);
7511
7512 assign(op1, get_gpr_w1(r1));
7513 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
7514 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7515 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
7516 put_gpr_w1(r1, mkexpr(result));
7517
7518 return "sh";
7519}
7520
7521static HChar *
7522s390_irgen_SHY(UChar r1, IRTemp op2addr)
7523{
7524 IRTemp op1 = newTemp(Ity_I32);
7525 IRTemp op2 = newTemp(Ity_I32);
7526 IRTemp result = newTemp(Ity_I32);
7527
7528 assign(op1, get_gpr_w1(r1));
7529 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
7530 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7531 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
7532 put_gpr_w1(r1, mkexpr(result));
7533
7534 return "shy";
7535}
7536
7537static HChar *
7538s390_irgen_SHHHR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
7539{
7540 IRTemp op2 = newTemp(Ity_I32);
7541 IRTemp op3 = newTemp(Ity_I32);
7542 IRTemp result = newTemp(Ity_I32);
7543
7544 assign(op2, get_gpr_w0(r1));
7545 assign(op3, get_gpr_w0(r2));
7546 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
7547 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op2, op3);
7548 put_gpr_w0(r1, mkexpr(result));
7549
7550 return "shhhr";
7551}
7552
7553static HChar *
7554s390_irgen_SHHLR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
7555{
7556 IRTemp op2 = newTemp(Ity_I32);
7557 IRTemp op3 = newTemp(Ity_I32);
7558 IRTemp result = newTemp(Ity_I32);
7559
7560 assign(op2, get_gpr_w0(r1));
7561 assign(op3, get_gpr_w1(r2));
7562 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
7563 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op2, op3);
7564 put_gpr_w0(r1, mkexpr(result));
7565
7566 return "shhlr";
7567}
7568
7569static HChar *
7570s390_irgen_SLR(UChar r1, UChar r2)
7571{
7572 IRTemp op1 = newTemp(Ity_I32);
7573 IRTemp op2 = newTemp(Ity_I32);
7574 IRTemp result = newTemp(Ity_I32);
7575
7576 assign(op1, get_gpr_w1(r1));
7577 assign(op2, get_gpr_w1(r2));
7578 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7579 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, op2);
7580 put_gpr_w1(r1, mkexpr(result));
7581
7582 return "slr";
7583}
7584
7585static HChar *
7586s390_irgen_SLGR(UChar r1, UChar r2)
7587{
7588 IRTemp op1 = newTemp(Ity_I64);
7589 IRTemp op2 = newTemp(Ity_I64);
7590 IRTemp result = newTemp(Ity_I64);
7591
7592 assign(op1, get_gpr_dw0(r1));
7593 assign(op2, get_gpr_dw0(r2));
7594 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7595 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
7596 put_gpr_dw0(r1, mkexpr(result));
7597
7598 return "slgr";
7599}
7600
7601static HChar *
7602s390_irgen_SLGFR(UChar r1, UChar r2)
7603{
7604 IRTemp op1 = newTemp(Ity_I64);
7605 IRTemp op2 = newTemp(Ity_I64);
7606 IRTemp result = newTemp(Ity_I64);
7607
7608 assign(op1, get_gpr_dw0(r1));
7609 assign(op2, unop(Iop_32Uto64, get_gpr_w1(r2)));
7610 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7611 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
7612 put_gpr_dw0(r1, mkexpr(result));
7613
7614 return "slgfr";
7615}
7616
7617static HChar *
7618s390_irgen_SLRK(UChar r3, UChar r1, UChar r2)
7619{
7620 IRTemp op2 = newTemp(Ity_I32);
7621 IRTemp op3 = newTemp(Ity_I32);
7622 IRTemp result = newTemp(Ity_I32);
7623
7624 assign(op2, get_gpr_w1(r2));
7625 assign(op3, get_gpr_w1(r3));
7626 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
7627 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op2, op3);
7628 put_gpr_w1(r1, mkexpr(result));
7629
7630 return "slrk";
7631}
7632
7633static HChar *
7634s390_irgen_SLGRK(UChar r3, UChar r1, UChar r2)
7635{
7636 IRTemp op2 = newTemp(Ity_I64);
7637 IRTemp op3 = newTemp(Ity_I64);
7638 IRTemp result = newTemp(Ity_I64);
7639
7640 assign(op2, get_gpr_dw0(r2));
7641 assign(op3, get_gpr_dw0(r3));
7642 assign(result, binop(Iop_Sub64, mkexpr(op2), mkexpr(op3)));
7643 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op2, op3);
7644 put_gpr_dw0(r1, mkexpr(result));
7645
7646 return "slgrk";
7647}
7648
7649static HChar *
7650s390_irgen_SL(UChar r1, IRTemp op2addr)
7651{
7652 IRTemp op1 = newTemp(Ity_I32);
7653 IRTemp op2 = newTemp(Ity_I32);
7654 IRTemp result = newTemp(Ity_I32);
7655
7656 assign(op1, get_gpr_w1(r1));
7657 assign(op2, load(Ity_I32, mkexpr(op2addr)));
7658 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7659 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, op2);
7660 put_gpr_w1(r1, mkexpr(result));
7661
7662 return "sl";
7663}
7664
7665static HChar *
7666s390_irgen_SLY(UChar r1, IRTemp op2addr)
7667{
7668 IRTemp op1 = newTemp(Ity_I32);
7669 IRTemp op2 = newTemp(Ity_I32);
7670 IRTemp result = newTemp(Ity_I32);
7671
7672 assign(op1, get_gpr_w1(r1));
7673 assign(op2, load(Ity_I32, mkexpr(op2addr)));
7674 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7675 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, op2);
7676 put_gpr_w1(r1, mkexpr(result));
7677
7678 return "sly";
7679}
7680
7681static HChar *
7682s390_irgen_SLG(UChar r1, IRTemp op2addr)
7683{
7684 IRTemp op1 = newTemp(Ity_I64);
7685 IRTemp op2 = newTemp(Ity_I64);
7686 IRTemp result = newTemp(Ity_I64);
7687
7688 assign(op1, get_gpr_dw0(r1));
7689 assign(op2, load(Ity_I64, mkexpr(op2addr)));
7690 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7691 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
7692 put_gpr_dw0(r1, mkexpr(result));
7693
7694 return "slg";
7695}
7696
7697static HChar *
7698s390_irgen_SLGF(UChar r1, IRTemp op2addr)
7699{
7700 IRTemp op1 = newTemp(Ity_I64);
7701 IRTemp op2 = newTemp(Ity_I64);
7702 IRTemp result = newTemp(Ity_I64);
7703
7704 assign(op1, get_gpr_dw0(r1));
7705 assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
7706 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7707 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
7708 put_gpr_dw0(r1, mkexpr(result));
7709
7710 return "slgf";
7711}
7712
7713static HChar *
7714s390_irgen_SLFI(UChar r1, UInt i2)
7715{
7716 IRTemp op1 = newTemp(Ity_I32);
7717 UInt op2;
7718 IRTemp result = newTemp(Ity_I32);
7719
7720 assign(op1, get_gpr_w1(r1));
7721 op2 = i2;
7722 assign(result, binop(Iop_Sub32, mkexpr(op1), mkU32(op2)));
7723 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, mktemp(Ity_I32,
7724 mkU32(op2)));
7725 put_gpr_w1(r1, mkexpr(result));
7726
7727 return "slfi";
7728}
7729
7730static HChar *
7731s390_irgen_SLGFI(UChar r1, UInt i2)
7732{
7733 IRTemp op1 = newTemp(Ity_I64);
7734 ULong op2;
7735 IRTemp result = newTemp(Ity_I64);
7736
7737 assign(op1, get_gpr_dw0(r1));
7738 op2 = (ULong)i2;
7739 assign(result, binop(Iop_Sub64, mkexpr(op1), mkU64(op2)));
7740 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, mktemp(Ity_I64,
7741 mkU64(op2)));
7742 put_gpr_dw0(r1, mkexpr(result));
7743
7744 return "slgfi";
7745}
7746
7747static HChar *
7748s390_irgen_SLHHHR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
7749{
7750 IRTemp op2 = newTemp(Ity_I32);
7751 IRTemp op3 = newTemp(Ity_I32);
7752 IRTemp result = newTemp(Ity_I32);
7753
7754 assign(op2, get_gpr_w0(r1));
7755 assign(op3, get_gpr_w0(r2));
7756 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
7757 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op2, op3);
7758 put_gpr_w0(r1, mkexpr(result));
7759
7760 return "slhhhr";
7761}
7762
7763static HChar *
7764s390_irgen_SLHHLR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
7765{
7766 IRTemp op2 = newTemp(Ity_I32);
7767 IRTemp op3 = newTemp(Ity_I32);
7768 IRTemp result = newTemp(Ity_I32);
7769
7770 assign(op2, get_gpr_w0(r1));
7771 assign(op3, get_gpr_w1(r2));
7772 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
7773 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op2, op3);
7774 put_gpr_w0(r1, mkexpr(result));
7775
7776 return "slhhlr";
7777}
7778
7779static HChar *
7780s390_irgen_SLBR(UChar r1, UChar r2)
7781{
7782 IRTemp op1 = newTemp(Ity_I32);
7783 IRTemp op2 = newTemp(Ity_I32);
7784 IRTemp result = newTemp(Ity_I32);
7785 IRTemp borrow_in = newTemp(Ity_I32);
7786
7787 assign(op1, get_gpr_w1(r1));
7788 assign(op2, get_gpr_w1(r2));
7789 assign(borrow_in, binop(Iop_Sub32, mkU32(1), binop(Iop_Shr32,
7790 s390_call_calculate_cc(), mkU8(1))));
7791 assign(result, binop(Iop_Sub32, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)),
7792 mkexpr(borrow_in)));
7793 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_32, op1, op2, borrow_in);
7794 put_gpr_w1(r1, mkexpr(result));
7795
7796 return "slbr";
7797}
7798
7799static HChar *
7800s390_irgen_SLBGR(UChar r1, UChar r2)
7801{
7802 IRTemp op1 = newTemp(Ity_I64);
7803 IRTemp op2 = newTemp(Ity_I64);
7804 IRTemp result = newTemp(Ity_I64);
7805 IRTemp borrow_in = newTemp(Ity_I64);
7806
7807 assign(op1, get_gpr_dw0(r1));
7808 assign(op2, get_gpr_dw0(r2));
7809 assign(borrow_in, unop(Iop_32Uto64, binop(Iop_Sub32, mkU32(1),
7810 binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)))));
7811 assign(result, binop(Iop_Sub64, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)),
7812 mkexpr(borrow_in)));
7813 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_64, op1, op2, borrow_in);
7814 put_gpr_dw0(r1, mkexpr(result));
7815
7816 return "slbgr";
7817}
7818
7819static HChar *
7820s390_irgen_SLB(UChar r1, IRTemp op2addr)
7821{
7822 IRTemp op1 = newTemp(Ity_I32);
7823 IRTemp op2 = newTemp(Ity_I32);
7824 IRTemp result = newTemp(Ity_I32);
7825 IRTemp borrow_in = newTemp(Ity_I32);
7826
7827 assign(op1, get_gpr_w1(r1));
7828 assign(op2, load(Ity_I32, mkexpr(op2addr)));
7829 assign(borrow_in, binop(Iop_Sub32, mkU32(1), binop(Iop_Shr32,
7830 s390_call_calculate_cc(), mkU8(1))));
7831 assign(result, binop(Iop_Sub32, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)),
7832 mkexpr(borrow_in)));
7833 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_32, op1, op2, borrow_in);
7834 put_gpr_w1(r1, mkexpr(result));
7835
7836 return "slb";
7837}
7838
7839static HChar *
7840s390_irgen_SLBG(UChar r1, IRTemp op2addr)
7841{
7842 IRTemp op1 = newTemp(Ity_I64);
7843 IRTemp op2 = newTemp(Ity_I64);
7844 IRTemp result = newTemp(Ity_I64);
7845 IRTemp borrow_in = newTemp(Ity_I64);
7846
7847 assign(op1, get_gpr_dw0(r1));
7848 assign(op2, load(Ity_I64, mkexpr(op2addr)));
7849 assign(borrow_in, unop(Iop_32Uto64, binop(Iop_Sub32, mkU32(1),
7850 binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)))));
7851 assign(result, binop(Iop_Sub64, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)),
7852 mkexpr(borrow_in)));
7853 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_64, op1, op2, borrow_in);
7854 put_gpr_dw0(r1, mkexpr(result));
7855
7856 return "slbg";
7857}
7858
7859static HChar *
7860s390_irgen_SVC(UChar i)
7861{
7862 IRTemp sysno = newTemp(Ity_I64);
7863
7864 if (i != 0) {
7865 assign(sysno, mkU64(i));
7866 } else {
7867 assign(sysno, unop(Iop_32Uto64, get_gpr_w1(1)));
7868 }
7869 system_call(mkexpr(sysno));
7870
7871 return "svc";
7872}
7873
7874static HChar *
sewardj2019a972011-03-07 16:04:07 +00007875s390_irgen_TM(UChar i2, IRTemp op1addr)
7876{
7877 UChar mask;
7878 IRTemp value = newTemp(Ity_I8);
7879
7880 mask = i2;
7881 assign(value, load(Ity_I8, mkexpr(op1addr)));
7882 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_8, value, mktemp(Ity_I8,
7883 mkU8(mask)));
7884
7885 return "tm";
7886}
7887
7888static HChar *
7889s390_irgen_TMY(UChar i2, IRTemp op1addr)
7890{
7891 UChar mask;
7892 IRTemp value = newTemp(Ity_I8);
7893
7894 mask = i2;
7895 assign(value, load(Ity_I8, mkexpr(op1addr)));
7896 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_8, value, mktemp(Ity_I8,
7897 mkU8(mask)));
7898
7899 return "tmy";
7900}
7901
7902static HChar *
7903s390_irgen_TMHH(UChar r1, UShort i2)
7904{
7905 UShort mask;
7906 IRTemp value = newTemp(Ity_I16);
7907
7908 mask = i2;
7909 assign(value, get_gpr_hw0(r1));
7910 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
7911 mkU16(mask)));
7912
7913 return "tmhh";
7914}
7915
7916static HChar *
7917s390_irgen_TMHL(UChar r1, UShort i2)
7918{
7919 UShort mask;
7920 IRTemp value = newTemp(Ity_I16);
7921
7922 mask = i2;
7923 assign(value, get_gpr_hw1(r1));
7924 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
7925 mkU16(mask)));
7926
7927 return "tmhl";
7928}
7929
7930static HChar *
7931s390_irgen_TMLH(UChar r1, UShort i2)
7932{
7933 UShort mask;
7934 IRTemp value = newTemp(Ity_I16);
7935
7936 mask = i2;
7937 assign(value, get_gpr_hw2(r1));
7938 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
7939 mkU16(mask)));
7940
7941 return "tmlh";
7942}
7943
7944static HChar *
7945s390_irgen_TMLL(UChar r1, UShort i2)
7946{
7947 UShort mask;
7948 IRTemp value = newTemp(Ity_I16);
7949
7950 mask = i2;
7951 assign(value, get_gpr_hw3(r1));
7952 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
7953 mkU16(mask)));
7954
7955 return "tmll";
7956}
7957
7958static HChar *
7959s390_irgen_EFPC(UChar r1)
7960{
7961 put_gpr_w1(r1, get_fpc_w0());
7962
7963 return "efpc";
7964}
7965
7966static HChar *
7967s390_irgen_LER(UChar r1, UChar r2)
7968{
7969 put_fpr_w0(r1, get_fpr_w0(r2));
7970
7971 return "ler";
7972}
7973
7974static HChar *
7975s390_irgen_LDR(UChar r1, UChar r2)
7976{
7977 put_fpr_dw0(r1, get_fpr_dw0(r2));
7978
7979 return "ldr";
7980}
7981
7982static HChar *
7983s390_irgen_LXR(UChar r1, UChar r2)
7984{
7985 put_fpr_dw0(r1, get_fpr_dw0(r2));
7986 put_fpr_dw0(r1 + 2, get_fpr_dw0(r2 + 2));
7987
7988 return "lxr";
7989}
7990
7991static HChar *
7992s390_irgen_LE(UChar r1, IRTemp op2addr)
7993{
7994 put_fpr_w0(r1, load(Ity_F32, mkexpr(op2addr)));
7995
7996 return "le";
7997}
7998
7999static HChar *
8000s390_irgen_LD(UChar r1, IRTemp op2addr)
8001{
8002 put_fpr_dw0(r1, load(Ity_F64, mkexpr(op2addr)));
8003
8004 return "ld";
8005}
8006
8007static HChar *
8008s390_irgen_LEY(UChar r1, IRTemp op2addr)
8009{
8010 put_fpr_w0(r1, load(Ity_F32, mkexpr(op2addr)));
8011
8012 return "ley";
8013}
8014
8015static HChar *
8016s390_irgen_LDY(UChar r1, IRTemp op2addr)
8017{
8018 put_fpr_dw0(r1, load(Ity_F64, mkexpr(op2addr)));
8019
8020 return "ldy";
8021}
8022
8023static HChar *
8024s390_irgen_LFPC(IRTemp op2addr)
8025{
8026 put_fpc_w0(load(Ity_I32, mkexpr(op2addr)));
8027
8028 return "lfpc";
8029}
8030
8031static HChar *
8032s390_irgen_LZER(UChar r1)
8033{
8034 put_fpr_w0(r1, mkF32i(0x0));
8035
8036 return "lzer";
8037}
8038
8039static HChar *
8040s390_irgen_LZDR(UChar r1)
8041{
8042 put_fpr_dw0(r1, mkF64i(0x0));
8043
8044 return "lzdr";
8045}
8046
8047static HChar *
8048s390_irgen_LZXR(UChar r1)
8049{
8050 put_fpr_dw0(r1, mkF64i(0x0));
8051 put_fpr_dw0(r1 + 2, mkF64i(0x0));
8052
8053 return "lzxr";
8054}
8055
8056static HChar *
8057s390_irgen_SRNM(IRTemp op2addr)
8058{
8059 UInt mask;
8060
8061 mask = 3;
8062 put_fpc_w0(binop(Iop_Or32, binop(Iop_And32, get_fpc_w0(), mkU32(~mask)),
8063 binop(Iop_And32, unop(Iop_64to32, mkexpr(op2addr)), mkU32(mask)))
8064 );
8065
8066 return "srnm";
8067}
8068
8069static HChar *
8070s390_irgen_SFPC(UChar r1)
8071{
8072 put_fpc_w0(get_gpr_w1(r1));
8073
8074 return "sfpc";
8075}
8076
8077static HChar *
8078s390_irgen_STE(UChar r1, IRTemp op2addr)
8079{
8080 store(mkexpr(op2addr), get_fpr_w0(r1));
8081
8082 return "ste";
8083}
8084
8085static HChar *
8086s390_irgen_STD(UChar r1, IRTemp op2addr)
8087{
8088 store(mkexpr(op2addr), get_fpr_dw0(r1));
8089
8090 return "std";
8091}
8092
8093static HChar *
8094s390_irgen_STEY(UChar r1, IRTemp op2addr)
8095{
8096 store(mkexpr(op2addr), get_fpr_w0(r1));
8097
8098 return "stey";
8099}
8100
8101static HChar *
8102s390_irgen_STDY(UChar r1, IRTemp op2addr)
8103{
8104 store(mkexpr(op2addr), get_fpr_dw0(r1));
8105
8106 return "stdy";
8107}
8108
8109static HChar *
8110s390_irgen_STFPC(IRTemp op2addr)
8111{
8112 store(mkexpr(op2addr), get_fpc_w0());
8113
8114 return "stfpc";
8115}
8116
8117static HChar *
8118s390_irgen_AEBR(UChar r1, UChar r2)
8119{
8120 IRTemp op1 = newTemp(Ity_F32);
8121 IRTemp op2 = newTemp(Ity_F32);
8122 IRTemp result = newTemp(Ity_F32);
8123
8124 assign(op1, get_fpr_w0(r1));
8125 assign(op2, get_fpr_w0(r2));
8126 assign(result, triop(Iop_AddF32, mkU32(Irrm_NEAREST), mkexpr(op1),
8127 mkexpr(op2)));
8128 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
8129 put_fpr_w0(r1, mkexpr(result));
8130
8131 return "aebr";
8132}
8133
8134static HChar *
8135s390_irgen_ADBR(UChar r1, UChar r2)
8136{
8137 IRTemp op1 = newTemp(Ity_F64);
8138 IRTemp op2 = newTemp(Ity_F64);
8139 IRTemp result = newTemp(Ity_F64);
8140
8141 assign(op1, get_fpr_dw0(r1));
8142 assign(op2, get_fpr_dw0(r2));
8143 assign(result, triop(Iop_AddF64, mkU32(Irrm_NEAREST), mkexpr(op1),
8144 mkexpr(op2)));
8145 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
8146 put_fpr_dw0(r1, mkexpr(result));
8147
8148 return "adbr";
8149}
8150
8151static HChar *
8152s390_irgen_AEB(UChar r1, IRTemp op2addr)
8153{
8154 IRTemp op1 = newTemp(Ity_F32);
8155 IRTemp op2 = newTemp(Ity_F32);
8156 IRTemp result = newTemp(Ity_F32);
8157
8158 assign(op1, get_fpr_w0(r1));
8159 assign(op2, load(Ity_F32, mkexpr(op2addr)));
8160 assign(result, triop(Iop_AddF32, mkU32(Irrm_NEAREST), mkexpr(op1),
8161 mkexpr(op2)));
8162 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
8163 put_fpr_w0(r1, mkexpr(result));
8164
8165 return "aeb";
8166}
8167
8168static HChar *
8169s390_irgen_ADB(UChar r1, IRTemp op2addr)
8170{
8171 IRTemp op1 = newTemp(Ity_F64);
8172 IRTemp op2 = newTemp(Ity_F64);
8173 IRTemp result = newTemp(Ity_F64);
8174
8175 assign(op1, get_fpr_dw0(r1));
8176 assign(op2, load(Ity_F64, mkexpr(op2addr)));
8177 assign(result, triop(Iop_AddF64, mkU32(Irrm_NEAREST), mkexpr(op1),
8178 mkexpr(op2)));
8179 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
8180 put_fpr_dw0(r1, mkexpr(result));
8181
8182 return "adb";
8183}
8184
8185static HChar *
8186s390_irgen_CEFBR(UChar r1, UChar r2)
8187{
8188 IRTemp op2 = newTemp(Ity_I32);
8189
8190 assign(op2, get_gpr_w1(r2));
8191 put_fpr_w0(r1, binop(Iop_I32StoF32, mkU32(Irrm_NEAREST), mkexpr(op2)));
8192
8193 return "cefbr";
8194}
8195
8196static HChar *
8197s390_irgen_CDFBR(UChar r1, UChar r2)
8198{
8199 IRTemp op2 = newTemp(Ity_I32);
8200
8201 assign(op2, get_gpr_w1(r2));
8202 put_fpr_dw0(r1, unop(Iop_I32StoF64, mkexpr(op2)));
8203
8204 return "cdfbr";
8205}
8206
8207static HChar *
8208s390_irgen_CEGBR(UChar r1, UChar r2)
8209{
8210 IRTemp op2 = newTemp(Ity_I64);
8211
8212 assign(op2, get_gpr_dw0(r2));
8213 put_fpr_w0(r1, binop(Iop_I64StoF32, mkU32(Irrm_NEAREST), mkexpr(op2)));
8214
8215 return "cegbr";
8216}
8217
8218static HChar *
8219s390_irgen_CDGBR(UChar r1, UChar r2)
8220{
8221 IRTemp op2 = newTemp(Ity_I64);
8222
8223 assign(op2, get_gpr_dw0(r2));
8224 put_fpr_dw0(r1, binop(Iop_I64StoF64, mkU32(Irrm_NEAREST), mkexpr(op2)));
8225
8226 return "cdgbr";
8227}
8228
8229static HChar *
8230s390_irgen_CFEBR(UChar r3, UChar r1, UChar r2)
8231{
8232 IRTemp op = newTemp(Ity_F32);
8233 IRTemp result = newTemp(Ity_I32);
8234
8235 assign(op, get_fpr_w0(r2));
8236 assign(result, binop(Iop_F32toI32S, mkU32(encode_rounding_mode(r3)),
8237 mkexpr(op)));
8238 put_gpr_w1(r1, mkexpr(result));
8239 s390_cc_thunk_putF(S390_CC_OP_BFP_32_TO_INT_32, op);
8240
8241 return "cfebr";
8242}
8243
8244static HChar *
8245s390_irgen_CFDBR(UChar r3, UChar r1, UChar r2)
8246{
8247 IRTemp op = newTemp(Ity_F64);
8248 IRTemp result = newTemp(Ity_I32);
8249
8250 assign(op, get_fpr_dw0(r2));
8251 assign(result, binop(Iop_F64toI32S, mkU32(encode_rounding_mode(r3)),
8252 mkexpr(op)));
8253 put_gpr_w1(r1, mkexpr(result));
8254 s390_cc_thunk_putF(S390_CC_OP_BFP_64_TO_INT_32, op);
8255
8256 return "cfdbr";
8257}
8258
8259static HChar *
8260s390_irgen_CGEBR(UChar r3, UChar r1, UChar r2)
8261{
8262 IRTemp op = newTemp(Ity_F32);
8263 IRTemp result = newTemp(Ity_I64);
8264
8265 assign(op, get_fpr_w0(r2));
8266 assign(result, binop(Iop_F32toI64S, mkU32(encode_rounding_mode(r3)),
8267 mkexpr(op)));
8268 put_gpr_dw0(r1, mkexpr(result));
8269 s390_cc_thunk_putF(S390_CC_OP_BFP_32_TO_INT_64, op);
8270
8271 return "cgebr";
8272}
8273
8274static HChar *
8275s390_irgen_CGDBR(UChar r3, UChar r1, UChar r2)
8276{
8277 IRTemp op = newTemp(Ity_F64);
8278 IRTemp result = newTemp(Ity_I64);
8279
8280 assign(op, get_fpr_dw0(r2));
8281 assign(result, binop(Iop_F64toI64S, mkU32(encode_rounding_mode(r3)),
8282 mkexpr(op)));
8283 put_gpr_dw0(r1, mkexpr(result));
8284 s390_cc_thunk_putF(S390_CC_OP_BFP_64_TO_INT_64, op);
8285
8286 return "cgdbr";
8287}
8288
8289static HChar *
8290s390_irgen_DEBR(UChar r1, UChar r2)
8291{
8292 IRTemp op1 = newTemp(Ity_F32);
8293 IRTemp op2 = newTemp(Ity_F32);
8294 IRTemp result = newTemp(Ity_F32);
8295
8296 assign(op1, get_fpr_w0(r1));
8297 assign(op2, get_fpr_w0(r2));
8298 assign(result, triop(Iop_DivF32, mkU32(Irrm_NEAREST), mkexpr(op1),
8299 mkexpr(op2)));
8300 put_fpr_w0(r1, mkexpr(result));
8301
8302 return "debr";
8303}
8304
8305static HChar *
8306s390_irgen_DDBR(UChar r1, UChar r2)
8307{
8308 IRTemp op1 = newTemp(Ity_F64);
8309 IRTemp op2 = newTemp(Ity_F64);
8310 IRTemp result = newTemp(Ity_F64);
8311
8312 assign(op1, get_fpr_dw0(r1));
8313 assign(op2, get_fpr_dw0(r2));
8314 assign(result, triop(Iop_DivF64, mkU32(Irrm_NEAREST), mkexpr(op1),
8315 mkexpr(op2)));
8316 put_fpr_dw0(r1, mkexpr(result));
8317
8318 return "ddbr";
8319}
8320
8321static HChar *
8322s390_irgen_DEB(UChar r1, IRTemp op2addr)
8323{
8324 IRTemp op1 = newTemp(Ity_F32);
8325 IRTemp op2 = newTemp(Ity_F32);
8326 IRTemp result = newTemp(Ity_F32);
8327
8328 assign(op1, get_fpr_w0(r1));
8329 assign(op2, load(Ity_F32, mkexpr(op2addr)));
8330 assign(result, triop(Iop_DivF32, mkU32(Irrm_NEAREST), mkexpr(op1),
8331 mkexpr(op2)));
8332 put_fpr_w0(r1, mkexpr(result));
8333
8334 return "deb";
8335}
8336
8337static HChar *
8338s390_irgen_DDB(UChar r1, IRTemp op2addr)
8339{
8340 IRTemp op1 = newTemp(Ity_F64);
8341 IRTemp op2 = newTemp(Ity_F64);
8342 IRTemp result = newTemp(Ity_F64);
8343
8344 assign(op1, get_fpr_dw0(r1));
8345 assign(op2, load(Ity_F64, mkexpr(op2addr)));
8346 assign(result, triop(Iop_DivF64, mkU32(Irrm_NEAREST), mkexpr(op1),
8347 mkexpr(op2)));
8348 put_fpr_dw0(r1, mkexpr(result));
8349
8350 return "ddb";
8351}
8352
8353static HChar *
8354s390_irgen_LTEBR(UChar r1, UChar r2)
8355{
8356 IRTemp result = newTemp(Ity_F32);
8357
8358 assign(result, get_fpr_w0(r2));
8359 put_fpr_w0(r1, mkexpr(result));
8360 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
8361
8362 return "ltebr";
8363}
8364
8365static HChar *
8366s390_irgen_LTDBR(UChar r1, UChar r2)
8367{
8368 IRTemp result = newTemp(Ity_F64);
8369
8370 assign(result, get_fpr_dw0(r2));
8371 put_fpr_dw0(r1, mkexpr(result));
8372 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
8373
8374 return "ltdbr";
8375}
8376
8377static HChar *
8378s390_irgen_LCEBR(UChar r1, UChar r2)
8379{
8380 IRTemp result = newTemp(Ity_F32);
8381
8382 assign(result, unop(Iop_NegF32, get_fpr_w0(r2)));
8383 put_fpr_w0(r1, mkexpr(result));
8384 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
8385
8386 return "lcebr";
8387}
8388
8389static HChar *
8390s390_irgen_LCDBR(UChar r1, UChar r2)
8391{
8392 IRTemp result = newTemp(Ity_F64);
8393
8394 assign(result, unop(Iop_NegF64, get_fpr_dw0(r2)));
8395 put_fpr_dw0(r1, mkexpr(result));
8396 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
8397
8398 return "lcdbr";
8399}
8400
8401static HChar *
8402s390_irgen_LDEBR(UChar r1, UChar r2)
8403{
8404 IRTemp op = newTemp(Ity_F32);
8405
8406 assign(op, get_fpr_w0(r2));
8407 put_fpr_dw0(r1, unop(Iop_F32toF64, mkexpr(op)));
8408
8409 return "ldebr";
8410}
8411
8412static HChar *
8413s390_irgen_LDEB(UChar r1, IRTemp op2addr)
8414{
8415 IRTemp op = newTemp(Ity_F32);
8416
8417 assign(op, load(Ity_F32, mkexpr(op2addr)));
8418 put_fpr_dw0(r1, unop(Iop_F32toF64, mkexpr(op)));
8419
8420 return "ldeb";
8421}
8422
8423static HChar *
8424s390_irgen_LEDBR(UChar r1, UChar r2)
8425{
8426 IRTemp op = newTemp(Ity_F64);
8427
8428 assign(op, get_fpr_dw0(r2));
8429 put_fpr_w0(r1, binop(Iop_F64toF32, mkU32(Irrm_NEAREST), mkexpr(op)));
8430
8431 return "ledbr";
8432}
8433
8434static HChar *
8435s390_irgen_MEEBR(UChar r1, UChar r2)
8436{
8437 IRTemp op1 = newTemp(Ity_F32);
8438 IRTemp op2 = newTemp(Ity_F32);
8439 IRTemp result = newTemp(Ity_F32);
8440
8441 assign(op1, get_fpr_w0(r1));
8442 assign(op2, get_fpr_w0(r2));
8443 assign(result, triop(Iop_MulF32, mkU32(Irrm_NEAREST), mkexpr(op1),
8444 mkexpr(op2)));
8445 put_fpr_w0(r1, mkexpr(result));
8446
8447 return "meebr";
8448}
8449
8450static HChar *
8451s390_irgen_MDBR(UChar r1, UChar r2)
8452{
8453 IRTemp op1 = newTemp(Ity_F64);
8454 IRTemp op2 = newTemp(Ity_F64);
8455 IRTemp result = newTemp(Ity_F64);
8456
8457 assign(op1, get_fpr_dw0(r1));
8458 assign(op2, get_fpr_dw0(r2));
8459 assign(result, triop(Iop_MulF64, mkU32(Irrm_NEAREST), mkexpr(op1),
8460 mkexpr(op2)));
8461 put_fpr_dw0(r1, mkexpr(result));
8462
8463 return "mdbr";
8464}
8465
8466static HChar *
8467s390_irgen_MEEB(UChar r1, IRTemp op2addr)
8468{
8469 IRTemp op1 = newTemp(Ity_F32);
8470 IRTemp op2 = newTemp(Ity_F32);
8471 IRTemp result = newTemp(Ity_F32);
8472
8473 assign(op1, get_fpr_w0(r1));
8474 assign(op2, load(Ity_F32, mkexpr(op2addr)));
8475 assign(result, triop(Iop_MulF32, mkU32(Irrm_NEAREST), mkexpr(op1),
8476 mkexpr(op2)));
8477 put_fpr_w0(r1, mkexpr(result));
8478
8479 return "meeb";
8480}
8481
8482static HChar *
8483s390_irgen_MDB(UChar r1, IRTemp op2addr)
8484{
8485 IRTemp op1 = newTemp(Ity_F64);
8486 IRTemp op2 = newTemp(Ity_F64);
8487 IRTemp result = newTemp(Ity_F64);
8488
8489 assign(op1, get_fpr_dw0(r1));
8490 assign(op2, load(Ity_F64, mkexpr(op2addr)));
8491 assign(result, triop(Iop_MulF64, mkU32(Irrm_NEAREST), mkexpr(op1),
8492 mkexpr(op2)));
8493 put_fpr_dw0(r1, mkexpr(result));
8494
8495 return "mdb";
8496}
8497
8498static HChar *
8499s390_irgen_SEBR(UChar r1, UChar r2)
8500{
8501 IRTemp op1 = newTemp(Ity_F32);
8502 IRTemp op2 = newTemp(Ity_F32);
8503 IRTemp result = newTemp(Ity_F32);
8504
8505 assign(op1, get_fpr_w0(r1));
8506 assign(op2, get_fpr_w0(r2));
8507 assign(result, triop(Iop_SubF32, mkU32(Irrm_NEAREST), mkexpr(op1),
8508 mkexpr(op2)));
8509 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
8510 put_fpr_w0(r1, mkexpr(result));
8511
8512 return "sebr";
8513}
8514
8515static HChar *
8516s390_irgen_SDBR(UChar r1, UChar r2)
8517{
8518 IRTemp op1 = newTemp(Ity_F64);
8519 IRTemp op2 = newTemp(Ity_F64);
8520 IRTemp result = newTemp(Ity_F64);
8521
8522 assign(op1, get_fpr_dw0(r1));
8523 assign(op2, get_fpr_dw0(r2));
8524 assign(result, triop(Iop_SubF64, mkU32(Irrm_NEAREST), mkexpr(op1),
8525 mkexpr(op2)));
8526 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
8527 put_fpr_dw0(r1, mkexpr(result));
8528
8529 return "sdbr";
8530}
8531
8532static HChar *
8533s390_irgen_SEB(UChar r1, IRTemp op2addr)
8534{
8535 IRTemp op1 = newTemp(Ity_F32);
8536 IRTemp op2 = newTemp(Ity_F32);
8537 IRTemp result = newTemp(Ity_F32);
8538
8539 assign(op1, get_fpr_w0(r1));
8540 assign(op2, load(Ity_F32, mkexpr(op2addr)));
8541 assign(result, triop(Iop_SubF32, mkU32(Irrm_NEAREST), mkexpr(op1),
8542 mkexpr(op2)));
8543 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
8544 put_fpr_w0(r1, mkexpr(result));
8545
8546 return "seb";
8547}
8548
8549static HChar *
8550s390_irgen_SDB(UChar r1, IRTemp op2addr)
8551{
8552 IRTemp op1 = newTemp(Ity_F64);
8553 IRTemp op2 = newTemp(Ity_F64);
8554 IRTemp result = newTemp(Ity_F64);
8555
8556 assign(op1, get_fpr_dw0(r1));
8557 assign(op2, load(Ity_F64, mkexpr(op2addr)));
8558 assign(result, triop(Iop_SubF64, mkU32(Irrm_NEAREST), mkexpr(op1),
8559 mkexpr(op2)));
8560 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
8561 put_fpr_dw0(r1, mkexpr(result));
8562
8563 return "sdb";
8564}
8565
8566
8567static HChar *
8568s390_irgen_CLC(UChar length, IRTemp start1, IRTemp start2)
8569{
florian79e839e2012-05-05 02:20:30 +00008570 IRTemp len = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00008571
florian79e839e2012-05-05 02:20:30 +00008572 assign(len, mkU64(length));
8573 s390_irgen_CLC_EX(len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +00008574
8575 return "clc";
8576}
8577
8578static HChar *
florianb0c9a132011-09-08 15:37:39 +00008579s390_irgen_CLCL(UChar r1, UChar r2)
8580{
8581 IRTemp addr1 = newTemp(Ity_I64);
8582 IRTemp addr2 = newTemp(Ity_I64);
8583 IRTemp addr1_load = newTemp(Ity_I64);
8584 IRTemp addr2_load = newTemp(Ity_I64);
8585 IRTemp len1 = newTemp(Ity_I32);
8586 IRTemp len2 = newTemp(Ity_I32);
8587 IRTemp r1p1 = newTemp(Ity_I32); /* contents of r1 + 1 */
8588 IRTemp r2p1 = newTemp(Ity_I32); /* contents of r2 + 1 */
8589 IRTemp single1 = newTemp(Ity_I8);
8590 IRTemp single2 = newTemp(Ity_I8);
8591 IRTemp pad = newTemp(Ity_I8);
8592
8593 assign(addr1, get_gpr_dw0(r1));
8594 assign(r1p1, get_gpr_w1(r1 + 1));
8595 assign(len1, binop(Iop_And32, mkexpr(r1p1), mkU32(0x00ffffff)));
8596 assign(addr2, get_gpr_dw0(r2));
8597 assign(r2p1, get_gpr_w1(r2 + 1));
8598 assign(len2, binop(Iop_And32, mkexpr(r2p1), mkU32(0x00ffffff)));
8599 assign(pad, get_gpr_b4(r2 + 1));
8600
8601 /* len1 == 0 and len2 == 0? Exit */
8602 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +00008603 next_insn_if(binop(Iop_CmpEQ32, binop(Iop_Or32, mkexpr(len1),
8604 mkexpr(len2)), mkU32(0)));
florianb0c9a132011-09-08 15:37:39 +00008605
8606 /* Because mkite evaluates both the then-clause and the else-clause
8607 we cannot load directly from addr1 here. If len1 is 0, then adddr1
8608 may be NULL and loading from there would segfault. So we provide a
8609 valid dummy address in that case. Loading from there does no harm and
8610 the value will be discarded at runtime. */
8611 assign(addr1_load,
8612 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
8613 mkU64(guest_IA_curr_instr), mkexpr(addr1)));
8614 assign(single1,
8615 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
8616 mkexpr(pad), load(Ity_I8, mkexpr(addr1_load))));
8617
8618 assign(addr2_load,
8619 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
8620 mkU64(guest_IA_curr_instr), mkexpr(addr2)));
8621 assign(single2,
8622 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
8623 mkexpr(pad), load(Ity_I8, mkexpr(addr2_load))));
8624
8625 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, single1, single2, False);
8626 /* Fields differ ? */
florian6820ba52012-07-26 02:01:50 +00008627 next_insn_if(binop(Iop_CmpNE8, mkexpr(single1), mkexpr(single2)));
florianb0c9a132011-09-08 15:37:39 +00008628
8629 /* Update len1 and addr1, unless len1 == 0. */
8630 put_gpr_dw0(r1,
8631 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
8632 mkexpr(addr1),
8633 binop(Iop_Add64, mkexpr(addr1), mkU64(1))));
8634
8635 /* When updating len1 we must not modify bits (r1+1)[0:39] */
8636 put_gpr_w1(r1 + 1,
8637 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
8638 binop(Iop_And32, mkexpr(r1p1), mkU32(0xFF000000u)),
8639 binop(Iop_Sub32, mkexpr(r1p1), mkU32(1))));
8640
8641 /* Update len2 and addr2, unless len2 == 0. */
8642 put_gpr_dw0(r2,
8643 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
8644 mkexpr(addr2),
8645 binop(Iop_Add64, mkexpr(addr2), mkU64(1))));
8646
8647 /* When updating len2 we must not modify bits (r2+1)[0:39] */
8648 put_gpr_w1(r2 + 1,
8649 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
8650 binop(Iop_And32, mkexpr(r2p1), mkU32(0xFF000000u)),
8651 binop(Iop_Sub32, mkexpr(r2p1), mkU32(1))));
8652
florian6820ba52012-07-26 02:01:50 +00008653 iterate();
florianb0c9a132011-09-08 15:37:39 +00008654
8655 return "clcl";
8656}
8657
8658static HChar *
sewardj2019a972011-03-07 16:04:07 +00008659s390_irgen_CLCLE(UChar r1, UChar r3, IRTemp pad2)
8660{
8661 IRTemp addr1, addr3, addr1_load, addr3_load, len1, len3, single1, single3;
8662
8663 addr1 = newTemp(Ity_I64);
8664 addr3 = newTemp(Ity_I64);
8665 addr1_load = newTemp(Ity_I64);
8666 addr3_load = newTemp(Ity_I64);
8667 len1 = newTemp(Ity_I64);
8668 len3 = newTemp(Ity_I64);
8669 single1 = newTemp(Ity_I8);
8670 single3 = newTemp(Ity_I8);
8671
8672 assign(addr1, get_gpr_dw0(r1));
8673 assign(len1, get_gpr_dw0(r1 + 1));
8674 assign(addr3, get_gpr_dw0(r3));
8675 assign(len3, get_gpr_dw0(r3 + 1));
8676
8677 /* len1 == 0 and len3 == 0? Exit */
8678 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +00008679 next_insn_if(binop(Iop_CmpEQ64,binop(Iop_Or64, mkexpr(len1),
8680 mkexpr(len3)), mkU64(0)));
sewardj2019a972011-03-07 16:04:07 +00008681
8682 /* A mux requires both ways to be possible. This is a way to prevent clcle
8683 from reading from addr1 if it should read from the pad. Since the pad
8684 has no address, just read from the instruction, we discard that anyway */
8685 assign(addr1_load,
florian6ad49522011-09-09 02:38:55 +00008686 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
8687 mkU64(guest_IA_curr_instr), mkexpr(addr1)));
sewardj2019a972011-03-07 16:04:07 +00008688
8689 /* same for addr3 */
8690 assign(addr3_load,
florian6ad49522011-09-09 02:38:55 +00008691 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
8692 mkU64(guest_IA_curr_instr), mkexpr(addr3)));
sewardj2019a972011-03-07 16:04:07 +00008693
8694 assign(single1,
florian6ad49522011-09-09 02:38:55 +00008695 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
8696 unop(Iop_64to8, mkexpr(pad2)),
8697 load(Ity_I8, mkexpr(addr1_load))));
sewardj2019a972011-03-07 16:04:07 +00008698
8699 assign(single3,
florian6ad49522011-09-09 02:38:55 +00008700 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
8701 unop(Iop_64to8, mkexpr(pad2)),
8702 load(Ity_I8, mkexpr(addr3_load))));
sewardj2019a972011-03-07 16:04:07 +00008703
8704 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, single1, single3, False);
8705 /* Both fields differ ? */
florian6820ba52012-07-26 02:01:50 +00008706 next_insn_if(binop(Iop_CmpNE8, mkexpr(single1), mkexpr(single3)));
sewardj2019a972011-03-07 16:04:07 +00008707
8708 /* If a length in 0 we must not change this length and the address */
8709 put_gpr_dw0(r1,
florian6ad49522011-09-09 02:38:55 +00008710 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
8711 mkexpr(addr1),
8712 binop(Iop_Add64, mkexpr(addr1), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +00008713
8714 put_gpr_dw0(r1 + 1,
florian6ad49522011-09-09 02:38:55 +00008715 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
8716 mkU64(0), binop(Iop_Sub64, mkexpr(len1), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +00008717
8718 put_gpr_dw0(r3,
florian6ad49522011-09-09 02:38:55 +00008719 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
8720 mkexpr(addr3),
8721 binop(Iop_Add64, mkexpr(addr3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +00008722
8723 put_gpr_dw0(r3 + 1,
florian6ad49522011-09-09 02:38:55 +00008724 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
8725 mkU64(0), binop(Iop_Sub64, mkexpr(len3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +00008726
florian6820ba52012-07-26 02:01:50 +00008727 iterate();
sewardj2019a972011-03-07 16:04:07 +00008728
8729 return "clcle";
8730}
floriana64c2432011-07-16 02:11:50 +00008731
florianb0bf6602012-05-05 00:01:16 +00008732
sewardj2019a972011-03-07 16:04:07 +00008733static void
8734s390_irgen_XC_EX(IRTemp length, IRTemp start1, IRTemp start2)
8735{
florianb0bf6602012-05-05 00:01:16 +00008736 s390_irgen_xonc(Iop_Xor8, length, start1, start2);
8737}
sewardj2019a972011-03-07 16:04:07 +00008738
sewardj2019a972011-03-07 16:04:07 +00008739
florianb0bf6602012-05-05 00:01:16 +00008740static void
8741s390_irgen_NC_EX(IRTemp length, IRTemp start1, IRTemp start2)
8742{
8743 s390_irgen_xonc(Iop_And8, length, start1, start2);
8744}
sewardj2019a972011-03-07 16:04:07 +00008745
sewardj2019a972011-03-07 16:04:07 +00008746
florianb0bf6602012-05-05 00:01:16 +00008747static void
8748s390_irgen_OC_EX(IRTemp length, IRTemp start1, IRTemp start2)
8749{
8750 s390_irgen_xonc(Iop_Or8, length, start1, start2);
sewardj2019a972011-03-07 16:04:07 +00008751}
8752
8753
8754static void
8755s390_irgen_CLC_EX(IRTemp length, IRTemp start1, IRTemp start2)
8756{
8757 IRTemp current1 = newTemp(Ity_I8);
8758 IRTemp current2 = newTemp(Ity_I8);
8759 IRTemp counter = newTemp(Ity_I64);
8760
8761 assign(counter, get_counter_dw0());
8762 put_counter_dw0(mkU64(0));
8763
8764 assign(current1, load(Ity_I8, binop(Iop_Add64, mkexpr(start1),
8765 mkexpr(counter))));
8766 assign(current2, load(Ity_I8, binop(Iop_Add64, mkexpr(start2),
8767 mkexpr(counter))));
8768 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, current1, current2,
8769 False);
8770
8771 /* Both fields differ ? */
florian6820ba52012-07-26 02:01:50 +00008772 next_insn_if(binop(Iop_CmpNE8, mkexpr(current1), mkexpr(current2)));
sewardj2019a972011-03-07 16:04:07 +00008773
8774 /* Check for end of field */
8775 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
florian6820ba52012-07-26 02:01:50 +00008776 iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)));
sewardj2019a972011-03-07 16:04:07 +00008777 put_counter_dw0(mkU64(0));
8778}
8779
8780static void
8781s390_irgen_MVC_EX(IRTemp length, IRTemp start1, IRTemp start2)
8782{
8783 IRTemp counter = newTemp(Ity_I64);
8784
8785 assign(counter, get_counter_dw0());
8786
8787 store(binop(Iop_Add64, mkexpr(start1), mkexpr(counter)),
8788 load(Ity_I8, binop(Iop_Add64, mkexpr(start2), mkexpr(counter))));
8789
8790 /* Check for end of field */
8791 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
florian6820ba52012-07-26 02:01:50 +00008792 iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)));
sewardj2019a972011-03-07 16:04:07 +00008793 put_counter_dw0(mkU64(0));
8794}
8795
florianf87d4fb2012-05-05 02:55:24 +00008796static void
8797s390_irgen_TR_EX(IRTemp length, IRTemp start1, IRTemp start2)
8798{
8799 IRTemp op = newTemp(Ity_I8);
8800 IRTemp op1 = newTemp(Ity_I8);
8801 IRTemp result = newTemp(Ity_I64);
8802 IRTemp counter = newTemp(Ity_I64);
8803
8804 assign(counter, get_counter_dw0());
8805
8806 assign(op, load(Ity_I8, binop(Iop_Add64, mkexpr(start1), mkexpr(counter))));
8807
8808 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)), mkexpr(start2)));
8809
8810 assign(op1, load(Ity_I8, mkexpr(result)));
8811 store(binop(Iop_Add64, mkexpr(start1), mkexpr(counter)), mkexpr(op1));
8812
8813 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
florian6820ba52012-07-26 02:01:50 +00008814 iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)));
florianf87d4fb2012-05-05 02:55:24 +00008815 put_counter_dw0(mkU64(0));
8816}
sewardj2019a972011-03-07 16:04:07 +00008817
8818
8819static void
8820s390_irgen_EX_SS(UChar r, IRTemp addr2,
florian6820ba52012-07-26 02:01:50 +00008821 void (*irgen)(IRTemp length, IRTemp start1, IRTemp start2),
8822 int lensize)
sewardj2019a972011-03-07 16:04:07 +00008823{
8824 struct SS {
8825 unsigned int op : 8;
8826 unsigned int l : 8;
8827 unsigned int b1 : 4;
8828 unsigned int d1 : 12;
8829 unsigned int b2 : 4;
8830 unsigned int d2 : 12;
8831 };
8832 union {
8833 struct SS dec;
8834 unsigned long bytes;
8835 } ss;
8836 IRTemp cond;
8837 IRDirty *d;
8838 IRTemp torun;
8839
8840 IRTemp start1 = newTemp(Ity_I64);
8841 IRTemp start2 = newTemp(Ity_I64);
8842 IRTemp len = newTemp(lensize == 64 ? Ity_I64 : Ity_I32);
8843 cond = newTemp(Ity_I1);
8844 torun = newTemp(Ity_I64);
8845
8846 assign(torun, load(Ity_I64, mkexpr(addr2)));
8847 /* Start with a check that the saved code is still correct */
8848 assign(cond, binop(Iop_CmpNE64, mkexpr(torun), mkU64(last_execute_target)));
8849 /* If not, save the new value */
8850 d = unsafeIRDirty_0_N (0, "s390x_dirtyhelper_EX", &s390x_dirtyhelper_EX,
8851 mkIRExprVec_1(mkexpr(torun)));
8852 d->guard = mkexpr(cond);
8853 stmt(IRStmt_Dirty(d));
8854
8855 /* and restart */
florian428dfdd2012-03-27 03:09:49 +00008856 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TISTART),
8857 mkU64(guest_IA_curr_instr)));
8858 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TILEN), mkU64(4)));
florian6820ba52012-07-26 02:01:50 +00008859 restart_if(mkexpr(cond));
sewardj2019a972011-03-07 16:04:07 +00008860
8861 ss.bytes = last_execute_target;
8862 assign(start1, binop(Iop_Add64, mkU64(ss.dec.d1),
8863 ss.dec.b1 != 0 ? get_gpr_dw0(ss.dec.b1) : mkU64(0)));
8864 assign(start2, binop(Iop_Add64, mkU64(ss.dec.d2),
8865 ss.dec.b2 != 0 ? get_gpr_dw0(ss.dec.b2) : mkU64(0)));
8866 assign(len, unop(lensize == 64 ? Iop_8Uto64 : Iop_8Uto32, binop(Iop_Or8,
8867 r != 0 ? get_gpr_b7(r): mkU8(0), mkU8(ss.dec.l))));
8868 irgen(len, start1, start2);
florian8844a632012-04-13 04:04:06 +00008869
sewardj2019a972011-03-07 16:04:07 +00008870 last_execute_target = 0;
8871}
8872
8873static HChar *
8874s390_irgen_EX(UChar r1, IRTemp addr2)
8875{
8876 switch(last_execute_target & 0xff00000000000000ULL) {
8877 case 0:
8878 {
8879 /* no code information yet */
8880 IRDirty *d;
8881
8882 /* so safe the code... */
8883 d = unsafeIRDirty_0_N (0, "s390x_dirtyhelper_EX", &s390x_dirtyhelper_EX,
8884 mkIRExprVec_1(load(Ity_I64, mkexpr(addr2))));
8885 stmt(IRStmt_Dirty(d));
8886 /* and restart */
florian428dfdd2012-03-27 03:09:49 +00008887 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TISTART),
8888 mkU64(guest_IA_curr_instr)));
8889 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TILEN), mkU64(4)));
florian6820ba52012-07-26 02:01:50 +00008890 restart_if(IRExpr_Const(IRConst_U1(True)));
8891
sewardj2019a972011-03-07 16:04:07 +00008892 /* we know that this will be invalidated */
florianf9e1ed72012-04-17 02:41:56 +00008893 put_IA(mkaddr_expr(guest_IA_next_instr));
sewardj2019a972011-03-07 16:04:07 +00008894 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +00008895 dis_res->jk_StopHere = Ijk_TInval;
sewardj2019a972011-03-07 16:04:07 +00008896 break;
8897 }
8898
8899 case 0xd200000000000000ULL:
8900 /* special case MVC */
8901 s390_irgen_EX_SS(r1, addr2, s390_irgen_MVC_EX, 64);
8902 return "mvc via ex";
8903
8904 case 0xd500000000000000ULL:
8905 /* special case CLC */
8906 s390_irgen_EX_SS(r1, addr2, s390_irgen_CLC_EX, 64);
8907 return "clc via ex";
8908
8909 case 0xd700000000000000ULL:
8910 /* special case XC */
8911 s390_irgen_EX_SS(r1, addr2, s390_irgen_XC_EX, 32);
8912 return "xc via ex";
8913
florianb0bf6602012-05-05 00:01:16 +00008914 case 0xd600000000000000ULL:
8915 /* special case OC */
8916 s390_irgen_EX_SS(r1, addr2, s390_irgen_OC_EX, 32);
8917 return "oc via ex";
8918
8919 case 0xd400000000000000ULL:
8920 /* special case NC */
8921 s390_irgen_EX_SS(r1, addr2, s390_irgen_NC_EX, 32);
8922 return "nc via ex";
sewardj2019a972011-03-07 16:04:07 +00008923
florianf87d4fb2012-05-05 02:55:24 +00008924 case 0xdc00000000000000ULL:
8925 /* special case TR */
8926 s390_irgen_EX_SS(r1, addr2, s390_irgen_TR_EX, 64);
8927 return "tr via ex";
8928
sewardj2019a972011-03-07 16:04:07 +00008929 default:
8930 {
8931 /* everything else will get a self checking prefix that also checks the
8932 register content */
8933 IRDirty *d;
8934 UChar *bytes;
8935 IRTemp cond;
8936 IRTemp orperand;
8937 IRTemp torun;
8938
8939 cond = newTemp(Ity_I1);
8940 orperand = newTemp(Ity_I64);
8941 torun = newTemp(Ity_I64);
8942
8943 if (r1 == 0)
8944 assign(orperand, mkU64(0));
8945 else
8946 assign(orperand, unop(Iop_8Uto64,get_gpr_b7(r1)));
8947 /* This code is going to be translated */
8948 assign(torun, binop(Iop_Or64, load(Ity_I64, mkexpr(addr2)),
8949 binop(Iop_Shl64, mkexpr(orperand), mkU8(48))));
8950
8951 /* Start with a check that saved code is still correct */
8952 assign(cond, binop(Iop_CmpNE64, mkexpr(torun),
8953 mkU64(last_execute_target)));
8954 /* If not, save the new value */
8955 d = unsafeIRDirty_0_N (0, "s390x_dirtyhelper_EX", &s390x_dirtyhelper_EX,
8956 mkIRExprVec_1(mkexpr(torun)));
8957 d->guard = mkexpr(cond);
8958 stmt(IRStmt_Dirty(d));
8959
8960 /* and restart */
florian428dfdd2012-03-27 03:09:49 +00008961 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TISTART), mkU64(guest_IA_curr_instr)));
8962 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TILEN), mkU64(4)));
florian6820ba52012-07-26 02:01:50 +00008963 restart_if(mkexpr(cond));
sewardj2019a972011-03-07 16:04:07 +00008964
8965 /* Now comes the actual translation */
8966 bytes = (UChar *) &last_execute_target;
8967 s390_decode_and_irgen(bytes, ((((bytes[0] >> 6) + 1) >> 1) + 1) << 1,
8968 dis_res);
sewardj7ee97522011-05-09 21:45:04 +00008969 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00008970 vex_printf(" which was executed by\n");
8971 /* dont make useless translations in the next execute */
8972 last_execute_target = 0;
8973 }
8974 }
8975 return "ex";
8976}
8977
8978static HChar *
8979s390_irgen_EXRL(UChar r1, UInt offset)
8980{
8981 IRTemp addr = newTemp(Ity_I64);
8982 /* we might save one round trip because we know the target */
8983 if (!last_execute_target)
8984 last_execute_target = *(ULong *)(HWord)
8985 (guest_IA_curr_instr + offset * 2UL);
8986 assign(addr, mkU64(guest_IA_curr_instr + offset * 2UL));
8987 s390_irgen_EX(r1, addr);
8988 return "exrl";
8989}
8990
8991static HChar *
8992s390_irgen_IPM(UChar r1)
8993{
8994 // As long as we dont support SPM, lets just assume 0 as program mask
8995 put_gpr_b4(r1, unop(Iop_32to8, binop(Iop_Or32, mkU32(0 /* program mask */),
8996 binop(Iop_Shl32, s390_call_calculate_cc(), mkU8(4)))));
8997
8998 return "ipm";
8999}
9000
9001
9002static HChar *
9003s390_irgen_SRST(UChar r1, UChar r2)
9004{
9005 IRTemp address = newTemp(Ity_I64);
9006 IRTemp next = newTemp(Ity_I64);
9007 IRTemp delim = newTemp(Ity_I8);
9008 IRTemp counter = newTemp(Ity_I64);
9009 IRTemp byte = newTemp(Ity_I8);
9010
9011 assign(address, get_gpr_dw0(r2));
9012 assign(next, get_gpr_dw0(r1));
9013
9014 assign(counter, get_counter_dw0());
9015 put_counter_dw0(mkU64(0));
9016
9017 // start = next? CC=2 and out r1 and r2 unchanged
9018 s390_cc_set(2);
9019 put_gpr_dw0(r2, binop(Iop_Sub64, mkexpr(address), mkexpr(counter)));
florian6820ba52012-07-26 02:01:50 +00009020 next_insn_if(binop(Iop_CmpEQ64, mkexpr(address), mkexpr(next)));
sewardj2019a972011-03-07 16:04:07 +00009021
9022 assign(byte, load(Ity_I8, mkexpr(address)));
9023 assign(delim, get_gpr_b7(0));
9024
9025 // byte = delim? CC=1, R1=address
9026 s390_cc_set(1);
9027 put_gpr_dw0(r1, mkexpr(address));
florian6820ba52012-07-26 02:01:50 +00009028 next_insn_if(binop(Iop_CmpEQ8, mkexpr(delim), mkexpr(byte)));
sewardj2019a972011-03-07 16:04:07 +00009029
9030 // else: all equal, no end yet, loop
9031 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
9032 put_gpr_dw0(r1, mkexpr(next));
9033 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(address), mkU64(1)));
floriancf87c942012-07-25 00:52:21 +00009034
florian6820ba52012-07-26 02:01:50 +00009035 iterate();
sewardj2019a972011-03-07 16:04:07 +00009036
9037 return "srst";
9038}
9039
9040static HChar *
9041s390_irgen_CLST(UChar r1, UChar r2)
9042{
9043 IRTemp address1 = newTemp(Ity_I64);
9044 IRTemp address2 = newTemp(Ity_I64);
9045 IRTemp end = newTemp(Ity_I8);
9046 IRTemp counter = newTemp(Ity_I64);
9047 IRTemp byte1 = newTemp(Ity_I8);
9048 IRTemp byte2 = newTemp(Ity_I8);
9049
9050 assign(address1, get_gpr_dw0(r1));
9051 assign(address2, get_gpr_dw0(r2));
9052 assign(end, get_gpr_b7(0));
9053 assign(counter, get_counter_dw0());
9054 put_counter_dw0(mkU64(0));
9055 assign(byte1, load(Ity_I8, mkexpr(address1)));
9056 assign(byte2, load(Ity_I8, mkexpr(address2)));
9057
9058 // end in both? all equal, reset r1 and r2 to start values
9059 s390_cc_set(0);
9060 put_gpr_dw0(r1, binop(Iop_Sub64, mkexpr(address1), mkexpr(counter)));
9061 put_gpr_dw0(r2, binop(Iop_Sub64, mkexpr(address2), mkexpr(counter)));
florian6820ba52012-07-26 02:01:50 +00009062 next_insn_if(binop(Iop_CmpEQ8, mkU8(0),
9063 binop(Iop_Or8,
9064 binop(Iop_Xor8, mkexpr(byte1), mkexpr(end)),
9065 binop(Iop_Xor8, mkexpr(byte2), mkexpr(end)))));
sewardj2019a972011-03-07 16:04:07 +00009066
9067 put_gpr_dw0(r1, mkexpr(address1));
9068 put_gpr_dw0(r2, mkexpr(address2));
9069
9070 // End found in string1
9071 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +00009072 next_insn_if(binop(Iop_CmpEQ8, mkexpr(end), mkexpr(byte1)));
sewardj2019a972011-03-07 16:04:07 +00009073
9074 // End found in string2
9075 s390_cc_set(2);
florian6820ba52012-07-26 02:01:50 +00009076 next_insn_if(binop(Iop_CmpEQ8, mkexpr(end), mkexpr(byte2)));
sewardj2019a972011-03-07 16:04:07 +00009077
9078 // string1 < string2
9079 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +00009080 next_insn_if(binop(Iop_CmpLT32U, unop(Iop_8Uto32, mkexpr(byte1)),
9081 unop(Iop_8Uto32, mkexpr(byte2))));
sewardj2019a972011-03-07 16:04:07 +00009082
9083 // string2 < string1
9084 s390_cc_set(2);
florian6820ba52012-07-26 02:01:50 +00009085 next_insn_if(binop(Iop_CmpLT32U, unop(Iop_8Uto32, mkexpr(byte2)),
9086 unop(Iop_8Uto32, mkexpr(byte1))));
sewardj2019a972011-03-07 16:04:07 +00009087
9088 // else: all equal, no end yet, loop
9089 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
9090 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), mkU64(1)));
9091 put_gpr_dw0(r2, binop(Iop_Add64, get_gpr_dw0(r2), mkU64(1)));
floriancf87c942012-07-25 00:52:21 +00009092
florian6820ba52012-07-26 02:01:50 +00009093 iterate();
sewardj2019a972011-03-07 16:04:07 +00009094
9095 return "clst";
9096}
9097
9098static void
9099s390_irgen_load_multiple_32bit(UChar r1, UChar r3, IRTemp op2addr)
9100{
9101 UChar reg;
9102 IRTemp addr = newTemp(Ity_I64);
9103
9104 assign(addr, mkexpr(op2addr));
9105 reg = r1;
9106 do {
9107 IRTemp old = addr;
9108
9109 reg %= 16;
9110 put_gpr_w1(reg, load(Ity_I32, mkexpr(addr)));
9111 addr = newTemp(Ity_I64);
9112 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
9113 reg++;
9114 } while (reg != (r3 + 1));
9115}
9116
9117static HChar *
9118s390_irgen_LM(UChar r1, UChar r3, IRTemp op2addr)
9119{
9120 s390_irgen_load_multiple_32bit(r1, r3, op2addr);
9121
9122 return "lm";
9123}
9124
9125static HChar *
9126s390_irgen_LMY(UChar r1, UChar r3, IRTemp op2addr)
9127{
9128 s390_irgen_load_multiple_32bit(r1, r3, op2addr);
9129
9130 return "lmy";
9131}
9132
9133static HChar *
9134s390_irgen_LMH(UChar r1, UChar r3, IRTemp op2addr)
9135{
9136 UChar reg;
9137 IRTemp addr = newTemp(Ity_I64);
9138
9139 assign(addr, mkexpr(op2addr));
9140 reg = r1;
9141 do {
9142 IRTemp old = addr;
9143
9144 reg %= 16;
9145 put_gpr_w0(reg, load(Ity_I32, mkexpr(addr)));
9146 addr = newTemp(Ity_I64);
9147 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
9148 reg++;
9149 } while (reg != (r3 + 1));
9150
9151 return "lmh";
9152}
9153
9154static HChar *
9155s390_irgen_LMG(UChar r1, UChar r3, IRTemp op2addr)
9156{
9157 UChar reg;
9158 IRTemp addr = newTemp(Ity_I64);
9159
9160 assign(addr, mkexpr(op2addr));
9161 reg = r1;
9162 do {
9163 IRTemp old = addr;
9164
9165 reg %= 16;
9166 put_gpr_dw0(reg, load(Ity_I64, mkexpr(addr)));
9167 addr = newTemp(Ity_I64);
9168 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(8)));
9169 reg++;
9170 } while (reg != (r3 + 1));
9171
9172 return "lmg";
9173}
9174
9175static void
9176s390_irgen_store_multiple_32bit(UChar r1, UChar r3, IRTemp op2addr)
9177{
9178 UChar reg;
9179 IRTemp addr = newTemp(Ity_I64);
9180
9181 assign(addr, mkexpr(op2addr));
9182 reg = r1;
9183 do {
9184 IRTemp old = addr;
9185
9186 reg %= 16;
9187 store(mkexpr(addr), get_gpr_w1(reg));
9188 addr = newTemp(Ity_I64);
9189 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
9190 reg++;
9191 } while( reg != (r3 + 1));
9192}
9193
9194static HChar *
9195s390_irgen_STM(UChar r1, UChar r3, IRTemp op2addr)
9196{
9197 s390_irgen_store_multiple_32bit(r1, r3, op2addr);
9198
9199 return "stm";
9200}
9201
9202static HChar *
9203s390_irgen_STMY(UChar r1, UChar r3, IRTemp op2addr)
9204{
9205 s390_irgen_store_multiple_32bit(r1, r3, op2addr);
9206
9207 return "stmy";
9208}
9209
9210static HChar *
9211s390_irgen_STMH(UChar r1, UChar r3, IRTemp op2addr)
9212{
9213 UChar reg;
9214 IRTemp addr = newTemp(Ity_I64);
9215
9216 assign(addr, mkexpr(op2addr));
9217 reg = r1;
9218 do {
9219 IRTemp old = addr;
9220
9221 reg %= 16;
9222 store(mkexpr(addr), get_gpr_w0(reg));
9223 addr = newTemp(Ity_I64);
9224 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
9225 reg++;
9226 } while( reg != (r3 + 1));
9227
9228 return "stmh";
9229}
9230
9231static HChar *
9232s390_irgen_STMG(UChar r1, UChar r3, IRTemp op2addr)
9233{
9234 UChar reg;
9235 IRTemp addr = newTemp(Ity_I64);
9236
9237 assign(addr, mkexpr(op2addr));
9238 reg = r1;
9239 do {
9240 IRTemp old = addr;
9241
9242 reg %= 16;
9243 store(mkexpr(addr), get_gpr_dw0(reg));
9244 addr = newTemp(Ity_I64);
9245 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(8)));
9246 reg++;
9247 } while( reg != (r3 + 1));
9248
9249 return "stmg";
9250}
9251
9252static void
florianb0bf6602012-05-05 00:01:16 +00009253s390_irgen_xonc(IROp op, IRTemp length, IRTemp start1, IRTemp start2)
sewardj2019a972011-03-07 16:04:07 +00009254{
9255 IRTemp old1 = newTemp(Ity_I8);
9256 IRTemp old2 = newTemp(Ity_I8);
9257 IRTemp new1 = newTemp(Ity_I8);
9258 IRTemp counter = newTemp(Ity_I32);
9259 IRTemp addr1 = newTemp(Ity_I64);
9260
9261 assign(counter, get_counter_w0());
9262
9263 assign(addr1, binop(Iop_Add64, mkexpr(start1),
9264 unop(Iop_32Uto64, mkexpr(counter))));
9265
9266 assign(old1, load(Ity_I8, mkexpr(addr1)));
9267 assign(old2, load(Ity_I8, binop(Iop_Add64, mkexpr(start2),
9268 unop(Iop_32Uto64,mkexpr(counter)))));
9269 assign(new1, binop(op, mkexpr(old1), mkexpr(old2)));
9270
9271 /* Special case: xc is used to zero memory */
sewardj2019a972011-03-07 16:04:07 +00009272 if (op == Iop_Xor8) {
9273 store(mkexpr(addr1),
florian6ad49522011-09-09 02:38:55 +00009274 mkite(binop(Iop_CmpEQ64, mkexpr(start1), mkexpr(start2)),
9275 mkU8(0), mkexpr(new1)));
sewardj2019a972011-03-07 16:04:07 +00009276 } else
9277 store(mkexpr(addr1), mkexpr(new1));
9278 put_counter_w1(binop(Iop_Or32, unop(Iop_8Uto32, mkexpr(new1)),
9279 get_counter_w1()));
9280
9281 /* Check for end of field */
9282 put_counter_w0(binop(Iop_Add32, mkexpr(counter), mkU32(1)));
florian6820ba52012-07-26 02:01:50 +00009283 iterate_if(binop(Iop_CmpNE32, mkexpr(counter), mkexpr(length)));
sewardj2019a972011-03-07 16:04:07 +00009284 s390_cc_thunk_put1(S390_CC_OP_BITWISE, mktemp(Ity_I32, get_counter_w1()),
9285 False);
9286 put_counter_dw0(mkU64(0));
9287}
9288
9289static HChar *
9290s390_irgen_XC(UChar length, IRTemp start1, IRTemp start2)
9291{
florianb0bf6602012-05-05 00:01:16 +00009292 IRTemp len = newTemp(Ity_I32);
9293
9294 assign(len, mkU32(length));
9295 s390_irgen_xonc(Iop_Xor8, len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +00009296
9297 return "xc";
9298}
9299
sewardjb63967e2011-03-24 08:50:04 +00009300static void
9301s390_irgen_XC_sameloc(UChar length, UChar b, UShort d)
9302{
9303 IRTemp counter = newTemp(Ity_I32);
9304 IRTemp start = newTemp(Ity_I64);
9305 IRTemp addr = newTemp(Ity_I64);
9306
9307 assign(start,
9308 binop(Iop_Add64, mkU64(d), b != 0 ? get_gpr_dw0(b) : mkU64(0)));
9309
9310 if (length < 8) {
9311 UInt i;
9312
9313 for (i = 0; i <= length; ++i) {
9314 store(binop(Iop_Add64, mkexpr(start), mkU64(i)), mkU8(0));
9315 }
9316 } else {
9317 assign(counter, get_counter_w0());
9318
9319 assign(addr, binop(Iop_Add64, mkexpr(start),
9320 unop(Iop_32Uto64, mkexpr(counter))));
9321
9322 store(mkexpr(addr), mkU8(0));
9323
9324 /* Check for end of field */
9325 put_counter_w0(binop(Iop_Add32, mkexpr(counter), mkU32(1)));
florian6820ba52012-07-26 02:01:50 +00009326 iterate_if(binop(Iop_CmpNE32, mkexpr(counter), mkU32(length)));
sewardjb63967e2011-03-24 08:50:04 +00009327
9328 /* Reset counter */
9329 put_counter_dw0(mkU64(0));
9330 }
9331
9332 s390_cc_thunk_put1(S390_CC_OP_BITWISE, mktemp(Ity_I32, mkU32(0)), False);
9333
sewardj7ee97522011-05-09 21:45:04 +00009334 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardjb63967e2011-03-24 08:50:04 +00009335 s390_disasm(ENC3(MNM, UDLB, UDXB), "xc", d, length, b, d, 0, b);
9336}
9337
sewardj2019a972011-03-07 16:04:07 +00009338static HChar *
9339s390_irgen_NC(UChar length, IRTemp start1, IRTemp start2)
9340{
florianb0bf6602012-05-05 00:01:16 +00009341 IRTemp len = newTemp(Ity_I32);
9342
9343 assign(len, mkU32(length));
9344 s390_irgen_xonc(Iop_And8, len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +00009345
9346 return "nc";
9347}
9348
9349static HChar *
9350s390_irgen_OC(UChar length, IRTemp start1, IRTemp start2)
9351{
florianb0bf6602012-05-05 00:01:16 +00009352 IRTemp len = newTemp(Ity_I32);
9353
9354 assign(len, mkU32(length));
9355 s390_irgen_xonc(Iop_Or8, len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +00009356
9357 return "oc";
9358}
9359
9360
9361static HChar *
9362s390_irgen_MVC(UChar length, IRTemp start1, IRTemp start2)
9363{
florian79e839e2012-05-05 02:20:30 +00009364 IRTemp len = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00009365
florian79e839e2012-05-05 02:20:30 +00009366 assign(len, mkU64(length));
9367 s390_irgen_MVC_EX(len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +00009368
9369 return "mvc";
9370}
9371
9372static HChar *
florianb0c9a132011-09-08 15:37:39 +00009373s390_irgen_MVCL(UChar r1, UChar r2)
9374{
9375 IRTemp addr1 = newTemp(Ity_I64);
9376 IRTemp addr2 = newTemp(Ity_I64);
9377 IRTemp addr2_load = newTemp(Ity_I64);
9378 IRTemp r1p1 = newTemp(Ity_I32); /* contents of r1 + 1 */
9379 IRTemp r2p1 = newTemp(Ity_I32); /* contents of r2 + 1 */
9380 IRTemp len1 = newTemp(Ity_I32);
9381 IRTemp len2 = newTemp(Ity_I32);
9382 IRTemp pad = newTemp(Ity_I8);
9383 IRTemp single = newTemp(Ity_I8);
9384
9385 assign(addr1, get_gpr_dw0(r1));
9386 assign(r1p1, get_gpr_w1(r1 + 1));
9387 assign(len1, binop(Iop_And32, mkexpr(r1p1), mkU32(0x00ffffff)));
9388 assign(addr2, get_gpr_dw0(r2));
9389 assign(r2p1, get_gpr_w1(r2 + 1));
9390 assign(len2, binop(Iop_And32, mkexpr(r2p1), mkU32(0x00ffffff)));
9391 assign(pad, get_gpr_b4(r2 + 1));
9392
9393 /* len1 == 0 ? */
9394 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len2, False);
florian6820ba52012-07-26 02:01:50 +00009395 next_insn_if(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)));
florianb0c9a132011-09-08 15:37:39 +00009396
9397 /* Check for destructive overlap:
9398 addr1 > addr2 && addr2 + len1 > addr1 && (addr2 + len2) > addr1 */
9399 s390_cc_set(3);
9400 IRTemp cond1 = newTemp(Ity_I32);
9401 assign(cond1, unop(Iop_1Uto32,
9402 binop(Iop_CmpLT64U, mkexpr(addr2), mkexpr(addr1))));
9403 IRTemp cond2 = newTemp(Ity_I32);
9404 assign(cond2, unop(Iop_1Uto32,
9405 binop(Iop_CmpLT64U, mkexpr(addr1),
9406 binop(Iop_Add64, mkexpr(addr2),
9407 unop(Iop_32Uto64, mkexpr(len1))))));
9408 IRTemp cond3 = newTemp(Ity_I32);
9409 assign(cond3, unop(Iop_1Uto32,
9410 binop(Iop_CmpLT64U,
9411 mkexpr(addr1),
9412 binop(Iop_Add64, mkexpr(addr2),
9413 unop(Iop_32Uto64, mkexpr(len2))))));
9414
florian6820ba52012-07-26 02:01:50 +00009415 next_insn_if(binop(Iop_CmpEQ32,
9416 binop(Iop_And32,
9417 binop(Iop_And32, mkexpr(cond1), mkexpr(cond2)),
9418 mkexpr(cond3)),
9419 mkU32(1)));
florianb0c9a132011-09-08 15:37:39 +00009420
9421 /* See s390_irgen_CLCL for explanation why we cannot load directly
9422 and need two steps. */
9423 assign(addr2_load,
9424 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
9425 mkU64(guest_IA_curr_instr), mkexpr(addr2)));
9426 assign(single,
9427 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
9428 mkexpr(pad), load(Ity_I8, mkexpr(addr2_load))));
9429
9430 store(mkexpr(addr1), mkexpr(single));
9431
9432 /* Update addr1 and len1 */
9433 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkU64(1)));
9434 put_gpr_w1(r1 + 1, binop(Iop_Sub32, mkexpr(r1p1), mkU32(1)));
9435
9436 /* Update addr2 and len2 */
9437 put_gpr_dw0(r2,
9438 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
9439 mkexpr(addr2),
9440 binop(Iop_Add64, mkexpr(addr2), mkU64(1))));
9441
9442 /* When updating len2 we must not modify bits (r2+1)[0:39] */
9443 put_gpr_w1(r2 + 1,
9444 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
9445 binop(Iop_And32, mkexpr(r2p1), mkU32(0xFF000000u)),
9446 binop(Iop_Sub32, mkexpr(r2p1), mkU32(1))));
9447
9448 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len2, False);
florian6820ba52012-07-26 02:01:50 +00009449 iterate_if(binop(Iop_CmpNE32, mkexpr(len1), mkU32(1)));
florianb0c9a132011-09-08 15:37:39 +00009450
9451 return "mvcl";
9452}
9453
9454
9455static HChar *
sewardj2019a972011-03-07 16:04:07 +00009456s390_irgen_MVCLE(UChar r1, UChar r3, IRTemp pad2)
9457{
9458 IRTemp addr1, addr3, addr3_load, len1, len3, single;
9459
9460 addr1 = newTemp(Ity_I64);
9461 addr3 = newTemp(Ity_I64);
9462 addr3_load = newTemp(Ity_I64);
9463 len1 = newTemp(Ity_I64);
9464 len3 = newTemp(Ity_I64);
9465 single = newTemp(Ity_I8);
9466
9467 assign(addr1, get_gpr_dw0(r1));
9468 assign(len1, get_gpr_dw0(r1 + 1));
9469 assign(addr3, get_gpr_dw0(r3));
9470 assign(len3, get_gpr_dw0(r3 + 1));
9471
9472 // len1 == 0 ?
9473 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len3, False);
florian6820ba52012-07-26 02:01:50 +00009474 next_insn_if(binop(Iop_CmpEQ64,mkexpr(len1), mkU64(0)));
sewardj2019a972011-03-07 16:04:07 +00009475
9476 /* This is a hack to prevent mvcle from reading from addr3 if it
9477 should read from the pad. Since the pad has no address, just
9478 read from the instruction, we discard that anyway */
9479 assign(addr3_load,
florian6ad49522011-09-09 02:38:55 +00009480 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
9481 mkU64(guest_IA_curr_instr), mkexpr(addr3)));
sewardj2019a972011-03-07 16:04:07 +00009482
9483 assign(single,
florian6ad49522011-09-09 02:38:55 +00009484 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
9485 unop(Iop_64to8, mkexpr(pad2)),
9486 load(Ity_I8, mkexpr(addr3_load))));
sewardj2019a972011-03-07 16:04:07 +00009487 store(mkexpr(addr1), mkexpr(single));
9488
9489 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkU64(1)));
9490
9491 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkU64(1)));
9492
9493 put_gpr_dw0(r3,
florian6ad49522011-09-09 02:38:55 +00009494 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
9495 mkexpr(addr3),
9496 binop(Iop_Add64, mkexpr(addr3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +00009497
9498 put_gpr_dw0(r3 + 1,
florian6ad49522011-09-09 02:38:55 +00009499 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
9500 mkU64(0), binop(Iop_Sub64, mkexpr(len3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +00009501
sewardj2019a972011-03-07 16:04:07 +00009502 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len3, False);
florian6820ba52012-07-26 02:01:50 +00009503 iterate_if(binop(Iop_CmpNE64, mkexpr(len1), mkU64(1)));
sewardj2019a972011-03-07 16:04:07 +00009504
9505 return "mvcle";
9506}
9507
9508static HChar *
9509s390_irgen_MVST(UChar r1, UChar r2)
9510{
9511 IRTemp addr1 = newTemp(Ity_I64);
9512 IRTemp addr2 = newTemp(Ity_I64);
9513 IRTemp end = newTemp(Ity_I8);
9514 IRTemp byte = newTemp(Ity_I8);
9515 IRTemp counter = newTemp(Ity_I64);
9516
9517 assign(addr1, get_gpr_dw0(r1));
9518 assign(addr2, get_gpr_dw0(r2));
9519 assign(counter, get_counter_dw0());
9520 assign(end, get_gpr_b7(0));
9521 assign(byte, load(Ity_I8, binop(Iop_Add64, mkexpr(addr2),mkexpr(counter))));
9522 store(binop(Iop_Add64,mkexpr(addr1),mkexpr(counter)), mkexpr(byte));
9523
9524 // We use unlimited as cpu-determined number
9525 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
florian6820ba52012-07-26 02:01:50 +00009526 iterate_if(binop(Iop_CmpNE8, mkexpr(end), mkexpr(byte)));
sewardj2019a972011-03-07 16:04:07 +00009527
9528 // and always set cc=1 at the end + update r1
9529 s390_cc_set(1);
9530 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(counter)));
9531 put_counter_dw0(mkU64(0));
9532
9533 return "mvst";
9534}
9535
9536static void
9537s390_irgen_divide_64to32(IROp op, UChar r1, IRTemp op2)
9538{
9539 IRTemp op1 = newTemp(Ity_I64);
9540 IRTemp result = newTemp(Ity_I64);
9541
9542 assign(op1, binop(Iop_32HLto64,
9543 get_gpr_w1(r1), // high 32 bits
9544 get_gpr_w1(r1 + 1))); // low 32 bits
9545 assign(result, binop(op, mkexpr(op1), mkexpr(op2)));
9546 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result))); // remainder
9547 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result))); // quotient
9548}
9549
9550static void
9551s390_irgen_divide_128to64(IROp op, UChar r1, IRTemp op2)
9552{
9553 IRTemp op1 = newTemp(Ity_I128);
9554 IRTemp result = newTemp(Ity_I128);
9555
9556 assign(op1, binop(Iop_64HLto128,
9557 get_gpr_dw0(r1), // high 64 bits
9558 get_gpr_dw0(r1 + 1))); // low 64 bits
9559 assign(result, binop(op, mkexpr(op1), mkexpr(op2)));
9560 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result))); // remainder
9561 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result))); // quotient
9562}
9563
9564static void
9565s390_irgen_divide_64to64(IROp op, UChar r1, IRTemp op2)
9566{
9567 IRTemp op1 = newTemp(Ity_I64);
9568 IRTemp result = newTemp(Ity_I128);
9569
9570 assign(op1, get_gpr_dw0(r1 + 1));
9571 assign(result, binop(op, mkexpr(op1), mkexpr(op2)));
9572 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result))); // remainder
9573 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result))); // quotient
9574}
9575
9576static HChar *
9577s390_irgen_DR(UChar r1, UChar r2)
9578{
9579 IRTemp op2 = newTemp(Ity_I32);
9580
9581 assign(op2, get_gpr_w1(r2));
9582
9583 s390_irgen_divide_64to32(Iop_DivModS64to32, r1, op2);
9584
9585 return "dr";
9586}
9587
9588static HChar *
9589s390_irgen_D(UChar r1, IRTemp op2addr)
9590{
9591 IRTemp op2 = newTemp(Ity_I32);
9592
9593 assign(op2, load(Ity_I32, mkexpr(op2addr)));
9594
9595 s390_irgen_divide_64to32(Iop_DivModS64to32, r1, op2);
9596
9597 return "d";
9598}
9599
9600static HChar *
9601s390_irgen_DLR(UChar r1, UChar r2)
9602{
9603 IRTemp op2 = newTemp(Ity_I32);
9604
9605 assign(op2, get_gpr_w1(r2));
9606
9607 s390_irgen_divide_64to32(Iop_DivModU64to32, r1, op2);
9608
9609 return "dr";
9610}
9611
9612static HChar *
9613s390_irgen_DL(UChar r1, IRTemp op2addr)
9614{
9615 IRTemp op2 = newTemp(Ity_I32);
9616
9617 assign(op2, load(Ity_I32, mkexpr(op2addr)));
9618
9619 s390_irgen_divide_64to32(Iop_DivModU64to32, r1, op2);
9620
9621 return "dl";
9622}
9623
9624static HChar *
9625s390_irgen_DLG(UChar r1, IRTemp op2addr)
9626{
9627 IRTemp op2 = newTemp(Ity_I64);
9628
9629 assign(op2, load(Ity_I64, mkexpr(op2addr)));
9630
9631 s390_irgen_divide_128to64(Iop_DivModU128to64, r1, op2);
9632
9633 return "dlg";
9634}
9635
9636static HChar *
9637s390_irgen_DLGR(UChar r1, UChar r2)
9638{
9639 IRTemp op2 = newTemp(Ity_I64);
9640
9641 assign(op2, get_gpr_dw0(r2));
9642
9643 s390_irgen_divide_128to64(Iop_DivModU128to64, r1, op2);
9644
9645 return "dlgr";
9646}
9647
9648static HChar *
9649s390_irgen_DSGR(UChar r1, UChar r2)
9650{
9651 IRTemp op2 = newTemp(Ity_I64);
9652
9653 assign(op2, get_gpr_dw0(r2));
9654
9655 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
9656
9657 return "dsgr";
9658}
9659
9660static HChar *
9661s390_irgen_DSG(UChar r1, IRTemp op2addr)
9662{
9663 IRTemp op2 = newTemp(Ity_I64);
9664
9665 assign(op2, load(Ity_I64, mkexpr(op2addr)));
9666
9667 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
9668
9669 return "dsg";
9670}
9671
9672static HChar *
9673s390_irgen_DSGFR(UChar r1, UChar r2)
9674{
9675 IRTemp op2 = newTemp(Ity_I64);
9676
9677 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
9678
9679 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
9680
9681 return "dsgfr";
9682}
9683
9684static HChar *
9685s390_irgen_DSGF(UChar r1, IRTemp op2addr)
9686{
9687 IRTemp op2 = newTemp(Ity_I64);
9688
9689 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
9690
9691 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
9692
9693 return "dsgf";
9694}
9695
9696static void
9697s390_irgen_load_ar_multiple(UChar r1, UChar r3, IRTemp op2addr)
9698{
9699 UChar reg;
9700 IRTemp addr = newTemp(Ity_I64);
9701
9702 assign(addr, mkexpr(op2addr));
9703 reg = r1;
9704 do {
9705 IRTemp old = addr;
9706
9707 reg %= 16;
9708 put_ar_w0(reg, load(Ity_I32, mkexpr(addr)));
9709 addr = newTemp(Ity_I64);
9710 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
9711 reg++;
9712 } while (reg != (r3 + 1));
9713}
9714
9715static HChar *
9716s390_irgen_LAM(UChar r1, UChar r3, IRTemp op2addr)
9717{
9718 s390_irgen_load_ar_multiple(r1, r3, op2addr);
9719
9720 return "lam";
9721}
9722
9723static HChar *
9724s390_irgen_LAMY(UChar r1, UChar r3, IRTemp op2addr)
9725{
9726 s390_irgen_load_ar_multiple(r1, r3, op2addr);
9727
9728 return "lamy";
9729}
9730
9731static void
9732s390_irgen_store_ar_multiple(UChar r1, UChar r3, IRTemp op2addr)
9733{
9734 UChar reg;
9735 IRTemp addr = newTemp(Ity_I64);
9736
9737 assign(addr, mkexpr(op2addr));
9738 reg = r1;
9739 do {
9740 IRTemp old = addr;
9741
9742 reg %= 16;
9743 store(mkexpr(addr), get_ar_w0(reg));
9744 addr = newTemp(Ity_I64);
9745 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
9746 reg++;
9747 } while (reg != (r3 + 1));
9748}
9749
9750static HChar *
9751s390_irgen_STAM(UChar r1, UChar r3, IRTemp op2addr)
9752{
9753 s390_irgen_store_ar_multiple(r1, r3, op2addr);
9754
9755 return "stam";
9756}
9757
9758static HChar *
9759s390_irgen_STAMY(UChar r1, UChar r3, IRTemp op2addr)
9760{
9761 s390_irgen_store_ar_multiple(r1, r3, op2addr);
9762
9763 return "stamy";
9764}
9765
9766
9767/* Implementation for 32-bit compare-and-swap */
9768static void
9769s390_irgen_cas_32(UChar r1, UChar r3, IRTemp op2addr)
9770{
9771 IRCAS *cas;
9772 IRTemp op1 = newTemp(Ity_I32);
9773 IRTemp old_mem = newTemp(Ity_I32);
9774 IRTemp op3 = newTemp(Ity_I32);
9775 IRTemp result = newTemp(Ity_I32);
9776 IRTemp nequal = newTemp(Ity_I1);
9777
9778 assign(op1, get_gpr_w1(r1));
9779 assign(op3, get_gpr_w1(r3));
9780
9781 /* The first and second operands are compared. If they are equal,
9782 the third operand is stored at the second- operand location. */
9783 cas = mkIRCAS(IRTemp_INVALID, old_mem,
9784 Iend_BE, mkexpr(op2addr),
9785 NULL, mkexpr(op1), /* expected value */
9786 NULL, mkexpr(op3) /* new value */);
9787 stmt(IRStmt_CAS(cas));
9788
9789 /* Set CC. Operands compared equal -> 0, else 1. */
9790 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(old_mem)));
9791 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
9792
9793 /* If operands were equal (cc == 0) just store the old value op1 in r1.
9794 Otherwise, store the old_value from memory in r1 and yield. */
9795 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
9796 put_gpr_w1(r1, mkite(mkexpr(nequal), mkexpr(old_mem), mkexpr(op1)));
florian6820ba52012-07-26 02:01:50 +00009797 yield_if(mkexpr(nequal));
sewardj2019a972011-03-07 16:04:07 +00009798}
9799
9800static HChar *
9801s390_irgen_CS(UChar r1, UChar r3, IRTemp op2addr)
9802{
9803 s390_irgen_cas_32(r1, r3, op2addr);
9804
9805 return "cs";
9806}
9807
9808static HChar *
9809s390_irgen_CSY(UChar r1, UChar r3, IRTemp op2addr)
9810{
9811 s390_irgen_cas_32(r1, r3, op2addr);
9812
9813 return "csy";
9814}
9815
9816static HChar *
9817s390_irgen_CSG(UChar r1, UChar r3, IRTemp op2addr)
9818{
9819 IRCAS *cas;
9820 IRTemp op1 = newTemp(Ity_I64);
9821 IRTemp old_mem = newTemp(Ity_I64);
9822 IRTemp op3 = newTemp(Ity_I64);
9823 IRTemp result = newTemp(Ity_I64);
9824 IRTemp nequal = newTemp(Ity_I1);
9825
9826 assign(op1, get_gpr_dw0(r1));
9827 assign(op3, get_gpr_dw0(r3));
9828
9829 /* The first and second operands are compared. If they are equal,
9830 the third operand is stored at the second- operand location. */
9831 cas = mkIRCAS(IRTemp_INVALID, old_mem,
9832 Iend_BE, mkexpr(op2addr),
9833 NULL, mkexpr(op1), /* expected value */
9834 NULL, mkexpr(op3) /* new value */);
9835 stmt(IRStmt_CAS(cas));
9836
9837 /* Set CC. Operands compared equal -> 0, else 1. */
9838 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(old_mem)));
9839 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
9840
9841 /* If operands were equal (cc == 0) just store the old value op1 in r1.
9842 Otherwise, store the old_value from memory in r1 and yield. */
9843 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
9844 put_gpr_dw0(r1, mkite(mkexpr(nequal), mkexpr(old_mem), mkexpr(op1)));
florian6820ba52012-07-26 02:01:50 +00009845 yield_if(mkexpr(nequal));
sewardj2019a972011-03-07 16:04:07 +00009846
9847 return "csg";
9848}
9849
florian448cbba2012-06-06 02:26:01 +00009850/* Implementation for 32-bit compare-double-and-swap */
9851static void
9852s390_irgen_cdas_32(UChar r1, UChar r3, IRTemp op2addr)
9853{
9854 IRCAS *cas;
9855 IRTemp op1_high = newTemp(Ity_I32);
9856 IRTemp op1_low = newTemp(Ity_I32);
9857 IRTemp old_mem_high = newTemp(Ity_I32);
9858 IRTemp old_mem_low = newTemp(Ity_I32);
9859 IRTemp op3_high = newTemp(Ity_I32);
9860 IRTemp op3_low = newTemp(Ity_I32);
9861 IRTemp result = newTemp(Ity_I32);
9862 IRTemp nequal = newTemp(Ity_I1);
9863
9864 assign(op1_high, get_gpr_w1(r1));
9865 assign(op1_low, get_gpr_w1(r1+1));
9866 assign(op3_high, get_gpr_w1(r3));
9867 assign(op3_low, get_gpr_w1(r3+1));
9868
9869 /* The first and second operands are compared. If they are equal,
9870 the third operand is stored at the second-operand location. */
9871 cas = mkIRCAS(old_mem_high, old_mem_low,
9872 Iend_BE, mkexpr(op2addr),
9873 mkexpr(op1_high), mkexpr(op1_low), /* expected value */
9874 mkexpr(op3_high), mkexpr(op3_low) /* new value */);
9875 stmt(IRStmt_CAS(cas));
9876
9877 /* Set CC. Operands compared equal -> 0, else 1. */
9878 assign(result, unop(Iop_1Uto32,
9879 binop(Iop_CmpNE32,
9880 binop(Iop_Or32,
9881 binop(Iop_Xor32, mkexpr(op1_high), mkexpr(old_mem_high)),
9882 binop(Iop_Xor32, mkexpr(op1_low), mkexpr(old_mem_low))),
9883 mkU32(0))));
9884
9885 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
9886
9887 /* If operands were equal (cc == 0) just store the old value op1 in r1.
9888 Otherwise, store the old_value from memory in r1 and yield. */
9889 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
9890 put_gpr_w1(r1, mkite(mkexpr(nequal), mkexpr(old_mem_high), mkexpr(op1_high)));
9891 put_gpr_w1(r1+1, mkite(mkexpr(nequal), mkexpr(old_mem_low), mkexpr(op1_low)));
florian6820ba52012-07-26 02:01:50 +00009892 yield_if(mkexpr(nequal));
florian448cbba2012-06-06 02:26:01 +00009893}
9894
9895static HChar *
9896s390_irgen_CDS(UChar r1, UChar r3, IRTemp op2addr)
9897{
9898 s390_irgen_cdas_32(r1, r3, op2addr);
9899
9900 return "cds";
9901}
9902
9903static HChar *
9904s390_irgen_CDSY(UChar r1, UChar r3, IRTemp op2addr)
9905{
9906 s390_irgen_cdas_32(r1, r3, op2addr);
9907
9908 return "cdsy";
9909}
9910
9911static HChar *
9912s390_irgen_CDSG(UChar r1, UChar r3, IRTemp op2addr)
9913{
9914 IRCAS *cas;
9915 IRTemp op1_high = newTemp(Ity_I64);
9916 IRTemp op1_low = newTemp(Ity_I64);
9917 IRTemp old_mem_high = newTemp(Ity_I64);
9918 IRTemp old_mem_low = newTemp(Ity_I64);
9919 IRTemp op3_high = newTemp(Ity_I64);
9920 IRTemp op3_low = newTemp(Ity_I64);
9921 IRTemp result = newTemp(Ity_I64);
9922 IRTemp nequal = newTemp(Ity_I1);
9923
9924 assign(op1_high, get_gpr_dw0(r1));
9925 assign(op1_low, get_gpr_dw0(r1+1));
9926 assign(op3_high, get_gpr_dw0(r3));
9927 assign(op3_low, get_gpr_dw0(r3+1));
9928
9929 /* The first and second operands are compared. If they are equal,
9930 the third operand is stored at the second-operand location. */
9931 cas = mkIRCAS(old_mem_high, old_mem_low,
9932 Iend_BE, mkexpr(op2addr),
9933 mkexpr(op1_high), mkexpr(op1_low), /* expected value */
9934 mkexpr(op3_high), mkexpr(op3_low) /* new value */);
9935 stmt(IRStmt_CAS(cas));
9936
9937 /* Set CC. Operands compared equal -> 0, else 1. */
9938 assign(result, unop(Iop_1Uto64,
9939 binop(Iop_CmpNE64,
9940 binop(Iop_Or64,
9941 binop(Iop_Xor64, mkexpr(op1_high), mkexpr(old_mem_high)),
9942 binop(Iop_Xor64, mkexpr(op1_low), mkexpr(old_mem_low))),
9943 mkU64(0))));
9944
9945 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
9946
9947 /* If operands were equal (cc == 0) just store the old value op1 in r1.
9948 Otherwise, store the old_value from memory in r1 and yield. */
9949 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
9950 put_gpr_dw0(r1, mkite(mkexpr(nequal), mkexpr(old_mem_high), mkexpr(op1_high)));
9951 put_gpr_dw0(r1+1, mkite(mkexpr(nequal), mkexpr(old_mem_low), mkexpr(op1_low)));
florian6820ba52012-07-26 02:01:50 +00009952 yield_if(mkexpr(nequal));
9953
florian448cbba2012-06-06 02:26:01 +00009954 return "cdsg";
9955}
9956
sewardj2019a972011-03-07 16:04:07 +00009957
9958/* Binary floating point */
9959
9960static HChar *
9961s390_irgen_AXBR(UChar r1, UChar r2)
9962{
9963 IRTemp op1 = newTemp(Ity_F128);
9964 IRTemp op2 = newTemp(Ity_F128);
9965 IRTemp result = newTemp(Ity_F128);
9966
9967 assign(op1, get_fpr_pair(r1));
9968 assign(op2, get_fpr_pair(r2));
9969 assign(result, triop(Iop_AddF128, mkU32(Irrm_NEAREST), mkexpr(op1),
9970 mkexpr(op2)));
9971 put_fpr_pair(r1, mkexpr(result));
9972
9973 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
9974
9975 return "axbr";
9976}
9977
9978/* The result of a Iop_CmdFxx operation is a condition code. It is
9979 encoded using the values defined in type IRCmpFxxResult.
9980 Before we can store the condition code into the guest state (or do
9981 anything else with it for that matter) we need to convert it to
9982 the encoding that s390 uses. This is what this function does.
9983
9984 s390 VEX b6 b2 b0 cc.1 cc.0
9985 0 0x40 EQ 1 0 0 0 0
9986 1 0x01 LT 0 0 1 0 1
9987 2 0x00 GT 0 0 0 1 0
9988 3 0x45 Unordered 1 1 1 1 1
9989
9990 The following bits from the VEX encoding are interesting:
9991 b0, b2, b6 with b0 being the LSB. We observe:
9992
9993 cc.0 = b0;
9994 cc.1 = b2 | (~b0 & ~b6)
9995
9996 with cc being the s390 condition code.
9997*/
9998static IRExpr *
9999convert_vex_fpcc_to_s390(IRTemp vex_cc)
10000{
10001 IRTemp cc0 = newTemp(Ity_I32);
10002 IRTemp cc1 = newTemp(Ity_I32);
10003 IRTemp b0 = newTemp(Ity_I32);
10004 IRTemp b2 = newTemp(Ity_I32);
10005 IRTemp b6 = newTemp(Ity_I32);
10006
10007 assign(b0, binop(Iop_And32, mkexpr(vex_cc), mkU32(1)));
10008 assign(b2, binop(Iop_And32, binop(Iop_Shr32, mkexpr(vex_cc), mkU8(2)),
10009 mkU32(1)));
10010 assign(b6, binop(Iop_And32, binop(Iop_Shr32, mkexpr(vex_cc), mkU8(6)),
10011 mkU32(1)));
10012
10013 assign(cc0, mkexpr(b0));
10014 assign(cc1, binop(Iop_Or32, mkexpr(b2),
10015 binop(Iop_And32,
10016 binop(Iop_Sub32, mkU32(1), mkexpr(b0)), /* ~b0 */
10017 binop(Iop_Sub32, mkU32(1), mkexpr(b6)) /* ~b6 */
10018 )));
10019
10020 return binop(Iop_Or32, mkexpr(cc0), binop(Iop_Shl32, mkexpr(cc1), mkU8(1)));
10021}
10022
10023static HChar *
10024s390_irgen_CEBR(UChar r1, UChar r2)
10025{
10026 IRTemp op1 = newTemp(Ity_F32);
10027 IRTemp op2 = newTemp(Ity_F32);
10028 IRTemp cc_vex = newTemp(Ity_I32);
10029 IRTemp cc_s390 = newTemp(Ity_I32);
10030
10031 assign(op1, get_fpr_w0(r1));
10032 assign(op2, get_fpr_w0(r2));
10033 assign(cc_vex, binop(Iop_CmpF32, mkexpr(op1), mkexpr(op2)));
10034
10035 assign(cc_s390, convert_vex_fpcc_to_s390(cc_vex));
10036 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
10037
10038 return "cebr";
10039}
10040
10041static HChar *
10042s390_irgen_CDBR(UChar r1, UChar r2)
10043{
10044 IRTemp op1 = newTemp(Ity_F64);
10045 IRTemp op2 = newTemp(Ity_F64);
10046 IRTemp cc_vex = newTemp(Ity_I32);
10047 IRTemp cc_s390 = newTemp(Ity_I32);
10048
10049 assign(op1, get_fpr_dw0(r1));
10050 assign(op2, get_fpr_dw0(r2));
10051 assign(cc_vex, binop(Iop_CmpF64, mkexpr(op1), mkexpr(op2)));
10052
10053 assign(cc_s390, convert_vex_fpcc_to_s390(cc_vex));
10054 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
10055
10056 return "cdbr";
10057}
10058
10059static HChar *
10060s390_irgen_CXBR(UChar r1, UChar r2)
10061{
10062 IRTemp op1 = newTemp(Ity_F128);
10063 IRTemp op2 = newTemp(Ity_F128);
10064 IRTemp cc_vex = newTemp(Ity_I32);
10065 IRTemp cc_s390 = newTemp(Ity_I32);
10066
10067 assign(op1, get_fpr_pair(r1));
10068 assign(op2, get_fpr_pair(r2));
10069 assign(cc_vex, binop(Iop_CmpF128, mkexpr(op1), mkexpr(op2)));
10070
10071 assign(cc_s390, convert_vex_fpcc_to_s390(cc_vex));
10072 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
10073
10074 return "cxbr";
10075}
10076
10077static HChar *
10078s390_irgen_CEB(UChar r1, IRTemp op2addr)
10079{
10080 IRTemp op1 = newTemp(Ity_F32);
10081 IRTemp op2 = newTemp(Ity_F32);
10082 IRTemp cc_vex = newTemp(Ity_I32);
10083 IRTemp cc_s390 = newTemp(Ity_I32);
10084
10085 assign(op1, get_fpr_w0(r1));
10086 assign(op2, load(Ity_F32, mkexpr(op2addr)));
10087 assign(cc_vex, binop(Iop_CmpF32, mkexpr(op1), mkexpr(op2)));
10088
10089 assign(cc_s390, convert_vex_fpcc_to_s390(cc_vex));
10090 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
10091
10092 return "ceb";
10093}
10094
10095static HChar *
10096s390_irgen_CDB(UChar r1, IRTemp op2addr)
10097{
10098 IRTemp op1 = newTemp(Ity_F64);
10099 IRTemp op2 = newTemp(Ity_F64);
10100 IRTemp cc_vex = newTemp(Ity_I32);
10101 IRTemp cc_s390 = newTemp(Ity_I32);
10102
10103 assign(op1, get_fpr_dw0(r1));
10104 assign(op2, load(Ity_F64, mkexpr(op2addr)));
10105 assign(cc_vex, binop(Iop_CmpF64, mkexpr(op1), mkexpr(op2)));
10106
10107 assign(cc_s390, convert_vex_fpcc_to_s390(cc_vex));
10108 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
10109
10110 return "cdb";
10111}
10112
10113static HChar *
10114s390_irgen_CXFBR(UChar r1, UChar r2)
10115{
10116 IRTemp op2 = newTemp(Ity_I32);
10117
10118 assign(op2, get_gpr_w1(r2));
10119 put_fpr_pair(r1, unop(Iop_I32StoF128, mkexpr(op2)));
10120
10121 return "cxfbr";
10122}
10123
10124static HChar *
10125s390_irgen_CXGBR(UChar r1, UChar r2)
10126{
10127 IRTemp op2 = newTemp(Ity_I64);
10128
10129 assign(op2, get_gpr_dw0(r2));
10130 put_fpr_pair(r1, unop(Iop_I64StoF128, mkexpr(op2)));
10131
10132 return "cxgbr";
10133}
10134
10135static HChar *
10136s390_irgen_CFXBR(UChar r3, UChar r1, UChar r2)
10137{
10138 IRTemp op = newTemp(Ity_F128);
10139 IRTemp result = newTemp(Ity_I32);
10140
10141 assign(op, get_fpr_pair(r2));
10142 assign(result, binop(Iop_F128toI32S, mkU32(encode_rounding_mode(r3)),
10143 mkexpr(op)));
10144 put_gpr_w1(r1, mkexpr(result));
10145 s390_cc_thunk_put1f128(S390_CC_OP_BFP_128_TO_INT_32, op);
10146
10147 return "cfxbr";
10148}
10149
10150static HChar *
10151s390_irgen_CGXBR(UChar r3, UChar r1, UChar r2)
10152{
10153 IRTemp op = newTemp(Ity_F128);
10154 IRTemp result = newTemp(Ity_I64);
10155
10156 assign(op, get_fpr_pair(r2));
10157 assign(result, binop(Iop_F128toI64S, mkU32(encode_rounding_mode(r3)),
10158 mkexpr(op)));
10159 put_gpr_dw0(r1, mkexpr(result));
10160 s390_cc_thunk_put1f128(S390_CC_OP_BFP_128_TO_INT_64, op);
10161
10162 return "cgxbr";
10163}
10164
10165static HChar *
10166s390_irgen_DXBR(UChar r1, UChar r2)
10167{
10168 IRTemp op1 = newTemp(Ity_F128);
10169 IRTemp op2 = newTemp(Ity_F128);
10170 IRTemp result = newTemp(Ity_F128);
10171
10172 assign(op1, get_fpr_pair(r1));
10173 assign(op2, get_fpr_pair(r2));
10174 assign(result, triop(Iop_DivF128, mkU32(Irrm_NEAREST), mkexpr(op1),
10175 mkexpr(op2)));
10176 put_fpr_pair(r1, mkexpr(result));
10177
10178 return "dxbr";
10179}
10180
10181static HChar *
10182s390_irgen_LTXBR(UChar r1, UChar r2)
10183{
10184 IRTemp result = newTemp(Ity_F128);
10185
10186 assign(result, get_fpr_pair(r2));
10187 put_fpr_pair(r1, mkexpr(result));
10188 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
10189
10190 return "ltxbr";
10191}
10192
10193static HChar *
10194s390_irgen_LCXBR(UChar r1, UChar r2)
10195{
10196 IRTemp result = newTemp(Ity_F128);
10197
10198 assign(result, unop(Iop_NegF128, get_fpr_pair(r2)));
10199 put_fpr_pair(r1, mkexpr(result));
10200 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
10201
10202 return "lcxbr";
10203}
10204
10205static HChar *
10206s390_irgen_LXDBR(UChar r1, UChar r2)
10207{
10208 IRTemp op = newTemp(Ity_F64);
10209
10210 assign(op, get_fpr_dw0(r2));
10211 put_fpr_pair(r1, unop(Iop_F64toF128, mkexpr(op)));
10212
10213 return "lxdbr";
10214}
10215
10216static HChar *
10217s390_irgen_LXEBR(UChar r1, UChar r2)
10218{
10219 IRTemp op = newTemp(Ity_F32);
10220
10221 assign(op, get_fpr_w0(r2));
10222 put_fpr_pair(r1, unop(Iop_F32toF128, mkexpr(op)));
10223
10224 return "lxebr";
10225}
10226
10227static HChar *
10228s390_irgen_LXDB(UChar r1, IRTemp op2addr)
10229{
10230 IRTemp op = newTemp(Ity_F64);
10231
10232 assign(op, load(Ity_F64, mkexpr(op2addr)));
10233 put_fpr_pair(r1, unop(Iop_F64toF128, mkexpr(op)));
10234
10235 return "lxdb";
10236}
10237
10238static HChar *
10239s390_irgen_LXEB(UChar r1, IRTemp op2addr)
10240{
10241 IRTemp op = newTemp(Ity_F32);
10242
10243 assign(op, load(Ity_F32, mkexpr(op2addr)));
10244 put_fpr_pair(r1, unop(Iop_F32toF128, mkexpr(op)));
10245
10246 return "lxeb";
10247}
10248
10249static HChar *
10250s390_irgen_LNEBR(UChar r1, UChar r2)
10251{
10252 IRTemp result = newTemp(Ity_F32);
10253
10254 assign(result, unop(Iop_NegF32, unop(Iop_AbsF32, get_fpr_w0(r2))));
10255 put_fpr_w0(r1, mkexpr(result));
10256 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_32, result);
10257
10258 return "lnebr";
10259}
10260
10261static HChar *
10262s390_irgen_LNDBR(UChar r1, UChar r2)
10263{
10264 IRTemp result = newTemp(Ity_F64);
10265
10266 assign(result, unop(Iop_NegF64, unop(Iop_AbsF64, get_fpr_dw0(r2))));
10267 put_fpr_dw0(r1, mkexpr(result));
10268 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_64, result);
10269
10270 return "lndbr";
10271}
10272
10273static HChar *
10274s390_irgen_LNXBR(UChar r1, UChar r2)
10275{
10276 IRTemp result = newTemp(Ity_F128);
10277
10278 assign(result, unop(Iop_NegF128, unop(Iop_AbsF128, get_fpr_pair(r2))));
10279 put_fpr_pair(r1, mkexpr(result));
10280 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
10281
10282 return "lnxbr";
10283}
10284
10285static HChar *
10286s390_irgen_LPEBR(UChar r1, UChar r2)
10287{
10288 IRTemp result = newTemp(Ity_F32);
10289
10290 assign(result, unop(Iop_AbsF32, get_fpr_w0(r2)));
10291 put_fpr_w0(r1, mkexpr(result));
10292 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_32, result);
10293
10294 return "lpebr";
10295}
10296
10297static HChar *
10298s390_irgen_LPDBR(UChar r1, UChar r2)
10299{
10300 IRTemp result = newTemp(Ity_F64);
10301
10302 assign(result, unop(Iop_AbsF64, get_fpr_dw0(r2)));
10303 put_fpr_dw0(r1, mkexpr(result));
10304 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_64, result);
10305
10306 return "lpdbr";
10307}
10308
10309static HChar *
10310s390_irgen_LPXBR(UChar r1, UChar r2)
10311{
10312 IRTemp result = newTemp(Ity_F128);
10313
10314 assign(result, unop(Iop_AbsF128, get_fpr_pair(r2)));
10315 put_fpr_pair(r1, mkexpr(result));
10316 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
10317
10318 return "lpxbr";
10319}
10320
10321static HChar *
10322s390_irgen_LDXBR(UChar r1, UChar r2)
10323{
10324 IRTemp result = newTemp(Ity_F64);
10325
10326 assign(result, binop(Iop_F128toF64, mkU32(Irrm_NEAREST), get_fpr_pair(r2)));
10327 put_fpr_dw0(r1, mkexpr(result));
10328
10329 return "ldxbr";
10330}
10331
10332static HChar *
10333s390_irgen_LEXBR(UChar r1, UChar r2)
10334{
10335 IRTemp result = newTemp(Ity_F32);
10336
10337 assign(result, binop(Iop_F128toF32, mkU32(Irrm_NEAREST), get_fpr_pair(r2)));
10338 put_fpr_w0(r1, mkexpr(result));
10339
10340 return "lexbr";
10341}
10342
10343static HChar *
10344s390_irgen_MXBR(UChar r1, UChar r2)
10345{
10346 IRTemp op1 = newTemp(Ity_F128);
10347 IRTemp op2 = newTemp(Ity_F128);
10348 IRTemp result = newTemp(Ity_F128);
10349
10350 assign(op1, get_fpr_pair(r1));
10351 assign(op2, get_fpr_pair(r2));
10352 assign(result, triop(Iop_MulF128, mkU32(Irrm_NEAREST), mkexpr(op1),
10353 mkexpr(op2)));
10354 put_fpr_pair(r1, mkexpr(result));
10355
10356 return "mxbr";
10357}
10358
10359static HChar *
10360s390_irgen_MAEBR(UChar r1, UChar r3, UChar r2)
10361{
10362 put_fpr_w0(r1, qop(Iop_MAddF32, mkU32(Irrm_NEAREST),
10363 get_fpr_w0(r1), get_fpr_w0(r2), get_fpr_w0(r3)));
10364
10365 return "maebr";
10366}
10367
10368static HChar *
10369s390_irgen_MADBR(UChar r1, UChar r3, UChar r2)
10370{
10371 put_fpr_dw0(r1, qop(Iop_MAddF64, mkU32(Irrm_NEAREST),
10372 get_fpr_dw0(r1), get_fpr_dw0(r2), get_fpr_dw0(r3)));
10373
10374 return "madbr";
10375}
10376
10377static HChar *
10378s390_irgen_MAEB(UChar r3, IRTemp op2addr, UChar r1)
10379{
10380 IRExpr *op2 = load(Ity_F32, mkexpr(op2addr));
10381
10382 put_fpr_w0(r1, qop(Iop_MAddF32, mkU32(Irrm_NEAREST),
10383 get_fpr_w0(r1), op2, get_fpr_w0(r3)));
10384
10385 return "maeb";
10386}
10387
10388static HChar *
10389s390_irgen_MADB(UChar r3, IRTemp op2addr, UChar r1)
10390{
10391 IRExpr *op2 = load(Ity_F64, mkexpr(op2addr));
10392
10393 put_fpr_dw0(r1, qop(Iop_MAddF64, mkU32(Irrm_NEAREST),
10394 get_fpr_dw0(r1), op2, get_fpr_dw0(r3)));
10395
10396 return "madb";
10397}
10398
10399static HChar *
10400s390_irgen_MSEBR(UChar r1, UChar r3, UChar r2)
10401{
10402 put_fpr_w0(r1, qop(Iop_MSubF32, mkU32(Irrm_NEAREST),
10403 get_fpr_w0(r1), get_fpr_w0(r2), get_fpr_w0(r3)));
10404
10405 return "msebr";
10406}
10407
10408static HChar *
10409s390_irgen_MSDBR(UChar r1, UChar r3, UChar r2)
10410{
10411 put_fpr_dw0(r1, qop(Iop_MSubF64, mkU32(Irrm_NEAREST),
10412 get_fpr_dw0(r1), get_fpr_dw0(r2), get_fpr_dw0(r3)));
10413
10414 return "msdbr";
10415}
10416
10417static HChar *
10418s390_irgen_MSEB(UChar r3, IRTemp op2addr, UChar r1)
10419{
10420 IRExpr *op2 = load(Ity_F32, mkexpr(op2addr));
10421
10422 put_fpr_w0(r1, qop(Iop_MSubF32, mkU32(Irrm_NEAREST),
10423 get_fpr_w0(r1), op2, get_fpr_w0(r3)));
10424
10425 return "mseb";
10426}
10427
10428static HChar *
10429s390_irgen_MSDB(UChar r3, IRTemp op2addr, UChar r1)
10430{
10431 IRExpr *op2 = load(Ity_F64, mkexpr(op2addr));
10432
10433 put_fpr_dw0(r1, qop(Iop_MSubF64, mkU32(Irrm_NEAREST),
10434 get_fpr_dw0(r1), op2, get_fpr_dw0(r3)));
10435
10436 return "msdb";
10437}
10438
10439static HChar *
10440s390_irgen_SQEBR(UChar r1, UChar r2)
10441{
10442 IRTemp result = newTemp(Ity_F32);
10443
10444 assign(result, binop(Iop_SqrtF32, mkU32(Irrm_NEAREST), get_fpr_w0(r2)));
10445 put_fpr_w0(r1, mkexpr(result));
10446
10447 return "sqebr";
10448}
10449
10450static HChar *
10451s390_irgen_SQDBR(UChar r1, UChar r2)
10452{
10453 IRTemp result = newTemp(Ity_F64);
10454
10455 assign(result, binop(Iop_SqrtF64, mkU32(Irrm_NEAREST), get_fpr_dw0(r2)));
10456 put_fpr_dw0(r1, mkexpr(result));
10457
10458 return "sqdbr";
10459}
10460
10461static HChar *
10462s390_irgen_SQXBR(UChar r1, UChar r2)
10463{
10464 IRTemp result = newTemp(Ity_F128);
10465
10466 assign(result, binop(Iop_SqrtF128, mkU32(Irrm_NEAREST), get_fpr_pair(r2)));
10467 put_fpr_pair(r1, mkexpr(result));
10468
10469 return "sqxbr";
10470}
10471
10472static HChar *
10473s390_irgen_SQEB(UChar r1, IRTemp op2addr)
10474{
10475 IRTemp op = newTemp(Ity_F32);
10476
10477 assign(op, load(Ity_F32, mkexpr(op2addr)));
10478 put_fpr_w0(r1, binop(Iop_SqrtF32, mkU32(Irrm_NEAREST), mkexpr(op)));
10479
10480 return "sqeb";
10481}
10482
10483static HChar *
10484s390_irgen_SQDB(UChar r1, IRTemp op2addr)
10485{
10486 IRTemp op = newTemp(Ity_F64);
10487
10488 assign(op, load(Ity_F64, mkexpr(op2addr)));
10489 put_fpr_dw0(r1, binop(Iop_SqrtF64, mkU32(Irrm_NEAREST), mkexpr(op)));
10490
10491 return "sqdb";
10492}
10493
10494static HChar *
10495s390_irgen_SXBR(UChar r1, UChar r2)
10496{
10497 IRTemp op1 = newTemp(Ity_F128);
10498 IRTemp op2 = newTemp(Ity_F128);
10499 IRTemp result = newTemp(Ity_F128);
10500
10501 assign(op1, get_fpr_pair(r1));
10502 assign(op2, get_fpr_pair(r2));
10503 assign(result, triop(Iop_SubF128, mkU32(Irrm_NEAREST), mkexpr(op1),
10504 mkexpr(op2)));
10505 put_fpr_pair(r1, mkexpr(result));
10506 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
10507
10508 return "sxbr";
10509}
10510
10511static HChar *
10512s390_irgen_TCEB(UChar r1, IRTemp op2addr)
10513{
10514 IRTemp value = newTemp(Ity_F32);
10515
10516 assign(value, get_fpr_w0(r1));
10517
10518 s390_cc_thunk_putFZ(S390_CC_OP_BFP_TDC_32, value, op2addr);
10519
10520 return "tceb";
10521}
10522
10523static HChar *
10524s390_irgen_TCDB(UChar r1, IRTemp op2addr)
10525{
10526 IRTemp value = newTemp(Ity_F64);
10527
10528 assign(value, get_fpr_dw0(r1));
10529
10530 s390_cc_thunk_putFZ(S390_CC_OP_BFP_TDC_64, value, op2addr);
10531
10532 return "tcdb";
10533}
10534
10535static HChar *
10536s390_irgen_TCXB(UChar r1, IRTemp op2addr)
10537{
10538 IRTemp value = newTemp(Ity_F128);
10539
10540 assign(value, get_fpr_pair(r1));
10541
10542 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_TDC_128, value, op2addr);
10543
10544 return "tcxb";
10545}
10546
10547static HChar *
10548s390_irgen_LCDFR(UChar r1, UChar r2)
10549{
10550 IRTemp result = newTemp(Ity_F64);
10551
10552 assign(result, unop(Iop_NegF64, get_fpr_dw0(r2)));
10553 put_fpr_dw0(r1, mkexpr(result));
10554
10555 return "lcdfr";
10556}
10557
10558static HChar *
10559s390_irgen_LNDFR(UChar r1, UChar r2)
10560{
10561 IRTemp result = newTemp(Ity_F64);
10562
10563 assign(result, unop(Iop_NegF64, unop(Iop_AbsF64, get_fpr_dw0(r2))));
10564 put_fpr_dw0(r1, mkexpr(result));
10565
10566 return "lndfr";
10567}
10568
10569static HChar *
10570s390_irgen_LPDFR(UChar r1, UChar r2)
10571{
10572 IRTemp result = newTemp(Ity_F64);
10573
10574 assign(result, unop(Iop_AbsF64, get_fpr_dw0(r2)));
10575 put_fpr_dw0(r1, mkexpr(result));
10576
10577 return "lpdfr";
10578}
10579
10580static HChar *
10581s390_irgen_LDGR(UChar r1, UChar r2)
10582{
10583 put_fpr_dw0(r1, unop(Iop_ReinterpI64asF64, get_gpr_dw0(r2)));
10584
10585 return "ldgr";
10586}
10587
10588static HChar *
10589s390_irgen_LGDR(UChar r1, UChar r2)
10590{
10591 put_gpr_dw0(r1, unop(Iop_ReinterpF64asI64, get_fpr_dw0(r2)));
10592
10593 return "lgdr";
10594}
10595
10596
10597static HChar *
10598s390_irgen_CPSDR(UChar r3, UChar r1, UChar r2)
10599{
10600 IRTemp sign = newTemp(Ity_I64);
10601 IRTemp value = newTemp(Ity_I64);
10602
10603 assign(sign, binop(Iop_And64, unop(Iop_ReinterpF64asI64, get_fpr_dw0(r3)),
10604 mkU64(1ULL << 63)));
10605 assign(value, binop(Iop_And64, unop(Iop_ReinterpF64asI64, get_fpr_dw0(r2)),
10606 mkU64((1ULL << 63) - 1)));
10607 put_fpr_dw0(r1, unop(Iop_ReinterpI64asF64, binop(Iop_Or64, mkexpr(value),
10608 mkexpr(sign))));
10609
10610 return "cpsdr";
10611}
10612
10613
sewardj2019a972011-03-07 16:04:07 +000010614static IRExpr *
10615s390_call_cvb(IRExpr *in)
10616{
10617 IRExpr **args, *call;
10618
10619 args = mkIRExprVec_1(in);
10620 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
10621 "s390_do_cvb", &s390_do_cvb, args);
10622
10623 /* Nothing is excluded from definedness checking. */
10624 call->Iex.CCall.cee->mcx_mask = 0;
10625
10626 return call;
10627}
10628
10629static HChar *
10630s390_irgen_CVB(UChar r1, IRTemp op2addr)
10631{
10632 put_gpr_w1(r1, s390_call_cvb(load(Ity_I64, mkexpr(op2addr))));
10633
10634 return "cvb";
10635}
10636
10637static HChar *
10638s390_irgen_CVBY(UChar r1, IRTemp op2addr)
10639{
10640 put_gpr_w1(r1, s390_call_cvb(load(Ity_I64, mkexpr(op2addr))));
10641
10642 return "cvby";
10643}
10644
10645
sewardj2019a972011-03-07 16:04:07 +000010646static IRExpr *
10647s390_call_cvd(IRExpr *in)
10648{
10649 IRExpr **args, *call;
10650
10651 args = mkIRExprVec_1(in);
10652 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
10653 "s390_do_cvd", &s390_do_cvd, args);
10654
10655 /* Nothing is excluded from definedness checking. */
10656 call->Iex.CCall.cee->mcx_mask = 0;
10657
10658 return call;
10659}
10660
10661static HChar *
10662s390_irgen_CVD(UChar r1, IRTemp op2addr)
10663{
10664 store(mkexpr(op2addr), s390_call_cvd(get_gpr_w1(r1)));
10665
10666 return "cvd";
10667}
10668
10669static HChar *
10670s390_irgen_CVDY(UChar r1, IRTemp op2addr)
10671{
10672 store(mkexpr(op2addr), s390_call_cvd(get_gpr_w1(r1)));
10673
10674 return "cvdy";
10675}
10676
10677static HChar *
10678s390_irgen_FLOGR(UChar r1, UChar r2)
10679{
10680 IRTemp input = newTemp(Ity_I64);
10681 IRTemp not_zero = newTemp(Ity_I64);
10682 IRTemp tmpnum = newTemp(Ity_I64);
10683 IRTemp num = newTemp(Ity_I64);
10684 IRTemp shift_amount = newTemp(Ity_I8);
10685
10686 /* We use the "count leading zeroes" operator because the number of
10687 leading zeroes is identical with the bit position of the first '1' bit.
10688 However, that operator does not work when the input value is zero.
10689 Therefore, we set the LSB of the input value to 1 and use Clz64 on
10690 the modified value. If input == 0, then the result is 64. Otherwise,
10691 the result of Clz64 is what we want. */
10692
10693 assign(input, get_gpr_dw0(r2));
10694 assign(not_zero, binop(Iop_Or64, mkexpr(input), mkU64(1)));
10695 assign(tmpnum, unop(Iop_Clz64, mkexpr(not_zero)));
10696
10697 /* num = (input == 0) ? 64 : tmpnum */
10698 assign(num, mkite(binop(Iop_CmpEQ64, mkexpr(input), mkU64(0)),
10699 /* == 0 */ mkU64(64),
10700 /* != 0 */ mkexpr(tmpnum)));
10701
10702 put_gpr_dw0(r1, mkexpr(num));
10703
10704 /* Set the leftmost '1' bit of the input value to zero. The general scheme
10705 is to first shift the input value by NUM + 1 bits to the left which
10706 causes the leftmost '1' bit to disappear. Then we shift logically to
10707 the right by NUM + 1 bits. Because the semantics of Iop_Shl64 and
10708 Iop_Shr64 are undefined if the shift-amount is greater than or equal to
10709 the width of the value-to-be-shifted, we need to special case
10710 NUM + 1 >= 64. This is equivalent to INPUT != 0 && INPUT != 1.
10711 For both such INPUT values the result will be 0. */
10712
10713 assign(shift_amount, unop(Iop_64to8, binop(Iop_Add64, mkexpr(num),
10714 mkU64(1))));
10715
10716 put_gpr_dw0(r1 + 1,
florian6ad49522011-09-09 02:38:55 +000010717 mkite(binop(Iop_CmpLE64U, mkexpr(input), mkU64(1)),
10718 /* == 0 || == 1*/ mkU64(0),
10719 /* otherwise */
10720 binop(Iop_Shr64,
10721 binop(Iop_Shl64, mkexpr(input),
10722 mkexpr(shift_amount)),
10723 mkexpr(shift_amount))));
sewardj2019a972011-03-07 16:04:07 +000010724
10725 /* Compare the original value as an unsigned integer with 0. */
10726 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, input,
10727 mktemp(Ity_I64, mkU64(0)), False);
10728
10729 return "flogr";
10730}
10731
sewardj1e5fea62011-05-17 16:18:36 +000010732static HChar *
10733s390_irgen_STCK(IRTemp op2addr)
10734{
10735 IRDirty *d;
10736 IRTemp cc = newTemp(Ity_I64);
10737
10738 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STCK",
10739 &s390x_dirtyhelper_STCK,
10740 mkIRExprVec_1(mkexpr(op2addr)));
10741 d->mFx = Ifx_Write;
10742 d->mAddr = mkexpr(op2addr);
10743 d->mSize = 8;
10744 stmt(IRStmt_Dirty(d));
10745 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
10746 mkexpr(cc), mkU64(0), mkU64(0));
10747 return "stck";
10748}
10749
10750static HChar *
10751s390_irgen_STCKF(IRTemp op2addr)
10752{
10753 IRDirty *d;
10754 IRTemp cc = newTemp(Ity_I64);
10755
10756 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STCKF",
10757 &s390x_dirtyhelper_STCKF,
10758 mkIRExprVec_1(mkexpr(op2addr)));
10759 d->mFx = Ifx_Write;
10760 d->mAddr = mkexpr(op2addr);
10761 d->mSize = 8;
10762 stmt(IRStmt_Dirty(d));
10763 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
10764 mkexpr(cc), mkU64(0), mkU64(0));
10765 return "stckf";
10766}
10767
10768static HChar *
10769s390_irgen_STCKE(IRTemp op2addr)
10770{
10771 IRDirty *d;
10772 IRTemp cc = newTemp(Ity_I64);
10773
10774 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STCKE",
10775 &s390x_dirtyhelper_STCKE,
10776 mkIRExprVec_1(mkexpr(op2addr)));
10777 d->mFx = Ifx_Write;
10778 d->mAddr = mkexpr(op2addr);
10779 d->mSize = 16;
10780 stmt(IRStmt_Dirty(d));
10781 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
10782 mkexpr(cc), mkU64(0), mkU64(0));
10783 return "stcke";
10784}
10785
florian933065d2011-07-11 01:48:02 +000010786static HChar *
10787s390_irgen_STFLE(IRTemp op2addr)
10788{
10789 IRDirty *d;
10790 IRTemp cc = newTemp(Ity_I64);
10791
10792 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STFLE",
10793 &s390x_dirtyhelper_STFLE,
10794 mkIRExprVec_1(mkexpr(op2addr)));
10795
10796 d->needsBBP = 1; /* Need to pass pointer to guest state to helper */
10797
sewardjc9069f22012-06-01 16:09:50 +000010798 d->nFxState = 1;
10799 vex_bzero(&d->fxState, sizeof(d->fxState));
10800
florian933065d2011-07-11 01:48:02 +000010801 d->fxState[0].fx = Ifx_Modify; /* read then write */
10802 d->fxState[0].offset = S390X_GUEST_OFFSET(guest_r0);
10803 d->fxState[0].size = sizeof(ULong);
florian933065d2011-07-11 01:48:02 +000010804
10805 d->mAddr = mkexpr(op2addr);
10806 /* Pretend all double words are written */
10807 d->mSize = S390_NUM_FACILITY_DW * sizeof(ULong);
10808 d->mFx = Ifx_Write;
10809
10810 stmt(IRStmt_Dirty(d));
10811
10812 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET), mkexpr(cc), mkU64(0), mkU64(0));
10813
10814 return "stfle";
10815}
10816
floriana4384a32011-08-11 16:58:45 +000010817static HChar *
10818s390_irgen_CKSM(UChar r1,UChar r2)
10819{
10820 IRTemp addr = newTemp(Ity_I64);
10821 IRTemp op = newTemp(Ity_I32);
10822 IRTemp len = newTemp(Ity_I64);
10823 IRTemp oldval = newTemp(Ity_I32);
10824 IRTemp mask = newTemp(Ity_I32);
10825 IRTemp newop = newTemp(Ity_I32);
10826 IRTemp result = newTemp(Ity_I32);
10827 IRTemp result1 = newTemp(Ity_I32);
10828 IRTemp inc = newTemp(Ity_I64);
10829
10830 assign(oldval, get_gpr_w1(r1));
10831 assign(addr, get_gpr_dw0(r2));
10832 assign(len, get_gpr_dw0(r2+1));
10833
10834 /* Condition code is always zero. */
10835 s390_cc_set(0);
10836
10837 /* If length is zero, there is no need to calculate the checksum */
florian6820ba52012-07-26 02:01:50 +000010838 next_insn_if(binop(Iop_CmpEQ64, mkexpr(len), mkU64(0)));
floriana4384a32011-08-11 16:58:45 +000010839
10840 /* Assiging the increment variable to adjust address and length
10841 later on. */
10842 assign(inc, mkite(binop(Iop_CmpLT64U, mkexpr(len), mkU64(4)),
10843 mkexpr(len), mkU64(4)));
10844
10845 /* If length < 4 the final 4-byte 2nd operand value is computed by
10846 appending the remaining bytes to the right with 0. This is done
10847 by AND'ing the 4 bytes loaded from memory with an appropriate
10848 mask. If length >= 4, that mask is simply 0xffffffff. */
10849
10850 assign(mask, mkite(binop(Iop_CmpLT64U, mkexpr(len), mkU64(4)),
10851 /* Mask computation when len < 4:
10852 0xffffffff << (32 - (len % 4)*8) */
10853 binop(Iop_Shl32, mkU32(0xffffffff),
10854 unop(Iop_32to8,
10855 binop(Iop_Sub32, mkU32(32),
10856 binop(Iop_Shl32,
10857 unop(Iop_64to32,
10858 binop(Iop_And64,
10859 mkexpr(len), mkU64(3))),
10860 mkU8(3))))),
10861 mkU32(0xffffffff)));
10862
10863 assign(op, load(Ity_I32, mkexpr(addr)));
10864 assign(newop, binop(Iop_And32, mkexpr(op), mkexpr(mask)));
10865 assign(result, binop(Iop_Add32, mkexpr(newop), mkexpr(oldval)));
10866
10867 /* Checking for carry */
10868 assign(result1, mkite(binop(Iop_CmpLT32U, mkexpr(result), mkexpr(newop)),
10869 binop(Iop_Add32, mkexpr(result), mkU32(1)),
10870 mkexpr(result)));
10871
10872 put_gpr_w1(r1, mkexpr(result1));
10873 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr), mkexpr(inc)));
10874 put_gpr_dw0(r2+1, binop(Iop_Sub64, mkexpr(len), mkexpr(inc)));
10875
florian6820ba52012-07-26 02:01:50 +000010876 iterate_if(binop(Iop_CmpNE64, mkexpr(len), mkU64(0)));
floriana4384a32011-08-11 16:58:45 +000010877
10878 return "cksm";
10879}
10880
florian9af37692012-01-15 21:01:16 +000010881static HChar *
10882s390_irgen_TROO(UChar m3, UChar r1, UChar r2)
10883{
10884 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
10885 src_addr = newTemp(Ity_I64);
10886 des_addr = newTemp(Ity_I64);
10887 tab_addr = newTemp(Ity_I64);
10888 test_byte = newTemp(Ity_I8);
10889 src_len = newTemp(Ity_I64);
10890
10891 assign(src_addr, get_gpr_dw0(r2));
10892 assign(des_addr, get_gpr_dw0(r1));
10893 assign(tab_addr, get_gpr_dw0(1));
florian53518532012-01-18 14:00:31 +000010894 assign(src_len, get_gpr_dw0(r1+1));
florian9af37692012-01-15 21:01:16 +000010895 assign(test_byte, get_gpr_b7(0));
10896
10897 IRTemp op = newTemp(Ity_I8);
10898 IRTemp op1 = newTemp(Ity_I8);
10899 IRTemp result = newTemp(Ity_I64);
10900
10901 /* End of source string? We're done; proceed to next insn */
10902 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000010903 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian9af37692012-01-15 21:01:16 +000010904
10905 /* Load character from source string, index translation table and
10906 store translated character in op1. */
10907 assign(op, load(Ity_I8, mkexpr(src_addr)));
10908
10909 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)),
10910 mkexpr(tab_addr)));
10911 assign(op1, load(Ity_I8, mkexpr(result)));
10912
10913 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
10914 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000010915 next_insn_if(binop(Iop_CmpEQ8, mkexpr(op1), mkexpr(test_byte)));
florian9af37692012-01-15 21:01:16 +000010916 }
10917 store(get_gpr_dw0(r1), mkexpr(op1));
10918
10919 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(1)));
10920 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(1)));
10921 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(1)));
10922
florian6820ba52012-07-26 02:01:50 +000010923 iterate();
florian9af37692012-01-15 21:01:16 +000010924
10925 return "troo";
10926}
10927
florian730448f2012-02-04 17:07:07 +000010928static HChar *
10929s390_irgen_TRTO(UChar m3, UChar r1, UChar r2)
10930{
10931 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
10932 src_addr = newTemp(Ity_I64);
10933 des_addr = newTemp(Ity_I64);
10934 tab_addr = newTemp(Ity_I64);
10935 test_byte = newTemp(Ity_I8);
10936 src_len = newTemp(Ity_I64);
10937
10938 assign(src_addr, get_gpr_dw0(r2));
10939 assign(des_addr, get_gpr_dw0(r1));
10940 assign(tab_addr, get_gpr_dw0(1));
10941 assign(src_len, get_gpr_dw0(r1+1));
10942 assign(test_byte, get_gpr_b7(0));
10943
10944 IRTemp op = newTemp(Ity_I16);
10945 IRTemp op1 = newTemp(Ity_I8);
10946 IRTemp result = newTemp(Ity_I64);
10947
10948 /* End of source string? We're done; proceed to next insn */
10949 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000010950 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian730448f2012-02-04 17:07:07 +000010951
10952 /* Load character from source string, index translation table and
10953 store translated character in op1. */
10954 assign(op, load(Ity_I16, mkexpr(src_addr)));
10955
10956 assign(result, binop(Iop_Add64, unop(Iop_16Uto64, mkexpr(op)),
10957 mkexpr(tab_addr)));
10958
10959 assign(op1, load(Ity_I8, mkexpr(result)));
10960
10961 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
10962 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000010963 next_insn_if(binop(Iop_CmpEQ8, mkexpr(op1), mkexpr(test_byte)));
florian730448f2012-02-04 17:07:07 +000010964 }
10965 store(get_gpr_dw0(r1), mkexpr(op1));
10966
10967 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(2)));
10968 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(1)));
10969 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(2)));
10970
florian6820ba52012-07-26 02:01:50 +000010971 iterate();
florian730448f2012-02-04 17:07:07 +000010972
10973 return "trto";
10974}
10975
10976static HChar *
10977s390_irgen_TROT(UChar m3, UChar r1, UChar r2)
10978{
10979 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
10980 src_addr = newTemp(Ity_I64);
10981 des_addr = newTemp(Ity_I64);
10982 tab_addr = newTemp(Ity_I64);
10983 test_byte = newTemp(Ity_I16);
10984 src_len = newTemp(Ity_I64);
10985
10986 assign(src_addr, get_gpr_dw0(r2));
10987 assign(des_addr, get_gpr_dw0(r1));
10988 assign(tab_addr, get_gpr_dw0(1));
10989 assign(src_len, get_gpr_dw0(r1+1));
10990 assign(test_byte, get_gpr_hw3(0));
10991
10992 IRTemp op = newTemp(Ity_I8);
10993 IRTemp op1 = newTemp(Ity_I16);
10994 IRTemp result = newTemp(Ity_I64);
10995
10996 /* End of source string? We're done; proceed to next insn */
10997 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000010998 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian730448f2012-02-04 17:07:07 +000010999
11000 /* Load character from source string, index translation table and
11001 store translated character in op1. */
11002 assign(op, binop(Iop_Shl8, load(Ity_I8, mkexpr(src_addr)), mkU8(1)));
11003
11004 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)),
11005 mkexpr(tab_addr)));
11006 assign(op1, load(Ity_I16, mkexpr(result)));
11007
11008 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
11009 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000011010 next_insn_if(binop(Iop_CmpEQ16, mkexpr(op1), mkexpr(test_byte)));
florian730448f2012-02-04 17:07:07 +000011011 }
11012 store(get_gpr_dw0(r1), mkexpr(op1));
11013
11014 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(1)));
11015 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(2)));
11016 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(1)));
11017
florian6820ba52012-07-26 02:01:50 +000011018 iterate();
florian730448f2012-02-04 17:07:07 +000011019
11020 return "trot";
11021}
11022
11023static HChar *
11024s390_irgen_TRTT(UChar m3, UChar r1, UChar r2)
11025{
11026 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
11027 src_addr = newTemp(Ity_I64);
11028 des_addr = newTemp(Ity_I64);
11029 tab_addr = newTemp(Ity_I64);
11030 test_byte = newTemp(Ity_I16);
11031 src_len = newTemp(Ity_I64);
11032
11033 assign(src_addr, get_gpr_dw0(r2));
11034 assign(des_addr, get_gpr_dw0(r1));
11035 assign(tab_addr, get_gpr_dw0(1));
11036 assign(src_len, get_gpr_dw0(r1+1));
11037 assign(test_byte, get_gpr_hw3(0));
11038
11039 IRTemp op = newTemp(Ity_I16);
11040 IRTemp op1 = newTemp(Ity_I16);
11041 IRTemp result = newTemp(Ity_I64);
11042
11043 /* End of source string? We're done; proceed to next insn */
11044 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000011045 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian730448f2012-02-04 17:07:07 +000011046
11047 /* Load character from source string, index translation table and
11048 store translated character in op1. */
11049 assign(op, binop(Iop_Shl16, load(Ity_I16, mkexpr(src_addr)), mkU8(1)));
11050
11051 assign(result, binop(Iop_Add64, unop(Iop_16Uto64, mkexpr(op)),
11052 mkexpr(tab_addr)));
11053 assign(op1, load(Ity_I16, mkexpr(result)));
11054
11055 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
11056 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000011057 next_insn_if(binop(Iop_CmpEQ16, mkexpr(op1), mkexpr(test_byte)));
florian730448f2012-02-04 17:07:07 +000011058 }
11059
11060 store(get_gpr_dw0(r1), mkexpr(op1));
11061
11062 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(2)));
11063 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(2)));
11064 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(2)));
11065
florian6820ba52012-07-26 02:01:50 +000011066 iterate();
florian730448f2012-02-04 17:07:07 +000011067
11068 return "trtt";
11069}
11070
11071static HChar *
11072s390_irgen_TR(UChar length, IRTemp start1, IRTemp start2)
11073{
florianf87d4fb2012-05-05 02:55:24 +000011074 IRTemp len = newTemp(Ity_I64);
florian730448f2012-02-04 17:07:07 +000011075
florianf87d4fb2012-05-05 02:55:24 +000011076 assign(len, mkU64(length));
11077 s390_irgen_TR_EX(len, start1, start2);
florian730448f2012-02-04 17:07:07 +000011078
11079 return "tr";
11080}
11081
11082static HChar *
11083s390_irgen_TRE(UChar r1,UChar r2)
11084{
11085 IRTemp src_addr, tab_addr, src_len, test_byte;
11086 src_addr = newTemp(Ity_I64);
11087 tab_addr = newTemp(Ity_I64);
11088 src_len = newTemp(Ity_I64);
11089 test_byte = newTemp(Ity_I8);
11090
11091 assign(src_addr, get_gpr_dw0(r1));
11092 assign(src_len, get_gpr_dw0(r1+1));
11093 assign(tab_addr, get_gpr_dw0(r2));
11094 assign(test_byte, get_gpr_b7(0));
11095
11096 IRTemp op = newTemp(Ity_I8);
11097 IRTemp op1 = newTemp(Ity_I8);
11098 IRTemp result = newTemp(Ity_I64);
11099
11100 /* End of source string? We're done; proceed to next insn */
11101 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000011102 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian730448f2012-02-04 17:07:07 +000011103
11104 /* Load character from source string and compare with test byte */
11105 assign(op, load(Ity_I8, mkexpr(src_addr)));
11106
11107 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000011108 next_insn_if(binop(Iop_CmpEQ8, mkexpr(op), mkexpr(test_byte)));
florian730448f2012-02-04 17:07:07 +000011109
11110 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)),
11111 mkexpr(tab_addr)));
11112
11113 assign(op1, load(Ity_I8, mkexpr(result)));
11114
11115 store(get_gpr_dw0(r1), mkexpr(op1));
11116 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(src_addr), mkU64(1)));
11117 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(1)));
11118
florian6820ba52012-07-26 02:01:50 +000011119 iterate();
florian730448f2012-02-04 17:07:07 +000011120
11121 return "tre";
11122}
11123
floriana0100c92012-07-20 00:06:35 +000011124static IRExpr *
11125s390_call_cu21(IRExpr *srcval, IRExpr *low_surrogate)
11126{
11127 IRExpr **args, *call;
11128 args = mkIRExprVec_2(srcval, low_surrogate);
11129 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
11130 "s390_do_cu21", &s390_do_cu21, args);
11131
11132 /* Nothing is excluded from definedness checking. */
11133 call->Iex.CCall.cee->mcx_mask = 0;
11134
11135 return call;
11136}
11137
11138static HChar *
11139s390_irgen_CU21(UChar m3, UChar r1, UChar r2)
11140{
11141 IRTemp addr1 = newTemp(Ity_I64);
11142 IRTemp addr2 = newTemp(Ity_I64);
11143 IRTemp len1 = newTemp(Ity_I64);
11144 IRTemp len2 = newTemp(Ity_I64);
11145
11146 assign(addr1, get_gpr_dw0(r1));
11147 assign(addr2, get_gpr_dw0(r2));
11148 assign(len1, get_gpr_dw0(r1 + 1));
11149 assign(len2, get_gpr_dw0(r2 + 1));
11150
11151 /* We're processing the 2nd operand 2 bytes at a time. Therefore, if
11152 there are less than 2 bytes left, then the 2nd operand is exhausted
11153 and we're done here. cc = 0 */
11154 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000011155 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(2)));
floriana0100c92012-07-20 00:06:35 +000011156
11157 /* There are at least two bytes there. Read them. */
11158 IRTemp srcval = newTemp(Ity_I32);
11159 assign(srcval, unop(Iop_16Uto32, load(Ity_I16, mkexpr(addr2))));
11160
11161 /* Find out whether this is a high surrogate. I.e. SRCVAL lies
11162 inside the interval [0xd800 - 0xdbff] */
11163 IRTemp is_high_surrogate = newTemp(Ity_I32);
11164 IRExpr *flag1 = mkite(binop(Iop_CmpLE32U, mkU32(0xd800), mkexpr(srcval)),
11165 mkU32(1), mkU32(0));
11166 IRExpr *flag2 = mkite(binop(Iop_CmpLE32U, mkexpr(srcval), mkU32(0xdbff)),
11167 mkU32(1), mkU32(0));
11168 assign(is_high_surrogate, binop(Iop_And32, flag1, flag2));
11169
11170 /* If SRCVAL is a high surrogate and there are less than 4 bytes left,
11171 then the 2nd operand is exhausted and we're done here. cc = 0 */
11172 IRExpr *not_enough_bytes =
11173 mkite(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)), mkU32(1), mkU32(0));
11174
florian6820ba52012-07-26 02:01:50 +000011175 next_insn_if(binop(Iop_CmpEQ32,
11176 binop(Iop_And32, mkexpr(is_high_surrogate),
11177 not_enough_bytes), mkU32(1)));
floriana0100c92012-07-20 00:06:35 +000011178
11179 /* The 2nd operand is not exhausted. If the first 2 bytes are a high
11180 surrogate, read the next two bytes (low surrogate). */
11181 IRTemp low_surrogate = newTemp(Ity_I32);
11182 IRExpr *low_surrogate_addr = binop(Iop_Add64, mkexpr(addr2), mkU64(2));
11183
11184 assign(low_surrogate,
11185 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
11186 unop(Iop_16Uto32, load(Ity_I16, low_surrogate_addr)),
11187 mkU32(0))); // any value is fine; it will not be used
11188
11189 /* Call the helper */
11190 IRTemp retval = newTemp(Ity_I64);
11191 assign(retval, s390_call_cu21(mkexpr(srcval), mkexpr(low_surrogate)));
11192
11193 /* Before we can test whether the 1st operand is exhausted we need to
11194 test for an invalid low surrogate. Because cc=2 outranks cc=1. */
11195 if (s390_host_has_etf3 && (m3 & 0x1) == 1) {
11196 IRExpr *invalid_low_surrogate =
11197 binop(Iop_And64, mkexpr(retval), mkU64(0xff));
11198
11199 s390_cc_set(2);
florian6820ba52012-07-26 02:01:50 +000011200 next_insn_if(binop(Iop_CmpEQ64, invalid_low_surrogate, mkU64(1)));
floriana0100c92012-07-20 00:06:35 +000011201 }
11202
11203 /* Now test whether the 1st operand is exhausted */
11204 IRTemp num_bytes = newTemp(Ity_I64);
11205 assign(num_bytes, binop(Iop_And64,
11206 binop(Iop_Shr64, mkexpr(retval), mkU8(8)),
11207 mkU64(0xff)));
11208 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000011209 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
floriana0100c92012-07-20 00:06:35 +000011210
11211 /* Extract the bytes to be stored at addr1 */
11212 IRTemp data = newTemp(Ity_I64);
11213 assign(data, binop(Iop_Shr64, mkexpr(retval), mkU8(16)));
11214
11215 /* To store the bytes construct 4 dirty helper calls. The helper calls
11216 are guarded (num_bytes == 1, num_bytes == 2, etc) such that only
11217 one of them will be called at runtime. */
11218 int i;
11219 for (i = 1; i <= 4; ++i) {
11220 IRDirty *d;
11221
11222 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
11223 &s390x_dirtyhelper_CUxy,
11224 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
11225 mkexpr(num_bytes)));
11226 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
11227 d->mFx = Ifx_Write;
11228 d->mAddr = mkexpr(addr1);
11229 d->mSize = i;
11230 stmt(IRStmt_Dirty(d));
11231 }
11232
11233 /* Update source address and length */
11234 IRTemp num_src_bytes = newTemp(Ity_I64);
11235 assign(num_src_bytes,
11236 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
11237 mkU64(4), mkU64(2)));
11238 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkexpr(num_src_bytes)));
11239 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkexpr(num_src_bytes)));
11240
11241 /* Update destination address and length */
11242 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
11243 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
11244
florian6820ba52012-07-26 02:01:50 +000011245 iterate();
floriana0100c92012-07-20 00:06:35 +000011246
11247 return "cu21";
11248}
11249
florian2a415a12012-07-21 17:41:36 +000011250static IRExpr *
11251s390_call_cu24(IRExpr *srcval, IRExpr *low_surrogate)
11252{
11253 IRExpr **args, *call;
11254 args = mkIRExprVec_2(srcval, low_surrogate);
11255 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
11256 "s390_do_cu24", &s390_do_cu24, args);
11257
11258 /* Nothing is excluded from definedness checking. */
11259 call->Iex.CCall.cee->mcx_mask = 0;
11260
11261 return call;
11262}
11263
11264static HChar *
11265s390_irgen_CU24(UChar m3, UChar r1, UChar r2)
11266{
11267 IRTemp addr1 = newTemp(Ity_I64);
11268 IRTemp addr2 = newTemp(Ity_I64);
11269 IRTemp len1 = newTemp(Ity_I64);
11270 IRTemp len2 = newTemp(Ity_I64);
11271
11272 assign(addr1, get_gpr_dw0(r1));
11273 assign(addr2, get_gpr_dw0(r2));
11274 assign(len1, get_gpr_dw0(r1 + 1));
11275 assign(len2, get_gpr_dw0(r2 + 1));
11276
11277 /* We're processing the 2nd operand 2 bytes at a time. Therefore, if
11278 there are less than 2 bytes left, then the 2nd operand is exhausted
11279 and we're done here. cc = 0 */
11280 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000011281 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(2)));
florian2a415a12012-07-21 17:41:36 +000011282
11283 /* There are at least two bytes there. Read them. */
11284 IRTemp srcval = newTemp(Ity_I32);
11285 assign(srcval, unop(Iop_16Uto32, load(Ity_I16, mkexpr(addr2))));
11286
11287 /* Find out whether this is a high surrogate. I.e. SRCVAL lies
11288 inside the interval [0xd800 - 0xdbff] */
11289 IRTemp is_high_surrogate = newTemp(Ity_I32);
11290 IRExpr *flag1 = mkite(binop(Iop_CmpLE32U, mkU32(0xd800), mkexpr(srcval)),
11291 mkU32(1), mkU32(0));
11292 IRExpr *flag2 = mkite(binop(Iop_CmpLE32U, mkexpr(srcval), mkU32(0xdbff)),
11293 mkU32(1), mkU32(0));
11294 assign(is_high_surrogate, binop(Iop_And32, flag1, flag2));
11295
11296 /* If SRCVAL is a high surrogate and there are less than 4 bytes left,
11297 then the 2nd operand is exhausted and we're done here. cc = 0 */
11298 IRExpr *not_enough_bytes =
11299 mkite(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)), mkU32(1), mkU32(0));
11300
florian6820ba52012-07-26 02:01:50 +000011301 next_insn_if(binop(Iop_CmpEQ32,
11302 binop(Iop_And32, mkexpr(is_high_surrogate),
11303 not_enough_bytes),
11304 mkU32(1)));
florian2a415a12012-07-21 17:41:36 +000011305
11306 /* The 2nd operand is not exhausted. If the first 2 bytes are a high
11307 surrogate, read the next two bytes (low surrogate). */
11308 IRTemp low_surrogate = newTemp(Ity_I32);
11309 IRExpr *low_surrogate_addr = binop(Iop_Add64, mkexpr(addr2), mkU64(2));
11310
11311 assign(low_surrogate,
11312 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
11313 unop(Iop_16Uto32, load(Ity_I16, low_surrogate_addr)),
11314 mkU32(0))); // any value is fine; it will not be used
11315
11316 /* Call the helper */
11317 IRTemp retval = newTemp(Ity_I64);
11318 assign(retval, s390_call_cu24(mkexpr(srcval), mkexpr(low_surrogate)));
11319
11320 /* Before we can test whether the 1st operand is exhausted we need to
11321 test for an invalid low surrogate. Because cc=2 outranks cc=1. */
11322 if (s390_host_has_etf3 && (m3 & 0x1) == 1) {
11323 IRExpr *invalid_low_surrogate =
11324 binop(Iop_And64, mkexpr(retval), mkU64(0xff));
11325
11326 s390_cc_set(2);
florian6820ba52012-07-26 02:01:50 +000011327 next_insn_if(binop(Iop_CmpEQ64, invalid_low_surrogate, mkU64(1)));
florian2a415a12012-07-21 17:41:36 +000011328 }
11329
11330 /* Now test whether the 1st operand is exhausted */
11331 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000011332 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkU64(4)));
florian2a415a12012-07-21 17:41:36 +000011333
11334 /* Extract the bytes to be stored at addr1 */
11335 IRExpr *data = unop(Iop_64to32, binop(Iop_Shr64, mkexpr(retval), mkU8(8)));
11336
11337 store(mkexpr(addr1), data);
11338
11339 /* Update source address and length */
11340 IRTemp num_src_bytes = newTemp(Ity_I64);
11341 assign(num_src_bytes,
11342 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
11343 mkU64(4), mkU64(2)));
11344 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkexpr(num_src_bytes)));
11345 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkexpr(num_src_bytes)));
11346
11347 /* Update destination address and length */
11348 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkU64(4)));
11349 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkU64(4)));
11350
florian6820ba52012-07-26 02:01:50 +000011351 iterate();
florian2a415a12012-07-21 17:41:36 +000011352
11353 return "cu24";
11354}
floriana4384a32011-08-11 16:58:45 +000011355
florian956194b2012-07-28 22:18:32 +000011356static IRExpr *
11357s390_call_cu42(IRExpr *srcval)
11358{
11359 IRExpr **args, *call;
11360 args = mkIRExprVec_1(srcval);
11361 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
11362 "s390_do_cu42", &s390_do_cu42, args);
11363
11364 /* Nothing is excluded from definedness checking. */
11365 call->Iex.CCall.cee->mcx_mask = 0;
11366
11367 return call;
11368}
11369
11370static HChar *
11371s390_irgen_CU42(UChar r1, UChar r2)
11372{
11373 IRTemp addr1 = newTemp(Ity_I64);
11374 IRTemp addr2 = newTemp(Ity_I64);
11375 IRTemp len1 = newTemp(Ity_I64);
11376 IRTemp len2 = newTemp(Ity_I64);
11377
11378 assign(addr1, get_gpr_dw0(r1));
11379 assign(addr2, get_gpr_dw0(r2));
11380 assign(len1, get_gpr_dw0(r1 + 1));
11381 assign(len2, get_gpr_dw0(r2 + 1));
11382
11383 /* We're processing the 2nd operand 4 bytes at a time. Therefore, if
11384 there are less than 4 bytes left, then the 2nd operand is exhausted
11385 and we're done here. cc = 0 */
11386 s390_cc_set(0);
11387 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)));
11388
11389 /* Read the 2nd operand. */
11390 IRTemp srcval = newTemp(Ity_I32);
11391 assign(srcval, load(Ity_I32, mkexpr(addr2)));
11392
11393 /* Call the helper */
11394 IRTemp retval = newTemp(Ity_I64);
11395 assign(retval, s390_call_cu42(mkexpr(srcval)));
11396
11397 /* If the UTF-32 character was invalid, set cc=2 and we're done.
11398 cc=2 outranks cc=1 (1st operand exhausted) */
11399 IRExpr *invalid_character = binop(Iop_And64, mkexpr(retval), mkU64(0xff));
11400
11401 s390_cc_set(2);
11402 next_insn_if(binop(Iop_CmpEQ64, invalid_character, mkU64(1)));
11403
11404 /* Now test whether the 1st operand is exhausted */
11405 IRTemp num_bytes = newTemp(Ity_I64);
11406 assign(num_bytes, binop(Iop_And64,
11407 binop(Iop_Shr64, mkexpr(retval), mkU8(8)),
11408 mkU64(0xff)));
11409 s390_cc_set(1);
11410 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
11411
11412 /* Extract the bytes to be stored at addr1 */
11413 IRTemp data = newTemp(Ity_I64);
11414 assign(data, binop(Iop_Shr64, mkexpr(retval), mkU8(16)));
11415
11416 /* To store the bytes construct 2 dirty helper calls. The helper calls
11417 are guarded (num_bytes == 2 and num_bytes == 4, respectively) such
11418 that only one of them will be called at runtime. */
11419
11420 Int i;
11421 for (i = 2; i <= 4; ++i) {
11422 IRDirty *d;
11423
11424 if (i == 3) continue; // skip this one
11425
11426 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
11427 &s390x_dirtyhelper_CUxy,
11428 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
11429 mkexpr(num_bytes)));
11430 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
11431 d->mFx = Ifx_Write;
11432 d->mAddr = mkexpr(addr1);
11433 d->mSize = i;
11434 stmt(IRStmt_Dirty(d));
11435 }
11436
11437 /* Update source address and length */
11438 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkU64(4)));
11439 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkU64(4)));
11440
11441 /* Update destination address and length */
11442 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
11443 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
11444
11445 iterate();
11446
11447 return "cu42";
11448}
11449
sewardj2019a972011-03-07 16:04:07 +000011450/*------------------------------------------------------------*/
11451/*--- Build IR for special instructions ---*/
11452/*------------------------------------------------------------*/
11453
florianb4df7682011-07-05 02:09:01 +000011454static void
sewardj2019a972011-03-07 16:04:07 +000011455s390_irgen_client_request(void)
11456{
11457 if (0)
11458 vex_printf("%%R3 = client_request ( %%R2 )\n");
11459
florianf9e1ed72012-04-17 02:41:56 +000011460 Addr64 next = guest_IA_curr_instr + S390_SPECIAL_OP_PREAMBLE_SIZE
11461 + S390_SPECIAL_OP_SIZE;
sewardj2019a972011-03-07 16:04:07 +000011462
florianf9e1ed72012-04-17 02:41:56 +000011463 dis_res->jk_StopHere = Ijk_ClientReq;
sewardj2019a972011-03-07 16:04:07 +000011464 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +000011465
11466 put_IA(mkaddr_expr(next));
sewardj2019a972011-03-07 16:04:07 +000011467}
11468
florianb4df7682011-07-05 02:09:01 +000011469static void
sewardj2019a972011-03-07 16:04:07 +000011470s390_irgen_guest_NRADDR(void)
11471{
11472 if (0)
11473 vex_printf("%%R3 = guest_NRADDR\n");
11474
floriane88b3c92011-07-05 02:48:39 +000011475 put_gpr_dw0(3, IRExpr_Get(S390X_GUEST_OFFSET(guest_NRADDR), Ity_I64));
sewardj2019a972011-03-07 16:04:07 +000011476}
11477
florianb4df7682011-07-05 02:09:01 +000011478static void
sewardj2019a972011-03-07 16:04:07 +000011479s390_irgen_call_noredir(void)
11480{
florianf9e1ed72012-04-17 02:41:56 +000011481 Addr64 next = guest_IA_curr_instr + S390_SPECIAL_OP_PREAMBLE_SIZE
11482 + S390_SPECIAL_OP_SIZE;
11483
sewardj2019a972011-03-07 16:04:07 +000011484 /* Continue after special op */
florianf9e1ed72012-04-17 02:41:56 +000011485 put_gpr_dw0(14, mkaddr_expr(next));
sewardj2019a972011-03-07 16:04:07 +000011486
11487 /* The address is in REG1, all parameters are in the right (guest) places */
florianf9e1ed72012-04-17 02:41:56 +000011488 put_IA(get_gpr_dw0(1));
sewardj2019a972011-03-07 16:04:07 +000011489
11490 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +000011491 dis_res->jk_StopHere = Ijk_NoRedir;
sewardj2019a972011-03-07 16:04:07 +000011492}
11493
11494/* Force proper alignment for the structures below. */
11495#pragma pack(1)
11496
11497
11498static s390_decode_t
11499s390_decode_2byte_and_irgen(UChar *bytes)
11500{
11501 typedef union {
11502 struct {
11503 unsigned int op : 16;
11504 } E;
11505 struct {
11506 unsigned int op : 8;
11507 unsigned int i : 8;
11508 } I;
11509 struct {
11510 unsigned int op : 8;
11511 unsigned int r1 : 4;
11512 unsigned int r2 : 4;
11513 } RR;
11514 } formats;
11515 union {
11516 formats fmt;
11517 UShort value;
11518 } ovl;
11519
11520 vassert(sizeof(formats) == 2);
11521
11522 ((char *)(&ovl.value))[0] = bytes[0];
11523 ((char *)(&ovl.value))[1] = bytes[1];
11524
11525 switch (ovl.value & 0xffff) {
11526 case 0x0101: /* PR */ goto unimplemented;
11527 case 0x0102: /* UPT */ goto unimplemented;
11528 case 0x0104: /* PTFF */ goto unimplemented;
11529 case 0x0107: /* SCKPF */ goto unimplemented;
11530 case 0x010a: /* PFPO */ goto unimplemented;
11531 case 0x010b: /* TAM */ goto unimplemented;
11532 case 0x010c: /* SAM24 */ goto unimplemented;
11533 case 0x010d: /* SAM31 */ goto unimplemented;
11534 case 0x010e: /* SAM64 */ goto unimplemented;
11535 case 0x01ff: /* TRAP2 */ goto unimplemented;
11536 }
11537
11538 switch ((ovl.value & 0xff00) >> 8) {
11539 case 0x04: /* SPM */ goto unimplemented;
11540 case 0x05: /* BALR */ goto unimplemented;
11541 case 0x06: s390_format_RR_RR(s390_irgen_BCTR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
11542 goto ok;
11543 case 0x07: s390_format_RR(s390_irgen_BCR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
11544 goto ok;
11545 case 0x0a: s390_format_I(s390_irgen_SVC, ovl.fmt.I.i); goto ok;
11546 case 0x0b: /* BSM */ goto unimplemented;
11547 case 0x0c: /* BASSM */ goto unimplemented;
11548 case 0x0d: s390_format_RR_RR(s390_irgen_BASR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
11549 goto ok;
florianb0c9a132011-09-08 15:37:39 +000011550 case 0x0e: s390_format_RR(s390_irgen_MVCL, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
11551 goto ok;
11552 case 0x0f: s390_format_RR(s390_irgen_CLCL, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
11553 goto ok;
sewardj2019a972011-03-07 16:04:07 +000011554 case 0x10: s390_format_RR_RR(s390_irgen_LPR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
11555 goto ok;
11556 case 0x11: s390_format_RR_RR(s390_irgen_LNR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
11557 goto ok;
11558 case 0x12: s390_format_RR_RR(s390_irgen_LTR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
11559 goto ok;
11560 case 0x13: s390_format_RR_RR(s390_irgen_LCR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
11561 goto ok;
11562 case 0x14: s390_format_RR_RR(s390_irgen_NR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
11563 goto ok;
11564 case 0x15: s390_format_RR_RR(s390_irgen_CLR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
11565 goto ok;
11566 case 0x16: s390_format_RR_RR(s390_irgen_OR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
11567 goto ok;
11568 case 0x17: s390_format_RR_RR(s390_irgen_XR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
11569 goto ok;
11570 case 0x18: s390_format_RR_RR(s390_irgen_LR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
11571 goto ok;
11572 case 0x19: s390_format_RR_RR(s390_irgen_CR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
11573 goto ok;
11574 case 0x1a: s390_format_RR_RR(s390_irgen_AR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
11575 goto ok;
11576 case 0x1b: s390_format_RR_RR(s390_irgen_SR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
11577 goto ok;
11578 case 0x1c: s390_format_RR_RR(s390_irgen_MR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
11579 goto ok;
11580 case 0x1d: s390_format_RR_RR(s390_irgen_DR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
11581 goto ok;
11582 case 0x1e: s390_format_RR_RR(s390_irgen_ALR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
11583 goto ok;
11584 case 0x1f: s390_format_RR_RR(s390_irgen_SLR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
11585 goto ok;
11586 case 0x20: /* LPDR */ goto unimplemented;
11587 case 0x21: /* LNDR */ goto unimplemented;
11588 case 0x22: /* LTDR */ goto unimplemented;
11589 case 0x23: /* LCDR */ goto unimplemented;
11590 case 0x24: /* HDR */ goto unimplemented;
11591 case 0x25: /* LDXR */ goto unimplemented;
11592 case 0x26: /* MXR */ goto unimplemented;
11593 case 0x27: /* MXDR */ goto unimplemented;
11594 case 0x28: s390_format_RR_FF(s390_irgen_LDR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
11595 goto ok;
11596 case 0x29: /* CDR */ goto unimplemented;
11597 case 0x2a: /* ADR */ goto unimplemented;
11598 case 0x2b: /* SDR */ goto unimplemented;
11599 case 0x2c: /* MDR */ goto unimplemented;
11600 case 0x2d: /* DDR */ goto unimplemented;
11601 case 0x2e: /* AWR */ goto unimplemented;
11602 case 0x2f: /* SWR */ goto unimplemented;
11603 case 0x30: /* LPER */ goto unimplemented;
11604 case 0x31: /* LNER */ goto unimplemented;
11605 case 0x32: /* LTER */ goto unimplemented;
11606 case 0x33: /* LCER */ goto unimplemented;
11607 case 0x34: /* HER */ goto unimplemented;
11608 case 0x35: /* LEDR */ goto unimplemented;
11609 case 0x36: /* AXR */ goto unimplemented;
11610 case 0x37: /* SXR */ goto unimplemented;
11611 case 0x38: s390_format_RR_FF(s390_irgen_LER, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
11612 goto ok;
11613 case 0x39: /* CER */ goto unimplemented;
11614 case 0x3a: /* AER */ goto unimplemented;
11615 case 0x3b: /* SER */ goto unimplemented;
11616 case 0x3c: /* MDER */ goto unimplemented;
11617 case 0x3d: /* DER */ goto unimplemented;
11618 case 0x3e: /* AUR */ goto unimplemented;
11619 case 0x3f: /* SUR */ goto unimplemented;
11620 }
11621
11622 return S390_DECODE_UNKNOWN_INSN;
11623
11624ok:
11625 return S390_DECODE_OK;
11626
11627unimplemented:
11628 return S390_DECODE_UNIMPLEMENTED_INSN;
11629}
11630
11631static s390_decode_t
11632s390_decode_4byte_and_irgen(UChar *bytes)
11633{
11634 typedef union {
11635 struct {
11636 unsigned int op1 : 8;
11637 unsigned int r1 : 4;
11638 unsigned int op2 : 4;
11639 unsigned int i2 : 16;
11640 } RI;
11641 struct {
11642 unsigned int op : 16;
11643 unsigned int : 8;
11644 unsigned int r1 : 4;
11645 unsigned int r2 : 4;
11646 } RRE;
11647 struct {
11648 unsigned int op : 16;
11649 unsigned int r1 : 4;
11650 unsigned int : 4;
11651 unsigned int r3 : 4;
11652 unsigned int r2 : 4;
11653 } RRF;
11654 struct {
11655 unsigned int op : 16;
11656 unsigned int r3 : 4;
11657 unsigned int m4 : 4;
11658 unsigned int r1 : 4;
11659 unsigned int r2 : 4;
11660 } RRF2;
11661 struct {
11662 unsigned int op : 16;
11663 unsigned int r3 : 4;
11664 unsigned int : 4;
11665 unsigned int r1 : 4;
11666 unsigned int r2 : 4;
11667 } RRF3;
11668 struct {
11669 unsigned int op : 16;
11670 unsigned int r3 : 4;
11671 unsigned int : 4;
11672 unsigned int r1 : 4;
11673 unsigned int r2 : 4;
11674 } RRR;
11675 struct {
11676 unsigned int op : 16;
11677 unsigned int r3 : 4;
11678 unsigned int : 4;
11679 unsigned int r1 : 4;
11680 unsigned int r2 : 4;
11681 } RRF4;
11682 struct {
11683 unsigned int op : 8;
11684 unsigned int r1 : 4;
11685 unsigned int r3 : 4;
11686 unsigned int b2 : 4;
11687 unsigned int d2 : 12;
11688 } RS;
11689 struct {
11690 unsigned int op : 8;
11691 unsigned int r1 : 4;
11692 unsigned int r3 : 4;
11693 unsigned int i2 : 16;
11694 } RSI;
11695 struct {
11696 unsigned int op : 8;
11697 unsigned int r1 : 4;
11698 unsigned int x2 : 4;
11699 unsigned int b2 : 4;
11700 unsigned int d2 : 12;
11701 } RX;
11702 struct {
11703 unsigned int op : 16;
11704 unsigned int b2 : 4;
11705 unsigned int d2 : 12;
11706 } S;
11707 struct {
11708 unsigned int op : 8;
11709 unsigned int i2 : 8;
11710 unsigned int b1 : 4;
11711 unsigned int d1 : 12;
11712 } SI;
11713 } formats;
11714 union {
11715 formats fmt;
11716 UInt value;
11717 } ovl;
11718
11719 vassert(sizeof(formats) == 4);
11720
11721 ((char *)(&ovl.value))[0] = bytes[0];
11722 ((char *)(&ovl.value))[1] = bytes[1];
11723 ((char *)(&ovl.value))[2] = bytes[2];
11724 ((char *)(&ovl.value))[3] = bytes[3];
11725
11726 switch ((ovl.value & 0xff0f0000) >> 16) {
11727 case 0xa500: s390_format_RI_RU(s390_irgen_IIHH, ovl.fmt.RI.r1,
11728 ovl.fmt.RI.i2); goto ok;
11729 case 0xa501: s390_format_RI_RU(s390_irgen_IIHL, ovl.fmt.RI.r1,
11730 ovl.fmt.RI.i2); goto ok;
11731 case 0xa502: s390_format_RI_RU(s390_irgen_IILH, ovl.fmt.RI.r1,
11732 ovl.fmt.RI.i2); goto ok;
11733 case 0xa503: s390_format_RI_RU(s390_irgen_IILL, ovl.fmt.RI.r1,
11734 ovl.fmt.RI.i2); goto ok;
11735 case 0xa504: s390_format_RI_RU(s390_irgen_NIHH, ovl.fmt.RI.r1,
11736 ovl.fmt.RI.i2); goto ok;
11737 case 0xa505: s390_format_RI_RU(s390_irgen_NIHL, ovl.fmt.RI.r1,
11738 ovl.fmt.RI.i2); goto ok;
11739 case 0xa506: s390_format_RI_RU(s390_irgen_NILH, ovl.fmt.RI.r1,
11740 ovl.fmt.RI.i2); goto ok;
11741 case 0xa507: s390_format_RI_RU(s390_irgen_NILL, ovl.fmt.RI.r1,
11742 ovl.fmt.RI.i2); goto ok;
11743 case 0xa508: s390_format_RI_RU(s390_irgen_OIHH, ovl.fmt.RI.r1,
11744 ovl.fmt.RI.i2); goto ok;
11745 case 0xa509: s390_format_RI_RU(s390_irgen_OIHL, ovl.fmt.RI.r1,
11746 ovl.fmt.RI.i2); goto ok;
11747 case 0xa50a: s390_format_RI_RU(s390_irgen_OILH, ovl.fmt.RI.r1,
11748 ovl.fmt.RI.i2); goto ok;
11749 case 0xa50b: s390_format_RI_RU(s390_irgen_OILL, ovl.fmt.RI.r1,
11750 ovl.fmt.RI.i2); goto ok;
11751 case 0xa50c: s390_format_RI_RU(s390_irgen_LLIHH, ovl.fmt.RI.r1,
11752 ovl.fmt.RI.i2); goto ok;
11753 case 0xa50d: s390_format_RI_RU(s390_irgen_LLIHL, ovl.fmt.RI.r1,
11754 ovl.fmt.RI.i2); goto ok;
11755 case 0xa50e: s390_format_RI_RU(s390_irgen_LLILH, ovl.fmt.RI.r1,
11756 ovl.fmt.RI.i2); goto ok;
11757 case 0xa50f: s390_format_RI_RU(s390_irgen_LLILL, ovl.fmt.RI.r1,
11758 ovl.fmt.RI.i2); goto ok;
11759 case 0xa700: s390_format_RI_RU(s390_irgen_TMLH, ovl.fmt.RI.r1,
11760 ovl.fmt.RI.i2); goto ok;
11761 case 0xa701: s390_format_RI_RU(s390_irgen_TMLL, ovl.fmt.RI.r1,
11762 ovl.fmt.RI.i2); goto ok;
11763 case 0xa702: s390_format_RI_RU(s390_irgen_TMHH, ovl.fmt.RI.r1,
11764 ovl.fmt.RI.i2); goto ok;
11765 case 0xa703: s390_format_RI_RU(s390_irgen_TMHL, ovl.fmt.RI.r1,
11766 ovl.fmt.RI.i2); goto ok;
11767 case 0xa704: s390_format_RI(s390_irgen_BRC, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
11768 goto ok;
11769 case 0xa705: s390_format_RI_RP(s390_irgen_BRAS, ovl.fmt.RI.r1,
11770 ovl.fmt.RI.i2); goto ok;
11771 case 0xa706: s390_format_RI_RP(s390_irgen_BRCT, ovl.fmt.RI.r1,
11772 ovl.fmt.RI.i2); goto ok;
11773 case 0xa707: s390_format_RI_RP(s390_irgen_BRCTG, ovl.fmt.RI.r1,
11774 ovl.fmt.RI.i2); goto ok;
11775 case 0xa708: s390_format_RI_RI(s390_irgen_LHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
11776 goto ok;
11777 case 0xa709: s390_format_RI_RI(s390_irgen_LGHI, ovl.fmt.RI.r1,
11778 ovl.fmt.RI.i2); goto ok;
11779 case 0xa70a: s390_format_RI_RI(s390_irgen_AHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
11780 goto ok;
11781 case 0xa70b: s390_format_RI_RI(s390_irgen_AGHI, ovl.fmt.RI.r1,
11782 ovl.fmt.RI.i2); goto ok;
11783 case 0xa70c: s390_format_RI_RI(s390_irgen_MHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
11784 goto ok;
11785 case 0xa70d: s390_format_RI_RI(s390_irgen_MGHI, ovl.fmt.RI.r1,
11786 ovl.fmt.RI.i2); goto ok;
11787 case 0xa70e: s390_format_RI_RI(s390_irgen_CHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
11788 goto ok;
11789 case 0xa70f: s390_format_RI_RI(s390_irgen_CGHI, ovl.fmt.RI.r1,
11790 ovl.fmt.RI.i2); goto ok;
11791 }
11792
11793 switch ((ovl.value & 0xffff0000) >> 16) {
11794 case 0x8000: /* SSM */ goto unimplemented;
11795 case 0x8200: /* LPSW */ goto unimplemented;
florian7700fc92012-01-16 17:25:55 +000011796 case 0x9300: /* TS */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000011797 case 0xb202: /* STIDP */ goto unimplemented;
11798 case 0xb204: /* SCK */ goto unimplemented;
florian7700fc92012-01-16 17:25:55 +000011799 case 0xb205: s390_format_S_RD(s390_irgen_STCK, ovl.fmt.S.b2, ovl.fmt.S.d2);
11800 goto ok;
sewardj2019a972011-03-07 16:04:07 +000011801 case 0xb206: /* SCKC */ goto unimplemented;
11802 case 0xb207: /* STCKC */ goto unimplemented;
11803 case 0xb208: /* SPT */ goto unimplemented;
11804 case 0xb209: /* STPT */ goto unimplemented;
11805 case 0xb20a: /* SPKA */ goto unimplemented;
11806 case 0xb20b: /* IPK */ goto unimplemented;
11807 case 0xb20d: /* PTLB */ goto unimplemented;
11808 case 0xb210: /* SPX */ goto unimplemented;
11809 case 0xb211: /* STPX */ goto unimplemented;
11810 case 0xb212: /* STAP */ goto unimplemented;
11811 case 0xb214: /* SIE */ goto unimplemented;
11812 case 0xb218: /* PC */ goto unimplemented;
11813 case 0xb219: /* SAC */ goto unimplemented;
11814 case 0xb21a: /* CFC */ goto unimplemented;
11815 case 0xb221: /* IPTE */ goto unimplemented;
11816 case 0xb222: s390_format_RRE_R0(s390_irgen_IPM, ovl.fmt.RRE.r1); goto ok;
11817 case 0xb223: /* IVSK */ goto unimplemented;
11818 case 0xb224: /* IAC */ goto unimplemented;
11819 case 0xb225: /* SSAR */ goto unimplemented;
11820 case 0xb226: /* EPAR */ goto unimplemented;
11821 case 0xb227: /* ESAR */ goto unimplemented;
11822 case 0xb228: /* PT */ goto unimplemented;
11823 case 0xb229: /* ISKE */ goto unimplemented;
11824 case 0xb22a: /* RRBE */ goto unimplemented;
11825 case 0xb22b: /* SSKE */ goto unimplemented;
11826 case 0xb22c: /* TB */ goto unimplemented;
11827 case 0xb22d: /* DXR */ goto unimplemented;
11828 case 0xb22e: /* PGIN */ goto unimplemented;
11829 case 0xb22f: /* PGOUT */ goto unimplemented;
11830 case 0xb230: /* CSCH */ goto unimplemented;
11831 case 0xb231: /* HSCH */ goto unimplemented;
11832 case 0xb232: /* MSCH */ goto unimplemented;
11833 case 0xb233: /* SSCH */ goto unimplemented;
11834 case 0xb234: /* STSCH */ goto unimplemented;
11835 case 0xb235: /* TSCH */ goto unimplemented;
11836 case 0xb236: /* TPI */ goto unimplemented;
11837 case 0xb237: /* SAL */ goto unimplemented;
11838 case 0xb238: /* RSCH */ goto unimplemented;
11839 case 0xb239: /* STCRW */ goto unimplemented;
11840 case 0xb23a: /* STCPS */ goto unimplemented;
11841 case 0xb23b: /* RCHP */ goto unimplemented;
11842 case 0xb23c: /* SCHM */ goto unimplemented;
11843 case 0xb240: /* BAKR */ goto unimplemented;
floriana4384a32011-08-11 16:58:45 +000011844 case 0xb241: s390_format_RRE(s390_irgen_CKSM, ovl.fmt.RRE.r1,
11845 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000011846 case 0xb244: /* SQDR */ goto unimplemented;
11847 case 0xb245: /* SQER */ goto unimplemented;
11848 case 0xb246: /* STURA */ goto unimplemented;
11849 case 0xb247: /* MSTA */ goto unimplemented;
11850 case 0xb248: /* PALB */ goto unimplemented;
11851 case 0xb249: /* EREG */ goto unimplemented;
11852 case 0xb24a: /* ESTA */ goto unimplemented;
11853 case 0xb24b: /* LURA */ goto unimplemented;
11854 case 0xb24c: /* TAR */ goto unimplemented;
11855 case 0xb24d: s390_format_RRE(s390_irgen_CPYA, ovl.fmt.RRE.r1,
11856 ovl.fmt.RRE.r2); goto ok;
11857 case 0xb24e: s390_format_RRE(s390_irgen_SAR, ovl.fmt.RRE.r1, ovl.fmt.RRE.r2);
11858 goto ok;
11859 case 0xb24f: s390_format_RRE(s390_irgen_EAR, ovl.fmt.RRE.r1, ovl.fmt.RRE.r2);
11860 goto ok;
11861 case 0xb250: /* CSP */ goto unimplemented;
11862 case 0xb252: s390_format_RRE_RR(s390_irgen_MSR, ovl.fmt.RRE.r1,
11863 ovl.fmt.RRE.r2); goto ok;
11864 case 0xb254: /* MVPG */ goto unimplemented;
11865 case 0xb255: s390_format_RRE_RR(s390_irgen_MVST, ovl.fmt.RRE.r1,
11866 ovl.fmt.RRE.r2); goto ok;
11867 case 0xb257: /* CUSE */ goto unimplemented;
11868 case 0xb258: /* BSG */ goto unimplemented;
11869 case 0xb25a: /* BSA */ goto unimplemented;
11870 case 0xb25d: s390_format_RRE_RR(s390_irgen_CLST, ovl.fmt.RRE.r1,
11871 ovl.fmt.RRE.r2); goto ok;
11872 case 0xb25e: s390_format_RRE_RR(s390_irgen_SRST, ovl.fmt.RRE.r1,
11873 ovl.fmt.RRE.r2); goto ok;
11874 case 0xb263: /* CMPSC */ goto unimplemented;
11875 case 0xb274: /* SIGA */ goto unimplemented;
11876 case 0xb276: /* XSCH */ goto unimplemented;
11877 case 0xb277: /* RP */ goto unimplemented;
sewardj1e5fea62011-05-17 16:18:36 +000011878 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 +000011879 case 0xb279: /* SACF */ goto unimplemented;
sewardj1e5fea62011-05-17 16:18:36 +000011880 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 +000011881 case 0xb27d: /* STSI */ goto unimplemented;
11882 case 0xb299: s390_format_S_RD(s390_irgen_SRNM, ovl.fmt.S.b2, ovl.fmt.S.d2);
11883 goto ok;
11884 case 0xb29c: s390_format_S_RD(s390_irgen_STFPC, ovl.fmt.S.b2, ovl.fmt.S.d2);
11885 goto ok;
11886 case 0xb29d: s390_format_S_RD(s390_irgen_LFPC, ovl.fmt.S.b2, ovl.fmt.S.d2);
11887 goto ok;
florian730448f2012-02-04 17:07:07 +000011888 case 0xb2a5: s390_format_RRE_FF(s390_irgen_TRE, ovl.fmt.RRE.r1, ovl.fmt.RRE.r2); goto ok;
floriana0100c92012-07-20 00:06:35 +000011889 case 0xb2a6: s390_format_RRF_M0RERE(s390_irgen_CU21, ovl.fmt.RRF3.r3,
11890 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
11891 goto ok;
sewardj2019a972011-03-07 16:04:07 +000011892 case 0xb2a7: /* CU12 */ goto unimplemented;
florian933065d2011-07-11 01:48:02 +000011893 case 0xb2b0: s390_format_S_RD(s390_irgen_STFLE, ovl.fmt.S.b2, ovl.fmt.S.d2);
11894 goto ok;
sewardj2019a972011-03-07 16:04:07 +000011895 case 0xb2b1: /* STFL */ goto unimplemented;
11896 case 0xb2b2: /* LPSWE */ goto unimplemented;
11897 case 0xb2b8: /* SRNMB */ goto unimplemented;
11898 case 0xb2b9: /* SRNMT */ goto unimplemented;
11899 case 0xb2bd: /* LFAS */ goto unimplemented;
11900 case 0xb2ff: /* TRAP4 */ goto unimplemented;
11901 case 0xb300: s390_format_RRE_FF(s390_irgen_LPEBR, ovl.fmt.RRE.r1,
11902 ovl.fmt.RRE.r2); goto ok;
11903 case 0xb301: s390_format_RRE_FF(s390_irgen_LNEBR, ovl.fmt.RRE.r1,
11904 ovl.fmt.RRE.r2); goto ok;
11905 case 0xb302: s390_format_RRE_FF(s390_irgen_LTEBR, ovl.fmt.RRE.r1,
11906 ovl.fmt.RRE.r2); goto ok;
11907 case 0xb303: s390_format_RRE_FF(s390_irgen_LCEBR, ovl.fmt.RRE.r1,
11908 ovl.fmt.RRE.r2); goto ok;
11909 case 0xb304: s390_format_RRE_FF(s390_irgen_LDEBR, ovl.fmt.RRE.r1,
11910 ovl.fmt.RRE.r2); goto ok;
11911 case 0xb305: s390_format_RRE_FF(s390_irgen_LXDBR, ovl.fmt.RRE.r1,
11912 ovl.fmt.RRE.r2); goto ok;
11913 case 0xb306: s390_format_RRE_FF(s390_irgen_LXEBR, ovl.fmt.RRE.r1,
11914 ovl.fmt.RRE.r2); goto ok;
11915 case 0xb307: /* MXDBR */ goto unimplemented;
11916 case 0xb308: /* KEBR */ goto unimplemented;
11917 case 0xb309: s390_format_RRE_FF(s390_irgen_CEBR, ovl.fmt.RRE.r1,
11918 ovl.fmt.RRE.r2); goto ok;
11919 case 0xb30a: s390_format_RRE_FF(s390_irgen_AEBR, ovl.fmt.RRE.r1,
11920 ovl.fmt.RRE.r2); goto ok;
11921 case 0xb30b: s390_format_RRE_FF(s390_irgen_SEBR, ovl.fmt.RRE.r1,
11922 ovl.fmt.RRE.r2); goto ok;
11923 case 0xb30c: /* MDEBR */ goto unimplemented;
11924 case 0xb30d: s390_format_RRE_FF(s390_irgen_DEBR, ovl.fmt.RRE.r1,
11925 ovl.fmt.RRE.r2); goto ok;
11926 case 0xb30e: s390_format_RRF_F0FF(s390_irgen_MAEBR, ovl.fmt.RRF.r1,
11927 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
11928 case 0xb30f: s390_format_RRF_F0FF(s390_irgen_MSEBR, ovl.fmt.RRF.r1,
11929 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
11930 case 0xb310: s390_format_RRE_FF(s390_irgen_LPDBR, ovl.fmt.RRE.r1,
11931 ovl.fmt.RRE.r2); goto ok;
11932 case 0xb311: s390_format_RRE_FF(s390_irgen_LNDBR, ovl.fmt.RRE.r1,
11933 ovl.fmt.RRE.r2); goto ok;
11934 case 0xb312: s390_format_RRE_FF(s390_irgen_LTDBR, ovl.fmt.RRE.r1,
11935 ovl.fmt.RRE.r2); goto ok;
11936 case 0xb313: s390_format_RRE_FF(s390_irgen_LCDBR, ovl.fmt.RRE.r1,
11937 ovl.fmt.RRE.r2); goto ok;
11938 case 0xb314: s390_format_RRE_FF(s390_irgen_SQEBR, ovl.fmt.RRE.r1,
11939 ovl.fmt.RRE.r2); goto ok;
11940 case 0xb315: s390_format_RRE_FF(s390_irgen_SQDBR, ovl.fmt.RRE.r1,
11941 ovl.fmt.RRE.r2); goto ok;
11942 case 0xb316: s390_format_RRE_FF(s390_irgen_SQXBR, ovl.fmt.RRE.r1,
11943 ovl.fmt.RRE.r2); goto ok;
11944 case 0xb317: s390_format_RRE_FF(s390_irgen_MEEBR, ovl.fmt.RRE.r1,
11945 ovl.fmt.RRE.r2); goto ok;
11946 case 0xb318: /* KDBR */ goto unimplemented;
11947 case 0xb319: s390_format_RRE_FF(s390_irgen_CDBR, ovl.fmt.RRE.r1,
11948 ovl.fmt.RRE.r2); goto ok;
11949 case 0xb31a: s390_format_RRE_FF(s390_irgen_ADBR, ovl.fmt.RRE.r1,
11950 ovl.fmt.RRE.r2); goto ok;
11951 case 0xb31b: s390_format_RRE_FF(s390_irgen_SDBR, ovl.fmt.RRE.r1,
11952 ovl.fmt.RRE.r2); goto ok;
11953 case 0xb31c: s390_format_RRE_FF(s390_irgen_MDBR, ovl.fmt.RRE.r1,
11954 ovl.fmt.RRE.r2); goto ok;
11955 case 0xb31d: s390_format_RRE_FF(s390_irgen_DDBR, ovl.fmt.RRE.r1,
11956 ovl.fmt.RRE.r2); goto ok;
11957 case 0xb31e: s390_format_RRF_F0FF(s390_irgen_MADBR, ovl.fmt.RRF.r1,
11958 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
11959 case 0xb31f: s390_format_RRF_F0FF(s390_irgen_MSDBR, ovl.fmt.RRF.r1,
11960 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
11961 case 0xb324: /* LDER */ goto unimplemented;
11962 case 0xb325: /* LXDR */ goto unimplemented;
11963 case 0xb326: /* LXER */ goto unimplemented;
11964 case 0xb32e: /* MAER */ goto unimplemented;
11965 case 0xb32f: /* MSER */ goto unimplemented;
11966 case 0xb336: /* SQXR */ goto unimplemented;
11967 case 0xb337: /* MEER */ goto unimplemented;
11968 case 0xb338: /* MAYLR */ goto unimplemented;
11969 case 0xb339: /* MYLR */ goto unimplemented;
11970 case 0xb33a: /* MAYR */ goto unimplemented;
11971 case 0xb33b: /* MYR */ goto unimplemented;
11972 case 0xb33c: /* MAYHR */ goto unimplemented;
11973 case 0xb33d: /* MYHR */ goto unimplemented;
11974 case 0xb33e: /* MADR */ goto unimplemented;
11975 case 0xb33f: /* MSDR */ goto unimplemented;
11976 case 0xb340: s390_format_RRE_FF(s390_irgen_LPXBR, ovl.fmt.RRE.r1,
11977 ovl.fmt.RRE.r2); goto ok;
11978 case 0xb341: s390_format_RRE_FF(s390_irgen_LNXBR, ovl.fmt.RRE.r1,
11979 ovl.fmt.RRE.r2); goto ok;
11980 case 0xb342: s390_format_RRE_FF(s390_irgen_LTXBR, ovl.fmt.RRE.r1,
11981 ovl.fmt.RRE.r2); goto ok;
11982 case 0xb343: s390_format_RRE_FF(s390_irgen_LCXBR, ovl.fmt.RRE.r1,
11983 ovl.fmt.RRE.r2); goto ok;
11984 case 0xb344: s390_format_RRE_FF(s390_irgen_LEDBR, ovl.fmt.RRE.r1,
11985 ovl.fmt.RRE.r2); goto ok;
11986 case 0xb345: s390_format_RRE_FF(s390_irgen_LDXBR, ovl.fmt.RRE.r1,
11987 ovl.fmt.RRE.r2); goto ok;
11988 case 0xb346: s390_format_RRE_FF(s390_irgen_LEXBR, ovl.fmt.RRE.r1,
11989 ovl.fmt.RRE.r2); goto ok;
11990 case 0xb347: /* FIXBR */ goto unimplemented;
11991 case 0xb348: /* KXBR */ goto unimplemented;
11992 case 0xb349: s390_format_RRE_FF(s390_irgen_CXBR, ovl.fmt.RRE.r1,
11993 ovl.fmt.RRE.r2); goto ok;
11994 case 0xb34a: s390_format_RRE_FF(s390_irgen_AXBR, ovl.fmt.RRE.r1,
11995 ovl.fmt.RRE.r2); goto ok;
11996 case 0xb34b: s390_format_RRE_FF(s390_irgen_SXBR, ovl.fmt.RRE.r1,
11997 ovl.fmt.RRE.r2); goto ok;
11998 case 0xb34c: s390_format_RRE_FF(s390_irgen_MXBR, ovl.fmt.RRE.r1,
11999 ovl.fmt.RRE.r2); goto ok;
12000 case 0xb34d: s390_format_RRE_FF(s390_irgen_DXBR, ovl.fmt.RRE.r1,
12001 ovl.fmt.RRE.r2); goto ok;
12002 case 0xb350: /* TBEDR */ goto unimplemented;
12003 case 0xb351: /* TBDR */ goto unimplemented;
12004 case 0xb353: /* DIEBR */ goto unimplemented;
12005 case 0xb357: /* FIEBR */ goto unimplemented;
12006 case 0xb358: /* THDER */ goto unimplemented;
12007 case 0xb359: /* THDR */ goto unimplemented;
12008 case 0xb35b: /* DIDBR */ goto unimplemented;
12009 case 0xb35f: /* FIDBR */ goto unimplemented;
12010 case 0xb360: /* LPXR */ goto unimplemented;
12011 case 0xb361: /* LNXR */ goto unimplemented;
12012 case 0xb362: /* LTXR */ goto unimplemented;
12013 case 0xb363: /* LCXR */ goto unimplemented;
12014 case 0xb365: s390_format_RRE_FF(s390_irgen_LXR, ovl.fmt.RRE.r1,
12015 ovl.fmt.RRE.r2); goto ok;
12016 case 0xb366: /* LEXR */ goto unimplemented;
12017 case 0xb367: /* FIXR */ goto unimplemented;
12018 case 0xb369: /* CXR */ goto unimplemented;
12019 case 0xb370: s390_format_RRE_FF(s390_irgen_LPDFR, ovl.fmt.RRE.r1,
12020 ovl.fmt.RRE.r2); goto ok;
12021 case 0xb371: s390_format_RRE_FF(s390_irgen_LNDFR, ovl.fmt.RRE.r1,
12022 ovl.fmt.RRE.r2); goto ok;
12023 case 0xb372: s390_format_RRF_F0FF2(s390_irgen_CPSDR, ovl.fmt.RRF3.r3,
12024 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
12025 goto ok;
12026 case 0xb373: s390_format_RRE_FF(s390_irgen_LCDFR, ovl.fmt.RRE.r1,
12027 ovl.fmt.RRE.r2); goto ok;
12028 case 0xb374: s390_format_RRE_F0(s390_irgen_LZER, ovl.fmt.RRE.r1); goto ok;
12029 case 0xb375: s390_format_RRE_F0(s390_irgen_LZDR, ovl.fmt.RRE.r1); goto ok;
12030 case 0xb376: s390_format_RRE_F0(s390_irgen_LZXR, ovl.fmt.RRE.r1); goto ok;
12031 case 0xb377: /* FIER */ goto unimplemented;
12032 case 0xb37f: /* FIDR */ goto unimplemented;
12033 case 0xb384: s390_format_RRE_R0(s390_irgen_SFPC, ovl.fmt.RRE.r1); goto ok;
12034 case 0xb385: /* SFASR */ goto unimplemented;
12035 case 0xb38c: s390_format_RRE_R0(s390_irgen_EFPC, ovl.fmt.RRE.r1); goto ok;
12036 case 0xb390: /* CELFBR */ goto unimplemented;
12037 case 0xb391: /* CDLFBR */ goto unimplemented;
12038 case 0xb392: /* CXLFBR */ goto unimplemented;
12039 case 0xb394: s390_format_RRE_FR(s390_irgen_CEFBR, ovl.fmt.RRE.r1,
12040 ovl.fmt.RRE.r2); goto ok;
12041 case 0xb395: s390_format_RRE_FR(s390_irgen_CDFBR, ovl.fmt.RRE.r1,
12042 ovl.fmt.RRE.r2); goto ok;
12043 case 0xb396: s390_format_RRE_FR(s390_irgen_CXFBR, ovl.fmt.RRE.r1,
12044 ovl.fmt.RRE.r2); goto ok;
12045 case 0xb398: s390_format_RRF_U0RF(s390_irgen_CFEBR, ovl.fmt.RRF3.r3,
12046 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
12047 goto ok;
12048 case 0xb399: s390_format_RRF_U0RF(s390_irgen_CFDBR, ovl.fmt.RRF3.r3,
12049 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
12050 goto ok;
12051 case 0xb39a: s390_format_RRF_U0RF(s390_irgen_CFXBR, ovl.fmt.RRF3.r3,
12052 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
12053 goto ok;
12054 case 0xb3a0: /* CELGBR */ goto unimplemented;
12055 case 0xb3a1: /* CDLGBR */ goto unimplemented;
12056 case 0xb3a2: /* CXLGBR */ goto unimplemented;
12057 case 0xb3a4: s390_format_RRE_FR(s390_irgen_CEGBR, ovl.fmt.RRE.r1,
12058 ovl.fmt.RRE.r2); goto ok;
12059 case 0xb3a5: s390_format_RRE_FR(s390_irgen_CDGBR, ovl.fmt.RRE.r1,
12060 ovl.fmt.RRE.r2); goto ok;
12061 case 0xb3a6: s390_format_RRE_FR(s390_irgen_CXGBR, ovl.fmt.RRE.r1,
12062 ovl.fmt.RRE.r2); goto ok;
12063 case 0xb3a8: s390_format_RRF_U0RF(s390_irgen_CGEBR, ovl.fmt.RRF3.r3,
12064 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
12065 goto ok;
12066 case 0xb3a9: s390_format_RRF_U0RF(s390_irgen_CGDBR, ovl.fmt.RRF3.r3,
12067 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
12068 goto ok;
12069 case 0xb3aa: s390_format_RRF_U0RF(s390_irgen_CGXBR, ovl.fmt.RRF3.r3,
12070 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
12071 goto ok;
12072 case 0xb3b4: /* CEFR */ goto unimplemented;
12073 case 0xb3b5: /* CDFR */ goto unimplemented;
12074 case 0xb3b6: /* CXFR */ goto unimplemented;
12075 case 0xb3b8: /* CFER */ goto unimplemented;
12076 case 0xb3b9: /* CFDR */ goto unimplemented;
12077 case 0xb3ba: /* CFXR */ goto unimplemented;
12078 case 0xb3c1: s390_format_RRE_FR(s390_irgen_LDGR, ovl.fmt.RRE.r1,
12079 ovl.fmt.RRE.r2); goto ok;
12080 case 0xb3c4: /* CEGR */ goto unimplemented;
12081 case 0xb3c5: /* CDGR */ goto unimplemented;
12082 case 0xb3c6: /* CXGR */ goto unimplemented;
12083 case 0xb3c8: /* CGER */ goto unimplemented;
12084 case 0xb3c9: /* CGDR */ goto unimplemented;
12085 case 0xb3ca: /* CGXR */ goto unimplemented;
12086 case 0xb3cd: s390_format_RRE_RF(s390_irgen_LGDR, ovl.fmt.RRE.r1,
12087 ovl.fmt.RRE.r2); goto ok;
12088 case 0xb3d0: /* MDTR */ goto unimplemented;
12089 case 0xb3d1: /* DDTR */ goto unimplemented;
12090 case 0xb3d2: /* ADTR */ goto unimplemented;
12091 case 0xb3d3: /* SDTR */ goto unimplemented;
12092 case 0xb3d4: /* LDETR */ goto unimplemented;
12093 case 0xb3d5: /* LEDTR */ goto unimplemented;
12094 case 0xb3d6: /* LTDTR */ goto unimplemented;
12095 case 0xb3d7: /* FIDTR */ goto unimplemented;
12096 case 0xb3d8: /* MXTR */ goto unimplemented;
12097 case 0xb3d9: /* DXTR */ goto unimplemented;
12098 case 0xb3da: /* AXTR */ goto unimplemented;
12099 case 0xb3db: /* SXTR */ goto unimplemented;
12100 case 0xb3dc: /* LXDTR */ goto unimplemented;
12101 case 0xb3dd: /* LDXTR */ goto unimplemented;
12102 case 0xb3de: /* LTXTR */ goto unimplemented;
12103 case 0xb3df: /* FIXTR */ goto unimplemented;
12104 case 0xb3e0: /* KDTR */ goto unimplemented;
12105 case 0xb3e1: /* CGDTR */ goto unimplemented;
12106 case 0xb3e2: /* CUDTR */ goto unimplemented;
12107 case 0xb3e3: /* CSDTR */ goto unimplemented;
12108 case 0xb3e4: /* CDTR */ goto unimplemented;
12109 case 0xb3e5: /* EEDTR */ goto unimplemented;
12110 case 0xb3e7: /* ESDTR */ goto unimplemented;
12111 case 0xb3e8: /* KXTR */ goto unimplemented;
12112 case 0xb3e9: /* CGXTR */ goto unimplemented;
12113 case 0xb3ea: /* CUXTR */ goto unimplemented;
12114 case 0xb3eb: /* CSXTR */ goto unimplemented;
12115 case 0xb3ec: /* CXTR */ goto unimplemented;
12116 case 0xb3ed: /* EEXTR */ goto unimplemented;
12117 case 0xb3ef: /* ESXTR */ goto unimplemented;
12118 case 0xb3f1: /* CDGTR */ goto unimplemented;
12119 case 0xb3f2: /* CDUTR */ goto unimplemented;
12120 case 0xb3f3: /* CDSTR */ goto unimplemented;
12121 case 0xb3f4: /* CEDTR */ goto unimplemented;
12122 case 0xb3f5: /* QADTR */ goto unimplemented;
12123 case 0xb3f6: /* IEDTR */ goto unimplemented;
12124 case 0xb3f7: /* RRDTR */ goto unimplemented;
12125 case 0xb3f9: /* CXGTR */ goto unimplemented;
12126 case 0xb3fa: /* CXUTR */ goto unimplemented;
12127 case 0xb3fb: /* CXSTR */ goto unimplemented;
12128 case 0xb3fc: /* CEXTR */ goto unimplemented;
12129 case 0xb3fd: /* QAXTR */ goto unimplemented;
12130 case 0xb3fe: /* IEXTR */ goto unimplemented;
12131 case 0xb3ff: /* RRXTR */ goto unimplemented;
12132 case 0xb900: s390_format_RRE_RR(s390_irgen_LPGR, ovl.fmt.RRE.r1,
12133 ovl.fmt.RRE.r2); goto ok;
12134 case 0xb901: s390_format_RRE_RR(s390_irgen_LNGR, ovl.fmt.RRE.r1,
12135 ovl.fmt.RRE.r2); goto ok;
12136 case 0xb902: s390_format_RRE_RR(s390_irgen_LTGR, ovl.fmt.RRE.r1,
12137 ovl.fmt.RRE.r2); goto ok;
12138 case 0xb903: s390_format_RRE_RR(s390_irgen_LCGR, ovl.fmt.RRE.r1,
12139 ovl.fmt.RRE.r2); goto ok;
12140 case 0xb904: s390_format_RRE_RR(s390_irgen_LGR, ovl.fmt.RRE.r1,
12141 ovl.fmt.RRE.r2); goto ok;
12142 case 0xb905: /* LURAG */ goto unimplemented;
12143 case 0xb906: s390_format_RRE_RR(s390_irgen_LGBR, ovl.fmt.RRE.r1,
12144 ovl.fmt.RRE.r2); goto ok;
12145 case 0xb907: s390_format_RRE_RR(s390_irgen_LGHR, ovl.fmt.RRE.r1,
12146 ovl.fmt.RRE.r2); goto ok;
12147 case 0xb908: s390_format_RRE_RR(s390_irgen_AGR, ovl.fmt.RRE.r1,
12148 ovl.fmt.RRE.r2); goto ok;
12149 case 0xb909: s390_format_RRE_RR(s390_irgen_SGR, ovl.fmt.RRE.r1,
12150 ovl.fmt.RRE.r2); goto ok;
12151 case 0xb90a: s390_format_RRE_RR(s390_irgen_ALGR, ovl.fmt.RRE.r1,
12152 ovl.fmt.RRE.r2); goto ok;
12153 case 0xb90b: s390_format_RRE_RR(s390_irgen_SLGR, ovl.fmt.RRE.r1,
12154 ovl.fmt.RRE.r2); goto ok;
12155 case 0xb90c: s390_format_RRE_RR(s390_irgen_MSGR, ovl.fmt.RRE.r1,
12156 ovl.fmt.RRE.r2); goto ok;
12157 case 0xb90d: s390_format_RRE_RR(s390_irgen_DSGR, ovl.fmt.RRE.r1,
12158 ovl.fmt.RRE.r2); goto ok;
12159 case 0xb90e: /* EREGG */ goto unimplemented;
12160 case 0xb90f: s390_format_RRE_RR(s390_irgen_LRVGR, ovl.fmt.RRE.r1,
12161 ovl.fmt.RRE.r2); goto ok;
12162 case 0xb910: s390_format_RRE_RR(s390_irgen_LPGFR, ovl.fmt.RRE.r1,
12163 ovl.fmt.RRE.r2); goto ok;
12164 case 0xb911: s390_format_RRE_RR(s390_irgen_LNGFR, ovl.fmt.RRE.r1,
12165 ovl.fmt.RRE.r2); goto ok;
12166 case 0xb912: s390_format_RRE_RR(s390_irgen_LTGFR, ovl.fmt.RRE.r1,
12167 ovl.fmt.RRE.r2); goto ok;
12168 case 0xb913: s390_format_RRE_RR(s390_irgen_LCGFR, ovl.fmt.RRE.r1,
12169 ovl.fmt.RRE.r2); goto ok;
12170 case 0xb914: s390_format_RRE_RR(s390_irgen_LGFR, ovl.fmt.RRE.r1,
12171 ovl.fmt.RRE.r2); goto ok;
12172 case 0xb916: s390_format_RRE_RR(s390_irgen_LLGFR, ovl.fmt.RRE.r1,
12173 ovl.fmt.RRE.r2); goto ok;
12174 case 0xb917: s390_format_RRE_RR(s390_irgen_LLGTR, ovl.fmt.RRE.r1,
12175 ovl.fmt.RRE.r2); goto ok;
12176 case 0xb918: s390_format_RRE_RR(s390_irgen_AGFR, ovl.fmt.RRE.r1,
12177 ovl.fmt.RRE.r2); goto ok;
12178 case 0xb919: s390_format_RRE_RR(s390_irgen_SGFR, ovl.fmt.RRE.r1,
12179 ovl.fmt.RRE.r2); goto ok;
12180 case 0xb91a: s390_format_RRE_RR(s390_irgen_ALGFR, ovl.fmt.RRE.r1,
12181 ovl.fmt.RRE.r2); goto ok;
12182 case 0xb91b: s390_format_RRE_RR(s390_irgen_SLGFR, ovl.fmt.RRE.r1,
12183 ovl.fmt.RRE.r2); goto ok;
12184 case 0xb91c: s390_format_RRE_RR(s390_irgen_MSGFR, ovl.fmt.RRE.r1,
12185 ovl.fmt.RRE.r2); goto ok;
12186 case 0xb91d: s390_format_RRE_RR(s390_irgen_DSGFR, ovl.fmt.RRE.r1,
12187 ovl.fmt.RRE.r2); goto ok;
12188 case 0xb91e: /* KMAC */ goto unimplemented;
12189 case 0xb91f: s390_format_RRE_RR(s390_irgen_LRVR, ovl.fmt.RRE.r1,
12190 ovl.fmt.RRE.r2); goto ok;
12191 case 0xb920: s390_format_RRE_RR(s390_irgen_CGR, ovl.fmt.RRE.r1,
12192 ovl.fmt.RRE.r2); goto ok;
12193 case 0xb921: s390_format_RRE_RR(s390_irgen_CLGR, ovl.fmt.RRE.r1,
12194 ovl.fmt.RRE.r2); goto ok;
12195 case 0xb925: /* STURG */ goto unimplemented;
12196 case 0xb926: s390_format_RRE_RR(s390_irgen_LBR, ovl.fmt.RRE.r1,
12197 ovl.fmt.RRE.r2); goto ok;
12198 case 0xb927: s390_format_RRE_RR(s390_irgen_LHR, ovl.fmt.RRE.r1,
12199 ovl.fmt.RRE.r2); goto ok;
12200 case 0xb928: /* PCKMO */ goto unimplemented;
12201 case 0xb92b: /* KMO */ goto unimplemented;
12202 case 0xb92c: /* PCC */ goto unimplemented;
12203 case 0xb92d: /* KMCTR */ goto unimplemented;
12204 case 0xb92e: /* KM */ goto unimplemented;
12205 case 0xb92f: /* KMC */ goto unimplemented;
12206 case 0xb930: s390_format_RRE_RR(s390_irgen_CGFR, ovl.fmt.RRE.r1,
12207 ovl.fmt.RRE.r2); goto ok;
12208 case 0xb931: s390_format_RRE_RR(s390_irgen_CLGFR, ovl.fmt.RRE.r1,
12209 ovl.fmt.RRE.r2); goto ok;
12210 case 0xb93e: /* KIMD */ goto unimplemented;
12211 case 0xb93f: /* KLMD */ goto unimplemented;
12212 case 0xb941: /* CFDTR */ goto unimplemented;
12213 case 0xb942: /* CLGDTR */ goto unimplemented;
12214 case 0xb943: /* CLFDTR */ goto unimplemented;
12215 case 0xb946: s390_format_RRE_RR(s390_irgen_BCTGR, ovl.fmt.RRE.r1,
12216 ovl.fmt.RRE.r2); goto ok;
12217 case 0xb949: /* CFXTR */ goto unimplemented;
12218 case 0xb94a: /* CLGXTR */ goto unimplemented;
12219 case 0xb94b: /* CLFXTR */ goto unimplemented;
12220 case 0xb951: /* CDFTR */ goto unimplemented;
12221 case 0xb952: /* CDLGTR */ goto unimplemented;
12222 case 0xb953: /* CDLFTR */ goto unimplemented;
12223 case 0xb959: /* CXFTR */ goto unimplemented;
12224 case 0xb95a: /* CXLGTR */ goto unimplemented;
12225 case 0xb95b: /* CXLFTR */ goto unimplemented;
12226 case 0xb960: /* CGRT */ goto unimplemented;
12227 case 0xb961: /* CLGRT */ goto unimplemented;
12228 case 0xb972: /* CRT */ goto unimplemented;
12229 case 0xb973: /* CLRT */ goto unimplemented;
12230 case 0xb980: s390_format_RRE_RR(s390_irgen_NGR, ovl.fmt.RRE.r1,
12231 ovl.fmt.RRE.r2); goto ok;
12232 case 0xb981: s390_format_RRE_RR(s390_irgen_OGR, ovl.fmt.RRE.r1,
12233 ovl.fmt.RRE.r2); goto ok;
12234 case 0xb982: s390_format_RRE_RR(s390_irgen_XGR, ovl.fmt.RRE.r1,
12235 ovl.fmt.RRE.r2); goto ok;
12236 case 0xb983: s390_format_RRE_RR(s390_irgen_FLOGR, ovl.fmt.RRE.r1,
12237 ovl.fmt.RRE.r2); goto ok;
12238 case 0xb984: s390_format_RRE_RR(s390_irgen_LLGCR, ovl.fmt.RRE.r1,
12239 ovl.fmt.RRE.r2); goto ok;
12240 case 0xb985: s390_format_RRE_RR(s390_irgen_LLGHR, ovl.fmt.RRE.r1,
12241 ovl.fmt.RRE.r2); goto ok;
12242 case 0xb986: s390_format_RRE_RR(s390_irgen_MLGR, ovl.fmt.RRE.r1,
12243 ovl.fmt.RRE.r2); goto ok;
12244 case 0xb987: s390_format_RRE_RR(s390_irgen_DLGR, ovl.fmt.RRE.r1,
12245 ovl.fmt.RRE.r2); goto ok;
12246 case 0xb988: s390_format_RRE_RR(s390_irgen_ALCGR, ovl.fmt.RRE.r1,
12247 ovl.fmt.RRE.r2); goto ok;
12248 case 0xb989: s390_format_RRE_RR(s390_irgen_SLBGR, ovl.fmt.RRE.r1,
12249 ovl.fmt.RRE.r2); goto ok;
12250 case 0xb98a: /* CSPG */ goto unimplemented;
12251 case 0xb98d: /* EPSW */ goto unimplemented;
12252 case 0xb98e: /* IDTE */ goto unimplemented;
florian730448f2012-02-04 17:07:07 +000012253 case 0xb990: s390_format_RRF_M0RERE(s390_irgen_TRTT, ovl.fmt.RRF3.r3,
12254 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
12255 case 0xb991: s390_format_RRF_M0RERE(s390_irgen_TRTO, ovl.fmt.RRF3.r3,
12256 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
12257 case 0xb992: s390_format_RRF_M0RERE(s390_irgen_TROT, ovl.fmt.RRF3.r3,
12258 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
florian9af37692012-01-15 21:01:16 +000012259 case 0xb993: s390_format_RRF_M0RERE(s390_irgen_TROO, ovl.fmt.RRF3.r3,
12260 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000012261 case 0xb994: s390_format_RRE_RR(s390_irgen_LLCR, ovl.fmt.RRE.r1,
12262 ovl.fmt.RRE.r2); goto ok;
12263 case 0xb995: s390_format_RRE_RR(s390_irgen_LLHR, ovl.fmt.RRE.r1,
12264 ovl.fmt.RRE.r2); goto ok;
12265 case 0xb996: s390_format_RRE_RR(s390_irgen_MLR, ovl.fmt.RRE.r1,
12266 ovl.fmt.RRE.r2); goto ok;
12267 case 0xb997: s390_format_RRE_RR(s390_irgen_DLR, ovl.fmt.RRE.r1,
12268 ovl.fmt.RRE.r2); goto ok;
12269 case 0xb998: s390_format_RRE_RR(s390_irgen_ALCR, ovl.fmt.RRE.r1,
12270 ovl.fmt.RRE.r2); goto ok;
12271 case 0xb999: s390_format_RRE_RR(s390_irgen_SLBR, ovl.fmt.RRE.r1,
12272 ovl.fmt.RRE.r2); goto ok;
12273 case 0xb99a: /* EPAIR */ goto unimplemented;
12274 case 0xb99b: /* ESAIR */ goto unimplemented;
12275 case 0xb99d: /* ESEA */ goto unimplemented;
12276 case 0xb99e: /* PTI */ goto unimplemented;
12277 case 0xb99f: /* SSAIR */ goto unimplemented;
12278 case 0xb9a2: /* PTF */ goto unimplemented;
12279 case 0xb9aa: /* LPTEA */ goto unimplemented;
12280 case 0xb9ae: /* RRBM */ goto unimplemented;
12281 case 0xb9af: /* PFMF */ goto unimplemented;
12282 case 0xb9b0: /* CU14 */ goto unimplemented;
florian2a415a12012-07-21 17:41:36 +000012283 case 0xb9b1: s390_format_RRF_M0RERE(s390_irgen_CU24, ovl.fmt.RRF3.r3,
12284 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
12285 goto ok;
sewardj2019a972011-03-07 16:04:07 +000012286 case 0xb9b2: /* CU41 */ goto unimplemented;
florian956194b2012-07-28 22:18:32 +000012287 case 0xb9b3: s390_format_RRE_RR(s390_irgen_CU42, ovl.fmt.RRE.r1,
12288 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000012289 case 0xb9bd: /* TRTRE */ goto unimplemented;
12290 case 0xb9be: /* SRSTU */ goto unimplemented;
12291 case 0xb9bf: /* TRTE */ goto unimplemented;
12292 case 0xb9c8: s390_format_RRF_R0RR2(s390_irgen_AHHHR, ovl.fmt.RRF4.r3,
12293 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12294 goto ok;
12295 case 0xb9c9: s390_format_RRF_R0RR2(s390_irgen_SHHHR, ovl.fmt.RRF4.r3,
12296 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12297 goto ok;
12298 case 0xb9ca: s390_format_RRF_R0RR2(s390_irgen_ALHHHR, ovl.fmt.RRF4.r3,
12299 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12300 goto ok;
12301 case 0xb9cb: s390_format_RRF_R0RR2(s390_irgen_SLHHHR, ovl.fmt.RRF4.r3,
12302 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12303 goto ok;
12304 case 0xb9cd: s390_format_RRE_RR(s390_irgen_CHHR, ovl.fmt.RRE.r1,
12305 ovl.fmt.RRE.r2); goto ok;
12306 case 0xb9cf: s390_format_RRE_RR(s390_irgen_CLHHR, ovl.fmt.RRE.r1,
12307 ovl.fmt.RRE.r2); goto ok;
12308 case 0xb9d8: s390_format_RRF_R0RR2(s390_irgen_AHHLR, ovl.fmt.RRF4.r3,
12309 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12310 goto ok;
12311 case 0xb9d9: s390_format_RRF_R0RR2(s390_irgen_SHHLR, ovl.fmt.RRF4.r3,
12312 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12313 goto ok;
12314 case 0xb9da: s390_format_RRF_R0RR2(s390_irgen_ALHHLR, ovl.fmt.RRF4.r3,
12315 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12316 goto ok;
12317 case 0xb9db: s390_format_RRF_R0RR2(s390_irgen_SLHHLR, ovl.fmt.RRF4.r3,
12318 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12319 goto ok;
12320 case 0xb9dd: s390_format_RRE_RR(s390_irgen_CHLR, ovl.fmt.RRE.r1,
12321 ovl.fmt.RRE.r2); goto ok;
12322 case 0xb9df: s390_format_RRE_RR(s390_irgen_CLHLR, ovl.fmt.RRE.r1,
12323 ovl.fmt.RRE.r2); goto ok;
12324 case 0xb9e1: /* POPCNT */ goto unimplemented;
sewardjd7bde722011-04-05 13:19:33 +000012325 case 0xb9e2: s390_format_RRF_U0RR(s390_irgen_LOCGR, ovl.fmt.RRF3.r3,
12326 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2,
12327 S390_XMNM_LOCGR); goto ok;
sewardj2019a972011-03-07 16:04:07 +000012328 case 0xb9e4: s390_format_RRF_R0RR2(s390_irgen_NGRK, ovl.fmt.RRF4.r3,
12329 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12330 goto ok;
12331 case 0xb9e6: s390_format_RRF_R0RR2(s390_irgen_OGRK, ovl.fmt.RRF4.r3,
12332 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12333 goto ok;
12334 case 0xb9e7: s390_format_RRF_R0RR2(s390_irgen_XGRK, ovl.fmt.RRF4.r3,
12335 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12336 goto ok;
12337 case 0xb9e8: s390_format_RRF_R0RR2(s390_irgen_AGRK, ovl.fmt.RRF4.r3,
12338 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12339 goto ok;
12340 case 0xb9e9: s390_format_RRF_R0RR2(s390_irgen_SGRK, ovl.fmt.RRF4.r3,
12341 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12342 goto ok;
12343 case 0xb9ea: s390_format_RRF_R0RR2(s390_irgen_ALGRK, ovl.fmt.RRF4.r3,
12344 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12345 goto ok;
12346 case 0xb9eb: s390_format_RRF_R0RR2(s390_irgen_SLGRK, ovl.fmt.RRF4.r3,
12347 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12348 goto ok;
sewardjd7bde722011-04-05 13:19:33 +000012349 case 0xb9f2: s390_format_RRF_U0RR(s390_irgen_LOCR, ovl.fmt.RRF3.r3,
12350 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2,
12351 S390_XMNM_LOCR); goto ok;
sewardj2019a972011-03-07 16:04:07 +000012352 case 0xb9f4: s390_format_RRF_R0RR2(s390_irgen_NRK, ovl.fmt.RRF4.r3,
12353 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12354 goto ok;
12355 case 0xb9f6: s390_format_RRF_R0RR2(s390_irgen_ORK, ovl.fmt.RRF4.r3,
12356 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12357 goto ok;
12358 case 0xb9f7: s390_format_RRF_R0RR2(s390_irgen_XRK, ovl.fmt.RRF4.r3,
12359 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12360 goto ok;
12361 case 0xb9f8: s390_format_RRF_R0RR2(s390_irgen_ARK, ovl.fmt.RRF4.r3,
12362 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12363 goto ok;
12364 case 0xb9f9: s390_format_RRF_R0RR2(s390_irgen_SRK, ovl.fmt.RRF4.r3,
12365 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12366 goto ok;
12367 case 0xb9fa: s390_format_RRF_R0RR2(s390_irgen_ALRK, ovl.fmt.RRF4.r3,
12368 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12369 goto ok;
12370 case 0xb9fb: s390_format_RRF_R0RR2(s390_irgen_SLRK, ovl.fmt.RRF4.r3,
12371 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12372 goto ok;
12373 }
12374
12375 switch ((ovl.value & 0xff000000) >> 24) {
12376 case 0x40: s390_format_RX_RRRD(s390_irgen_STH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12377 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12378 case 0x41: s390_format_RX_RRRD(s390_irgen_LA, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12379 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12380 case 0x42: s390_format_RX_RRRD(s390_irgen_STC, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12381 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12382 case 0x43: s390_format_RX_RRRD(s390_irgen_IC, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12383 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12384 case 0x44: s390_format_RX_RRRD(s390_irgen_EX, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12385 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12386 case 0x45: /* BAL */ goto unimplemented;
12387 case 0x46: s390_format_RX_RRRD(s390_irgen_BCT, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12388 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12389 case 0x47: s390_format_RX(s390_irgen_BC, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12390 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12391 case 0x48: s390_format_RX_RRRD(s390_irgen_LH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12392 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12393 case 0x49: s390_format_RX_RRRD(s390_irgen_CH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12394 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12395 case 0x4a: s390_format_RX_RRRD(s390_irgen_AH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12396 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12397 case 0x4b: s390_format_RX_RRRD(s390_irgen_SH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12398 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12399 case 0x4c: s390_format_RX_RRRD(s390_irgen_MH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12400 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12401 case 0x4d: s390_format_RX_RRRD(s390_irgen_BAS, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12402 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12403 case 0x4e: s390_format_RX_RRRD(s390_irgen_CVD, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12404 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12405 case 0x4f: s390_format_RX_RRRD(s390_irgen_CVB, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12406 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12407 case 0x50: s390_format_RX_RRRD(s390_irgen_ST, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12408 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12409 case 0x51: s390_format_RX_RRRD(s390_irgen_LAE, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12410 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12411 case 0x54: s390_format_RX_RRRD(s390_irgen_N, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12412 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12413 case 0x55: s390_format_RX_RRRD(s390_irgen_CL, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12414 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12415 case 0x56: s390_format_RX_RRRD(s390_irgen_O, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12416 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12417 case 0x57: s390_format_RX_RRRD(s390_irgen_X, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12418 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12419 case 0x58: s390_format_RX_RRRD(s390_irgen_L, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12420 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12421 case 0x59: s390_format_RX_RRRD(s390_irgen_C, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12422 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12423 case 0x5a: s390_format_RX_RRRD(s390_irgen_A, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12424 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12425 case 0x5b: s390_format_RX_RRRD(s390_irgen_S, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12426 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12427 case 0x5c: s390_format_RX_RRRD(s390_irgen_M, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12428 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12429 case 0x5d: s390_format_RX_RRRD(s390_irgen_D, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12430 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12431 case 0x5e: s390_format_RX_RRRD(s390_irgen_AL, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12432 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12433 case 0x5f: s390_format_RX_RRRD(s390_irgen_SL, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12434 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12435 case 0x60: s390_format_RX_FRRD(s390_irgen_STD, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12436 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12437 case 0x67: /* MXD */ goto unimplemented;
12438 case 0x68: s390_format_RX_FRRD(s390_irgen_LD, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12439 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12440 case 0x69: /* CD */ goto unimplemented;
12441 case 0x6a: /* AD */ goto unimplemented;
12442 case 0x6b: /* SD */ goto unimplemented;
12443 case 0x6c: /* MD */ goto unimplemented;
12444 case 0x6d: /* DD */ goto unimplemented;
12445 case 0x6e: /* AW */ goto unimplemented;
12446 case 0x6f: /* SW */ goto unimplemented;
12447 case 0x70: s390_format_RX_FRRD(s390_irgen_STE, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12448 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12449 case 0x71: s390_format_RX_RRRD(s390_irgen_MS, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12450 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12451 case 0x78: s390_format_RX_FRRD(s390_irgen_LE, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12452 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12453 case 0x79: /* CE */ goto unimplemented;
12454 case 0x7a: /* AE */ goto unimplemented;
12455 case 0x7b: /* SE */ goto unimplemented;
12456 case 0x7c: /* MDE */ goto unimplemented;
12457 case 0x7d: /* DE */ goto unimplemented;
12458 case 0x7e: /* AU */ goto unimplemented;
12459 case 0x7f: /* SU */ goto unimplemented;
12460 case 0x83: /* DIAG */ goto unimplemented;
12461 case 0x84: s390_format_RSI_RRP(s390_irgen_BRXH, ovl.fmt.RSI.r1,
12462 ovl.fmt.RSI.r3, ovl.fmt.RSI.i2); goto ok;
12463 case 0x85: s390_format_RSI_RRP(s390_irgen_BRXLE, ovl.fmt.RSI.r1,
12464 ovl.fmt.RSI.r3, ovl.fmt.RSI.i2); goto ok;
12465 case 0x86: s390_format_RS_RRRD(s390_irgen_BXH, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
12466 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
12467 case 0x87: s390_format_RS_RRRD(s390_irgen_BXLE, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
12468 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
12469 case 0x88: s390_format_RS_R0RD(s390_irgen_SRL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
12470 ovl.fmt.RS.d2); goto ok;
12471 case 0x89: s390_format_RS_R0RD(s390_irgen_SLL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
12472 ovl.fmt.RS.d2); goto ok;
12473 case 0x8a: s390_format_RS_R0RD(s390_irgen_SRA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
12474 ovl.fmt.RS.d2); goto ok;
12475 case 0x8b: s390_format_RS_R0RD(s390_irgen_SLA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
12476 ovl.fmt.RS.d2); goto ok;
12477 case 0x8c: s390_format_RS_R0RD(s390_irgen_SRDL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
12478 ovl.fmt.RS.d2); goto ok;
12479 case 0x8d: s390_format_RS_R0RD(s390_irgen_SLDL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
12480 ovl.fmt.RS.d2); goto ok;
12481 case 0x8e: s390_format_RS_R0RD(s390_irgen_SRDA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
12482 ovl.fmt.RS.d2); goto ok;
12483 case 0x8f: s390_format_RS_R0RD(s390_irgen_SLDA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
12484 ovl.fmt.RS.d2); goto ok;
12485 case 0x90: s390_format_RS_RRRD(s390_irgen_STM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
12486 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
12487 case 0x91: s390_format_SI_URD(s390_irgen_TM, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
12488 ovl.fmt.SI.d1); goto ok;
12489 case 0x92: s390_format_SI_URD(s390_irgen_MVI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
12490 ovl.fmt.SI.d1); goto ok;
12491 case 0x94: s390_format_SI_URD(s390_irgen_NI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
12492 ovl.fmt.SI.d1); goto ok;
12493 case 0x95: s390_format_SI_URD(s390_irgen_CLI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
12494 ovl.fmt.SI.d1); goto ok;
12495 case 0x96: s390_format_SI_URD(s390_irgen_OI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
12496 ovl.fmt.SI.d1); goto ok;
12497 case 0x97: s390_format_SI_URD(s390_irgen_XI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
12498 ovl.fmt.SI.d1); goto ok;
12499 case 0x98: s390_format_RS_RRRD(s390_irgen_LM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
12500 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
12501 case 0x99: /* TRACE */ goto unimplemented;
12502 case 0x9a: s390_format_RS_AARD(s390_irgen_LAM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
12503 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
12504 case 0x9b: s390_format_RS_AARD(s390_irgen_STAM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
12505 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
12506 case 0xa8: s390_format_RS_RRRD(s390_irgen_MVCLE, ovl.fmt.RS.r1,
12507 ovl.fmt.RS.r3, ovl.fmt.RS.b2, ovl.fmt.RS.d2);
12508 goto ok;
12509 case 0xa9: s390_format_RS_RRRD(s390_irgen_CLCLE, ovl.fmt.RS.r1,
12510 ovl.fmt.RS.r3, ovl.fmt.RS.b2, ovl.fmt.RS.d2);
12511 goto ok;
12512 case 0xac: /* STNSM */ goto unimplemented;
12513 case 0xad: /* STOSM */ goto unimplemented;
12514 case 0xae: /* SIGP */ goto unimplemented;
12515 case 0xaf: /* MC */ goto unimplemented;
12516 case 0xb1: /* LRA */ goto unimplemented;
12517 case 0xb6: /* STCTL */ goto unimplemented;
12518 case 0xb7: /* LCTL */ goto unimplemented;
12519 case 0xba: s390_format_RS_RRRD(s390_irgen_CS, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
12520 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
florian448cbba2012-06-06 02:26:01 +000012521 case 0xbb: s390_format_RS_RRRD(s390_irgen_CDS, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
12522 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000012523 case 0xbd: s390_format_RS_RURD(s390_irgen_CLM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
12524 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
12525 case 0xbe: s390_format_RS_RURD(s390_irgen_STCM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
12526 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
12527 case 0xbf: s390_format_RS_RURD(s390_irgen_ICM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
12528 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
12529 }
12530
12531 return S390_DECODE_UNKNOWN_INSN;
12532
12533ok:
12534 return S390_DECODE_OK;
12535
12536unimplemented:
12537 return S390_DECODE_UNIMPLEMENTED_INSN;
12538}
12539
12540static s390_decode_t
12541s390_decode_6byte_and_irgen(UChar *bytes)
12542{
12543 typedef union {
12544 struct {
12545 unsigned int op1 : 8;
12546 unsigned int r1 : 4;
12547 unsigned int r3 : 4;
12548 unsigned int i2 : 16;
12549 unsigned int : 8;
12550 unsigned int op2 : 8;
12551 } RIE;
12552 struct {
12553 unsigned int op1 : 8;
12554 unsigned int r1 : 4;
12555 unsigned int r2 : 4;
12556 unsigned int i3 : 8;
12557 unsigned int i4 : 8;
12558 unsigned int i5 : 8;
12559 unsigned int op2 : 8;
12560 } RIE_RRUUU;
12561 struct {
12562 unsigned int op1 : 8;
12563 unsigned int r1 : 4;
12564 unsigned int : 4;
12565 unsigned int i2 : 16;
12566 unsigned int m3 : 4;
12567 unsigned int : 4;
12568 unsigned int op2 : 8;
12569 } RIEv1;
12570 struct {
12571 unsigned int op1 : 8;
12572 unsigned int r1 : 4;
12573 unsigned int r2 : 4;
12574 unsigned int i4 : 16;
12575 unsigned int m3 : 4;
12576 unsigned int : 4;
12577 unsigned int op2 : 8;
12578 } RIE_RRPU;
12579 struct {
12580 unsigned int op1 : 8;
12581 unsigned int r1 : 4;
12582 unsigned int m3 : 4;
12583 unsigned int i4 : 16;
12584 unsigned int i2 : 8;
12585 unsigned int op2 : 8;
12586 } RIEv3;
12587 struct {
12588 unsigned int op1 : 8;
12589 unsigned int r1 : 4;
12590 unsigned int op2 : 4;
12591 unsigned int i2 : 32;
12592 } RIL;
12593 struct {
12594 unsigned int op1 : 8;
12595 unsigned int r1 : 4;
12596 unsigned int m3 : 4;
12597 unsigned int b4 : 4;
12598 unsigned int d4 : 12;
12599 unsigned int i2 : 8;
12600 unsigned int op2 : 8;
12601 } RIS;
12602 struct {
12603 unsigned int op1 : 8;
12604 unsigned int r1 : 4;
12605 unsigned int r2 : 4;
12606 unsigned int b4 : 4;
12607 unsigned int d4 : 12;
12608 unsigned int m3 : 4;
12609 unsigned int : 4;
12610 unsigned int op2 : 8;
12611 } RRS;
12612 struct {
12613 unsigned int op1 : 8;
12614 unsigned int l1 : 4;
12615 unsigned int : 4;
12616 unsigned int b1 : 4;
12617 unsigned int d1 : 12;
12618 unsigned int : 8;
12619 unsigned int op2 : 8;
12620 } RSL;
12621 struct {
12622 unsigned int op1 : 8;
12623 unsigned int r1 : 4;
12624 unsigned int r3 : 4;
12625 unsigned int b2 : 4;
12626 unsigned int dl2 : 12;
12627 unsigned int dh2 : 8;
12628 unsigned int op2 : 8;
12629 } RSY;
12630 struct {
12631 unsigned int op1 : 8;
12632 unsigned int r1 : 4;
12633 unsigned int x2 : 4;
12634 unsigned int b2 : 4;
12635 unsigned int d2 : 12;
12636 unsigned int : 8;
12637 unsigned int op2 : 8;
12638 } RXE;
12639 struct {
12640 unsigned int op1 : 8;
12641 unsigned int r3 : 4;
12642 unsigned int x2 : 4;
12643 unsigned int b2 : 4;
12644 unsigned int d2 : 12;
12645 unsigned int r1 : 4;
12646 unsigned int : 4;
12647 unsigned int op2 : 8;
12648 } RXF;
12649 struct {
12650 unsigned int op1 : 8;
12651 unsigned int r1 : 4;
12652 unsigned int x2 : 4;
12653 unsigned int b2 : 4;
12654 unsigned int dl2 : 12;
12655 unsigned int dh2 : 8;
12656 unsigned int op2 : 8;
12657 } RXY;
12658 struct {
12659 unsigned int op1 : 8;
12660 unsigned int i2 : 8;
12661 unsigned int b1 : 4;
12662 unsigned int dl1 : 12;
12663 unsigned int dh1 : 8;
12664 unsigned int op2 : 8;
12665 } SIY;
12666 struct {
12667 unsigned int op : 8;
12668 unsigned int l : 8;
12669 unsigned int b1 : 4;
12670 unsigned int d1 : 12;
12671 unsigned int b2 : 4;
12672 unsigned int d2 : 12;
12673 } SS;
12674 struct {
12675 unsigned int op : 8;
12676 unsigned int l1 : 4;
12677 unsigned int l2 : 4;
12678 unsigned int b1 : 4;
12679 unsigned int d1 : 12;
12680 unsigned int b2 : 4;
12681 unsigned int d2 : 12;
12682 } SS_LLRDRD;
12683 struct {
12684 unsigned int op : 8;
12685 unsigned int r1 : 4;
12686 unsigned int r3 : 4;
12687 unsigned int b2 : 4;
12688 unsigned int d2 : 12;
12689 unsigned int b4 : 4;
12690 unsigned int d4 : 12;
12691 } SS_RRRDRD2;
12692 struct {
12693 unsigned int op : 16;
12694 unsigned int b1 : 4;
12695 unsigned int d1 : 12;
12696 unsigned int b2 : 4;
12697 unsigned int d2 : 12;
12698 } SSE;
12699 struct {
12700 unsigned int op1 : 8;
12701 unsigned int r3 : 4;
12702 unsigned int op2 : 4;
12703 unsigned int b1 : 4;
12704 unsigned int d1 : 12;
12705 unsigned int b2 : 4;
12706 unsigned int d2 : 12;
12707 } SSF;
12708 struct {
12709 unsigned int op : 16;
12710 unsigned int b1 : 4;
12711 unsigned int d1 : 12;
12712 unsigned int i2 : 16;
12713 } SIL;
12714 } formats;
12715 union {
12716 formats fmt;
12717 ULong value;
12718 } ovl;
12719
12720 vassert(sizeof(formats) == 6);
12721
12722 ((char *)(&ovl.value))[0] = bytes[0];
12723 ((char *)(&ovl.value))[1] = bytes[1];
12724 ((char *)(&ovl.value))[2] = bytes[2];
12725 ((char *)(&ovl.value))[3] = bytes[3];
12726 ((char *)(&ovl.value))[4] = bytes[4];
12727 ((char *)(&ovl.value))[5] = bytes[5];
12728 ((char *)(&ovl.value))[6] = 0x0;
12729 ((char *)(&ovl.value))[7] = 0x0;
12730
12731 switch ((ovl.value >> 16) & 0xff00000000ffULL) {
12732 case 0xe30000000002ULL: s390_format_RXY_RRRD(s390_irgen_LTG, 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 0xe30000000003ULL: /* LRAG */ goto unimplemented;
12737 case 0xe30000000004ULL: s390_format_RXY_RRRD(s390_irgen_LG, ovl.fmt.RXY.r1,
12738 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12739 ovl.fmt.RXY.dl2,
12740 ovl.fmt.RXY.dh2); goto ok;
12741 case 0xe30000000006ULL: s390_format_RXY_RRRD(s390_irgen_CVBY, ovl.fmt.RXY.r1,
12742 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12743 ovl.fmt.RXY.dl2,
12744 ovl.fmt.RXY.dh2); goto ok;
12745 case 0xe30000000008ULL: s390_format_RXY_RRRD(s390_irgen_AG, ovl.fmt.RXY.r1,
12746 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12747 ovl.fmt.RXY.dl2,
12748 ovl.fmt.RXY.dh2); goto ok;
12749 case 0xe30000000009ULL: s390_format_RXY_RRRD(s390_irgen_SG, ovl.fmt.RXY.r1,
12750 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12751 ovl.fmt.RXY.dl2,
12752 ovl.fmt.RXY.dh2); goto ok;
12753 case 0xe3000000000aULL: s390_format_RXY_RRRD(s390_irgen_ALG, ovl.fmt.RXY.r1,
12754 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12755 ovl.fmt.RXY.dl2,
12756 ovl.fmt.RXY.dh2); goto ok;
12757 case 0xe3000000000bULL: s390_format_RXY_RRRD(s390_irgen_SLG, ovl.fmt.RXY.r1,
12758 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12759 ovl.fmt.RXY.dl2,
12760 ovl.fmt.RXY.dh2); goto ok;
12761 case 0xe3000000000cULL: s390_format_RXY_RRRD(s390_irgen_MSG, ovl.fmt.RXY.r1,
12762 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12763 ovl.fmt.RXY.dl2,
12764 ovl.fmt.RXY.dh2); goto ok;
12765 case 0xe3000000000dULL: s390_format_RXY_RRRD(s390_irgen_DSG, ovl.fmt.RXY.r1,
12766 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12767 ovl.fmt.RXY.dl2,
12768 ovl.fmt.RXY.dh2); goto ok;
12769 case 0xe3000000000eULL: /* CVBG */ goto unimplemented;
12770 case 0xe3000000000fULL: s390_format_RXY_RRRD(s390_irgen_LRVG, ovl.fmt.RXY.r1,
12771 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12772 ovl.fmt.RXY.dl2,
12773 ovl.fmt.RXY.dh2); goto ok;
12774 case 0xe30000000012ULL: s390_format_RXY_RRRD(s390_irgen_LT, ovl.fmt.RXY.r1,
12775 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12776 ovl.fmt.RXY.dl2,
12777 ovl.fmt.RXY.dh2); goto ok;
12778 case 0xe30000000013ULL: /* LRAY */ goto unimplemented;
12779 case 0xe30000000014ULL: s390_format_RXY_RRRD(s390_irgen_LGF, ovl.fmt.RXY.r1,
12780 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12781 ovl.fmt.RXY.dl2,
12782 ovl.fmt.RXY.dh2); goto ok;
12783 case 0xe30000000015ULL: s390_format_RXY_RRRD(s390_irgen_LGH, ovl.fmt.RXY.r1,
12784 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12785 ovl.fmt.RXY.dl2,
12786 ovl.fmt.RXY.dh2); goto ok;
12787 case 0xe30000000016ULL: s390_format_RXY_RRRD(s390_irgen_LLGF, ovl.fmt.RXY.r1,
12788 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12789 ovl.fmt.RXY.dl2,
12790 ovl.fmt.RXY.dh2); goto ok;
12791 case 0xe30000000017ULL: s390_format_RXY_RRRD(s390_irgen_LLGT, ovl.fmt.RXY.r1,
12792 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12793 ovl.fmt.RXY.dl2,
12794 ovl.fmt.RXY.dh2); goto ok;
12795 case 0xe30000000018ULL: s390_format_RXY_RRRD(s390_irgen_AGF, ovl.fmt.RXY.r1,
12796 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12797 ovl.fmt.RXY.dl2,
12798 ovl.fmt.RXY.dh2); goto ok;
12799 case 0xe30000000019ULL: s390_format_RXY_RRRD(s390_irgen_SGF, ovl.fmt.RXY.r1,
12800 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12801 ovl.fmt.RXY.dl2,
12802 ovl.fmt.RXY.dh2); goto ok;
12803 case 0xe3000000001aULL: s390_format_RXY_RRRD(s390_irgen_ALGF, ovl.fmt.RXY.r1,
12804 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12805 ovl.fmt.RXY.dl2,
12806 ovl.fmt.RXY.dh2); goto ok;
12807 case 0xe3000000001bULL: s390_format_RXY_RRRD(s390_irgen_SLGF, ovl.fmt.RXY.r1,
12808 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12809 ovl.fmt.RXY.dl2,
12810 ovl.fmt.RXY.dh2); goto ok;
12811 case 0xe3000000001cULL: s390_format_RXY_RRRD(s390_irgen_MSGF, ovl.fmt.RXY.r1,
12812 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12813 ovl.fmt.RXY.dl2,
12814 ovl.fmt.RXY.dh2); goto ok;
12815 case 0xe3000000001dULL: s390_format_RXY_RRRD(s390_irgen_DSGF, ovl.fmt.RXY.r1,
12816 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12817 ovl.fmt.RXY.dl2,
12818 ovl.fmt.RXY.dh2); goto ok;
12819 case 0xe3000000001eULL: s390_format_RXY_RRRD(s390_irgen_LRV, ovl.fmt.RXY.r1,
12820 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12821 ovl.fmt.RXY.dl2,
12822 ovl.fmt.RXY.dh2); goto ok;
12823 case 0xe3000000001fULL: s390_format_RXY_RRRD(s390_irgen_LRVH, ovl.fmt.RXY.r1,
12824 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12825 ovl.fmt.RXY.dl2,
12826 ovl.fmt.RXY.dh2); goto ok;
12827 case 0xe30000000020ULL: s390_format_RXY_RRRD(s390_irgen_CG, ovl.fmt.RXY.r1,
12828 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12829 ovl.fmt.RXY.dl2,
12830 ovl.fmt.RXY.dh2); goto ok;
12831 case 0xe30000000021ULL: s390_format_RXY_RRRD(s390_irgen_CLG, ovl.fmt.RXY.r1,
12832 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12833 ovl.fmt.RXY.dl2,
12834 ovl.fmt.RXY.dh2); goto ok;
12835 case 0xe30000000024ULL: s390_format_RXY_RRRD(s390_irgen_STG, ovl.fmt.RXY.r1,
12836 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12837 ovl.fmt.RXY.dl2,
12838 ovl.fmt.RXY.dh2); goto ok;
12839 case 0xe30000000026ULL: s390_format_RXY_RRRD(s390_irgen_CVDY, ovl.fmt.RXY.r1,
12840 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12841 ovl.fmt.RXY.dl2,
12842 ovl.fmt.RXY.dh2); goto ok;
12843 case 0xe3000000002eULL: /* CVDG */ goto unimplemented;
12844 case 0xe3000000002fULL: s390_format_RXY_RRRD(s390_irgen_STRVG,
12845 ovl.fmt.RXY.r1, ovl.fmt.RXY.x2,
12846 ovl.fmt.RXY.b2, ovl.fmt.RXY.dl2,
12847 ovl.fmt.RXY.dh2); goto ok;
12848 case 0xe30000000030ULL: s390_format_RXY_RRRD(s390_irgen_CGF, ovl.fmt.RXY.r1,
12849 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12850 ovl.fmt.RXY.dl2,
12851 ovl.fmt.RXY.dh2); goto ok;
12852 case 0xe30000000031ULL: s390_format_RXY_RRRD(s390_irgen_CLGF, ovl.fmt.RXY.r1,
12853 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12854 ovl.fmt.RXY.dl2,
12855 ovl.fmt.RXY.dh2); goto ok;
12856 case 0xe30000000032ULL: s390_format_RXY_RRRD(s390_irgen_LTGF, ovl.fmt.RXY.r1,
12857 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12858 ovl.fmt.RXY.dl2,
12859 ovl.fmt.RXY.dh2); goto ok;
12860 case 0xe30000000034ULL: s390_format_RXY_RRRD(s390_irgen_CGH, ovl.fmt.RXY.r1,
12861 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12862 ovl.fmt.RXY.dl2,
12863 ovl.fmt.RXY.dh2); goto ok;
12864 case 0xe30000000036ULL: s390_format_RXY_URRD(s390_irgen_PFD, ovl.fmt.RXY.r1,
12865 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12866 ovl.fmt.RXY.dl2,
12867 ovl.fmt.RXY.dh2); goto ok;
12868 case 0xe3000000003eULL: s390_format_RXY_RRRD(s390_irgen_STRV, ovl.fmt.RXY.r1,
12869 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12870 ovl.fmt.RXY.dl2,
12871 ovl.fmt.RXY.dh2); goto ok;
12872 case 0xe3000000003fULL: s390_format_RXY_RRRD(s390_irgen_STRVH,
12873 ovl.fmt.RXY.r1, ovl.fmt.RXY.x2,
12874 ovl.fmt.RXY.b2, ovl.fmt.RXY.dl2,
12875 ovl.fmt.RXY.dh2); goto ok;
12876 case 0xe30000000046ULL: s390_format_RXY_RRRD(s390_irgen_BCTG, ovl.fmt.RXY.r1,
12877 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12878 ovl.fmt.RXY.dl2,
12879 ovl.fmt.RXY.dh2); goto ok;
12880 case 0xe30000000050ULL: s390_format_RXY_RRRD(s390_irgen_STY, ovl.fmt.RXY.r1,
12881 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12882 ovl.fmt.RXY.dl2,
12883 ovl.fmt.RXY.dh2); goto ok;
12884 case 0xe30000000051ULL: s390_format_RXY_RRRD(s390_irgen_MSY, ovl.fmt.RXY.r1,
12885 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12886 ovl.fmt.RXY.dl2,
12887 ovl.fmt.RXY.dh2); goto ok;
12888 case 0xe30000000054ULL: s390_format_RXY_RRRD(s390_irgen_NY, ovl.fmt.RXY.r1,
12889 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12890 ovl.fmt.RXY.dl2,
12891 ovl.fmt.RXY.dh2); goto ok;
12892 case 0xe30000000055ULL: s390_format_RXY_RRRD(s390_irgen_CLY, ovl.fmt.RXY.r1,
12893 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12894 ovl.fmt.RXY.dl2,
12895 ovl.fmt.RXY.dh2); goto ok;
12896 case 0xe30000000056ULL: s390_format_RXY_RRRD(s390_irgen_OY, ovl.fmt.RXY.r1,
12897 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12898 ovl.fmt.RXY.dl2,
12899 ovl.fmt.RXY.dh2); goto ok;
12900 case 0xe30000000057ULL: s390_format_RXY_RRRD(s390_irgen_XY, ovl.fmt.RXY.r1,
12901 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12902 ovl.fmt.RXY.dl2,
12903 ovl.fmt.RXY.dh2); goto ok;
12904 case 0xe30000000058ULL: s390_format_RXY_RRRD(s390_irgen_LY, ovl.fmt.RXY.r1,
12905 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12906 ovl.fmt.RXY.dl2,
12907 ovl.fmt.RXY.dh2); goto ok;
12908 case 0xe30000000059ULL: s390_format_RXY_RRRD(s390_irgen_CY, ovl.fmt.RXY.r1,
12909 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12910 ovl.fmt.RXY.dl2,
12911 ovl.fmt.RXY.dh2); goto ok;
12912 case 0xe3000000005aULL: s390_format_RXY_RRRD(s390_irgen_AY, ovl.fmt.RXY.r1,
12913 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12914 ovl.fmt.RXY.dl2,
12915 ovl.fmt.RXY.dh2); goto ok;
12916 case 0xe3000000005bULL: s390_format_RXY_RRRD(s390_irgen_SY, ovl.fmt.RXY.r1,
12917 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12918 ovl.fmt.RXY.dl2,
12919 ovl.fmt.RXY.dh2); goto ok;
12920 case 0xe3000000005cULL: s390_format_RXY_RRRD(s390_irgen_MFY, ovl.fmt.RXY.r1,
12921 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12922 ovl.fmt.RXY.dl2,
12923 ovl.fmt.RXY.dh2); goto ok;
12924 case 0xe3000000005eULL: s390_format_RXY_RRRD(s390_irgen_ALY, ovl.fmt.RXY.r1,
12925 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12926 ovl.fmt.RXY.dl2,
12927 ovl.fmt.RXY.dh2); goto ok;
12928 case 0xe3000000005fULL: s390_format_RXY_RRRD(s390_irgen_SLY, ovl.fmt.RXY.r1,
12929 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12930 ovl.fmt.RXY.dl2,
12931 ovl.fmt.RXY.dh2); goto ok;
12932 case 0xe30000000070ULL: s390_format_RXY_RRRD(s390_irgen_STHY, ovl.fmt.RXY.r1,
12933 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12934 ovl.fmt.RXY.dl2,
12935 ovl.fmt.RXY.dh2); goto ok;
12936 case 0xe30000000071ULL: s390_format_RXY_RRRD(s390_irgen_LAY, ovl.fmt.RXY.r1,
12937 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12938 ovl.fmt.RXY.dl2,
12939 ovl.fmt.RXY.dh2); goto ok;
12940 case 0xe30000000072ULL: s390_format_RXY_RRRD(s390_irgen_STCY, ovl.fmt.RXY.r1,
12941 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12942 ovl.fmt.RXY.dl2,
12943 ovl.fmt.RXY.dh2); goto ok;
12944 case 0xe30000000073ULL: s390_format_RXY_RRRD(s390_irgen_ICY, ovl.fmt.RXY.r1,
12945 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12946 ovl.fmt.RXY.dl2,
12947 ovl.fmt.RXY.dh2); goto ok;
12948 case 0xe30000000075ULL: s390_format_RXY_RRRD(s390_irgen_LAEY, ovl.fmt.RXY.r1,
12949 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12950 ovl.fmt.RXY.dl2,
12951 ovl.fmt.RXY.dh2); goto ok;
12952 case 0xe30000000076ULL: s390_format_RXY_RRRD(s390_irgen_LB, ovl.fmt.RXY.r1,
12953 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12954 ovl.fmt.RXY.dl2,
12955 ovl.fmt.RXY.dh2); goto ok;
12956 case 0xe30000000077ULL: s390_format_RXY_RRRD(s390_irgen_LGB, ovl.fmt.RXY.r1,
12957 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12958 ovl.fmt.RXY.dl2,
12959 ovl.fmt.RXY.dh2); goto ok;
12960 case 0xe30000000078ULL: s390_format_RXY_RRRD(s390_irgen_LHY, ovl.fmt.RXY.r1,
12961 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12962 ovl.fmt.RXY.dl2,
12963 ovl.fmt.RXY.dh2); goto ok;
12964 case 0xe30000000079ULL: s390_format_RXY_RRRD(s390_irgen_CHY, ovl.fmt.RXY.r1,
12965 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12966 ovl.fmt.RXY.dl2,
12967 ovl.fmt.RXY.dh2); goto ok;
12968 case 0xe3000000007aULL: s390_format_RXY_RRRD(s390_irgen_AHY, ovl.fmt.RXY.r1,
12969 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12970 ovl.fmt.RXY.dl2,
12971 ovl.fmt.RXY.dh2); goto ok;
12972 case 0xe3000000007bULL: s390_format_RXY_RRRD(s390_irgen_SHY, ovl.fmt.RXY.r1,
12973 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12974 ovl.fmt.RXY.dl2,
12975 ovl.fmt.RXY.dh2); goto ok;
12976 case 0xe3000000007cULL: s390_format_RXY_RRRD(s390_irgen_MHY, ovl.fmt.RXY.r1,
12977 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12978 ovl.fmt.RXY.dl2,
12979 ovl.fmt.RXY.dh2); goto ok;
12980 case 0xe30000000080ULL: s390_format_RXY_RRRD(s390_irgen_NG, ovl.fmt.RXY.r1,
12981 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12982 ovl.fmt.RXY.dl2,
12983 ovl.fmt.RXY.dh2); goto ok;
12984 case 0xe30000000081ULL: s390_format_RXY_RRRD(s390_irgen_OG, ovl.fmt.RXY.r1,
12985 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12986 ovl.fmt.RXY.dl2,
12987 ovl.fmt.RXY.dh2); goto ok;
12988 case 0xe30000000082ULL: s390_format_RXY_RRRD(s390_irgen_XG, ovl.fmt.RXY.r1,
12989 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12990 ovl.fmt.RXY.dl2,
12991 ovl.fmt.RXY.dh2); goto ok;
12992 case 0xe30000000086ULL: s390_format_RXY_RRRD(s390_irgen_MLG, ovl.fmt.RXY.r1,
12993 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12994 ovl.fmt.RXY.dl2,
12995 ovl.fmt.RXY.dh2); goto ok;
12996 case 0xe30000000087ULL: s390_format_RXY_RRRD(s390_irgen_DLG, ovl.fmt.RXY.r1,
12997 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
12998 ovl.fmt.RXY.dl2,
12999 ovl.fmt.RXY.dh2); goto ok;
13000 case 0xe30000000088ULL: s390_format_RXY_RRRD(s390_irgen_ALCG, ovl.fmt.RXY.r1,
13001 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13002 ovl.fmt.RXY.dl2,
13003 ovl.fmt.RXY.dh2); goto ok;
13004 case 0xe30000000089ULL: s390_format_RXY_RRRD(s390_irgen_SLBG, ovl.fmt.RXY.r1,
13005 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13006 ovl.fmt.RXY.dl2,
13007 ovl.fmt.RXY.dh2); goto ok;
13008 case 0xe3000000008eULL: s390_format_RXY_RRRD(s390_irgen_STPQ, ovl.fmt.RXY.r1,
13009 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13010 ovl.fmt.RXY.dl2,
13011 ovl.fmt.RXY.dh2); goto ok;
13012 case 0xe3000000008fULL: s390_format_RXY_RRRD(s390_irgen_LPQ, ovl.fmt.RXY.r1,
13013 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13014 ovl.fmt.RXY.dl2,
13015 ovl.fmt.RXY.dh2); goto ok;
13016 case 0xe30000000090ULL: s390_format_RXY_RRRD(s390_irgen_LLGC, ovl.fmt.RXY.r1,
13017 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13018 ovl.fmt.RXY.dl2,
13019 ovl.fmt.RXY.dh2); goto ok;
13020 case 0xe30000000091ULL: s390_format_RXY_RRRD(s390_irgen_LLGH, ovl.fmt.RXY.r1,
13021 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13022 ovl.fmt.RXY.dl2,
13023 ovl.fmt.RXY.dh2); goto ok;
13024 case 0xe30000000094ULL: s390_format_RXY_RRRD(s390_irgen_LLC, ovl.fmt.RXY.r1,
13025 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13026 ovl.fmt.RXY.dl2,
13027 ovl.fmt.RXY.dh2); goto ok;
13028 case 0xe30000000095ULL: s390_format_RXY_RRRD(s390_irgen_LLH, ovl.fmt.RXY.r1,
13029 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13030 ovl.fmt.RXY.dl2,
13031 ovl.fmt.RXY.dh2); goto ok;
13032 case 0xe30000000096ULL: s390_format_RXY_RRRD(s390_irgen_ML, ovl.fmt.RXY.r1,
13033 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13034 ovl.fmt.RXY.dl2,
13035 ovl.fmt.RXY.dh2); goto ok;
13036 case 0xe30000000097ULL: s390_format_RXY_RRRD(s390_irgen_DL, ovl.fmt.RXY.r1,
13037 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13038 ovl.fmt.RXY.dl2,
13039 ovl.fmt.RXY.dh2); goto ok;
13040 case 0xe30000000098ULL: s390_format_RXY_RRRD(s390_irgen_ALC, ovl.fmt.RXY.r1,
13041 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13042 ovl.fmt.RXY.dl2,
13043 ovl.fmt.RXY.dh2); goto ok;
13044 case 0xe30000000099ULL: s390_format_RXY_RRRD(s390_irgen_SLB, ovl.fmt.RXY.r1,
13045 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13046 ovl.fmt.RXY.dl2,
13047 ovl.fmt.RXY.dh2); goto ok;
13048 case 0xe300000000c0ULL: s390_format_RXY_RRRD(s390_irgen_LBH, ovl.fmt.RXY.r1,
13049 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13050 ovl.fmt.RXY.dl2,
13051 ovl.fmt.RXY.dh2); goto ok;
13052 case 0xe300000000c2ULL: s390_format_RXY_RRRD(s390_irgen_LLCH, ovl.fmt.RXY.r1,
13053 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13054 ovl.fmt.RXY.dl2,
13055 ovl.fmt.RXY.dh2); goto ok;
13056 case 0xe300000000c3ULL: s390_format_RXY_RRRD(s390_irgen_STCH, ovl.fmt.RXY.r1,
13057 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13058 ovl.fmt.RXY.dl2,
13059 ovl.fmt.RXY.dh2); goto ok;
13060 case 0xe300000000c4ULL: s390_format_RXY_RRRD(s390_irgen_LHH, ovl.fmt.RXY.r1,
13061 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13062 ovl.fmt.RXY.dl2,
13063 ovl.fmt.RXY.dh2); goto ok;
13064 case 0xe300000000c6ULL: s390_format_RXY_RRRD(s390_irgen_LLHH, ovl.fmt.RXY.r1,
13065 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13066 ovl.fmt.RXY.dl2,
13067 ovl.fmt.RXY.dh2); goto ok;
13068 case 0xe300000000c7ULL: s390_format_RXY_RRRD(s390_irgen_STHH, ovl.fmt.RXY.r1,
13069 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13070 ovl.fmt.RXY.dl2,
13071 ovl.fmt.RXY.dh2); goto ok;
13072 case 0xe300000000caULL: s390_format_RXY_RRRD(s390_irgen_LFH, ovl.fmt.RXY.r1,
13073 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13074 ovl.fmt.RXY.dl2,
13075 ovl.fmt.RXY.dh2); goto ok;
13076 case 0xe300000000cbULL: s390_format_RXY_RRRD(s390_irgen_STFH, ovl.fmt.RXY.r1,
13077 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13078 ovl.fmt.RXY.dl2,
13079 ovl.fmt.RXY.dh2); goto ok;
13080 case 0xe300000000cdULL: s390_format_RXY_RRRD(s390_irgen_CHF, ovl.fmt.RXY.r1,
13081 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13082 ovl.fmt.RXY.dl2,
13083 ovl.fmt.RXY.dh2); goto ok;
13084 case 0xe300000000cfULL: s390_format_RXY_RRRD(s390_irgen_CLHF, ovl.fmt.RXY.r1,
13085 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13086 ovl.fmt.RXY.dl2,
13087 ovl.fmt.RXY.dh2); goto ok;
13088 case 0xeb0000000004ULL: s390_format_RSY_RRRD(s390_irgen_LMG, ovl.fmt.RSY.r1,
13089 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13090 ovl.fmt.RSY.dl2,
13091 ovl.fmt.RSY.dh2); goto ok;
13092 case 0xeb000000000aULL: s390_format_RSY_RRRD(s390_irgen_SRAG, ovl.fmt.RSY.r1,
13093 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13094 ovl.fmt.RSY.dl2,
13095 ovl.fmt.RSY.dh2); goto ok;
13096 case 0xeb000000000bULL: s390_format_RSY_RRRD(s390_irgen_SLAG, ovl.fmt.RSY.r1,
13097 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13098 ovl.fmt.RSY.dl2,
13099 ovl.fmt.RSY.dh2); goto ok;
13100 case 0xeb000000000cULL: s390_format_RSY_RRRD(s390_irgen_SRLG, ovl.fmt.RSY.r1,
13101 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13102 ovl.fmt.RSY.dl2,
13103 ovl.fmt.RSY.dh2); goto ok;
13104 case 0xeb000000000dULL: s390_format_RSY_RRRD(s390_irgen_SLLG, ovl.fmt.RSY.r1,
13105 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13106 ovl.fmt.RSY.dl2,
13107 ovl.fmt.RSY.dh2); goto ok;
13108 case 0xeb000000000fULL: /* TRACG */ goto unimplemented;
13109 case 0xeb0000000014ULL: s390_format_RSY_RRRD(s390_irgen_CSY, ovl.fmt.RSY.r1,
13110 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13111 ovl.fmt.RSY.dl2,
13112 ovl.fmt.RSY.dh2); goto ok;
13113 case 0xeb000000001cULL: s390_format_RSY_RRRD(s390_irgen_RLLG, ovl.fmt.RSY.r1,
13114 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13115 ovl.fmt.RSY.dl2,
13116 ovl.fmt.RSY.dh2); goto ok;
13117 case 0xeb000000001dULL: s390_format_RSY_RRRD(s390_irgen_RLL, ovl.fmt.RSY.r1,
13118 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13119 ovl.fmt.RSY.dl2,
13120 ovl.fmt.RSY.dh2); goto ok;
13121 case 0xeb0000000020ULL: s390_format_RSY_RURD(s390_irgen_CLMH, ovl.fmt.RSY.r1,
13122 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13123 ovl.fmt.RSY.dl2,
13124 ovl.fmt.RSY.dh2); goto ok;
13125 case 0xeb0000000021ULL: s390_format_RSY_RURD(s390_irgen_CLMY, ovl.fmt.RSY.r1,
13126 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13127 ovl.fmt.RSY.dl2,
13128 ovl.fmt.RSY.dh2); goto ok;
13129 case 0xeb0000000024ULL: s390_format_RSY_RRRD(s390_irgen_STMG, ovl.fmt.RSY.r1,
13130 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13131 ovl.fmt.RSY.dl2,
13132 ovl.fmt.RSY.dh2); goto ok;
13133 case 0xeb0000000025ULL: /* STCTG */ goto unimplemented;
13134 case 0xeb0000000026ULL: s390_format_RSY_RRRD(s390_irgen_STMH, ovl.fmt.RSY.r1,
13135 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13136 ovl.fmt.RSY.dl2,
13137 ovl.fmt.RSY.dh2); goto ok;
13138 case 0xeb000000002cULL: s390_format_RSY_RURD(s390_irgen_STCMH,
13139 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
13140 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
13141 ovl.fmt.RSY.dh2); goto ok;
13142 case 0xeb000000002dULL: s390_format_RSY_RURD(s390_irgen_STCMY,
13143 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
13144 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
13145 ovl.fmt.RSY.dh2); goto ok;
13146 case 0xeb000000002fULL: /* LCTLG */ goto unimplemented;
13147 case 0xeb0000000030ULL: s390_format_RSY_RRRD(s390_irgen_CSG, ovl.fmt.RSY.r1,
13148 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13149 ovl.fmt.RSY.dl2,
13150 ovl.fmt.RSY.dh2); goto ok;
florian448cbba2012-06-06 02:26:01 +000013151 case 0xeb0000000031ULL: s390_format_RSY_RRRD(s390_irgen_CDSY, ovl.fmt.RSY.r1,
13152 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13153 ovl.fmt.RSY.dl2,
13154 ovl.fmt.RSY.dh2); goto ok;
13155 case 0xeb000000003eULL: s390_format_RSY_RRRD(s390_irgen_CDSG, ovl.fmt.RSY.r1,
13156 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13157 ovl.fmt.RSY.dl2,
13158 ovl.fmt.RSY.dh2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013159 case 0xeb0000000044ULL: s390_format_RSY_RRRD(s390_irgen_BXHG, ovl.fmt.RSY.r1,
13160 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13161 ovl.fmt.RSY.dl2,
13162 ovl.fmt.RSY.dh2); goto ok;
13163 case 0xeb0000000045ULL: s390_format_RSY_RRRD(s390_irgen_BXLEG,
13164 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
13165 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
13166 ovl.fmt.RSY.dh2); goto ok;
13167 case 0xeb000000004cULL: /* ECAG */ goto unimplemented;
13168 case 0xeb0000000051ULL: s390_format_SIY_URD(s390_irgen_TMY, ovl.fmt.SIY.i2,
13169 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
13170 ovl.fmt.SIY.dh1); goto ok;
13171 case 0xeb0000000052ULL: s390_format_SIY_URD(s390_irgen_MVIY, ovl.fmt.SIY.i2,
13172 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
13173 ovl.fmt.SIY.dh1); goto ok;
13174 case 0xeb0000000054ULL: s390_format_SIY_URD(s390_irgen_NIY, ovl.fmt.SIY.i2,
13175 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
13176 ovl.fmt.SIY.dh1); goto ok;
13177 case 0xeb0000000055ULL: s390_format_SIY_URD(s390_irgen_CLIY, ovl.fmt.SIY.i2,
13178 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
13179 ovl.fmt.SIY.dh1); goto ok;
13180 case 0xeb0000000056ULL: s390_format_SIY_URD(s390_irgen_OIY, ovl.fmt.SIY.i2,
13181 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
13182 ovl.fmt.SIY.dh1); goto ok;
13183 case 0xeb0000000057ULL: s390_format_SIY_URD(s390_irgen_XIY, ovl.fmt.SIY.i2,
13184 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
13185 ovl.fmt.SIY.dh1); goto ok;
13186 case 0xeb000000006aULL: s390_format_SIY_IRD(s390_irgen_ASI, ovl.fmt.SIY.i2,
13187 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
13188 ovl.fmt.SIY.dh1); goto ok;
13189 case 0xeb000000006eULL: s390_format_SIY_IRD(s390_irgen_ALSI, ovl.fmt.SIY.i2,
13190 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
13191 ovl.fmt.SIY.dh1); goto ok;
13192 case 0xeb000000007aULL: s390_format_SIY_IRD(s390_irgen_AGSI, ovl.fmt.SIY.i2,
13193 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
13194 ovl.fmt.SIY.dh1); goto ok;
13195 case 0xeb000000007eULL: s390_format_SIY_IRD(s390_irgen_ALGSI, ovl.fmt.SIY.i2,
13196 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
13197 ovl.fmt.SIY.dh1); goto ok;
13198 case 0xeb0000000080ULL: s390_format_RSY_RURD(s390_irgen_ICMH, ovl.fmt.RSY.r1,
13199 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13200 ovl.fmt.RSY.dl2,
13201 ovl.fmt.RSY.dh2); goto ok;
13202 case 0xeb0000000081ULL: s390_format_RSY_RURD(s390_irgen_ICMY, ovl.fmt.RSY.r1,
13203 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13204 ovl.fmt.RSY.dl2,
13205 ovl.fmt.RSY.dh2); goto ok;
13206 case 0xeb000000008eULL: /* MVCLU */ goto unimplemented;
13207 case 0xeb000000008fULL: /* CLCLU */ goto unimplemented;
13208 case 0xeb0000000090ULL: s390_format_RSY_RRRD(s390_irgen_STMY, ovl.fmt.RSY.r1,
13209 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13210 ovl.fmt.RSY.dl2,
13211 ovl.fmt.RSY.dh2); goto ok;
13212 case 0xeb0000000096ULL: s390_format_RSY_RRRD(s390_irgen_LMH, ovl.fmt.RSY.r1,
13213 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13214 ovl.fmt.RSY.dl2,
13215 ovl.fmt.RSY.dh2); goto ok;
13216 case 0xeb0000000098ULL: s390_format_RSY_RRRD(s390_irgen_LMY, ovl.fmt.RSY.r1,
13217 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13218 ovl.fmt.RSY.dl2,
13219 ovl.fmt.RSY.dh2); goto ok;
13220 case 0xeb000000009aULL: s390_format_RSY_AARD(s390_irgen_LAMY, ovl.fmt.RSY.r1,
13221 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13222 ovl.fmt.RSY.dl2,
13223 ovl.fmt.RSY.dh2); goto ok;
13224 case 0xeb000000009bULL: s390_format_RSY_AARD(s390_irgen_STAMY,
13225 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
13226 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
13227 ovl.fmt.RSY.dh2); goto ok;
13228 case 0xeb00000000c0ULL: /* TP */ goto unimplemented;
13229 case 0xeb00000000dcULL: s390_format_RSY_RRRD(s390_irgen_SRAK, ovl.fmt.RSY.r1,
13230 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13231 ovl.fmt.RSY.dl2,
13232 ovl.fmt.RSY.dh2); goto ok;
13233 case 0xeb00000000ddULL: s390_format_RSY_RRRD(s390_irgen_SLAK, ovl.fmt.RSY.r1,
13234 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13235 ovl.fmt.RSY.dl2,
13236 ovl.fmt.RSY.dh2); goto ok;
13237 case 0xeb00000000deULL: s390_format_RSY_RRRD(s390_irgen_SRLK, ovl.fmt.RSY.r1,
13238 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13239 ovl.fmt.RSY.dl2,
13240 ovl.fmt.RSY.dh2); goto ok;
13241 case 0xeb00000000dfULL: s390_format_RSY_RRRD(s390_irgen_SLLK, ovl.fmt.RSY.r1,
13242 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13243 ovl.fmt.RSY.dl2,
13244 ovl.fmt.RSY.dh2); goto ok;
sewardjd7bde722011-04-05 13:19:33 +000013245 case 0xeb00000000e2ULL: s390_format_RSY_RDRM(s390_irgen_LOCG, ovl.fmt.RSY.r1,
13246 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13247 ovl.fmt.RSY.dl2,
13248 ovl.fmt.RSY.dh2,
13249 S390_XMNM_LOCG); goto ok;
13250 case 0xeb00000000e3ULL: s390_format_RSY_RDRM(s390_irgen_STOCG,
13251 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
13252 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
13253 ovl.fmt.RSY.dh2,
13254 S390_XMNM_STOCG); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013255 case 0xeb00000000e4ULL: s390_format_RSY_RRRD(s390_irgen_LANG, ovl.fmt.RSY.r1,
13256 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13257 ovl.fmt.RSY.dl2,
13258 ovl.fmt.RSY.dh2); goto ok;
13259 case 0xeb00000000e6ULL: s390_format_RSY_RRRD(s390_irgen_LAOG, ovl.fmt.RSY.r1,
13260 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13261 ovl.fmt.RSY.dl2,
13262 ovl.fmt.RSY.dh2); goto ok;
13263 case 0xeb00000000e7ULL: s390_format_RSY_RRRD(s390_irgen_LAXG, ovl.fmt.RSY.r1,
13264 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13265 ovl.fmt.RSY.dl2,
13266 ovl.fmt.RSY.dh2); goto ok;
13267 case 0xeb00000000e8ULL: s390_format_RSY_RRRD(s390_irgen_LAAG, ovl.fmt.RSY.r1,
13268 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13269 ovl.fmt.RSY.dl2,
13270 ovl.fmt.RSY.dh2); goto ok;
13271 case 0xeb00000000eaULL: s390_format_RSY_RRRD(s390_irgen_LAALG,
13272 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
13273 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
13274 ovl.fmt.RSY.dh2); goto ok;
sewardjd7bde722011-04-05 13:19:33 +000013275 case 0xeb00000000f2ULL: s390_format_RSY_RDRM(s390_irgen_LOC, ovl.fmt.RSY.r1,
13276 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13277 ovl.fmt.RSY.dl2,
13278 ovl.fmt.RSY.dh2, S390_XMNM_LOC);
13279 goto ok;
13280 case 0xeb00000000f3ULL: s390_format_RSY_RDRM(s390_irgen_STOC, ovl.fmt.RSY.r1,
13281 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13282 ovl.fmt.RSY.dl2,
13283 ovl.fmt.RSY.dh2,
13284 S390_XMNM_STOC); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013285 case 0xeb00000000f4ULL: s390_format_RSY_RRRD(s390_irgen_LAN, ovl.fmt.RSY.r1,
13286 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13287 ovl.fmt.RSY.dl2,
13288 ovl.fmt.RSY.dh2); goto ok;
13289 case 0xeb00000000f6ULL: s390_format_RSY_RRRD(s390_irgen_LAO, ovl.fmt.RSY.r1,
13290 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13291 ovl.fmt.RSY.dl2,
13292 ovl.fmt.RSY.dh2); goto ok;
13293 case 0xeb00000000f7ULL: s390_format_RSY_RRRD(s390_irgen_LAX, ovl.fmt.RSY.r1,
13294 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13295 ovl.fmt.RSY.dl2,
13296 ovl.fmt.RSY.dh2); goto ok;
13297 case 0xeb00000000f8ULL: s390_format_RSY_RRRD(s390_irgen_LAA, ovl.fmt.RSY.r1,
13298 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13299 ovl.fmt.RSY.dl2,
13300 ovl.fmt.RSY.dh2); goto ok;
13301 case 0xeb00000000faULL: s390_format_RSY_RRRD(s390_irgen_LAAL, ovl.fmt.RSY.r1,
13302 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13303 ovl.fmt.RSY.dl2,
13304 ovl.fmt.RSY.dh2); goto ok;
13305 case 0xec0000000044ULL: s390_format_RIE_RRP(s390_irgen_BRXHG, ovl.fmt.RIE.r1,
13306 ovl.fmt.RIE.r3, ovl.fmt.RIE.i2);
13307 goto ok;
13308 case 0xec0000000045ULL: s390_format_RIE_RRP(s390_irgen_BRXLG, ovl.fmt.RIE.r1,
13309 ovl.fmt.RIE.r3, ovl.fmt.RIE.i2);
13310 goto ok;
13311 case 0xec0000000051ULL: /* RISBLG */ goto unimplemented;
13312 case 0xec0000000054ULL: s390_format_RIE_RRUUU(s390_irgen_RNSBG,
13313 ovl.fmt.RIE_RRUUU.r1,
13314 ovl.fmt.RIE_RRUUU.r2,
13315 ovl.fmt.RIE_RRUUU.i3,
13316 ovl.fmt.RIE_RRUUU.i4,
13317 ovl.fmt.RIE_RRUUU.i5);
13318 goto ok;
13319 case 0xec0000000055ULL: s390_format_RIE_RRUUU(s390_irgen_RISBG,
13320 ovl.fmt.RIE_RRUUU.r1,
13321 ovl.fmt.RIE_RRUUU.r2,
13322 ovl.fmt.RIE_RRUUU.i3,
13323 ovl.fmt.RIE_RRUUU.i4,
13324 ovl.fmt.RIE_RRUUU.i5);
13325 goto ok;
13326 case 0xec0000000056ULL: s390_format_RIE_RRUUU(s390_irgen_ROSBG,
13327 ovl.fmt.RIE_RRUUU.r1,
13328 ovl.fmt.RIE_RRUUU.r2,
13329 ovl.fmt.RIE_RRUUU.i3,
13330 ovl.fmt.RIE_RRUUU.i4,
13331 ovl.fmt.RIE_RRUUU.i5);
13332 goto ok;
13333 case 0xec0000000057ULL: s390_format_RIE_RRUUU(s390_irgen_RXSBG,
13334 ovl.fmt.RIE_RRUUU.r1,
13335 ovl.fmt.RIE_RRUUU.r2,
13336 ovl.fmt.RIE_RRUUU.i3,
13337 ovl.fmt.RIE_RRUUU.i4,
13338 ovl.fmt.RIE_RRUUU.i5);
13339 goto ok;
13340 case 0xec000000005dULL: /* RISBHG */ goto unimplemented;
13341 case 0xec0000000064ULL: s390_format_RIE_RRPU(s390_irgen_CGRJ,
13342 ovl.fmt.RIE_RRPU.r1,
13343 ovl.fmt.RIE_RRPU.r2,
13344 ovl.fmt.RIE_RRPU.i4,
13345 ovl.fmt.RIE_RRPU.m3); goto ok;
13346 case 0xec0000000065ULL: s390_format_RIE_RRPU(s390_irgen_CLGRJ,
13347 ovl.fmt.RIE_RRPU.r1,
13348 ovl.fmt.RIE_RRPU.r2,
13349 ovl.fmt.RIE_RRPU.i4,
13350 ovl.fmt.RIE_RRPU.m3); goto ok;
13351 case 0xec0000000070ULL: /* CGIT */ goto unimplemented;
13352 case 0xec0000000071ULL: /* CLGIT */ goto unimplemented;
13353 case 0xec0000000072ULL: /* CIT */ goto unimplemented;
13354 case 0xec0000000073ULL: /* CLFIT */ goto unimplemented;
13355 case 0xec0000000076ULL: s390_format_RIE_RRPU(s390_irgen_CRJ,
13356 ovl.fmt.RIE_RRPU.r1,
13357 ovl.fmt.RIE_RRPU.r2,
13358 ovl.fmt.RIE_RRPU.i4,
13359 ovl.fmt.RIE_RRPU.m3); goto ok;
13360 case 0xec0000000077ULL: s390_format_RIE_RRPU(s390_irgen_CLRJ,
13361 ovl.fmt.RIE_RRPU.r1,
13362 ovl.fmt.RIE_RRPU.r2,
13363 ovl.fmt.RIE_RRPU.i4,
13364 ovl.fmt.RIE_RRPU.m3); goto ok;
13365 case 0xec000000007cULL: s390_format_RIE_RUPI(s390_irgen_CGIJ,
13366 ovl.fmt.RIEv3.r1,
13367 ovl.fmt.RIEv3.m3,
13368 ovl.fmt.RIEv3.i4,
13369 ovl.fmt.RIEv3.i2); goto ok;
13370 case 0xec000000007dULL: s390_format_RIE_RUPU(s390_irgen_CLGIJ,
13371 ovl.fmt.RIEv3.r1,
13372 ovl.fmt.RIEv3.m3,
13373 ovl.fmt.RIEv3.i4,
13374 ovl.fmt.RIEv3.i2); goto ok;
13375 case 0xec000000007eULL: s390_format_RIE_RUPI(s390_irgen_CIJ,
13376 ovl.fmt.RIEv3.r1,
13377 ovl.fmt.RIEv3.m3,
13378 ovl.fmt.RIEv3.i4,
13379 ovl.fmt.RIEv3.i2); goto ok;
13380 case 0xec000000007fULL: s390_format_RIE_RUPU(s390_irgen_CLIJ,
13381 ovl.fmt.RIEv3.r1,
13382 ovl.fmt.RIEv3.m3,
13383 ovl.fmt.RIEv3.i4,
13384 ovl.fmt.RIEv3.i2); goto ok;
13385 case 0xec00000000d8ULL: s390_format_RIE_RRI0(s390_irgen_AHIK, ovl.fmt.RIE.r1,
13386 ovl.fmt.RIE.r3, ovl.fmt.RIE.i2);
13387 goto ok;
13388 case 0xec00000000d9ULL: s390_format_RIE_RRI0(s390_irgen_AGHIK,
13389 ovl.fmt.RIE.r1, ovl.fmt.RIE.r3,
13390 ovl.fmt.RIE.i2); goto ok;
13391 case 0xec00000000daULL: s390_format_RIE_RRI0(s390_irgen_ALHSIK,
13392 ovl.fmt.RIE.r1, ovl.fmt.RIE.r3,
13393 ovl.fmt.RIE.i2); goto ok;
13394 case 0xec00000000dbULL: s390_format_RIE_RRI0(s390_irgen_ALGHSIK,
13395 ovl.fmt.RIE.r1, ovl.fmt.RIE.r3,
13396 ovl.fmt.RIE.i2); goto ok;
13397 case 0xec00000000e4ULL: s390_format_RRS(s390_irgen_CGRB, ovl.fmt.RRS.r1,
13398 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
13399 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
13400 goto ok;
13401 case 0xec00000000e5ULL: s390_format_RRS(s390_irgen_CLGRB, ovl.fmt.RRS.r1,
13402 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
13403 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
13404 goto ok;
13405 case 0xec00000000f6ULL: s390_format_RRS(s390_irgen_CRB, ovl.fmt.RRS.r1,
13406 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
13407 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
13408 goto ok;
13409 case 0xec00000000f7ULL: s390_format_RRS(s390_irgen_CLRB, ovl.fmt.RRS.r1,
13410 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
13411 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
13412 goto ok;
13413 case 0xec00000000fcULL: s390_format_RIS_RURDI(s390_irgen_CGIB,
13414 ovl.fmt.RIS.r1, ovl.fmt.RIS.m3,
13415 ovl.fmt.RIS.b4, ovl.fmt.RIS.d4,
13416 ovl.fmt.RIS.i2); goto ok;
13417 case 0xec00000000fdULL: s390_format_RIS_RURDU(s390_irgen_CLGIB,
13418 ovl.fmt.RIS.r1, ovl.fmt.RIS.m3,
13419 ovl.fmt.RIS.b4, ovl.fmt.RIS.d4,
13420 ovl.fmt.RIS.i2); goto ok;
13421 case 0xec00000000feULL: s390_format_RIS_RURDI(s390_irgen_CIB, ovl.fmt.RIS.r1,
13422 ovl.fmt.RIS.m3, ovl.fmt.RIS.b4,
13423 ovl.fmt.RIS.d4,
13424 ovl.fmt.RIS.i2); goto ok;
13425 case 0xec00000000ffULL: s390_format_RIS_RURDU(s390_irgen_CLIB,
13426 ovl.fmt.RIS.r1, ovl.fmt.RIS.m3,
13427 ovl.fmt.RIS.b4, ovl.fmt.RIS.d4,
13428 ovl.fmt.RIS.i2); goto ok;
13429 case 0xed0000000004ULL: s390_format_RXE_FRRD(s390_irgen_LDEB, ovl.fmt.RXE.r1,
13430 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
13431 ovl.fmt.RXE.d2); goto ok;
13432 case 0xed0000000005ULL: s390_format_RXE_FRRD(s390_irgen_LXDB, ovl.fmt.RXE.r1,
13433 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
13434 ovl.fmt.RXE.d2); goto ok;
13435 case 0xed0000000006ULL: s390_format_RXE_FRRD(s390_irgen_LXEB, ovl.fmt.RXE.r1,
13436 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
13437 ovl.fmt.RXE.d2); goto ok;
13438 case 0xed0000000007ULL: /* MXDB */ goto unimplemented;
13439 case 0xed0000000008ULL: /* KEB */ goto unimplemented;
13440 case 0xed0000000009ULL: s390_format_RXE_FRRD(s390_irgen_CEB, ovl.fmt.RXE.r1,
13441 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
13442 ovl.fmt.RXE.d2); goto ok;
13443 case 0xed000000000aULL: s390_format_RXE_FRRD(s390_irgen_AEB, ovl.fmt.RXE.r1,
13444 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
13445 ovl.fmt.RXE.d2); goto ok;
13446 case 0xed000000000bULL: s390_format_RXE_FRRD(s390_irgen_SEB, ovl.fmt.RXE.r1,
13447 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
13448 ovl.fmt.RXE.d2); goto ok;
13449 case 0xed000000000cULL: /* MDEB */ goto unimplemented;
13450 case 0xed000000000dULL: s390_format_RXE_FRRD(s390_irgen_DEB, ovl.fmt.RXE.r1,
13451 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
13452 ovl.fmt.RXE.d2); goto ok;
13453 case 0xed000000000eULL: s390_format_RXF_FRRDF(s390_irgen_MAEB,
13454 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
13455 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
13456 ovl.fmt.RXF.r1); goto ok;
13457 case 0xed000000000fULL: s390_format_RXF_FRRDF(s390_irgen_MSEB,
13458 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
13459 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
13460 ovl.fmt.RXF.r1); goto ok;
13461 case 0xed0000000010ULL: s390_format_RXE_FRRD(s390_irgen_TCEB, ovl.fmt.RXE.r1,
13462 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
13463 ovl.fmt.RXE.d2); goto ok;
13464 case 0xed0000000011ULL: s390_format_RXE_FRRD(s390_irgen_TCDB, ovl.fmt.RXE.r1,
13465 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
13466 ovl.fmt.RXE.d2); goto ok;
13467 case 0xed0000000012ULL: s390_format_RXE_FRRD(s390_irgen_TCXB, ovl.fmt.RXE.r1,
13468 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
13469 ovl.fmt.RXE.d2); goto ok;
13470 case 0xed0000000014ULL: s390_format_RXE_FRRD(s390_irgen_SQEB, ovl.fmt.RXE.r1,
13471 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
13472 ovl.fmt.RXE.d2); goto ok;
13473 case 0xed0000000015ULL: s390_format_RXE_FRRD(s390_irgen_SQDB, ovl.fmt.RXE.r1,
13474 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
13475 ovl.fmt.RXE.d2); goto ok;
13476 case 0xed0000000017ULL: s390_format_RXE_FRRD(s390_irgen_MEEB, ovl.fmt.RXE.r1,
13477 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
13478 ovl.fmt.RXE.d2); goto ok;
13479 case 0xed0000000018ULL: /* KDB */ goto unimplemented;
13480 case 0xed0000000019ULL: s390_format_RXE_FRRD(s390_irgen_CDB, ovl.fmt.RXE.r1,
13481 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
13482 ovl.fmt.RXE.d2); goto ok;
13483 case 0xed000000001aULL: s390_format_RXE_FRRD(s390_irgen_ADB, ovl.fmt.RXE.r1,
13484 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
13485 ovl.fmt.RXE.d2); goto ok;
13486 case 0xed000000001bULL: s390_format_RXE_FRRD(s390_irgen_SDB, ovl.fmt.RXE.r1,
13487 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
13488 ovl.fmt.RXE.d2); goto ok;
13489 case 0xed000000001cULL: s390_format_RXE_FRRD(s390_irgen_MDB, ovl.fmt.RXE.r1,
13490 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
13491 ovl.fmt.RXE.d2); goto ok;
13492 case 0xed000000001dULL: s390_format_RXE_FRRD(s390_irgen_DDB, ovl.fmt.RXE.r1,
13493 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
13494 ovl.fmt.RXE.d2); goto ok;
13495 case 0xed000000001eULL: s390_format_RXF_FRRDF(s390_irgen_MADB,
13496 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
13497 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
13498 ovl.fmt.RXF.r1); goto ok;
13499 case 0xed000000001fULL: s390_format_RXF_FRRDF(s390_irgen_MSDB,
13500 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
13501 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
13502 ovl.fmt.RXF.r1); goto ok;
13503 case 0xed0000000024ULL: /* LDE */ goto unimplemented;
13504 case 0xed0000000025ULL: /* LXD */ goto unimplemented;
13505 case 0xed0000000026ULL: /* LXE */ goto unimplemented;
13506 case 0xed000000002eULL: /* MAE */ goto unimplemented;
13507 case 0xed000000002fULL: /* MSE */ goto unimplemented;
13508 case 0xed0000000034ULL: /* SQE */ goto unimplemented;
13509 case 0xed0000000035ULL: /* SQD */ goto unimplemented;
13510 case 0xed0000000037ULL: /* MEE */ goto unimplemented;
13511 case 0xed0000000038ULL: /* MAYL */ goto unimplemented;
13512 case 0xed0000000039ULL: /* MYL */ goto unimplemented;
13513 case 0xed000000003aULL: /* MAY */ goto unimplemented;
13514 case 0xed000000003bULL: /* MY */ goto unimplemented;
13515 case 0xed000000003cULL: /* MAYH */ goto unimplemented;
13516 case 0xed000000003dULL: /* MYH */ goto unimplemented;
13517 case 0xed000000003eULL: /* MAD */ goto unimplemented;
13518 case 0xed000000003fULL: /* MSD */ goto unimplemented;
13519 case 0xed0000000040ULL: /* SLDT */ goto unimplemented;
13520 case 0xed0000000041ULL: /* SRDT */ goto unimplemented;
13521 case 0xed0000000048ULL: /* SLXT */ goto unimplemented;
13522 case 0xed0000000049ULL: /* SRXT */ goto unimplemented;
13523 case 0xed0000000050ULL: /* TDCET */ goto unimplemented;
13524 case 0xed0000000051ULL: /* TDGET */ goto unimplemented;
13525 case 0xed0000000054ULL: /* TDCDT */ goto unimplemented;
13526 case 0xed0000000055ULL: /* TDGDT */ goto unimplemented;
13527 case 0xed0000000058ULL: /* TDCXT */ goto unimplemented;
13528 case 0xed0000000059ULL: /* TDGXT */ goto unimplemented;
13529 case 0xed0000000064ULL: s390_format_RXY_FRRD(s390_irgen_LEY, ovl.fmt.RXY.r1,
13530 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13531 ovl.fmt.RXY.dl2,
13532 ovl.fmt.RXY.dh2); goto ok;
13533 case 0xed0000000065ULL: s390_format_RXY_FRRD(s390_irgen_LDY, ovl.fmt.RXY.r1,
13534 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13535 ovl.fmt.RXY.dl2,
13536 ovl.fmt.RXY.dh2); goto ok;
13537 case 0xed0000000066ULL: s390_format_RXY_FRRD(s390_irgen_STEY, ovl.fmt.RXY.r1,
13538 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13539 ovl.fmt.RXY.dl2,
13540 ovl.fmt.RXY.dh2); goto ok;
13541 case 0xed0000000067ULL: s390_format_RXY_FRRD(s390_irgen_STDY, ovl.fmt.RXY.r1,
13542 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13543 ovl.fmt.RXY.dl2,
13544 ovl.fmt.RXY.dh2); goto ok;
13545 }
13546
13547 switch (((ovl.value >> 16) & 0xff0f00000000ULL) >> 32) {
13548 case 0xc000ULL: s390_format_RIL_RP(s390_irgen_LARL, ovl.fmt.RIL.r1,
13549 ovl.fmt.RIL.i2); goto ok;
13550 case 0xc001ULL: s390_format_RIL_RI(s390_irgen_LGFI, ovl.fmt.RIL.r1,
13551 ovl.fmt.RIL.i2); goto ok;
13552 case 0xc004ULL: s390_format_RIL(s390_irgen_BRCL, ovl.fmt.RIL.r1,
13553 ovl.fmt.RIL.i2); goto ok;
13554 case 0xc005ULL: s390_format_RIL_RP(s390_irgen_BRASL, ovl.fmt.RIL.r1,
13555 ovl.fmt.RIL.i2); goto ok;
13556 case 0xc006ULL: s390_format_RIL_RU(s390_irgen_XIHF, ovl.fmt.RIL.r1,
13557 ovl.fmt.RIL.i2); goto ok;
13558 case 0xc007ULL: s390_format_RIL_RU(s390_irgen_XILF, ovl.fmt.RIL.r1,
13559 ovl.fmt.RIL.i2); goto ok;
13560 case 0xc008ULL: s390_format_RIL_RU(s390_irgen_IIHF, ovl.fmt.RIL.r1,
13561 ovl.fmt.RIL.i2); goto ok;
13562 case 0xc009ULL: s390_format_RIL_RU(s390_irgen_IILF, ovl.fmt.RIL.r1,
13563 ovl.fmt.RIL.i2); goto ok;
13564 case 0xc00aULL: s390_format_RIL_RU(s390_irgen_NIHF, ovl.fmt.RIL.r1,
13565 ovl.fmt.RIL.i2); goto ok;
13566 case 0xc00bULL: s390_format_RIL_RU(s390_irgen_NILF, ovl.fmt.RIL.r1,
13567 ovl.fmt.RIL.i2); goto ok;
13568 case 0xc00cULL: s390_format_RIL_RU(s390_irgen_OIHF, ovl.fmt.RIL.r1,
13569 ovl.fmt.RIL.i2); goto ok;
13570 case 0xc00dULL: s390_format_RIL_RU(s390_irgen_OILF, ovl.fmt.RIL.r1,
13571 ovl.fmt.RIL.i2); goto ok;
13572 case 0xc00eULL: s390_format_RIL_RU(s390_irgen_LLIHF, ovl.fmt.RIL.r1,
13573 ovl.fmt.RIL.i2); goto ok;
13574 case 0xc00fULL: s390_format_RIL_RU(s390_irgen_LLILF, ovl.fmt.RIL.r1,
13575 ovl.fmt.RIL.i2); goto ok;
13576 case 0xc200ULL: s390_format_RIL_RI(s390_irgen_MSGFI, ovl.fmt.RIL.r1,
13577 ovl.fmt.RIL.i2); goto ok;
13578 case 0xc201ULL: s390_format_RIL_RI(s390_irgen_MSFI, ovl.fmt.RIL.r1,
13579 ovl.fmt.RIL.i2); goto ok;
13580 case 0xc204ULL: s390_format_RIL_RU(s390_irgen_SLGFI, ovl.fmt.RIL.r1,
13581 ovl.fmt.RIL.i2); goto ok;
13582 case 0xc205ULL: s390_format_RIL_RU(s390_irgen_SLFI, ovl.fmt.RIL.r1,
13583 ovl.fmt.RIL.i2); goto ok;
13584 case 0xc208ULL: s390_format_RIL_RI(s390_irgen_AGFI, ovl.fmt.RIL.r1,
13585 ovl.fmt.RIL.i2); goto ok;
13586 case 0xc209ULL: s390_format_RIL_RI(s390_irgen_AFI, ovl.fmt.RIL.r1,
13587 ovl.fmt.RIL.i2); goto ok;
13588 case 0xc20aULL: s390_format_RIL_RU(s390_irgen_ALGFI, ovl.fmt.RIL.r1,
13589 ovl.fmt.RIL.i2); goto ok;
13590 case 0xc20bULL: s390_format_RIL_RU(s390_irgen_ALFI, ovl.fmt.RIL.r1,
13591 ovl.fmt.RIL.i2); goto ok;
13592 case 0xc20cULL: s390_format_RIL_RI(s390_irgen_CGFI, ovl.fmt.RIL.r1,
13593 ovl.fmt.RIL.i2); goto ok;
13594 case 0xc20dULL: s390_format_RIL_RI(s390_irgen_CFI, ovl.fmt.RIL.r1,
13595 ovl.fmt.RIL.i2); goto ok;
13596 case 0xc20eULL: s390_format_RIL_RU(s390_irgen_CLGFI, ovl.fmt.RIL.r1,
13597 ovl.fmt.RIL.i2); goto ok;
13598 case 0xc20fULL: s390_format_RIL_RU(s390_irgen_CLFI, ovl.fmt.RIL.r1,
13599 ovl.fmt.RIL.i2); goto ok;
13600 case 0xc402ULL: s390_format_RIL_RP(s390_irgen_LLHRL, ovl.fmt.RIL.r1,
13601 ovl.fmt.RIL.i2); goto ok;
13602 case 0xc404ULL: s390_format_RIL_RP(s390_irgen_LGHRL, ovl.fmt.RIL.r1,
13603 ovl.fmt.RIL.i2); goto ok;
13604 case 0xc405ULL: s390_format_RIL_RP(s390_irgen_LHRL, ovl.fmt.RIL.r1,
13605 ovl.fmt.RIL.i2); goto ok;
13606 case 0xc406ULL: s390_format_RIL_RP(s390_irgen_LLGHRL, ovl.fmt.RIL.r1,
13607 ovl.fmt.RIL.i2); goto ok;
13608 case 0xc407ULL: s390_format_RIL_RP(s390_irgen_STHRL, ovl.fmt.RIL.r1,
13609 ovl.fmt.RIL.i2); goto ok;
13610 case 0xc408ULL: s390_format_RIL_RP(s390_irgen_LGRL, ovl.fmt.RIL.r1,
13611 ovl.fmt.RIL.i2); goto ok;
13612 case 0xc40bULL: s390_format_RIL_RP(s390_irgen_STGRL, ovl.fmt.RIL.r1,
13613 ovl.fmt.RIL.i2); goto ok;
13614 case 0xc40cULL: s390_format_RIL_RP(s390_irgen_LGFRL, ovl.fmt.RIL.r1,
13615 ovl.fmt.RIL.i2); goto ok;
13616 case 0xc40dULL: s390_format_RIL_RP(s390_irgen_LRL, ovl.fmt.RIL.r1,
13617 ovl.fmt.RIL.i2); goto ok;
13618 case 0xc40eULL: s390_format_RIL_RP(s390_irgen_LLGFRL, ovl.fmt.RIL.r1,
13619 ovl.fmt.RIL.i2); goto ok;
13620 case 0xc40fULL: s390_format_RIL_RP(s390_irgen_STRL, ovl.fmt.RIL.r1,
13621 ovl.fmt.RIL.i2); goto ok;
13622 case 0xc600ULL: s390_format_RIL_RP(s390_irgen_EXRL, ovl.fmt.RIL.r1,
13623 ovl.fmt.RIL.i2); goto ok;
13624 case 0xc602ULL: s390_format_RIL_UP(s390_irgen_PFDRL, ovl.fmt.RIL.r1,
13625 ovl.fmt.RIL.i2); goto ok;
13626 case 0xc604ULL: s390_format_RIL_RP(s390_irgen_CGHRL, ovl.fmt.RIL.r1,
13627 ovl.fmt.RIL.i2); goto ok;
13628 case 0xc605ULL: s390_format_RIL_RP(s390_irgen_CHRL, ovl.fmt.RIL.r1,
13629 ovl.fmt.RIL.i2); goto ok;
13630 case 0xc606ULL: s390_format_RIL_RP(s390_irgen_CLGHRL, ovl.fmt.RIL.r1,
13631 ovl.fmt.RIL.i2); goto ok;
13632 case 0xc607ULL: s390_format_RIL_RP(s390_irgen_CLHRL, ovl.fmt.RIL.r1,
13633 ovl.fmt.RIL.i2); goto ok;
13634 case 0xc608ULL: s390_format_RIL_RP(s390_irgen_CGRL, ovl.fmt.RIL.r1,
13635 ovl.fmt.RIL.i2); goto ok;
13636 case 0xc60aULL: s390_format_RIL_RP(s390_irgen_CLGRL, ovl.fmt.RIL.r1,
13637 ovl.fmt.RIL.i2); goto ok;
13638 case 0xc60cULL: s390_format_RIL_RP(s390_irgen_CGFRL, ovl.fmt.RIL.r1,
13639 ovl.fmt.RIL.i2); goto ok;
13640 case 0xc60dULL: s390_format_RIL_RP(s390_irgen_CRL, ovl.fmt.RIL.r1,
13641 ovl.fmt.RIL.i2); goto ok;
13642 case 0xc60eULL: s390_format_RIL_RP(s390_irgen_CLGFRL, ovl.fmt.RIL.r1,
13643 ovl.fmt.RIL.i2); goto ok;
13644 case 0xc60fULL: s390_format_RIL_RP(s390_irgen_CLRL, ovl.fmt.RIL.r1,
13645 ovl.fmt.RIL.i2); goto ok;
13646 case 0xc800ULL: /* MVCOS */ goto unimplemented;
13647 case 0xc801ULL: /* ECTG */ goto unimplemented;
13648 case 0xc802ULL: /* CSST */ goto unimplemented;
13649 case 0xc804ULL: /* LPD */ goto unimplemented;
13650 case 0xc805ULL: /* LPDG */ goto unimplemented;
13651 case 0xcc06ULL: /* BRCTH */ goto unimplemented;
13652 case 0xcc08ULL: s390_format_RIL_RI(s390_irgen_AIH, ovl.fmt.RIL.r1,
13653 ovl.fmt.RIL.i2); goto ok;
13654 case 0xcc0aULL: s390_format_RIL_RI(s390_irgen_ALSIH, ovl.fmt.RIL.r1,
13655 ovl.fmt.RIL.i2); goto ok;
13656 case 0xcc0bULL: s390_format_RIL_RI(s390_irgen_ALSIHN, ovl.fmt.RIL.r1,
13657 ovl.fmt.RIL.i2); goto ok;
13658 case 0xcc0dULL: s390_format_RIL_RI(s390_irgen_CIH, ovl.fmt.RIL.r1,
13659 ovl.fmt.RIL.i2); goto ok;
13660 case 0xcc0fULL: s390_format_RIL_RU(s390_irgen_CLIH, ovl.fmt.RIL.r1,
13661 ovl.fmt.RIL.i2); goto ok;
13662 }
13663
13664 switch (((ovl.value >> 16) & 0xff0000000000ULL) >> 40) {
13665 case 0xd0ULL: /* TRTR */ goto unimplemented;
13666 case 0xd1ULL: /* MVN */ goto unimplemented;
13667 case 0xd2ULL: s390_format_SS_L0RDRD(s390_irgen_MVC, ovl.fmt.SS.l,
13668 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
13669 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
13670 case 0xd3ULL: /* MVZ */ goto unimplemented;
13671 case 0xd4ULL: s390_format_SS_L0RDRD(s390_irgen_NC, ovl.fmt.SS.l,
13672 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
13673 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
13674 case 0xd5ULL: s390_format_SS_L0RDRD(s390_irgen_CLC, ovl.fmt.SS.l,
13675 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
13676 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
13677 case 0xd6ULL: s390_format_SS_L0RDRD(s390_irgen_OC, ovl.fmt.SS.l,
13678 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
13679 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
sewardjb63967e2011-03-24 08:50:04 +000013680 case 0xd7ULL:
13681 if (ovl.fmt.SS.b1 == ovl.fmt.SS.b2 && ovl.fmt.SS.d1 == ovl.fmt.SS.d2)
13682 s390_irgen_XC_sameloc(ovl.fmt.SS.l, ovl.fmt.SS.b1, ovl.fmt.SS.d1);
13683 else
13684 s390_format_SS_L0RDRD(s390_irgen_XC, ovl.fmt.SS.l,
13685 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
13686 ovl.fmt.SS.b2, ovl.fmt.SS.d2);
13687 goto ok;
sewardj2019a972011-03-07 16:04:07 +000013688 case 0xd9ULL: /* MVCK */ goto unimplemented;
13689 case 0xdaULL: /* MVCP */ goto unimplemented;
13690 case 0xdbULL: /* MVCS */ goto unimplemented;
florian730448f2012-02-04 17:07:07 +000013691 case 0xdcULL: s390_format_SS_L0RDRD(s390_irgen_TR, ovl.fmt.SS.l,
13692 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
13693 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013694 case 0xddULL: /* TRT */ goto unimplemented;
13695 case 0xdeULL: /* ED */ goto unimplemented;
13696 case 0xdfULL: /* EDMK */ goto unimplemented;
13697 case 0xe1ULL: /* PKU */ goto unimplemented;
13698 case 0xe2ULL: /* UNPKU */ goto unimplemented;
13699 case 0xe8ULL: /* MVCIN */ goto unimplemented;
13700 case 0xe9ULL: /* PKA */ goto unimplemented;
13701 case 0xeaULL: /* UNPKA */ goto unimplemented;
13702 case 0xeeULL: /* PLO */ goto unimplemented;
13703 case 0xefULL: /* LMD */ goto unimplemented;
13704 case 0xf0ULL: /* SRP */ goto unimplemented;
13705 case 0xf1ULL: /* MVO */ goto unimplemented;
13706 case 0xf2ULL: /* PACK */ goto unimplemented;
13707 case 0xf3ULL: /* UNPK */ goto unimplemented;
13708 case 0xf8ULL: /* ZAP */ goto unimplemented;
13709 case 0xf9ULL: /* CP */ goto unimplemented;
13710 case 0xfaULL: /* AP */ goto unimplemented;
13711 case 0xfbULL: /* SP */ goto unimplemented;
13712 case 0xfcULL: /* MP */ goto unimplemented;
13713 case 0xfdULL: /* DP */ goto unimplemented;
13714 }
13715
13716 switch (((ovl.value >> 16) & 0xffff00000000ULL) >> 32) {
13717 case 0xe500ULL: /* LASP */ goto unimplemented;
13718 case 0xe501ULL: /* TPROT */ goto unimplemented;
13719 case 0xe502ULL: /* STRAG */ goto unimplemented;
13720 case 0xe50eULL: /* MVCSK */ goto unimplemented;
13721 case 0xe50fULL: /* MVCDK */ goto unimplemented;
13722 case 0xe544ULL: s390_format_SIL_RDI(s390_irgen_MVHHI, ovl.fmt.SIL.b1,
13723 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
13724 goto ok;
13725 case 0xe548ULL: s390_format_SIL_RDI(s390_irgen_MVGHI, ovl.fmt.SIL.b1,
13726 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
13727 goto ok;
13728 case 0xe54cULL: s390_format_SIL_RDI(s390_irgen_MVHI, ovl.fmt.SIL.b1,
13729 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
13730 goto ok;
13731 case 0xe554ULL: s390_format_SIL_RDI(s390_irgen_CHHSI, ovl.fmt.SIL.b1,
13732 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
13733 goto ok;
13734 case 0xe555ULL: s390_format_SIL_RDU(s390_irgen_CLHHSI, ovl.fmt.SIL.b1,
13735 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
13736 goto ok;
13737 case 0xe558ULL: s390_format_SIL_RDI(s390_irgen_CGHSI, ovl.fmt.SIL.b1,
13738 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
13739 goto ok;
13740 case 0xe559ULL: s390_format_SIL_RDU(s390_irgen_CLGHSI, ovl.fmt.SIL.b1,
13741 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
13742 goto ok;
13743 case 0xe55cULL: s390_format_SIL_RDI(s390_irgen_CHSI, ovl.fmt.SIL.b1,
13744 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
13745 goto ok;
13746 case 0xe55dULL: s390_format_SIL_RDU(s390_irgen_CLFHSI, ovl.fmt.SIL.b1,
13747 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
13748 goto ok;
13749 }
13750
13751 return S390_DECODE_UNKNOWN_INSN;
13752
13753ok:
13754 return S390_DECODE_OK;
13755
13756unimplemented:
13757 return S390_DECODE_UNIMPLEMENTED_INSN;
13758}
13759
13760/* Handle "special" instructions. */
13761static s390_decode_t
13762s390_decode_special_and_irgen(UChar *bytes)
13763{
13764 s390_decode_t status = S390_DECODE_OK;
13765
13766 /* Got a "Special" instruction preamble. Which one is it? */
13767 if (bytes[0] == 0x18 && bytes[1] == 0x22 /* lr %r2, %r2 */) {
13768 s390_irgen_client_request();
13769 } else if (bytes[0] == 0x18 && bytes[1] == 0x33 /* lr %r3, %r3 */) {
13770 s390_irgen_guest_NRADDR();
13771 } else if (bytes[0] == 0x18 && bytes[1] == 0x44 /* lr %r4, %r4 */) {
13772 s390_irgen_call_noredir();
13773 } else {
13774 /* We don't know what it is. */
13775 return S390_DECODE_UNKNOWN_SPECIAL_INSN;
13776 }
13777
13778 dis_res->len = S390_SPECIAL_OP_PREAMBLE_SIZE + S390_SPECIAL_OP_SIZE;
13779
13780 return status;
13781}
13782
13783
13784/* Function returns # bytes that were decoded or 0 in case of failure */
florianb4df7682011-07-05 02:09:01 +000013785static UInt
sewardj2019a972011-03-07 16:04:07 +000013786s390_decode_and_irgen(UChar *bytes, UInt insn_length, DisResult *dres)
13787{
13788 s390_decode_t status;
13789
13790 dis_res = dres;
13791
13792 /* Spot the 8-byte preamble: 18ff lr r15,r15
13793 1811 lr r1,r1
13794 1822 lr r2,r2
13795 1833 lr r3,r3 */
13796 if (bytes[ 0] == 0x18 && bytes[ 1] == 0xff && bytes[ 2] == 0x18 &&
13797 bytes[ 3] == 0x11 && bytes[ 4] == 0x18 && bytes[ 5] == 0x22 &&
13798 bytes[ 6] == 0x18 && bytes[ 7] == 0x33) {
13799
13800 /* Handle special instruction that follows that preamble. */
13801 if (0) vex_printf("special function handling...\n");
florian2c8ed942011-08-01 22:07:51 +000013802
13803 insn_length = S390_SPECIAL_OP_PREAMBLE_SIZE + S390_SPECIAL_OP_SIZE;
13804 guest_IA_next_instr = guest_IA_curr_instr + insn_length;
13805
13806 status =
13807 s390_decode_special_and_irgen(bytes + S390_SPECIAL_OP_PREAMBLE_SIZE);
sewardj2019a972011-03-07 16:04:07 +000013808 } else {
13809 /* Handle normal instructions. */
13810 switch (insn_length) {
13811 case 2:
13812 status = s390_decode_2byte_and_irgen(bytes);
13813 break;
13814
13815 case 4:
13816 status = s390_decode_4byte_and_irgen(bytes);
13817 break;
13818
13819 case 6:
13820 status = s390_decode_6byte_and_irgen(bytes);
13821 break;
13822
13823 default:
13824 status = S390_DECODE_ERROR;
13825 break;
13826 }
13827 }
florian5fcbba22011-07-27 20:40:22 +000013828 /* If next instruction is execute, stop here */
florianf9e1ed72012-04-17 02:41:56 +000013829 if (dis_res->whatNext == Dis_Continue && bytes[insn_length] == 0x44) {
13830 put_IA(mkaddr_expr(guest_IA_next_instr));
sewardj2019a972011-03-07 16:04:07 +000013831 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +000013832 dis_res->jk_StopHere = Ijk_Boring;
sewardj2019a972011-03-07 16:04:07 +000013833 }
13834
13835 if (status == S390_DECODE_OK) return insn_length; /* OK */
13836
13837 /* Decoding failed somehow */
13838 vex_printf("vex s390->IR: ");
13839 switch (status) {
13840 case S390_DECODE_UNKNOWN_INSN:
13841 vex_printf("unknown insn: ");
13842 break;
13843
13844 case S390_DECODE_UNIMPLEMENTED_INSN:
13845 vex_printf("unimplemented insn: ");
13846 break;
13847
13848 case S390_DECODE_UNKNOWN_SPECIAL_INSN:
13849 vex_printf("unimplemented special insn: ");
13850 break;
13851
13852 default:
13853 case S390_DECODE_ERROR:
13854 vex_printf("decoding error: ");
13855 break;
13856 }
13857
13858 vex_printf("%02x%02x", bytes[0], bytes[1]);
13859 if (insn_length > 2) {
13860 vex_printf(" %02x%02x", bytes[2], bytes[3]);
13861 }
13862 if (insn_length > 4) {
13863 vex_printf(" %02x%02x", bytes[4], bytes[5]);
13864 }
13865 vex_printf("\n");
13866
13867 return 0; /* Failed */
13868}
13869
13870
sewardj2019a972011-03-07 16:04:07 +000013871/* Disassemble a single instruction INSN into IR. */
13872static DisResult
florian420c5012011-07-22 02:12:28 +000013873disInstr_S390_WRK(UChar *insn)
sewardj2019a972011-03-07 16:04:07 +000013874{
13875 UChar byte;
13876 UInt insn_length;
13877 DisResult dres;
13878
13879 /* ---------------------------------------------------- */
13880 /* --- Compute instruction length -- */
13881 /* ---------------------------------------------------- */
13882
13883 /* Get the first byte of the insn. */
13884 byte = insn[0];
13885
13886 /* The leftmost two bits (0:1) encode the length of the insn in bytes.
13887 00 -> 2 bytes, 01 -> 4 bytes, 10 -> 4 bytes, 11 -> 6 bytes. */
13888 insn_length = ((((byte >> 6) + 1) >> 1) + 1) << 1;
13889
13890 guest_IA_next_instr = guest_IA_curr_instr + insn_length;
13891
13892 /* ---------------------------------------------------- */
13893 /* --- Initialise the DisResult data -- */
13894 /* ---------------------------------------------------- */
13895 dres.whatNext = Dis_Continue;
13896 dres.len = insn_length;
13897 dres.continueAt = 0;
florian8844a632012-04-13 04:04:06 +000013898 dres.jk_StopHere = Ijk_INVALID;
sewardj2019a972011-03-07 16:04:07 +000013899
floriana99f20e2011-07-17 14:16:41 +000013900 /* fixs390: consider chasing of conditional jumps */
13901
sewardj2019a972011-03-07 16:04:07 +000013902 /* Normal and special instruction handling starts here. */
13903 if (s390_decode_and_irgen(insn, insn_length, &dres) == 0) {
13904 /* All decode failures end up here. The decoder has already issued an
13905 error message.
13906 Tell the dispatcher that this insn cannot be decoded, and so has
florian342e01a2012-07-26 02:37:49 +000013907 not been executed, and (is currently) the next to be executed.
13908 The insn address in the guest state needs to be set to
13909 guest_IA_curr_instr, otherwise the complaint will report an
13910 incorrect address. */
13911 put_IA(mkaddr_expr(guest_IA_curr_instr));
sewardj2019a972011-03-07 16:04:07 +000013912
florian8844a632012-04-13 04:04:06 +000013913 dres.whatNext = Dis_StopHere;
13914 dres.jk_StopHere = Ijk_NoDecode;
13915 dres.continueAt = 0;
13916 dres.len = 0;
13917 } else {
13918 /* Decode success */
13919 switch (dres.whatNext) {
13920 case Dis_Continue:
florian8559e412012-04-19 14:23:48 +000013921 put_IA(mkaddr_expr(guest_IA_next_instr));
florian8844a632012-04-13 04:04:06 +000013922 break;
13923 case Dis_ResteerU:
13924 case Dis_ResteerC:
13925 put_IA(mkaddr_expr(dres.continueAt));
13926 break;
13927 case Dis_StopHere:
13928 break;
13929 default:
13930 vassert(0);
13931 }
sewardj2019a972011-03-07 16:04:07 +000013932 }
13933
13934 return dres;
13935}
13936
13937
13938/*------------------------------------------------------------*/
13939/*--- Top-level fn ---*/
13940/*------------------------------------------------------------*/
13941
13942/* Disassemble a single instruction into IR. The instruction
13943 is located in host memory at &guest_code[delta]. */
13944
13945DisResult
13946disInstr_S390(IRSB *irsb_IN,
sewardj2019a972011-03-07 16:04:07 +000013947 Bool (*resteerOkFn)(void *, Addr64),
13948 Bool resteerCisOk,
13949 void *callback_opaque,
13950 UChar *guest_code,
13951 Long delta,
13952 Addr64 guest_IP,
13953 VexArch guest_arch,
13954 VexArchInfo *archinfo,
13955 VexAbiInfo *abiinfo,
13956 Bool host_bigendian)
13957{
13958 vassert(guest_arch == VexArchS390X);
13959
13960 /* The instruction decoder requires a big-endian machine. */
13961 vassert(host_bigendian == True);
13962
13963 /* Set globals (see top of this file) */
13964 guest_IA_curr_instr = guest_IP;
sewardj2019a972011-03-07 16:04:07 +000013965 irsb = irsb_IN;
florian420c5012011-07-22 02:12:28 +000013966 resteer_fn = resteerOkFn;
13967 resteer_data = callback_opaque;
sewardj2019a972011-03-07 16:04:07 +000013968
florian420c5012011-07-22 02:12:28 +000013969 return disInstr_S390_WRK(guest_code + delta);
sewardj2019a972011-03-07 16:04:07 +000013970}
13971
13972/*---------------------------------------------------------------*/
13973/*--- end guest_s390_toIR.c ---*/
13974/*---------------------------------------------------------------*/