blob: 3612f0567109322808d3b383356140db8cf32ba3 [file] [log] [blame]
sewardj2019a972011-03-07 16:04:07 +00001/* -*- mode: C; c-basic-offset: 3; -*- */
2
3/*---------------------------------------------------------------*/
4/*--- begin guest_s390_toIR.c ---*/
5/*---------------------------------------------------------------*/
6
7/*
8 This file is part of Valgrind, a dynamic binary instrumentation
9 framework.
10
florian61f23c12012-08-06 18:33:21 +000011 Copyright IBM Corp. 2010-2012
sewardj2019a972011-03-07 16:04:07 +000012
13 This program is free software; you can redistribute it and/or
14 modify it under the terms of the GNU General Public License as
15 published by the Free Software Foundation; either version 2 of the
16 License, or (at your option) any later version.
17
18 This program is distributed in the hope that it will be useful, but
19 WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 General Public License for more details.
22
23 You should have received a copy of the GNU General Public License
24 along with this program; if not, write to the Free Software
25 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
26 02110-1301, USA.
27
28 The GNU General Public License is contained in the file COPYING.
29*/
30
31/* Contributed by Florian Krohm and Christian Borntraeger */
32
33/* Translates s390 code to IR. */
34
35#include "libvex_basictypes.h"
36#include "libvex_ir.h"
sewardj2019a972011-03-07 16:04:07 +000037#include "libvex.h" /* needed for bb_to_IR.h */
florian933065d2011-07-11 01:48:02 +000038#include "libvex_s390x_common.h"
sewardj2019a972011-03-07 16:04:07 +000039#include "main_util.h" /* vassert */
40#include "main_globals.h" /* vex_traceflags */
41#include "guest_generic_bb_to_IR.h" /* DisResult */
42#include "guest_s390_defs.h" /* prototypes for this file's functions */
43#include "host_s390_disasm.h"
44#include "host_s390_defs.h" /* S390_ROUND_xyzzy */
45
sewardj2019a972011-03-07 16:04:07 +000046
47/*------------------------------------------------------------*/
florianb4df7682011-07-05 02:09:01 +000048/*--- Forward declarations ---*/
49/*------------------------------------------------------------*/
50static UInt s390_decode_and_irgen(UChar *, UInt, DisResult *);
florianb0bf6602012-05-05 00:01:16 +000051static void s390_irgen_xonc(IROp, IRTemp, IRTemp, IRTemp);
florian79e839e2012-05-05 02:20:30 +000052static void s390_irgen_CLC_EX(IRTemp, IRTemp, IRTemp);
florianb4df7682011-07-05 02:09:01 +000053
54
55/*------------------------------------------------------------*/
sewardj2019a972011-03-07 16:04:07 +000056/*--- Globals ---*/
57/*------------------------------------------------------------*/
58
59/* The IRSB* into which we're generating code. */
60static IRSB *irsb;
61
62/* The guest address for the instruction currently being
63 translated. */
64static Addr64 guest_IA_curr_instr;
65
66/* The guest address for the instruction following the current instruction. */
67static Addr64 guest_IA_next_instr;
68
69/* Result of disassembly step. */
70static DisResult *dis_res;
71
floriana64c2432011-07-16 02:11:50 +000072/* Resteer function and callback data */
73static Bool (*resteer_fn)(void *, Addr64);
74static void *resteer_data;
75
sewardj2019a972011-03-07 16:04:07 +000076/* The last seen execute target instruction */
77ULong last_execute_target;
78
79/* The possible outcomes of a decoding operation */
80typedef enum {
81 S390_DECODE_OK,
82 S390_DECODE_UNKNOWN_INSN,
83 S390_DECODE_UNIMPLEMENTED_INSN,
84 S390_DECODE_UNKNOWN_SPECIAL_INSN,
85 S390_DECODE_ERROR
86} s390_decode_t;
87
florian428dfdd2012-03-27 03:09:49 +000088
sewardj2019a972011-03-07 16:04:07 +000089/*------------------------------------------------------------*/
90/*--- Helpers for constructing IR. ---*/
91/*------------------------------------------------------------*/
92
93/* Sign extend a value with the given number of bits. This is a
94 macro because it allows us to overload the type of the value.
95 Note that VALUE must have a signed type! */
96#undef sign_extend
97#define sign_extend(value,num_bits) \
98(((value) << (sizeof(__typeof__(value)) * 8 - (num_bits))) >> \
99 (sizeof(__typeof__(value)) * 8 - (num_bits)))
100
101
102/* Add a statement to the current irsb. */
103static __inline__ void
104stmt(IRStmt *st)
105{
106 addStmtToIRSB(irsb, st);
107}
108
109/* Allocate a new temporary of the given type. */
110static __inline__ IRTemp
111newTemp(IRType type)
112{
113 vassert(isPlausibleIRType(type));
114
115 return newIRTemp(irsb->tyenv, type);
116}
117
118/* Create an expression node for a temporary */
119static __inline__ IRExpr *
120mkexpr(IRTemp tmp)
121{
122 return IRExpr_RdTmp(tmp);
123}
124
florian8844a632012-04-13 04:04:06 +0000125/* Generate an expression node for an address. */
126static __inline__ IRExpr *
127mkaddr_expr(Addr64 addr)
128{
129 return IRExpr_Const(IRConst_U64(addr));
130}
131
sewardj2019a972011-03-07 16:04:07 +0000132/* Add a statement that assigns to a temporary */
133static __inline__ void
134assign(IRTemp dst, IRExpr *expr)
135{
136 stmt(IRStmt_WrTmp(dst, expr));
137}
138
florian8844a632012-04-13 04:04:06 +0000139/* Write an address into the guest_IA */
140static __inline__ void
141put_IA(IRExpr *address)
142{
143 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_IA), address));
144}
145
sewardj2019a972011-03-07 16:04:07 +0000146/* Create a temporary of the given type and assign the expression to it */
147static __inline__ IRTemp
148mktemp(IRType type, IRExpr *expr)
149{
150 IRTemp temp = newTemp(type);
151
152 assign(temp, expr);
153
154 return temp;
155}
156
157/* Create a unary expression */
158static __inline__ IRExpr *
159unop(IROp kind, IRExpr *op)
160{
161 return IRExpr_Unop(kind, op);
162}
163
164/* Create a binary expression */
165static __inline__ IRExpr *
166binop(IROp kind, IRExpr *op1, IRExpr *op2)
167{
168 return IRExpr_Binop(kind, op1, op2);
169}
170
171/* Create a ternary expression */
172static __inline__ IRExpr *
173triop(IROp kind, IRExpr *op1, IRExpr *op2, IRExpr *op3)
174{
175 return IRExpr_Triop(kind, op1, op2, op3);
176}
177
178/* Create a quaternary expression */
179static __inline__ IRExpr *
180qop(IROp kind, IRExpr *op1, IRExpr *op2, IRExpr *op3, IRExpr *op4)
181{
182 return IRExpr_Qop(kind, op1, op2, op3, op4);
183}
184
185/* Create an expression node for an 8-bit integer constant */
186static __inline__ IRExpr *
187mkU8(UInt value)
188{
189 vassert(value < 256);
190
191 return IRExpr_Const(IRConst_U8((UChar)value));
192}
193
194/* Create an expression node for a 16-bit integer constant */
195static __inline__ IRExpr *
196mkU16(UInt value)
197{
198 vassert(value < 65536);
199
200 return IRExpr_Const(IRConst_U16((UShort)value));
201}
202
203/* Create an expression node for a 32-bit integer constant */
204static __inline__ IRExpr *
205mkU32(UInt value)
206{
207 return IRExpr_Const(IRConst_U32(value));
208}
209
210/* Create an expression node for a 64-bit integer constant */
211static __inline__ IRExpr *
212mkU64(ULong value)
213{
214 return IRExpr_Const(IRConst_U64(value));
215}
216
217/* Create an expression node for a 32-bit floating point constant
218 whose value is given by a bit pattern. */
219static __inline__ IRExpr *
220mkF32i(UInt value)
221{
222 return IRExpr_Const(IRConst_F32i(value));
223}
224
225/* Create an expression node for a 32-bit floating point constant
226 whose value is given by a bit pattern. */
227static __inline__ IRExpr *
228mkF64i(ULong value)
229{
230 return IRExpr_Const(IRConst_F64i(value));
231}
232
233/* Little helper function for my sanity. ITE = if-then-else */
234static IRExpr *
235mkite(IRExpr *condition, IRExpr *iftrue, IRExpr *iffalse)
236{
237 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
238
239 return IRExpr_Mux0X(unop(Iop_1Uto8, condition), iffalse, iftrue);
240}
241
242/* Add a statement that stores DATA at ADDR. This is a big-endian machine. */
243static void __inline__
244store(IRExpr *addr, IRExpr *data)
245{
246 stmt(IRStmt_Store(Iend_BE, addr, data));
247}
248
249/* Create an expression that loads a TYPE sized value from ADDR.
250 This is a big-endian machine. */
251static __inline__ IRExpr *
252load(IRType type, IRExpr *addr)
253{
254 return IRExpr_Load(Iend_BE, type, addr);
255}
256
257/* Function call */
258static void
259call_function(IRExpr *callee_address)
260{
florian8844a632012-04-13 04:04:06 +0000261 put_IA(callee_address);
sewardj2019a972011-03-07 16:04:07 +0000262
florian8844a632012-04-13 04:04:06 +0000263 dis_res->whatNext = Dis_StopHere;
264 dis_res->jk_StopHere = Ijk_Call;
sewardj2019a972011-03-07 16:04:07 +0000265}
266
floriana64c2432011-07-16 02:11:50 +0000267/* Function call with known target. */
268static void
269call_function_and_chase(Addr64 callee_address)
270{
271 if (resteer_fn(resteer_data, callee_address)) {
272 dis_res->whatNext = Dis_ResteerU;
273 dis_res->continueAt = callee_address;
274 } else {
florian8844a632012-04-13 04:04:06 +0000275 put_IA(mkaddr_expr(callee_address));
276
floriana64c2432011-07-16 02:11:50 +0000277 dis_res->whatNext = Dis_StopHere;
florian8844a632012-04-13 04:04:06 +0000278 dis_res->jk_StopHere = Ijk_Call;
floriana64c2432011-07-16 02:11:50 +0000279 }
280}
281
sewardj2019a972011-03-07 16:04:07 +0000282/* Function return sequence */
283static void
284return_from_function(IRExpr *return_address)
285{
florian8844a632012-04-13 04:04:06 +0000286 put_IA(return_address);
sewardj2019a972011-03-07 16:04:07 +0000287
florian8844a632012-04-13 04:04:06 +0000288 dis_res->whatNext = Dis_StopHere;
289 dis_res->jk_StopHere = Ijk_Ret;
sewardj2019a972011-03-07 16:04:07 +0000290}
291
292/* A conditional branch whose target is not known at instrumentation time.
293
294 if (condition) goto computed_target;
295
296 Needs to be represented as:
297
298 if (! condition) goto next_instruction;
299 goto computed_target;
sewardj2019a972011-03-07 16:04:07 +0000300*/
301static void
florianf321da72012-07-21 20:32:57 +0000302if_condition_goto_computed(IRExpr *condition, IRExpr *target)
sewardj2019a972011-03-07 16:04:07 +0000303{
304 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
305
florianf321da72012-07-21 20:32:57 +0000306 condition = unop(Iop_Not1, condition);
307
florian8844a632012-04-13 04:04:06 +0000308 stmt(IRStmt_Exit(condition, Ijk_Boring, IRConst_U64(guest_IA_next_instr),
309 S390X_GUEST_OFFSET(guest_IA)));
sewardj2019a972011-03-07 16:04:07 +0000310
florian8844a632012-04-13 04:04:06 +0000311 put_IA(target);
sewardj2019a972011-03-07 16:04:07 +0000312
florian8844a632012-04-13 04:04:06 +0000313 dis_res->whatNext = Dis_StopHere;
314 dis_res->jk_StopHere = Ijk_Boring;
sewardj2019a972011-03-07 16:04:07 +0000315}
316
317/* A conditional branch whose target is known at instrumentation time. */
318static void
319if_condition_goto(IRExpr *condition, Addr64 target)
320{
321 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
322
florian8844a632012-04-13 04:04:06 +0000323 stmt(IRStmt_Exit(condition, Ijk_Boring, IRConst_U64(target),
324 S390X_GUEST_OFFSET(guest_IA)));
325
florian7346c7a2012-04-13 21:14:24 +0000326 put_IA(mkaddr_expr(guest_IA_next_instr));
florian8844a632012-04-13 04:04:06 +0000327
328 dis_res->whatNext = Dis_StopHere;
329 dis_res->jk_StopHere = Ijk_Boring;
sewardj2019a972011-03-07 16:04:07 +0000330}
331
332/* An unconditional branch. Target may or may not be known at instrumentation
333 time. */
334static void
335always_goto(IRExpr *target)
336{
florian8844a632012-04-13 04:04:06 +0000337 put_IA(target);
sewardj2019a972011-03-07 16:04:07 +0000338
florian8844a632012-04-13 04:04:06 +0000339 dis_res->whatNext = Dis_StopHere;
340 dis_res->jk_StopHere = Ijk_Boring;
sewardj2019a972011-03-07 16:04:07 +0000341}
342
florian8844a632012-04-13 04:04:06 +0000343
floriana64c2432011-07-16 02:11:50 +0000344/* An unconditional branch to a known target. */
345static void
346always_goto_and_chase(Addr64 target)
347{
348 if (resteer_fn(resteer_data, target)) {
florian8844a632012-04-13 04:04:06 +0000349 /* Follow into the target */
floriana64c2432011-07-16 02:11:50 +0000350 dis_res->whatNext = Dis_ResteerU;
351 dis_res->continueAt = target;
352 } else {
florian8844a632012-04-13 04:04:06 +0000353 put_IA(mkaddr_expr(target));
354
355 dis_res->whatNext = Dis_StopHere;
356 dis_res->jk_StopHere = Ijk_Boring;
floriana64c2432011-07-16 02:11:50 +0000357 }
358}
359
sewardj2019a972011-03-07 16:04:07 +0000360/* A system call */
361static void
362system_call(IRExpr *sysno)
363{
364 /* Store the system call number in the pseudo register. */
florian428dfdd2012-03-27 03:09:49 +0000365 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_SYSNO), sysno));
sewardj2019a972011-03-07 16:04:07 +0000366
sewardj69007022011-04-28 20:13:45 +0000367 /* Store the current IA into guest_IP_AT_SYSCALL. libvex_ir.h says so. */
florian428dfdd2012-03-27 03:09:49 +0000368 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_IP_AT_SYSCALL),
369 mkU64(guest_IA_curr_instr)));
sewardj2019a972011-03-07 16:04:07 +0000370
florian8844a632012-04-13 04:04:06 +0000371 put_IA(mkaddr_expr(guest_IA_next_instr));
372
sewardj2019a972011-03-07 16:04:07 +0000373 /* It's important that all ArchRegs carry their up-to-date value
374 at this point. So we declare an end-of-block here, which
375 forces any TempRegs caching ArchRegs to be flushed. */
florian8844a632012-04-13 04:04:06 +0000376 dis_res->whatNext = Dis_StopHere;
377 dis_res->jk_StopHere = Ijk_Sys_syscall;
sewardj2019a972011-03-07 16:04:07 +0000378}
379
florian6820ba52012-07-26 02:01:50 +0000380/* A side exit that branches back to the current insn if CONDITION is
381 true. Does not set DisResult. */
382static void
383iterate_if(IRExpr *condition)
384{
385 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
386
387 stmt(IRStmt_Exit(condition, Ijk_Boring, IRConst_U64(guest_IA_curr_instr),
388 S390X_GUEST_OFFSET(guest_IA)));
389}
390
391/* A side exit that branches back to the current insn.
392 Does not set DisResult. */
393static __inline__ void
394iterate(void)
395{
396 iterate_if(IRExpr_Const(IRConst_U1(True)));
397}
398
399/* A side exit that branches back to the insn immediately following the
400 current insn if CONDITION is true. Does not set DisResult. */
401static void
402next_insn_if(IRExpr *condition)
403{
404 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
405
406 stmt(IRStmt_Exit(condition, Ijk_Boring, IRConst_U64(guest_IA_next_instr),
407 S390X_GUEST_OFFSET(guest_IA)));
408}
409
410/* Convenience function to restart the current insn */
411static void
412restart_if(IRExpr *condition)
413{
414 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
415
416 stmt(IRStmt_Exit(condition, Ijk_TInval, IRConst_U64(guest_IA_curr_instr),
417 S390X_GUEST_OFFSET(guest_IA)));
418}
419
420/* Convenience function to yield to thread scheduler */
421static void
422yield_if(IRExpr *condition)
423{
424 stmt(IRStmt_Exit(condition, Ijk_Yield, IRConst_U64(guest_IA_next_instr),
425 S390X_GUEST_OFFSET(guest_IA)));
426}
427
sewardj2019a972011-03-07 16:04:07 +0000428/* Encode the s390 rounding mode as it appears in the m3/m4 fields of certain
429 instructions to VEX's IRRoundingMode. */
430static IRRoundingMode
431encode_rounding_mode(UChar mode)
432{
433 switch (mode) {
434 case S390_ROUND_NEAREST_EVEN: return Irrm_NEAREST;
435 case S390_ROUND_ZERO: return Irrm_ZERO;
436 case S390_ROUND_POSINF: return Irrm_PosINF;
437 case S390_ROUND_NEGINF: return Irrm_NegINF;
438 }
439 vpanic("encode_rounding_mode");
440}
441
442static __inline__ IRExpr *get_fpr_dw0(UInt);
443static __inline__ void put_fpr_dw0(UInt, IRExpr *);
444
445/* Read a floating point register pair and combine their contents into a
446 128-bit value */
447static IRExpr *
448get_fpr_pair(UInt archreg)
449{
450 IRExpr *high = get_fpr_dw0(archreg);
451 IRExpr *low = get_fpr_dw0(archreg + 2);
452
453 return binop(Iop_F64HLtoF128, high, low);
454}
455
456/* Write a 128-bit floating point value into a register pair. */
457static void
458put_fpr_pair(UInt archreg, IRExpr *expr)
459{
460 IRExpr *high = unop(Iop_F128HItoF64, expr);
461 IRExpr *low = unop(Iop_F128LOtoF64, expr);
462
463 put_fpr_dw0(archreg, high);
464 put_fpr_dw0(archreg + 2, low);
465}
466
467
sewardj2019a972011-03-07 16:04:07 +0000468/*------------------------------------------------------------*/
florianf3410f92012-08-03 18:41:58 +0000469/*--- IR Debugging aids. ---*/
470/*------------------------------------------------------------*/
471#if 0
472
473static ULong
474s390_do_print(HChar *text, ULong value)
475{
476 vex_printf("%s %llu\n", text, value);
477 return 0;
478}
479
480static void
481s390_print(HChar *text, IRExpr *value)
482{
483 IRDirty *d;
484
485 d = unsafeIRDirty_0_N(0 /* regparms */, "s390_do_print", &s390_do_print,
486 mkIRExprVec_2(mkU64((ULong)text), value));
487 stmt(IRStmt_Dirty(d));
488}
489#endif
490
491
492/*------------------------------------------------------------*/
sewardj2019a972011-03-07 16:04:07 +0000493/*--- Build the flags thunk. ---*/
494/*------------------------------------------------------------*/
495
496/* Completely fill the flags thunk. We're always filling all fields.
497 Apparently, that is better for redundant PUT elimination. */
498static void
499s390_cc_thunk_fill(IRExpr *op, IRExpr *dep1, IRExpr *dep2, IRExpr *ndep)
500{
501 UInt op_off, dep1_off, dep2_off, ndep_off;
502
florian428dfdd2012-03-27 03:09:49 +0000503 op_off = S390X_GUEST_OFFSET(guest_CC_OP);
504 dep1_off = S390X_GUEST_OFFSET(guest_CC_DEP1);
505 dep2_off = S390X_GUEST_OFFSET(guest_CC_DEP2);
506 ndep_off = S390X_GUEST_OFFSET(guest_CC_NDEP);
sewardj2019a972011-03-07 16:04:07 +0000507
508 stmt(IRStmt_Put(op_off, op));
509 stmt(IRStmt_Put(dep1_off, dep1));
510 stmt(IRStmt_Put(dep2_off, dep2));
511 stmt(IRStmt_Put(ndep_off, ndep));
512}
513
514
515/* Create an expression for V and widen the result to 64 bit. */
516static IRExpr *
517s390_cc_widen(IRTemp v, Bool sign_extend)
518{
519 IRExpr *expr;
520
521 expr = mkexpr(v);
522
523 switch (typeOfIRTemp(irsb->tyenv, v)) {
524 case Ity_I64:
525 break;
526 case Ity_I32:
527 expr = unop(sign_extend ? Iop_32Sto64 : Iop_32Uto64, expr);
528 break;
529 case Ity_I16:
530 expr = unop(sign_extend ? Iop_16Sto64 : Iop_16Uto64, expr);
531 break;
532 case Ity_I8:
533 expr = unop(sign_extend ? Iop_8Sto64 : Iop_8Uto64, expr);
534 break;
535 default:
536 vpanic("s390_cc_widen");
537 }
538
539 return expr;
540}
541
542static void
543s390_cc_thunk_put1(UInt opc, IRTemp d1, Bool sign_extend)
544{
545 IRExpr *op, *dep1, *dep2, *ndep;
546
547 op = mkU64(opc);
548 dep1 = s390_cc_widen(d1, sign_extend);
549 dep2 = mkU64(0);
550 ndep = mkU64(0);
551
552 s390_cc_thunk_fill(op, dep1, dep2, ndep);
553}
554
555
556static void
557s390_cc_thunk_put2(UInt opc, IRTemp d1, IRTemp d2, Bool sign_extend)
558{
559 IRExpr *op, *dep1, *dep2, *ndep;
560
561 op = mkU64(opc);
562 dep1 = s390_cc_widen(d1, sign_extend);
563 dep2 = s390_cc_widen(d2, sign_extend);
564 ndep = mkU64(0);
565
566 s390_cc_thunk_fill(op, dep1, dep2, ndep);
567}
568
569
570/* memcheck believes that the NDEP field in the flags thunk is always
571 defined. But for some flag computations (e.g. add with carry) that is
572 just not true. We therefore need to convey to memcheck that the value
573 of the ndep field does matter and therefore we make the DEP2 field
574 depend on it:
575
576 DEP2 = original_DEP2 ^ NDEP
577
578 In s390_calculate_cc we exploit that (a^b)^b == a
579 I.e. we xor the DEP2 value with the NDEP value to recover the
580 original_DEP2 value. */
581static void
582s390_cc_thunk_put3(UInt opc, IRTemp d1, IRTemp d2, IRTemp nd, Bool sign_extend)
583{
584 IRExpr *op, *dep1, *dep2, *ndep, *dep2x;
585
586 op = mkU64(opc);
587 dep1 = s390_cc_widen(d1, sign_extend);
588 dep2 = s390_cc_widen(d2, sign_extend);
589 ndep = s390_cc_widen(nd, sign_extend);
590
591 dep2x = binop(Iop_Xor64, dep2, ndep);
592
593 s390_cc_thunk_fill(op, dep1, dep2x, ndep);
594}
595
596
597/* Write one floating point value into the flags thunk */
598static void
599s390_cc_thunk_put1f(UInt opc, IRTemp d1)
600{
601 IRExpr *op, *dep1, *dep2, *ndep;
602
603 op = mkU64(opc);
604 dep1 = mkexpr(d1);
605 dep2 = mkU64(0);
606 ndep = mkU64(0);
607
608 s390_cc_thunk_fill(op, dep1, dep2, ndep);
609}
610
611
612/* Write a floating point value and an integer into the flags thunk. The
613 integer value is zero-extended first. */
614static void
615s390_cc_thunk_putFZ(UInt opc, IRTemp d1, IRTemp d2)
616{
617 IRExpr *op, *dep1, *dep2, *ndep;
618
619 op = mkU64(opc);
620 dep1 = mkexpr(d1);
621 dep2 = s390_cc_widen(d2, False);
622 ndep = mkU64(0);
623
624 s390_cc_thunk_fill(op, dep1, dep2, ndep);
625}
626
627
628/* Write a 128-bit floating point value into the flags thunk. This is
629 done by splitting the value into two 64-bits values. */
630static void
631s390_cc_thunk_put1f128(UInt opc, IRTemp d1)
632{
633 IRExpr *op, *hi, *lo, *ndep;
634
635 op = mkU64(opc);
636 hi = unop(Iop_F128HItoF64, mkexpr(d1));
637 lo = unop(Iop_F128LOtoF64, mkexpr(d1));
638 ndep = mkU64(0);
639
640 s390_cc_thunk_fill(op, hi, lo, ndep);
641}
642
643
644/* Write a 128-bit floating point value and an integer into the flags thunk.
645 The integer value is zero-extended first. */
646static void
647s390_cc_thunk_put1f128Z(UInt opc, IRTemp d1, IRTemp nd)
648{
649 IRExpr *op, *hi, *lo, *lox, *ndep;
650
651 op = mkU64(opc);
652 hi = unop(Iop_F128HItoF64, mkexpr(d1));
653 lo = unop(Iop_ReinterpF64asI64, unop(Iop_F128LOtoF64, mkexpr(d1)));
654 ndep = s390_cc_widen(nd, False);
655
656 lox = binop(Iop_Xor64, lo, ndep); /* convey dependency */
657
658 s390_cc_thunk_fill(op, hi, lox, ndep);
659}
660
661
662static void
663s390_cc_set(UInt val)
664{
665 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
666 mkU64(val), mkU64(0), mkU64(0));
667}
668
669/* Build IR to calculate the condition code from flags thunk.
670 Returns an expression of type Ity_I32 */
671static IRExpr *
672s390_call_calculate_cc(void)
673{
674 IRExpr **args, *call, *op, *dep1, *dep2, *ndep;
675
florian428dfdd2012-03-27 03:09:49 +0000676 op = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_OP), Ity_I64);
677 dep1 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP1), Ity_I64);
678 dep2 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP2), Ity_I64);
679 ndep = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_NDEP), Ity_I64);
sewardj2019a972011-03-07 16:04:07 +0000680
681 args = mkIRExprVec_4(op, dep1, dep2, ndep);
682 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
683 "s390_calculate_cc", &s390_calculate_cc, args);
684
685 /* Exclude OP and NDEP from definedness checking. We're only
686 interested in DEP1 and DEP2. */
687 call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<3);
688
689 return call;
690}
691
692/* Build IR to calculate the internal condition code for a "compare and branch"
693 insn. Returns an expression of type Ity_I32 */
694static IRExpr *
florianff9613f2012-05-12 15:26:44 +0000695s390_call_calculate_icc(UInt m, UInt opc, IRTemp op1, IRTemp op2)
sewardj2019a972011-03-07 16:04:07 +0000696{
florianff9613f2012-05-12 15:26:44 +0000697 IRExpr **args, *call, *op, *dep1, *dep2, *mask;
sewardj2019a972011-03-07 16:04:07 +0000698
florianff9613f2012-05-12 15:26:44 +0000699 switch (opc) {
700 case S390_CC_OP_SIGNED_COMPARE:
701 dep1 = s390_cc_widen(op1, True);
702 dep2 = s390_cc_widen(op2, True);
703 break;
704
705 case S390_CC_OP_UNSIGNED_COMPARE:
706 dep1 = s390_cc_widen(op1, False);
707 dep2 = s390_cc_widen(op2, False);
708 break;
709
710 default:
711 vpanic("s390_call_calculate_icc");
712 }
713
714 mask = mkU64(m);
sewardj2019a972011-03-07 16:04:07 +0000715 op = mkU64(opc);
sewardj2019a972011-03-07 16:04:07 +0000716
florianff9613f2012-05-12 15:26:44 +0000717 args = mkIRExprVec_5(mask, op, dep1, dep2, mkU64(0) /* unused */);
sewardj2019a972011-03-07 16:04:07 +0000718 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
florianff9613f2012-05-12 15:26:44 +0000719 "s390_calculate_cond", &s390_calculate_cond, args);
sewardj2019a972011-03-07 16:04:07 +0000720
florianff9613f2012-05-12 15:26:44 +0000721 /* Exclude the requested condition, OP and NDEP from definedness
722 checking. We're only interested in DEP1 and DEP2. */
723 call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<1) | (1<<4);
sewardj2019a972011-03-07 16:04:07 +0000724
725 return call;
726}
727
728/* Build IR to calculate the condition code from flags thunk.
729 Returns an expression of type Ity_I32 */
730static IRExpr *
731s390_call_calculate_cond(UInt m)
732{
733 IRExpr **args, *call, *op, *dep1, *dep2, *ndep, *mask;
734
735 mask = mkU64(m);
florian428dfdd2012-03-27 03:09:49 +0000736 op = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_OP), Ity_I64);
737 dep1 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP1), Ity_I64);
738 dep2 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP2), Ity_I64);
739 ndep = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_NDEP), Ity_I64);
sewardj2019a972011-03-07 16:04:07 +0000740
741 args = mkIRExprVec_5(mask, op, dep1, dep2, ndep);
742 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
743 "s390_calculate_cond", &s390_calculate_cond, args);
744
745 /* Exclude the requested condition, OP and NDEP from definedness
746 checking. We're only interested in DEP1 and DEP2. */
747 call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<1) | (1<<4);
748
749 return call;
750}
751
752#define s390_cc_thunk_putZ(op,dep1) s390_cc_thunk_put1(op,dep1,False)
753#define s390_cc_thunk_putS(op,dep1) s390_cc_thunk_put1(op,dep1,True)
754#define s390_cc_thunk_putF(op,dep1) s390_cc_thunk_put1f(op,dep1)
755#define s390_cc_thunk_putZZ(op,dep1,dep2) s390_cc_thunk_put2(op,dep1,dep2,False)
756#define s390_cc_thunk_putSS(op,dep1,dep2) s390_cc_thunk_put2(op,dep1,dep2,True)
757#define s390_cc_thunk_putFF(op,dep1,dep2) s390_cc_thunk_put2f(op,dep1,dep2)
758#define s390_cc_thunk_putZZZ(op,dep1,dep2,ndep) \
759 s390_cc_thunk_put3(op,dep1,dep2,ndep,False)
760#define s390_cc_thunk_putSSS(op,dep1,dep2,ndep) \
761 s390_cc_thunk_put3(op,dep1,dep2,ndep,True)
sewardj2019a972011-03-07 16:04:07 +0000762
763
sewardj2019a972011-03-07 16:04:07 +0000764
765
766/*------------------------------------------------------------*/
767/*--- Guest register access ---*/
768/*------------------------------------------------------------*/
769
770
771/*------------------------------------------------------------*/
772/*--- ar registers ---*/
773/*------------------------------------------------------------*/
774
775/* Return the guest state offset of a ar register. */
776static UInt
777ar_offset(UInt archreg)
778{
779 static const UInt offset[16] = {
floriane88b3c92011-07-05 02:48:39 +0000780 S390X_GUEST_OFFSET(guest_a0),
781 S390X_GUEST_OFFSET(guest_a1),
782 S390X_GUEST_OFFSET(guest_a2),
783 S390X_GUEST_OFFSET(guest_a3),
784 S390X_GUEST_OFFSET(guest_a4),
785 S390X_GUEST_OFFSET(guest_a5),
786 S390X_GUEST_OFFSET(guest_a6),
787 S390X_GUEST_OFFSET(guest_a7),
788 S390X_GUEST_OFFSET(guest_a8),
789 S390X_GUEST_OFFSET(guest_a9),
790 S390X_GUEST_OFFSET(guest_a10),
791 S390X_GUEST_OFFSET(guest_a11),
792 S390X_GUEST_OFFSET(guest_a12),
793 S390X_GUEST_OFFSET(guest_a13),
794 S390X_GUEST_OFFSET(guest_a14),
795 S390X_GUEST_OFFSET(guest_a15),
sewardj2019a972011-03-07 16:04:07 +0000796 };
797
798 vassert(archreg < 16);
799
800 return offset[archreg];
801}
802
803
804/* Return the guest state offset of word #0 of a ar register. */
805static __inline__ UInt
806ar_w0_offset(UInt archreg)
807{
808 return ar_offset(archreg) + 0;
809}
810
811/* Write word #0 of a ar to the guest state. */
812static __inline__ void
813put_ar_w0(UInt archreg, IRExpr *expr)
814{
815 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
816
817 stmt(IRStmt_Put(ar_w0_offset(archreg), expr));
818}
819
820/* Read word #0 of a ar register. */
821static __inline__ IRExpr *
822get_ar_w0(UInt archreg)
823{
824 return IRExpr_Get(ar_w0_offset(archreg), Ity_I32);
825}
826
827
828/*------------------------------------------------------------*/
829/*--- fpr registers ---*/
830/*------------------------------------------------------------*/
831
832/* Return the guest state offset of a fpr register. */
833static UInt
834fpr_offset(UInt archreg)
835{
836 static const UInt offset[16] = {
floriane88b3c92011-07-05 02:48:39 +0000837 S390X_GUEST_OFFSET(guest_f0),
838 S390X_GUEST_OFFSET(guest_f1),
839 S390X_GUEST_OFFSET(guest_f2),
840 S390X_GUEST_OFFSET(guest_f3),
841 S390X_GUEST_OFFSET(guest_f4),
842 S390X_GUEST_OFFSET(guest_f5),
843 S390X_GUEST_OFFSET(guest_f6),
844 S390X_GUEST_OFFSET(guest_f7),
845 S390X_GUEST_OFFSET(guest_f8),
846 S390X_GUEST_OFFSET(guest_f9),
847 S390X_GUEST_OFFSET(guest_f10),
848 S390X_GUEST_OFFSET(guest_f11),
849 S390X_GUEST_OFFSET(guest_f12),
850 S390X_GUEST_OFFSET(guest_f13),
851 S390X_GUEST_OFFSET(guest_f14),
852 S390X_GUEST_OFFSET(guest_f15),
sewardj2019a972011-03-07 16:04:07 +0000853 };
854
855 vassert(archreg < 16);
856
857 return offset[archreg];
858}
859
860
861/* Return the guest state offset of word #0 of a fpr register. */
862static __inline__ UInt
863fpr_w0_offset(UInt archreg)
864{
865 return fpr_offset(archreg) + 0;
866}
867
868/* Write word #0 of a fpr to the guest state. */
869static __inline__ void
870put_fpr_w0(UInt archreg, IRExpr *expr)
871{
872 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_F32);
873
874 stmt(IRStmt_Put(fpr_w0_offset(archreg), expr));
875}
876
877/* Read word #0 of a fpr register. */
878static __inline__ IRExpr *
879get_fpr_w0(UInt archreg)
880{
881 return IRExpr_Get(fpr_w0_offset(archreg), Ity_F32);
882}
883
884/* Return the guest state offset of double word #0 of a fpr register. */
885static __inline__ UInt
886fpr_dw0_offset(UInt archreg)
887{
888 return fpr_offset(archreg) + 0;
889}
890
891/* Write double word #0 of a fpr to the guest state. */
892static __inline__ void
893put_fpr_dw0(UInt archreg, IRExpr *expr)
894{
895 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_F64);
896
897 stmt(IRStmt_Put(fpr_dw0_offset(archreg), expr));
898}
899
900/* Read double word #0 of a fpr register. */
901static __inline__ IRExpr *
902get_fpr_dw0(UInt archreg)
903{
904 return IRExpr_Get(fpr_dw0_offset(archreg), Ity_F64);
905}
906
907
908/*------------------------------------------------------------*/
909/*--- gpr registers ---*/
910/*------------------------------------------------------------*/
911
912/* Return the guest state offset of a gpr register. */
913static UInt
914gpr_offset(UInt archreg)
915{
916 static const UInt offset[16] = {
floriane88b3c92011-07-05 02:48:39 +0000917 S390X_GUEST_OFFSET(guest_r0),
918 S390X_GUEST_OFFSET(guest_r1),
919 S390X_GUEST_OFFSET(guest_r2),
920 S390X_GUEST_OFFSET(guest_r3),
921 S390X_GUEST_OFFSET(guest_r4),
922 S390X_GUEST_OFFSET(guest_r5),
923 S390X_GUEST_OFFSET(guest_r6),
924 S390X_GUEST_OFFSET(guest_r7),
925 S390X_GUEST_OFFSET(guest_r8),
926 S390X_GUEST_OFFSET(guest_r9),
927 S390X_GUEST_OFFSET(guest_r10),
928 S390X_GUEST_OFFSET(guest_r11),
929 S390X_GUEST_OFFSET(guest_r12),
930 S390X_GUEST_OFFSET(guest_r13),
931 S390X_GUEST_OFFSET(guest_r14),
932 S390X_GUEST_OFFSET(guest_r15),
sewardj2019a972011-03-07 16:04:07 +0000933 };
934
935 vassert(archreg < 16);
936
937 return offset[archreg];
938}
939
940
941/* Return the guest state offset of word #0 of a gpr register. */
942static __inline__ UInt
943gpr_w0_offset(UInt archreg)
944{
945 return gpr_offset(archreg) + 0;
946}
947
948/* Write word #0 of a gpr to the guest state. */
949static __inline__ void
950put_gpr_w0(UInt archreg, IRExpr *expr)
951{
952 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
953
954 stmt(IRStmt_Put(gpr_w0_offset(archreg), expr));
955}
956
957/* Read word #0 of a gpr register. */
958static __inline__ IRExpr *
959get_gpr_w0(UInt archreg)
960{
961 return IRExpr_Get(gpr_w0_offset(archreg), Ity_I32);
962}
963
964/* Return the guest state offset of double word #0 of a gpr register. */
965static __inline__ UInt
966gpr_dw0_offset(UInt archreg)
967{
968 return gpr_offset(archreg) + 0;
969}
970
971/* Write double word #0 of a gpr to the guest state. */
972static __inline__ void
973put_gpr_dw0(UInt archreg, IRExpr *expr)
974{
975 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I64);
976
977 stmt(IRStmt_Put(gpr_dw0_offset(archreg), expr));
978}
979
980/* Read double word #0 of a gpr register. */
981static __inline__ IRExpr *
982get_gpr_dw0(UInt archreg)
983{
984 return IRExpr_Get(gpr_dw0_offset(archreg), Ity_I64);
985}
986
987/* Return the guest state offset of half word #1 of a gpr register. */
988static __inline__ UInt
989gpr_hw1_offset(UInt archreg)
990{
991 return gpr_offset(archreg) + 2;
992}
993
994/* Write half word #1 of a gpr to the guest state. */
995static __inline__ void
996put_gpr_hw1(UInt archreg, IRExpr *expr)
997{
998 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
999
1000 stmt(IRStmt_Put(gpr_hw1_offset(archreg), expr));
1001}
1002
1003/* Read half word #1 of a gpr register. */
1004static __inline__ IRExpr *
1005get_gpr_hw1(UInt archreg)
1006{
1007 return IRExpr_Get(gpr_hw1_offset(archreg), Ity_I16);
1008}
1009
1010/* Return the guest state offset of byte #6 of a gpr register. */
1011static __inline__ UInt
1012gpr_b6_offset(UInt archreg)
1013{
1014 return gpr_offset(archreg) + 6;
1015}
1016
1017/* Write byte #6 of a gpr to the guest state. */
1018static __inline__ void
1019put_gpr_b6(UInt archreg, IRExpr *expr)
1020{
1021 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1022
1023 stmt(IRStmt_Put(gpr_b6_offset(archreg), expr));
1024}
1025
1026/* Read byte #6 of a gpr register. */
1027static __inline__ IRExpr *
1028get_gpr_b6(UInt archreg)
1029{
1030 return IRExpr_Get(gpr_b6_offset(archreg), Ity_I8);
1031}
1032
1033/* Return the guest state offset of byte #3 of a gpr register. */
1034static __inline__ UInt
1035gpr_b3_offset(UInt archreg)
1036{
1037 return gpr_offset(archreg) + 3;
1038}
1039
1040/* Write byte #3 of a gpr to the guest state. */
1041static __inline__ void
1042put_gpr_b3(UInt archreg, IRExpr *expr)
1043{
1044 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1045
1046 stmt(IRStmt_Put(gpr_b3_offset(archreg), expr));
1047}
1048
1049/* Read byte #3 of a gpr register. */
1050static __inline__ IRExpr *
1051get_gpr_b3(UInt archreg)
1052{
1053 return IRExpr_Get(gpr_b3_offset(archreg), Ity_I8);
1054}
1055
1056/* Return the guest state offset of byte #0 of a gpr register. */
1057static __inline__ UInt
1058gpr_b0_offset(UInt archreg)
1059{
1060 return gpr_offset(archreg) + 0;
1061}
1062
1063/* Write byte #0 of a gpr to the guest state. */
1064static __inline__ void
1065put_gpr_b0(UInt archreg, IRExpr *expr)
1066{
1067 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1068
1069 stmt(IRStmt_Put(gpr_b0_offset(archreg), expr));
1070}
1071
1072/* Read byte #0 of a gpr register. */
1073static __inline__ IRExpr *
1074get_gpr_b0(UInt archreg)
1075{
1076 return IRExpr_Get(gpr_b0_offset(archreg), Ity_I8);
1077}
1078
1079/* Return the guest state offset of word #1 of a gpr register. */
1080static __inline__ UInt
1081gpr_w1_offset(UInt archreg)
1082{
1083 return gpr_offset(archreg) + 4;
1084}
1085
1086/* Write word #1 of a gpr to the guest state. */
1087static __inline__ void
1088put_gpr_w1(UInt archreg, IRExpr *expr)
1089{
1090 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1091
1092 stmt(IRStmt_Put(gpr_w1_offset(archreg), expr));
1093}
1094
1095/* Read word #1 of a gpr register. */
1096static __inline__ IRExpr *
1097get_gpr_w1(UInt archreg)
1098{
1099 return IRExpr_Get(gpr_w1_offset(archreg), Ity_I32);
1100}
1101
1102/* Return the guest state offset of half word #3 of a gpr register. */
1103static __inline__ UInt
1104gpr_hw3_offset(UInt archreg)
1105{
1106 return gpr_offset(archreg) + 6;
1107}
1108
1109/* Write half word #3 of a gpr to the guest state. */
1110static __inline__ void
1111put_gpr_hw3(UInt archreg, IRExpr *expr)
1112{
1113 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1114
1115 stmt(IRStmt_Put(gpr_hw3_offset(archreg), expr));
1116}
1117
1118/* Read half word #3 of a gpr register. */
1119static __inline__ IRExpr *
1120get_gpr_hw3(UInt archreg)
1121{
1122 return IRExpr_Get(gpr_hw3_offset(archreg), Ity_I16);
1123}
1124
1125/* Return the guest state offset of byte #7 of a gpr register. */
1126static __inline__ UInt
1127gpr_b7_offset(UInt archreg)
1128{
1129 return gpr_offset(archreg) + 7;
1130}
1131
1132/* Write byte #7 of a gpr to the guest state. */
1133static __inline__ void
1134put_gpr_b7(UInt archreg, IRExpr *expr)
1135{
1136 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1137
1138 stmt(IRStmt_Put(gpr_b7_offset(archreg), expr));
1139}
1140
1141/* Read byte #7 of a gpr register. */
1142static __inline__ IRExpr *
1143get_gpr_b7(UInt archreg)
1144{
1145 return IRExpr_Get(gpr_b7_offset(archreg), Ity_I8);
1146}
1147
1148/* Return the guest state offset of half word #0 of a gpr register. */
1149static __inline__ UInt
1150gpr_hw0_offset(UInt archreg)
1151{
1152 return gpr_offset(archreg) + 0;
1153}
1154
1155/* Write half word #0 of a gpr to the guest state. */
1156static __inline__ void
1157put_gpr_hw0(UInt archreg, IRExpr *expr)
1158{
1159 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1160
1161 stmt(IRStmt_Put(gpr_hw0_offset(archreg), expr));
1162}
1163
1164/* Read half word #0 of a gpr register. */
1165static __inline__ IRExpr *
1166get_gpr_hw0(UInt archreg)
1167{
1168 return IRExpr_Get(gpr_hw0_offset(archreg), Ity_I16);
1169}
1170
1171/* Return the guest state offset of byte #4 of a gpr register. */
1172static __inline__ UInt
1173gpr_b4_offset(UInt archreg)
1174{
1175 return gpr_offset(archreg) + 4;
1176}
1177
1178/* Write byte #4 of a gpr to the guest state. */
1179static __inline__ void
1180put_gpr_b4(UInt archreg, IRExpr *expr)
1181{
1182 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1183
1184 stmt(IRStmt_Put(gpr_b4_offset(archreg), expr));
1185}
1186
1187/* Read byte #4 of a gpr register. */
1188static __inline__ IRExpr *
1189get_gpr_b4(UInt archreg)
1190{
1191 return IRExpr_Get(gpr_b4_offset(archreg), Ity_I8);
1192}
1193
1194/* Return the guest state offset of byte #1 of a gpr register. */
1195static __inline__ UInt
1196gpr_b1_offset(UInt archreg)
1197{
1198 return gpr_offset(archreg) + 1;
1199}
1200
1201/* Write byte #1 of a gpr to the guest state. */
1202static __inline__ void
1203put_gpr_b1(UInt archreg, IRExpr *expr)
1204{
1205 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1206
1207 stmt(IRStmt_Put(gpr_b1_offset(archreg), expr));
1208}
1209
1210/* Read byte #1 of a gpr register. */
1211static __inline__ IRExpr *
1212get_gpr_b1(UInt archreg)
1213{
1214 return IRExpr_Get(gpr_b1_offset(archreg), Ity_I8);
1215}
1216
1217/* Return the guest state offset of half word #2 of a gpr register. */
1218static __inline__ UInt
1219gpr_hw2_offset(UInt archreg)
1220{
1221 return gpr_offset(archreg) + 4;
1222}
1223
1224/* Write half word #2 of a gpr to the guest state. */
1225static __inline__ void
1226put_gpr_hw2(UInt archreg, IRExpr *expr)
1227{
1228 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1229
1230 stmt(IRStmt_Put(gpr_hw2_offset(archreg), expr));
1231}
1232
1233/* Read half word #2 of a gpr register. */
1234static __inline__ IRExpr *
1235get_gpr_hw2(UInt archreg)
1236{
1237 return IRExpr_Get(gpr_hw2_offset(archreg), Ity_I16);
1238}
1239
1240/* Return the guest state offset of byte #5 of a gpr register. */
1241static __inline__ UInt
1242gpr_b5_offset(UInt archreg)
1243{
1244 return gpr_offset(archreg) + 5;
1245}
1246
1247/* Write byte #5 of a gpr to the guest state. */
1248static __inline__ void
1249put_gpr_b5(UInt archreg, IRExpr *expr)
1250{
1251 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1252
1253 stmt(IRStmt_Put(gpr_b5_offset(archreg), expr));
1254}
1255
1256/* Read byte #5 of a gpr register. */
1257static __inline__ IRExpr *
1258get_gpr_b5(UInt archreg)
1259{
1260 return IRExpr_Get(gpr_b5_offset(archreg), Ity_I8);
1261}
1262
1263/* Return the guest state offset of byte #2 of a gpr register. */
1264static __inline__ UInt
1265gpr_b2_offset(UInt archreg)
1266{
1267 return gpr_offset(archreg) + 2;
1268}
1269
1270/* Write byte #2 of a gpr to the guest state. */
1271static __inline__ void
1272put_gpr_b2(UInt archreg, IRExpr *expr)
1273{
1274 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1275
1276 stmt(IRStmt_Put(gpr_b2_offset(archreg), expr));
1277}
1278
1279/* Read byte #2 of a gpr register. */
1280static __inline__ IRExpr *
1281get_gpr_b2(UInt archreg)
1282{
1283 return IRExpr_Get(gpr_b2_offset(archreg), Ity_I8);
1284}
1285
1286/* Return the guest state offset of the counter register. */
1287static UInt
1288counter_offset(void)
1289{
floriane88b3c92011-07-05 02:48:39 +00001290 return S390X_GUEST_OFFSET(guest_counter);
sewardj2019a972011-03-07 16:04:07 +00001291}
1292
1293/* Return the guest state offset of double word #0 of the counter register. */
1294static __inline__ UInt
1295counter_dw0_offset(void)
1296{
1297 return counter_offset() + 0;
1298}
1299
1300/* Write double word #0 of the counter to the guest state. */
1301static __inline__ void
1302put_counter_dw0(IRExpr *expr)
1303{
1304 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I64);
1305
1306 stmt(IRStmt_Put(counter_dw0_offset(), expr));
1307}
1308
1309/* Read double word #0 of the counter register. */
1310static __inline__ IRExpr *
1311get_counter_dw0(void)
1312{
1313 return IRExpr_Get(counter_dw0_offset(), Ity_I64);
1314}
1315
1316/* Return the guest state offset of word #0 of the counter register. */
1317static __inline__ UInt
1318counter_w0_offset(void)
1319{
1320 return counter_offset() + 0;
1321}
1322
1323/* Return the guest state offset of word #1 of the counter register. */
1324static __inline__ UInt
1325counter_w1_offset(void)
1326{
1327 return counter_offset() + 4;
1328}
1329
1330/* Write word #0 of the counter to the guest state. */
1331static __inline__ void
1332put_counter_w0(IRExpr *expr)
1333{
1334 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1335
1336 stmt(IRStmt_Put(counter_w0_offset(), expr));
1337}
1338
1339/* Read word #0 of the counter register. */
1340static __inline__ IRExpr *
1341get_counter_w0(void)
1342{
1343 return IRExpr_Get(counter_w0_offset(), Ity_I32);
1344}
1345
1346/* Write word #1 of the counter to the guest state. */
1347static __inline__ void
1348put_counter_w1(IRExpr *expr)
1349{
1350 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1351
1352 stmt(IRStmt_Put(counter_w1_offset(), expr));
1353}
1354
1355/* Read word #1 of the counter register. */
1356static __inline__ IRExpr *
1357get_counter_w1(void)
1358{
1359 return IRExpr_Get(counter_w1_offset(), Ity_I32);
1360}
1361
1362/* Return the guest state offset of the fpc register. */
1363static UInt
1364fpc_offset(void)
1365{
floriane88b3c92011-07-05 02:48:39 +00001366 return S390X_GUEST_OFFSET(guest_fpc);
sewardj2019a972011-03-07 16:04:07 +00001367}
1368
1369/* Return the guest state offset of word #0 of the fpc register. */
1370static __inline__ UInt
1371fpc_w0_offset(void)
1372{
1373 return fpc_offset() + 0;
1374}
1375
1376/* Write word #0 of the fpc to the guest state. */
1377static __inline__ void
1378put_fpc_w0(IRExpr *expr)
1379{
1380 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1381
1382 stmt(IRStmt_Put(fpc_w0_offset(), expr));
1383}
1384
1385/* Read word #0 of the fpc register. */
1386static __inline__ IRExpr *
1387get_fpc_w0(void)
1388{
1389 return IRExpr_Get(fpc_w0_offset(), Ity_I32);
1390}
1391
1392
1393/*------------------------------------------------------------*/
1394/*--- Build IR for formats ---*/
1395/*------------------------------------------------------------*/
1396static void
1397s390_format_I(HChar *(*irgen)(UChar i),
1398 UChar i)
1399{
1400 HChar *mnm = irgen(i);
1401
sewardj7ee97522011-05-09 21:45:04 +00001402 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001403 s390_disasm(ENC2(MNM, UINT), mnm, i);
1404}
1405
1406static void
1407s390_format_RI(HChar *(*irgen)(UChar r1, UShort i2),
1408 UChar r1, UShort i2)
1409{
1410 irgen(r1, i2);
1411}
1412
1413static void
1414s390_format_RI_RU(HChar *(*irgen)(UChar r1, UShort i2),
1415 UChar r1, UShort i2)
1416{
1417 HChar *mnm = irgen(r1, i2);
1418
sewardj7ee97522011-05-09 21:45:04 +00001419 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001420 s390_disasm(ENC3(MNM, GPR, UINT), mnm, r1, i2);
1421}
1422
1423static void
1424s390_format_RI_RI(HChar *(*irgen)(UChar r1, UShort i2),
1425 UChar r1, UShort i2)
1426{
1427 HChar *mnm = irgen(r1, i2);
1428
sewardj7ee97522011-05-09 21:45:04 +00001429 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001430 s390_disasm(ENC3(MNM, GPR, INT), mnm, r1, (Int)(Short)i2);
1431}
1432
1433static void
1434s390_format_RI_RP(HChar *(*irgen)(UChar r1, UShort i2),
1435 UChar r1, UShort i2)
1436{
1437 HChar *mnm = irgen(r1, i2);
1438
sewardj7ee97522011-05-09 21:45:04 +00001439 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001440 s390_disasm(ENC3(MNM, GPR, PCREL), mnm, r1, (Int)(Short)i2);
1441}
1442
1443static void
1444s390_format_RIE_RRP(HChar *(*irgen)(UChar r1, UChar r3, UShort i2),
1445 UChar r1, UChar r3, UShort i2)
1446{
1447 HChar *mnm = irgen(r1, r3, i2);
1448
sewardj7ee97522011-05-09 21:45:04 +00001449 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001450 s390_disasm(ENC4(MNM, GPR, GPR, PCREL), mnm, r1, r3, (Int)(Short)i2);
1451}
1452
1453static void
1454s390_format_RIE_RRI0(HChar *(*irgen)(UChar r1, UChar r3, UShort i2),
1455 UChar r1, UChar r3, UShort i2)
1456{
1457 HChar *mnm = irgen(r1, r3, i2);
1458
sewardj7ee97522011-05-09 21:45:04 +00001459 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001460 s390_disasm(ENC4(MNM, GPR, GPR, INT), mnm, r1, r3, (Int)(Short)i2);
1461}
1462
1463static void
1464s390_format_RIE_RRUUU(HChar *(*irgen)(UChar r1, UChar r2, UChar i3, UChar i4,
1465 UChar i5),
1466 UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
1467{
1468 HChar *mnm = irgen(r1, r2, i3, i4, i5);
1469
sewardj7ee97522011-05-09 21:45:04 +00001470 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001471 s390_disasm(ENC6(MNM, GPR, GPR, UINT, UINT, UINT), mnm, r1, r2, i3, i4,
1472 i5);
1473}
1474
1475static void
1476s390_format_RIE_RRPU(HChar *(*irgen)(UChar r1, UChar r2, UShort i4, UChar m3),
1477 UChar r1, UChar r2, UShort i4, UChar m3)
1478{
1479 HChar *mnm = irgen(r1, r2, i4, m3);
1480
sewardj7ee97522011-05-09 21:45:04 +00001481 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001482 s390_disasm(ENC5(XMNM, GPR, GPR, CABM, PCREL), S390_XMNM_CAB, mnm, m3, r1,
1483 r2, m3, (Int)(Short)i4);
1484}
1485
1486static void
1487s390_format_RIE_RUPU(HChar *(*irgen)(UChar r1, UChar m3, UShort i4, UChar i2),
1488 UChar r1, UChar m3, UShort i4, UChar i2)
1489{
1490 HChar *mnm = irgen(r1, m3, i4, i2);
1491
sewardj7ee97522011-05-09 21:45:04 +00001492 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001493 s390_disasm(ENC5(XMNM, GPR, UINT, CABM, PCREL), S390_XMNM_CAB, mnm, m3,
1494 r1, i2, m3, (Int)(Short)i4);
1495}
1496
1497static void
1498s390_format_RIE_RUPI(HChar *(*irgen)(UChar r1, UChar m3, UShort i4, UChar i2),
1499 UChar r1, UChar m3, UShort i4, UChar i2)
1500{
1501 HChar *mnm = irgen(r1, m3, i4, i2);
1502
sewardj7ee97522011-05-09 21:45:04 +00001503 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001504 s390_disasm(ENC5(XMNM, GPR, INT, CABM, PCREL), S390_XMNM_CAB, mnm, m3, r1,
1505 (Int)(Char)i2, m3, (Int)(Short)i4);
1506}
1507
1508static void
1509s390_format_RIL(HChar *(*irgen)(UChar r1, UInt i2),
1510 UChar r1, UInt i2)
1511{
1512 irgen(r1, i2);
1513}
1514
1515static void
1516s390_format_RIL_RU(HChar *(*irgen)(UChar r1, UInt i2),
1517 UChar r1, UInt i2)
1518{
1519 HChar *mnm = irgen(r1, i2);
1520
sewardj7ee97522011-05-09 21:45:04 +00001521 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001522 s390_disasm(ENC3(MNM, GPR, UINT), mnm, r1, i2);
1523}
1524
1525static void
1526s390_format_RIL_RI(HChar *(*irgen)(UChar r1, UInt i2),
1527 UChar r1, UInt i2)
1528{
1529 HChar *mnm = irgen(r1, i2);
1530
sewardj7ee97522011-05-09 21:45:04 +00001531 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001532 s390_disasm(ENC3(MNM, GPR, INT), mnm, r1, i2);
1533}
1534
1535static void
1536s390_format_RIL_RP(HChar *(*irgen)(UChar r1, UInt i2),
1537 UChar r1, UInt i2)
1538{
1539 HChar *mnm = irgen(r1, i2);
1540
sewardj7ee97522011-05-09 21:45:04 +00001541 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001542 s390_disasm(ENC3(MNM, GPR, PCREL), mnm, r1, i2);
1543}
1544
1545static void
1546s390_format_RIL_UP(HChar *(*irgen)(void),
1547 UChar r1, UInt i2)
1548{
1549 HChar *mnm = irgen();
1550
sewardj7ee97522011-05-09 21:45:04 +00001551 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001552 s390_disasm(ENC3(MNM, UINT, PCREL), mnm, r1, i2);
1553}
1554
1555static void
1556s390_format_RIS_RURDI(HChar *(*irgen)(UChar r1, UChar m3, UChar i2,
1557 IRTemp op4addr),
1558 UChar r1, UChar m3, UChar b4, UShort d4, UChar i2)
1559{
1560 HChar *mnm;
1561 IRTemp op4addr = newTemp(Ity_I64);
1562
1563 assign(op4addr, binop(Iop_Add64, mkU64(d4), b4 != 0 ? get_gpr_dw0(b4) :
1564 mkU64(0)));
1565
1566 mnm = irgen(r1, m3, i2, op4addr);
1567
sewardj7ee97522011-05-09 21:45:04 +00001568 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001569 s390_disasm(ENC5(XMNM, GPR, INT, CABM, UDXB), S390_XMNM_CAB, mnm, m3, r1,
1570 (Int)(Char)i2, m3, d4, 0, b4);
1571}
1572
1573static void
1574s390_format_RIS_RURDU(HChar *(*irgen)(UChar r1, UChar m3, UChar i2,
1575 IRTemp op4addr),
1576 UChar r1, UChar m3, UChar b4, UShort d4, UChar i2)
1577{
1578 HChar *mnm;
1579 IRTemp op4addr = newTemp(Ity_I64);
1580
1581 assign(op4addr, binop(Iop_Add64, mkU64(d4), b4 != 0 ? get_gpr_dw0(b4) :
1582 mkU64(0)));
1583
1584 mnm = irgen(r1, m3, i2, op4addr);
1585
sewardj7ee97522011-05-09 21:45:04 +00001586 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001587 s390_disasm(ENC5(XMNM, GPR, UINT, CABM, UDXB), S390_XMNM_CAB, mnm, m3, r1,
1588 i2, m3, d4, 0, b4);
1589}
1590
1591static void
1592s390_format_RR(HChar *(*irgen)(UChar r1, UChar r2),
1593 UChar r1, UChar r2)
1594{
1595 irgen(r1, r2);
1596}
1597
1598static void
1599s390_format_RR_RR(HChar *(*irgen)(UChar r1, UChar r2),
1600 UChar r1, UChar r2)
1601{
1602 HChar *mnm = irgen(r1, r2);
1603
sewardj7ee97522011-05-09 21:45:04 +00001604 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001605 s390_disasm(ENC3(MNM, GPR, GPR), mnm, r1, r2);
1606}
1607
1608static void
1609s390_format_RR_FF(HChar *(*irgen)(UChar r1, UChar r2),
1610 UChar r1, UChar r2)
1611{
1612 HChar *mnm = irgen(r1, r2);
1613
sewardj7ee97522011-05-09 21:45:04 +00001614 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001615 s390_disasm(ENC3(MNM, FPR, FPR), mnm, r1, r2);
1616}
1617
1618static void
1619s390_format_RRE(HChar *(*irgen)(UChar r1, UChar r2),
1620 UChar r1, UChar r2)
1621{
1622 irgen(r1, r2);
1623}
1624
1625static void
1626s390_format_RRE_RR(HChar *(*irgen)(UChar r1, UChar r2),
1627 UChar r1, UChar r2)
1628{
1629 HChar *mnm = irgen(r1, r2);
1630
sewardj7ee97522011-05-09 21:45:04 +00001631 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001632 s390_disasm(ENC3(MNM, GPR, GPR), mnm, r1, r2);
1633}
1634
1635static void
1636s390_format_RRE_FF(HChar *(*irgen)(UChar r1, UChar r2),
1637 UChar r1, UChar r2)
1638{
1639 HChar *mnm = irgen(r1, r2);
1640
sewardj7ee97522011-05-09 21:45:04 +00001641 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001642 s390_disasm(ENC3(MNM, FPR, FPR), mnm, r1, r2);
1643}
1644
1645static void
1646s390_format_RRE_RF(HChar *(*irgen)(UChar, UChar),
1647 UChar r1, UChar r2)
1648{
1649 HChar *mnm = irgen(r1, r2);
1650
sewardj7ee97522011-05-09 21:45:04 +00001651 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001652 s390_disasm(ENC3(MNM, GPR, FPR), mnm, r1, r2);
1653}
1654
1655static void
1656s390_format_RRE_FR(HChar *(*irgen)(UChar r1, UChar r2),
1657 UChar r1, UChar r2)
1658{
1659 HChar *mnm = irgen(r1, r2);
1660
sewardj7ee97522011-05-09 21:45:04 +00001661 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001662 s390_disasm(ENC3(MNM, FPR, GPR), mnm, r1, r2);
1663}
1664
1665static void
1666s390_format_RRE_R0(HChar *(*irgen)(UChar r1),
1667 UChar r1)
1668{
1669 HChar *mnm = irgen(r1);
1670
sewardj7ee97522011-05-09 21:45:04 +00001671 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001672 s390_disasm(ENC2(MNM, GPR), mnm, r1);
1673}
1674
1675static void
1676s390_format_RRE_F0(HChar *(*irgen)(UChar r1),
1677 UChar r1)
1678{
1679 HChar *mnm = irgen(r1);
1680
sewardj7ee97522011-05-09 21:45:04 +00001681 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001682 s390_disasm(ENC2(MNM, FPR), mnm, r1);
1683}
1684
1685static void
florian9af37692012-01-15 21:01:16 +00001686s390_format_RRF_M0RERE(HChar *(*irgen)(UChar m3, UChar r1, UChar r2),
1687 UChar m3, UChar r1, UChar r2)
1688{
florianfed3ea32012-07-19 14:54:03 +00001689 HChar *mnm = irgen(m3, r1, r2);
florian9af37692012-01-15 21:01:16 +00001690
1691 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
florianfed3ea32012-07-19 14:54:03 +00001692 s390_disasm(ENC4(MNM, GPR, GPR, UINT), mnm, r1, r2, m3);
florian9af37692012-01-15 21:01:16 +00001693}
1694
1695static void
sewardj2019a972011-03-07 16:04:07 +00001696s390_format_RRF_F0FF(HChar *(*irgen)(UChar, UChar, UChar),
1697 UChar r1, UChar r3, UChar r2)
1698{
1699 HChar *mnm = irgen(r1, r3, r2);
1700
sewardj7ee97522011-05-09 21:45:04 +00001701 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001702 s390_disasm(ENC4(MNM, FPR, FPR, FPR), mnm, r1, r3, r2);
1703}
1704
1705static void
sewardjd7bde722011-04-05 13:19:33 +00001706s390_format_RRF_U0RR(HChar *(*irgen)(UChar m3, UChar r1, UChar r2),
1707 UChar m3, UChar r1, UChar r2, Int xmnm_kind)
1708{
1709 irgen(m3, r1, r2);
1710
sewardj7ee97522011-05-09 21:45:04 +00001711 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardjd7bde722011-04-05 13:19:33 +00001712 s390_disasm(ENC3(XMNM, GPR, GPR), xmnm_kind, m3, r1, r2);
1713}
1714
1715static void
sewardj2019a972011-03-07 16:04:07 +00001716s390_format_RRF_U0RF(HChar *(*irgen)(UChar r3, UChar r1, UChar r2),
1717 UChar r3, UChar r1, UChar r2)
1718{
1719 HChar *mnm = irgen(r3, r1, r2);
1720
sewardj7ee97522011-05-09 21:45:04 +00001721 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001722 s390_disasm(ENC4(MNM, GPR, UINT, FPR), mnm, r1, r3, r2);
1723}
1724
1725static void
1726s390_format_RRF_F0FF2(HChar *(*irgen)(UChar, UChar, UChar),
1727 UChar r3, UChar r1, UChar r2)
1728{
1729 HChar *mnm = irgen(r3, r1, r2);
1730
sewardj7ee97522011-05-09 21:45:04 +00001731 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001732 s390_disasm(ENC4(MNM, FPR, FPR, FPR), mnm, r1, r3, r2);
1733}
1734
1735static void
1736s390_format_RRF_R0RR2(HChar *(*irgen)(UChar r3, UChar r1, UChar r2),
1737 UChar r3, UChar r1, UChar r2)
1738{
1739 HChar *mnm = irgen(r3, r1, r2);
1740
sewardj7ee97522011-05-09 21:45:04 +00001741 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001742 s390_disasm(ENC4(MNM, GPR, GPR, GPR), mnm, r1, r2, r3);
1743}
1744
1745static void
1746s390_format_RRS(HChar *(*irgen)(UChar r1, UChar r2, UChar m3, IRTemp op4addr),
1747 UChar r1, UChar r2, UChar b4, UShort d4, UChar m3)
1748{
1749 HChar *mnm;
1750 IRTemp op4addr = newTemp(Ity_I64);
1751
1752 assign(op4addr, binop(Iop_Add64, mkU64(d4), b4 != 0 ? get_gpr_dw0(b4) :
1753 mkU64(0)));
1754
1755 mnm = irgen(r1, r2, m3, op4addr);
1756
sewardj7ee97522011-05-09 21:45:04 +00001757 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001758 s390_disasm(ENC5(XMNM, GPR, GPR, CABM, UDXB), S390_XMNM_CAB, mnm, m3, r1,
1759 r2, m3, d4, 0, b4);
1760}
1761
1762static void
1763s390_format_RS_R0RD(HChar *(*irgen)(UChar r1, IRTemp op2addr),
1764 UChar r1, UChar b2, UShort d2)
1765{
1766 HChar *mnm;
1767 IRTemp op2addr = newTemp(Ity_I64);
1768
1769 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
1770 mkU64(0)));
1771
1772 mnm = irgen(r1, op2addr);
1773
sewardj7ee97522011-05-09 21:45:04 +00001774 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001775 s390_disasm(ENC3(MNM, GPR, UDXB), mnm, r1, d2, 0, b2);
1776}
1777
1778static void
1779s390_format_RS_RRRD(HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
1780 UChar r1, UChar r3, UChar b2, UShort d2)
1781{
1782 HChar *mnm;
1783 IRTemp op2addr = newTemp(Ity_I64);
1784
1785 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
1786 mkU64(0)));
1787
1788 mnm = irgen(r1, r3, op2addr);
1789
sewardj7ee97522011-05-09 21:45:04 +00001790 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001791 s390_disasm(ENC4(MNM, GPR, GPR, UDXB), mnm, r1, r3, d2, 0, b2);
1792}
1793
1794static void
1795s390_format_RS_RURD(HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
1796 UChar r1, UChar r3, UChar b2, UShort d2)
1797{
1798 HChar *mnm;
1799 IRTemp op2addr = newTemp(Ity_I64);
1800
1801 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
1802 mkU64(0)));
1803
1804 mnm = irgen(r1, r3, op2addr);
1805
sewardj7ee97522011-05-09 21:45:04 +00001806 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001807 s390_disasm(ENC4(MNM, GPR, UINT, UDXB), mnm, r1, r3, d2, 0, b2);
1808}
1809
1810static void
1811s390_format_RS_AARD(HChar *(*irgen)(UChar, UChar, IRTemp),
1812 UChar r1, UChar r3, UChar b2, UShort d2)
1813{
1814 HChar *mnm;
1815 IRTemp op2addr = newTemp(Ity_I64);
1816
1817 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
1818 mkU64(0)));
1819
1820 mnm = irgen(r1, r3, op2addr);
1821
sewardj7ee97522011-05-09 21:45:04 +00001822 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001823 s390_disasm(ENC4(MNM, AR, AR, UDXB), mnm, r1, r3, d2, 0, b2);
1824}
1825
1826static void
1827s390_format_RSI_RRP(HChar *(*irgen)(UChar r1, UChar r3, UShort i2),
1828 UChar r1, UChar r3, UShort i2)
1829{
1830 HChar *mnm = irgen(r1, r3, i2);
1831
sewardj7ee97522011-05-09 21:45:04 +00001832 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001833 s390_disasm(ENC4(MNM, GPR, GPR, PCREL), mnm, r1, r3, (Int)(Short)i2);
1834}
1835
1836static void
1837s390_format_RSY_RRRD(HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
1838 UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2)
1839{
1840 HChar *mnm;
1841 IRTemp op2addr = newTemp(Ity_I64);
1842 IRTemp d2 = newTemp(Ity_I64);
1843
1844 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
1845 assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
1846 mkU64(0)));
1847
1848 mnm = irgen(r1, r3, op2addr);
1849
sewardj7ee97522011-05-09 21:45:04 +00001850 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001851 s390_disasm(ENC4(MNM, GPR, GPR, SDXB), mnm, r1, r3, dh2, dl2, 0, b2);
1852}
1853
1854static void
1855s390_format_RSY_AARD(HChar *(*irgen)(UChar, UChar, IRTemp),
1856 UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2)
1857{
1858 HChar *mnm;
1859 IRTemp op2addr = newTemp(Ity_I64);
1860 IRTemp d2 = newTemp(Ity_I64);
1861
1862 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
1863 assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
1864 mkU64(0)));
1865
1866 mnm = irgen(r1, r3, op2addr);
1867
sewardj7ee97522011-05-09 21:45:04 +00001868 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001869 s390_disasm(ENC4(MNM, AR, AR, SDXB), mnm, r1, r3, dh2, dl2, 0, b2);
1870}
1871
1872static void
1873s390_format_RSY_RURD(HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
1874 UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2)
1875{
1876 HChar *mnm;
1877 IRTemp op2addr = newTemp(Ity_I64);
1878 IRTemp d2 = newTemp(Ity_I64);
1879
1880 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
1881 assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
1882 mkU64(0)));
1883
1884 mnm = irgen(r1, r3, op2addr);
1885
sewardj7ee97522011-05-09 21:45:04 +00001886 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001887 s390_disasm(ENC4(MNM, GPR, UINT, SDXB), mnm, r1, r3, dh2, dl2, 0, b2);
1888}
1889
1890static void
sewardjd7bde722011-04-05 13:19:33 +00001891s390_format_RSY_RDRM(HChar *(*irgen)(UChar r1, IRTemp op2addr),
1892 UChar r1, UChar m3, UChar b2, UShort dl2, UChar dh2,
1893 Int xmnm_kind)
1894{
1895 IRTemp op2addr = newTemp(Ity_I64);
1896 IRTemp d2 = newTemp(Ity_I64);
1897
florian6820ba52012-07-26 02:01:50 +00001898 next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0)));
1899
sewardjd7bde722011-04-05 13:19:33 +00001900 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
1901 assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
1902 mkU64(0)));
1903
1904 irgen(r1, op2addr);
florian6820ba52012-07-26 02:01:50 +00001905
1906 vassert(dis_res->whatNext == Dis_Continue);
sewardjd7bde722011-04-05 13:19:33 +00001907
sewardj7ee97522011-05-09 21:45:04 +00001908 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardjd7bde722011-04-05 13:19:33 +00001909 s390_disasm(ENC3(XMNM, GPR, SDXB), xmnm_kind, m3, r1, dh2, dl2, 0, b2);
1910}
1911
1912static void
sewardj2019a972011-03-07 16:04:07 +00001913s390_format_RX(HChar *(*irgen)(UChar r1, UChar x2, UChar b2, UShort d2,
1914 IRTemp op2addr),
1915 UChar r1, UChar x2, UChar b2, UShort d2)
1916{
1917 IRTemp op2addr = newTemp(Ity_I64);
1918
1919 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
1920 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
1921 mkU64(0)));
1922
1923 irgen(r1, x2, b2, d2, op2addr);
1924}
1925
1926static void
1927s390_format_RX_RRRD(HChar *(*irgen)(UChar r1, IRTemp op2addr),
1928 UChar r1, UChar x2, UChar b2, UShort d2)
1929{
1930 HChar *mnm;
1931 IRTemp op2addr = newTemp(Ity_I64);
1932
1933 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
1934 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
1935 mkU64(0)));
1936
1937 mnm = irgen(r1, op2addr);
1938
sewardj7ee97522011-05-09 21:45:04 +00001939 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001940 s390_disasm(ENC3(MNM, GPR, UDXB), mnm, r1, d2, x2, b2);
1941}
1942
1943static void
1944s390_format_RX_FRRD(HChar *(*irgen)(UChar r1, IRTemp op2addr),
1945 UChar r1, UChar x2, UChar b2, UShort d2)
1946{
1947 HChar *mnm;
1948 IRTemp op2addr = newTemp(Ity_I64);
1949
1950 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
1951 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
1952 mkU64(0)));
1953
1954 mnm = irgen(r1, op2addr);
1955
sewardj7ee97522011-05-09 21:45:04 +00001956 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001957 s390_disasm(ENC3(MNM, FPR, UDXB), mnm, r1, d2, x2, b2);
1958}
1959
1960static void
1961s390_format_RXE_FRRD(HChar *(*irgen)(UChar r1, IRTemp op2addr),
1962 UChar r1, UChar x2, UChar b2, UShort d2)
1963{
1964 HChar *mnm;
1965 IRTemp op2addr = newTemp(Ity_I64);
1966
1967 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
1968 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
1969 mkU64(0)));
1970
1971 mnm = irgen(r1, op2addr);
1972
sewardj7ee97522011-05-09 21:45:04 +00001973 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001974 s390_disasm(ENC3(MNM, FPR, UDXB), mnm, r1, d2, x2, b2);
1975}
1976
1977static void
1978s390_format_RXF_FRRDF(HChar *(*irgen)(UChar, IRTemp, UChar),
1979 UChar r3, UChar x2, UChar b2, UShort d2, UChar r1)
1980{
1981 HChar *mnm;
1982 IRTemp op2addr = newTemp(Ity_I64);
1983
1984 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
1985 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
1986 mkU64(0)));
1987
1988 mnm = irgen(r3, op2addr, r1);
1989
sewardj7ee97522011-05-09 21:45:04 +00001990 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001991 s390_disasm(ENC4(MNM, FPR, FPR, UDXB), mnm, r1, r3, d2, x2, b2);
1992}
1993
1994static void
1995s390_format_RXY_RRRD(HChar *(*irgen)(UChar r1, IRTemp op2addr),
1996 UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
1997{
1998 HChar *mnm;
1999 IRTemp op2addr = newTemp(Ity_I64);
2000 IRTemp d2 = newTemp(Ity_I64);
2001
2002 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2003 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkexpr(d2),
2004 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2005 mkU64(0)));
2006
2007 mnm = irgen(r1, op2addr);
2008
sewardj7ee97522011-05-09 21:45:04 +00002009 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002010 s390_disasm(ENC3(MNM, GPR, SDXB), mnm, r1, dh2, dl2, x2, b2);
2011}
2012
2013static void
2014s390_format_RXY_FRRD(HChar *(*irgen)(UChar r1, IRTemp op2addr),
2015 UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
2016{
2017 HChar *mnm;
2018 IRTemp op2addr = newTemp(Ity_I64);
2019 IRTemp d2 = newTemp(Ity_I64);
2020
2021 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2022 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkexpr(d2),
2023 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2024 mkU64(0)));
2025
2026 mnm = irgen(r1, op2addr);
2027
sewardj7ee97522011-05-09 21:45:04 +00002028 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002029 s390_disasm(ENC3(MNM, FPR, SDXB), mnm, r1, dh2, dl2, x2, b2);
2030}
2031
2032static void
2033s390_format_RXY_URRD(HChar *(*irgen)(void),
2034 UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
2035{
2036 HChar *mnm;
2037 IRTemp op2addr = newTemp(Ity_I64);
2038 IRTemp d2 = newTemp(Ity_I64);
2039
2040 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2041 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkexpr(d2),
2042 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2043 mkU64(0)));
2044
2045 mnm = irgen();
2046
sewardj7ee97522011-05-09 21:45:04 +00002047 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002048 s390_disasm(ENC3(MNM, UINT, SDXB), mnm, r1, dh2, dl2, x2, b2);
2049}
2050
2051static void
2052s390_format_S_RD(HChar *(*irgen)(IRTemp op2addr),
2053 UChar b2, UShort d2)
2054{
2055 HChar *mnm;
2056 IRTemp op2addr = newTemp(Ity_I64);
2057
2058 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2059 mkU64(0)));
2060
2061 mnm = irgen(op2addr);
2062
sewardj7ee97522011-05-09 21:45:04 +00002063 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002064 s390_disasm(ENC2(MNM, UDXB), mnm, d2, 0, b2);
2065}
2066
2067static void
2068s390_format_SI_URD(HChar *(*irgen)(UChar i2, IRTemp op1addr),
2069 UChar i2, UChar b1, UShort d1)
2070{
2071 HChar *mnm;
2072 IRTemp op1addr = newTemp(Ity_I64);
2073
2074 assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
2075 mkU64(0)));
2076
2077 mnm = irgen(i2, op1addr);
2078
sewardj7ee97522011-05-09 21:45:04 +00002079 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002080 s390_disasm(ENC3(MNM, UDXB, UINT), mnm, d1, 0, b1, i2);
2081}
2082
2083static void
2084s390_format_SIY_URD(HChar *(*irgen)(UChar i2, IRTemp op1addr),
2085 UChar i2, UChar b1, UShort dl1, UChar dh1)
2086{
2087 HChar *mnm;
2088 IRTemp op1addr = newTemp(Ity_I64);
2089 IRTemp d1 = newTemp(Ity_I64);
2090
2091 assign(d1, mkU64(((ULong)(Long)(Char)dh1 << 12) | ((ULong)dl1)));
2092 assign(op1addr, binop(Iop_Add64, mkexpr(d1), b1 != 0 ? get_gpr_dw0(b1) :
2093 mkU64(0)));
2094
2095 mnm = irgen(i2, op1addr);
2096
sewardj7ee97522011-05-09 21:45:04 +00002097 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002098 s390_disasm(ENC3(MNM, SDXB, UINT), mnm, dh1, dl1, 0, b1, i2);
2099}
2100
2101static void
2102s390_format_SIY_IRD(HChar *(*irgen)(UChar i2, IRTemp op1addr),
2103 UChar i2, UChar b1, UShort dl1, UChar dh1)
2104{
2105 HChar *mnm;
2106 IRTemp op1addr = newTemp(Ity_I64);
2107 IRTemp d1 = newTemp(Ity_I64);
2108
2109 assign(d1, mkU64(((ULong)(Long)(Char)dh1 << 12) | ((ULong)dl1)));
2110 assign(op1addr, binop(Iop_Add64, mkexpr(d1), b1 != 0 ? get_gpr_dw0(b1) :
2111 mkU64(0)));
2112
2113 mnm = irgen(i2, op1addr);
2114
sewardj7ee97522011-05-09 21:45:04 +00002115 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002116 s390_disasm(ENC3(MNM, SDXB, INT), mnm, dh1, dl1, 0, b1, (Int)(Char)i2);
2117}
2118
2119static void
2120s390_format_SS_L0RDRD(HChar *(*irgen)(UChar, IRTemp, IRTemp),
2121 UChar l, UChar b1, UShort d1, UChar b2, UShort d2)
2122{
2123 HChar *mnm;
2124 IRTemp op1addr = newTemp(Ity_I64);
2125 IRTemp op2addr = newTemp(Ity_I64);
2126
2127 assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
2128 mkU64(0)));
2129 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2130 mkU64(0)));
2131
2132 mnm = irgen(l, op1addr, op2addr);
2133
sewardj7ee97522011-05-09 21:45:04 +00002134 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002135 s390_disasm(ENC3(MNM, UDLB, UDXB), mnm, d1, l, b1, d2, 0, b2);
2136}
2137
2138static void
2139s390_format_SIL_RDI(HChar *(*irgen)(UShort i2, IRTemp op1addr),
2140 UChar b1, UShort d1, UShort i2)
2141{
2142 HChar *mnm;
2143 IRTemp op1addr = newTemp(Ity_I64);
2144
2145 assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
2146 mkU64(0)));
2147
2148 mnm = irgen(i2, op1addr);
2149
sewardj7ee97522011-05-09 21:45:04 +00002150 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002151 s390_disasm(ENC3(MNM, UDXB, INT), mnm, d1, 0, b1, (Int)(Short)i2);
2152}
2153
2154static void
2155s390_format_SIL_RDU(HChar *(*irgen)(UShort i2, IRTemp op1addr),
2156 UChar b1, UShort d1, UShort i2)
2157{
2158 HChar *mnm;
2159 IRTemp op1addr = newTemp(Ity_I64);
2160
2161 assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
2162 mkU64(0)));
2163
2164 mnm = irgen(i2, op1addr);
2165
sewardj7ee97522011-05-09 21:45:04 +00002166 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002167 s390_disasm(ENC3(MNM, UDXB, UINT), mnm, d1, 0, b1, i2);
2168}
2169
2170
2171
2172/*------------------------------------------------------------*/
2173/*--- Build IR for opcodes ---*/
2174/*------------------------------------------------------------*/
2175
2176static HChar *
2177s390_irgen_AR(UChar r1, UChar r2)
2178{
2179 IRTemp op1 = newTemp(Ity_I32);
2180 IRTemp op2 = newTemp(Ity_I32);
2181 IRTemp result = newTemp(Ity_I32);
2182
2183 assign(op1, get_gpr_w1(r1));
2184 assign(op2, get_gpr_w1(r2));
2185 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2186 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2187 put_gpr_w1(r1, mkexpr(result));
2188
2189 return "ar";
2190}
2191
2192static HChar *
2193s390_irgen_AGR(UChar r1, UChar r2)
2194{
2195 IRTemp op1 = newTemp(Ity_I64);
2196 IRTemp op2 = newTemp(Ity_I64);
2197 IRTemp result = newTemp(Ity_I64);
2198
2199 assign(op1, get_gpr_dw0(r1));
2200 assign(op2, get_gpr_dw0(r2));
2201 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2202 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
2203 put_gpr_dw0(r1, mkexpr(result));
2204
2205 return "agr";
2206}
2207
2208static HChar *
2209s390_irgen_AGFR(UChar r1, UChar r2)
2210{
2211 IRTemp op1 = newTemp(Ity_I64);
2212 IRTemp op2 = newTemp(Ity_I64);
2213 IRTemp result = newTemp(Ity_I64);
2214
2215 assign(op1, get_gpr_dw0(r1));
2216 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
2217 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2218 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
2219 put_gpr_dw0(r1, mkexpr(result));
2220
2221 return "agfr";
2222}
2223
2224static HChar *
2225s390_irgen_ARK(UChar r3, UChar r1, UChar r2)
2226{
2227 IRTemp op2 = newTemp(Ity_I32);
2228 IRTemp op3 = newTemp(Ity_I32);
2229 IRTemp result = newTemp(Ity_I32);
2230
2231 assign(op2, get_gpr_w1(r2));
2232 assign(op3, get_gpr_w1(r3));
2233 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2234 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
2235 put_gpr_w1(r1, mkexpr(result));
2236
2237 return "ark";
2238}
2239
2240static HChar *
2241s390_irgen_AGRK(UChar r3, UChar r1, UChar r2)
2242{
2243 IRTemp op2 = newTemp(Ity_I64);
2244 IRTemp op3 = newTemp(Ity_I64);
2245 IRTemp result = newTemp(Ity_I64);
2246
2247 assign(op2, get_gpr_dw0(r2));
2248 assign(op3, get_gpr_dw0(r3));
2249 assign(result, binop(Iop_Add64, mkexpr(op2), mkexpr(op3)));
2250 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op2, op3);
2251 put_gpr_dw0(r1, mkexpr(result));
2252
2253 return "agrk";
2254}
2255
2256static HChar *
2257s390_irgen_A(UChar r1, IRTemp op2addr)
2258{
2259 IRTemp op1 = newTemp(Ity_I32);
2260 IRTemp op2 = newTemp(Ity_I32);
2261 IRTemp result = newTemp(Ity_I32);
2262
2263 assign(op1, get_gpr_w1(r1));
2264 assign(op2, load(Ity_I32, mkexpr(op2addr)));
2265 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2266 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2267 put_gpr_w1(r1, mkexpr(result));
2268
2269 return "a";
2270}
2271
2272static HChar *
2273s390_irgen_AY(UChar r1, IRTemp op2addr)
2274{
2275 IRTemp op1 = newTemp(Ity_I32);
2276 IRTemp op2 = newTemp(Ity_I32);
2277 IRTemp result = newTemp(Ity_I32);
2278
2279 assign(op1, get_gpr_w1(r1));
2280 assign(op2, load(Ity_I32, mkexpr(op2addr)));
2281 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2282 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2283 put_gpr_w1(r1, mkexpr(result));
2284
2285 return "ay";
2286}
2287
2288static HChar *
2289s390_irgen_AG(UChar r1, IRTemp op2addr)
2290{
2291 IRTemp op1 = newTemp(Ity_I64);
2292 IRTemp op2 = newTemp(Ity_I64);
2293 IRTemp result = newTemp(Ity_I64);
2294
2295 assign(op1, get_gpr_dw0(r1));
2296 assign(op2, load(Ity_I64, mkexpr(op2addr)));
2297 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2298 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
2299 put_gpr_dw0(r1, mkexpr(result));
2300
2301 return "ag";
2302}
2303
2304static HChar *
2305s390_irgen_AGF(UChar r1, IRTemp op2addr)
2306{
2307 IRTemp op1 = newTemp(Ity_I64);
2308 IRTemp op2 = newTemp(Ity_I64);
2309 IRTemp result = newTemp(Ity_I64);
2310
2311 assign(op1, get_gpr_dw0(r1));
2312 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
2313 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2314 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
2315 put_gpr_dw0(r1, mkexpr(result));
2316
2317 return "agf";
2318}
2319
2320static HChar *
2321s390_irgen_AFI(UChar r1, UInt i2)
2322{
2323 IRTemp op1 = newTemp(Ity_I32);
2324 Int op2;
2325 IRTemp result = newTemp(Ity_I32);
2326
2327 assign(op1, get_gpr_w1(r1));
2328 op2 = (Int)i2;
2329 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
2330 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
2331 mkU32((UInt)op2)));
2332 put_gpr_w1(r1, mkexpr(result));
2333
2334 return "afi";
2335}
2336
2337static HChar *
2338s390_irgen_AGFI(UChar r1, UInt i2)
2339{
2340 IRTemp op1 = newTemp(Ity_I64);
2341 Long op2;
2342 IRTemp result = newTemp(Ity_I64);
2343
2344 assign(op1, get_gpr_dw0(r1));
2345 op2 = (Long)(Int)i2;
2346 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64((ULong)op2)));
2347 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, mktemp(Ity_I64,
2348 mkU64((ULong)op2)));
2349 put_gpr_dw0(r1, mkexpr(result));
2350
2351 return "agfi";
2352}
2353
2354static HChar *
2355s390_irgen_AHIK(UChar r1, UChar r3, UShort i2)
2356{
2357 Int op2;
2358 IRTemp op3 = newTemp(Ity_I32);
2359 IRTemp result = newTemp(Ity_I32);
2360
2361 op2 = (Int)(Short)i2;
2362 assign(op3, get_gpr_w1(r3));
2363 assign(result, binop(Iop_Add32, mkU32((UInt)op2), mkexpr(op3)));
2364 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, mktemp(Ity_I32, mkU32((UInt)
2365 op2)), op3);
2366 put_gpr_w1(r1, mkexpr(result));
2367
2368 return "ahik";
2369}
2370
2371static HChar *
2372s390_irgen_AGHIK(UChar r1, UChar r3, UShort i2)
2373{
2374 Long op2;
2375 IRTemp op3 = newTemp(Ity_I64);
2376 IRTemp result = newTemp(Ity_I64);
2377
2378 op2 = (Long)(Short)i2;
2379 assign(op3, get_gpr_dw0(r3));
2380 assign(result, binop(Iop_Add64, mkU64((ULong)op2), mkexpr(op3)));
2381 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, mktemp(Ity_I64, mkU64((ULong)
2382 op2)), op3);
2383 put_gpr_dw0(r1, mkexpr(result));
2384
2385 return "aghik";
2386}
2387
2388static HChar *
2389s390_irgen_ASI(UChar i2, IRTemp op1addr)
2390{
2391 IRTemp op1 = newTemp(Ity_I32);
2392 Int op2;
2393 IRTemp result = newTemp(Ity_I32);
2394
2395 assign(op1, load(Ity_I32, mkexpr(op1addr)));
2396 op2 = (Int)(Char)i2;
2397 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
2398 store(mkexpr(op1addr), mkexpr(result));
2399 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
2400 mkU32((UInt)op2)));
2401
2402 return "asi";
2403}
2404
2405static HChar *
2406s390_irgen_AGSI(UChar i2, IRTemp op1addr)
2407{
2408 IRTemp op1 = newTemp(Ity_I64);
2409 Long op2;
2410 IRTemp result = newTemp(Ity_I64);
2411
2412 assign(op1, load(Ity_I64, mkexpr(op1addr)));
2413 op2 = (Long)(Char)i2;
2414 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64((ULong)op2)));
2415 store(mkexpr(op1addr), mkexpr(result));
2416 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, mktemp(Ity_I64,
2417 mkU64((ULong)op2)));
2418
2419 return "agsi";
2420}
2421
2422static HChar *
2423s390_irgen_AH(UChar r1, IRTemp op2addr)
2424{
2425 IRTemp op1 = newTemp(Ity_I32);
2426 IRTemp op2 = newTemp(Ity_I32);
2427 IRTemp result = newTemp(Ity_I32);
2428
2429 assign(op1, get_gpr_w1(r1));
2430 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
2431 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2432 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2433 put_gpr_w1(r1, mkexpr(result));
2434
2435 return "ah";
2436}
2437
2438static HChar *
2439s390_irgen_AHY(UChar r1, IRTemp op2addr)
2440{
2441 IRTemp op1 = newTemp(Ity_I32);
2442 IRTemp op2 = newTemp(Ity_I32);
2443 IRTemp result = newTemp(Ity_I32);
2444
2445 assign(op1, get_gpr_w1(r1));
2446 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
2447 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2448 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2449 put_gpr_w1(r1, mkexpr(result));
2450
2451 return "ahy";
2452}
2453
2454static HChar *
2455s390_irgen_AHI(UChar r1, UShort i2)
2456{
2457 IRTemp op1 = newTemp(Ity_I32);
2458 Int op2;
2459 IRTemp result = newTemp(Ity_I32);
2460
2461 assign(op1, get_gpr_w1(r1));
2462 op2 = (Int)(Short)i2;
2463 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
2464 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
2465 mkU32((UInt)op2)));
2466 put_gpr_w1(r1, mkexpr(result));
2467
2468 return "ahi";
2469}
2470
2471static HChar *
2472s390_irgen_AGHI(UChar r1, UShort i2)
2473{
2474 IRTemp op1 = newTemp(Ity_I64);
2475 Long op2;
2476 IRTemp result = newTemp(Ity_I64);
2477
2478 assign(op1, get_gpr_dw0(r1));
2479 op2 = (Long)(Short)i2;
2480 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64((ULong)op2)));
2481 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, mktemp(Ity_I64,
2482 mkU64((ULong)op2)));
2483 put_gpr_dw0(r1, mkexpr(result));
2484
2485 return "aghi";
2486}
2487
2488static HChar *
2489s390_irgen_AHHHR(UChar r3, UChar r1, UChar r2)
2490{
2491 IRTemp op2 = newTemp(Ity_I32);
2492 IRTemp op3 = newTemp(Ity_I32);
2493 IRTemp result = newTemp(Ity_I32);
2494
2495 assign(op2, get_gpr_w0(r2));
2496 assign(op3, get_gpr_w0(r3));
2497 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2498 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
2499 put_gpr_w0(r1, mkexpr(result));
2500
2501 return "ahhhr";
2502}
2503
2504static HChar *
2505s390_irgen_AHHLR(UChar r3, UChar r1, UChar r2)
2506{
2507 IRTemp op2 = newTemp(Ity_I32);
2508 IRTemp op3 = newTemp(Ity_I32);
2509 IRTemp result = newTemp(Ity_I32);
2510
2511 assign(op2, get_gpr_w0(r2));
2512 assign(op3, get_gpr_w1(r3));
2513 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2514 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
2515 put_gpr_w0(r1, mkexpr(result));
2516
2517 return "ahhlr";
2518}
2519
2520static HChar *
2521s390_irgen_AIH(UChar r1, UInt i2)
2522{
2523 IRTemp op1 = newTemp(Ity_I32);
2524 Int op2;
2525 IRTemp result = newTemp(Ity_I32);
2526
2527 assign(op1, get_gpr_w0(r1));
2528 op2 = (Int)i2;
2529 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
2530 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
2531 mkU32((UInt)op2)));
2532 put_gpr_w0(r1, mkexpr(result));
2533
2534 return "aih";
2535}
2536
2537static HChar *
2538s390_irgen_ALR(UChar r1, UChar r2)
2539{
2540 IRTemp op1 = newTemp(Ity_I32);
2541 IRTemp op2 = newTemp(Ity_I32);
2542 IRTemp result = newTemp(Ity_I32);
2543
2544 assign(op1, get_gpr_w1(r1));
2545 assign(op2, get_gpr_w1(r2));
2546 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2547 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, op2);
2548 put_gpr_w1(r1, mkexpr(result));
2549
2550 return "alr";
2551}
2552
2553static HChar *
2554s390_irgen_ALGR(UChar r1, UChar r2)
2555{
2556 IRTemp op1 = newTemp(Ity_I64);
2557 IRTemp op2 = newTemp(Ity_I64);
2558 IRTemp result = newTemp(Ity_I64);
2559
2560 assign(op1, get_gpr_dw0(r1));
2561 assign(op2, get_gpr_dw0(r2));
2562 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2563 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
2564 put_gpr_dw0(r1, mkexpr(result));
2565
2566 return "algr";
2567}
2568
2569static HChar *
2570s390_irgen_ALGFR(UChar r1, UChar r2)
2571{
2572 IRTemp op1 = newTemp(Ity_I64);
2573 IRTemp op2 = newTemp(Ity_I64);
2574 IRTemp result = newTemp(Ity_I64);
2575
2576 assign(op1, get_gpr_dw0(r1));
2577 assign(op2, unop(Iop_32Uto64, get_gpr_w1(r2)));
2578 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2579 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
2580 put_gpr_dw0(r1, mkexpr(result));
2581
2582 return "algfr";
2583}
2584
2585static HChar *
2586s390_irgen_ALRK(UChar r3, UChar r1, UChar r2)
2587{
2588 IRTemp op2 = newTemp(Ity_I32);
2589 IRTemp op3 = newTemp(Ity_I32);
2590 IRTemp result = newTemp(Ity_I32);
2591
2592 assign(op2, get_gpr_w1(r2));
2593 assign(op3, get_gpr_w1(r3));
2594 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2595 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
2596 put_gpr_w1(r1, mkexpr(result));
2597
2598 return "alrk";
2599}
2600
2601static HChar *
2602s390_irgen_ALGRK(UChar r3, UChar r1, UChar r2)
2603{
2604 IRTemp op2 = newTemp(Ity_I64);
2605 IRTemp op3 = newTemp(Ity_I64);
2606 IRTemp result = newTemp(Ity_I64);
2607
2608 assign(op2, get_gpr_dw0(r2));
2609 assign(op3, get_gpr_dw0(r3));
2610 assign(result, binop(Iop_Add64, mkexpr(op2), mkexpr(op3)));
2611 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op2, op3);
2612 put_gpr_dw0(r1, mkexpr(result));
2613
2614 return "algrk";
2615}
2616
2617static HChar *
2618s390_irgen_AL(UChar r1, IRTemp op2addr)
2619{
2620 IRTemp op1 = newTemp(Ity_I32);
2621 IRTemp op2 = newTemp(Ity_I32);
2622 IRTemp result = newTemp(Ity_I32);
2623
2624 assign(op1, get_gpr_w1(r1));
2625 assign(op2, load(Ity_I32, mkexpr(op2addr)));
2626 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2627 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, op2);
2628 put_gpr_w1(r1, mkexpr(result));
2629
2630 return "al";
2631}
2632
2633static HChar *
2634s390_irgen_ALY(UChar r1, IRTemp op2addr)
2635{
2636 IRTemp op1 = newTemp(Ity_I32);
2637 IRTemp op2 = newTemp(Ity_I32);
2638 IRTemp result = newTemp(Ity_I32);
2639
2640 assign(op1, get_gpr_w1(r1));
2641 assign(op2, load(Ity_I32, mkexpr(op2addr)));
2642 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2643 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, op2);
2644 put_gpr_w1(r1, mkexpr(result));
2645
2646 return "aly";
2647}
2648
2649static HChar *
2650s390_irgen_ALG(UChar r1, IRTemp op2addr)
2651{
2652 IRTemp op1 = newTemp(Ity_I64);
2653 IRTemp op2 = newTemp(Ity_I64);
2654 IRTemp result = newTemp(Ity_I64);
2655
2656 assign(op1, get_gpr_dw0(r1));
2657 assign(op2, load(Ity_I64, mkexpr(op2addr)));
2658 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2659 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
2660 put_gpr_dw0(r1, mkexpr(result));
2661
2662 return "alg";
2663}
2664
2665static HChar *
2666s390_irgen_ALGF(UChar r1, IRTemp op2addr)
2667{
2668 IRTemp op1 = newTemp(Ity_I64);
2669 IRTemp op2 = newTemp(Ity_I64);
2670 IRTemp result = newTemp(Ity_I64);
2671
2672 assign(op1, get_gpr_dw0(r1));
2673 assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
2674 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2675 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
2676 put_gpr_dw0(r1, mkexpr(result));
2677
2678 return "algf";
2679}
2680
2681static HChar *
2682s390_irgen_ALFI(UChar r1, UInt i2)
2683{
2684 IRTemp op1 = newTemp(Ity_I32);
2685 UInt op2;
2686 IRTemp result = newTemp(Ity_I32);
2687
2688 assign(op1, get_gpr_w1(r1));
2689 op2 = i2;
2690 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
2691 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, mktemp(Ity_I32,
2692 mkU32(op2)));
2693 put_gpr_w1(r1, mkexpr(result));
2694
2695 return "alfi";
2696}
2697
2698static HChar *
2699s390_irgen_ALGFI(UChar r1, UInt i2)
2700{
2701 IRTemp op1 = newTemp(Ity_I64);
2702 ULong op2;
2703 IRTemp result = newTemp(Ity_I64);
2704
2705 assign(op1, get_gpr_dw0(r1));
2706 op2 = (ULong)i2;
2707 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64(op2)));
2708 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, mktemp(Ity_I64,
2709 mkU64(op2)));
2710 put_gpr_dw0(r1, mkexpr(result));
2711
2712 return "algfi";
2713}
2714
2715static HChar *
2716s390_irgen_ALHHHR(UChar r3, UChar r1, UChar r2)
2717{
2718 IRTemp op2 = newTemp(Ity_I32);
2719 IRTemp op3 = newTemp(Ity_I32);
2720 IRTemp result = newTemp(Ity_I32);
2721
2722 assign(op2, get_gpr_w0(r2));
2723 assign(op3, get_gpr_w0(r3));
2724 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2725 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
2726 put_gpr_w0(r1, mkexpr(result));
2727
2728 return "alhhhr";
2729}
2730
2731static HChar *
2732s390_irgen_ALHHLR(UChar r3, UChar r1, UChar r2)
2733{
2734 IRTemp op2 = newTemp(Ity_I32);
2735 IRTemp op3 = newTemp(Ity_I32);
2736 IRTemp result = newTemp(Ity_I32);
2737
2738 assign(op2, get_gpr_w0(r2));
2739 assign(op3, get_gpr_w1(r3));
2740 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2741 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
2742 put_gpr_w0(r1, mkexpr(result));
2743
2744 return "alhhlr";
2745}
2746
2747static HChar *
2748s390_irgen_ALCR(UChar r1, UChar r2)
2749{
2750 IRTemp op1 = newTemp(Ity_I32);
2751 IRTemp op2 = newTemp(Ity_I32);
2752 IRTemp result = newTemp(Ity_I32);
2753 IRTemp carry_in = newTemp(Ity_I32);
2754
2755 assign(op1, get_gpr_w1(r1));
2756 assign(op2, get_gpr_w1(r2));
2757 assign(carry_in, binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)));
2758 assign(result, binop(Iop_Add32, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)),
2759 mkexpr(carry_in)));
2760 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_32, op1, op2, carry_in);
2761 put_gpr_w1(r1, mkexpr(result));
2762
2763 return "alcr";
2764}
2765
2766static HChar *
2767s390_irgen_ALCGR(UChar r1, UChar r2)
2768{
2769 IRTemp op1 = newTemp(Ity_I64);
2770 IRTemp op2 = newTemp(Ity_I64);
2771 IRTemp result = newTemp(Ity_I64);
2772 IRTemp carry_in = newTemp(Ity_I64);
2773
2774 assign(op1, get_gpr_dw0(r1));
2775 assign(op2, get_gpr_dw0(r2));
2776 assign(carry_in, unop(Iop_32Uto64, binop(Iop_Shr32, s390_call_calculate_cc(),
2777 mkU8(1))));
2778 assign(result, binop(Iop_Add64, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)),
2779 mkexpr(carry_in)));
2780 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_64, op1, op2, carry_in);
2781 put_gpr_dw0(r1, mkexpr(result));
2782
2783 return "alcgr";
2784}
2785
2786static HChar *
2787s390_irgen_ALC(UChar r1, IRTemp op2addr)
2788{
2789 IRTemp op1 = newTemp(Ity_I32);
2790 IRTemp op2 = newTemp(Ity_I32);
2791 IRTemp result = newTemp(Ity_I32);
2792 IRTemp carry_in = newTemp(Ity_I32);
2793
2794 assign(op1, get_gpr_w1(r1));
2795 assign(op2, load(Ity_I32, mkexpr(op2addr)));
2796 assign(carry_in, binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)));
2797 assign(result, binop(Iop_Add32, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)),
2798 mkexpr(carry_in)));
2799 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_32, op1, op2, carry_in);
2800 put_gpr_w1(r1, mkexpr(result));
2801
2802 return "alc";
2803}
2804
2805static HChar *
2806s390_irgen_ALCG(UChar r1, IRTemp op2addr)
2807{
2808 IRTemp op1 = newTemp(Ity_I64);
2809 IRTemp op2 = newTemp(Ity_I64);
2810 IRTemp result = newTemp(Ity_I64);
2811 IRTemp carry_in = newTemp(Ity_I64);
2812
2813 assign(op1, get_gpr_dw0(r1));
2814 assign(op2, load(Ity_I64, mkexpr(op2addr)));
2815 assign(carry_in, unop(Iop_32Uto64, binop(Iop_Shr32, s390_call_calculate_cc(),
2816 mkU8(1))));
2817 assign(result, binop(Iop_Add64, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)),
2818 mkexpr(carry_in)));
2819 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_64, op1, op2, carry_in);
2820 put_gpr_dw0(r1, mkexpr(result));
2821
2822 return "alcg";
2823}
2824
2825static HChar *
2826s390_irgen_ALSI(UChar i2, IRTemp op1addr)
2827{
2828 IRTemp op1 = newTemp(Ity_I32);
2829 UInt op2;
2830 IRTemp result = newTemp(Ity_I32);
2831
2832 assign(op1, load(Ity_I32, mkexpr(op1addr)));
2833 op2 = (UInt)(Int)(Char)i2;
2834 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
2835 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, mktemp(Ity_I32,
2836 mkU32(op2)));
2837 store(mkexpr(op1addr), mkexpr(result));
2838
2839 return "alsi";
2840}
2841
2842static HChar *
2843s390_irgen_ALGSI(UChar i2, IRTemp op1addr)
2844{
2845 IRTemp op1 = newTemp(Ity_I64);
2846 ULong op2;
2847 IRTemp result = newTemp(Ity_I64);
2848
2849 assign(op1, load(Ity_I64, mkexpr(op1addr)));
2850 op2 = (ULong)(Long)(Char)i2;
2851 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64(op2)));
2852 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, mktemp(Ity_I64,
2853 mkU64(op2)));
2854 store(mkexpr(op1addr), mkexpr(result));
2855
2856 return "algsi";
2857}
2858
2859static HChar *
2860s390_irgen_ALHSIK(UChar r1, UChar r3, UShort i2)
2861{
2862 UInt op2;
2863 IRTemp op3 = newTemp(Ity_I32);
2864 IRTemp result = newTemp(Ity_I32);
2865
2866 op2 = (UInt)(Int)(Short)i2;
2867 assign(op3, get_gpr_w1(r3));
2868 assign(result, binop(Iop_Add32, mkU32(op2), mkexpr(op3)));
2869 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, mktemp(Ity_I32, mkU32(op2)),
2870 op3);
2871 put_gpr_w1(r1, mkexpr(result));
2872
2873 return "alhsik";
2874}
2875
2876static HChar *
2877s390_irgen_ALGHSIK(UChar r1, UChar r3, UShort i2)
2878{
2879 ULong op2;
2880 IRTemp op3 = newTemp(Ity_I64);
2881 IRTemp result = newTemp(Ity_I64);
2882
2883 op2 = (ULong)(Long)(Short)i2;
2884 assign(op3, get_gpr_dw0(r3));
2885 assign(result, binop(Iop_Add64, mkU64(op2), mkexpr(op3)));
2886 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, mktemp(Ity_I64, mkU64(op2)),
2887 op3);
2888 put_gpr_dw0(r1, mkexpr(result));
2889
2890 return "alghsik";
2891}
2892
2893static HChar *
2894s390_irgen_ALSIH(UChar r1, UInt i2)
2895{
2896 IRTemp op1 = newTemp(Ity_I32);
2897 UInt op2;
2898 IRTemp result = newTemp(Ity_I32);
2899
2900 assign(op1, get_gpr_w0(r1));
2901 op2 = i2;
2902 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
2903 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, mktemp(Ity_I32,
2904 mkU32(op2)));
2905 put_gpr_w0(r1, mkexpr(result));
2906
2907 return "alsih";
2908}
2909
2910static HChar *
2911s390_irgen_ALSIHN(UChar r1, UInt i2)
2912{
2913 IRTemp op1 = newTemp(Ity_I32);
2914 UInt op2;
2915 IRTemp result = newTemp(Ity_I32);
2916
2917 assign(op1, get_gpr_w0(r1));
2918 op2 = i2;
2919 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
2920 put_gpr_w0(r1, mkexpr(result));
2921
2922 return "alsihn";
2923}
2924
2925static HChar *
2926s390_irgen_NR(UChar r1, UChar r2)
2927{
2928 IRTemp op1 = newTemp(Ity_I32);
2929 IRTemp op2 = newTemp(Ity_I32);
2930 IRTemp result = newTemp(Ity_I32);
2931
2932 assign(op1, get_gpr_w1(r1));
2933 assign(op2, get_gpr_w1(r2));
2934 assign(result, binop(Iop_And32, mkexpr(op1), mkexpr(op2)));
2935 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
2936 put_gpr_w1(r1, mkexpr(result));
2937
2938 return "nr";
2939}
2940
2941static HChar *
2942s390_irgen_NGR(UChar r1, UChar r2)
2943{
2944 IRTemp op1 = newTemp(Ity_I64);
2945 IRTemp op2 = newTemp(Ity_I64);
2946 IRTemp result = newTemp(Ity_I64);
2947
2948 assign(op1, get_gpr_dw0(r1));
2949 assign(op2, get_gpr_dw0(r2));
2950 assign(result, binop(Iop_And64, mkexpr(op1), mkexpr(op2)));
2951 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
2952 put_gpr_dw0(r1, mkexpr(result));
2953
2954 return "ngr";
2955}
2956
2957static HChar *
2958s390_irgen_NRK(UChar r3, UChar r1, UChar r2)
2959{
2960 IRTemp op2 = newTemp(Ity_I32);
2961 IRTemp op3 = newTemp(Ity_I32);
2962 IRTemp result = newTemp(Ity_I32);
2963
2964 assign(op2, get_gpr_w1(r2));
2965 assign(op3, get_gpr_w1(r3));
2966 assign(result, binop(Iop_And32, mkexpr(op2), mkexpr(op3)));
2967 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
2968 put_gpr_w1(r1, mkexpr(result));
2969
2970 return "nrk";
2971}
2972
2973static HChar *
2974s390_irgen_NGRK(UChar r3, UChar r1, UChar r2)
2975{
2976 IRTemp op2 = newTemp(Ity_I64);
2977 IRTemp op3 = newTemp(Ity_I64);
2978 IRTemp result = newTemp(Ity_I64);
2979
2980 assign(op2, get_gpr_dw0(r2));
2981 assign(op3, get_gpr_dw0(r3));
2982 assign(result, binop(Iop_And64, mkexpr(op2), mkexpr(op3)));
2983 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
2984 put_gpr_dw0(r1, mkexpr(result));
2985
2986 return "ngrk";
2987}
2988
2989static HChar *
2990s390_irgen_N(UChar r1, IRTemp op2addr)
2991{
2992 IRTemp op1 = newTemp(Ity_I32);
2993 IRTemp op2 = newTemp(Ity_I32);
2994 IRTemp result = newTemp(Ity_I32);
2995
2996 assign(op1, get_gpr_w1(r1));
2997 assign(op2, load(Ity_I32, mkexpr(op2addr)));
2998 assign(result, binop(Iop_And32, mkexpr(op1), mkexpr(op2)));
2999 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3000 put_gpr_w1(r1, mkexpr(result));
3001
3002 return "n";
3003}
3004
3005static HChar *
3006s390_irgen_NY(UChar r1, IRTemp op2addr)
3007{
3008 IRTemp op1 = newTemp(Ity_I32);
3009 IRTemp op2 = newTemp(Ity_I32);
3010 IRTemp result = newTemp(Ity_I32);
3011
3012 assign(op1, get_gpr_w1(r1));
3013 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3014 assign(result, binop(Iop_And32, mkexpr(op1), mkexpr(op2)));
3015 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3016 put_gpr_w1(r1, mkexpr(result));
3017
3018 return "ny";
3019}
3020
3021static HChar *
3022s390_irgen_NG(UChar r1, IRTemp op2addr)
3023{
3024 IRTemp op1 = newTemp(Ity_I64);
3025 IRTemp op2 = newTemp(Ity_I64);
3026 IRTemp result = newTemp(Ity_I64);
3027
3028 assign(op1, get_gpr_dw0(r1));
3029 assign(op2, load(Ity_I64, mkexpr(op2addr)));
3030 assign(result, binop(Iop_And64, mkexpr(op1), mkexpr(op2)));
3031 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3032 put_gpr_dw0(r1, mkexpr(result));
3033
3034 return "ng";
3035}
3036
3037static HChar *
3038s390_irgen_NI(UChar i2, IRTemp op1addr)
3039{
3040 IRTemp op1 = newTemp(Ity_I8);
3041 UChar op2;
3042 IRTemp result = newTemp(Ity_I8);
3043
3044 assign(op1, load(Ity_I8, mkexpr(op1addr)));
3045 op2 = i2;
3046 assign(result, binop(Iop_And8, mkexpr(op1), mkU8(op2)));
3047 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3048 store(mkexpr(op1addr), mkexpr(result));
3049
3050 return "ni";
3051}
3052
3053static HChar *
3054s390_irgen_NIY(UChar i2, IRTemp op1addr)
3055{
3056 IRTemp op1 = newTemp(Ity_I8);
3057 UChar op2;
3058 IRTemp result = newTemp(Ity_I8);
3059
3060 assign(op1, load(Ity_I8, mkexpr(op1addr)));
3061 op2 = i2;
3062 assign(result, binop(Iop_And8, mkexpr(op1), mkU8(op2)));
3063 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3064 store(mkexpr(op1addr), mkexpr(result));
3065
3066 return "niy";
3067}
3068
3069static HChar *
3070s390_irgen_NIHF(UChar r1, UInt i2)
3071{
3072 IRTemp op1 = newTemp(Ity_I32);
3073 UInt op2;
3074 IRTemp result = newTemp(Ity_I32);
3075
3076 assign(op1, get_gpr_w0(r1));
3077 op2 = i2;
3078 assign(result, binop(Iop_And32, mkexpr(op1), mkU32(op2)));
3079 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3080 put_gpr_w0(r1, mkexpr(result));
3081
3082 return "nihf";
3083}
3084
3085static HChar *
3086s390_irgen_NIHH(UChar r1, UShort i2)
3087{
3088 IRTemp op1 = newTemp(Ity_I16);
3089 UShort op2;
3090 IRTemp result = newTemp(Ity_I16);
3091
3092 assign(op1, get_gpr_hw0(r1));
3093 op2 = i2;
3094 assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
3095 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3096 put_gpr_hw0(r1, mkexpr(result));
3097
3098 return "nihh";
3099}
3100
3101static HChar *
3102s390_irgen_NIHL(UChar r1, UShort i2)
3103{
3104 IRTemp op1 = newTemp(Ity_I16);
3105 UShort op2;
3106 IRTemp result = newTemp(Ity_I16);
3107
3108 assign(op1, get_gpr_hw1(r1));
3109 op2 = i2;
3110 assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
3111 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3112 put_gpr_hw1(r1, mkexpr(result));
3113
3114 return "nihl";
3115}
3116
3117static HChar *
3118s390_irgen_NILF(UChar r1, UInt i2)
3119{
3120 IRTemp op1 = newTemp(Ity_I32);
3121 UInt op2;
3122 IRTemp result = newTemp(Ity_I32);
3123
3124 assign(op1, get_gpr_w1(r1));
3125 op2 = i2;
3126 assign(result, binop(Iop_And32, mkexpr(op1), mkU32(op2)));
3127 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3128 put_gpr_w1(r1, mkexpr(result));
3129
3130 return "nilf";
3131}
3132
3133static HChar *
3134s390_irgen_NILH(UChar r1, UShort i2)
3135{
3136 IRTemp op1 = newTemp(Ity_I16);
3137 UShort op2;
3138 IRTemp result = newTemp(Ity_I16);
3139
3140 assign(op1, get_gpr_hw2(r1));
3141 op2 = i2;
3142 assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
3143 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3144 put_gpr_hw2(r1, mkexpr(result));
3145
3146 return "nilh";
3147}
3148
3149static HChar *
3150s390_irgen_NILL(UChar r1, UShort i2)
3151{
3152 IRTemp op1 = newTemp(Ity_I16);
3153 UShort op2;
3154 IRTemp result = newTemp(Ity_I16);
3155
3156 assign(op1, get_gpr_hw3(r1));
3157 op2 = i2;
3158 assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
3159 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3160 put_gpr_hw3(r1, mkexpr(result));
3161
3162 return "nill";
3163}
3164
3165static HChar *
3166s390_irgen_BASR(UChar r1, UChar r2)
3167{
3168 IRTemp target = newTemp(Ity_I64);
3169
3170 if (r2 == 0) {
3171 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 2ULL));
3172 } else {
3173 if (r1 != r2) {
3174 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 2ULL));
3175 call_function(get_gpr_dw0(r2));
3176 } else {
3177 assign(target, get_gpr_dw0(r2));
3178 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 2ULL));
3179 call_function(mkexpr(target));
3180 }
3181 }
3182
3183 return "basr";
3184}
3185
3186static HChar *
3187s390_irgen_BAS(UChar r1, IRTemp op2addr)
3188{
3189 IRTemp target = newTemp(Ity_I64);
3190
3191 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 4ULL));
3192 assign(target, mkexpr(op2addr));
3193 call_function(mkexpr(target));
3194
3195 return "bas";
3196}
3197
3198static HChar *
3199s390_irgen_BCR(UChar r1, UChar r2)
3200{
3201 IRTemp cond = newTemp(Ity_I32);
3202
sewardja52e37e2011-04-28 18:48:06 +00003203 if (r2 == 0 && (r1 >= 14)) { /* serialization */
3204 stmt(IRStmt_MBE(Imbe_Fence));
3205 }
3206
sewardj2019a972011-03-07 16:04:07 +00003207 if ((r2 == 0) || (r1 == 0)) {
3208 } else {
3209 if (r1 == 15) {
3210 return_from_function(get_gpr_dw0(r2));
3211 } else {
3212 assign(cond, s390_call_calculate_cond(r1));
florianf321da72012-07-21 20:32:57 +00003213 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3214 get_gpr_dw0(r2));
sewardj2019a972011-03-07 16:04:07 +00003215 }
3216 }
sewardj7ee97522011-05-09 21:45:04 +00003217 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00003218 s390_disasm(ENC2(XMNM, GPR), S390_XMNM_BCR, r1, r2);
3219
3220 return "bcr";
3221}
3222
3223static HChar *
3224s390_irgen_BC(UChar r1, UChar x2, UChar b2, UShort d2, IRTemp op2addr)
3225{
3226 IRTemp cond = newTemp(Ity_I32);
3227
3228 if (r1 == 0) {
3229 } else {
3230 if (r1 == 15) {
3231 always_goto(mkexpr(op2addr));
3232 } else {
3233 assign(cond, s390_call_calculate_cond(r1));
florianf321da72012-07-21 20:32:57 +00003234 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3235 mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003236 }
3237 }
sewardj7ee97522011-05-09 21:45:04 +00003238 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00003239 s390_disasm(ENC2(XMNM, UDXB), S390_XMNM_BC, r1, d2, x2, b2);
3240
3241 return "bc";
3242}
3243
3244static HChar *
3245s390_irgen_BCTR(UChar r1, UChar r2)
3246{
3247 put_gpr_w1(r1, binop(Iop_Sub32, get_gpr_w1(r1), mkU32(1)));
3248 if (r2 != 0) {
florianf321da72012-07-21 20:32:57 +00003249 if_condition_goto_computed(binop(Iop_CmpNE32, get_gpr_w1(r1), mkU32(0)),
3250 get_gpr_dw0(r2));
sewardj2019a972011-03-07 16:04:07 +00003251 }
3252
3253 return "bctr";
3254}
3255
3256static HChar *
3257s390_irgen_BCTGR(UChar r1, UChar r2)
3258{
3259 put_gpr_dw0(r1, binop(Iop_Sub64, get_gpr_dw0(r1), mkU64(1)));
3260 if (r2 != 0) {
florianf321da72012-07-21 20:32:57 +00003261 if_condition_goto_computed(binop(Iop_CmpNE64, get_gpr_dw0(r1), mkU64(0)),
3262 get_gpr_dw0(r2));
sewardj2019a972011-03-07 16:04:07 +00003263 }
3264
3265 return "bctgr";
3266}
3267
3268static HChar *
3269s390_irgen_BCT(UChar r1, IRTemp op2addr)
3270{
3271 put_gpr_w1(r1, binop(Iop_Sub32, get_gpr_w1(r1), mkU32(1)));
florianf321da72012-07-21 20:32:57 +00003272 if_condition_goto_computed(binop(Iop_CmpNE32, get_gpr_w1(r1), mkU32(0)),
3273 mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003274
3275 return "bct";
3276}
3277
3278static HChar *
3279s390_irgen_BCTG(UChar r1, IRTemp op2addr)
3280{
3281 put_gpr_dw0(r1, binop(Iop_Sub64, get_gpr_dw0(r1), mkU64(1)));
florianf321da72012-07-21 20:32:57 +00003282 if_condition_goto_computed(binop(Iop_CmpNE64, get_gpr_dw0(r1), mkU64(0)),
3283 mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003284
3285 return "bctg";
3286}
3287
3288static HChar *
3289s390_irgen_BXH(UChar r1, UChar r3, IRTemp op2addr)
3290{
3291 IRTemp value = newTemp(Ity_I32);
3292
3293 assign(value, get_gpr_w1(r3 | 1));
3294 put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
florianf321da72012-07-21 20:32:57 +00003295 if_condition_goto_computed(binop(Iop_CmpLT32S, mkexpr(value),
3296 get_gpr_w1(r1)), mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003297
3298 return "bxh";
3299}
3300
3301static HChar *
3302s390_irgen_BXHG(UChar r1, UChar r3, IRTemp op2addr)
3303{
3304 IRTemp value = newTemp(Ity_I64);
3305
3306 assign(value, get_gpr_dw0(r3 | 1));
3307 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
florianf321da72012-07-21 20:32:57 +00003308 if_condition_goto_computed(binop(Iop_CmpLT64S, mkexpr(value),
3309 get_gpr_dw0(r1)), mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003310
3311 return "bxhg";
3312}
3313
3314static HChar *
3315s390_irgen_BXLE(UChar r1, UChar r3, IRTemp op2addr)
3316{
3317 IRTemp value = newTemp(Ity_I32);
3318
3319 assign(value, get_gpr_w1(r3 | 1));
3320 put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
florianf321da72012-07-21 20:32:57 +00003321 if_condition_goto_computed(binop(Iop_CmpLE32S, get_gpr_w1(r1),
3322 mkexpr(value)), mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003323
3324 return "bxle";
3325}
3326
3327static HChar *
3328s390_irgen_BXLEG(UChar r1, UChar r3, IRTemp op2addr)
3329{
3330 IRTemp value = newTemp(Ity_I64);
3331
3332 assign(value, get_gpr_dw0(r3 | 1));
3333 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
florianf321da72012-07-21 20:32:57 +00003334 if_condition_goto_computed(binop(Iop_CmpLE64S, get_gpr_dw0(r1),
3335 mkexpr(value)), mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003336
3337 return "bxleg";
3338}
3339
3340static HChar *
3341s390_irgen_BRAS(UChar r1, UShort i2)
3342{
3343 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 4ULL));
floriana64c2432011-07-16 02:11:50 +00003344 call_function_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
sewardj2019a972011-03-07 16:04:07 +00003345
3346 return "bras";
3347}
3348
3349static HChar *
3350s390_irgen_BRASL(UChar r1, UInt i2)
3351{
3352 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 6ULL));
floriana64c2432011-07-16 02:11:50 +00003353 call_function_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1));
sewardj2019a972011-03-07 16:04:07 +00003354
3355 return "brasl";
3356}
3357
3358static HChar *
3359s390_irgen_BRC(UChar r1, UShort i2)
3360{
3361 IRTemp cond = newTemp(Ity_I32);
3362
3363 if (r1 == 0) {
3364 } else {
3365 if (r1 == 15) {
floriana64c2432011-07-16 02:11:50 +00003366 always_goto_and_chase(
3367 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
sewardj2019a972011-03-07 16:04:07 +00003368 } else {
3369 assign(cond, s390_call_calculate_cond(r1));
3370 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3371 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3372
3373 }
3374 }
sewardj7ee97522011-05-09 21:45:04 +00003375 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00003376 s390_disasm(ENC2(XMNM, PCREL), S390_XMNM_BRC, r1, (Int)(Short)i2);
3377
3378 return "brc";
3379}
3380
3381static HChar *
3382s390_irgen_BRCL(UChar r1, UInt i2)
3383{
3384 IRTemp cond = newTemp(Ity_I32);
3385
3386 if (r1 == 0) {
3387 } else {
3388 if (r1 == 15) {
floriana64c2432011-07-16 02:11:50 +00003389 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1));
sewardj2019a972011-03-07 16:04:07 +00003390 } else {
3391 assign(cond, s390_call_calculate_cond(r1));
3392 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3393 guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1));
3394 }
3395 }
sewardj7ee97522011-05-09 21:45:04 +00003396 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00003397 s390_disasm(ENC2(XMNM, PCREL), S390_XMNM_BRCL, r1, i2);
3398
3399 return "brcl";
3400}
3401
3402static HChar *
3403s390_irgen_BRCT(UChar r1, UShort i2)
3404{
3405 put_gpr_w1(r1, binop(Iop_Sub32, get_gpr_w1(r1), mkU32(1)));
3406 if_condition_goto(binop(Iop_CmpNE32, get_gpr_w1(r1), mkU32(0)),
3407 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3408
3409 return "brct";
3410}
3411
3412static HChar *
3413s390_irgen_BRCTG(UChar r1, UShort i2)
3414{
3415 put_gpr_dw0(r1, binop(Iop_Sub64, get_gpr_dw0(r1), mkU64(1)));
3416 if_condition_goto(binop(Iop_CmpNE64, get_gpr_dw0(r1), mkU64(0)),
3417 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3418
3419 return "brctg";
3420}
3421
3422static HChar *
3423s390_irgen_BRXH(UChar r1, UChar r3, UShort i2)
3424{
3425 IRTemp value = newTemp(Ity_I32);
3426
3427 assign(value, get_gpr_w1(r3 | 1));
3428 put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
3429 if_condition_goto(binop(Iop_CmpLT32S, mkexpr(value), get_gpr_w1(r1)),
3430 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3431
3432 return "brxh";
3433}
3434
3435static HChar *
3436s390_irgen_BRXHG(UChar r1, UChar r3, UShort i2)
3437{
3438 IRTemp value = newTemp(Ity_I64);
3439
3440 assign(value, get_gpr_dw0(r3 | 1));
3441 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
3442 if_condition_goto(binop(Iop_CmpLT64S, mkexpr(value), get_gpr_dw0(r1)),
3443 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3444
3445 return "brxhg";
3446}
3447
3448static HChar *
3449s390_irgen_BRXLE(UChar r1, UChar r3, UShort i2)
3450{
3451 IRTemp value = newTemp(Ity_I32);
3452
3453 assign(value, get_gpr_w1(r3 | 1));
3454 put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
3455 if_condition_goto(binop(Iop_CmpLE32S, get_gpr_w1(r1), mkexpr(value)),
3456 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3457
3458 return "brxle";
3459}
3460
3461static HChar *
3462s390_irgen_BRXLG(UChar r1, UChar r3, UShort i2)
3463{
3464 IRTemp value = newTemp(Ity_I64);
3465
3466 assign(value, get_gpr_dw0(r3 | 1));
3467 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
3468 if_condition_goto(binop(Iop_CmpLE64S, get_gpr_dw0(r1), mkexpr(value)),
3469 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3470
3471 return "brxlg";
3472}
3473
3474static HChar *
3475s390_irgen_CR(UChar r1, UChar r2)
3476{
3477 IRTemp op1 = newTemp(Ity_I32);
3478 IRTemp op2 = newTemp(Ity_I32);
3479
3480 assign(op1, get_gpr_w1(r1));
3481 assign(op2, get_gpr_w1(r2));
3482 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3483
3484 return "cr";
3485}
3486
3487static HChar *
3488s390_irgen_CGR(UChar r1, UChar r2)
3489{
3490 IRTemp op1 = newTemp(Ity_I64);
3491 IRTemp op2 = newTemp(Ity_I64);
3492
3493 assign(op1, get_gpr_dw0(r1));
3494 assign(op2, get_gpr_dw0(r2));
3495 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3496
3497 return "cgr";
3498}
3499
3500static HChar *
3501s390_irgen_CGFR(UChar r1, UChar r2)
3502{
3503 IRTemp op1 = newTemp(Ity_I64);
3504 IRTemp op2 = newTemp(Ity_I64);
3505
3506 assign(op1, get_gpr_dw0(r1));
3507 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
3508 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3509
3510 return "cgfr";
3511}
3512
3513static HChar *
3514s390_irgen_C(UChar r1, IRTemp op2addr)
3515{
3516 IRTemp op1 = newTemp(Ity_I32);
3517 IRTemp op2 = newTemp(Ity_I32);
3518
3519 assign(op1, get_gpr_w1(r1));
3520 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3521 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3522
3523 return "c";
3524}
3525
3526static HChar *
3527s390_irgen_CY(UChar r1, IRTemp op2addr)
3528{
3529 IRTemp op1 = newTemp(Ity_I32);
3530 IRTemp op2 = newTemp(Ity_I32);
3531
3532 assign(op1, get_gpr_w1(r1));
3533 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3534 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3535
3536 return "cy";
3537}
3538
3539static HChar *
3540s390_irgen_CG(UChar r1, IRTemp op2addr)
3541{
3542 IRTemp op1 = newTemp(Ity_I64);
3543 IRTemp op2 = newTemp(Ity_I64);
3544
3545 assign(op1, get_gpr_dw0(r1));
3546 assign(op2, load(Ity_I64, mkexpr(op2addr)));
3547 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3548
3549 return "cg";
3550}
3551
3552static HChar *
3553s390_irgen_CGF(UChar r1, IRTemp op2addr)
3554{
3555 IRTemp op1 = newTemp(Ity_I64);
3556 IRTemp op2 = newTemp(Ity_I64);
3557
3558 assign(op1, get_gpr_dw0(r1));
3559 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
3560 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3561
3562 return "cgf";
3563}
3564
3565static HChar *
3566s390_irgen_CFI(UChar r1, UInt i2)
3567{
3568 IRTemp op1 = newTemp(Ity_I32);
3569 Int op2;
3570
3571 assign(op1, get_gpr_w1(r1));
3572 op2 = (Int)i2;
3573 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
3574 mkU32((UInt)op2)));
3575
3576 return "cfi";
3577}
3578
3579static HChar *
3580s390_irgen_CGFI(UChar r1, UInt i2)
3581{
3582 IRTemp op1 = newTemp(Ity_I64);
3583 Long op2;
3584
3585 assign(op1, get_gpr_dw0(r1));
3586 op2 = (Long)(Int)i2;
3587 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I64,
3588 mkU64((ULong)op2)));
3589
3590 return "cgfi";
3591}
3592
3593static HChar *
3594s390_irgen_CRL(UChar r1, UInt i2)
3595{
3596 IRTemp op1 = newTemp(Ity_I32);
3597 IRTemp op2 = newTemp(Ity_I32);
3598
3599 assign(op1, get_gpr_w1(r1));
3600 assign(op2, load(Ity_I32, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
3601 i2 << 1))));
3602 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3603
3604 return "crl";
3605}
3606
3607static HChar *
3608s390_irgen_CGRL(UChar r1, UInt i2)
3609{
3610 IRTemp op1 = newTemp(Ity_I64);
3611 IRTemp op2 = newTemp(Ity_I64);
3612
3613 assign(op1, get_gpr_dw0(r1));
3614 assign(op2, load(Ity_I64, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
3615 i2 << 1))));
3616 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3617
3618 return "cgrl";
3619}
3620
3621static HChar *
3622s390_irgen_CGFRL(UChar r1, UInt i2)
3623{
3624 IRTemp op1 = newTemp(Ity_I64);
3625 IRTemp op2 = newTemp(Ity_I64);
3626
3627 assign(op1, get_gpr_dw0(r1));
3628 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
3629 ((ULong)(Long)(Int)i2 << 1)))));
3630 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3631
3632 return "cgfrl";
3633}
3634
3635static HChar *
3636s390_irgen_CRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
3637{
3638 IRTemp op1 = newTemp(Ity_I32);
3639 IRTemp op2 = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00003640 IRTemp cond = newTemp(Ity_I32);
3641
3642 if (m3 == 0) {
3643 } else {
3644 if (m3 == 14) {
3645 always_goto(mkexpr(op4addr));
3646 } else {
3647 assign(op1, get_gpr_w1(r1));
3648 assign(op2, get_gpr_w1(r2));
florianff9613f2012-05-12 15:26:44 +00003649 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
3650 op1, op2));
florianf321da72012-07-21 20:32:57 +00003651 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond),
3652 mkU32(0)), mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00003653 }
3654 }
3655
3656 return "crb";
3657}
3658
3659static HChar *
3660s390_irgen_CGRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
3661{
3662 IRTemp op1 = newTemp(Ity_I64);
3663 IRTemp op2 = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00003664 IRTemp cond = newTemp(Ity_I32);
3665
3666 if (m3 == 0) {
3667 } else {
3668 if (m3 == 14) {
3669 always_goto(mkexpr(op4addr));
3670 } else {
3671 assign(op1, get_gpr_dw0(r1));
3672 assign(op2, get_gpr_dw0(r2));
florianff9613f2012-05-12 15:26:44 +00003673 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
3674 op1, op2));
florianf321da72012-07-21 20:32:57 +00003675 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond),
3676 mkU32(0)), mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00003677 }
3678 }
3679
3680 return "cgrb";
3681}
3682
3683static HChar *
3684s390_irgen_CRJ(UChar r1, UChar r2, UShort i4, UChar m3)
3685{
3686 IRTemp op1 = newTemp(Ity_I32);
3687 IRTemp op2 = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00003688 IRTemp cond = newTemp(Ity_I32);
3689
3690 if (m3 == 0) {
3691 } else {
3692 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00003693 always_goto_and_chase(
3694 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00003695 } else {
3696 assign(op1, get_gpr_w1(r1));
3697 assign(op2, get_gpr_w1(r2));
florianff9613f2012-05-12 15:26:44 +00003698 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
3699 op1, op2));
sewardj2019a972011-03-07 16:04:07 +00003700 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3701 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
3702
3703 }
3704 }
3705
3706 return "crj";
3707}
3708
3709static HChar *
3710s390_irgen_CGRJ(UChar r1, UChar r2, UShort i4, UChar m3)
3711{
3712 IRTemp op1 = newTemp(Ity_I64);
3713 IRTemp op2 = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00003714 IRTemp cond = newTemp(Ity_I32);
3715
3716 if (m3 == 0) {
3717 } else {
3718 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00003719 always_goto_and_chase(
3720 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00003721 } else {
3722 assign(op1, get_gpr_dw0(r1));
3723 assign(op2, get_gpr_dw0(r2));
florianff9613f2012-05-12 15:26:44 +00003724 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
3725 op1, op2));
sewardj2019a972011-03-07 16:04:07 +00003726 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3727 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
3728
3729 }
3730 }
3731
3732 return "cgrj";
3733}
3734
3735static HChar *
3736s390_irgen_CIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
3737{
3738 IRTemp op1 = newTemp(Ity_I32);
3739 Int op2;
sewardj2019a972011-03-07 16:04:07 +00003740 IRTemp cond = newTemp(Ity_I32);
3741
3742 if (m3 == 0) {
3743 } else {
3744 if (m3 == 14) {
3745 always_goto(mkexpr(op4addr));
3746 } else {
3747 assign(op1, get_gpr_w1(r1));
3748 op2 = (Int)(Char)i2;
florianff9613f2012-05-12 15:26:44 +00003749 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
3750 mktemp(Ity_I32, mkU32((UInt)op2))));
florianf321da72012-07-21 20:32:57 +00003751 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3752 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00003753 }
3754 }
3755
3756 return "cib";
3757}
3758
3759static HChar *
3760s390_irgen_CGIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
3761{
3762 IRTemp op1 = newTemp(Ity_I64);
3763 Long op2;
sewardj2019a972011-03-07 16:04:07 +00003764 IRTemp cond = newTemp(Ity_I32);
3765
3766 if (m3 == 0) {
3767 } else {
3768 if (m3 == 14) {
3769 always_goto(mkexpr(op4addr));
3770 } else {
3771 assign(op1, get_gpr_dw0(r1));
3772 op2 = (Long)(Char)i2;
florianff9613f2012-05-12 15:26:44 +00003773 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
3774 mktemp(Ity_I64, mkU64((ULong)op2))));
florianf321da72012-07-21 20:32:57 +00003775 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3776 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00003777 }
3778 }
3779
3780 return "cgib";
3781}
3782
3783static HChar *
3784s390_irgen_CIJ(UChar r1, UChar m3, UShort i4, UChar i2)
3785{
3786 IRTemp op1 = newTemp(Ity_I32);
3787 Int op2;
sewardj2019a972011-03-07 16:04:07 +00003788 IRTemp cond = newTemp(Ity_I32);
3789
3790 if (m3 == 0) {
3791 } else {
3792 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00003793 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00003794 } else {
3795 assign(op1, get_gpr_w1(r1));
3796 op2 = (Int)(Char)i2;
florianff9613f2012-05-12 15:26:44 +00003797 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
3798 mktemp(Ity_I32, mkU32((UInt)op2))));
sewardj2019a972011-03-07 16:04:07 +00003799 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3800 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
3801
3802 }
3803 }
3804
3805 return "cij";
3806}
3807
3808static HChar *
3809s390_irgen_CGIJ(UChar r1, UChar m3, UShort i4, UChar i2)
3810{
3811 IRTemp op1 = newTemp(Ity_I64);
3812 Long op2;
sewardj2019a972011-03-07 16:04:07 +00003813 IRTemp cond = newTemp(Ity_I32);
3814
3815 if (m3 == 0) {
3816 } else {
3817 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00003818 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00003819 } else {
3820 assign(op1, get_gpr_dw0(r1));
3821 op2 = (Long)(Char)i2;
florianff9613f2012-05-12 15:26:44 +00003822 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
3823 mktemp(Ity_I64, mkU64((ULong)op2))));
sewardj2019a972011-03-07 16:04:07 +00003824 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3825 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
3826
3827 }
3828 }
3829
3830 return "cgij";
3831}
3832
3833static HChar *
3834s390_irgen_CH(UChar r1, IRTemp op2addr)
3835{
3836 IRTemp op1 = newTemp(Ity_I32);
3837 IRTemp op2 = newTemp(Ity_I32);
3838
3839 assign(op1, get_gpr_w1(r1));
3840 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
3841 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3842
3843 return "ch";
3844}
3845
3846static HChar *
3847s390_irgen_CHY(UChar r1, IRTemp op2addr)
3848{
3849 IRTemp op1 = newTemp(Ity_I32);
3850 IRTemp op2 = newTemp(Ity_I32);
3851
3852 assign(op1, get_gpr_w1(r1));
3853 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
3854 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3855
3856 return "chy";
3857}
3858
3859static HChar *
3860s390_irgen_CGH(UChar r1, IRTemp op2addr)
3861{
3862 IRTemp op1 = newTemp(Ity_I64);
3863 IRTemp op2 = newTemp(Ity_I64);
3864
3865 assign(op1, get_gpr_dw0(r1));
3866 assign(op2, unop(Iop_16Sto64, load(Ity_I16, mkexpr(op2addr))));
3867 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3868
3869 return "cgh";
3870}
3871
3872static HChar *
3873s390_irgen_CHI(UChar r1, UShort i2)
3874{
3875 IRTemp op1 = newTemp(Ity_I32);
3876 Int op2;
3877
3878 assign(op1, get_gpr_w1(r1));
3879 op2 = (Int)(Short)i2;
3880 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
3881 mkU32((UInt)op2)));
3882
3883 return "chi";
3884}
3885
3886static HChar *
3887s390_irgen_CGHI(UChar r1, UShort i2)
3888{
3889 IRTemp op1 = newTemp(Ity_I64);
3890 Long op2;
3891
3892 assign(op1, get_gpr_dw0(r1));
3893 op2 = (Long)(Short)i2;
3894 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I64,
3895 mkU64((ULong)op2)));
3896
3897 return "cghi";
3898}
3899
3900static HChar *
3901s390_irgen_CHHSI(UShort i2, IRTemp op1addr)
3902{
3903 IRTemp op1 = newTemp(Ity_I16);
3904 Short op2;
3905
3906 assign(op1, load(Ity_I16, mkexpr(op1addr)));
3907 op2 = (Short)i2;
3908 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I16,
3909 mkU16((UShort)op2)));
3910
3911 return "chhsi";
3912}
3913
3914static HChar *
3915s390_irgen_CHSI(UShort i2, IRTemp op1addr)
3916{
3917 IRTemp op1 = newTemp(Ity_I32);
3918 Int op2;
3919
3920 assign(op1, load(Ity_I32, mkexpr(op1addr)));
3921 op2 = (Int)(Short)i2;
3922 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
3923 mkU32((UInt)op2)));
3924
3925 return "chsi";
3926}
3927
3928static HChar *
3929s390_irgen_CGHSI(UShort i2, IRTemp op1addr)
3930{
3931 IRTemp op1 = newTemp(Ity_I64);
3932 Long op2;
3933
3934 assign(op1, load(Ity_I64, mkexpr(op1addr)));
3935 op2 = (Long)(Short)i2;
3936 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I64,
3937 mkU64((ULong)op2)));
3938
3939 return "cghsi";
3940}
3941
3942static HChar *
3943s390_irgen_CHRL(UChar r1, UInt i2)
3944{
3945 IRTemp op1 = newTemp(Ity_I32);
3946 IRTemp op2 = newTemp(Ity_I32);
3947
3948 assign(op1, get_gpr_w1(r1));
3949 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
3950 ((ULong)(Long)(Int)i2 << 1)))));
3951 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3952
3953 return "chrl";
3954}
3955
3956static HChar *
3957s390_irgen_CGHRL(UChar r1, UInt i2)
3958{
3959 IRTemp op1 = newTemp(Ity_I64);
3960 IRTemp op2 = newTemp(Ity_I64);
3961
3962 assign(op1, get_gpr_dw0(r1));
3963 assign(op2, unop(Iop_16Sto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
3964 ((ULong)(Long)(Int)i2 << 1)))));
3965 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3966
3967 return "cghrl";
3968}
3969
3970static HChar *
3971s390_irgen_CHHR(UChar r1, UChar r2)
3972{
3973 IRTemp op1 = newTemp(Ity_I32);
3974 IRTemp op2 = newTemp(Ity_I32);
3975
3976 assign(op1, get_gpr_w0(r1));
3977 assign(op2, get_gpr_w0(r2));
3978 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3979
3980 return "chhr";
3981}
3982
3983static HChar *
3984s390_irgen_CHLR(UChar r1, UChar r2)
3985{
3986 IRTemp op1 = newTemp(Ity_I32);
3987 IRTemp op2 = newTemp(Ity_I32);
3988
3989 assign(op1, get_gpr_w0(r1));
3990 assign(op2, get_gpr_w1(r2));
3991 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3992
3993 return "chlr";
3994}
3995
3996static HChar *
3997s390_irgen_CHF(UChar r1, IRTemp op2addr)
3998{
3999 IRTemp op1 = newTemp(Ity_I32);
4000 IRTemp op2 = newTemp(Ity_I32);
4001
4002 assign(op1, get_gpr_w0(r1));
4003 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4004 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4005
4006 return "chf";
4007}
4008
4009static HChar *
4010s390_irgen_CIH(UChar r1, UInt i2)
4011{
4012 IRTemp op1 = newTemp(Ity_I32);
4013 Int op2;
4014
4015 assign(op1, get_gpr_w0(r1));
4016 op2 = (Int)i2;
4017 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
4018 mkU32((UInt)op2)));
4019
4020 return "cih";
4021}
4022
4023static HChar *
4024s390_irgen_CLR(UChar r1, UChar r2)
4025{
4026 IRTemp op1 = newTemp(Ity_I32);
4027 IRTemp op2 = newTemp(Ity_I32);
4028
4029 assign(op1, get_gpr_w1(r1));
4030 assign(op2, get_gpr_w1(r2));
4031 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4032
4033 return "clr";
4034}
4035
4036static HChar *
4037s390_irgen_CLGR(UChar r1, UChar r2)
4038{
4039 IRTemp op1 = newTemp(Ity_I64);
4040 IRTemp op2 = newTemp(Ity_I64);
4041
4042 assign(op1, get_gpr_dw0(r1));
4043 assign(op2, get_gpr_dw0(r2));
4044 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4045
4046 return "clgr";
4047}
4048
4049static HChar *
4050s390_irgen_CLGFR(UChar r1, UChar r2)
4051{
4052 IRTemp op1 = newTemp(Ity_I64);
4053 IRTemp op2 = newTemp(Ity_I64);
4054
4055 assign(op1, get_gpr_dw0(r1));
4056 assign(op2, unop(Iop_32Uto64, get_gpr_w1(r2)));
4057 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4058
4059 return "clgfr";
4060}
4061
4062static HChar *
4063s390_irgen_CL(UChar r1, IRTemp op2addr)
4064{
4065 IRTemp op1 = newTemp(Ity_I32);
4066 IRTemp op2 = newTemp(Ity_I32);
4067
4068 assign(op1, get_gpr_w1(r1));
4069 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4070 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4071
4072 return "cl";
4073}
4074
4075static HChar *
4076s390_irgen_CLY(UChar r1, IRTemp op2addr)
4077{
4078 IRTemp op1 = newTemp(Ity_I32);
4079 IRTemp op2 = newTemp(Ity_I32);
4080
4081 assign(op1, get_gpr_w1(r1));
4082 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4083 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4084
4085 return "cly";
4086}
4087
4088static HChar *
4089s390_irgen_CLG(UChar r1, IRTemp op2addr)
4090{
4091 IRTemp op1 = newTemp(Ity_I64);
4092 IRTemp op2 = newTemp(Ity_I64);
4093
4094 assign(op1, get_gpr_dw0(r1));
4095 assign(op2, load(Ity_I64, mkexpr(op2addr)));
4096 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4097
4098 return "clg";
4099}
4100
4101static HChar *
4102s390_irgen_CLGF(UChar r1, IRTemp op2addr)
4103{
4104 IRTemp op1 = newTemp(Ity_I64);
4105 IRTemp op2 = newTemp(Ity_I64);
4106
4107 assign(op1, get_gpr_dw0(r1));
4108 assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
4109 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4110
4111 return "clgf";
4112}
4113
4114static HChar *
4115s390_irgen_CLFI(UChar r1, UInt i2)
4116{
4117 IRTemp op1 = newTemp(Ity_I32);
4118 UInt op2;
4119
4120 assign(op1, get_gpr_w1(r1));
4121 op2 = i2;
4122 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I32,
4123 mkU32(op2)));
4124
4125 return "clfi";
4126}
4127
4128static HChar *
4129s390_irgen_CLGFI(UChar r1, UInt i2)
4130{
4131 IRTemp op1 = newTemp(Ity_I64);
4132 ULong op2;
4133
4134 assign(op1, get_gpr_dw0(r1));
4135 op2 = (ULong)i2;
4136 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I64,
4137 mkU64(op2)));
4138
4139 return "clgfi";
4140}
4141
4142static HChar *
4143s390_irgen_CLI(UChar i2, IRTemp op1addr)
4144{
4145 IRTemp op1 = newTemp(Ity_I8);
4146 UChar op2;
4147
4148 assign(op1, load(Ity_I8, mkexpr(op1addr)));
4149 op2 = i2;
4150 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I8,
4151 mkU8(op2)));
4152
4153 return "cli";
4154}
4155
4156static HChar *
4157s390_irgen_CLIY(UChar i2, IRTemp op1addr)
4158{
4159 IRTemp op1 = newTemp(Ity_I8);
4160 UChar op2;
4161
4162 assign(op1, load(Ity_I8, mkexpr(op1addr)));
4163 op2 = i2;
4164 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I8,
4165 mkU8(op2)));
4166
4167 return "cliy";
4168}
4169
4170static HChar *
4171s390_irgen_CLFHSI(UShort i2, IRTemp op1addr)
4172{
4173 IRTemp op1 = newTemp(Ity_I32);
4174 UInt op2;
4175
4176 assign(op1, load(Ity_I32, mkexpr(op1addr)));
4177 op2 = (UInt)i2;
4178 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I32,
4179 mkU32(op2)));
4180
4181 return "clfhsi";
4182}
4183
4184static HChar *
4185s390_irgen_CLGHSI(UShort i2, IRTemp op1addr)
4186{
4187 IRTemp op1 = newTemp(Ity_I64);
4188 ULong op2;
4189
4190 assign(op1, load(Ity_I64, mkexpr(op1addr)));
4191 op2 = (ULong)i2;
4192 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I64,
4193 mkU64(op2)));
4194
4195 return "clghsi";
4196}
4197
4198static HChar *
4199s390_irgen_CLHHSI(UShort i2, IRTemp op1addr)
4200{
4201 IRTemp op1 = newTemp(Ity_I16);
4202 UShort op2;
4203
4204 assign(op1, load(Ity_I16, mkexpr(op1addr)));
4205 op2 = i2;
4206 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I16,
4207 mkU16(op2)));
4208
4209 return "clhhsi";
4210}
4211
4212static HChar *
4213s390_irgen_CLRL(UChar r1, UInt i2)
4214{
4215 IRTemp op1 = newTemp(Ity_I32);
4216 IRTemp op2 = newTemp(Ity_I32);
4217
4218 assign(op1, get_gpr_w1(r1));
4219 assign(op2, load(Ity_I32, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
4220 i2 << 1))));
4221 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4222
4223 return "clrl";
4224}
4225
4226static HChar *
4227s390_irgen_CLGRL(UChar r1, UInt i2)
4228{
4229 IRTemp op1 = newTemp(Ity_I64);
4230 IRTemp op2 = newTemp(Ity_I64);
4231
4232 assign(op1, get_gpr_dw0(r1));
4233 assign(op2, load(Ity_I64, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
4234 i2 << 1))));
4235 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4236
4237 return "clgrl";
4238}
4239
4240static HChar *
4241s390_irgen_CLGFRL(UChar r1, UInt i2)
4242{
4243 IRTemp op1 = newTemp(Ity_I64);
4244 IRTemp op2 = newTemp(Ity_I64);
4245
4246 assign(op1, get_gpr_dw0(r1));
4247 assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
4248 ((ULong)(Long)(Int)i2 << 1)))));
4249 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4250
4251 return "clgfrl";
4252}
4253
4254static HChar *
4255s390_irgen_CLHRL(UChar r1, UInt i2)
4256{
4257 IRTemp op1 = newTemp(Ity_I32);
4258 IRTemp op2 = newTemp(Ity_I32);
4259
4260 assign(op1, get_gpr_w1(r1));
4261 assign(op2, unop(Iop_16Uto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
4262 ((ULong)(Long)(Int)i2 << 1)))));
4263 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4264
4265 return "clhrl";
4266}
4267
4268static HChar *
4269s390_irgen_CLGHRL(UChar r1, UInt i2)
4270{
4271 IRTemp op1 = newTemp(Ity_I64);
4272 IRTemp op2 = newTemp(Ity_I64);
4273
4274 assign(op1, get_gpr_dw0(r1));
4275 assign(op2, unop(Iop_16Uto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
4276 ((ULong)(Long)(Int)i2 << 1)))));
4277 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4278
4279 return "clghrl";
4280}
4281
4282static HChar *
4283s390_irgen_CLRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
4284{
4285 IRTemp op1 = newTemp(Ity_I32);
4286 IRTemp op2 = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00004287 IRTemp cond = newTemp(Ity_I32);
4288
4289 if (m3 == 0) {
4290 } else {
4291 if (m3 == 14) {
4292 always_goto(mkexpr(op4addr));
4293 } else {
4294 assign(op1, get_gpr_w1(r1));
4295 assign(op2, get_gpr_w1(r2));
florianff9613f2012-05-12 15:26:44 +00004296 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4297 op1, op2));
florianf321da72012-07-21 20:32:57 +00004298 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4299 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004300 }
4301 }
4302
4303 return "clrb";
4304}
4305
4306static HChar *
4307s390_irgen_CLGRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
4308{
4309 IRTemp op1 = newTemp(Ity_I64);
4310 IRTemp op2 = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00004311 IRTemp cond = newTemp(Ity_I32);
4312
4313 if (m3 == 0) {
4314 } else {
4315 if (m3 == 14) {
4316 always_goto(mkexpr(op4addr));
4317 } else {
4318 assign(op1, get_gpr_dw0(r1));
4319 assign(op2, get_gpr_dw0(r2));
florianff9613f2012-05-12 15:26:44 +00004320 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4321 op1, op2));
florianf321da72012-07-21 20:32:57 +00004322 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4323 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004324 }
4325 }
4326
4327 return "clgrb";
4328}
4329
4330static HChar *
4331s390_irgen_CLRJ(UChar r1, UChar r2, UShort i4, UChar m3)
4332{
4333 IRTemp op1 = newTemp(Ity_I32);
4334 IRTemp op2 = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00004335 IRTemp cond = newTemp(Ity_I32);
4336
4337 if (m3 == 0) {
4338 } else {
4339 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004340 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004341 } else {
4342 assign(op1, get_gpr_w1(r1));
4343 assign(op2, get_gpr_w1(r2));
florianff9613f2012-05-12 15:26:44 +00004344 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4345 op1, op2));
sewardj2019a972011-03-07 16:04:07 +00004346 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4347 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4348
4349 }
4350 }
4351
4352 return "clrj";
4353}
4354
4355static HChar *
4356s390_irgen_CLGRJ(UChar r1, UChar r2, UShort i4, UChar m3)
4357{
4358 IRTemp op1 = newTemp(Ity_I64);
4359 IRTemp op2 = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00004360 IRTemp cond = newTemp(Ity_I32);
4361
4362 if (m3 == 0) {
4363 } else {
4364 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004365 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004366 } else {
4367 assign(op1, get_gpr_dw0(r1));
4368 assign(op2, get_gpr_dw0(r2));
florianff9613f2012-05-12 15:26:44 +00004369 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4370 op1, op2));
sewardj2019a972011-03-07 16:04:07 +00004371 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4372 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4373
4374 }
4375 }
4376
4377 return "clgrj";
4378}
4379
4380static HChar *
4381s390_irgen_CLIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
4382{
4383 IRTemp op1 = newTemp(Ity_I32);
4384 UInt op2;
sewardj2019a972011-03-07 16:04:07 +00004385 IRTemp cond = newTemp(Ity_I32);
4386
4387 if (m3 == 0) {
4388 } else {
4389 if (m3 == 14) {
4390 always_goto(mkexpr(op4addr));
4391 } else {
4392 assign(op1, get_gpr_w1(r1));
4393 op2 = (UInt)i2;
florianff9613f2012-05-12 15:26:44 +00004394 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4395 mktemp(Ity_I32, mkU32(op2))));
florianf321da72012-07-21 20:32:57 +00004396 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4397 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004398 }
4399 }
4400
4401 return "clib";
4402}
4403
4404static HChar *
4405s390_irgen_CLGIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
4406{
4407 IRTemp op1 = newTemp(Ity_I64);
4408 ULong op2;
sewardj2019a972011-03-07 16:04:07 +00004409 IRTemp cond = newTemp(Ity_I32);
4410
4411 if (m3 == 0) {
4412 } else {
4413 if (m3 == 14) {
4414 always_goto(mkexpr(op4addr));
4415 } else {
4416 assign(op1, get_gpr_dw0(r1));
4417 op2 = (ULong)i2;
florianff9613f2012-05-12 15:26:44 +00004418 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4419 mktemp(Ity_I64, mkU64(op2))));
florianf321da72012-07-21 20:32:57 +00004420 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4421 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004422 }
4423 }
4424
4425 return "clgib";
4426}
4427
4428static HChar *
4429s390_irgen_CLIJ(UChar r1, UChar m3, UShort i4, UChar i2)
4430{
4431 IRTemp op1 = newTemp(Ity_I32);
4432 UInt op2;
sewardj2019a972011-03-07 16:04:07 +00004433 IRTemp cond = newTemp(Ity_I32);
4434
4435 if (m3 == 0) {
4436 } else {
4437 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004438 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004439 } else {
4440 assign(op1, get_gpr_w1(r1));
4441 op2 = (UInt)i2;
florianff9613f2012-05-12 15:26:44 +00004442 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4443 mktemp(Ity_I32, mkU32(op2))));
sewardj2019a972011-03-07 16:04:07 +00004444 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4445 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4446
4447 }
4448 }
4449
4450 return "clij";
4451}
4452
4453static HChar *
4454s390_irgen_CLGIJ(UChar r1, UChar m3, UShort i4, UChar i2)
4455{
4456 IRTemp op1 = newTemp(Ity_I64);
4457 ULong op2;
sewardj2019a972011-03-07 16:04:07 +00004458 IRTemp cond = newTemp(Ity_I32);
4459
4460 if (m3 == 0) {
4461 } else {
4462 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004463 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004464 } else {
4465 assign(op1, get_gpr_dw0(r1));
4466 op2 = (ULong)i2;
florianff9613f2012-05-12 15:26:44 +00004467 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4468 mktemp(Ity_I64, mkU64(op2))));
sewardj2019a972011-03-07 16:04:07 +00004469 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4470 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4471
4472 }
4473 }
4474
4475 return "clgij";
4476}
4477
4478static HChar *
4479s390_irgen_CLM(UChar r1, UChar r3, IRTemp op2addr)
4480{
4481 IRTemp op1 = newTemp(Ity_I32);
4482 IRTemp op2 = newTemp(Ity_I32);
4483 IRTemp b0 = newTemp(Ity_I32);
4484 IRTemp b1 = newTemp(Ity_I32);
4485 IRTemp b2 = newTemp(Ity_I32);
4486 IRTemp b3 = newTemp(Ity_I32);
4487 IRTemp c0 = newTemp(Ity_I32);
4488 IRTemp c1 = newTemp(Ity_I32);
4489 IRTemp c2 = newTemp(Ity_I32);
4490 IRTemp c3 = newTemp(Ity_I32);
4491 UChar n;
4492
4493 n = 0;
4494 if ((r3 & 8) != 0) {
4495 assign(b0, unop(Iop_8Uto32, get_gpr_b4(r1)));
4496 assign(c0, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
4497 n = n + 1;
4498 } else {
4499 assign(b0, mkU32(0));
4500 assign(c0, mkU32(0));
4501 }
4502 if ((r3 & 4) != 0) {
4503 assign(b1, unop(Iop_8Uto32, get_gpr_b5(r1)));
4504 assign(c1, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4505 mkU64(n)))));
4506 n = n + 1;
4507 } else {
4508 assign(b1, mkU32(0));
4509 assign(c1, mkU32(0));
4510 }
4511 if ((r3 & 2) != 0) {
4512 assign(b2, unop(Iop_8Uto32, get_gpr_b6(r1)));
4513 assign(c2, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4514 mkU64(n)))));
4515 n = n + 1;
4516 } else {
4517 assign(b2, mkU32(0));
4518 assign(c2, mkU32(0));
4519 }
4520 if ((r3 & 1) != 0) {
4521 assign(b3, unop(Iop_8Uto32, get_gpr_b7(r1)));
4522 assign(c3, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4523 mkU64(n)))));
4524 n = n + 1;
4525 } else {
4526 assign(b3, mkU32(0));
4527 assign(c3, mkU32(0));
4528 }
4529 assign(op1, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4530 mkexpr(b0), mkU8(24)), binop(Iop_Shl32, mkexpr(b1), mkU8(16))),
4531 binop(Iop_Shl32, mkexpr(b2), mkU8(8))), mkexpr(b3)));
4532 assign(op2, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4533 mkexpr(c0), mkU8(24)), binop(Iop_Shl32, mkexpr(c1), mkU8(16))),
4534 binop(Iop_Shl32, mkexpr(c2), mkU8(8))), mkexpr(c3)));
4535 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4536
4537 return "clm";
4538}
4539
4540static HChar *
4541s390_irgen_CLMY(UChar r1, UChar r3, IRTemp op2addr)
4542{
4543 IRTemp op1 = newTemp(Ity_I32);
4544 IRTemp op2 = newTemp(Ity_I32);
4545 IRTemp b0 = newTemp(Ity_I32);
4546 IRTemp b1 = newTemp(Ity_I32);
4547 IRTemp b2 = newTemp(Ity_I32);
4548 IRTemp b3 = newTemp(Ity_I32);
4549 IRTemp c0 = newTemp(Ity_I32);
4550 IRTemp c1 = newTemp(Ity_I32);
4551 IRTemp c2 = newTemp(Ity_I32);
4552 IRTemp c3 = newTemp(Ity_I32);
4553 UChar n;
4554
4555 n = 0;
4556 if ((r3 & 8) != 0) {
4557 assign(b0, unop(Iop_8Uto32, get_gpr_b4(r1)));
4558 assign(c0, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
4559 n = n + 1;
4560 } else {
4561 assign(b0, mkU32(0));
4562 assign(c0, mkU32(0));
4563 }
4564 if ((r3 & 4) != 0) {
4565 assign(b1, unop(Iop_8Uto32, get_gpr_b5(r1)));
4566 assign(c1, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4567 mkU64(n)))));
4568 n = n + 1;
4569 } else {
4570 assign(b1, mkU32(0));
4571 assign(c1, mkU32(0));
4572 }
4573 if ((r3 & 2) != 0) {
4574 assign(b2, unop(Iop_8Uto32, get_gpr_b6(r1)));
4575 assign(c2, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4576 mkU64(n)))));
4577 n = n + 1;
4578 } else {
4579 assign(b2, mkU32(0));
4580 assign(c2, mkU32(0));
4581 }
4582 if ((r3 & 1) != 0) {
4583 assign(b3, unop(Iop_8Uto32, get_gpr_b7(r1)));
4584 assign(c3, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4585 mkU64(n)))));
4586 n = n + 1;
4587 } else {
4588 assign(b3, mkU32(0));
4589 assign(c3, mkU32(0));
4590 }
4591 assign(op1, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4592 mkexpr(b0), mkU8(24)), binop(Iop_Shl32, mkexpr(b1), mkU8(16))),
4593 binop(Iop_Shl32, mkexpr(b2), mkU8(8))), mkexpr(b3)));
4594 assign(op2, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4595 mkexpr(c0), mkU8(24)), binop(Iop_Shl32, mkexpr(c1), mkU8(16))),
4596 binop(Iop_Shl32, mkexpr(c2), mkU8(8))), mkexpr(c3)));
4597 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4598
4599 return "clmy";
4600}
4601
4602static HChar *
4603s390_irgen_CLMH(UChar r1, UChar r3, IRTemp op2addr)
4604{
4605 IRTemp op1 = newTemp(Ity_I32);
4606 IRTemp op2 = newTemp(Ity_I32);
4607 IRTemp b0 = newTemp(Ity_I32);
4608 IRTemp b1 = newTemp(Ity_I32);
4609 IRTemp b2 = newTemp(Ity_I32);
4610 IRTemp b3 = newTemp(Ity_I32);
4611 IRTemp c0 = newTemp(Ity_I32);
4612 IRTemp c1 = newTemp(Ity_I32);
4613 IRTemp c2 = newTemp(Ity_I32);
4614 IRTemp c3 = newTemp(Ity_I32);
4615 UChar n;
4616
4617 n = 0;
4618 if ((r3 & 8) != 0) {
4619 assign(b0, unop(Iop_8Uto32, get_gpr_b0(r1)));
4620 assign(c0, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
4621 n = n + 1;
4622 } else {
4623 assign(b0, mkU32(0));
4624 assign(c0, mkU32(0));
4625 }
4626 if ((r3 & 4) != 0) {
4627 assign(b1, unop(Iop_8Uto32, get_gpr_b1(r1)));
4628 assign(c1, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4629 mkU64(n)))));
4630 n = n + 1;
4631 } else {
4632 assign(b1, mkU32(0));
4633 assign(c1, mkU32(0));
4634 }
4635 if ((r3 & 2) != 0) {
4636 assign(b2, unop(Iop_8Uto32, get_gpr_b2(r1)));
4637 assign(c2, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4638 mkU64(n)))));
4639 n = n + 1;
4640 } else {
4641 assign(b2, mkU32(0));
4642 assign(c2, mkU32(0));
4643 }
4644 if ((r3 & 1) != 0) {
4645 assign(b3, unop(Iop_8Uto32, get_gpr_b3(r1)));
4646 assign(c3, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4647 mkU64(n)))));
4648 n = n + 1;
4649 } else {
4650 assign(b3, mkU32(0));
4651 assign(c3, mkU32(0));
4652 }
4653 assign(op1, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4654 mkexpr(b0), mkU8(24)), binop(Iop_Shl32, mkexpr(b1), mkU8(16))),
4655 binop(Iop_Shl32, mkexpr(b2), mkU8(8))), mkexpr(b3)));
4656 assign(op2, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4657 mkexpr(c0), mkU8(24)), binop(Iop_Shl32, mkexpr(c1), mkU8(16))),
4658 binop(Iop_Shl32, mkexpr(c2), mkU8(8))), mkexpr(c3)));
4659 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4660
4661 return "clmh";
4662}
4663
4664static HChar *
4665s390_irgen_CLHHR(UChar r1, UChar r2)
4666{
4667 IRTemp op1 = newTemp(Ity_I32);
4668 IRTemp op2 = newTemp(Ity_I32);
4669
4670 assign(op1, get_gpr_w0(r1));
4671 assign(op2, get_gpr_w0(r2));
4672 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4673
4674 return "clhhr";
4675}
4676
4677static HChar *
4678s390_irgen_CLHLR(UChar r1, UChar r2)
4679{
4680 IRTemp op1 = newTemp(Ity_I32);
4681 IRTemp op2 = newTemp(Ity_I32);
4682
4683 assign(op1, get_gpr_w0(r1));
4684 assign(op2, get_gpr_w1(r2));
4685 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4686
4687 return "clhlr";
4688}
4689
4690static HChar *
4691s390_irgen_CLHF(UChar r1, IRTemp op2addr)
4692{
4693 IRTemp op1 = newTemp(Ity_I32);
4694 IRTemp op2 = newTemp(Ity_I32);
4695
4696 assign(op1, get_gpr_w0(r1));
4697 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4698 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4699
4700 return "clhf";
4701}
4702
4703static HChar *
4704s390_irgen_CLIH(UChar r1, UInt i2)
4705{
4706 IRTemp op1 = newTemp(Ity_I32);
4707 UInt op2;
4708
4709 assign(op1, get_gpr_w0(r1));
4710 op2 = i2;
4711 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I32,
4712 mkU32(op2)));
4713
4714 return "clih";
4715}
4716
4717static HChar *
4718s390_irgen_CPYA(UChar r1, UChar r2)
4719{
4720 put_ar_w0(r1, get_ar_w0(r2));
sewardj7ee97522011-05-09 21:45:04 +00004721 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00004722 s390_disasm(ENC3(MNM, AR, AR), "cpya", r1, r2);
4723
4724 return "cpya";
4725}
4726
4727static HChar *
4728s390_irgen_XR(UChar r1, UChar r2)
4729{
4730 IRTemp op1 = newTemp(Ity_I32);
4731 IRTemp op2 = newTemp(Ity_I32);
4732 IRTemp result = newTemp(Ity_I32);
4733
4734 if (r1 == r2) {
4735 assign(result, mkU32(0));
4736 } else {
4737 assign(op1, get_gpr_w1(r1));
4738 assign(op2, get_gpr_w1(r2));
4739 assign(result, binop(Iop_Xor32, mkexpr(op1), mkexpr(op2)));
4740 }
4741 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4742 put_gpr_w1(r1, mkexpr(result));
4743
4744 return "xr";
4745}
4746
4747static HChar *
4748s390_irgen_XGR(UChar r1, UChar r2)
4749{
4750 IRTemp op1 = newTemp(Ity_I64);
4751 IRTemp op2 = newTemp(Ity_I64);
4752 IRTemp result = newTemp(Ity_I64);
4753
4754 if (r1 == r2) {
4755 assign(result, mkU64(0));
4756 } else {
4757 assign(op1, get_gpr_dw0(r1));
4758 assign(op2, get_gpr_dw0(r2));
4759 assign(result, binop(Iop_Xor64, mkexpr(op1), mkexpr(op2)));
4760 }
4761 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4762 put_gpr_dw0(r1, mkexpr(result));
4763
4764 return "xgr";
4765}
4766
4767static HChar *
4768s390_irgen_XRK(UChar r3, UChar r1, UChar r2)
4769{
4770 IRTemp op2 = newTemp(Ity_I32);
4771 IRTemp op3 = newTemp(Ity_I32);
4772 IRTemp result = newTemp(Ity_I32);
4773
4774 assign(op2, get_gpr_w1(r2));
4775 assign(op3, get_gpr_w1(r3));
4776 assign(result, binop(Iop_Xor32, mkexpr(op2), mkexpr(op3)));
4777 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4778 put_gpr_w1(r1, mkexpr(result));
4779
4780 return "xrk";
4781}
4782
4783static HChar *
4784s390_irgen_XGRK(UChar r3, UChar r1, UChar r2)
4785{
4786 IRTemp op2 = newTemp(Ity_I64);
4787 IRTemp op3 = newTemp(Ity_I64);
4788 IRTemp result = newTemp(Ity_I64);
4789
4790 assign(op2, get_gpr_dw0(r2));
4791 assign(op3, get_gpr_dw0(r3));
4792 assign(result, binop(Iop_Xor64, mkexpr(op2), mkexpr(op3)));
4793 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4794 put_gpr_dw0(r1, mkexpr(result));
4795
4796 return "xgrk";
4797}
4798
4799static HChar *
4800s390_irgen_X(UChar r1, IRTemp op2addr)
4801{
4802 IRTemp op1 = newTemp(Ity_I32);
4803 IRTemp op2 = newTemp(Ity_I32);
4804 IRTemp result = newTemp(Ity_I32);
4805
4806 assign(op1, get_gpr_w1(r1));
4807 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4808 assign(result, binop(Iop_Xor32, mkexpr(op1), mkexpr(op2)));
4809 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4810 put_gpr_w1(r1, mkexpr(result));
4811
4812 return "x";
4813}
4814
4815static HChar *
4816s390_irgen_XY(UChar r1, IRTemp op2addr)
4817{
4818 IRTemp op1 = newTemp(Ity_I32);
4819 IRTemp op2 = newTemp(Ity_I32);
4820 IRTemp result = newTemp(Ity_I32);
4821
4822 assign(op1, get_gpr_w1(r1));
4823 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4824 assign(result, binop(Iop_Xor32, mkexpr(op1), mkexpr(op2)));
4825 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4826 put_gpr_w1(r1, mkexpr(result));
4827
4828 return "xy";
4829}
4830
4831static HChar *
4832s390_irgen_XG(UChar r1, IRTemp op2addr)
4833{
4834 IRTemp op1 = newTemp(Ity_I64);
4835 IRTemp op2 = newTemp(Ity_I64);
4836 IRTemp result = newTemp(Ity_I64);
4837
4838 assign(op1, get_gpr_dw0(r1));
4839 assign(op2, load(Ity_I64, mkexpr(op2addr)));
4840 assign(result, binop(Iop_Xor64, mkexpr(op1), mkexpr(op2)));
4841 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4842 put_gpr_dw0(r1, mkexpr(result));
4843
4844 return "xg";
4845}
4846
4847static HChar *
4848s390_irgen_XI(UChar i2, IRTemp op1addr)
4849{
4850 IRTemp op1 = newTemp(Ity_I8);
4851 UChar op2;
4852 IRTemp result = newTemp(Ity_I8);
4853
4854 assign(op1, load(Ity_I8, mkexpr(op1addr)));
4855 op2 = i2;
4856 assign(result, binop(Iop_Xor8, mkexpr(op1), mkU8(op2)));
4857 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4858 store(mkexpr(op1addr), mkexpr(result));
4859
4860 return "xi";
4861}
4862
4863static HChar *
4864s390_irgen_XIY(UChar i2, IRTemp op1addr)
4865{
4866 IRTemp op1 = newTemp(Ity_I8);
4867 UChar op2;
4868 IRTemp result = newTemp(Ity_I8);
4869
4870 assign(op1, load(Ity_I8, mkexpr(op1addr)));
4871 op2 = i2;
4872 assign(result, binop(Iop_Xor8, mkexpr(op1), mkU8(op2)));
4873 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4874 store(mkexpr(op1addr), mkexpr(result));
4875
4876 return "xiy";
4877}
4878
4879static HChar *
4880s390_irgen_XIHF(UChar r1, UInt i2)
4881{
4882 IRTemp op1 = newTemp(Ity_I32);
4883 UInt op2;
4884 IRTemp result = newTemp(Ity_I32);
4885
4886 assign(op1, get_gpr_w0(r1));
4887 op2 = i2;
4888 assign(result, binop(Iop_Xor32, mkexpr(op1), mkU32(op2)));
4889 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4890 put_gpr_w0(r1, mkexpr(result));
4891
4892 return "xihf";
4893}
4894
4895static HChar *
4896s390_irgen_XILF(UChar r1, UInt i2)
4897{
4898 IRTemp op1 = newTemp(Ity_I32);
4899 UInt op2;
4900 IRTemp result = newTemp(Ity_I32);
4901
4902 assign(op1, get_gpr_w1(r1));
4903 op2 = i2;
4904 assign(result, binop(Iop_Xor32, mkexpr(op1), mkU32(op2)));
4905 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4906 put_gpr_w1(r1, mkexpr(result));
4907
4908 return "xilf";
4909}
4910
4911static HChar *
4912s390_irgen_EAR(UChar r1, UChar r2)
4913{
4914 put_gpr_w1(r1, get_ar_w0(r2));
sewardj7ee97522011-05-09 21:45:04 +00004915 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00004916 s390_disasm(ENC3(MNM, GPR, AR), "ear", r1, r2);
4917
4918 return "ear";
4919}
4920
4921static HChar *
4922s390_irgen_IC(UChar r1, IRTemp op2addr)
4923{
4924 put_gpr_b7(r1, load(Ity_I8, mkexpr(op2addr)));
4925
4926 return "ic";
4927}
4928
4929static HChar *
4930s390_irgen_ICY(UChar r1, IRTemp op2addr)
4931{
4932 put_gpr_b7(r1, load(Ity_I8, mkexpr(op2addr)));
4933
4934 return "icy";
4935}
4936
4937static HChar *
4938s390_irgen_ICM(UChar r1, UChar r3, IRTemp op2addr)
4939{
4940 UChar n;
4941 IRTemp result = newTemp(Ity_I32);
4942 UInt mask;
4943
4944 n = 0;
4945 mask = (UInt)r3;
4946 if ((mask & 8) != 0) {
4947 put_gpr_b4(r1, load(Ity_I8, mkexpr(op2addr)));
4948 n = n + 1;
4949 }
4950 if ((mask & 4) != 0) {
4951 put_gpr_b5(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
4952
4953 n = n + 1;
4954 }
4955 if ((mask & 2) != 0) {
4956 put_gpr_b6(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
4957
4958 n = n + 1;
4959 }
4960 if ((mask & 1) != 0) {
4961 put_gpr_b7(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
4962
4963 n = n + 1;
4964 }
4965 assign(result, get_gpr_w1(r1));
4966 s390_cc_thunk_putZZ(S390_CC_OP_INSERT_CHAR_MASK_32, result, mktemp(Ity_I32,
4967 mkU32(mask)));
4968
4969 return "icm";
4970}
4971
4972static HChar *
4973s390_irgen_ICMY(UChar r1, UChar r3, IRTemp op2addr)
4974{
4975 UChar n;
4976 IRTemp result = newTemp(Ity_I32);
4977 UInt mask;
4978
4979 n = 0;
4980 mask = (UInt)r3;
4981 if ((mask & 8) != 0) {
4982 put_gpr_b4(r1, load(Ity_I8, mkexpr(op2addr)));
4983 n = n + 1;
4984 }
4985 if ((mask & 4) != 0) {
4986 put_gpr_b5(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
4987
4988 n = n + 1;
4989 }
4990 if ((mask & 2) != 0) {
4991 put_gpr_b6(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
4992
4993 n = n + 1;
4994 }
4995 if ((mask & 1) != 0) {
4996 put_gpr_b7(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
4997
4998 n = n + 1;
4999 }
5000 assign(result, get_gpr_w1(r1));
5001 s390_cc_thunk_putZZ(S390_CC_OP_INSERT_CHAR_MASK_32, result, mktemp(Ity_I32,
5002 mkU32(mask)));
5003
5004 return "icmy";
5005}
5006
5007static HChar *
5008s390_irgen_ICMH(UChar r1, UChar r3, IRTemp op2addr)
5009{
5010 UChar n;
5011 IRTemp result = newTemp(Ity_I32);
5012 UInt mask;
5013
5014 n = 0;
5015 mask = (UInt)r3;
5016 if ((mask & 8) != 0) {
5017 put_gpr_b0(r1, load(Ity_I8, mkexpr(op2addr)));
5018 n = n + 1;
5019 }
5020 if ((mask & 4) != 0) {
5021 put_gpr_b1(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5022
5023 n = n + 1;
5024 }
5025 if ((mask & 2) != 0) {
5026 put_gpr_b2(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5027
5028 n = n + 1;
5029 }
5030 if ((mask & 1) != 0) {
5031 put_gpr_b3(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5032
5033 n = n + 1;
5034 }
5035 assign(result, get_gpr_w0(r1));
5036 s390_cc_thunk_putZZ(S390_CC_OP_INSERT_CHAR_MASK_32, result, mktemp(Ity_I32,
5037 mkU32(mask)));
5038
5039 return "icmh";
5040}
5041
5042static HChar *
5043s390_irgen_IIHF(UChar r1, UInt i2)
5044{
5045 put_gpr_w0(r1, mkU32(i2));
5046
5047 return "iihf";
5048}
5049
5050static HChar *
5051s390_irgen_IIHH(UChar r1, UShort i2)
5052{
5053 put_gpr_hw0(r1, mkU16(i2));
5054
5055 return "iihh";
5056}
5057
5058static HChar *
5059s390_irgen_IIHL(UChar r1, UShort i2)
5060{
5061 put_gpr_hw1(r1, mkU16(i2));
5062
5063 return "iihl";
5064}
5065
5066static HChar *
5067s390_irgen_IILF(UChar r1, UInt i2)
5068{
5069 put_gpr_w1(r1, mkU32(i2));
5070
5071 return "iilf";
5072}
5073
5074static HChar *
5075s390_irgen_IILH(UChar r1, UShort i2)
5076{
5077 put_gpr_hw2(r1, mkU16(i2));
5078
5079 return "iilh";
5080}
5081
5082static HChar *
5083s390_irgen_IILL(UChar r1, UShort i2)
5084{
5085 put_gpr_hw3(r1, mkU16(i2));
5086
5087 return "iill";
5088}
5089
5090static HChar *
5091s390_irgen_LR(UChar r1, UChar r2)
5092{
5093 put_gpr_w1(r1, get_gpr_w1(r2));
5094
5095 return "lr";
5096}
5097
5098static HChar *
5099s390_irgen_LGR(UChar r1, UChar r2)
5100{
5101 put_gpr_dw0(r1, get_gpr_dw0(r2));
5102
5103 return "lgr";
5104}
5105
5106static HChar *
5107s390_irgen_LGFR(UChar r1, UChar r2)
5108{
5109 put_gpr_dw0(r1, unop(Iop_32Sto64, get_gpr_w1(r2)));
5110
5111 return "lgfr";
5112}
5113
5114static HChar *
5115s390_irgen_L(UChar r1, IRTemp op2addr)
5116{
5117 put_gpr_w1(r1, load(Ity_I32, mkexpr(op2addr)));
5118
5119 return "l";
5120}
5121
5122static HChar *
5123s390_irgen_LY(UChar r1, IRTemp op2addr)
5124{
5125 put_gpr_w1(r1, load(Ity_I32, mkexpr(op2addr)));
5126
5127 return "ly";
5128}
5129
5130static HChar *
5131s390_irgen_LG(UChar r1, IRTemp op2addr)
5132{
5133 put_gpr_dw0(r1, load(Ity_I64, mkexpr(op2addr)));
5134
5135 return "lg";
5136}
5137
5138static HChar *
5139s390_irgen_LGF(UChar r1, IRTemp op2addr)
5140{
5141 put_gpr_dw0(r1, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
5142
5143 return "lgf";
5144}
5145
5146static HChar *
5147s390_irgen_LGFI(UChar r1, UInt i2)
5148{
5149 put_gpr_dw0(r1, mkU64((ULong)(Long)(Int)i2));
5150
5151 return "lgfi";
5152}
5153
5154static HChar *
5155s390_irgen_LRL(UChar r1, UInt i2)
5156{
5157 put_gpr_w1(r1, load(Ity_I32, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
5158 i2 << 1))));
5159
5160 return "lrl";
5161}
5162
5163static HChar *
5164s390_irgen_LGRL(UChar r1, UInt i2)
5165{
5166 put_gpr_dw0(r1, load(Ity_I64, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
5167 i2 << 1))));
5168
5169 return "lgrl";
5170}
5171
5172static HChar *
5173s390_irgen_LGFRL(UChar r1, UInt i2)
5174{
5175 put_gpr_dw0(r1, unop(Iop_32Sto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
5176 ((ULong)(Long)(Int)i2 << 1)))));
5177
5178 return "lgfrl";
5179}
5180
5181static HChar *
5182s390_irgen_LA(UChar r1, IRTemp op2addr)
5183{
5184 put_gpr_dw0(r1, mkexpr(op2addr));
5185
5186 return "la";
5187}
5188
5189static HChar *
5190s390_irgen_LAY(UChar r1, IRTemp op2addr)
5191{
5192 put_gpr_dw0(r1, mkexpr(op2addr));
5193
5194 return "lay";
5195}
5196
5197static HChar *
5198s390_irgen_LAE(UChar r1, IRTemp op2addr)
5199{
5200 put_gpr_dw0(r1, mkexpr(op2addr));
5201
5202 return "lae";
5203}
5204
5205static HChar *
5206s390_irgen_LAEY(UChar r1, IRTemp op2addr)
5207{
5208 put_gpr_dw0(r1, mkexpr(op2addr));
5209
5210 return "laey";
5211}
5212
5213static HChar *
5214s390_irgen_LARL(UChar r1, UInt i2)
5215{
5216 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)));
5217
5218 return "larl";
5219}
5220
5221static HChar *
5222s390_irgen_LAA(UChar r1, UChar r3, IRTemp op2addr)
5223{
5224 IRTemp op2 = newTemp(Ity_I32);
5225 IRTemp op3 = newTemp(Ity_I32);
5226 IRTemp result = newTemp(Ity_I32);
5227
5228 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5229 assign(op3, get_gpr_w1(r3));
5230 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
5231 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
5232 store(mkexpr(op2addr), mkexpr(result));
5233 put_gpr_w1(r1, mkexpr(op2));
5234
5235 return "laa";
5236}
5237
5238static HChar *
5239s390_irgen_LAAG(UChar r1, UChar r3, IRTemp op2addr)
5240{
5241 IRTemp op2 = newTemp(Ity_I64);
5242 IRTemp op3 = newTemp(Ity_I64);
5243 IRTemp result = newTemp(Ity_I64);
5244
5245 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5246 assign(op3, get_gpr_dw0(r3));
5247 assign(result, binop(Iop_Add64, mkexpr(op2), mkexpr(op3)));
5248 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op2, op3);
5249 store(mkexpr(op2addr), mkexpr(result));
5250 put_gpr_dw0(r1, mkexpr(op2));
5251
5252 return "laag";
5253}
5254
5255static HChar *
5256s390_irgen_LAAL(UChar r1, UChar r3, IRTemp op2addr)
5257{
5258 IRTemp op2 = newTemp(Ity_I32);
5259 IRTemp op3 = newTemp(Ity_I32);
5260 IRTemp result = newTemp(Ity_I32);
5261
5262 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5263 assign(op3, get_gpr_w1(r3));
5264 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
5265 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
5266 store(mkexpr(op2addr), mkexpr(result));
5267 put_gpr_w1(r1, mkexpr(op2));
5268
5269 return "laal";
5270}
5271
5272static HChar *
5273s390_irgen_LAALG(UChar r1, UChar r3, IRTemp op2addr)
5274{
5275 IRTemp op2 = newTemp(Ity_I64);
5276 IRTemp op3 = newTemp(Ity_I64);
5277 IRTemp result = newTemp(Ity_I64);
5278
5279 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5280 assign(op3, get_gpr_dw0(r3));
5281 assign(result, binop(Iop_Add64, mkexpr(op2), mkexpr(op3)));
5282 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op2, op3);
5283 store(mkexpr(op2addr), mkexpr(result));
5284 put_gpr_dw0(r1, mkexpr(op2));
5285
5286 return "laalg";
5287}
5288
5289static HChar *
5290s390_irgen_LAN(UChar r1, UChar r3, IRTemp op2addr)
5291{
5292 IRTemp op2 = newTemp(Ity_I32);
5293 IRTemp op3 = newTemp(Ity_I32);
5294 IRTemp result = newTemp(Ity_I32);
5295
5296 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5297 assign(op3, get_gpr_w1(r3));
5298 assign(result, binop(Iop_And32, mkexpr(op2), mkexpr(op3)));
5299 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5300 store(mkexpr(op2addr), mkexpr(result));
5301 put_gpr_w1(r1, mkexpr(op2));
5302
5303 return "lan";
5304}
5305
5306static HChar *
5307s390_irgen_LANG(UChar r1, UChar r3, IRTemp op2addr)
5308{
5309 IRTemp op2 = newTemp(Ity_I64);
5310 IRTemp op3 = newTemp(Ity_I64);
5311 IRTemp result = newTemp(Ity_I64);
5312
5313 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5314 assign(op3, get_gpr_dw0(r3));
5315 assign(result, binop(Iop_And64, mkexpr(op2), mkexpr(op3)));
5316 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5317 store(mkexpr(op2addr), mkexpr(result));
5318 put_gpr_dw0(r1, mkexpr(op2));
5319
5320 return "lang";
5321}
5322
5323static HChar *
5324s390_irgen_LAX(UChar r1, UChar r3, IRTemp op2addr)
5325{
5326 IRTemp op2 = newTemp(Ity_I32);
5327 IRTemp op3 = newTemp(Ity_I32);
5328 IRTemp result = newTemp(Ity_I32);
5329
5330 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5331 assign(op3, get_gpr_w1(r3));
5332 assign(result, binop(Iop_Xor32, mkexpr(op2), mkexpr(op3)));
5333 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5334 store(mkexpr(op2addr), mkexpr(result));
5335 put_gpr_w1(r1, mkexpr(op2));
5336
5337 return "lax";
5338}
5339
5340static HChar *
5341s390_irgen_LAXG(UChar r1, UChar r3, IRTemp op2addr)
5342{
5343 IRTemp op2 = newTemp(Ity_I64);
5344 IRTemp op3 = newTemp(Ity_I64);
5345 IRTemp result = newTemp(Ity_I64);
5346
5347 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5348 assign(op3, get_gpr_dw0(r3));
5349 assign(result, binop(Iop_Xor64, mkexpr(op2), mkexpr(op3)));
5350 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5351 store(mkexpr(op2addr), mkexpr(result));
5352 put_gpr_dw0(r1, mkexpr(op2));
5353
5354 return "laxg";
5355}
5356
5357static HChar *
5358s390_irgen_LAO(UChar r1, UChar r3, IRTemp op2addr)
5359{
5360 IRTemp op2 = newTemp(Ity_I32);
5361 IRTemp op3 = newTemp(Ity_I32);
5362 IRTemp result = newTemp(Ity_I32);
5363
5364 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5365 assign(op3, get_gpr_w1(r3));
5366 assign(result, binop(Iop_Or32, mkexpr(op2), mkexpr(op3)));
5367 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5368 store(mkexpr(op2addr), mkexpr(result));
5369 put_gpr_w1(r1, mkexpr(op2));
5370
5371 return "lao";
5372}
5373
5374static HChar *
5375s390_irgen_LAOG(UChar r1, UChar r3, IRTemp op2addr)
5376{
5377 IRTemp op2 = newTemp(Ity_I64);
5378 IRTemp op3 = newTemp(Ity_I64);
5379 IRTemp result = newTemp(Ity_I64);
5380
5381 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5382 assign(op3, get_gpr_dw0(r3));
5383 assign(result, binop(Iop_Or64, mkexpr(op2), mkexpr(op3)));
5384 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5385 store(mkexpr(op2addr), mkexpr(result));
5386 put_gpr_dw0(r1, mkexpr(op2));
5387
5388 return "laog";
5389}
5390
5391static HChar *
5392s390_irgen_LTR(UChar r1, UChar r2)
5393{
5394 IRTemp op2 = newTemp(Ity_I32);
5395
5396 assign(op2, get_gpr_w1(r2));
5397 put_gpr_w1(r1, mkexpr(op2));
5398 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5399
5400 return "ltr";
5401}
5402
5403static HChar *
5404s390_irgen_LTGR(UChar r1, UChar r2)
5405{
5406 IRTemp op2 = newTemp(Ity_I64);
5407
5408 assign(op2, get_gpr_dw0(r2));
5409 put_gpr_dw0(r1, mkexpr(op2));
5410 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5411
5412 return "ltgr";
5413}
5414
5415static HChar *
5416s390_irgen_LTGFR(UChar r1, UChar r2)
5417{
5418 IRTemp op2 = newTemp(Ity_I64);
5419
5420 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
5421 put_gpr_dw0(r1, mkexpr(op2));
5422 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5423
5424 return "ltgfr";
5425}
5426
5427static HChar *
5428s390_irgen_LT(UChar r1, IRTemp op2addr)
5429{
5430 IRTemp op2 = newTemp(Ity_I32);
5431
5432 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5433 put_gpr_w1(r1, mkexpr(op2));
5434 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5435
5436 return "lt";
5437}
5438
5439static HChar *
5440s390_irgen_LTG(UChar r1, IRTemp op2addr)
5441{
5442 IRTemp op2 = newTemp(Ity_I64);
5443
5444 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5445 put_gpr_dw0(r1, mkexpr(op2));
5446 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5447
5448 return "ltg";
5449}
5450
5451static HChar *
5452s390_irgen_LTGF(UChar r1, IRTemp op2addr)
5453{
5454 IRTemp op2 = newTemp(Ity_I64);
5455
5456 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
5457 put_gpr_dw0(r1, mkexpr(op2));
5458 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5459
5460 return "ltgf";
5461}
5462
5463static HChar *
5464s390_irgen_LBR(UChar r1, UChar r2)
5465{
5466 put_gpr_w1(r1, unop(Iop_8Sto32, get_gpr_b7(r2)));
5467
5468 return "lbr";
5469}
5470
5471static HChar *
5472s390_irgen_LGBR(UChar r1, UChar r2)
5473{
5474 put_gpr_dw0(r1, unop(Iop_8Sto64, get_gpr_b7(r2)));
5475
5476 return "lgbr";
5477}
5478
5479static HChar *
5480s390_irgen_LB(UChar r1, IRTemp op2addr)
5481{
5482 put_gpr_w1(r1, unop(Iop_8Sto32, load(Ity_I8, mkexpr(op2addr))));
5483
5484 return "lb";
5485}
5486
5487static HChar *
5488s390_irgen_LGB(UChar r1, IRTemp op2addr)
5489{
5490 put_gpr_dw0(r1, unop(Iop_8Sto64, load(Ity_I8, mkexpr(op2addr))));
5491
5492 return "lgb";
5493}
5494
5495static HChar *
5496s390_irgen_LBH(UChar r1, IRTemp op2addr)
5497{
5498 put_gpr_w0(r1, unop(Iop_8Sto32, load(Ity_I8, mkexpr(op2addr))));
5499
5500 return "lbh";
5501}
5502
5503static HChar *
5504s390_irgen_LCR(UChar r1, UChar r2)
5505{
5506 Int op1;
5507 IRTemp op2 = newTemp(Ity_I32);
5508 IRTemp result = newTemp(Ity_I32);
5509
5510 op1 = 0;
5511 assign(op2, get_gpr_w1(r2));
5512 assign(result, binop(Iop_Sub32, mkU32((UInt)op1), mkexpr(op2)));
5513 put_gpr_w1(r1, mkexpr(result));
5514 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, mktemp(Ity_I32, mkU32((UInt)
5515 op1)), op2);
5516
5517 return "lcr";
5518}
5519
5520static HChar *
5521s390_irgen_LCGR(UChar r1, UChar r2)
5522{
5523 Long op1;
5524 IRTemp op2 = newTemp(Ity_I64);
5525 IRTemp result = newTemp(Ity_I64);
5526
5527 op1 = 0ULL;
5528 assign(op2, get_gpr_dw0(r2));
5529 assign(result, binop(Iop_Sub64, mkU64((ULong)op1), mkexpr(op2)));
5530 put_gpr_dw0(r1, mkexpr(result));
5531 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, mktemp(Ity_I64, mkU64((ULong)
5532 op1)), op2);
5533
5534 return "lcgr";
5535}
5536
5537static HChar *
5538s390_irgen_LCGFR(UChar r1, UChar r2)
5539{
5540 Long op1;
5541 IRTemp op2 = newTemp(Ity_I64);
5542 IRTemp result = newTemp(Ity_I64);
5543
5544 op1 = 0ULL;
5545 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
5546 assign(result, binop(Iop_Sub64, mkU64((ULong)op1), mkexpr(op2)));
5547 put_gpr_dw0(r1, mkexpr(result));
5548 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, mktemp(Ity_I64, mkU64((ULong)
5549 op1)), op2);
5550
5551 return "lcgfr";
5552}
5553
5554static HChar *
5555s390_irgen_LHR(UChar r1, UChar r2)
5556{
5557 put_gpr_w1(r1, unop(Iop_16Sto32, get_gpr_hw3(r2)));
5558
5559 return "lhr";
5560}
5561
5562static HChar *
5563s390_irgen_LGHR(UChar r1, UChar r2)
5564{
5565 put_gpr_dw0(r1, unop(Iop_16Sto64, get_gpr_hw3(r2)));
5566
5567 return "lghr";
5568}
5569
5570static HChar *
5571s390_irgen_LH(UChar r1, IRTemp op2addr)
5572{
5573 put_gpr_w1(r1, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
5574
5575 return "lh";
5576}
5577
5578static HChar *
5579s390_irgen_LHY(UChar r1, IRTemp op2addr)
5580{
5581 put_gpr_w1(r1, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
5582
5583 return "lhy";
5584}
5585
5586static HChar *
5587s390_irgen_LGH(UChar r1, IRTemp op2addr)
5588{
5589 put_gpr_dw0(r1, unop(Iop_16Sto64, load(Ity_I16, mkexpr(op2addr))));
5590
5591 return "lgh";
5592}
5593
5594static HChar *
5595s390_irgen_LHI(UChar r1, UShort i2)
5596{
5597 put_gpr_w1(r1, mkU32((UInt)(Int)(Short)i2));
5598
5599 return "lhi";
5600}
5601
5602static HChar *
5603s390_irgen_LGHI(UChar r1, UShort i2)
5604{
5605 put_gpr_dw0(r1, mkU64((ULong)(Long)(Short)i2));
5606
5607 return "lghi";
5608}
5609
5610static HChar *
5611s390_irgen_LHRL(UChar r1, UInt i2)
5612{
5613 put_gpr_w1(r1, unop(Iop_16Sto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
5614 ((ULong)(Long)(Int)i2 << 1)))));
5615
5616 return "lhrl";
5617}
5618
5619static HChar *
5620s390_irgen_LGHRL(UChar r1, UInt i2)
5621{
5622 put_gpr_dw0(r1, unop(Iop_16Sto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
5623 ((ULong)(Long)(Int)i2 << 1)))));
5624
5625 return "lghrl";
5626}
5627
5628static HChar *
5629s390_irgen_LHH(UChar r1, IRTemp op2addr)
5630{
5631 put_gpr_w0(r1, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
5632
5633 return "lhh";
5634}
5635
5636static HChar *
5637s390_irgen_LFH(UChar r1, IRTemp op2addr)
5638{
5639 put_gpr_w0(r1, load(Ity_I32, mkexpr(op2addr)));
5640
5641 return "lfh";
5642}
5643
5644static HChar *
5645s390_irgen_LLGFR(UChar r1, UChar r2)
5646{
5647 put_gpr_dw0(r1, unop(Iop_32Uto64, get_gpr_w1(r2)));
5648
5649 return "llgfr";
5650}
5651
5652static HChar *
5653s390_irgen_LLGF(UChar r1, IRTemp op2addr)
5654{
5655 put_gpr_dw0(r1, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
5656
5657 return "llgf";
5658}
5659
5660static HChar *
5661s390_irgen_LLGFRL(UChar r1, UInt i2)
5662{
5663 put_gpr_dw0(r1, unop(Iop_32Uto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
5664 ((ULong)(Long)(Int)i2 << 1)))));
5665
5666 return "llgfrl";
5667}
5668
5669static HChar *
5670s390_irgen_LLCR(UChar r1, UChar r2)
5671{
5672 put_gpr_w1(r1, unop(Iop_8Uto32, get_gpr_b7(r2)));
5673
5674 return "llcr";
5675}
5676
5677static HChar *
5678s390_irgen_LLGCR(UChar r1, UChar r2)
5679{
5680 put_gpr_dw0(r1, unop(Iop_8Uto64, get_gpr_b7(r2)));
5681
5682 return "llgcr";
5683}
5684
5685static HChar *
5686s390_irgen_LLC(UChar r1, IRTemp op2addr)
5687{
5688 put_gpr_w1(r1, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
5689
5690 return "llc";
5691}
5692
5693static HChar *
5694s390_irgen_LLGC(UChar r1, IRTemp op2addr)
5695{
5696 put_gpr_dw0(r1, unop(Iop_8Uto64, load(Ity_I8, mkexpr(op2addr))));
5697
5698 return "llgc";
5699}
5700
5701static HChar *
5702s390_irgen_LLCH(UChar r1, IRTemp op2addr)
5703{
5704 put_gpr_w0(r1, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
5705
5706 return "llch";
5707}
5708
5709static HChar *
5710s390_irgen_LLHR(UChar r1, UChar r2)
5711{
5712 put_gpr_w1(r1, unop(Iop_16Uto32, get_gpr_hw3(r2)));
5713
5714 return "llhr";
5715}
5716
5717static HChar *
5718s390_irgen_LLGHR(UChar r1, UChar r2)
5719{
5720 put_gpr_dw0(r1, unop(Iop_16Uto64, get_gpr_hw3(r2)));
5721
5722 return "llghr";
5723}
5724
5725static HChar *
5726s390_irgen_LLH(UChar r1, IRTemp op2addr)
5727{
5728 put_gpr_w1(r1, unop(Iop_16Uto32, load(Ity_I16, mkexpr(op2addr))));
5729
5730 return "llh";
5731}
5732
5733static HChar *
5734s390_irgen_LLGH(UChar r1, IRTemp op2addr)
5735{
5736 put_gpr_dw0(r1, unop(Iop_16Uto64, load(Ity_I16, mkexpr(op2addr))));
5737
5738 return "llgh";
5739}
5740
5741static HChar *
5742s390_irgen_LLHRL(UChar r1, UInt i2)
5743{
5744 put_gpr_w1(r1, unop(Iop_16Uto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
5745 ((ULong)(Long)(Int)i2 << 1)))));
5746
5747 return "llhrl";
5748}
5749
5750static HChar *
5751s390_irgen_LLGHRL(UChar r1, UInt i2)
5752{
5753 put_gpr_dw0(r1, unop(Iop_16Uto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
5754 ((ULong)(Long)(Int)i2 << 1)))));
5755
5756 return "llghrl";
5757}
5758
5759static HChar *
5760s390_irgen_LLHH(UChar r1, IRTemp op2addr)
5761{
5762 put_gpr_w0(r1, unop(Iop_16Uto32, load(Ity_I16, mkexpr(op2addr))));
5763
5764 return "llhh";
5765}
5766
5767static HChar *
5768s390_irgen_LLIHF(UChar r1, UInt i2)
5769{
5770 put_gpr_dw0(r1, mkU64(((ULong)i2) << 32));
5771
5772 return "llihf";
5773}
5774
5775static HChar *
5776s390_irgen_LLIHH(UChar r1, UShort i2)
5777{
5778 put_gpr_dw0(r1, mkU64(((ULong)i2) << 48));
5779
5780 return "llihh";
5781}
5782
5783static HChar *
5784s390_irgen_LLIHL(UChar r1, UShort i2)
5785{
5786 put_gpr_dw0(r1, mkU64(((ULong)i2) << 32));
5787
5788 return "llihl";
5789}
5790
5791static HChar *
5792s390_irgen_LLILF(UChar r1, UInt i2)
5793{
5794 put_gpr_dw0(r1, mkU64(i2));
5795
5796 return "llilf";
5797}
5798
5799static HChar *
5800s390_irgen_LLILH(UChar r1, UShort i2)
5801{
5802 put_gpr_dw0(r1, mkU64(((ULong)i2) << 16));
5803
5804 return "llilh";
5805}
5806
5807static HChar *
5808s390_irgen_LLILL(UChar r1, UShort i2)
5809{
5810 put_gpr_dw0(r1, mkU64(i2));
5811
5812 return "llill";
5813}
5814
5815static HChar *
5816s390_irgen_LLGTR(UChar r1, UChar r2)
5817{
5818 put_gpr_dw0(r1, unop(Iop_32Uto64, binop(Iop_And32, get_gpr_w1(r2),
5819 mkU32(2147483647))));
5820
5821 return "llgtr";
5822}
5823
5824static HChar *
5825s390_irgen_LLGT(UChar r1, IRTemp op2addr)
5826{
5827 put_gpr_dw0(r1, unop(Iop_32Uto64, binop(Iop_And32, load(Ity_I32,
5828 mkexpr(op2addr)), mkU32(2147483647))));
5829
5830 return "llgt";
5831}
5832
5833static HChar *
5834s390_irgen_LNR(UChar r1, UChar r2)
5835{
5836 IRTemp op2 = newTemp(Ity_I32);
5837 IRTemp result = newTemp(Ity_I32);
5838
5839 assign(op2, get_gpr_w1(r2));
5840 assign(result, mkite(binop(Iop_CmpLE32S, mkexpr(op2), mkU32(0)), mkexpr(op2),
5841 binop(Iop_Sub32, mkU32(0), mkexpr(op2))));
5842 put_gpr_w1(r1, mkexpr(result));
5843 s390_cc_thunk_putS(S390_CC_OP_BITWISE, result);
5844
5845 return "lnr";
5846}
5847
5848static HChar *
5849s390_irgen_LNGR(UChar r1, UChar r2)
5850{
5851 IRTemp op2 = newTemp(Ity_I64);
5852 IRTemp result = newTemp(Ity_I64);
5853
5854 assign(op2, get_gpr_dw0(r2));
5855 assign(result, mkite(binop(Iop_CmpLE64S, mkexpr(op2), mkU64(0)), mkexpr(op2),
5856 binop(Iop_Sub64, mkU64(0), mkexpr(op2))));
5857 put_gpr_dw0(r1, mkexpr(result));
5858 s390_cc_thunk_putS(S390_CC_OP_BITWISE, result);
5859
5860 return "lngr";
5861}
5862
5863static HChar *
5864s390_irgen_LNGFR(UChar r1, UChar r2 __attribute__((unused)))
5865{
5866 IRTemp op2 = newTemp(Ity_I64);
5867 IRTemp result = newTemp(Ity_I64);
5868
5869 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r1)));
5870 assign(result, mkite(binop(Iop_CmpLE64S, mkexpr(op2), mkU64(0)), mkexpr(op2),
5871 binop(Iop_Sub64, mkU64(0), mkexpr(op2))));
5872 put_gpr_dw0(r1, mkexpr(result));
5873 s390_cc_thunk_putS(S390_CC_OP_BITWISE, result);
5874
5875 return "lngfr";
5876}
5877
5878static HChar *
sewardjd7bde722011-04-05 13:19:33 +00005879s390_irgen_LOCR(UChar m3, UChar r1, UChar r2)
5880{
florian6820ba52012-07-26 02:01:50 +00005881 next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0)));
sewardjd7bde722011-04-05 13:19:33 +00005882 put_gpr_w1(r1, get_gpr_w1(r2));
5883
5884 return "locr";
5885}
5886
5887static HChar *
5888s390_irgen_LOCGR(UChar m3, UChar r1, UChar r2)
5889{
florian6820ba52012-07-26 02:01:50 +00005890 next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0)));
sewardjd7bde722011-04-05 13:19:33 +00005891 put_gpr_dw0(r1, get_gpr_dw0(r2));
5892
5893 return "locgr";
5894}
5895
5896static HChar *
5897s390_irgen_LOC(UChar r1, IRTemp op2addr)
5898{
5899 /* condition is checked in format handler */
5900 put_gpr_w1(r1, load(Ity_I32, mkexpr(op2addr)));
5901
5902 return "loc";
5903}
5904
5905static HChar *
5906s390_irgen_LOCG(UChar r1, IRTemp op2addr)
5907{
5908 /* condition is checked in format handler */
5909 put_gpr_dw0(r1, load(Ity_I64, mkexpr(op2addr)));
5910
5911 return "locg";
5912}
5913
5914static HChar *
sewardj2019a972011-03-07 16:04:07 +00005915s390_irgen_LPQ(UChar r1, IRTemp op2addr)
5916{
5917 put_gpr_dw0(r1, load(Ity_I64, mkexpr(op2addr)));
5918 put_gpr_dw0(r1 + 1, load(Ity_I64, binop(Iop_Add64, mkexpr(op2addr), mkU64(8))
5919 ));
5920
5921 return "lpq";
5922}
5923
5924static HChar *
5925s390_irgen_LPR(UChar r1, UChar r2)
5926{
5927 IRTemp op2 = newTemp(Ity_I32);
5928 IRTemp result = newTemp(Ity_I32);
5929
5930 assign(op2, get_gpr_w1(r2));
5931 assign(result, mkite(binop(Iop_CmpLT32S, mkexpr(op2), mkU32(0)),
5932 binop(Iop_Sub32, mkU32(0), mkexpr(op2)), mkexpr(op2)));
5933 put_gpr_w1(r1, mkexpr(result));
5934 s390_cc_thunk_putS(S390_CC_OP_LOAD_POSITIVE_32, op2);
5935
5936 return "lpr";
5937}
5938
5939static HChar *
5940s390_irgen_LPGR(UChar r1, UChar r2)
5941{
5942 IRTemp op2 = newTemp(Ity_I64);
5943 IRTemp result = newTemp(Ity_I64);
5944
5945 assign(op2, get_gpr_dw0(r2));
5946 assign(result, mkite(binop(Iop_CmpLT64S, mkexpr(op2), mkU64(0)),
5947 binop(Iop_Sub64, mkU64(0), mkexpr(op2)), mkexpr(op2)));
5948 put_gpr_dw0(r1, mkexpr(result));
5949 s390_cc_thunk_putS(S390_CC_OP_LOAD_POSITIVE_64, op2);
5950
5951 return "lpgr";
5952}
5953
5954static HChar *
5955s390_irgen_LPGFR(UChar r1, UChar r2)
5956{
5957 IRTemp op2 = newTemp(Ity_I64);
5958 IRTemp result = newTemp(Ity_I64);
5959
5960 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
5961 assign(result, mkite(binop(Iop_CmpLT64S, mkexpr(op2), mkU64(0)),
5962 binop(Iop_Sub64, mkU64(0), mkexpr(op2)), mkexpr(op2)));
5963 put_gpr_dw0(r1, mkexpr(result));
5964 s390_cc_thunk_putS(S390_CC_OP_LOAD_POSITIVE_64, op2);
5965
5966 return "lpgfr";
5967}
5968
5969static HChar *
5970s390_irgen_LRVR(UChar r1, UChar r2)
5971{
5972 IRTemp b0 = newTemp(Ity_I8);
5973 IRTemp b1 = newTemp(Ity_I8);
5974 IRTemp b2 = newTemp(Ity_I8);
5975 IRTemp b3 = newTemp(Ity_I8);
5976
5977 assign(b3, get_gpr_b7(r2));
5978 assign(b2, get_gpr_b6(r2));
5979 assign(b1, get_gpr_b5(r2));
5980 assign(b0, get_gpr_b4(r2));
5981 put_gpr_b4(r1, mkexpr(b3));
5982 put_gpr_b5(r1, mkexpr(b2));
5983 put_gpr_b6(r1, mkexpr(b1));
5984 put_gpr_b7(r1, mkexpr(b0));
5985
5986 return "lrvr";
5987}
5988
5989static HChar *
5990s390_irgen_LRVGR(UChar r1, UChar r2)
5991{
5992 IRTemp b0 = newTemp(Ity_I8);
5993 IRTemp b1 = newTemp(Ity_I8);
5994 IRTemp b2 = newTemp(Ity_I8);
5995 IRTemp b3 = newTemp(Ity_I8);
5996 IRTemp b4 = newTemp(Ity_I8);
5997 IRTemp b5 = newTemp(Ity_I8);
5998 IRTemp b6 = newTemp(Ity_I8);
5999 IRTemp b7 = newTemp(Ity_I8);
6000
6001 assign(b7, get_gpr_b7(r2));
6002 assign(b6, get_gpr_b6(r2));
6003 assign(b5, get_gpr_b5(r2));
6004 assign(b4, get_gpr_b4(r2));
6005 assign(b3, get_gpr_b3(r2));
6006 assign(b2, get_gpr_b2(r2));
6007 assign(b1, get_gpr_b1(r2));
6008 assign(b0, get_gpr_b0(r2));
6009 put_gpr_b0(r1, mkexpr(b7));
6010 put_gpr_b1(r1, mkexpr(b6));
6011 put_gpr_b2(r1, mkexpr(b5));
6012 put_gpr_b3(r1, mkexpr(b4));
6013 put_gpr_b4(r1, mkexpr(b3));
6014 put_gpr_b5(r1, mkexpr(b2));
6015 put_gpr_b6(r1, mkexpr(b1));
6016 put_gpr_b7(r1, mkexpr(b0));
6017
6018 return "lrvgr";
6019}
6020
6021static HChar *
6022s390_irgen_LRVH(UChar r1, IRTemp op2addr)
6023{
6024 IRTemp op2 = newTemp(Ity_I16);
6025
6026 assign(op2, load(Ity_I16, mkexpr(op2addr)));
6027 put_gpr_b6(r1, unop(Iop_16to8, mkexpr(op2)));
6028 put_gpr_b7(r1, unop(Iop_16HIto8, mkexpr(op2)));
6029
6030 return "lrvh";
6031}
6032
6033static HChar *
6034s390_irgen_LRV(UChar r1, IRTemp op2addr)
6035{
6036 IRTemp op2 = newTemp(Ity_I32);
6037
6038 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6039 put_gpr_b4(r1, unop(Iop_32to8, binop(Iop_And32, mkexpr(op2), mkU32(255))));
6040 put_gpr_b5(r1, unop(Iop_32to8, binop(Iop_And32, binop(Iop_Shr32, mkexpr(op2),
6041 mkU8(8)), mkU32(255))));
6042 put_gpr_b6(r1, unop(Iop_32to8, binop(Iop_And32, binop(Iop_Shr32, mkexpr(op2),
6043 mkU8(16)), mkU32(255))));
6044 put_gpr_b7(r1, unop(Iop_32to8, binop(Iop_And32, binop(Iop_Shr32, mkexpr(op2),
6045 mkU8(24)), mkU32(255))));
6046
6047 return "lrv";
6048}
6049
6050static HChar *
6051s390_irgen_LRVG(UChar r1, IRTemp op2addr)
6052{
6053 IRTemp op2 = newTemp(Ity_I64);
6054
6055 assign(op2, load(Ity_I64, mkexpr(op2addr)));
6056 put_gpr_b0(r1, unop(Iop_64to8, binop(Iop_And64, mkexpr(op2), mkU64(255))));
6057 put_gpr_b1(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6058 mkU8(8)), mkU64(255))));
6059 put_gpr_b2(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6060 mkU8(16)), mkU64(255))));
6061 put_gpr_b3(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6062 mkU8(24)), mkU64(255))));
6063 put_gpr_b4(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6064 mkU8(32)), mkU64(255))));
6065 put_gpr_b5(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6066 mkU8(40)), mkU64(255))));
6067 put_gpr_b6(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6068 mkU8(48)), mkU64(255))));
6069 put_gpr_b7(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6070 mkU8(56)), mkU64(255))));
6071
6072 return "lrvg";
6073}
6074
6075static HChar *
6076s390_irgen_MVHHI(UShort i2, IRTemp op1addr)
6077{
6078 store(mkexpr(op1addr), mkU16(i2));
6079
6080 return "mvhhi";
6081}
6082
6083static HChar *
6084s390_irgen_MVHI(UShort i2, IRTemp op1addr)
6085{
6086 store(mkexpr(op1addr), mkU32((UInt)(Int)(Short)i2));
6087
6088 return "mvhi";
6089}
6090
6091static HChar *
6092s390_irgen_MVGHI(UShort i2, IRTemp op1addr)
6093{
6094 store(mkexpr(op1addr), mkU64((ULong)(Long)(Short)i2));
6095
6096 return "mvghi";
6097}
6098
6099static HChar *
6100s390_irgen_MVI(UChar i2, IRTemp op1addr)
6101{
6102 store(mkexpr(op1addr), mkU8(i2));
6103
6104 return "mvi";
6105}
6106
6107static HChar *
6108s390_irgen_MVIY(UChar i2, IRTemp op1addr)
6109{
6110 store(mkexpr(op1addr), mkU8(i2));
6111
6112 return "mviy";
6113}
6114
6115static HChar *
6116s390_irgen_MR(UChar r1, UChar r2)
6117{
6118 IRTemp op1 = newTemp(Ity_I32);
6119 IRTemp op2 = newTemp(Ity_I32);
6120 IRTemp result = newTemp(Ity_I64);
6121
6122 assign(op1, get_gpr_w1(r1 + 1));
6123 assign(op2, get_gpr_w1(r2));
6124 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6125 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6126 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6127
6128 return "mr";
6129}
6130
6131static HChar *
6132s390_irgen_M(UChar r1, IRTemp op2addr)
6133{
6134 IRTemp op1 = newTemp(Ity_I32);
6135 IRTemp op2 = newTemp(Ity_I32);
6136 IRTemp result = newTemp(Ity_I64);
6137
6138 assign(op1, get_gpr_w1(r1 + 1));
6139 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6140 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6141 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6142 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6143
6144 return "m";
6145}
6146
6147static HChar *
6148s390_irgen_MFY(UChar r1, IRTemp op2addr)
6149{
6150 IRTemp op1 = newTemp(Ity_I32);
6151 IRTemp op2 = newTemp(Ity_I32);
6152 IRTemp result = newTemp(Ity_I64);
6153
6154 assign(op1, get_gpr_w1(r1 + 1));
6155 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6156 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6157 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6158 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6159
6160 return "mfy";
6161}
6162
6163static HChar *
6164s390_irgen_MH(UChar r1, IRTemp op2addr)
6165{
6166 IRTemp op1 = newTemp(Ity_I32);
6167 IRTemp op2 = newTemp(Ity_I16);
6168 IRTemp result = newTemp(Ity_I64);
6169
6170 assign(op1, get_gpr_w1(r1));
6171 assign(op2, load(Ity_I16, mkexpr(op2addr)));
6172 assign(result, binop(Iop_MullS32, mkexpr(op1), unop(Iop_16Sto32, mkexpr(op2))
6173 ));
6174 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6175
6176 return "mh";
6177}
6178
6179static HChar *
6180s390_irgen_MHY(UChar r1, IRTemp op2addr)
6181{
6182 IRTemp op1 = newTemp(Ity_I32);
6183 IRTemp op2 = newTemp(Ity_I16);
6184 IRTemp result = newTemp(Ity_I64);
6185
6186 assign(op1, get_gpr_w1(r1));
6187 assign(op2, load(Ity_I16, mkexpr(op2addr)));
6188 assign(result, binop(Iop_MullS32, mkexpr(op1), unop(Iop_16Sto32, mkexpr(op2))
6189 ));
6190 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6191
6192 return "mhy";
6193}
6194
6195static HChar *
6196s390_irgen_MHI(UChar r1, UShort i2)
6197{
6198 IRTemp op1 = newTemp(Ity_I32);
6199 Short op2;
6200 IRTemp result = newTemp(Ity_I64);
6201
6202 assign(op1, get_gpr_w1(r1));
6203 op2 = (Short)i2;
6204 assign(result, binop(Iop_MullS32, mkexpr(op1), unop(Iop_16Sto32,
6205 mkU16((UShort)op2))));
6206 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6207
6208 return "mhi";
6209}
6210
6211static HChar *
6212s390_irgen_MGHI(UChar r1, UShort i2)
6213{
6214 IRTemp op1 = newTemp(Ity_I64);
6215 Short op2;
6216 IRTemp result = newTemp(Ity_I128);
6217
6218 assign(op1, get_gpr_dw0(r1));
6219 op2 = (Short)i2;
6220 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_16Sto64,
6221 mkU16((UShort)op2))));
6222 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6223
6224 return "mghi";
6225}
6226
6227static HChar *
6228s390_irgen_MLR(UChar r1, UChar r2)
6229{
6230 IRTemp op1 = newTemp(Ity_I32);
6231 IRTemp op2 = newTemp(Ity_I32);
6232 IRTemp result = newTemp(Ity_I64);
6233
6234 assign(op1, get_gpr_w1(r1 + 1));
6235 assign(op2, get_gpr_w1(r2));
6236 assign(result, binop(Iop_MullU32, mkexpr(op1), mkexpr(op2)));
6237 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6238 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6239
6240 return "mlr";
6241}
6242
6243static HChar *
6244s390_irgen_MLGR(UChar r1, UChar r2)
6245{
6246 IRTemp op1 = newTemp(Ity_I64);
6247 IRTemp op2 = newTemp(Ity_I64);
6248 IRTemp result = newTemp(Ity_I128);
6249
6250 assign(op1, get_gpr_dw0(r1 + 1));
6251 assign(op2, get_gpr_dw0(r2));
6252 assign(result, binop(Iop_MullU64, mkexpr(op1), mkexpr(op2)));
6253 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result)));
6254 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result)));
6255
6256 return "mlgr";
6257}
6258
6259static HChar *
6260s390_irgen_ML(UChar r1, IRTemp op2addr)
6261{
6262 IRTemp op1 = newTemp(Ity_I32);
6263 IRTemp op2 = newTemp(Ity_I32);
6264 IRTemp result = newTemp(Ity_I64);
6265
6266 assign(op1, get_gpr_w1(r1 + 1));
6267 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6268 assign(result, binop(Iop_MullU32, mkexpr(op1), mkexpr(op2)));
6269 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6270 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6271
6272 return "ml";
6273}
6274
6275static HChar *
6276s390_irgen_MLG(UChar r1, IRTemp op2addr)
6277{
6278 IRTemp op1 = newTemp(Ity_I64);
6279 IRTemp op2 = newTemp(Ity_I64);
6280 IRTemp result = newTemp(Ity_I128);
6281
6282 assign(op1, get_gpr_dw0(r1 + 1));
6283 assign(op2, load(Ity_I64, mkexpr(op2addr)));
6284 assign(result, binop(Iop_MullU64, mkexpr(op1), mkexpr(op2)));
6285 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result)));
6286 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result)));
6287
6288 return "mlg";
6289}
6290
6291static HChar *
6292s390_irgen_MSR(UChar r1, UChar r2)
6293{
6294 IRTemp op1 = newTemp(Ity_I32);
6295 IRTemp op2 = newTemp(Ity_I32);
6296 IRTemp result = newTemp(Ity_I64);
6297
6298 assign(op1, get_gpr_w1(r1));
6299 assign(op2, get_gpr_w1(r2));
6300 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6301 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6302
6303 return "msr";
6304}
6305
6306static HChar *
6307s390_irgen_MSGR(UChar r1, UChar r2)
6308{
6309 IRTemp op1 = newTemp(Ity_I64);
6310 IRTemp op2 = newTemp(Ity_I64);
6311 IRTemp result = newTemp(Ity_I128);
6312
6313 assign(op1, get_gpr_dw0(r1));
6314 assign(op2, get_gpr_dw0(r2));
6315 assign(result, binop(Iop_MullS64, mkexpr(op1), mkexpr(op2)));
6316 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6317
6318 return "msgr";
6319}
6320
6321static HChar *
6322s390_irgen_MSGFR(UChar r1, UChar r2)
6323{
6324 IRTemp op1 = newTemp(Ity_I64);
6325 IRTemp op2 = newTemp(Ity_I32);
6326 IRTemp result = newTemp(Ity_I128);
6327
6328 assign(op1, get_gpr_dw0(r1));
6329 assign(op2, get_gpr_w1(r2));
6330 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_32Sto64, mkexpr(op2))
6331 ));
6332 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6333
6334 return "msgfr";
6335}
6336
6337static HChar *
6338s390_irgen_MS(UChar r1, IRTemp op2addr)
6339{
6340 IRTemp op1 = newTemp(Ity_I32);
6341 IRTemp op2 = newTemp(Ity_I32);
6342 IRTemp result = newTemp(Ity_I64);
6343
6344 assign(op1, get_gpr_w1(r1));
6345 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6346 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6347 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6348
6349 return "ms";
6350}
6351
6352static HChar *
6353s390_irgen_MSY(UChar r1, IRTemp op2addr)
6354{
6355 IRTemp op1 = newTemp(Ity_I32);
6356 IRTemp op2 = newTemp(Ity_I32);
6357 IRTemp result = newTemp(Ity_I64);
6358
6359 assign(op1, get_gpr_w1(r1));
6360 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6361 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6362 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6363
6364 return "msy";
6365}
6366
6367static HChar *
6368s390_irgen_MSG(UChar r1, IRTemp op2addr)
6369{
6370 IRTemp op1 = newTemp(Ity_I64);
6371 IRTemp op2 = newTemp(Ity_I64);
6372 IRTemp result = newTemp(Ity_I128);
6373
6374 assign(op1, get_gpr_dw0(r1));
6375 assign(op2, load(Ity_I64, mkexpr(op2addr)));
6376 assign(result, binop(Iop_MullS64, mkexpr(op1), mkexpr(op2)));
6377 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6378
6379 return "msg";
6380}
6381
6382static HChar *
6383s390_irgen_MSGF(UChar r1, IRTemp op2addr)
6384{
6385 IRTemp op1 = newTemp(Ity_I64);
6386 IRTemp op2 = newTemp(Ity_I32);
6387 IRTemp result = newTemp(Ity_I128);
6388
6389 assign(op1, get_gpr_dw0(r1));
6390 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6391 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_32Sto64, mkexpr(op2))
6392 ));
6393 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6394
6395 return "msgf";
6396}
6397
6398static HChar *
6399s390_irgen_MSFI(UChar r1, UInt i2)
6400{
6401 IRTemp op1 = newTemp(Ity_I32);
6402 Int op2;
6403 IRTemp result = newTemp(Ity_I64);
6404
6405 assign(op1, get_gpr_w1(r1));
6406 op2 = (Int)i2;
6407 assign(result, binop(Iop_MullS32, mkexpr(op1), mkU32((UInt)op2)));
6408 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6409
6410 return "msfi";
6411}
6412
6413static HChar *
6414s390_irgen_MSGFI(UChar r1, UInt i2)
6415{
6416 IRTemp op1 = newTemp(Ity_I64);
6417 Int op2;
6418 IRTemp result = newTemp(Ity_I128);
6419
6420 assign(op1, get_gpr_dw0(r1));
6421 op2 = (Int)i2;
6422 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_32Sto64, mkU32((UInt)
6423 op2))));
6424 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6425
6426 return "msgfi";
6427}
6428
6429static HChar *
6430s390_irgen_OR(UChar r1, UChar r2)
6431{
6432 IRTemp op1 = newTemp(Ity_I32);
6433 IRTemp op2 = newTemp(Ity_I32);
6434 IRTemp result = newTemp(Ity_I32);
6435
6436 assign(op1, get_gpr_w1(r1));
6437 assign(op2, get_gpr_w1(r2));
6438 assign(result, binop(Iop_Or32, mkexpr(op1), mkexpr(op2)));
6439 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6440 put_gpr_w1(r1, mkexpr(result));
6441
6442 return "or";
6443}
6444
6445static HChar *
6446s390_irgen_OGR(UChar r1, UChar r2)
6447{
6448 IRTemp op1 = newTemp(Ity_I64);
6449 IRTemp op2 = newTemp(Ity_I64);
6450 IRTemp result = newTemp(Ity_I64);
6451
6452 assign(op1, get_gpr_dw0(r1));
6453 assign(op2, get_gpr_dw0(r2));
6454 assign(result, binop(Iop_Or64, mkexpr(op1), mkexpr(op2)));
6455 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6456 put_gpr_dw0(r1, mkexpr(result));
6457
6458 return "ogr";
6459}
6460
6461static HChar *
6462s390_irgen_ORK(UChar r3, UChar r1, UChar r2)
6463{
6464 IRTemp op2 = newTemp(Ity_I32);
6465 IRTemp op3 = newTemp(Ity_I32);
6466 IRTemp result = newTemp(Ity_I32);
6467
6468 assign(op2, get_gpr_w1(r2));
6469 assign(op3, get_gpr_w1(r3));
6470 assign(result, binop(Iop_Or32, mkexpr(op2), mkexpr(op3)));
6471 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6472 put_gpr_w1(r1, mkexpr(result));
6473
6474 return "ork";
6475}
6476
6477static HChar *
6478s390_irgen_OGRK(UChar r3, UChar r1, UChar r2)
6479{
6480 IRTemp op2 = newTemp(Ity_I64);
6481 IRTemp op3 = newTemp(Ity_I64);
6482 IRTemp result = newTemp(Ity_I64);
6483
6484 assign(op2, get_gpr_dw0(r2));
6485 assign(op3, get_gpr_dw0(r3));
6486 assign(result, binop(Iop_Or64, mkexpr(op2), mkexpr(op3)));
6487 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6488 put_gpr_dw0(r1, mkexpr(result));
6489
6490 return "ogrk";
6491}
6492
6493static HChar *
6494s390_irgen_O(UChar r1, IRTemp op2addr)
6495{
6496 IRTemp op1 = newTemp(Ity_I32);
6497 IRTemp op2 = newTemp(Ity_I32);
6498 IRTemp result = newTemp(Ity_I32);
6499
6500 assign(op1, get_gpr_w1(r1));
6501 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6502 assign(result, binop(Iop_Or32, mkexpr(op1), mkexpr(op2)));
6503 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6504 put_gpr_w1(r1, mkexpr(result));
6505
6506 return "o";
6507}
6508
6509static HChar *
6510s390_irgen_OY(UChar r1, IRTemp op2addr)
6511{
6512 IRTemp op1 = newTemp(Ity_I32);
6513 IRTemp op2 = newTemp(Ity_I32);
6514 IRTemp result = newTemp(Ity_I32);
6515
6516 assign(op1, get_gpr_w1(r1));
6517 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6518 assign(result, binop(Iop_Or32, mkexpr(op1), mkexpr(op2)));
6519 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6520 put_gpr_w1(r1, mkexpr(result));
6521
6522 return "oy";
6523}
6524
6525static HChar *
6526s390_irgen_OG(UChar r1, IRTemp op2addr)
6527{
6528 IRTemp op1 = newTemp(Ity_I64);
6529 IRTemp op2 = newTemp(Ity_I64);
6530 IRTemp result = newTemp(Ity_I64);
6531
6532 assign(op1, get_gpr_dw0(r1));
6533 assign(op2, load(Ity_I64, mkexpr(op2addr)));
6534 assign(result, binop(Iop_Or64, mkexpr(op1), mkexpr(op2)));
6535 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6536 put_gpr_dw0(r1, mkexpr(result));
6537
6538 return "og";
6539}
6540
6541static HChar *
6542s390_irgen_OI(UChar i2, IRTemp op1addr)
6543{
6544 IRTemp op1 = newTemp(Ity_I8);
6545 UChar op2;
6546 IRTemp result = newTemp(Ity_I8);
6547
6548 assign(op1, load(Ity_I8, mkexpr(op1addr)));
6549 op2 = i2;
6550 assign(result, binop(Iop_Or8, mkexpr(op1), mkU8(op2)));
6551 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6552 store(mkexpr(op1addr), mkexpr(result));
6553
6554 return "oi";
6555}
6556
6557static HChar *
6558s390_irgen_OIY(UChar i2, IRTemp op1addr)
6559{
6560 IRTemp op1 = newTemp(Ity_I8);
6561 UChar op2;
6562 IRTemp result = newTemp(Ity_I8);
6563
6564 assign(op1, load(Ity_I8, mkexpr(op1addr)));
6565 op2 = i2;
6566 assign(result, binop(Iop_Or8, mkexpr(op1), mkU8(op2)));
6567 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6568 store(mkexpr(op1addr), mkexpr(result));
6569
6570 return "oiy";
6571}
6572
6573static HChar *
6574s390_irgen_OIHF(UChar r1, UInt i2)
6575{
6576 IRTemp op1 = newTemp(Ity_I32);
6577 UInt op2;
6578 IRTemp result = newTemp(Ity_I32);
6579
6580 assign(op1, get_gpr_w0(r1));
6581 op2 = i2;
6582 assign(result, binop(Iop_Or32, mkexpr(op1), mkU32(op2)));
6583 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6584 put_gpr_w0(r1, mkexpr(result));
6585
6586 return "oihf";
6587}
6588
6589static HChar *
6590s390_irgen_OIHH(UChar r1, UShort i2)
6591{
6592 IRTemp op1 = newTemp(Ity_I16);
6593 UShort op2;
6594 IRTemp result = newTemp(Ity_I16);
6595
6596 assign(op1, get_gpr_hw0(r1));
6597 op2 = i2;
6598 assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
6599 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6600 put_gpr_hw0(r1, mkexpr(result));
6601
6602 return "oihh";
6603}
6604
6605static HChar *
6606s390_irgen_OIHL(UChar r1, UShort i2)
6607{
6608 IRTemp op1 = newTemp(Ity_I16);
6609 UShort op2;
6610 IRTemp result = newTemp(Ity_I16);
6611
6612 assign(op1, get_gpr_hw1(r1));
6613 op2 = i2;
6614 assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
6615 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6616 put_gpr_hw1(r1, mkexpr(result));
6617
6618 return "oihl";
6619}
6620
6621static HChar *
6622s390_irgen_OILF(UChar r1, UInt i2)
6623{
6624 IRTemp op1 = newTemp(Ity_I32);
6625 UInt op2;
6626 IRTemp result = newTemp(Ity_I32);
6627
6628 assign(op1, get_gpr_w1(r1));
6629 op2 = i2;
6630 assign(result, binop(Iop_Or32, mkexpr(op1), mkU32(op2)));
6631 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6632 put_gpr_w1(r1, mkexpr(result));
6633
6634 return "oilf";
6635}
6636
6637static HChar *
6638s390_irgen_OILH(UChar r1, UShort i2)
6639{
6640 IRTemp op1 = newTemp(Ity_I16);
6641 UShort op2;
6642 IRTemp result = newTemp(Ity_I16);
6643
6644 assign(op1, get_gpr_hw2(r1));
6645 op2 = i2;
6646 assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
6647 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6648 put_gpr_hw2(r1, mkexpr(result));
6649
6650 return "oilh";
6651}
6652
6653static HChar *
6654s390_irgen_OILL(UChar r1, UShort i2)
6655{
6656 IRTemp op1 = newTemp(Ity_I16);
6657 UShort op2;
6658 IRTemp result = newTemp(Ity_I16);
6659
6660 assign(op1, get_gpr_hw3(r1));
6661 op2 = i2;
6662 assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
6663 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6664 put_gpr_hw3(r1, mkexpr(result));
6665
6666 return "oill";
6667}
6668
6669static HChar *
6670s390_irgen_PFD(void)
6671{
6672
6673 return "pfd";
6674}
6675
6676static HChar *
6677s390_irgen_PFDRL(void)
6678{
6679
6680 return "pfdrl";
6681}
6682
6683static HChar *
6684s390_irgen_RLL(UChar r1, UChar r3, IRTemp op2addr)
6685{
6686 IRTemp amount = newTemp(Ity_I64);
6687 IRTemp op = newTemp(Ity_I32);
6688
6689 assign(amount, binop(Iop_And64, mkexpr(op2addr), mkU64(31)));
6690 assign(op, get_gpr_w1(r3));
6691 put_gpr_w1(r1, binop(Iop_Or32, binop(Iop_Shl32, mkexpr(op), unop(Iop_64to8,
6692 mkexpr(amount))), binop(Iop_Shr32, mkexpr(op), unop(Iop_64to8,
6693 binop(Iop_Sub64, mkU64(32), mkexpr(amount))))));
6694
6695 return "rll";
6696}
6697
6698static HChar *
6699s390_irgen_RLLG(UChar r1, UChar r3, IRTemp op2addr)
6700{
6701 IRTemp amount = newTemp(Ity_I64);
6702 IRTemp op = newTemp(Ity_I64);
6703
6704 assign(amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
6705 assign(op, get_gpr_dw0(r3));
6706 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(op), unop(Iop_64to8,
6707 mkexpr(amount))), binop(Iop_Shr64, mkexpr(op), unop(Iop_64to8,
6708 binop(Iop_Sub64, mkU64(64), mkexpr(amount))))));
6709
6710 return "rllg";
6711}
6712
6713static HChar *
6714s390_irgen_RNSBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
6715{
6716 UChar from;
6717 UChar to;
6718 UChar rot;
6719 UChar t_bit;
6720 ULong mask;
6721 ULong maskc;
6722 IRTemp result = newTemp(Ity_I64);
6723 IRTemp op2 = newTemp(Ity_I64);
6724
6725 from = i3 & 63;
6726 to = i4 & 63;
6727 rot = i5 & 63;
6728 t_bit = i3 & 128;
6729 assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
6730 get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
6731 mkU8(64 - rot))));
6732 if (from <= to) {
6733 mask = ~0ULL;
6734 mask = (mask >> from) & (mask << (63 - to));
6735 maskc = ~mask;
6736 } else {
6737 maskc = ~0ULL;
6738 maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
6739 mask = ~maskc;
6740 }
6741 assign(result, binop(Iop_And64, binop(Iop_And64, get_gpr_dw0(r1), mkexpr(op2)
6742 ), mkU64(mask)));
6743 if (t_bit == 0) {
6744 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
6745 mkU64(maskc)), mkexpr(result)));
6746 }
6747 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6748
6749 return "rnsbg";
6750}
6751
6752static HChar *
6753s390_irgen_RXSBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
6754{
6755 UChar from;
6756 UChar to;
6757 UChar rot;
6758 UChar t_bit;
6759 ULong mask;
6760 ULong maskc;
6761 IRTemp result = newTemp(Ity_I64);
6762 IRTemp op2 = newTemp(Ity_I64);
6763
6764 from = i3 & 63;
6765 to = i4 & 63;
6766 rot = i5 & 63;
6767 t_bit = i3 & 128;
6768 assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
6769 get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
6770 mkU8(64 - rot))));
6771 if (from <= to) {
6772 mask = ~0ULL;
6773 mask = (mask >> from) & (mask << (63 - to));
6774 maskc = ~mask;
6775 } else {
6776 maskc = ~0ULL;
6777 maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
6778 mask = ~maskc;
6779 }
6780 assign(result, binop(Iop_And64, binop(Iop_Xor64, get_gpr_dw0(r1), mkexpr(op2)
6781 ), mkU64(mask)));
6782 if (t_bit == 0) {
6783 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
6784 mkU64(maskc)), mkexpr(result)));
6785 }
6786 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6787
6788 return "rxsbg";
6789}
6790
6791static HChar *
6792s390_irgen_ROSBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
6793{
6794 UChar from;
6795 UChar to;
6796 UChar rot;
6797 UChar t_bit;
6798 ULong mask;
6799 ULong maskc;
6800 IRTemp result = newTemp(Ity_I64);
6801 IRTemp op2 = newTemp(Ity_I64);
6802
6803 from = i3 & 63;
6804 to = i4 & 63;
6805 rot = i5 & 63;
6806 t_bit = i3 & 128;
6807 assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
6808 get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
6809 mkU8(64 - rot))));
6810 if (from <= to) {
6811 mask = ~0ULL;
6812 mask = (mask >> from) & (mask << (63 - to));
6813 maskc = ~mask;
6814 } else {
6815 maskc = ~0ULL;
6816 maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
6817 mask = ~maskc;
6818 }
6819 assign(result, binop(Iop_And64, binop(Iop_Or64, get_gpr_dw0(r1), mkexpr(op2)
6820 ), mkU64(mask)));
6821 if (t_bit == 0) {
6822 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
6823 mkU64(maskc)), mkexpr(result)));
6824 }
6825 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6826
6827 return "rosbg";
6828}
6829
6830static HChar *
6831s390_irgen_RISBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
6832{
6833 UChar from;
6834 UChar to;
6835 UChar rot;
6836 UChar z_bit;
6837 ULong mask;
6838 ULong maskc;
6839 IRTemp op2 = newTemp(Ity_I64);
6840 IRTemp result = newTemp(Ity_I64);
6841
6842 from = i3 & 63;
6843 to = i4 & 63;
6844 rot = i5 & 63;
6845 z_bit = i4 & 128;
6846 assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
6847 get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
6848 mkU8(64 - rot))));
6849 if (from <= to) {
6850 mask = ~0ULL;
6851 mask = (mask >> from) & (mask << (63 - to));
6852 maskc = ~mask;
6853 } else {
6854 maskc = ~0ULL;
6855 maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
6856 mask = ~maskc;
6857 }
6858 if (z_bit == 0) {
6859 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
6860 mkU64(maskc)), binop(Iop_And64, mkexpr(op2), mkU64(mask))));
6861 } else {
6862 put_gpr_dw0(r1, binop(Iop_And64, mkexpr(op2), mkU64(mask)));
6863 }
6864 assign(result, get_gpr_dw0(r1));
6865 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
6866
6867 return "risbg";
6868}
6869
6870static HChar *
6871s390_irgen_SAR(UChar r1, UChar r2)
6872{
6873 put_ar_w0(r1, get_gpr_w1(r2));
sewardj7ee97522011-05-09 21:45:04 +00006874 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00006875 s390_disasm(ENC3(MNM, AR, GPR), "sar", r1, r2);
6876
6877 return "sar";
6878}
6879
6880static HChar *
6881s390_irgen_SLDA(UChar r1, IRTemp op2addr)
6882{
6883 IRTemp p1 = newTemp(Ity_I64);
6884 IRTemp p2 = newTemp(Ity_I64);
6885 IRTemp op = newTemp(Ity_I64);
6886 IRTemp result = newTemp(Ity_I64);
florian417b22d2012-07-13 13:41:41 +00006887 ULong sign_mask;
sewardj2019a972011-03-07 16:04:07 +00006888 IRTemp shift_amount = newTemp(Ity_I64);
6889
6890 assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
6891 assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
6892 assign(op, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1), mkU8(32)), mkexpr(p2)
6893 ));
6894 sign_mask = 1ULL << 63;
6895 assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
6896 assign(result, binop(Iop_Or64, binop(Iop_And64, binop(Iop_Shl64, mkexpr(op),
florian417b22d2012-07-13 13:41:41 +00006897 unop(Iop_64to8, mkexpr(shift_amount))), mkU64(~sign_mask)),
6898 binop(Iop_And64, mkexpr(op), mkU64(sign_mask))));
sewardj2019a972011-03-07 16:04:07 +00006899 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6900 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6901 s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_64, op, shift_amount);
6902
6903 return "slda";
6904}
6905
6906static HChar *
6907s390_irgen_SLDL(UChar r1, IRTemp op2addr)
6908{
6909 IRTemp p1 = newTemp(Ity_I64);
6910 IRTemp p2 = newTemp(Ity_I64);
6911 IRTemp result = newTemp(Ity_I64);
6912
6913 assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
6914 assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
6915 assign(result, binop(Iop_Shl64, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1),
6916 mkU8(32)), mkexpr(p2)), unop(Iop_64to8, binop(Iop_And64,
6917 mkexpr(op2addr), mkU64(63)))));
6918 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6919 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6920
6921 return "sldl";
6922}
6923
6924static HChar *
6925s390_irgen_SLA(UChar r1, IRTemp op2addr)
6926{
6927 IRTemp uop = newTemp(Ity_I32);
6928 IRTemp result = newTemp(Ity_I32);
6929 UInt sign_mask;
6930 IRTemp shift_amount = newTemp(Ity_I64);
6931 IRTemp op = newTemp(Ity_I32);
6932
6933 assign(op, get_gpr_w1(r1));
6934 assign(uop, get_gpr_w1(r1));
6935 sign_mask = 2147483648U;
6936 assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
6937 assign(result, binop(Iop_Or32, binop(Iop_And32, binop(Iop_Shl32, mkexpr(uop),
6938 unop(Iop_64to8, mkexpr(shift_amount))), mkU32(~sign_mask)),
6939 binop(Iop_And32, mkexpr(uop), mkU32(sign_mask))));
6940 put_gpr_w1(r1, mkexpr(result));
6941 s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_32, op, shift_amount);
6942
6943 return "sla";
6944}
6945
6946static HChar *
6947s390_irgen_SLAK(UChar r1, UChar r3, IRTemp op2addr)
6948{
6949 IRTemp uop = newTemp(Ity_I32);
6950 IRTemp result = newTemp(Ity_I32);
6951 UInt sign_mask;
6952 IRTemp shift_amount = newTemp(Ity_I64);
6953 IRTemp op = newTemp(Ity_I32);
6954
6955 assign(op, get_gpr_w1(r3));
6956 assign(uop, get_gpr_w1(r3));
6957 sign_mask = 2147483648U;
6958 assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
6959 assign(result, binop(Iop_Or32, binop(Iop_And32, binop(Iop_Shl32, mkexpr(uop),
6960 unop(Iop_64to8, mkexpr(shift_amount))), mkU32(~sign_mask)),
6961 binop(Iop_And32, mkexpr(uop), mkU32(sign_mask))));
6962 put_gpr_w1(r1, mkexpr(result));
6963 s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_32, op, shift_amount);
6964
6965 return "slak";
6966}
6967
6968static HChar *
6969s390_irgen_SLAG(UChar r1, UChar r3, IRTemp op2addr)
6970{
6971 IRTemp uop = newTemp(Ity_I64);
6972 IRTemp result = newTemp(Ity_I64);
6973 ULong sign_mask;
6974 IRTemp shift_amount = newTemp(Ity_I64);
6975 IRTemp op = newTemp(Ity_I64);
6976
6977 assign(op, get_gpr_dw0(r3));
6978 assign(uop, get_gpr_dw0(r3));
6979 sign_mask = 9223372036854775808ULL;
6980 assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
6981 assign(result, binop(Iop_Or64, binop(Iop_And64, binop(Iop_Shl64, mkexpr(uop),
6982 unop(Iop_64to8, mkexpr(shift_amount))), mkU64(~sign_mask)),
6983 binop(Iop_And64, mkexpr(uop), mkU64(sign_mask))));
6984 put_gpr_dw0(r1, mkexpr(result));
6985 s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_64, op, shift_amount);
6986
6987 return "slag";
6988}
6989
6990static HChar *
6991s390_irgen_SLL(UChar r1, IRTemp op2addr)
6992{
6993 put_gpr_w1(r1, binop(Iop_Shl32, get_gpr_w1(r1), unop(Iop_64to8,
6994 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
6995
6996 return "sll";
6997}
6998
6999static HChar *
7000s390_irgen_SLLK(UChar r1, UChar r3, IRTemp op2addr)
7001{
7002 put_gpr_w1(r1, binop(Iop_Shl32, get_gpr_w1(r3), unop(Iop_64to8,
7003 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
7004
7005 return "sllk";
7006}
7007
7008static HChar *
7009s390_irgen_SLLG(UChar r1, UChar r3, IRTemp op2addr)
7010{
7011 put_gpr_dw0(r1, binop(Iop_Shl64, get_gpr_dw0(r3), unop(Iop_64to8,
7012 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
7013
7014 return "sllg";
7015}
7016
7017static HChar *
7018s390_irgen_SRDA(UChar r1, IRTemp op2addr)
7019{
7020 IRTemp p1 = newTemp(Ity_I64);
7021 IRTemp p2 = newTemp(Ity_I64);
7022 IRTemp result = newTemp(Ity_I64);
7023
7024 assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
7025 assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
7026 assign(result, binop(Iop_Sar64, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1),
7027 mkU8(32)), mkexpr(p2)), unop(Iop_64to8, binop(Iop_And64,
7028 mkexpr(op2addr), mkU64(63)))));
7029 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
7030 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
7031 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7032
7033 return "srda";
7034}
7035
7036static HChar *
7037s390_irgen_SRDL(UChar r1, IRTemp op2addr)
7038{
7039 IRTemp p1 = newTemp(Ity_I64);
7040 IRTemp p2 = newTemp(Ity_I64);
7041 IRTemp result = newTemp(Ity_I64);
7042
7043 assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
7044 assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
7045 assign(result, binop(Iop_Shr64, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1),
7046 mkU8(32)), mkexpr(p2)), unop(Iop_64to8, binop(Iop_And64,
7047 mkexpr(op2addr), mkU64(63)))));
7048 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
7049 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
7050
7051 return "srdl";
7052}
7053
7054static HChar *
7055s390_irgen_SRA(UChar r1, IRTemp op2addr)
7056{
7057 IRTemp result = newTemp(Ity_I32);
7058 IRTemp op = newTemp(Ity_I32);
7059
7060 assign(op, get_gpr_w1(r1));
7061 assign(result, binop(Iop_Sar32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7062 mkexpr(op2addr), mkU64(63)))));
7063 put_gpr_w1(r1, mkexpr(result));
7064 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7065
7066 return "sra";
7067}
7068
7069static HChar *
7070s390_irgen_SRAK(UChar r1, UChar r3, IRTemp op2addr)
7071{
7072 IRTemp result = newTemp(Ity_I32);
7073 IRTemp op = newTemp(Ity_I32);
7074
7075 assign(op, get_gpr_w1(r3));
7076 assign(result, binop(Iop_Sar32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7077 mkexpr(op2addr), mkU64(63)))));
7078 put_gpr_w1(r1, mkexpr(result));
7079 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7080
7081 return "srak";
7082}
7083
7084static HChar *
7085s390_irgen_SRAG(UChar r1, UChar r3, IRTemp op2addr)
7086{
7087 IRTemp result = newTemp(Ity_I64);
7088 IRTemp op = newTemp(Ity_I64);
7089
7090 assign(op, get_gpr_dw0(r3));
7091 assign(result, binop(Iop_Sar64, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7092 mkexpr(op2addr), mkU64(63)))));
7093 put_gpr_dw0(r1, mkexpr(result));
7094 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7095
7096 return "srag";
7097}
7098
7099static HChar *
7100s390_irgen_SRL(UChar r1, IRTemp op2addr)
7101{
7102 IRTemp op = newTemp(Ity_I32);
7103
7104 assign(op, get_gpr_w1(r1));
7105 put_gpr_w1(r1, binop(Iop_Shr32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7106 mkexpr(op2addr), mkU64(63)))));
7107
7108 return "srl";
7109}
7110
7111static HChar *
7112s390_irgen_SRLK(UChar r1, UChar r3, IRTemp op2addr)
7113{
7114 IRTemp op = newTemp(Ity_I32);
7115
7116 assign(op, get_gpr_w1(r3));
7117 put_gpr_w1(r1, binop(Iop_Shr32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7118 mkexpr(op2addr), mkU64(63)))));
7119
7120 return "srlk";
7121}
7122
7123static HChar *
7124s390_irgen_SRLG(UChar r1, UChar r3, IRTemp op2addr)
7125{
7126 IRTemp op = newTemp(Ity_I64);
7127
7128 assign(op, get_gpr_dw0(r3));
7129 put_gpr_dw0(r1, binop(Iop_Shr64, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7130 mkexpr(op2addr), mkU64(63)))));
7131
7132 return "srlg";
7133}
7134
7135static HChar *
7136s390_irgen_ST(UChar r1, IRTemp op2addr)
7137{
7138 store(mkexpr(op2addr), get_gpr_w1(r1));
7139
7140 return "st";
7141}
7142
7143static HChar *
7144s390_irgen_STY(UChar r1, IRTemp op2addr)
7145{
7146 store(mkexpr(op2addr), get_gpr_w1(r1));
7147
7148 return "sty";
7149}
7150
7151static HChar *
7152s390_irgen_STG(UChar r1, IRTemp op2addr)
7153{
7154 store(mkexpr(op2addr), get_gpr_dw0(r1));
7155
7156 return "stg";
7157}
7158
7159static HChar *
7160s390_irgen_STRL(UChar r1, UInt i2)
7161{
7162 store(mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)),
7163 get_gpr_w1(r1));
7164
7165 return "strl";
7166}
7167
7168static HChar *
7169s390_irgen_STGRL(UChar r1, UInt i2)
7170{
7171 store(mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)),
7172 get_gpr_dw0(r1));
7173
7174 return "stgrl";
7175}
7176
7177static HChar *
7178s390_irgen_STC(UChar r1, IRTemp op2addr)
7179{
7180 store(mkexpr(op2addr), get_gpr_b7(r1));
7181
7182 return "stc";
7183}
7184
7185static HChar *
7186s390_irgen_STCY(UChar r1, IRTemp op2addr)
7187{
7188 store(mkexpr(op2addr), get_gpr_b7(r1));
7189
7190 return "stcy";
7191}
7192
7193static HChar *
7194s390_irgen_STCH(UChar r1, IRTemp op2addr)
7195{
7196 store(mkexpr(op2addr), get_gpr_b3(r1));
7197
7198 return "stch";
7199}
7200
7201static HChar *
7202s390_irgen_STCM(UChar r1, UChar r3, IRTemp op2addr)
7203{
7204 UChar mask;
7205 UChar n;
7206
7207 mask = (UChar)r3;
7208 n = 0;
7209 if ((mask & 8) != 0) {
7210 store(mkexpr(op2addr), get_gpr_b4(r1));
7211 n = n + 1;
7212 }
7213 if ((mask & 4) != 0) {
7214 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b5(r1));
7215 n = n + 1;
7216 }
7217 if ((mask & 2) != 0) {
7218 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b6(r1));
7219 n = n + 1;
7220 }
7221 if ((mask & 1) != 0) {
7222 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b7(r1));
7223 }
7224
7225 return "stcm";
7226}
7227
7228static HChar *
7229s390_irgen_STCMY(UChar r1, UChar r3, IRTemp op2addr)
7230{
7231 UChar mask;
7232 UChar n;
7233
7234 mask = (UChar)r3;
7235 n = 0;
7236 if ((mask & 8) != 0) {
7237 store(mkexpr(op2addr), get_gpr_b4(r1));
7238 n = n + 1;
7239 }
7240 if ((mask & 4) != 0) {
7241 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b5(r1));
7242 n = n + 1;
7243 }
7244 if ((mask & 2) != 0) {
7245 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b6(r1));
7246 n = n + 1;
7247 }
7248 if ((mask & 1) != 0) {
7249 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b7(r1));
7250 }
7251
7252 return "stcmy";
7253}
7254
7255static HChar *
7256s390_irgen_STCMH(UChar r1, UChar r3, IRTemp op2addr)
7257{
7258 UChar mask;
7259 UChar n;
7260
7261 mask = (UChar)r3;
7262 n = 0;
7263 if ((mask & 8) != 0) {
7264 store(mkexpr(op2addr), get_gpr_b0(r1));
7265 n = n + 1;
7266 }
7267 if ((mask & 4) != 0) {
7268 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b1(r1));
7269 n = n + 1;
7270 }
7271 if ((mask & 2) != 0) {
7272 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b2(r1));
7273 n = n + 1;
7274 }
7275 if ((mask & 1) != 0) {
7276 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b3(r1));
7277 }
7278
7279 return "stcmh";
7280}
7281
7282static HChar *
7283s390_irgen_STH(UChar r1, IRTemp op2addr)
7284{
7285 store(mkexpr(op2addr), get_gpr_hw3(r1));
7286
7287 return "sth";
7288}
7289
7290static HChar *
7291s390_irgen_STHY(UChar r1, IRTemp op2addr)
7292{
7293 store(mkexpr(op2addr), get_gpr_hw3(r1));
7294
7295 return "sthy";
7296}
7297
7298static HChar *
7299s390_irgen_STHRL(UChar r1, UInt i2)
7300{
7301 store(mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)),
7302 get_gpr_hw3(r1));
7303
7304 return "sthrl";
7305}
7306
7307static HChar *
7308s390_irgen_STHH(UChar r1, IRTemp op2addr)
7309{
7310 store(mkexpr(op2addr), get_gpr_hw1(r1));
7311
7312 return "sthh";
7313}
7314
7315static HChar *
7316s390_irgen_STFH(UChar r1, IRTemp op2addr)
7317{
7318 store(mkexpr(op2addr), get_gpr_w0(r1));
7319
7320 return "stfh";
7321}
7322
7323static HChar *
sewardjd7bde722011-04-05 13:19:33 +00007324s390_irgen_STOC(UChar r1, IRTemp op2addr)
7325{
7326 /* condition is checked in format handler */
7327 store(mkexpr(op2addr), get_gpr_w1(r1));
7328
7329 return "stoc";
7330}
7331
7332static HChar *
7333s390_irgen_STOCG(UChar r1, IRTemp op2addr)
7334{
7335 /* condition is checked in format handler */
7336 store(mkexpr(op2addr), get_gpr_dw0(r1));
7337
7338 return "stocg";
7339}
7340
7341static HChar *
sewardj2019a972011-03-07 16:04:07 +00007342s390_irgen_STPQ(UChar r1, IRTemp op2addr)
7343{
7344 store(mkexpr(op2addr), get_gpr_dw0(r1));
7345 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(8)), get_gpr_dw0(r1 + 1));
7346
7347 return "stpq";
7348}
7349
7350static HChar *
7351s390_irgen_STRVH(UChar r1, IRTemp op2addr)
7352{
7353 store(mkexpr(op2addr), get_gpr_b7(r1));
7354 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(1)), get_gpr_b6(r1));
7355
7356 return "strvh";
7357}
7358
7359static HChar *
7360s390_irgen_STRV(UChar r1, IRTemp op2addr)
7361{
7362 store(mkexpr(op2addr), get_gpr_b7(r1));
7363 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(1)), get_gpr_b6(r1));
7364 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(2)), get_gpr_b5(r1));
7365 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(3)), get_gpr_b4(r1));
7366
7367 return "strv";
7368}
7369
7370static HChar *
7371s390_irgen_STRVG(UChar r1, IRTemp op2addr)
7372{
7373 store(mkexpr(op2addr), get_gpr_b7(r1));
7374 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(1)), get_gpr_b6(r1));
7375 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(2)), get_gpr_b5(r1));
7376 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(3)), get_gpr_b4(r1));
7377 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(4)), get_gpr_b3(r1));
7378 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(5)), get_gpr_b2(r1));
7379 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(6)), get_gpr_b1(r1));
7380 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(7)), get_gpr_b0(r1));
7381
7382 return "strvg";
7383}
7384
7385static HChar *
7386s390_irgen_SR(UChar r1, UChar r2)
7387{
7388 IRTemp op1 = newTemp(Ity_I32);
7389 IRTemp op2 = newTemp(Ity_I32);
7390 IRTemp result = newTemp(Ity_I32);
7391
7392 assign(op1, get_gpr_w1(r1));
7393 assign(op2, get_gpr_w1(r2));
7394 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7395 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
7396 put_gpr_w1(r1, mkexpr(result));
7397
7398 return "sr";
7399}
7400
7401static HChar *
7402s390_irgen_SGR(UChar r1, UChar r2)
7403{
7404 IRTemp op1 = newTemp(Ity_I64);
7405 IRTemp op2 = newTemp(Ity_I64);
7406 IRTemp result = newTemp(Ity_I64);
7407
7408 assign(op1, get_gpr_dw0(r1));
7409 assign(op2, get_gpr_dw0(r2));
7410 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7411 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
7412 put_gpr_dw0(r1, mkexpr(result));
7413
7414 return "sgr";
7415}
7416
7417static HChar *
7418s390_irgen_SGFR(UChar r1, UChar r2)
7419{
7420 IRTemp op1 = newTemp(Ity_I64);
7421 IRTemp op2 = newTemp(Ity_I64);
7422 IRTemp result = newTemp(Ity_I64);
7423
7424 assign(op1, get_gpr_dw0(r1));
7425 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
7426 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7427 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
7428 put_gpr_dw0(r1, mkexpr(result));
7429
7430 return "sgfr";
7431}
7432
7433static HChar *
7434s390_irgen_SRK(UChar r3, UChar r1, UChar r2)
7435{
7436 IRTemp op2 = newTemp(Ity_I32);
7437 IRTemp op3 = newTemp(Ity_I32);
7438 IRTemp result = newTemp(Ity_I32);
7439
7440 assign(op2, get_gpr_w1(r2));
7441 assign(op3, get_gpr_w1(r3));
7442 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
7443 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op2, op3);
7444 put_gpr_w1(r1, mkexpr(result));
7445
7446 return "srk";
7447}
7448
7449static HChar *
7450s390_irgen_SGRK(UChar r3, UChar r1, UChar r2)
7451{
7452 IRTemp op2 = newTemp(Ity_I64);
7453 IRTemp op3 = newTemp(Ity_I64);
7454 IRTemp result = newTemp(Ity_I64);
7455
7456 assign(op2, get_gpr_dw0(r2));
7457 assign(op3, get_gpr_dw0(r3));
7458 assign(result, binop(Iop_Sub64, mkexpr(op2), mkexpr(op3)));
7459 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op2, op3);
7460 put_gpr_dw0(r1, mkexpr(result));
7461
7462 return "sgrk";
7463}
7464
7465static HChar *
7466s390_irgen_S(UChar r1, IRTemp op2addr)
7467{
7468 IRTemp op1 = newTemp(Ity_I32);
7469 IRTemp op2 = newTemp(Ity_I32);
7470 IRTemp result = newTemp(Ity_I32);
7471
7472 assign(op1, get_gpr_w1(r1));
7473 assign(op2, load(Ity_I32, mkexpr(op2addr)));
7474 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7475 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
7476 put_gpr_w1(r1, mkexpr(result));
7477
7478 return "s";
7479}
7480
7481static HChar *
7482s390_irgen_SY(UChar r1, IRTemp op2addr)
7483{
7484 IRTemp op1 = newTemp(Ity_I32);
7485 IRTemp op2 = newTemp(Ity_I32);
7486 IRTemp result = newTemp(Ity_I32);
7487
7488 assign(op1, get_gpr_w1(r1));
7489 assign(op2, load(Ity_I32, mkexpr(op2addr)));
7490 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7491 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
7492 put_gpr_w1(r1, mkexpr(result));
7493
7494 return "sy";
7495}
7496
7497static HChar *
7498s390_irgen_SG(UChar r1, IRTemp op2addr)
7499{
7500 IRTemp op1 = newTemp(Ity_I64);
7501 IRTemp op2 = newTemp(Ity_I64);
7502 IRTemp result = newTemp(Ity_I64);
7503
7504 assign(op1, get_gpr_dw0(r1));
7505 assign(op2, load(Ity_I64, mkexpr(op2addr)));
7506 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7507 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
7508 put_gpr_dw0(r1, mkexpr(result));
7509
7510 return "sg";
7511}
7512
7513static HChar *
7514s390_irgen_SGF(UChar r1, IRTemp op2addr)
7515{
7516 IRTemp op1 = newTemp(Ity_I64);
7517 IRTemp op2 = newTemp(Ity_I64);
7518 IRTemp result = newTemp(Ity_I64);
7519
7520 assign(op1, get_gpr_dw0(r1));
7521 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
7522 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7523 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
7524 put_gpr_dw0(r1, mkexpr(result));
7525
7526 return "sgf";
7527}
7528
7529static HChar *
7530s390_irgen_SH(UChar r1, IRTemp op2addr)
7531{
7532 IRTemp op1 = newTemp(Ity_I32);
7533 IRTemp op2 = newTemp(Ity_I32);
7534 IRTemp result = newTemp(Ity_I32);
7535
7536 assign(op1, get_gpr_w1(r1));
7537 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
7538 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7539 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
7540 put_gpr_w1(r1, mkexpr(result));
7541
7542 return "sh";
7543}
7544
7545static HChar *
7546s390_irgen_SHY(UChar r1, IRTemp op2addr)
7547{
7548 IRTemp op1 = newTemp(Ity_I32);
7549 IRTemp op2 = newTemp(Ity_I32);
7550 IRTemp result = newTemp(Ity_I32);
7551
7552 assign(op1, get_gpr_w1(r1));
7553 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
7554 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7555 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
7556 put_gpr_w1(r1, mkexpr(result));
7557
7558 return "shy";
7559}
7560
7561static HChar *
7562s390_irgen_SHHHR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
7563{
7564 IRTemp op2 = newTemp(Ity_I32);
7565 IRTemp op3 = newTemp(Ity_I32);
7566 IRTemp result = newTemp(Ity_I32);
7567
7568 assign(op2, get_gpr_w0(r1));
7569 assign(op3, get_gpr_w0(r2));
7570 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
7571 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op2, op3);
7572 put_gpr_w0(r1, mkexpr(result));
7573
7574 return "shhhr";
7575}
7576
7577static HChar *
7578s390_irgen_SHHLR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
7579{
7580 IRTemp op2 = newTemp(Ity_I32);
7581 IRTemp op3 = newTemp(Ity_I32);
7582 IRTemp result = newTemp(Ity_I32);
7583
7584 assign(op2, get_gpr_w0(r1));
7585 assign(op3, get_gpr_w1(r2));
7586 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
7587 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op2, op3);
7588 put_gpr_w0(r1, mkexpr(result));
7589
7590 return "shhlr";
7591}
7592
7593static HChar *
7594s390_irgen_SLR(UChar r1, UChar r2)
7595{
7596 IRTemp op1 = newTemp(Ity_I32);
7597 IRTemp op2 = newTemp(Ity_I32);
7598 IRTemp result = newTemp(Ity_I32);
7599
7600 assign(op1, get_gpr_w1(r1));
7601 assign(op2, get_gpr_w1(r2));
7602 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7603 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, op2);
7604 put_gpr_w1(r1, mkexpr(result));
7605
7606 return "slr";
7607}
7608
7609static HChar *
7610s390_irgen_SLGR(UChar r1, UChar r2)
7611{
7612 IRTemp op1 = newTemp(Ity_I64);
7613 IRTemp op2 = newTemp(Ity_I64);
7614 IRTemp result = newTemp(Ity_I64);
7615
7616 assign(op1, get_gpr_dw0(r1));
7617 assign(op2, get_gpr_dw0(r2));
7618 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7619 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
7620 put_gpr_dw0(r1, mkexpr(result));
7621
7622 return "slgr";
7623}
7624
7625static HChar *
7626s390_irgen_SLGFR(UChar r1, UChar r2)
7627{
7628 IRTemp op1 = newTemp(Ity_I64);
7629 IRTemp op2 = newTemp(Ity_I64);
7630 IRTemp result = newTemp(Ity_I64);
7631
7632 assign(op1, get_gpr_dw0(r1));
7633 assign(op2, unop(Iop_32Uto64, get_gpr_w1(r2)));
7634 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7635 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
7636 put_gpr_dw0(r1, mkexpr(result));
7637
7638 return "slgfr";
7639}
7640
7641static HChar *
7642s390_irgen_SLRK(UChar r3, UChar r1, UChar r2)
7643{
7644 IRTemp op2 = newTemp(Ity_I32);
7645 IRTemp op3 = newTemp(Ity_I32);
7646 IRTemp result = newTemp(Ity_I32);
7647
7648 assign(op2, get_gpr_w1(r2));
7649 assign(op3, get_gpr_w1(r3));
7650 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
7651 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op2, op3);
7652 put_gpr_w1(r1, mkexpr(result));
7653
7654 return "slrk";
7655}
7656
7657static HChar *
7658s390_irgen_SLGRK(UChar r3, UChar r1, UChar r2)
7659{
7660 IRTemp op2 = newTemp(Ity_I64);
7661 IRTemp op3 = newTemp(Ity_I64);
7662 IRTemp result = newTemp(Ity_I64);
7663
7664 assign(op2, get_gpr_dw0(r2));
7665 assign(op3, get_gpr_dw0(r3));
7666 assign(result, binop(Iop_Sub64, mkexpr(op2), mkexpr(op3)));
7667 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op2, op3);
7668 put_gpr_dw0(r1, mkexpr(result));
7669
7670 return "slgrk";
7671}
7672
7673static HChar *
7674s390_irgen_SL(UChar r1, IRTemp op2addr)
7675{
7676 IRTemp op1 = newTemp(Ity_I32);
7677 IRTemp op2 = newTemp(Ity_I32);
7678 IRTemp result = newTemp(Ity_I32);
7679
7680 assign(op1, get_gpr_w1(r1));
7681 assign(op2, load(Ity_I32, mkexpr(op2addr)));
7682 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7683 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, op2);
7684 put_gpr_w1(r1, mkexpr(result));
7685
7686 return "sl";
7687}
7688
7689static HChar *
7690s390_irgen_SLY(UChar r1, IRTemp op2addr)
7691{
7692 IRTemp op1 = newTemp(Ity_I32);
7693 IRTemp op2 = newTemp(Ity_I32);
7694 IRTemp result = newTemp(Ity_I32);
7695
7696 assign(op1, get_gpr_w1(r1));
7697 assign(op2, load(Ity_I32, mkexpr(op2addr)));
7698 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7699 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, op2);
7700 put_gpr_w1(r1, mkexpr(result));
7701
7702 return "sly";
7703}
7704
7705static HChar *
7706s390_irgen_SLG(UChar r1, IRTemp op2addr)
7707{
7708 IRTemp op1 = newTemp(Ity_I64);
7709 IRTemp op2 = newTemp(Ity_I64);
7710 IRTemp result = newTemp(Ity_I64);
7711
7712 assign(op1, get_gpr_dw0(r1));
7713 assign(op2, load(Ity_I64, mkexpr(op2addr)));
7714 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7715 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
7716 put_gpr_dw0(r1, mkexpr(result));
7717
7718 return "slg";
7719}
7720
7721static HChar *
7722s390_irgen_SLGF(UChar r1, IRTemp op2addr)
7723{
7724 IRTemp op1 = newTemp(Ity_I64);
7725 IRTemp op2 = newTemp(Ity_I64);
7726 IRTemp result = newTemp(Ity_I64);
7727
7728 assign(op1, get_gpr_dw0(r1));
7729 assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
7730 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7731 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
7732 put_gpr_dw0(r1, mkexpr(result));
7733
7734 return "slgf";
7735}
7736
7737static HChar *
7738s390_irgen_SLFI(UChar r1, UInt i2)
7739{
7740 IRTemp op1 = newTemp(Ity_I32);
7741 UInt op2;
7742 IRTemp result = newTemp(Ity_I32);
7743
7744 assign(op1, get_gpr_w1(r1));
7745 op2 = i2;
7746 assign(result, binop(Iop_Sub32, mkexpr(op1), mkU32(op2)));
7747 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, mktemp(Ity_I32,
7748 mkU32(op2)));
7749 put_gpr_w1(r1, mkexpr(result));
7750
7751 return "slfi";
7752}
7753
7754static HChar *
7755s390_irgen_SLGFI(UChar r1, UInt i2)
7756{
7757 IRTemp op1 = newTemp(Ity_I64);
7758 ULong op2;
7759 IRTemp result = newTemp(Ity_I64);
7760
7761 assign(op1, get_gpr_dw0(r1));
7762 op2 = (ULong)i2;
7763 assign(result, binop(Iop_Sub64, mkexpr(op1), mkU64(op2)));
7764 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, mktemp(Ity_I64,
7765 mkU64(op2)));
7766 put_gpr_dw0(r1, mkexpr(result));
7767
7768 return "slgfi";
7769}
7770
7771static HChar *
7772s390_irgen_SLHHHR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
7773{
7774 IRTemp op2 = newTemp(Ity_I32);
7775 IRTemp op3 = newTemp(Ity_I32);
7776 IRTemp result = newTemp(Ity_I32);
7777
7778 assign(op2, get_gpr_w0(r1));
7779 assign(op3, get_gpr_w0(r2));
7780 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
7781 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op2, op3);
7782 put_gpr_w0(r1, mkexpr(result));
7783
7784 return "slhhhr";
7785}
7786
7787static HChar *
7788s390_irgen_SLHHLR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
7789{
7790 IRTemp op2 = newTemp(Ity_I32);
7791 IRTemp op3 = newTemp(Ity_I32);
7792 IRTemp result = newTemp(Ity_I32);
7793
7794 assign(op2, get_gpr_w0(r1));
7795 assign(op3, get_gpr_w1(r2));
7796 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
7797 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op2, op3);
7798 put_gpr_w0(r1, mkexpr(result));
7799
7800 return "slhhlr";
7801}
7802
7803static HChar *
7804s390_irgen_SLBR(UChar r1, UChar r2)
7805{
7806 IRTemp op1 = newTemp(Ity_I32);
7807 IRTemp op2 = newTemp(Ity_I32);
7808 IRTemp result = newTemp(Ity_I32);
7809 IRTemp borrow_in = newTemp(Ity_I32);
7810
7811 assign(op1, get_gpr_w1(r1));
7812 assign(op2, get_gpr_w1(r2));
7813 assign(borrow_in, binop(Iop_Sub32, mkU32(1), binop(Iop_Shr32,
7814 s390_call_calculate_cc(), mkU8(1))));
7815 assign(result, binop(Iop_Sub32, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)),
7816 mkexpr(borrow_in)));
7817 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_32, op1, op2, borrow_in);
7818 put_gpr_w1(r1, mkexpr(result));
7819
7820 return "slbr";
7821}
7822
7823static HChar *
7824s390_irgen_SLBGR(UChar r1, UChar r2)
7825{
7826 IRTemp op1 = newTemp(Ity_I64);
7827 IRTemp op2 = newTemp(Ity_I64);
7828 IRTemp result = newTemp(Ity_I64);
7829 IRTemp borrow_in = newTemp(Ity_I64);
7830
7831 assign(op1, get_gpr_dw0(r1));
7832 assign(op2, get_gpr_dw0(r2));
7833 assign(borrow_in, unop(Iop_32Uto64, binop(Iop_Sub32, mkU32(1),
7834 binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)))));
7835 assign(result, binop(Iop_Sub64, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)),
7836 mkexpr(borrow_in)));
7837 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_64, op1, op2, borrow_in);
7838 put_gpr_dw0(r1, mkexpr(result));
7839
7840 return "slbgr";
7841}
7842
7843static HChar *
7844s390_irgen_SLB(UChar r1, IRTemp op2addr)
7845{
7846 IRTemp op1 = newTemp(Ity_I32);
7847 IRTemp op2 = newTemp(Ity_I32);
7848 IRTemp result = newTemp(Ity_I32);
7849 IRTemp borrow_in = newTemp(Ity_I32);
7850
7851 assign(op1, get_gpr_w1(r1));
7852 assign(op2, load(Ity_I32, mkexpr(op2addr)));
7853 assign(borrow_in, binop(Iop_Sub32, mkU32(1), binop(Iop_Shr32,
7854 s390_call_calculate_cc(), mkU8(1))));
7855 assign(result, binop(Iop_Sub32, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)),
7856 mkexpr(borrow_in)));
7857 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_32, op1, op2, borrow_in);
7858 put_gpr_w1(r1, mkexpr(result));
7859
7860 return "slb";
7861}
7862
7863static HChar *
7864s390_irgen_SLBG(UChar r1, IRTemp op2addr)
7865{
7866 IRTemp op1 = newTemp(Ity_I64);
7867 IRTemp op2 = newTemp(Ity_I64);
7868 IRTemp result = newTemp(Ity_I64);
7869 IRTemp borrow_in = newTemp(Ity_I64);
7870
7871 assign(op1, get_gpr_dw0(r1));
7872 assign(op2, load(Ity_I64, mkexpr(op2addr)));
7873 assign(borrow_in, unop(Iop_32Uto64, binop(Iop_Sub32, mkU32(1),
7874 binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)))));
7875 assign(result, binop(Iop_Sub64, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)),
7876 mkexpr(borrow_in)));
7877 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_64, op1, op2, borrow_in);
7878 put_gpr_dw0(r1, mkexpr(result));
7879
7880 return "slbg";
7881}
7882
7883static HChar *
7884s390_irgen_SVC(UChar i)
7885{
7886 IRTemp sysno = newTemp(Ity_I64);
7887
7888 if (i != 0) {
7889 assign(sysno, mkU64(i));
7890 } else {
7891 assign(sysno, unop(Iop_32Uto64, get_gpr_w1(1)));
7892 }
7893 system_call(mkexpr(sysno));
7894
7895 return "svc";
7896}
7897
7898static HChar *
sewardj2019a972011-03-07 16:04:07 +00007899s390_irgen_TM(UChar i2, IRTemp op1addr)
7900{
7901 UChar mask;
7902 IRTemp value = newTemp(Ity_I8);
7903
7904 mask = i2;
7905 assign(value, load(Ity_I8, mkexpr(op1addr)));
7906 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_8, value, mktemp(Ity_I8,
7907 mkU8(mask)));
7908
7909 return "tm";
7910}
7911
7912static HChar *
7913s390_irgen_TMY(UChar i2, IRTemp op1addr)
7914{
7915 UChar mask;
7916 IRTemp value = newTemp(Ity_I8);
7917
7918 mask = i2;
7919 assign(value, load(Ity_I8, mkexpr(op1addr)));
7920 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_8, value, mktemp(Ity_I8,
7921 mkU8(mask)));
7922
7923 return "tmy";
7924}
7925
7926static HChar *
7927s390_irgen_TMHH(UChar r1, UShort i2)
7928{
7929 UShort mask;
7930 IRTemp value = newTemp(Ity_I16);
7931
7932 mask = i2;
7933 assign(value, get_gpr_hw0(r1));
7934 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
7935 mkU16(mask)));
7936
7937 return "tmhh";
7938}
7939
7940static HChar *
7941s390_irgen_TMHL(UChar r1, UShort i2)
7942{
7943 UShort mask;
7944 IRTemp value = newTemp(Ity_I16);
7945
7946 mask = i2;
7947 assign(value, get_gpr_hw1(r1));
7948 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
7949 mkU16(mask)));
7950
7951 return "tmhl";
7952}
7953
7954static HChar *
7955s390_irgen_TMLH(UChar r1, UShort i2)
7956{
7957 UShort mask;
7958 IRTemp value = newTemp(Ity_I16);
7959
7960 mask = i2;
7961 assign(value, get_gpr_hw2(r1));
7962 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
7963 mkU16(mask)));
7964
7965 return "tmlh";
7966}
7967
7968static HChar *
7969s390_irgen_TMLL(UChar r1, UShort i2)
7970{
7971 UShort mask;
7972 IRTemp value = newTemp(Ity_I16);
7973
7974 mask = i2;
7975 assign(value, get_gpr_hw3(r1));
7976 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
7977 mkU16(mask)));
7978
7979 return "tmll";
7980}
7981
7982static HChar *
7983s390_irgen_EFPC(UChar r1)
7984{
7985 put_gpr_w1(r1, get_fpc_w0());
7986
7987 return "efpc";
7988}
7989
7990static HChar *
7991s390_irgen_LER(UChar r1, UChar r2)
7992{
7993 put_fpr_w0(r1, get_fpr_w0(r2));
7994
7995 return "ler";
7996}
7997
7998static HChar *
7999s390_irgen_LDR(UChar r1, UChar r2)
8000{
8001 put_fpr_dw0(r1, get_fpr_dw0(r2));
8002
8003 return "ldr";
8004}
8005
8006static HChar *
8007s390_irgen_LXR(UChar r1, UChar r2)
8008{
8009 put_fpr_dw0(r1, get_fpr_dw0(r2));
8010 put_fpr_dw0(r1 + 2, get_fpr_dw0(r2 + 2));
8011
8012 return "lxr";
8013}
8014
8015static HChar *
8016s390_irgen_LE(UChar r1, IRTemp op2addr)
8017{
8018 put_fpr_w0(r1, load(Ity_F32, mkexpr(op2addr)));
8019
8020 return "le";
8021}
8022
8023static HChar *
8024s390_irgen_LD(UChar r1, IRTemp op2addr)
8025{
8026 put_fpr_dw0(r1, load(Ity_F64, mkexpr(op2addr)));
8027
8028 return "ld";
8029}
8030
8031static HChar *
8032s390_irgen_LEY(UChar r1, IRTemp op2addr)
8033{
8034 put_fpr_w0(r1, load(Ity_F32, mkexpr(op2addr)));
8035
8036 return "ley";
8037}
8038
8039static HChar *
8040s390_irgen_LDY(UChar r1, IRTemp op2addr)
8041{
8042 put_fpr_dw0(r1, load(Ity_F64, mkexpr(op2addr)));
8043
8044 return "ldy";
8045}
8046
8047static HChar *
8048s390_irgen_LFPC(IRTemp op2addr)
8049{
8050 put_fpc_w0(load(Ity_I32, mkexpr(op2addr)));
8051
8052 return "lfpc";
8053}
8054
8055static HChar *
8056s390_irgen_LZER(UChar r1)
8057{
8058 put_fpr_w0(r1, mkF32i(0x0));
8059
8060 return "lzer";
8061}
8062
8063static HChar *
8064s390_irgen_LZDR(UChar r1)
8065{
8066 put_fpr_dw0(r1, mkF64i(0x0));
8067
8068 return "lzdr";
8069}
8070
8071static HChar *
8072s390_irgen_LZXR(UChar r1)
8073{
8074 put_fpr_dw0(r1, mkF64i(0x0));
8075 put_fpr_dw0(r1 + 2, mkF64i(0x0));
8076
8077 return "lzxr";
8078}
8079
8080static HChar *
8081s390_irgen_SRNM(IRTemp op2addr)
8082{
8083 UInt mask;
8084
8085 mask = 3;
8086 put_fpc_w0(binop(Iop_Or32, binop(Iop_And32, get_fpc_w0(), mkU32(~mask)),
8087 binop(Iop_And32, unop(Iop_64to32, mkexpr(op2addr)), mkU32(mask)))
8088 );
8089
8090 return "srnm";
8091}
8092
8093static HChar *
8094s390_irgen_SFPC(UChar r1)
8095{
8096 put_fpc_w0(get_gpr_w1(r1));
8097
8098 return "sfpc";
8099}
8100
8101static HChar *
8102s390_irgen_STE(UChar r1, IRTemp op2addr)
8103{
8104 store(mkexpr(op2addr), get_fpr_w0(r1));
8105
8106 return "ste";
8107}
8108
8109static HChar *
8110s390_irgen_STD(UChar r1, IRTemp op2addr)
8111{
8112 store(mkexpr(op2addr), get_fpr_dw0(r1));
8113
8114 return "std";
8115}
8116
8117static HChar *
8118s390_irgen_STEY(UChar r1, IRTemp op2addr)
8119{
8120 store(mkexpr(op2addr), get_fpr_w0(r1));
8121
8122 return "stey";
8123}
8124
8125static HChar *
8126s390_irgen_STDY(UChar r1, IRTemp op2addr)
8127{
8128 store(mkexpr(op2addr), get_fpr_dw0(r1));
8129
8130 return "stdy";
8131}
8132
8133static HChar *
8134s390_irgen_STFPC(IRTemp op2addr)
8135{
8136 store(mkexpr(op2addr), get_fpc_w0());
8137
8138 return "stfpc";
8139}
8140
8141static HChar *
8142s390_irgen_AEBR(UChar r1, UChar r2)
8143{
8144 IRTemp op1 = newTemp(Ity_F32);
8145 IRTemp op2 = newTemp(Ity_F32);
8146 IRTemp result = newTemp(Ity_F32);
8147
8148 assign(op1, get_fpr_w0(r1));
8149 assign(op2, get_fpr_w0(r2));
8150 assign(result, triop(Iop_AddF32, mkU32(Irrm_NEAREST), mkexpr(op1),
8151 mkexpr(op2)));
8152 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
8153 put_fpr_w0(r1, mkexpr(result));
8154
8155 return "aebr";
8156}
8157
8158static HChar *
8159s390_irgen_ADBR(UChar r1, UChar r2)
8160{
8161 IRTemp op1 = newTemp(Ity_F64);
8162 IRTemp op2 = newTemp(Ity_F64);
8163 IRTemp result = newTemp(Ity_F64);
8164
8165 assign(op1, get_fpr_dw0(r1));
8166 assign(op2, get_fpr_dw0(r2));
8167 assign(result, triop(Iop_AddF64, mkU32(Irrm_NEAREST), mkexpr(op1),
8168 mkexpr(op2)));
8169 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
8170 put_fpr_dw0(r1, mkexpr(result));
8171
8172 return "adbr";
8173}
8174
8175static HChar *
8176s390_irgen_AEB(UChar r1, IRTemp op2addr)
8177{
8178 IRTemp op1 = newTemp(Ity_F32);
8179 IRTemp op2 = newTemp(Ity_F32);
8180 IRTemp result = newTemp(Ity_F32);
8181
8182 assign(op1, get_fpr_w0(r1));
8183 assign(op2, load(Ity_F32, mkexpr(op2addr)));
8184 assign(result, triop(Iop_AddF32, mkU32(Irrm_NEAREST), mkexpr(op1),
8185 mkexpr(op2)));
8186 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
8187 put_fpr_w0(r1, mkexpr(result));
8188
8189 return "aeb";
8190}
8191
8192static HChar *
8193s390_irgen_ADB(UChar r1, IRTemp op2addr)
8194{
8195 IRTemp op1 = newTemp(Ity_F64);
8196 IRTemp op2 = newTemp(Ity_F64);
8197 IRTemp result = newTemp(Ity_F64);
8198
8199 assign(op1, get_fpr_dw0(r1));
8200 assign(op2, load(Ity_F64, mkexpr(op2addr)));
8201 assign(result, triop(Iop_AddF64, mkU32(Irrm_NEAREST), mkexpr(op1),
8202 mkexpr(op2)));
8203 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
8204 put_fpr_dw0(r1, mkexpr(result));
8205
8206 return "adb";
8207}
8208
8209static HChar *
8210s390_irgen_CEFBR(UChar r1, UChar r2)
8211{
8212 IRTemp op2 = newTemp(Ity_I32);
8213
8214 assign(op2, get_gpr_w1(r2));
8215 put_fpr_w0(r1, binop(Iop_I32StoF32, mkU32(Irrm_NEAREST), mkexpr(op2)));
8216
8217 return "cefbr";
8218}
8219
8220static HChar *
8221s390_irgen_CDFBR(UChar r1, UChar r2)
8222{
8223 IRTemp op2 = newTemp(Ity_I32);
8224
8225 assign(op2, get_gpr_w1(r2));
8226 put_fpr_dw0(r1, unop(Iop_I32StoF64, mkexpr(op2)));
8227
8228 return "cdfbr";
8229}
8230
8231static HChar *
8232s390_irgen_CEGBR(UChar r1, UChar r2)
8233{
8234 IRTemp op2 = newTemp(Ity_I64);
8235
8236 assign(op2, get_gpr_dw0(r2));
8237 put_fpr_w0(r1, binop(Iop_I64StoF32, mkU32(Irrm_NEAREST), mkexpr(op2)));
8238
8239 return "cegbr";
8240}
8241
8242static HChar *
8243s390_irgen_CDGBR(UChar r1, UChar r2)
8244{
8245 IRTemp op2 = newTemp(Ity_I64);
8246
8247 assign(op2, get_gpr_dw0(r2));
8248 put_fpr_dw0(r1, binop(Iop_I64StoF64, mkU32(Irrm_NEAREST), mkexpr(op2)));
8249
8250 return "cdgbr";
8251}
8252
8253static HChar *
8254s390_irgen_CFEBR(UChar r3, UChar r1, UChar r2)
8255{
8256 IRTemp op = newTemp(Ity_F32);
8257 IRTemp result = newTemp(Ity_I32);
8258
8259 assign(op, get_fpr_w0(r2));
8260 assign(result, binop(Iop_F32toI32S, mkU32(encode_rounding_mode(r3)),
8261 mkexpr(op)));
8262 put_gpr_w1(r1, mkexpr(result));
8263 s390_cc_thunk_putF(S390_CC_OP_BFP_32_TO_INT_32, op);
8264
8265 return "cfebr";
8266}
8267
8268static HChar *
8269s390_irgen_CFDBR(UChar r3, UChar r1, UChar r2)
8270{
8271 IRTemp op = newTemp(Ity_F64);
8272 IRTemp result = newTemp(Ity_I32);
8273
8274 assign(op, get_fpr_dw0(r2));
8275 assign(result, binop(Iop_F64toI32S, mkU32(encode_rounding_mode(r3)),
8276 mkexpr(op)));
8277 put_gpr_w1(r1, mkexpr(result));
8278 s390_cc_thunk_putF(S390_CC_OP_BFP_64_TO_INT_32, op);
8279
8280 return "cfdbr";
8281}
8282
8283static HChar *
8284s390_irgen_CGEBR(UChar r3, UChar r1, UChar r2)
8285{
8286 IRTemp op = newTemp(Ity_F32);
8287 IRTemp result = newTemp(Ity_I64);
8288
8289 assign(op, get_fpr_w0(r2));
8290 assign(result, binop(Iop_F32toI64S, mkU32(encode_rounding_mode(r3)),
8291 mkexpr(op)));
8292 put_gpr_dw0(r1, mkexpr(result));
8293 s390_cc_thunk_putF(S390_CC_OP_BFP_32_TO_INT_64, op);
8294
8295 return "cgebr";
8296}
8297
8298static HChar *
8299s390_irgen_CGDBR(UChar r3, UChar r1, UChar r2)
8300{
8301 IRTemp op = newTemp(Ity_F64);
8302 IRTemp result = newTemp(Ity_I64);
8303
8304 assign(op, get_fpr_dw0(r2));
8305 assign(result, binop(Iop_F64toI64S, mkU32(encode_rounding_mode(r3)),
8306 mkexpr(op)));
8307 put_gpr_dw0(r1, mkexpr(result));
8308 s390_cc_thunk_putF(S390_CC_OP_BFP_64_TO_INT_64, op);
8309
8310 return "cgdbr";
8311}
8312
8313static HChar *
8314s390_irgen_DEBR(UChar r1, UChar r2)
8315{
8316 IRTemp op1 = newTemp(Ity_F32);
8317 IRTemp op2 = newTemp(Ity_F32);
8318 IRTemp result = newTemp(Ity_F32);
8319
8320 assign(op1, get_fpr_w0(r1));
8321 assign(op2, get_fpr_w0(r2));
8322 assign(result, triop(Iop_DivF32, mkU32(Irrm_NEAREST), mkexpr(op1),
8323 mkexpr(op2)));
8324 put_fpr_w0(r1, mkexpr(result));
8325
8326 return "debr";
8327}
8328
8329static HChar *
8330s390_irgen_DDBR(UChar r1, UChar r2)
8331{
8332 IRTemp op1 = newTemp(Ity_F64);
8333 IRTemp op2 = newTemp(Ity_F64);
8334 IRTemp result = newTemp(Ity_F64);
8335
8336 assign(op1, get_fpr_dw0(r1));
8337 assign(op2, get_fpr_dw0(r2));
8338 assign(result, triop(Iop_DivF64, mkU32(Irrm_NEAREST), mkexpr(op1),
8339 mkexpr(op2)));
8340 put_fpr_dw0(r1, mkexpr(result));
8341
8342 return "ddbr";
8343}
8344
8345static HChar *
8346s390_irgen_DEB(UChar r1, IRTemp op2addr)
8347{
8348 IRTemp op1 = newTemp(Ity_F32);
8349 IRTemp op2 = newTemp(Ity_F32);
8350 IRTemp result = newTemp(Ity_F32);
8351
8352 assign(op1, get_fpr_w0(r1));
8353 assign(op2, load(Ity_F32, mkexpr(op2addr)));
8354 assign(result, triop(Iop_DivF32, mkU32(Irrm_NEAREST), mkexpr(op1),
8355 mkexpr(op2)));
8356 put_fpr_w0(r1, mkexpr(result));
8357
8358 return "deb";
8359}
8360
8361static HChar *
8362s390_irgen_DDB(UChar r1, IRTemp op2addr)
8363{
8364 IRTemp op1 = newTemp(Ity_F64);
8365 IRTemp op2 = newTemp(Ity_F64);
8366 IRTemp result = newTemp(Ity_F64);
8367
8368 assign(op1, get_fpr_dw0(r1));
8369 assign(op2, load(Ity_F64, mkexpr(op2addr)));
8370 assign(result, triop(Iop_DivF64, mkU32(Irrm_NEAREST), mkexpr(op1),
8371 mkexpr(op2)));
8372 put_fpr_dw0(r1, mkexpr(result));
8373
8374 return "ddb";
8375}
8376
8377static HChar *
8378s390_irgen_LTEBR(UChar r1, UChar r2)
8379{
8380 IRTemp result = newTemp(Ity_F32);
8381
8382 assign(result, get_fpr_w0(r2));
8383 put_fpr_w0(r1, mkexpr(result));
8384 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
8385
8386 return "ltebr";
8387}
8388
8389static HChar *
8390s390_irgen_LTDBR(UChar r1, UChar r2)
8391{
8392 IRTemp result = newTemp(Ity_F64);
8393
8394 assign(result, get_fpr_dw0(r2));
8395 put_fpr_dw0(r1, mkexpr(result));
8396 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
8397
8398 return "ltdbr";
8399}
8400
8401static HChar *
8402s390_irgen_LCEBR(UChar r1, UChar r2)
8403{
8404 IRTemp result = newTemp(Ity_F32);
8405
8406 assign(result, unop(Iop_NegF32, get_fpr_w0(r2)));
8407 put_fpr_w0(r1, mkexpr(result));
8408 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
8409
8410 return "lcebr";
8411}
8412
8413static HChar *
8414s390_irgen_LCDBR(UChar r1, UChar r2)
8415{
8416 IRTemp result = newTemp(Ity_F64);
8417
8418 assign(result, unop(Iop_NegF64, get_fpr_dw0(r2)));
8419 put_fpr_dw0(r1, mkexpr(result));
8420 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
8421
8422 return "lcdbr";
8423}
8424
8425static HChar *
8426s390_irgen_LDEBR(UChar r1, UChar r2)
8427{
8428 IRTemp op = newTemp(Ity_F32);
8429
8430 assign(op, get_fpr_w0(r2));
8431 put_fpr_dw0(r1, unop(Iop_F32toF64, mkexpr(op)));
8432
8433 return "ldebr";
8434}
8435
8436static HChar *
8437s390_irgen_LDEB(UChar r1, IRTemp op2addr)
8438{
8439 IRTemp op = newTemp(Ity_F32);
8440
8441 assign(op, load(Ity_F32, mkexpr(op2addr)));
8442 put_fpr_dw0(r1, unop(Iop_F32toF64, mkexpr(op)));
8443
8444 return "ldeb";
8445}
8446
8447static HChar *
8448s390_irgen_LEDBR(UChar r1, UChar r2)
8449{
8450 IRTemp op = newTemp(Ity_F64);
8451
8452 assign(op, get_fpr_dw0(r2));
8453 put_fpr_w0(r1, binop(Iop_F64toF32, mkU32(Irrm_NEAREST), mkexpr(op)));
8454
8455 return "ledbr";
8456}
8457
8458static HChar *
8459s390_irgen_MEEBR(UChar r1, UChar r2)
8460{
8461 IRTemp op1 = newTemp(Ity_F32);
8462 IRTemp op2 = newTemp(Ity_F32);
8463 IRTemp result = newTemp(Ity_F32);
8464
8465 assign(op1, get_fpr_w0(r1));
8466 assign(op2, get_fpr_w0(r2));
8467 assign(result, triop(Iop_MulF32, mkU32(Irrm_NEAREST), mkexpr(op1),
8468 mkexpr(op2)));
8469 put_fpr_w0(r1, mkexpr(result));
8470
8471 return "meebr";
8472}
8473
8474static HChar *
8475s390_irgen_MDBR(UChar r1, UChar r2)
8476{
8477 IRTemp op1 = newTemp(Ity_F64);
8478 IRTemp op2 = newTemp(Ity_F64);
8479 IRTemp result = newTemp(Ity_F64);
8480
8481 assign(op1, get_fpr_dw0(r1));
8482 assign(op2, get_fpr_dw0(r2));
8483 assign(result, triop(Iop_MulF64, mkU32(Irrm_NEAREST), mkexpr(op1),
8484 mkexpr(op2)));
8485 put_fpr_dw0(r1, mkexpr(result));
8486
8487 return "mdbr";
8488}
8489
8490static HChar *
8491s390_irgen_MEEB(UChar r1, IRTemp op2addr)
8492{
8493 IRTemp op1 = newTemp(Ity_F32);
8494 IRTemp op2 = newTemp(Ity_F32);
8495 IRTemp result = newTemp(Ity_F32);
8496
8497 assign(op1, get_fpr_w0(r1));
8498 assign(op2, load(Ity_F32, mkexpr(op2addr)));
8499 assign(result, triop(Iop_MulF32, mkU32(Irrm_NEAREST), mkexpr(op1),
8500 mkexpr(op2)));
8501 put_fpr_w0(r1, mkexpr(result));
8502
8503 return "meeb";
8504}
8505
8506static HChar *
8507s390_irgen_MDB(UChar r1, IRTemp op2addr)
8508{
8509 IRTemp op1 = newTemp(Ity_F64);
8510 IRTemp op2 = newTemp(Ity_F64);
8511 IRTemp result = newTemp(Ity_F64);
8512
8513 assign(op1, get_fpr_dw0(r1));
8514 assign(op2, load(Ity_F64, mkexpr(op2addr)));
8515 assign(result, triop(Iop_MulF64, mkU32(Irrm_NEAREST), mkexpr(op1),
8516 mkexpr(op2)));
8517 put_fpr_dw0(r1, mkexpr(result));
8518
8519 return "mdb";
8520}
8521
8522static HChar *
8523s390_irgen_SEBR(UChar r1, UChar r2)
8524{
8525 IRTemp op1 = newTemp(Ity_F32);
8526 IRTemp op2 = newTemp(Ity_F32);
8527 IRTemp result = newTemp(Ity_F32);
8528
8529 assign(op1, get_fpr_w0(r1));
8530 assign(op2, get_fpr_w0(r2));
8531 assign(result, triop(Iop_SubF32, mkU32(Irrm_NEAREST), mkexpr(op1),
8532 mkexpr(op2)));
8533 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
8534 put_fpr_w0(r1, mkexpr(result));
8535
8536 return "sebr";
8537}
8538
8539static HChar *
8540s390_irgen_SDBR(UChar r1, UChar r2)
8541{
8542 IRTemp op1 = newTemp(Ity_F64);
8543 IRTemp op2 = newTemp(Ity_F64);
8544 IRTemp result = newTemp(Ity_F64);
8545
8546 assign(op1, get_fpr_dw0(r1));
8547 assign(op2, get_fpr_dw0(r2));
8548 assign(result, triop(Iop_SubF64, mkU32(Irrm_NEAREST), mkexpr(op1),
8549 mkexpr(op2)));
8550 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
8551 put_fpr_dw0(r1, mkexpr(result));
8552
8553 return "sdbr";
8554}
8555
8556static HChar *
8557s390_irgen_SEB(UChar r1, IRTemp op2addr)
8558{
8559 IRTemp op1 = newTemp(Ity_F32);
8560 IRTemp op2 = newTemp(Ity_F32);
8561 IRTemp result = newTemp(Ity_F32);
8562
8563 assign(op1, get_fpr_w0(r1));
8564 assign(op2, load(Ity_F32, mkexpr(op2addr)));
8565 assign(result, triop(Iop_SubF32, mkU32(Irrm_NEAREST), mkexpr(op1),
8566 mkexpr(op2)));
8567 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
8568 put_fpr_w0(r1, mkexpr(result));
8569
8570 return "seb";
8571}
8572
8573static HChar *
8574s390_irgen_SDB(UChar r1, IRTemp op2addr)
8575{
8576 IRTemp op1 = newTemp(Ity_F64);
8577 IRTemp op2 = newTemp(Ity_F64);
8578 IRTemp result = newTemp(Ity_F64);
8579
8580 assign(op1, get_fpr_dw0(r1));
8581 assign(op2, load(Ity_F64, mkexpr(op2addr)));
8582 assign(result, triop(Iop_SubF64, mkU32(Irrm_NEAREST), mkexpr(op1),
8583 mkexpr(op2)));
8584 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
8585 put_fpr_dw0(r1, mkexpr(result));
8586
8587 return "sdb";
8588}
8589
8590
8591static HChar *
8592s390_irgen_CLC(UChar length, IRTemp start1, IRTemp start2)
8593{
florian79e839e2012-05-05 02:20:30 +00008594 IRTemp len = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00008595
florian79e839e2012-05-05 02:20:30 +00008596 assign(len, mkU64(length));
8597 s390_irgen_CLC_EX(len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +00008598
8599 return "clc";
8600}
8601
8602static HChar *
florianb0c9a132011-09-08 15:37:39 +00008603s390_irgen_CLCL(UChar r1, UChar r2)
8604{
8605 IRTemp addr1 = newTemp(Ity_I64);
8606 IRTemp addr2 = newTemp(Ity_I64);
8607 IRTemp addr1_load = newTemp(Ity_I64);
8608 IRTemp addr2_load = newTemp(Ity_I64);
8609 IRTemp len1 = newTemp(Ity_I32);
8610 IRTemp len2 = newTemp(Ity_I32);
8611 IRTemp r1p1 = newTemp(Ity_I32); /* contents of r1 + 1 */
8612 IRTemp r2p1 = newTemp(Ity_I32); /* contents of r2 + 1 */
8613 IRTemp single1 = newTemp(Ity_I8);
8614 IRTemp single2 = newTemp(Ity_I8);
8615 IRTemp pad = newTemp(Ity_I8);
8616
8617 assign(addr1, get_gpr_dw0(r1));
8618 assign(r1p1, get_gpr_w1(r1 + 1));
8619 assign(len1, binop(Iop_And32, mkexpr(r1p1), mkU32(0x00ffffff)));
8620 assign(addr2, get_gpr_dw0(r2));
8621 assign(r2p1, get_gpr_w1(r2 + 1));
8622 assign(len2, binop(Iop_And32, mkexpr(r2p1), mkU32(0x00ffffff)));
8623 assign(pad, get_gpr_b4(r2 + 1));
8624
8625 /* len1 == 0 and len2 == 0? Exit */
8626 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +00008627 next_insn_if(binop(Iop_CmpEQ32, binop(Iop_Or32, mkexpr(len1),
8628 mkexpr(len2)), mkU32(0)));
florianb0c9a132011-09-08 15:37:39 +00008629
8630 /* Because mkite evaluates both the then-clause and the else-clause
8631 we cannot load directly from addr1 here. If len1 is 0, then adddr1
8632 may be NULL and loading from there would segfault. So we provide a
8633 valid dummy address in that case. Loading from there does no harm and
8634 the value will be discarded at runtime. */
8635 assign(addr1_load,
8636 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
8637 mkU64(guest_IA_curr_instr), mkexpr(addr1)));
8638 assign(single1,
8639 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
8640 mkexpr(pad), load(Ity_I8, mkexpr(addr1_load))));
8641
8642 assign(addr2_load,
8643 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
8644 mkU64(guest_IA_curr_instr), mkexpr(addr2)));
8645 assign(single2,
8646 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
8647 mkexpr(pad), load(Ity_I8, mkexpr(addr2_load))));
8648
8649 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, single1, single2, False);
8650 /* Fields differ ? */
florian6820ba52012-07-26 02:01:50 +00008651 next_insn_if(binop(Iop_CmpNE8, mkexpr(single1), mkexpr(single2)));
florianb0c9a132011-09-08 15:37:39 +00008652
8653 /* Update len1 and addr1, unless len1 == 0. */
8654 put_gpr_dw0(r1,
8655 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
8656 mkexpr(addr1),
8657 binop(Iop_Add64, mkexpr(addr1), mkU64(1))));
8658
8659 /* When updating len1 we must not modify bits (r1+1)[0:39] */
8660 put_gpr_w1(r1 + 1,
8661 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
8662 binop(Iop_And32, mkexpr(r1p1), mkU32(0xFF000000u)),
8663 binop(Iop_Sub32, mkexpr(r1p1), mkU32(1))));
8664
8665 /* Update len2 and addr2, unless len2 == 0. */
8666 put_gpr_dw0(r2,
8667 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
8668 mkexpr(addr2),
8669 binop(Iop_Add64, mkexpr(addr2), mkU64(1))));
8670
8671 /* When updating len2 we must not modify bits (r2+1)[0:39] */
8672 put_gpr_w1(r2 + 1,
8673 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
8674 binop(Iop_And32, mkexpr(r2p1), mkU32(0xFF000000u)),
8675 binop(Iop_Sub32, mkexpr(r2p1), mkU32(1))));
8676
florian6820ba52012-07-26 02:01:50 +00008677 iterate();
florianb0c9a132011-09-08 15:37:39 +00008678
8679 return "clcl";
8680}
8681
8682static HChar *
sewardj2019a972011-03-07 16:04:07 +00008683s390_irgen_CLCLE(UChar r1, UChar r3, IRTemp pad2)
8684{
8685 IRTemp addr1, addr3, addr1_load, addr3_load, len1, len3, single1, single3;
8686
8687 addr1 = newTemp(Ity_I64);
8688 addr3 = newTemp(Ity_I64);
8689 addr1_load = newTemp(Ity_I64);
8690 addr3_load = newTemp(Ity_I64);
8691 len1 = newTemp(Ity_I64);
8692 len3 = newTemp(Ity_I64);
8693 single1 = newTemp(Ity_I8);
8694 single3 = newTemp(Ity_I8);
8695
8696 assign(addr1, get_gpr_dw0(r1));
8697 assign(len1, get_gpr_dw0(r1 + 1));
8698 assign(addr3, get_gpr_dw0(r3));
8699 assign(len3, get_gpr_dw0(r3 + 1));
8700
8701 /* len1 == 0 and len3 == 0? Exit */
8702 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +00008703 next_insn_if(binop(Iop_CmpEQ64,binop(Iop_Or64, mkexpr(len1),
8704 mkexpr(len3)), mkU64(0)));
sewardj2019a972011-03-07 16:04:07 +00008705
8706 /* A mux requires both ways to be possible. This is a way to prevent clcle
8707 from reading from addr1 if it should read from the pad. Since the pad
8708 has no address, just read from the instruction, we discard that anyway */
8709 assign(addr1_load,
florian6ad49522011-09-09 02:38:55 +00008710 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
8711 mkU64(guest_IA_curr_instr), mkexpr(addr1)));
sewardj2019a972011-03-07 16:04:07 +00008712
8713 /* same for addr3 */
8714 assign(addr3_load,
florian6ad49522011-09-09 02:38:55 +00008715 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
8716 mkU64(guest_IA_curr_instr), mkexpr(addr3)));
sewardj2019a972011-03-07 16:04:07 +00008717
8718 assign(single1,
florian6ad49522011-09-09 02:38:55 +00008719 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
8720 unop(Iop_64to8, mkexpr(pad2)),
8721 load(Ity_I8, mkexpr(addr1_load))));
sewardj2019a972011-03-07 16:04:07 +00008722
8723 assign(single3,
florian6ad49522011-09-09 02:38:55 +00008724 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
8725 unop(Iop_64to8, mkexpr(pad2)),
8726 load(Ity_I8, mkexpr(addr3_load))));
sewardj2019a972011-03-07 16:04:07 +00008727
8728 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, single1, single3, False);
8729 /* Both fields differ ? */
florian6820ba52012-07-26 02:01:50 +00008730 next_insn_if(binop(Iop_CmpNE8, mkexpr(single1), mkexpr(single3)));
sewardj2019a972011-03-07 16:04:07 +00008731
8732 /* If a length in 0 we must not change this length and the address */
8733 put_gpr_dw0(r1,
florian6ad49522011-09-09 02:38:55 +00008734 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
8735 mkexpr(addr1),
8736 binop(Iop_Add64, mkexpr(addr1), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +00008737
8738 put_gpr_dw0(r1 + 1,
florian6ad49522011-09-09 02:38:55 +00008739 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
8740 mkU64(0), binop(Iop_Sub64, mkexpr(len1), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +00008741
8742 put_gpr_dw0(r3,
florian6ad49522011-09-09 02:38:55 +00008743 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
8744 mkexpr(addr3),
8745 binop(Iop_Add64, mkexpr(addr3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +00008746
8747 put_gpr_dw0(r3 + 1,
florian6ad49522011-09-09 02:38:55 +00008748 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
8749 mkU64(0), binop(Iop_Sub64, mkexpr(len3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +00008750
florian6820ba52012-07-26 02:01:50 +00008751 iterate();
sewardj2019a972011-03-07 16:04:07 +00008752
8753 return "clcle";
8754}
floriana64c2432011-07-16 02:11:50 +00008755
florianb0bf6602012-05-05 00:01:16 +00008756
sewardj2019a972011-03-07 16:04:07 +00008757static void
8758s390_irgen_XC_EX(IRTemp length, IRTemp start1, IRTemp start2)
8759{
florianb0bf6602012-05-05 00:01:16 +00008760 s390_irgen_xonc(Iop_Xor8, length, start1, start2);
8761}
sewardj2019a972011-03-07 16:04:07 +00008762
sewardj2019a972011-03-07 16:04:07 +00008763
florianb0bf6602012-05-05 00:01:16 +00008764static void
8765s390_irgen_NC_EX(IRTemp length, IRTemp start1, IRTemp start2)
8766{
8767 s390_irgen_xonc(Iop_And8, length, start1, start2);
8768}
sewardj2019a972011-03-07 16:04:07 +00008769
sewardj2019a972011-03-07 16:04:07 +00008770
florianb0bf6602012-05-05 00:01:16 +00008771static void
8772s390_irgen_OC_EX(IRTemp length, IRTemp start1, IRTemp start2)
8773{
8774 s390_irgen_xonc(Iop_Or8, length, start1, start2);
sewardj2019a972011-03-07 16:04:07 +00008775}
8776
8777
8778static void
8779s390_irgen_CLC_EX(IRTemp length, IRTemp start1, IRTemp start2)
8780{
8781 IRTemp current1 = newTemp(Ity_I8);
8782 IRTemp current2 = newTemp(Ity_I8);
8783 IRTemp counter = newTemp(Ity_I64);
8784
8785 assign(counter, get_counter_dw0());
8786 put_counter_dw0(mkU64(0));
8787
8788 assign(current1, load(Ity_I8, binop(Iop_Add64, mkexpr(start1),
8789 mkexpr(counter))));
8790 assign(current2, load(Ity_I8, binop(Iop_Add64, mkexpr(start2),
8791 mkexpr(counter))));
8792 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, current1, current2,
8793 False);
8794
8795 /* Both fields differ ? */
florian6820ba52012-07-26 02:01:50 +00008796 next_insn_if(binop(Iop_CmpNE8, mkexpr(current1), mkexpr(current2)));
sewardj2019a972011-03-07 16:04:07 +00008797
8798 /* Check for end of field */
8799 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
florian6820ba52012-07-26 02:01:50 +00008800 iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)));
sewardj2019a972011-03-07 16:04:07 +00008801 put_counter_dw0(mkU64(0));
8802}
8803
8804static void
8805s390_irgen_MVC_EX(IRTemp length, IRTemp start1, IRTemp start2)
8806{
8807 IRTemp counter = newTemp(Ity_I64);
8808
8809 assign(counter, get_counter_dw0());
8810
8811 store(binop(Iop_Add64, mkexpr(start1), mkexpr(counter)),
8812 load(Ity_I8, binop(Iop_Add64, mkexpr(start2), mkexpr(counter))));
8813
8814 /* Check for end of field */
8815 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
florian6820ba52012-07-26 02:01:50 +00008816 iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)));
sewardj2019a972011-03-07 16:04:07 +00008817 put_counter_dw0(mkU64(0));
8818}
8819
florianf87d4fb2012-05-05 02:55:24 +00008820static void
8821s390_irgen_TR_EX(IRTemp length, IRTemp start1, IRTemp start2)
8822{
8823 IRTemp op = newTemp(Ity_I8);
8824 IRTemp op1 = newTemp(Ity_I8);
8825 IRTemp result = newTemp(Ity_I64);
8826 IRTemp counter = newTemp(Ity_I64);
8827
8828 assign(counter, get_counter_dw0());
8829
8830 assign(op, load(Ity_I8, binop(Iop_Add64, mkexpr(start1), mkexpr(counter))));
8831
8832 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)), mkexpr(start2)));
8833
8834 assign(op1, load(Ity_I8, mkexpr(result)));
8835 store(binop(Iop_Add64, mkexpr(start1), mkexpr(counter)), mkexpr(op1));
8836
8837 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
florian6820ba52012-07-26 02:01:50 +00008838 iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)));
florianf87d4fb2012-05-05 02:55:24 +00008839 put_counter_dw0(mkU64(0));
8840}
sewardj2019a972011-03-07 16:04:07 +00008841
8842
8843static void
8844s390_irgen_EX_SS(UChar r, IRTemp addr2,
florian6820ba52012-07-26 02:01:50 +00008845 void (*irgen)(IRTemp length, IRTemp start1, IRTemp start2),
8846 int lensize)
sewardj2019a972011-03-07 16:04:07 +00008847{
8848 struct SS {
8849 unsigned int op : 8;
8850 unsigned int l : 8;
8851 unsigned int b1 : 4;
8852 unsigned int d1 : 12;
8853 unsigned int b2 : 4;
8854 unsigned int d2 : 12;
8855 };
8856 union {
8857 struct SS dec;
8858 unsigned long bytes;
8859 } ss;
8860 IRTemp cond;
8861 IRDirty *d;
8862 IRTemp torun;
8863
8864 IRTemp start1 = newTemp(Ity_I64);
8865 IRTemp start2 = newTemp(Ity_I64);
8866 IRTemp len = newTemp(lensize == 64 ? Ity_I64 : Ity_I32);
8867 cond = newTemp(Ity_I1);
8868 torun = newTemp(Ity_I64);
8869
8870 assign(torun, load(Ity_I64, mkexpr(addr2)));
8871 /* Start with a check that the saved code is still correct */
8872 assign(cond, binop(Iop_CmpNE64, mkexpr(torun), mkU64(last_execute_target)));
8873 /* If not, save the new value */
8874 d = unsafeIRDirty_0_N (0, "s390x_dirtyhelper_EX", &s390x_dirtyhelper_EX,
8875 mkIRExprVec_1(mkexpr(torun)));
8876 d->guard = mkexpr(cond);
8877 stmt(IRStmt_Dirty(d));
8878
8879 /* and restart */
florian428dfdd2012-03-27 03:09:49 +00008880 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TISTART),
8881 mkU64(guest_IA_curr_instr)));
8882 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TILEN), mkU64(4)));
florian6820ba52012-07-26 02:01:50 +00008883 restart_if(mkexpr(cond));
sewardj2019a972011-03-07 16:04:07 +00008884
8885 ss.bytes = last_execute_target;
8886 assign(start1, binop(Iop_Add64, mkU64(ss.dec.d1),
8887 ss.dec.b1 != 0 ? get_gpr_dw0(ss.dec.b1) : mkU64(0)));
8888 assign(start2, binop(Iop_Add64, mkU64(ss.dec.d2),
8889 ss.dec.b2 != 0 ? get_gpr_dw0(ss.dec.b2) : mkU64(0)));
8890 assign(len, unop(lensize == 64 ? Iop_8Uto64 : Iop_8Uto32, binop(Iop_Or8,
8891 r != 0 ? get_gpr_b7(r): mkU8(0), mkU8(ss.dec.l))));
8892 irgen(len, start1, start2);
florian8844a632012-04-13 04:04:06 +00008893
sewardj2019a972011-03-07 16:04:07 +00008894 last_execute_target = 0;
8895}
8896
8897static HChar *
8898s390_irgen_EX(UChar r1, IRTemp addr2)
8899{
8900 switch(last_execute_target & 0xff00000000000000ULL) {
8901 case 0:
8902 {
8903 /* no code information yet */
8904 IRDirty *d;
8905
8906 /* so safe the code... */
8907 d = unsafeIRDirty_0_N (0, "s390x_dirtyhelper_EX", &s390x_dirtyhelper_EX,
8908 mkIRExprVec_1(load(Ity_I64, mkexpr(addr2))));
8909 stmt(IRStmt_Dirty(d));
8910 /* and restart */
florian428dfdd2012-03-27 03:09:49 +00008911 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TISTART),
8912 mkU64(guest_IA_curr_instr)));
8913 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TILEN), mkU64(4)));
florian6820ba52012-07-26 02:01:50 +00008914 restart_if(IRExpr_Const(IRConst_U1(True)));
8915
sewardj2019a972011-03-07 16:04:07 +00008916 /* we know that this will be invalidated */
florianf9e1ed72012-04-17 02:41:56 +00008917 put_IA(mkaddr_expr(guest_IA_next_instr));
sewardj2019a972011-03-07 16:04:07 +00008918 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +00008919 dis_res->jk_StopHere = Ijk_TInval;
sewardj2019a972011-03-07 16:04:07 +00008920 break;
8921 }
8922
8923 case 0xd200000000000000ULL:
8924 /* special case MVC */
8925 s390_irgen_EX_SS(r1, addr2, s390_irgen_MVC_EX, 64);
8926 return "mvc via ex";
8927
8928 case 0xd500000000000000ULL:
8929 /* special case CLC */
8930 s390_irgen_EX_SS(r1, addr2, s390_irgen_CLC_EX, 64);
8931 return "clc via ex";
8932
8933 case 0xd700000000000000ULL:
8934 /* special case XC */
8935 s390_irgen_EX_SS(r1, addr2, s390_irgen_XC_EX, 32);
8936 return "xc via ex";
8937
florianb0bf6602012-05-05 00:01:16 +00008938 case 0xd600000000000000ULL:
8939 /* special case OC */
8940 s390_irgen_EX_SS(r1, addr2, s390_irgen_OC_EX, 32);
8941 return "oc via ex";
8942
8943 case 0xd400000000000000ULL:
8944 /* special case NC */
8945 s390_irgen_EX_SS(r1, addr2, s390_irgen_NC_EX, 32);
8946 return "nc via ex";
sewardj2019a972011-03-07 16:04:07 +00008947
florianf87d4fb2012-05-05 02:55:24 +00008948 case 0xdc00000000000000ULL:
8949 /* special case TR */
8950 s390_irgen_EX_SS(r1, addr2, s390_irgen_TR_EX, 64);
8951 return "tr via ex";
8952
sewardj2019a972011-03-07 16:04:07 +00008953 default:
8954 {
8955 /* everything else will get a self checking prefix that also checks the
8956 register content */
8957 IRDirty *d;
8958 UChar *bytes;
8959 IRTemp cond;
8960 IRTemp orperand;
8961 IRTemp torun;
8962
8963 cond = newTemp(Ity_I1);
8964 orperand = newTemp(Ity_I64);
8965 torun = newTemp(Ity_I64);
8966
8967 if (r1 == 0)
8968 assign(orperand, mkU64(0));
8969 else
8970 assign(orperand, unop(Iop_8Uto64,get_gpr_b7(r1)));
8971 /* This code is going to be translated */
8972 assign(torun, binop(Iop_Or64, load(Ity_I64, mkexpr(addr2)),
8973 binop(Iop_Shl64, mkexpr(orperand), mkU8(48))));
8974
8975 /* Start with a check that saved code is still correct */
8976 assign(cond, binop(Iop_CmpNE64, mkexpr(torun),
8977 mkU64(last_execute_target)));
8978 /* If not, save the new value */
8979 d = unsafeIRDirty_0_N (0, "s390x_dirtyhelper_EX", &s390x_dirtyhelper_EX,
8980 mkIRExprVec_1(mkexpr(torun)));
8981 d->guard = mkexpr(cond);
8982 stmt(IRStmt_Dirty(d));
8983
8984 /* and restart */
florian428dfdd2012-03-27 03:09:49 +00008985 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TISTART), mkU64(guest_IA_curr_instr)));
8986 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TILEN), mkU64(4)));
florian6820ba52012-07-26 02:01:50 +00008987 restart_if(mkexpr(cond));
sewardj2019a972011-03-07 16:04:07 +00008988
8989 /* Now comes the actual translation */
8990 bytes = (UChar *) &last_execute_target;
8991 s390_decode_and_irgen(bytes, ((((bytes[0] >> 6) + 1) >> 1) + 1) << 1,
8992 dis_res);
sewardj7ee97522011-05-09 21:45:04 +00008993 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00008994 vex_printf(" which was executed by\n");
8995 /* dont make useless translations in the next execute */
8996 last_execute_target = 0;
8997 }
8998 }
8999 return "ex";
9000}
9001
9002static HChar *
9003s390_irgen_EXRL(UChar r1, UInt offset)
9004{
9005 IRTemp addr = newTemp(Ity_I64);
9006 /* we might save one round trip because we know the target */
9007 if (!last_execute_target)
9008 last_execute_target = *(ULong *)(HWord)
9009 (guest_IA_curr_instr + offset * 2UL);
9010 assign(addr, mkU64(guest_IA_curr_instr + offset * 2UL));
9011 s390_irgen_EX(r1, addr);
9012 return "exrl";
9013}
9014
9015static HChar *
9016s390_irgen_IPM(UChar r1)
9017{
9018 // As long as we dont support SPM, lets just assume 0 as program mask
9019 put_gpr_b4(r1, unop(Iop_32to8, binop(Iop_Or32, mkU32(0 /* program mask */),
9020 binop(Iop_Shl32, s390_call_calculate_cc(), mkU8(4)))));
9021
9022 return "ipm";
9023}
9024
9025
9026static HChar *
9027s390_irgen_SRST(UChar r1, UChar r2)
9028{
9029 IRTemp address = newTemp(Ity_I64);
9030 IRTemp next = newTemp(Ity_I64);
9031 IRTemp delim = newTemp(Ity_I8);
9032 IRTemp counter = newTemp(Ity_I64);
9033 IRTemp byte = newTemp(Ity_I8);
9034
9035 assign(address, get_gpr_dw0(r2));
9036 assign(next, get_gpr_dw0(r1));
9037
9038 assign(counter, get_counter_dw0());
9039 put_counter_dw0(mkU64(0));
9040
9041 // start = next? CC=2 and out r1 and r2 unchanged
9042 s390_cc_set(2);
9043 put_gpr_dw0(r2, binop(Iop_Sub64, mkexpr(address), mkexpr(counter)));
florian6820ba52012-07-26 02:01:50 +00009044 next_insn_if(binop(Iop_CmpEQ64, mkexpr(address), mkexpr(next)));
sewardj2019a972011-03-07 16:04:07 +00009045
9046 assign(byte, load(Ity_I8, mkexpr(address)));
9047 assign(delim, get_gpr_b7(0));
9048
9049 // byte = delim? CC=1, R1=address
9050 s390_cc_set(1);
9051 put_gpr_dw0(r1, mkexpr(address));
florian6820ba52012-07-26 02:01:50 +00009052 next_insn_if(binop(Iop_CmpEQ8, mkexpr(delim), mkexpr(byte)));
sewardj2019a972011-03-07 16:04:07 +00009053
9054 // else: all equal, no end yet, loop
9055 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
9056 put_gpr_dw0(r1, mkexpr(next));
9057 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(address), mkU64(1)));
floriancf87c942012-07-25 00:52:21 +00009058
florian6820ba52012-07-26 02:01:50 +00009059 iterate();
sewardj2019a972011-03-07 16:04:07 +00009060
9061 return "srst";
9062}
9063
9064static HChar *
9065s390_irgen_CLST(UChar r1, UChar r2)
9066{
9067 IRTemp address1 = newTemp(Ity_I64);
9068 IRTemp address2 = newTemp(Ity_I64);
9069 IRTemp end = newTemp(Ity_I8);
9070 IRTemp counter = newTemp(Ity_I64);
9071 IRTemp byte1 = newTemp(Ity_I8);
9072 IRTemp byte2 = newTemp(Ity_I8);
9073
9074 assign(address1, get_gpr_dw0(r1));
9075 assign(address2, get_gpr_dw0(r2));
9076 assign(end, get_gpr_b7(0));
9077 assign(counter, get_counter_dw0());
9078 put_counter_dw0(mkU64(0));
9079 assign(byte1, load(Ity_I8, mkexpr(address1)));
9080 assign(byte2, load(Ity_I8, mkexpr(address2)));
9081
9082 // end in both? all equal, reset r1 and r2 to start values
9083 s390_cc_set(0);
9084 put_gpr_dw0(r1, binop(Iop_Sub64, mkexpr(address1), mkexpr(counter)));
9085 put_gpr_dw0(r2, binop(Iop_Sub64, mkexpr(address2), mkexpr(counter)));
florian6820ba52012-07-26 02:01:50 +00009086 next_insn_if(binop(Iop_CmpEQ8, mkU8(0),
9087 binop(Iop_Or8,
9088 binop(Iop_Xor8, mkexpr(byte1), mkexpr(end)),
9089 binop(Iop_Xor8, mkexpr(byte2), mkexpr(end)))));
sewardj2019a972011-03-07 16:04:07 +00009090
9091 put_gpr_dw0(r1, mkexpr(address1));
9092 put_gpr_dw0(r2, mkexpr(address2));
9093
9094 // End found in string1
9095 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +00009096 next_insn_if(binop(Iop_CmpEQ8, mkexpr(end), mkexpr(byte1)));
sewardj2019a972011-03-07 16:04:07 +00009097
9098 // End found in string2
9099 s390_cc_set(2);
florian6820ba52012-07-26 02:01:50 +00009100 next_insn_if(binop(Iop_CmpEQ8, mkexpr(end), mkexpr(byte2)));
sewardj2019a972011-03-07 16:04:07 +00009101
9102 // string1 < string2
9103 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +00009104 next_insn_if(binop(Iop_CmpLT32U, unop(Iop_8Uto32, mkexpr(byte1)),
9105 unop(Iop_8Uto32, mkexpr(byte2))));
sewardj2019a972011-03-07 16:04:07 +00009106
9107 // string2 < string1
9108 s390_cc_set(2);
florian6820ba52012-07-26 02:01:50 +00009109 next_insn_if(binop(Iop_CmpLT32U, unop(Iop_8Uto32, mkexpr(byte2)),
9110 unop(Iop_8Uto32, mkexpr(byte1))));
sewardj2019a972011-03-07 16:04:07 +00009111
9112 // else: all equal, no end yet, loop
9113 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
9114 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), mkU64(1)));
9115 put_gpr_dw0(r2, binop(Iop_Add64, get_gpr_dw0(r2), mkU64(1)));
floriancf87c942012-07-25 00:52:21 +00009116
florian6820ba52012-07-26 02:01:50 +00009117 iterate();
sewardj2019a972011-03-07 16:04:07 +00009118
9119 return "clst";
9120}
9121
9122static void
9123s390_irgen_load_multiple_32bit(UChar r1, UChar r3, IRTemp op2addr)
9124{
9125 UChar reg;
9126 IRTemp addr = newTemp(Ity_I64);
9127
9128 assign(addr, mkexpr(op2addr));
9129 reg = r1;
9130 do {
9131 IRTemp old = addr;
9132
9133 reg %= 16;
9134 put_gpr_w1(reg, load(Ity_I32, mkexpr(addr)));
9135 addr = newTemp(Ity_I64);
9136 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
9137 reg++;
9138 } while (reg != (r3 + 1));
9139}
9140
9141static HChar *
9142s390_irgen_LM(UChar r1, UChar r3, IRTemp op2addr)
9143{
9144 s390_irgen_load_multiple_32bit(r1, r3, op2addr);
9145
9146 return "lm";
9147}
9148
9149static HChar *
9150s390_irgen_LMY(UChar r1, UChar r3, IRTemp op2addr)
9151{
9152 s390_irgen_load_multiple_32bit(r1, r3, op2addr);
9153
9154 return "lmy";
9155}
9156
9157static HChar *
9158s390_irgen_LMH(UChar r1, UChar r3, IRTemp op2addr)
9159{
9160 UChar reg;
9161 IRTemp addr = newTemp(Ity_I64);
9162
9163 assign(addr, mkexpr(op2addr));
9164 reg = r1;
9165 do {
9166 IRTemp old = addr;
9167
9168 reg %= 16;
9169 put_gpr_w0(reg, load(Ity_I32, mkexpr(addr)));
9170 addr = newTemp(Ity_I64);
9171 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
9172 reg++;
9173 } while (reg != (r3 + 1));
9174
9175 return "lmh";
9176}
9177
9178static HChar *
9179s390_irgen_LMG(UChar r1, UChar r3, IRTemp op2addr)
9180{
9181 UChar reg;
9182 IRTemp addr = newTemp(Ity_I64);
9183
9184 assign(addr, mkexpr(op2addr));
9185 reg = r1;
9186 do {
9187 IRTemp old = addr;
9188
9189 reg %= 16;
9190 put_gpr_dw0(reg, load(Ity_I64, mkexpr(addr)));
9191 addr = newTemp(Ity_I64);
9192 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(8)));
9193 reg++;
9194 } while (reg != (r3 + 1));
9195
9196 return "lmg";
9197}
9198
9199static void
9200s390_irgen_store_multiple_32bit(UChar r1, UChar r3, IRTemp op2addr)
9201{
9202 UChar reg;
9203 IRTemp addr = newTemp(Ity_I64);
9204
9205 assign(addr, mkexpr(op2addr));
9206 reg = r1;
9207 do {
9208 IRTemp old = addr;
9209
9210 reg %= 16;
9211 store(mkexpr(addr), get_gpr_w1(reg));
9212 addr = newTemp(Ity_I64);
9213 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
9214 reg++;
9215 } while( reg != (r3 + 1));
9216}
9217
9218static HChar *
9219s390_irgen_STM(UChar r1, UChar r3, IRTemp op2addr)
9220{
9221 s390_irgen_store_multiple_32bit(r1, r3, op2addr);
9222
9223 return "stm";
9224}
9225
9226static HChar *
9227s390_irgen_STMY(UChar r1, UChar r3, IRTemp op2addr)
9228{
9229 s390_irgen_store_multiple_32bit(r1, r3, op2addr);
9230
9231 return "stmy";
9232}
9233
9234static HChar *
9235s390_irgen_STMH(UChar r1, UChar r3, IRTemp op2addr)
9236{
9237 UChar reg;
9238 IRTemp addr = newTemp(Ity_I64);
9239
9240 assign(addr, mkexpr(op2addr));
9241 reg = r1;
9242 do {
9243 IRTemp old = addr;
9244
9245 reg %= 16;
9246 store(mkexpr(addr), get_gpr_w0(reg));
9247 addr = newTemp(Ity_I64);
9248 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
9249 reg++;
9250 } while( reg != (r3 + 1));
9251
9252 return "stmh";
9253}
9254
9255static HChar *
9256s390_irgen_STMG(UChar r1, UChar r3, IRTemp op2addr)
9257{
9258 UChar reg;
9259 IRTemp addr = newTemp(Ity_I64);
9260
9261 assign(addr, mkexpr(op2addr));
9262 reg = r1;
9263 do {
9264 IRTemp old = addr;
9265
9266 reg %= 16;
9267 store(mkexpr(addr), get_gpr_dw0(reg));
9268 addr = newTemp(Ity_I64);
9269 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(8)));
9270 reg++;
9271 } while( reg != (r3 + 1));
9272
9273 return "stmg";
9274}
9275
9276static void
florianb0bf6602012-05-05 00:01:16 +00009277s390_irgen_xonc(IROp op, IRTemp length, IRTemp start1, IRTemp start2)
sewardj2019a972011-03-07 16:04:07 +00009278{
9279 IRTemp old1 = newTemp(Ity_I8);
9280 IRTemp old2 = newTemp(Ity_I8);
9281 IRTemp new1 = newTemp(Ity_I8);
9282 IRTemp counter = newTemp(Ity_I32);
9283 IRTemp addr1 = newTemp(Ity_I64);
9284
9285 assign(counter, get_counter_w0());
9286
9287 assign(addr1, binop(Iop_Add64, mkexpr(start1),
9288 unop(Iop_32Uto64, mkexpr(counter))));
9289
9290 assign(old1, load(Ity_I8, mkexpr(addr1)));
9291 assign(old2, load(Ity_I8, binop(Iop_Add64, mkexpr(start2),
9292 unop(Iop_32Uto64,mkexpr(counter)))));
9293 assign(new1, binop(op, mkexpr(old1), mkexpr(old2)));
9294
9295 /* Special case: xc is used to zero memory */
sewardj2019a972011-03-07 16:04:07 +00009296 if (op == Iop_Xor8) {
9297 store(mkexpr(addr1),
florian6ad49522011-09-09 02:38:55 +00009298 mkite(binop(Iop_CmpEQ64, mkexpr(start1), mkexpr(start2)),
9299 mkU8(0), mkexpr(new1)));
sewardj2019a972011-03-07 16:04:07 +00009300 } else
9301 store(mkexpr(addr1), mkexpr(new1));
9302 put_counter_w1(binop(Iop_Or32, unop(Iop_8Uto32, mkexpr(new1)),
9303 get_counter_w1()));
9304
9305 /* Check for end of field */
9306 put_counter_w0(binop(Iop_Add32, mkexpr(counter), mkU32(1)));
florian6820ba52012-07-26 02:01:50 +00009307 iterate_if(binop(Iop_CmpNE32, mkexpr(counter), mkexpr(length)));
sewardj2019a972011-03-07 16:04:07 +00009308 s390_cc_thunk_put1(S390_CC_OP_BITWISE, mktemp(Ity_I32, get_counter_w1()),
9309 False);
9310 put_counter_dw0(mkU64(0));
9311}
9312
9313static HChar *
9314s390_irgen_XC(UChar length, IRTemp start1, IRTemp start2)
9315{
florianb0bf6602012-05-05 00:01:16 +00009316 IRTemp len = newTemp(Ity_I32);
9317
9318 assign(len, mkU32(length));
9319 s390_irgen_xonc(Iop_Xor8, len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +00009320
9321 return "xc";
9322}
9323
sewardjb63967e2011-03-24 08:50:04 +00009324static void
9325s390_irgen_XC_sameloc(UChar length, UChar b, UShort d)
9326{
9327 IRTemp counter = newTemp(Ity_I32);
9328 IRTemp start = newTemp(Ity_I64);
9329 IRTemp addr = newTemp(Ity_I64);
9330
9331 assign(start,
9332 binop(Iop_Add64, mkU64(d), b != 0 ? get_gpr_dw0(b) : mkU64(0)));
9333
9334 if (length < 8) {
9335 UInt i;
9336
9337 for (i = 0; i <= length; ++i) {
9338 store(binop(Iop_Add64, mkexpr(start), mkU64(i)), mkU8(0));
9339 }
9340 } else {
9341 assign(counter, get_counter_w0());
9342
9343 assign(addr, binop(Iop_Add64, mkexpr(start),
9344 unop(Iop_32Uto64, mkexpr(counter))));
9345
9346 store(mkexpr(addr), mkU8(0));
9347
9348 /* Check for end of field */
9349 put_counter_w0(binop(Iop_Add32, mkexpr(counter), mkU32(1)));
florian6820ba52012-07-26 02:01:50 +00009350 iterate_if(binop(Iop_CmpNE32, mkexpr(counter), mkU32(length)));
sewardjb63967e2011-03-24 08:50:04 +00009351
9352 /* Reset counter */
9353 put_counter_dw0(mkU64(0));
9354 }
9355
9356 s390_cc_thunk_put1(S390_CC_OP_BITWISE, mktemp(Ity_I32, mkU32(0)), False);
9357
sewardj7ee97522011-05-09 21:45:04 +00009358 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardjb63967e2011-03-24 08:50:04 +00009359 s390_disasm(ENC3(MNM, UDLB, UDXB), "xc", d, length, b, d, 0, b);
9360}
9361
sewardj2019a972011-03-07 16:04:07 +00009362static HChar *
9363s390_irgen_NC(UChar length, IRTemp start1, IRTemp start2)
9364{
florianb0bf6602012-05-05 00:01:16 +00009365 IRTemp len = newTemp(Ity_I32);
9366
9367 assign(len, mkU32(length));
9368 s390_irgen_xonc(Iop_And8, len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +00009369
9370 return "nc";
9371}
9372
9373static HChar *
9374s390_irgen_OC(UChar length, IRTemp start1, IRTemp start2)
9375{
florianb0bf6602012-05-05 00:01:16 +00009376 IRTemp len = newTemp(Ity_I32);
9377
9378 assign(len, mkU32(length));
9379 s390_irgen_xonc(Iop_Or8, len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +00009380
9381 return "oc";
9382}
9383
9384
9385static HChar *
9386s390_irgen_MVC(UChar length, IRTemp start1, IRTemp start2)
9387{
florian79e839e2012-05-05 02:20:30 +00009388 IRTemp len = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00009389
florian79e839e2012-05-05 02:20:30 +00009390 assign(len, mkU64(length));
9391 s390_irgen_MVC_EX(len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +00009392
9393 return "mvc";
9394}
9395
9396static HChar *
florianb0c9a132011-09-08 15:37:39 +00009397s390_irgen_MVCL(UChar r1, UChar r2)
9398{
9399 IRTemp addr1 = newTemp(Ity_I64);
9400 IRTemp addr2 = newTemp(Ity_I64);
9401 IRTemp addr2_load = newTemp(Ity_I64);
9402 IRTemp r1p1 = newTemp(Ity_I32); /* contents of r1 + 1 */
9403 IRTemp r2p1 = newTemp(Ity_I32); /* contents of r2 + 1 */
9404 IRTemp len1 = newTemp(Ity_I32);
9405 IRTemp len2 = newTemp(Ity_I32);
9406 IRTemp pad = newTemp(Ity_I8);
9407 IRTemp single = newTemp(Ity_I8);
9408
9409 assign(addr1, get_gpr_dw0(r1));
9410 assign(r1p1, get_gpr_w1(r1 + 1));
9411 assign(len1, binop(Iop_And32, mkexpr(r1p1), mkU32(0x00ffffff)));
9412 assign(addr2, get_gpr_dw0(r2));
9413 assign(r2p1, get_gpr_w1(r2 + 1));
9414 assign(len2, binop(Iop_And32, mkexpr(r2p1), mkU32(0x00ffffff)));
9415 assign(pad, get_gpr_b4(r2 + 1));
9416
9417 /* len1 == 0 ? */
9418 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len2, False);
florian6820ba52012-07-26 02:01:50 +00009419 next_insn_if(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)));
florianb0c9a132011-09-08 15:37:39 +00009420
9421 /* Check for destructive overlap:
9422 addr1 > addr2 && addr2 + len1 > addr1 && (addr2 + len2) > addr1 */
9423 s390_cc_set(3);
9424 IRTemp cond1 = newTemp(Ity_I32);
9425 assign(cond1, unop(Iop_1Uto32,
9426 binop(Iop_CmpLT64U, mkexpr(addr2), mkexpr(addr1))));
9427 IRTemp cond2 = newTemp(Ity_I32);
9428 assign(cond2, unop(Iop_1Uto32,
9429 binop(Iop_CmpLT64U, mkexpr(addr1),
9430 binop(Iop_Add64, mkexpr(addr2),
9431 unop(Iop_32Uto64, mkexpr(len1))))));
9432 IRTemp cond3 = newTemp(Ity_I32);
9433 assign(cond3, unop(Iop_1Uto32,
9434 binop(Iop_CmpLT64U,
9435 mkexpr(addr1),
9436 binop(Iop_Add64, mkexpr(addr2),
9437 unop(Iop_32Uto64, mkexpr(len2))))));
9438
florian6820ba52012-07-26 02:01:50 +00009439 next_insn_if(binop(Iop_CmpEQ32,
9440 binop(Iop_And32,
9441 binop(Iop_And32, mkexpr(cond1), mkexpr(cond2)),
9442 mkexpr(cond3)),
9443 mkU32(1)));
florianb0c9a132011-09-08 15:37:39 +00009444
9445 /* See s390_irgen_CLCL for explanation why we cannot load directly
9446 and need two steps. */
9447 assign(addr2_load,
9448 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
9449 mkU64(guest_IA_curr_instr), mkexpr(addr2)));
9450 assign(single,
9451 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
9452 mkexpr(pad), load(Ity_I8, mkexpr(addr2_load))));
9453
9454 store(mkexpr(addr1), mkexpr(single));
9455
9456 /* Update addr1 and len1 */
9457 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkU64(1)));
9458 put_gpr_w1(r1 + 1, binop(Iop_Sub32, mkexpr(r1p1), mkU32(1)));
9459
9460 /* Update addr2 and len2 */
9461 put_gpr_dw0(r2,
9462 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
9463 mkexpr(addr2),
9464 binop(Iop_Add64, mkexpr(addr2), mkU64(1))));
9465
9466 /* When updating len2 we must not modify bits (r2+1)[0:39] */
9467 put_gpr_w1(r2 + 1,
9468 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
9469 binop(Iop_And32, mkexpr(r2p1), mkU32(0xFF000000u)),
9470 binop(Iop_Sub32, mkexpr(r2p1), mkU32(1))));
9471
9472 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len2, False);
florian6820ba52012-07-26 02:01:50 +00009473 iterate_if(binop(Iop_CmpNE32, mkexpr(len1), mkU32(1)));
florianb0c9a132011-09-08 15:37:39 +00009474
9475 return "mvcl";
9476}
9477
9478
9479static HChar *
sewardj2019a972011-03-07 16:04:07 +00009480s390_irgen_MVCLE(UChar r1, UChar r3, IRTemp pad2)
9481{
9482 IRTemp addr1, addr3, addr3_load, len1, len3, single;
9483
9484 addr1 = newTemp(Ity_I64);
9485 addr3 = newTemp(Ity_I64);
9486 addr3_load = newTemp(Ity_I64);
9487 len1 = newTemp(Ity_I64);
9488 len3 = newTemp(Ity_I64);
9489 single = newTemp(Ity_I8);
9490
9491 assign(addr1, get_gpr_dw0(r1));
9492 assign(len1, get_gpr_dw0(r1 + 1));
9493 assign(addr3, get_gpr_dw0(r3));
9494 assign(len3, get_gpr_dw0(r3 + 1));
9495
9496 // len1 == 0 ?
9497 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len3, False);
florian6820ba52012-07-26 02:01:50 +00009498 next_insn_if(binop(Iop_CmpEQ64,mkexpr(len1), mkU64(0)));
sewardj2019a972011-03-07 16:04:07 +00009499
9500 /* This is a hack to prevent mvcle from reading from addr3 if it
9501 should read from the pad. Since the pad has no address, just
9502 read from the instruction, we discard that anyway */
9503 assign(addr3_load,
florian6ad49522011-09-09 02:38:55 +00009504 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
9505 mkU64(guest_IA_curr_instr), mkexpr(addr3)));
sewardj2019a972011-03-07 16:04:07 +00009506
9507 assign(single,
florian6ad49522011-09-09 02:38:55 +00009508 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
9509 unop(Iop_64to8, mkexpr(pad2)),
9510 load(Ity_I8, mkexpr(addr3_load))));
sewardj2019a972011-03-07 16:04:07 +00009511 store(mkexpr(addr1), mkexpr(single));
9512
9513 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkU64(1)));
9514
9515 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkU64(1)));
9516
9517 put_gpr_dw0(r3,
florian6ad49522011-09-09 02:38:55 +00009518 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
9519 mkexpr(addr3),
9520 binop(Iop_Add64, mkexpr(addr3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +00009521
9522 put_gpr_dw0(r3 + 1,
florian6ad49522011-09-09 02:38:55 +00009523 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
9524 mkU64(0), binop(Iop_Sub64, mkexpr(len3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +00009525
sewardj2019a972011-03-07 16:04:07 +00009526 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len3, False);
florian6820ba52012-07-26 02:01:50 +00009527 iterate_if(binop(Iop_CmpNE64, mkexpr(len1), mkU64(1)));
sewardj2019a972011-03-07 16:04:07 +00009528
9529 return "mvcle";
9530}
9531
9532static HChar *
9533s390_irgen_MVST(UChar r1, UChar r2)
9534{
9535 IRTemp addr1 = newTemp(Ity_I64);
9536 IRTemp addr2 = newTemp(Ity_I64);
9537 IRTemp end = newTemp(Ity_I8);
9538 IRTemp byte = newTemp(Ity_I8);
9539 IRTemp counter = newTemp(Ity_I64);
9540
9541 assign(addr1, get_gpr_dw0(r1));
9542 assign(addr2, get_gpr_dw0(r2));
9543 assign(counter, get_counter_dw0());
9544 assign(end, get_gpr_b7(0));
9545 assign(byte, load(Ity_I8, binop(Iop_Add64, mkexpr(addr2),mkexpr(counter))));
9546 store(binop(Iop_Add64,mkexpr(addr1),mkexpr(counter)), mkexpr(byte));
9547
9548 // We use unlimited as cpu-determined number
9549 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
florian6820ba52012-07-26 02:01:50 +00009550 iterate_if(binop(Iop_CmpNE8, mkexpr(end), mkexpr(byte)));
sewardj2019a972011-03-07 16:04:07 +00009551
9552 // and always set cc=1 at the end + update r1
9553 s390_cc_set(1);
9554 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(counter)));
9555 put_counter_dw0(mkU64(0));
9556
9557 return "mvst";
9558}
9559
9560static void
9561s390_irgen_divide_64to32(IROp op, UChar r1, IRTemp op2)
9562{
9563 IRTemp op1 = newTemp(Ity_I64);
9564 IRTemp result = newTemp(Ity_I64);
9565
9566 assign(op1, binop(Iop_32HLto64,
9567 get_gpr_w1(r1), // high 32 bits
9568 get_gpr_w1(r1 + 1))); // low 32 bits
9569 assign(result, binop(op, mkexpr(op1), mkexpr(op2)));
9570 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result))); // remainder
9571 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result))); // quotient
9572}
9573
9574static void
9575s390_irgen_divide_128to64(IROp op, UChar r1, IRTemp op2)
9576{
9577 IRTemp op1 = newTemp(Ity_I128);
9578 IRTemp result = newTemp(Ity_I128);
9579
9580 assign(op1, binop(Iop_64HLto128,
9581 get_gpr_dw0(r1), // high 64 bits
9582 get_gpr_dw0(r1 + 1))); // low 64 bits
9583 assign(result, binop(op, mkexpr(op1), mkexpr(op2)));
9584 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result))); // remainder
9585 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result))); // quotient
9586}
9587
9588static void
9589s390_irgen_divide_64to64(IROp op, UChar r1, IRTemp op2)
9590{
9591 IRTemp op1 = newTemp(Ity_I64);
9592 IRTemp result = newTemp(Ity_I128);
9593
9594 assign(op1, get_gpr_dw0(r1 + 1));
9595 assign(result, binop(op, mkexpr(op1), mkexpr(op2)));
9596 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result))); // remainder
9597 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result))); // quotient
9598}
9599
9600static HChar *
9601s390_irgen_DR(UChar r1, UChar r2)
9602{
9603 IRTemp op2 = newTemp(Ity_I32);
9604
9605 assign(op2, get_gpr_w1(r2));
9606
9607 s390_irgen_divide_64to32(Iop_DivModS64to32, r1, op2);
9608
9609 return "dr";
9610}
9611
9612static HChar *
9613s390_irgen_D(UChar r1, IRTemp op2addr)
9614{
9615 IRTemp op2 = newTemp(Ity_I32);
9616
9617 assign(op2, load(Ity_I32, mkexpr(op2addr)));
9618
9619 s390_irgen_divide_64to32(Iop_DivModS64to32, r1, op2);
9620
9621 return "d";
9622}
9623
9624static HChar *
9625s390_irgen_DLR(UChar r1, UChar r2)
9626{
9627 IRTemp op2 = newTemp(Ity_I32);
9628
9629 assign(op2, get_gpr_w1(r2));
9630
9631 s390_irgen_divide_64to32(Iop_DivModU64to32, r1, op2);
9632
florian7cd1cde2012-08-16 23:57:43 +00009633 return "dlr";
sewardj2019a972011-03-07 16:04:07 +00009634}
9635
9636static HChar *
9637s390_irgen_DL(UChar r1, IRTemp op2addr)
9638{
9639 IRTemp op2 = newTemp(Ity_I32);
9640
9641 assign(op2, load(Ity_I32, mkexpr(op2addr)));
9642
9643 s390_irgen_divide_64to32(Iop_DivModU64to32, r1, op2);
9644
9645 return "dl";
9646}
9647
9648static HChar *
9649s390_irgen_DLG(UChar r1, IRTemp op2addr)
9650{
9651 IRTemp op2 = newTemp(Ity_I64);
9652
9653 assign(op2, load(Ity_I64, mkexpr(op2addr)));
9654
9655 s390_irgen_divide_128to64(Iop_DivModU128to64, r1, op2);
9656
9657 return "dlg";
9658}
9659
9660static HChar *
9661s390_irgen_DLGR(UChar r1, UChar r2)
9662{
9663 IRTemp op2 = newTemp(Ity_I64);
9664
9665 assign(op2, get_gpr_dw0(r2));
9666
9667 s390_irgen_divide_128to64(Iop_DivModU128to64, r1, op2);
9668
9669 return "dlgr";
9670}
9671
9672static HChar *
9673s390_irgen_DSGR(UChar r1, UChar r2)
9674{
9675 IRTemp op2 = newTemp(Ity_I64);
9676
9677 assign(op2, get_gpr_dw0(r2));
9678
9679 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
9680
9681 return "dsgr";
9682}
9683
9684static HChar *
9685s390_irgen_DSG(UChar r1, IRTemp op2addr)
9686{
9687 IRTemp op2 = newTemp(Ity_I64);
9688
9689 assign(op2, load(Ity_I64, mkexpr(op2addr)));
9690
9691 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
9692
9693 return "dsg";
9694}
9695
9696static HChar *
9697s390_irgen_DSGFR(UChar r1, UChar r2)
9698{
9699 IRTemp op2 = newTemp(Ity_I64);
9700
9701 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
9702
9703 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
9704
9705 return "dsgfr";
9706}
9707
9708static HChar *
9709s390_irgen_DSGF(UChar r1, IRTemp op2addr)
9710{
9711 IRTemp op2 = newTemp(Ity_I64);
9712
9713 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
9714
9715 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
9716
9717 return "dsgf";
9718}
9719
9720static void
9721s390_irgen_load_ar_multiple(UChar r1, UChar r3, IRTemp op2addr)
9722{
9723 UChar reg;
9724 IRTemp addr = newTemp(Ity_I64);
9725
9726 assign(addr, mkexpr(op2addr));
9727 reg = r1;
9728 do {
9729 IRTemp old = addr;
9730
9731 reg %= 16;
9732 put_ar_w0(reg, load(Ity_I32, mkexpr(addr)));
9733 addr = newTemp(Ity_I64);
9734 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
9735 reg++;
9736 } while (reg != (r3 + 1));
9737}
9738
9739static HChar *
9740s390_irgen_LAM(UChar r1, UChar r3, IRTemp op2addr)
9741{
9742 s390_irgen_load_ar_multiple(r1, r3, op2addr);
9743
9744 return "lam";
9745}
9746
9747static HChar *
9748s390_irgen_LAMY(UChar r1, UChar r3, IRTemp op2addr)
9749{
9750 s390_irgen_load_ar_multiple(r1, r3, op2addr);
9751
9752 return "lamy";
9753}
9754
9755static void
9756s390_irgen_store_ar_multiple(UChar r1, UChar r3, IRTemp op2addr)
9757{
9758 UChar reg;
9759 IRTemp addr = newTemp(Ity_I64);
9760
9761 assign(addr, mkexpr(op2addr));
9762 reg = r1;
9763 do {
9764 IRTemp old = addr;
9765
9766 reg %= 16;
9767 store(mkexpr(addr), get_ar_w0(reg));
9768 addr = newTemp(Ity_I64);
9769 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
9770 reg++;
9771 } while (reg != (r3 + 1));
9772}
9773
9774static HChar *
9775s390_irgen_STAM(UChar r1, UChar r3, IRTemp op2addr)
9776{
9777 s390_irgen_store_ar_multiple(r1, r3, op2addr);
9778
9779 return "stam";
9780}
9781
9782static HChar *
9783s390_irgen_STAMY(UChar r1, UChar r3, IRTemp op2addr)
9784{
9785 s390_irgen_store_ar_multiple(r1, r3, op2addr);
9786
9787 return "stamy";
9788}
9789
9790
9791/* Implementation for 32-bit compare-and-swap */
9792static void
9793s390_irgen_cas_32(UChar r1, UChar r3, IRTemp op2addr)
9794{
9795 IRCAS *cas;
9796 IRTemp op1 = newTemp(Ity_I32);
9797 IRTemp old_mem = newTemp(Ity_I32);
9798 IRTemp op3 = newTemp(Ity_I32);
9799 IRTemp result = newTemp(Ity_I32);
9800 IRTemp nequal = newTemp(Ity_I1);
9801
9802 assign(op1, get_gpr_w1(r1));
9803 assign(op3, get_gpr_w1(r3));
9804
9805 /* The first and second operands are compared. If they are equal,
9806 the third operand is stored at the second- operand location. */
9807 cas = mkIRCAS(IRTemp_INVALID, old_mem,
9808 Iend_BE, mkexpr(op2addr),
9809 NULL, mkexpr(op1), /* expected value */
9810 NULL, mkexpr(op3) /* new value */);
9811 stmt(IRStmt_CAS(cas));
9812
9813 /* Set CC. Operands compared equal -> 0, else 1. */
9814 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(old_mem)));
9815 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
9816
9817 /* If operands were equal (cc == 0) just store the old value op1 in r1.
9818 Otherwise, store the old_value from memory in r1 and yield. */
9819 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
9820 put_gpr_w1(r1, mkite(mkexpr(nequal), mkexpr(old_mem), mkexpr(op1)));
florian6820ba52012-07-26 02:01:50 +00009821 yield_if(mkexpr(nequal));
sewardj2019a972011-03-07 16:04:07 +00009822}
9823
9824static HChar *
9825s390_irgen_CS(UChar r1, UChar r3, IRTemp op2addr)
9826{
9827 s390_irgen_cas_32(r1, r3, op2addr);
9828
9829 return "cs";
9830}
9831
9832static HChar *
9833s390_irgen_CSY(UChar r1, UChar r3, IRTemp op2addr)
9834{
9835 s390_irgen_cas_32(r1, r3, op2addr);
9836
9837 return "csy";
9838}
9839
9840static HChar *
9841s390_irgen_CSG(UChar r1, UChar r3, IRTemp op2addr)
9842{
9843 IRCAS *cas;
9844 IRTemp op1 = newTemp(Ity_I64);
9845 IRTemp old_mem = newTemp(Ity_I64);
9846 IRTemp op3 = newTemp(Ity_I64);
9847 IRTemp result = newTemp(Ity_I64);
9848 IRTemp nequal = newTemp(Ity_I1);
9849
9850 assign(op1, get_gpr_dw0(r1));
9851 assign(op3, get_gpr_dw0(r3));
9852
9853 /* The first and second operands are compared. If they are equal,
9854 the third operand is stored at the second- operand location. */
9855 cas = mkIRCAS(IRTemp_INVALID, old_mem,
9856 Iend_BE, mkexpr(op2addr),
9857 NULL, mkexpr(op1), /* expected value */
9858 NULL, mkexpr(op3) /* new value */);
9859 stmt(IRStmt_CAS(cas));
9860
9861 /* Set CC. Operands compared equal -> 0, else 1. */
9862 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(old_mem)));
9863 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
9864
9865 /* If operands were equal (cc == 0) just store the old value op1 in r1.
9866 Otherwise, store the old_value from memory in r1 and yield. */
9867 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
9868 put_gpr_dw0(r1, mkite(mkexpr(nequal), mkexpr(old_mem), mkexpr(op1)));
florian6820ba52012-07-26 02:01:50 +00009869 yield_if(mkexpr(nequal));
sewardj2019a972011-03-07 16:04:07 +00009870
9871 return "csg";
9872}
9873
florian448cbba2012-06-06 02:26:01 +00009874/* Implementation for 32-bit compare-double-and-swap */
9875static void
9876s390_irgen_cdas_32(UChar r1, UChar r3, IRTemp op2addr)
9877{
9878 IRCAS *cas;
9879 IRTemp op1_high = newTemp(Ity_I32);
9880 IRTemp op1_low = newTemp(Ity_I32);
9881 IRTemp old_mem_high = newTemp(Ity_I32);
9882 IRTemp old_mem_low = newTemp(Ity_I32);
9883 IRTemp op3_high = newTemp(Ity_I32);
9884 IRTemp op3_low = newTemp(Ity_I32);
9885 IRTemp result = newTemp(Ity_I32);
9886 IRTemp nequal = newTemp(Ity_I1);
9887
9888 assign(op1_high, get_gpr_w1(r1));
9889 assign(op1_low, get_gpr_w1(r1+1));
9890 assign(op3_high, get_gpr_w1(r3));
9891 assign(op3_low, get_gpr_w1(r3+1));
9892
9893 /* The first and second operands are compared. If they are equal,
9894 the third operand is stored at the second-operand location. */
9895 cas = mkIRCAS(old_mem_high, old_mem_low,
9896 Iend_BE, mkexpr(op2addr),
9897 mkexpr(op1_high), mkexpr(op1_low), /* expected value */
9898 mkexpr(op3_high), mkexpr(op3_low) /* new value */);
9899 stmt(IRStmt_CAS(cas));
9900
9901 /* Set CC. Operands compared equal -> 0, else 1. */
9902 assign(result, unop(Iop_1Uto32,
9903 binop(Iop_CmpNE32,
9904 binop(Iop_Or32,
9905 binop(Iop_Xor32, mkexpr(op1_high), mkexpr(old_mem_high)),
9906 binop(Iop_Xor32, mkexpr(op1_low), mkexpr(old_mem_low))),
9907 mkU32(0))));
9908
9909 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
9910
9911 /* If operands were equal (cc == 0) just store the old value op1 in r1.
9912 Otherwise, store the old_value from memory in r1 and yield. */
9913 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
9914 put_gpr_w1(r1, mkite(mkexpr(nequal), mkexpr(old_mem_high), mkexpr(op1_high)));
9915 put_gpr_w1(r1+1, mkite(mkexpr(nequal), mkexpr(old_mem_low), mkexpr(op1_low)));
florian6820ba52012-07-26 02:01:50 +00009916 yield_if(mkexpr(nequal));
florian448cbba2012-06-06 02:26:01 +00009917}
9918
9919static HChar *
9920s390_irgen_CDS(UChar r1, UChar r3, IRTemp op2addr)
9921{
9922 s390_irgen_cdas_32(r1, r3, op2addr);
9923
9924 return "cds";
9925}
9926
9927static HChar *
9928s390_irgen_CDSY(UChar r1, UChar r3, IRTemp op2addr)
9929{
9930 s390_irgen_cdas_32(r1, r3, op2addr);
9931
9932 return "cdsy";
9933}
9934
9935static HChar *
9936s390_irgen_CDSG(UChar r1, UChar r3, IRTemp op2addr)
9937{
9938 IRCAS *cas;
9939 IRTemp op1_high = newTemp(Ity_I64);
9940 IRTemp op1_low = newTemp(Ity_I64);
9941 IRTemp old_mem_high = newTemp(Ity_I64);
9942 IRTemp old_mem_low = newTemp(Ity_I64);
9943 IRTemp op3_high = newTemp(Ity_I64);
9944 IRTemp op3_low = newTemp(Ity_I64);
9945 IRTemp result = newTemp(Ity_I64);
9946 IRTemp nequal = newTemp(Ity_I1);
9947
9948 assign(op1_high, get_gpr_dw0(r1));
9949 assign(op1_low, get_gpr_dw0(r1+1));
9950 assign(op3_high, get_gpr_dw0(r3));
9951 assign(op3_low, get_gpr_dw0(r3+1));
9952
9953 /* The first and second operands are compared. If they are equal,
9954 the third operand is stored at the second-operand location. */
9955 cas = mkIRCAS(old_mem_high, old_mem_low,
9956 Iend_BE, mkexpr(op2addr),
9957 mkexpr(op1_high), mkexpr(op1_low), /* expected value */
9958 mkexpr(op3_high), mkexpr(op3_low) /* new value */);
9959 stmt(IRStmt_CAS(cas));
9960
9961 /* Set CC. Operands compared equal -> 0, else 1. */
9962 assign(result, unop(Iop_1Uto64,
9963 binop(Iop_CmpNE64,
9964 binop(Iop_Or64,
9965 binop(Iop_Xor64, mkexpr(op1_high), mkexpr(old_mem_high)),
9966 binop(Iop_Xor64, mkexpr(op1_low), mkexpr(old_mem_low))),
9967 mkU64(0))));
9968
9969 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
9970
9971 /* If operands were equal (cc == 0) just store the old value op1 in r1.
9972 Otherwise, store the old_value from memory in r1 and yield. */
9973 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
9974 put_gpr_dw0(r1, mkite(mkexpr(nequal), mkexpr(old_mem_high), mkexpr(op1_high)));
9975 put_gpr_dw0(r1+1, mkite(mkexpr(nequal), mkexpr(old_mem_low), mkexpr(op1_low)));
florian6820ba52012-07-26 02:01:50 +00009976 yield_if(mkexpr(nequal));
9977
florian448cbba2012-06-06 02:26:01 +00009978 return "cdsg";
9979}
9980
sewardj2019a972011-03-07 16:04:07 +00009981
9982/* Binary floating point */
9983
9984static HChar *
9985s390_irgen_AXBR(UChar r1, UChar r2)
9986{
9987 IRTemp op1 = newTemp(Ity_F128);
9988 IRTemp op2 = newTemp(Ity_F128);
9989 IRTemp result = newTemp(Ity_F128);
9990
9991 assign(op1, get_fpr_pair(r1));
9992 assign(op2, get_fpr_pair(r2));
9993 assign(result, triop(Iop_AddF128, mkU32(Irrm_NEAREST), mkexpr(op1),
9994 mkexpr(op2)));
9995 put_fpr_pair(r1, mkexpr(result));
9996
9997 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
9998
9999 return "axbr";
10000}
10001
10002/* The result of a Iop_CmdFxx operation is a condition code. It is
10003 encoded using the values defined in type IRCmpFxxResult.
10004 Before we can store the condition code into the guest state (or do
10005 anything else with it for that matter) we need to convert it to
10006 the encoding that s390 uses. This is what this function does.
10007
10008 s390 VEX b6 b2 b0 cc.1 cc.0
10009 0 0x40 EQ 1 0 0 0 0
10010 1 0x01 LT 0 0 1 0 1
10011 2 0x00 GT 0 0 0 1 0
10012 3 0x45 Unordered 1 1 1 1 1
10013
10014 The following bits from the VEX encoding are interesting:
10015 b0, b2, b6 with b0 being the LSB. We observe:
10016
10017 cc.0 = b0;
10018 cc.1 = b2 | (~b0 & ~b6)
10019
10020 with cc being the s390 condition code.
10021*/
10022static IRExpr *
10023convert_vex_fpcc_to_s390(IRTemp vex_cc)
10024{
10025 IRTemp cc0 = newTemp(Ity_I32);
10026 IRTemp cc1 = newTemp(Ity_I32);
10027 IRTemp b0 = newTemp(Ity_I32);
10028 IRTemp b2 = newTemp(Ity_I32);
10029 IRTemp b6 = newTemp(Ity_I32);
10030
10031 assign(b0, binop(Iop_And32, mkexpr(vex_cc), mkU32(1)));
10032 assign(b2, binop(Iop_And32, binop(Iop_Shr32, mkexpr(vex_cc), mkU8(2)),
10033 mkU32(1)));
10034 assign(b6, binop(Iop_And32, binop(Iop_Shr32, mkexpr(vex_cc), mkU8(6)),
10035 mkU32(1)));
10036
10037 assign(cc0, mkexpr(b0));
10038 assign(cc1, binop(Iop_Or32, mkexpr(b2),
10039 binop(Iop_And32,
10040 binop(Iop_Sub32, mkU32(1), mkexpr(b0)), /* ~b0 */
10041 binop(Iop_Sub32, mkU32(1), mkexpr(b6)) /* ~b6 */
10042 )));
10043
10044 return binop(Iop_Or32, mkexpr(cc0), binop(Iop_Shl32, mkexpr(cc1), mkU8(1)));
10045}
10046
10047static HChar *
10048s390_irgen_CEBR(UChar r1, UChar r2)
10049{
10050 IRTemp op1 = newTemp(Ity_F32);
10051 IRTemp op2 = newTemp(Ity_F32);
10052 IRTemp cc_vex = newTemp(Ity_I32);
10053 IRTemp cc_s390 = newTemp(Ity_I32);
10054
10055 assign(op1, get_fpr_w0(r1));
10056 assign(op2, get_fpr_w0(r2));
10057 assign(cc_vex, binop(Iop_CmpF32, mkexpr(op1), mkexpr(op2)));
10058
10059 assign(cc_s390, convert_vex_fpcc_to_s390(cc_vex));
10060 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
10061
10062 return "cebr";
10063}
10064
10065static HChar *
10066s390_irgen_CDBR(UChar r1, UChar r2)
10067{
10068 IRTemp op1 = newTemp(Ity_F64);
10069 IRTemp op2 = newTemp(Ity_F64);
10070 IRTemp cc_vex = newTemp(Ity_I32);
10071 IRTemp cc_s390 = newTemp(Ity_I32);
10072
10073 assign(op1, get_fpr_dw0(r1));
10074 assign(op2, get_fpr_dw0(r2));
10075 assign(cc_vex, binop(Iop_CmpF64, mkexpr(op1), mkexpr(op2)));
10076
10077 assign(cc_s390, convert_vex_fpcc_to_s390(cc_vex));
10078 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
10079
10080 return "cdbr";
10081}
10082
10083static HChar *
10084s390_irgen_CXBR(UChar r1, UChar r2)
10085{
10086 IRTemp op1 = newTemp(Ity_F128);
10087 IRTemp op2 = newTemp(Ity_F128);
10088 IRTemp cc_vex = newTemp(Ity_I32);
10089 IRTemp cc_s390 = newTemp(Ity_I32);
10090
10091 assign(op1, get_fpr_pair(r1));
10092 assign(op2, get_fpr_pair(r2));
10093 assign(cc_vex, binop(Iop_CmpF128, mkexpr(op1), mkexpr(op2)));
10094
10095 assign(cc_s390, convert_vex_fpcc_to_s390(cc_vex));
10096 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
10097
10098 return "cxbr";
10099}
10100
10101static HChar *
10102s390_irgen_CEB(UChar r1, IRTemp op2addr)
10103{
10104 IRTemp op1 = newTemp(Ity_F32);
10105 IRTemp op2 = newTemp(Ity_F32);
10106 IRTemp cc_vex = newTemp(Ity_I32);
10107 IRTemp cc_s390 = newTemp(Ity_I32);
10108
10109 assign(op1, get_fpr_w0(r1));
10110 assign(op2, load(Ity_F32, mkexpr(op2addr)));
10111 assign(cc_vex, binop(Iop_CmpF32, mkexpr(op1), mkexpr(op2)));
10112
10113 assign(cc_s390, convert_vex_fpcc_to_s390(cc_vex));
10114 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
10115
10116 return "ceb";
10117}
10118
10119static HChar *
10120s390_irgen_CDB(UChar r1, IRTemp op2addr)
10121{
10122 IRTemp op1 = newTemp(Ity_F64);
10123 IRTemp op2 = newTemp(Ity_F64);
10124 IRTemp cc_vex = newTemp(Ity_I32);
10125 IRTemp cc_s390 = newTemp(Ity_I32);
10126
10127 assign(op1, get_fpr_dw0(r1));
10128 assign(op2, load(Ity_F64, mkexpr(op2addr)));
10129 assign(cc_vex, binop(Iop_CmpF64, mkexpr(op1), mkexpr(op2)));
10130
10131 assign(cc_s390, convert_vex_fpcc_to_s390(cc_vex));
10132 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
10133
10134 return "cdb";
10135}
10136
10137static HChar *
10138s390_irgen_CXFBR(UChar r1, UChar r2)
10139{
10140 IRTemp op2 = newTemp(Ity_I32);
10141
10142 assign(op2, get_gpr_w1(r2));
10143 put_fpr_pair(r1, unop(Iop_I32StoF128, mkexpr(op2)));
10144
10145 return "cxfbr";
10146}
10147
10148static HChar *
10149s390_irgen_CXGBR(UChar r1, UChar r2)
10150{
10151 IRTemp op2 = newTemp(Ity_I64);
10152
10153 assign(op2, get_gpr_dw0(r2));
10154 put_fpr_pair(r1, unop(Iop_I64StoF128, mkexpr(op2)));
10155
10156 return "cxgbr";
10157}
10158
10159static HChar *
10160s390_irgen_CFXBR(UChar r3, UChar r1, UChar r2)
10161{
10162 IRTemp op = newTemp(Ity_F128);
10163 IRTemp result = newTemp(Ity_I32);
10164
10165 assign(op, get_fpr_pair(r2));
10166 assign(result, binop(Iop_F128toI32S, mkU32(encode_rounding_mode(r3)),
10167 mkexpr(op)));
10168 put_gpr_w1(r1, mkexpr(result));
10169 s390_cc_thunk_put1f128(S390_CC_OP_BFP_128_TO_INT_32, op);
10170
10171 return "cfxbr";
10172}
10173
10174static HChar *
10175s390_irgen_CGXBR(UChar r3, UChar r1, UChar r2)
10176{
10177 IRTemp op = newTemp(Ity_F128);
10178 IRTemp result = newTemp(Ity_I64);
10179
10180 assign(op, get_fpr_pair(r2));
10181 assign(result, binop(Iop_F128toI64S, mkU32(encode_rounding_mode(r3)),
10182 mkexpr(op)));
10183 put_gpr_dw0(r1, mkexpr(result));
10184 s390_cc_thunk_put1f128(S390_CC_OP_BFP_128_TO_INT_64, op);
10185
10186 return "cgxbr";
10187}
10188
10189static HChar *
10190s390_irgen_DXBR(UChar r1, UChar r2)
10191{
10192 IRTemp op1 = newTemp(Ity_F128);
10193 IRTemp op2 = newTemp(Ity_F128);
10194 IRTemp result = newTemp(Ity_F128);
10195
10196 assign(op1, get_fpr_pair(r1));
10197 assign(op2, get_fpr_pair(r2));
10198 assign(result, triop(Iop_DivF128, mkU32(Irrm_NEAREST), mkexpr(op1),
10199 mkexpr(op2)));
10200 put_fpr_pair(r1, mkexpr(result));
10201
10202 return "dxbr";
10203}
10204
10205static HChar *
10206s390_irgen_LTXBR(UChar r1, UChar r2)
10207{
10208 IRTemp result = newTemp(Ity_F128);
10209
10210 assign(result, get_fpr_pair(r2));
10211 put_fpr_pair(r1, mkexpr(result));
10212 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
10213
10214 return "ltxbr";
10215}
10216
10217static HChar *
10218s390_irgen_LCXBR(UChar r1, UChar r2)
10219{
10220 IRTemp result = newTemp(Ity_F128);
10221
10222 assign(result, unop(Iop_NegF128, get_fpr_pair(r2)));
10223 put_fpr_pair(r1, mkexpr(result));
10224 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
10225
10226 return "lcxbr";
10227}
10228
10229static HChar *
10230s390_irgen_LXDBR(UChar r1, UChar r2)
10231{
10232 IRTemp op = newTemp(Ity_F64);
10233
10234 assign(op, get_fpr_dw0(r2));
10235 put_fpr_pair(r1, unop(Iop_F64toF128, mkexpr(op)));
10236
10237 return "lxdbr";
10238}
10239
10240static HChar *
10241s390_irgen_LXEBR(UChar r1, UChar r2)
10242{
10243 IRTemp op = newTemp(Ity_F32);
10244
10245 assign(op, get_fpr_w0(r2));
10246 put_fpr_pair(r1, unop(Iop_F32toF128, mkexpr(op)));
10247
10248 return "lxebr";
10249}
10250
10251static HChar *
10252s390_irgen_LXDB(UChar r1, IRTemp op2addr)
10253{
10254 IRTemp op = newTemp(Ity_F64);
10255
10256 assign(op, load(Ity_F64, mkexpr(op2addr)));
10257 put_fpr_pair(r1, unop(Iop_F64toF128, mkexpr(op)));
10258
10259 return "lxdb";
10260}
10261
10262static HChar *
10263s390_irgen_LXEB(UChar r1, IRTemp op2addr)
10264{
10265 IRTemp op = newTemp(Ity_F32);
10266
10267 assign(op, load(Ity_F32, mkexpr(op2addr)));
10268 put_fpr_pair(r1, unop(Iop_F32toF128, mkexpr(op)));
10269
10270 return "lxeb";
10271}
10272
10273static HChar *
10274s390_irgen_LNEBR(UChar r1, UChar r2)
10275{
10276 IRTemp result = newTemp(Ity_F32);
10277
10278 assign(result, unop(Iop_NegF32, unop(Iop_AbsF32, get_fpr_w0(r2))));
10279 put_fpr_w0(r1, mkexpr(result));
10280 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_32, result);
10281
10282 return "lnebr";
10283}
10284
10285static HChar *
10286s390_irgen_LNDBR(UChar r1, UChar r2)
10287{
10288 IRTemp result = newTemp(Ity_F64);
10289
10290 assign(result, unop(Iop_NegF64, unop(Iop_AbsF64, get_fpr_dw0(r2))));
10291 put_fpr_dw0(r1, mkexpr(result));
10292 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_64, result);
10293
10294 return "lndbr";
10295}
10296
10297static HChar *
10298s390_irgen_LNXBR(UChar r1, UChar r2)
10299{
10300 IRTemp result = newTemp(Ity_F128);
10301
10302 assign(result, unop(Iop_NegF128, unop(Iop_AbsF128, get_fpr_pair(r2))));
10303 put_fpr_pair(r1, mkexpr(result));
10304 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
10305
10306 return "lnxbr";
10307}
10308
10309static HChar *
10310s390_irgen_LPEBR(UChar r1, UChar r2)
10311{
10312 IRTemp result = newTemp(Ity_F32);
10313
10314 assign(result, unop(Iop_AbsF32, get_fpr_w0(r2)));
10315 put_fpr_w0(r1, mkexpr(result));
10316 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_32, result);
10317
10318 return "lpebr";
10319}
10320
10321static HChar *
10322s390_irgen_LPDBR(UChar r1, UChar r2)
10323{
10324 IRTemp result = newTemp(Ity_F64);
10325
10326 assign(result, unop(Iop_AbsF64, get_fpr_dw0(r2)));
10327 put_fpr_dw0(r1, mkexpr(result));
10328 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_64, result);
10329
10330 return "lpdbr";
10331}
10332
10333static HChar *
10334s390_irgen_LPXBR(UChar r1, UChar r2)
10335{
10336 IRTemp result = newTemp(Ity_F128);
10337
10338 assign(result, unop(Iop_AbsF128, get_fpr_pair(r2)));
10339 put_fpr_pair(r1, mkexpr(result));
10340 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
10341
10342 return "lpxbr";
10343}
10344
10345static HChar *
10346s390_irgen_LDXBR(UChar r1, UChar r2)
10347{
10348 IRTemp result = newTemp(Ity_F64);
10349
10350 assign(result, binop(Iop_F128toF64, mkU32(Irrm_NEAREST), get_fpr_pair(r2)));
10351 put_fpr_dw0(r1, mkexpr(result));
10352
10353 return "ldxbr";
10354}
10355
10356static HChar *
10357s390_irgen_LEXBR(UChar r1, UChar r2)
10358{
10359 IRTemp result = newTemp(Ity_F32);
10360
10361 assign(result, binop(Iop_F128toF32, mkU32(Irrm_NEAREST), get_fpr_pair(r2)));
10362 put_fpr_w0(r1, mkexpr(result));
10363
10364 return "lexbr";
10365}
10366
10367static HChar *
10368s390_irgen_MXBR(UChar r1, UChar r2)
10369{
10370 IRTemp op1 = newTemp(Ity_F128);
10371 IRTemp op2 = newTemp(Ity_F128);
10372 IRTemp result = newTemp(Ity_F128);
10373
10374 assign(op1, get_fpr_pair(r1));
10375 assign(op2, get_fpr_pair(r2));
10376 assign(result, triop(Iop_MulF128, mkU32(Irrm_NEAREST), mkexpr(op1),
10377 mkexpr(op2)));
10378 put_fpr_pair(r1, mkexpr(result));
10379
10380 return "mxbr";
10381}
10382
10383static HChar *
10384s390_irgen_MAEBR(UChar r1, UChar r3, UChar r2)
10385{
10386 put_fpr_w0(r1, qop(Iop_MAddF32, mkU32(Irrm_NEAREST),
10387 get_fpr_w0(r1), get_fpr_w0(r2), get_fpr_w0(r3)));
10388
10389 return "maebr";
10390}
10391
10392static HChar *
10393s390_irgen_MADBR(UChar r1, UChar r3, UChar r2)
10394{
10395 put_fpr_dw0(r1, qop(Iop_MAddF64, mkU32(Irrm_NEAREST),
10396 get_fpr_dw0(r1), get_fpr_dw0(r2), get_fpr_dw0(r3)));
10397
10398 return "madbr";
10399}
10400
10401static HChar *
10402s390_irgen_MAEB(UChar r3, IRTemp op2addr, UChar r1)
10403{
10404 IRExpr *op2 = load(Ity_F32, mkexpr(op2addr));
10405
10406 put_fpr_w0(r1, qop(Iop_MAddF32, mkU32(Irrm_NEAREST),
10407 get_fpr_w0(r1), op2, get_fpr_w0(r3)));
10408
10409 return "maeb";
10410}
10411
10412static HChar *
10413s390_irgen_MADB(UChar r3, IRTemp op2addr, UChar r1)
10414{
10415 IRExpr *op2 = load(Ity_F64, mkexpr(op2addr));
10416
10417 put_fpr_dw0(r1, qop(Iop_MAddF64, mkU32(Irrm_NEAREST),
10418 get_fpr_dw0(r1), op2, get_fpr_dw0(r3)));
10419
10420 return "madb";
10421}
10422
10423static HChar *
10424s390_irgen_MSEBR(UChar r1, UChar r3, UChar r2)
10425{
10426 put_fpr_w0(r1, qop(Iop_MSubF32, mkU32(Irrm_NEAREST),
10427 get_fpr_w0(r1), get_fpr_w0(r2), get_fpr_w0(r3)));
10428
10429 return "msebr";
10430}
10431
10432static HChar *
10433s390_irgen_MSDBR(UChar r1, UChar r3, UChar r2)
10434{
10435 put_fpr_dw0(r1, qop(Iop_MSubF64, mkU32(Irrm_NEAREST),
10436 get_fpr_dw0(r1), get_fpr_dw0(r2), get_fpr_dw0(r3)));
10437
10438 return "msdbr";
10439}
10440
10441static HChar *
10442s390_irgen_MSEB(UChar r3, IRTemp op2addr, UChar r1)
10443{
10444 IRExpr *op2 = load(Ity_F32, mkexpr(op2addr));
10445
10446 put_fpr_w0(r1, qop(Iop_MSubF32, mkU32(Irrm_NEAREST),
10447 get_fpr_w0(r1), op2, get_fpr_w0(r3)));
10448
10449 return "mseb";
10450}
10451
10452static HChar *
10453s390_irgen_MSDB(UChar r3, IRTemp op2addr, UChar r1)
10454{
10455 IRExpr *op2 = load(Ity_F64, mkexpr(op2addr));
10456
10457 put_fpr_dw0(r1, qop(Iop_MSubF64, mkU32(Irrm_NEAREST),
10458 get_fpr_dw0(r1), op2, get_fpr_dw0(r3)));
10459
10460 return "msdb";
10461}
10462
10463static HChar *
10464s390_irgen_SQEBR(UChar r1, UChar r2)
10465{
10466 IRTemp result = newTemp(Ity_F32);
10467
10468 assign(result, binop(Iop_SqrtF32, mkU32(Irrm_NEAREST), get_fpr_w0(r2)));
10469 put_fpr_w0(r1, mkexpr(result));
10470
10471 return "sqebr";
10472}
10473
10474static HChar *
10475s390_irgen_SQDBR(UChar r1, UChar r2)
10476{
10477 IRTemp result = newTemp(Ity_F64);
10478
10479 assign(result, binop(Iop_SqrtF64, mkU32(Irrm_NEAREST), get_fpr_dw0(r2)));
10480 put_fpr_dw0(r1, mkexpr(result));
10481
10482 return "sqdbr";
10483}
10484
10485static HChar *
10486s390_irgen_SQXBR(UChar r1, UChar r2)
10487{
10488 IRTemp result = newTemp(Ity_F128);
10489
10490 assign(result, binop(Iop_SqrtF128, mkU32(Irrm_NEAREST), get_fpr_pair(r2)));
10491 put_fpr_pair(r1, mkexpr(result));
10492
10493 return "sqxbr";
10494}
10495
10496static HChar *
10497s390_irgen_SQEB(UChar r1, IRTemp op2addr)
10498{
10499 IRTemp op = newTemp(Ity_F32);
10500
10501 assign(op, load(Ity_F32, mkexpr(op2addr)));
10502 put_fpr_w0(r1, binop(Iop_SqrtF32, mkU32(Irrm_NEAREST), mkexpr(op)));
10503
10504 return "sqeb";
10505}
10506
10507static HChar *
10508s390_irgen_SQDB(UChar r1, IRTemp op2addr)
10509{
10510 IRTemp op = newTemp(Ity_F64);
10511
10512 assign(op, load(Ity_F64, mkexpr(op2addr)));
10513 put_fpr_dw0(r1, binop(Iop_SqrtF64, mkU32(Irrm_NEAREST), mkexpr(op)));
10514
10515 return "sqdb";
10516}
10517
10518static HChar *
10519s390_irgen_SXBR(UChar r1, UChar r2)
10520{
10521 IRTemp op1 = newTemp(Ity_F128);
10522 IRTemp op2 = newTemp(Ity_F128);
10523 IRTemp result = newTemp(Ity_F128);
10524
10525 assign(op1, get_fpr_pair(r1));
10526 assign(op2, get_fpr_pair(r2));
10527 assign(result, triop(Iop_SubF128, mkU32(Irrm_NEAREST), mkexpr(op1),
10528 mkexpr(op2)));
10529 put_fpr_pair(r1, mkexpr(result));
10530 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
10531
10532 return "sxbr";
10533}
10534
10535static HChar *
10536s390_irgen_TCEB(UChar r1, IRTemp op2addr)
10537{
10538 IRTemp value = newTemp(Ity_F32);
10539
10540 assign(value, get_fpr_w0(r1));
10541
10542 s390_cc_thunk_putFZ(S390_CC_OP_BFP_TDC_32, value, op2addr);
10543
10544 return "tceb";
10545}
10546
10547static HChar *
10548s390_irgen_TCDB(UChar r1, IRTemp op2addr)
10549{
10550 IRTemp value = newTemp(Ity_F64);
10551
10552 assign(value, get_fpr_dw0(r1));
10553
10554 s390_cc_thunk_putFZ(S390_CC_OP_BFP_TDC_64, value, op2addr);
10555
10556 return "tcdb";
10557}
10558
10559static HChar *
10560s390_irgen_TCXB(UChar r1, IRTemp op2addr)
10561{
10562 IRTemp value = newTemp(Ity_F128);
10563
10564 assign(value, get_fpr_pair(r1));
10565
10566 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_TDC_128, value, op2addr);
10567
10568 return "tcxb";
10569}
10570
10571static HChar *
10572s390_irgen_LCDFR(UChar r1, UChar r2)
10573{
10574 IRTemp result = newTemp(Ity_F64);
10575
10576 assign(result, unop(Iop_NegF64, get_fpr_dw0(r2)));
10577 put_fpr_dw0(r1, mkexpr(result));
10578
10579 return "lcdfr";
10580}
10581
10582static HChar *
10583s390_irgen_LNDFR(UChar r1, UChar r2)
10584{
10585 IRTemp result = newTemp(Ity_F64);
10586
10587 assign(result, unop(Iop_NegF64, unop(Iop_AbsF64, get_fpr_dw0(r2))));
10588 put_fpr_dw0(r1, mkexpr(result));
10589
10590 return "lndfr";
10591}
10592
10593static HChar *
10594s390_irgen_LPDFR(UChar r1, UChar r2)
10595{
10596 IRTemp result = newTemp(Ity_F64);
10597
10598 assign(result, unop(Iop_AbsF64, get_fpr_dw0(r2)));
10599 put_fpr_dw0(r1, mkexpr(result));
10600
10601 return "lpdfr";
10602}
10603
10604static HChar *
10605s390_irgen_LDGR(UChar r1, UChar r2)
10606{
10607 put_fpr_dw0(r1, unop(Iop_ReinterpI64asF64, get_gpr_dw0(r2)));
10608
10609 return "ldgr";
10610}
10611
10612static HChar *
10613s390_irgen_LGDR(UChar r1, UChar r2)
10614{
10615 put_gpr_dw0(r1, unop(Iop_ReinterpF64asI64, get_fpr_dw0(r2)));
10616
10617 return "lgdr";
10618}
10619
10620
10621static HChar *
10622s390_irgen_CPSDR(UChar r3, UChar r1, UChar r2)
10623{
10624 IRTemp sign = newTemp(Ity_I64);
10625 IRTemp value = newTemp(Ity_I64);
10626
10627 assign(sign, binop(Iop_And64, unop(Iop_ReinterpF64asI64, get_fpr_dw0(r3)),
10628 mkU64(1ULL << 63)));
10629 assign(value, binop(Iop_And64, unop(Iop_ReinterpF64asI64, get_fpr_dw0(r2)),
10630 mkU64((1ULL << 63) - 1)));
10631 put_fpr_dw0(r1, unop(Iop_ReinterpI64asF64, binop(Iop_Or64, mkexpr(value),
10632 mkexpr(sign))));
10633
10634 return "cpsdr";
10635}
10636
10637
sewardj2019a972011-03-07 16:04:07 +000010638static IRExpr *
10639s390_call_cvb(IRExpr *in)
10640{
10641 IRExpr **args, *call;
10642
10643 args = mkIRExprVec_1(in);
10644 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
10645 "s390_do_cvb", &s390_do_cvb, args);
10646
10647 /* Nothing is excluded from definedness checking. */
10648 call->Iex.CCall.cee->mcx_mask = 0;
10649
10650 return call;
10651}
10652
10653static HChar *
10654s390_irgen_CVB(UChar r1, IRTemp op2addr)
10655{
10656 put_gpr_w1(r1, s390_call_cvb(load(Ity_I64, mkexpr(op2addr))));
10657
10658 return "cvb";
10659}
10660
10661static HChar *
10662s390_irgen_CVBY(UChar r1, IRTemp op2addr)
10663{
10664 put_gpr_w1(r1, s390_call_cvb(load(Ity_I64, mkexpr(op2addr))));
10665
10666 return "cvby";
10667}
10668
10669
sewardj2019a972011-03-07 16:04:07 +000010670static IRExpr *
10671s390_call_cvd(IRExpr *in)
10672{
10673 IRExpr **args, *call;
10674
10675 args = mkIRExprVec_1(in);
10676 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
10677 "s390_do_cvd", &s390_do_cvd, args);
10678
10679 /* Nothing is excluded from definedness checking. */
10680 call->Iex.CCall.cee->mcx_mask = 0;
10681
10682 return call;
10683}
10684
10685static HChar *
10686s390_irgen_CVD(UChar r1, IRTemp op2addr)
10687{
florian11b8ee82012-08-06 13:35:33 +000010688 store(mkexpr(op2addr), s390_call_cvd(unop(Iop_32Uto64, get_gpr_w1(r1))));
sewardj2019a972011-03-07 16:04:07 +000010689
10690 return "cvd";
10691}
10692
10693static HChar *
10694s390_irgen_CVDY(UChar r1, IRTemp op2addr)
10695{
10696 store(mkexpr(op2addr), s390_call_cvd(get_gpr_w1(r1)));
10697
10698 return "cvdy";
10699}
10700
10701static HChar *
10702s390_irgen_FLOGR(UChar r1, UChar r2)
10703{
10704 IRTemp input = newTemp(Ity_I64);
10705 IRTemp not_zero = newTemp(Ity_I64);
10706 IRTemp tmpnum = newTemp(Ity_I64);
10707 IRTemp num = newTemp(Ity_I64);
10708 IRTemp shift_amount = newTemp(Ity_I8);
10709
10710 /* We use the "count leading zeroes" operator because the number of
10711 leading zeroes is identical with the bit position of the first '1' bit.
10712 However, that operator does not work when the input value is zero.
10713 Therefore, we set the LSB of the input value to 1 and use Clz64 on
10714 the modified value. If input == 0, then the result is 64. Otherwise,
10715 the result of Clz64 is what we want. */
10716
10717 assign(input, get_gpr_dw0(r2));
10718 assign(not_zero, binop(Iop_Or64, mkexpr(input), mkU64(1)));
10719 assign(tmpnum, unop(Iop_Clz64, mkexpr(not_zero)));
10720
10721 /* num = (input == 0) ? 64 : tmpnum */
10722 assign(num, mkite(binop(Iop_CmpEQ64, mkexpr(input), mkU64(0)),
10723 /* == 0 */ mkU64(64),
10724 /* != 0 */ mkexpr(tmpnum)));
10725
10726 put_gpr_dw0(r1, mkexpr(num));
10727
10728 /* Set the leftmost '1' bit of the input value to zero. The general scheme
10729 is to first shift the input value by NUM + 1 bits to the left which
10730 causes the leftmost '1' bit to disappear. Then we shift logically to
10731 the right by NUM + 1 bits. Because the semantics of Iop_Shl64 and
10732 Iop_Shr64 are undefined if the shift-amount is greater than or equal to
10733 the width of the value-to-be-shifted, we need to special case
10734 NUM + 1 >= 64. This is equivalent to INPUT != 0 && INPUT != 1.
10735 For both such INPUT values the result will be 0. */
10736
10737 assign(shift_amount, unop(Iop_64to8, binop(Iop_Add64, mkexpr(num),
10738 mkU64(1))));
10739
10740 put_gpr_dw0(r1 + 1,
florian6ad49522011-09-09 02:38:55 +000010741 mkite(binop(Iop_CmpLE64U, mkexpr(input), mkU64(1)),
10742 /* == 0 || == 1*/ mkU64(0),
10743 /* otherwise */
10744 binop(Iop_Shr64,
10745 binop(Iop_Shl64, mkexpr(input),
10746 mkexpr(shift_amount)),
10747 mkexpr(shift_amount))));
sewardj2019a972011-03-07 16:04:07 +000010748
10749 /* Compare the original value as an unsigned integer with 0. */
10750 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, input,
10751 mktemp(Ity_I64, mkU64(0)), False);
10752
10753 return "flogr";
10754}
10755
sewardj1e5fea62011-05-17 16:18:36 +000010756static HChar *
10757s390_irgen_STCK(IRTemp op2addr)
10758{
10759 IRDirty *d;
10760 IRTemp cc = newTemp(Ity_I64);
10761
10762 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STCK",
10763 &s390x_dirtyhelper_STCK,
10764 mkIRExprVec_1(mkexpr(op2addr)));
10765 d->mFx = Ifx_Write;
10766 d->mAddr = mkexpr(op2addr);
10767 d->mSize = 8;
10768 stmt(IRStmt_Dirty(d));
10769 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
10770 mkexpr(cc), mkU64(0), mkU64(0));
10771 return "stck";
10772}
10773
10774static HChar *
10775s390_irgen_STCKF(IRTemp op2addr)
10776{
florianc5c669b2012-08-26 14:32:28 +000010777 if (! s390_host_has_stckf) {
10778 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_EMNOTE),
10779 mkU32(EmFail_S390X_stckf)));
10780 put_IA(mkaddr_expr(guest_IA_next_instr));
10781 dis_res->whatNext = Dis_StopHere;
10782 dis_res->jk_StopHere = Ijk_EmFail;
10783 } else {
10784 IRTemp cc = newTemp(Ity_I64);
sewardj1e5fea62011-05-17 16:18:36 +000010785
florianc5c669b2012-08-26 14:32:28 +000010786 IRDirty *d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STCKF",
10787 &s390x_dirtyhelper_STCKF,
10788 mkIRExprVec_1(mkexpr(op2addr)));
10789 d->mFx = Ifx_Write;
10790 d->mAddr = mkexpr(op2addr);
10791 d->mSize = 8;
10792 stmt(IRStmt_Dirty(d));
10793 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
10794 mkexpr(cc), mkU64(0), mkU64(0));
10795 }
sewardj1e5fea62011-05-17 16:18:36 +000010796 return "stckf";
10797}
10798
10799static HChar *
10800s390_irgen_STCKE(IRTemp op2addr)
10801{
10802 IRDirty *d;
10803 IRTemp cc = newTemp(Ity_I64);
10804
10805 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STCKE",
10806 &s390x_dirtyhelper_STCKE,
10807 mkIRExprVec_1(mkexpr(op2addr)));
10808 d->mFx = Ifx_Write;
10809 d->mAddr = mkexpr(op2addr);
10810 d->mSize = 16;
10811 stmt(IRStmt_Dirty(d));
10812 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
10813 mkexpr(cc), mkU64(0), mkU64(0));
10814 return "stcke";
10815}
10816
florian933065d2011-07-11 01:48:02 +000010817static HChar *
10818s390_irgen_STFLE(IRTemp op2addr)
10819{
florian4e0083e2012-08-26 03:41:56 +000010820 if (! s390_host_has_stfle) {
10821 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_EMNOTE),
10822 mkU32(EmFail_S390X_stfle)));
10823 put_IA(mkaddr_expr(guest_IA_next_instr));
10824 dis_res->whatNext = Dis_StopHere;
10825 dis_res->jk_StopHere = Ijk_EmFail;
10826 return "stfle";
10827 }
10828
florian933065d2011-07-11 01:48:02 +000010829 IRDirty *d;
10830 IRTemp cc = newTemp(Ity_I64);
10831
10832 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STFLE",
10833 &s390x_dirtyhelper_STFLE,
10834 mkIRExprVec_1(mkexpr(op2addr)));
10835
10836 d->needsBBP = 1; /* Need to pass pointer to guest state to helper */
10837
sewardjc9069f22012-06-01 16:09:50 +000010838 d->nFxState = 1;
10839 vex_bzero(&d->fxState, sizeof(d->fxState));
10840
florian933065d2011-07-11 01:48:02 +000010841 d->fxState[0].fx = Ifx_Modify; /* read then write */
10842 d->fxState[0].offset = S390X_GUEST_OFFSET(guest_r0);
10843 d->fxState[0].size = sizeof(ULong);
florian933065d2011-07-11 01:48:02 +000010844
10845 d->mAddr = mkexpr(op2addr);
10846 /* Pretend all double words are written */
10847 d->mSize = S390_NUM_FACILITY_DW * sizeof(ULong);
10848 d->mFx = Ifx_Write;
10849
10850 stmt(IRStmt_Dirty(d));
10851
10852 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET), mkexpr(cc), mkU64(0), mkU64(0));
10853
10854 return "stfle";
10855}
10856
floriana4384a32011-08-11 16:58:45 +000010857static HChar *
10858s390_irgen_CKSM(UChar r1,UChar r2)
10859{
10860 IRTemp addr = newTemp(Ity_I64);
10861 IRTemp op = newTemp(Ity_I32);
10862 IRTemp len = newTemp(Ity_I64);
10863 IRTemp oldval = newTemp(Ity_I32);
10864 IRTemp mask = newTemp(Ity_I32);
10865 IRTemp newop = newTemp(Ity_I32);
10866 IRTemp result = newTemp(Ity_I32);
10867 IRTemp result1 = newTemp(Ity_I32);
10868 IRTemp inc = newTemp(Ity_I64);
10869
10870 assign(oldval, get_gpr_w1(r1));
10871 assign(addr, get_gpr_dw0(r2));
10872 assign(len, get_gpr_dw0(r2+1));
10873
10874 /* Condition code is always zero. */
10875 s390_cc_set(0);
10876
10877 /* If length is zero, there is no need to calculate the checksum */
florian6820ba52012-07-26 02:01:50 +000010878 next_insn_if(binop(Iop_CmpEQ64, mkexpr(len), mkU64(0)));
floriana4384a32011-08-11 16:58:45 +000010879
10880 /* Assiging the increment variable to adjust address and length
10881 later on. */
10882 assign(inc, mkite(binop(Iop_CmpLT64U, mkexpr(len), mkU64(4)),
10883 mkexpr(len), mkU64(4)));
10884
10885 /* If length < 4 the final 4-byte 2nd operand value is computed by
10886 appending the remaining bytes to the right with 0. This is done
10887 by AND'ing the 4 bytes loaded from memory with an appropriate
10888 mask. If length >= 4, that mask is simply 0xffffffff. */
10889
10890 assign(mask, mkite(binop(Iop_CmpLT64U, mkexpr(len), mkU64(4)),
10891 /* Mask computation when len < 4:
10892 0xffffffff << (32 - (len % 4)*8) */
10893 binop(Iop_Shl32, mkU32(0xffffffff),
10894 unop(Iop_32to8,
10895 binop(Iop_Sub32, mkU32(32),
10896 binop(Iop_Shl32,
10897 unop(Iop_64to32,
10898 binop(Iop_And64,
10899 mkexpr(len), mkU64(3))),
10900 mkU8(3))))),
10901 mkU32(0xffffffff)));
10902
10903 assign(op, load(Ity_I32, mkexpr(addr)));
10904 assign(newop, binop(Iop_And32, mkexpr(op), mkexpr(mask)));
10905 assign(result, binop(Iop_Add32, mkexpr(newop), mkexpr(oldval)));
10906
10907 /* Checking for carry */
10908 assign(result1, mkite(binop(Iop_CmpLT32U, mkexpr(result), mkexpr(newop)),
10909 binop(Iop_Add32, mkexpr(result), mkU32(1)),
10910 mkexpr(result)));
10911
10912 put_gpr_w1(r1, mkexpr(result1));
10913 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr), mkexpr(inc)));
10914 put_gpr_dw0(r2+1, binop(Iop_Sub64, mkexpr(len), mkexpr(inc)));
10915
florian6820ba52012-07-26 02:01:50 +000010916 iterate_if(binop(Iop_CmpNE64, mkexpr(len), mkU64(0)));
floriana4384a32011-08-11 16:58:45 +000010917
10918 return "cksm";
10919}
10920
florian9af37692012-01-15 21:01:16 +000010921static HChar *
10922s390_irgen_TROO(UChar m3, UChar r1, UChar r2)
10923{
10924 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
10925 src_addr = newTemp(Ity_I64);
10926 des_addr = newTemp(Ity_I64);
10927 tab_addr = newTemp(Ity_I64);
10928 test_byte = newTemp(Ity_I8);
10929 src_len = newTemp(Ity_I64);
10930
10931 assign(src_addr, get_gpr_dw0(r2));
10932 assign(des_addr, get_gpr_dw0(r1));
10933 assign(tab_addr, get_gpr_dw0(1));
florian53518532012-01-18 14:00:31 +000010934 assign(src_len, get_gpr_dw0(r1+1));
florian9af37692012-01-15 21:01:16 +000010935 assign(test_byte, get_gpr_b7(0));
10936
10937 IRTemp op = newTemp(Ity_I8);
10938 IRTemp op1 = newTemp(Ity_I8);
10939 IRTemp result = newTemp(Ity_I64);
10940
10941 /* End of source string? We're done; proceed to next insn */
10942 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000010943 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian9af37692012-01-15 21:01:16 +000010944
10945 /* Load character from source string, index translation table and
10946 store translated character in op1. */
10947 assign(op, load(Ity_I8, mkexpr(src_addr)));
10948
10949 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)),
10950 mkexpr(tab_addr)));
10951 assign(op1, load(Ity_I8, mkexpr(result)));
10952
10953 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
10954 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000010955 next_insn_if(binop(Iop_CmpEQ8, mkexpr(op1), mkexpr(test_byte)));
florian9af37692012-01-15 21:01:16 +000010956 }
10957 store(get_gpr_dw0(r1), mkexpr(op1));
10958
10959 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(1)));
10960 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(1)));
10961 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(1)));
10962
florian6820ba52012-07-26 02:01:50 +000010963 iterate();
florian9af37692012-01-15 21:01:16 +000010964
10965 return "troo";
10966}
10967
florian730448f2012-02-04 17:07:07 +000010968static HChar *
10969s390_irgen_TRTO(UChar m3, UChar r1, UChar r2)
10970{
10971 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
10972 src_addr = newTemp(Ity_I64);
10973 des_addr = newTemp(Ity_I64);
10974 tab_addr = newTemp(Ity_I64);
10975 test_byte = newTemp(Ity_I8);
10976 src_len = newTemp(Ity_I64);
10977
10978 assign(src_addr, get_gpr_dw0(r2));
10979 assign(des_addr, get_gpr_dw0(r1));
10980 assign(tab_addr, get_gpr_dw0(1));
10981 assign(src_len, get_gpr_dw0(r1+1));
10982 assign(test_byte, get_gpr_b7(0));
10983
10984 IRTemp op = newTemp(Ity_I16);
10985 IRTemp op1 = newTemp(Ity_I8);
10986 IRTemp result = newTemp(Ity_I64);
10987
10988 /* End of source string? We're done; proceed to next insn */
10989 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000010990 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian730448f2012-02-04 17:07:07 +000010991
10992 /* Load character from source string, index translation table and
10993 store translated character in op1. */
10994 assign(op, load(Ity_I16, mkexpr(src_addr)));
10995
10996 assign(result, binop(Iop_Add64, unop(Iop_16Uto64, mkexpr(op)),
10997 mkexpr(tab_addr)));
10998
10999 assign(op1, load(Ity_I8, mkexpr(result)));
11000
11001 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
11002 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000011003 next_insn_if(binop(Iop_CmpEQ8, mkexpr(op1), mkexpr(test_byte)));
florian730448f2012-02-04 17:07:07 +000011004 }
11005 store(get_gpr_dw0(r1), mkexpr(op1));
11006
11007 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(2)));
11008 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(1)));
11009 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(2)));
11010
florian6820ba52012-07-26 02:01:50 +000011011 iterate();
florian730448f2012-02-04 17:07:07 +000011012
11013 return "trto";
11014}
11015
11016static HChar *
11017s390_irgen_TROT(UChar m3, UChar r1, UChar r2)
11018{
11019 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
11020 src_addr = newTemp(Ity_I64);
11021 des_addr = newTemp(Ity_I64);
11022 tab_addr = newTemp(Ity_I64);
11023 test_byte = newTemp(Ity_I16);
11024 src_len = newTemp(Ity_I64);
11025
11026 assign(src_addr, get_gpr_dw0(r2));
11027 assign(des_addr, get_gpr_dw0(r1));
11028 assign(tab_addr, get_gpr_dw0(1));
11029 assign(src_len, get_gpr_dw0(r1+1));
11030 assign(test_byte, get_gpr_hw3(0));
11031
11032 IRTemp op = newTemp(Ity_I8);
11033 IRTemp op1 = newTemp(Ity_I16);
11034 IRTemp result = newTemp(Ity_I64);
11035
11036 /* End of source string? We're done; proceed to next insn */
11037 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000011038 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian730448f2012-02-04 17:07:07 +000011039
11040 /* Load character from source string, index translation table and
11041 store translated character in op1. */
11042 assign(op, binop(Iop_Shl8, load(Ity_I8, mkexpr(src_addr)), mkU8(1)));
11043
11044 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)),
11045 mkexpr(tab_addr)));
11046 assign(op1, load(Ity_I16, mkexpr(result)));
11047
11048 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
11049 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000011050 next_insn_if(binop(Iop_CmpEQ16, mkexpr(op1), mkexpr(test_byte)));
florian730448f2012-02-04 17:07:07 +000011051 }
11052 store(get_gpr_dw0(r1), mkexpr(op1));
11053
11054 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(1)));
11055 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(2)));
11056 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(1)));
11057
florian6820ba52012-07-26 02:01:50 +000011058 iterate();
florian730448f2012-02-04 17:07:07 +000011059
11060 return "trot";
11061}
11062
11063static HChar *
11064s390_irgen_TRTT(UChar m3, UChar r1, UChar r2)
11065{
11066 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
11067 src_addr = newTemp(Ity_I64);
11068 des_addr = newTemp(Ity_I64);
11069 tab_addr = newTemp(Ity_I64);
11070 test_byte = newTemp(Ity_I16);
11071 src_len = newTemp(Ity_I64);
11072
11073 assign(src_addr, get_gpr_dw0(r2));
11074 assign(des_addr, get_gpr_dw0(r1));
11075 assign(tab_addr, get_gpr_dw0(1));
11076 assign(src_len, get_gpr_dw0(r1+1));
11077 assign(test_byte, get_gpr_hw3(0));
11078
11079 IRTemp op = newTemp(Ity_I16);
11080 IRTemp op1 = newTemp(Ity_I16);
11081 IRTemp result = newTemp(Ity_I64);
11082
11083 /* End of source string? We're done; proceed to next insn */
11084 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000011085 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian730448f2012-02-04 17:07:07 +000011086
11087 /* Load character from source string, index translation table and
11088 store translated character in op1. */
11089 assign(op, binop(Iop_Shl16, load(Ity_I16, mkexpr(src_addr)), mkU8(1)));
11090
11091 assign(result, binop(Iop_Add64, unop(Iop_16Uto64, mkexpr(op)),
11092 mkexpr(tab_addr)));
11093 assign(op1, load(Ity_I16, mkexpr(result)));
11094
11095 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
11096 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000011097 next_insn_if(binop(Iop_CmpEQ16, mkexpr(op1), mkexpr(test_byte)));
florian730448f2012-02-04 17:07:07 +000011098 }
11099
11100 store(get_gpr_dw0(r1), mkexpr(op1));
11101
11102 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(2)));
11103 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(2)));
11104 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(2)));
11105
florian6820ba52012-07-26 02:01:50 +000011106 iterate();
florian730448f2012-02-04 17:07:07 +000011107
11108 return "trtt";
11109}
11110
11111static HChar *
11112s390_irgen_TR(UChar length, IRTemp start1, IRTemp start2)
11113{
florianf87d4fb2012-05-05 02:55:24 +000011114 IRTemp len = newTemp(Ity_I64);
florian730448f2012-02-04 17:07:07 +000011115
florianf87d4fb2012-05-05 02:55:24 +000011116 assign(len, mkU64(length));
11117 s390_irgen_TR_EX(len, start1, start2);
florian730448f2012-02-04 17:07:07 +000011118
11119 return "tr";
11120}
11121
11122static HChar *
11123s390_irgen_TRE(UChar r1,UChar r2)
11124{
11125 IRTemp src_addr, tab_addr, src_len, test_byte;
11126 src_addr = newTemp(Ity_I64);
11127 tab_addr = newTemp(Ity_I64);
11128 src_len = newTemp(Ity_I64);
11129 test_byte = newTemp(Ity_I8);
11130
11131 assign(src_addr, get_gpr_dw0(r1));
11132 assign(src_len, get_gpr_dw0(r1+1));
11133 assign(tab_addr, get_gpr_dw0(r2));
11134 assign(test_byte, get_gpr_b7(0));
11135
11136 IRTemp op = newTemp(Ity_I8);
11137 IRTemp op1 = newTemp(Ity_I8);
11138 IRTemp result = newTemp(Ity_I64);
11139
11140 /* End of source string? We're done; proceed to next insn */
11141 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000011142 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian730448f2012-02-04 17:07:07 +000011143
11144 /* Load character from source string and compare with test byte */
11145 assign(op, load(Ity_I8, mkexpr(src_addr)));
11146
11147 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000011148 next_insn_if(binop(Iop_CmpEQ8, mkexpr(op), mkexpr(test_byte)));
florian730448f2012-02-04 17:07:07 +000011149
11150 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)),
11151 mkexpr(tab_addr)));
11152
11153 assign(op1, load(Ity_I8, mkexpr(result)));
11154
11155 store(get_gpr_dw0(r1), mkexpr(op1));
11156 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(src_addr), mkU64(1)));
11157 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(1)));
11158
florian6820ba52012-07-26 02:01:50 +000011159 iterate();
florian730448f2012-02-04 17:07:07 +000011160
11161 return "tre";
11162}
11163
floriana0100c92012-07-20 00:06:35 +000011164static IRExpr *
11165s390_call_cu21(IRExpr *srcval, IRExpr *low_surrogate)
11166{
11167 IRExpr **args, *call;
11168 args = mkIRExprVec_2(srcval, low_surrogate);
11169 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
11170 "s390_do_cu21", &s390_do_cu21, args);
11171
11172 /* Nothing is excluded from definedness checking. */
11173 call->Iex.CCall.cee->mcx_mask = 0;
11174
11175 return call;
11176}
11177
11178static HChar *
11179s390_irgen_CU21(UChar m3, UChar r1, UChar r2)
11180{
11181 IRTemp addr1 = newTemp(Ity_I64);
11182 IRTemp addr2 = newTemp(Ity_I64);
11183 IRTemp len1 = newTemp(Ity_I64);
11184 IRTemp len2 = newTemp(Ity_I64);
11185
11186 assign(addr1, get_gpr_dw0(r1));
11187 assign(addr2, get_gpr_dw0(r2));
11188 assign(len1, get_gpr_dw0(r1 + 1));
11189 assign(len2, get_gpr_dw0(r2 + 1));
11190
11191 /* We're processing the 2nd operand 2 bytes at a time. Therefore, if
11192 there are less than 2 bytes left, then the 2nd operand is exhausted
11193 and we're done here. cc = 0 */
11194 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000011195 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(2)));
floriana0100c92012-07-20 00:06:35 +000011196
11197 /* There are at least two bytes there. Read them. */
11198 IRTemp srcval = newTemp(Ity_I32);
11199 assign(srcval, unop(Iop_16Uto32, load(Ity_I16, mkexpr(addr2))));
11200
11201 /* Find out whether this is a high surrogate. I.e. SRCVAL lies
11202 inside the interval [0xd800 - 0xdbff] */
11203 IRTemp is_high_surrogate = newTemp(Ity_I32);
11204 IRExpr *flag1 = mkite(binop(Iop_CmpLE32U, mkU32(0xd800), mkexpr(srcval)),
11205 mkU32(1), mkU32(0));
11206 IRExpr *flag2 = mkite(binop(Iop_CmpLE32U, mkexpr(srcval), mkU32(0xdbff)),
11207 mkU32(1), mkU32(0));
11208 assign(is_high_surrogate, binop(Iop_And32, flag1, flag2));
11209
11210 /* If SRCVAL is a high surrogate and there are less than 4 bytes left,
11211 then the 2nd operand is exhausted and we're done here. cc = 0 */
11212 IRExpr *not_enough_bytes =
11213 mkite(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)), mkU32(1), mkU32(0));
11214
florian6820ba52012-07-26 02:01:50 +000011215 next_insn_if(binop(Iop_CmpEQ32,
11216 binop(Iop_And32, mkexpr(is_high_surrogate),
11217 not_enough_bytes), mkU32(1)));
floriana0100c92012-07-20 00:06:35 +000011218
11219 /* The 2nd operand is not exhausted. If the first 2 bytes are a high
11220 surrogate, read the next two bytes (low surrogate). */
11221 IRTemp low_surrogate = newTemp(Ity_I32);
11222 IRExpr *low_surrogate_addr = binop(Iop_Add64, mkexpr(addr2), mkU64(2));
11223
11224 assign(low_surrogate,
11225 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
11226 unop(Iop_16Uto32, load(Ity_I16, low_surrogate_addr)),
11227 mkU32(0))); // any value is fine; it will not be used
11228
11229 /* Call the helper */
11230 IRTemp retval = newTemp(Ity_I64);
florian11b8ee82012-08-06 13:35:33 +000011231 assign(retval, s390_call_cu21(unop(Iop_32Uto64, mkexpr(srcval)),
11232 unop(Iop_32Uto64, mkexpr(low_surrogate))));
floriana0100c92012-07-20 00:06:35 +000011233
11234 /* Before we can test whether the 1st operand is exhausted we need to
11235 test for an invalid low surrogate. Because cc=2 outranks cc=1. */
11236 if (s390_host_has_etf3 && (m3 & 0x1) == 1) {
11237 IRExpr *invalid_low_surrogate =
11238 binop(Iop_And64, mkexpr(retval), mkU64(0xff));
11239
11240 s390_cc_set(2);
florian6820ba52012-07-26 02:01:50 +000011241 next_insn_if(binop(Iop_CmpEQ64, invalid_low_surrogate, mkU64(1)));
floriana0100c92012-07-20 00:06:35 +000011242 }
11243
11244 /* Now test whether the 1st operand is exhausted */
11245 IRTemp num_bytes = newTemp(Ity_I64);
11246 assign(num_bytes, binop(Iop_And64,
11247 binop(Iop_Shr64, mkexpr(retval), mkU8(8)),
11248 mkU64(0xff)));
11249 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000011250 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
floriana0100c92012-07-20 00:06:35 +000011251
11252 /* Extract the bytes to be stored at addr1 */
11253 IRTemp data = newTemp(Ity_I64);
11254 assign(data, binop(Iop_Shr64, mkexpr(retval), mkU8(16)));
11255
11256 /* To store the bytes construct 4 dirty helper calls. The helper calls
11257 are guarded (num_bytes == 1, num_bytes == 2, etc) such that only
11258 one of them will be called at runtime. */
11259 int i;
11260 for (i = 1; i <= 4; ++i) {
11261 IRDirty *d;
11262
11263 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
11264 &s390x_dirtyhelper_CUxy,
11265 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
11266 mkexpr(num_bytes)));
11267 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
11268 d->mFx = Ifx_Write;
11269 d->mAddr = mkexpr(addr1);
11270 d->mSize = i;
11271 stmt(IRStmt_Dirty(d));
11272 }
11273
11274 /* Update source address and length */
11275 IRTemp num_src_bytes = newTemp(Ity_I64);
11276 assign(num_src_bytes,
11277 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
11278 mkU64(4), mkU64(2)));
11279 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkexpr(num_src_bytes)));
11280 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkexpr(num_src_bytes)));
11281
11282 /* Update destination address and length */
11283 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
11284 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
11285
florian6820ba52012-07-26 02:01:50 +000011286 iterate();
floriana0100c92012-07-20 00:06:35 +000011287
11288 return "cu21";
11289}
11290
florian2a415a12012-07-21 17:41:36 +000011291static IRExpr *
11292s390_call_cu24(IRExpr *srcval, IRExpr *low_surrogate)
11293{
11294 IRExpr **args, *call;
11295 args = mkIRExprVec_2(srcval, low_surrogate);
11296 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
11297 "s390_do_cu24", &s390_do_cu24, args);
11298
11299 /* Nothing is excluded from definedness checking. */
11300 call->Iex.CCall.cee->mcx_mask = 0;
11301
11302 return call;
11303}
11304
11305static HChar *
11306s390_irgen_CU24(UChar m3, UChar r1, UChar r2)
11307{
11308 IRTemp addr1 = newTemp(Ity_I64);
11309 IRTemp addr2 = newTemp(Ity_I64);
11310 IRTemp len1 = newTemp(Ity_I64);
11311 IRTemp len2 = newTemp(Ity_I64);
11312
11313 assign(addr1, get_gpr_dw0(r1));
11314 assign(addr2, get_gpr_dw0(r2));
11315 assign(len1, get_gpr_dw0(r1 + 1));
11316 assign(len2, get_gpr_dw0(r2 + 1));
11317
11318 /* We're processing the 2nd operand 2 bytes at a time. Therefore, if
11319 there are less than 2 bytes left, then the 2nd operand is exhausted
11320 and we're done here. cc = 0 */
11321 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000011322 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(2)));
florian2a415a12012-07-21 17:41:36 +000011323
11324 /* There are at least two bytes there. Read them. */
11325 IRTemp srcval = newTemp(Ity_I32);
11326 assign(srcval, unop(Iop_16Uto32, load(Ity_I16, mkexpr(addr2))));
11327
11328 /* Find out whether this is a high surrogate. I.e. SRCVAL lies
11329 inside the interval [0xd800 - 0xdbff] */
11330 IRTemp is_high_surrogate = newTemp(Ity_I32);
11331 IRExpr *flag1 = mkite(binop(Iop_CmpLE32U, mkU32(0xd800), mkexpr(srcval)),
11332 mkU32(1), mkU32(0));
11333 IRExpr *flag2 = mkite(binop(Iop_CmpLE32U, mkexpr(srcval), mkU32(0xdbff)),
11334 mkU32(1), mkU32(0));
11335 assign(is_high_surrogate, binop(Iop_And32, flag1, flag2));
11336
11337 /* If SRCVAL is a high surrogate and there are less than 4 bytes left,
11338 then the 2nd operand is exhausted and we're done here. cc = 0 */
11339 IRExpr *not_enough_bytes =
11340 mkite(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)), mkU32(1), mkU32(0));
11341
florian6820ba52012-07-26 02:01:50 +000011342 next_insn_if(binop(Iop_CmpEQ32,
11343 binop(Iop_And32, mkexpr(is_high_surrogate),
11344 not_enough_bytes),
11345 mkU32(1)));
florian2a415a12012-07-21 17:41:36 +000011346
11347 /* The 2nd operand is not exhausted. If the first 2 bytes are a high
11348 surrogate, read the next two bytes (low surrogate). */
11349 IRTemp low_surrogate = newTemp(Ity_I32);
11350 IRExpr *low_surrogate_addr = binop(Iop_Add64, mkexpr(addr2), mkU64(2));
11351
11352 assign(low_surrogate,
11353 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
11354 unop(Iop_16Uto32, load(Ity_I16, low_surrogate_addr)),
11355 mkU32(0))); // any value is fine; it will not be used
11356
11357 /* Call the helper */
11358 IRTemp retval = newTemp(Ity_I64);
florian11b8ee82012-08-06 13:35:33 +000011359 assign(retval, s390_call_cu24(unop(Iop_32Uto64, mkexpr(srcval)),
11360 unop(Iop_32Uto64, mkexpr(low_surrogate))));
florian2a415a12012-07-21 17:41:36 +000011361
11362 /* Before we can test whether the 1st operand is exhausted we need to
11363 test for an invalid low surrogate. Because cc=2 outranks cc=1. */
11364 if (s390_host_has_etf3 && (m3 & 0x1) == 1) {
11365 IRExpr *invalid_low_surrogate =
11366 binop(Iop_And64, mkexpr(retval), mkU64(0xff));
11367
11368 s390_cc_set(2);
florian6820ba52012-07-26 02:01:50 +000011369 next_insn_if(binop(Iop_CmpEQ64, invalid_low_surrogate, mkU64(1)));
florian2a415a12012-07-21 17:41:36 +000011370 }
11371
11372 /* Now test whether the 1st operand is exhausted */
11373 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000011374 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkU64(4)));
florian2a415a12012-07-21 17:41:36 +000011375
11376 /* Extract the bytes to be stored at addr1 */
11377 IRExpr *data = unop(Iop_64to32, binop(Iop_Shr64, mkexpr(retval), mkU8(8)));
11378
11379 store(mkexpr(addr1), data);
11380
11381 /* Update source address and length */
11382 IRTemp num_src_bytes = newTemp(Ity_I64);
11383 assign(num_src_bytes,
11384 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
11385 mkU64(4), mkU64(2)));
11386 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkexpr(num_src_bytes)));
11387 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkexpr(num_src_bytes)));
11388
11389 /* Update destination address and length */
11390 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkU64(4)));
11391 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkU64(4)));
11392
florian6820ba52012-07-26 02:01:50 +000011393 iterate();
florian2a415a12012-07-21 17:41:36 +000011394
11395 return "cu24";
11396}
floriana4384a32011-08-11 16:58:45 +000011397
florian956194b2012-07-28 22:18:32 +000011398static IRExpr *
11399s390_call_cu42(IRExpr *srcval)
11400{
11401 IRExpr **args, *call;
11402 args = mkIRExprVec_1(srcval);
11403 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
11404 "s390_do_cu42", &s390_do_cu42, args);
11405
11406 /* Nothing is excluded from definedness checking. */
11407 call->Iex.CCall.cee->mcx_mask = 0;
11408
11409 return call;
11410}
11411
11412static HChar *
11413s390_irgen_CU42(UChar r1, UChar r2)
11414{
11415 IRTemp addr1 = newTemp(Ity_I64);
11416 IRTemp addr2 = newTemp(Ity_I64);
11417 IRTemp len1 = newTemp(Ity_I64);
11418 IRTemp len2 = newTemp(Ity_I64);
11419
11420 assign(addr1, get_gpr_dw0(r1));
11421 assign(addr2, get_gpr_dw0(r2));
11422 assign(len1, get_gpr_dw0(r1 + 1));
11423 assign(len2, get_gpr_dw0(r2 + 1));
11424
11425 /* We're processing the 2nd operand 4 bytes at a time. Therefore, if
11426 there are less than 4 bytes left, then the 2nd operand is exhausted
11427 and we're done here. cc = 0 */
11428 s390_cc_set(0);
11429 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)));
11430
11431 /* Read the 2nd operand. */
11432 IRTemp srcval = newTemp(Ity_I32);
11433 assign(srcval, load(Ity_I32, mkexpr(addr2)));
11434
11435 /* Call the helper */
11436 IRTemp retval = newTemp(Ity_I64);
florian11b8ee82012-08-06 13:35:33 +000011437 assign(retval, s390_call_cu42(unop(Iop_32Uto64, mkexpr(srcval))));
florian956194b2012-07-28 22:18:32 +000011438
11439 /* If the UTF-32 character was invalid, set cc=2 and we're done.
11440 cc=2 outranks cc=1 (1st operand exhausted) */
11441 IRExpr *invalid_character = binop(Iop_And64, mkexpr(retval), mkU64(0xff));
11442
11443 s390_cc_set(2);
11444 next_insn_if(binop(Iop_CmpEQ64, invalid_character, mkU64(1)));
11445
11446 /* Now test whether the 1st operand is exhausted */
11447 IRTemp num_bytes = newTemp(Ity_I64);
11448 assign(num_bytes, binop(Iop_And64,
11449 binop(Iop_Shr64, mkexpr(retval), mkU8(8)),
11450 mkU64(0xff)));
11451 s390_cc_set(1);
11452 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
11453
11454 /* Extract the bytes to be stored at addr1 */
11455 IRTemp data = newTemp(Ity_I64);
11456 assign(data, binop(Iop_Shr64, mkexpr(retval), mkU8(16)));
11457
11458 /* To store the bytes construct 2 dirty helper calls. The helper calls
11459 are guarded (num_bytes == 2 and num_bytes == 4, respectively) such
11460 that only one of them will be called at runtime. */
11461
11462 Int i;
11463 for (i = 2; i <= 4; ++i) {
11464 IRDirty *d;
11465
11466 if (i == 3) continue; // skip this one
11467
11468 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
11469 &s390x_dirtyhelper_CUxy,
11470 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
11471 mkexpr(num_bytes)));
11472 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
11473 d->mFx = Ifx_Write;
11474 d->mAddr = mkexpr(addr1);
11475 d->mSize = i;
11476 stmt(IRStmt_Dirty(d));
11477 }
11478
11479 /* Update source address and length */
11480 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkU64(4)));
11481 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkU64(4)));
11482
11483 /* Update destination address and length */
11484 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
11485 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
11486
11487 iterate();
11488
11489 return "cu42";
11490}
11491
florian6d9b9b22012-08-03 18:35:39 +000011492static IRExpr *
florianaf2194f2012-08-06 00:07:54 +000011493s390_call_cu41(IRExpr *srcval)
11494{
11495 IRExpr **args, *call;
11496 args = mkIRExprVec_1(srcval);
11497 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
11498 "s390_do_cu41", &s390_do_cu41, args);
11499
11500 /* Nothing is excluded from definedness checking. */
11501 call->Iex.CCall.cee->mcx_mask = 0;
11502
11503 return call;
11504}
11505
11506static HChar *
11507s390_irgen_CU41(UChar r1, UChar r2)
11508{
11509 IRTemp addr1 = newTemp(Ity_I64);
11510 IRTemp addr2 = newTemp(Ity_I64);
11511 IRTemp len1 = newTemp(Ity_I64);
11512 IRTemp len2 = newTemp(Ity_I64);
11513
11514 assign(addr1, get_gpr_dw0(r1));
11515 assign(addr2, get_gpr_dw0(r2));
11516 assign(len1, get_gpr_dw0(r1 + 1));
11517 assign(len2, get_gpr_dw0(r2 + 1));
11518
11519 /* We're processing the 2nd operand 4 bytes at a time. Therefore, if
11520 there are less than 4 bytes left, then the 2nd operand is exhausted
11521 and we're done here. cc = 0 */
11522 s390_cc_set(0);
11523 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)));
11524
11525 /* Read the 2nd operand. */
11526 IRTemp srcval = newTemp(Ity_I32);
11527 assign(srcval, load(Ity_I32, mkexpr(addr2)));
11528
11529 /* Call the helper */
11530 IRTemp retval = newTemp(Ity_I64);
florian11b8ee82012-08-06 13:35:33 +000011531 assign(retval, s390_call_cu41(unop(Iop_32Uto64, mkexpr(srcval))));
florianaf2194f2012-08-06 00:07:54 +000011532
11533 /* If the UTF-32 character was invalid, set cc=2 and we're done.
11534 cc=2 outranks cc=1 (1st operand exhausted) */
11535 IRExpr *invalid_character = binop(Iop_And64, mkexpr(retval), mkU64(0xff));
11536
11537 s390_cc_set(2);
11538 next_insn_if(binop(Iop_CmpEQ64, invalid_character, mkU64(1)));
11539
11540 /* Now test whether the 1st operand is exhausted */
11541 IRTemp num_bytes = newTemp(Ity_I64);
11542 assign(num_bytes, binop(Iop_And64,
11543 binop(Iop_Shr64, mkexpr(retval), mkU8(8)),
11544 mkU64(0xff)));
11545 s390_cc_set(1);
11546 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
11547
11548 /* Extract the bytes to be stored at addr1 */
11549 IRTemp data = newTemp(Ity_I64);
11550 assign(data, binop(Iop_Shr64, mkexpr(retval), mkU8(16)));
11551
11552 /* To store the bytes construct 4 dirty helper calls. The helper calls
11553 are guarded (num_bytes == 1, num_bytes == 2, etc) such that only
11554 one of them will be called at runtime. */
11555 int i;
11556 for (i = 1; i <= 4; ++i) {
11557 IRDirty *d;
11558
11559 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
11560 &s390x_dirtyhelper_CUxy,
11561 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
11562 mkexpr(num_bytes)));
11563 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
11564 d->mFx = Ifx_Write;
11565 d->mAddr = mkexpr(addr1);
11566 d->mSize = i;
11567 stmt(IRStmt_Dirty(d));
11568 }
11569
11570 /* Update source address and length */
11571 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkU64(4)));
11572 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkU64(4)));
11573
11574 /* Update destination address and length */
11575 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
11576 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
11577
11578 iterate();
11579
11580 return "cu41";
11581}
11582
11583static IRExpr *
florian3f8a96a2012-08-05 02:59:55 +000011584s390_call_cu12_cu14_helper1(IRExpr *byte1, IRExpr *etf3_and_m3_is_1)
florian6d9b9b22012-08-03 18:35:39 +000011585{
11586 IRExpr **args, *call;
11587 args = mkIRExprVec_2(byte1, etf3_and_m3_is_1);
florian3f8a96a2012-08-05 02:59:55 +000011588 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/, "s390_do_cu12_cu14_helper1",
11589 &s390_do_cu12_cu14_helper1, args);
florian6d9b9b22012-08-03 18:35:39 +000011590
11591 /* Nothing is excluded from definedness checking. */
11592 call->Iex.CCall.cee->mcx_mask = 0;
11593
11594 return call;
11595}
11596
11597static IRExpr *
11598s390_call_cu12_helper2(IRExpr *byte1, IRExpr *byte2, IRExpr *byte3,
11599 IRExpr *byte4, IRExpr *stuff)
11600{
11601 IRExpr **args, *call;
11602 args = mkIRExprVec_5(byte1, byte2, byte3, byte4, stuff);
11603 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
11604 "s390_do_cu12_helper2", &s390_do_cu12_helper2, args);
11605
11606 /* Nothing is excluded from definedness checking. */
11607 call->Iex.CCall.cee->mcx_mask = 0;
11608
11609 return call;
11610}
11611
florian3f8a96a2012-08-05 02:59:55 +000011612static IRExpr *
11613s390_call_cu14_helper2(IRExpr *byte1, IRExpr *byte2, IRExpr *byte3,
11614 IRExpr *byte4, IRExpr *stuff)
11615{
11616 IRExpr **args, *call;
11617 args = mkIRExprVec_5(byte1, byte2, byte3, byte4, stuff);
11618 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
11619 "s390_do_cu14_helper2", &s390_do_cu14_helper2, args);
11620
11621 /* Nothing is excluded from definedness checking. */
11622 call->Iex.CCall.cee->mcx_mask = 0;
11623
11624 return call;
11625}
11626
11627static void
11628s390_irgen_cu12_cu14(UChar m3, UChar r1, UChar r2, Bool is_cu12)
florian6d9b9b22012-08-03 18:35:39 +000011629{
11630 IRTemp addr1 = newTemp(Ity_I64);
11631 IRTemp addr2 = newTemp(Ity_I64);
11632 IRTemp len1 = newTemp(Ity_I64);
11633 IRTemp len2 = newTemp(Ity_I64);
11634
11635 assign(addr1, get_gpr_dw0(r1));
11636 assign(addr2, get_gpr_dw0(r2));
11637 assign(len1, get_gpr_dw0(r1 + 1));
11638 assign(len2, get_gpr_dw0(r2 + 1));
11639
11640 UInt extended_checking = s390_host_has_etf3 && (m3 & 0x1) == 1;
11641
11642 /* We're processing the 2nd operand 1 byte at a time. Therefore, if
11643 there is less than 1 byte left, then the 2nd operand is exhausted
11644 and we're done here. cc = 0 */
11645 s390_cc_set(0);
11646 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(1)));
11647
11648 /* There is at least one byte there. Read it. */
florian11b8ee82012-08-06 13:35:33 +000011649 IRTemp byte1 = newTemp(Ity_I64);
11650 assign(byte1, unop(Iop_8Uto64, load(Ity_I8, mkexpr(addr2))));
florian6d9b9b22012-08-03 18:35:39 +000011651
11652 /* Call the helper to get number of bytes and invalid byte indicator */
11653 IRTemp retval1 = newTemp(Ity_I64);
florian3f8a96a2012-08-05 02:59:55 +000011654 assign(retval1, s390_call_cu12_cu14_helper1(mkexpr(byte1),
florian11b8ee82012-08-06 13:35:33 +000011655 mkU64(extended_checking)));
florian6d9b9b22012-08-03 18:35:39 +000011656
11657 /* Check for invalid 1st byte */
11658 IRExpr *is_invalid = unop(Iop_64to1, mkexpr(retval1));
11659 s390_cc_set(2);
11660 next_insn_if(is_invalid);
11661
11662 /* How many bytes do we have to read? */
11663 IRTemp num_src_bytes = newTemp(Ity_I64);
11664 assign(num_src_bytes, binop(Iop_Shr64, mkexpr(retval1), mkU8(8)));
11665
11666 /* Now test whether the 2nd operand is exhausted */
11667 s390_cc_set(0);
11668 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkexpr(num_src_bytes)));
11669
11670 /* Read the remaining bytes */
11671 IRExpr *cond, *addr, *byte2, *byte3, *byte4;
11672
11673 cond = binop(Iop_CmpLE64U, mkU64(2), mkexpr(num_src_bytes));
11674 addr = binop(Iop_Add64, mkexpr(addr2), mkU64(1));
florian11b8ee82012-08-06 13:35:33 +000011675 byte2 = mkite(cond, unop(Iop_8Uto64, load(Ity_I8, addr)), mkU64(0));
florian6d9b9b22012-08-03 18:35:39 +000011676 cond = binop(Iop_CmpLE64U, mkU64(3), mkexpr(num_src_bytes));
11677 addr = binop(Iop_Add64, mkexpr(addr2), mkU64(2));
florian11b8ee82012-08-06 13:35:33 +000011678 byte3 = mkite(cond, unop(Iop_8Uto64, load(Ity_I8, addr)), mkU64(0));
florian6d9b9b22012-08-03 18:35:39 +000011679 cond = binop(Iop_CmpLE64U, mkU64(4), mkexpr(num_src_bytes));
11680 addr = binop(Iop_Add64, mkexpr(addr2), mkU64(3));
florian11b8ee82012-08-06 13:35:33 +000011681 byte4 = mkite(cond, unop(Iop_8Uto64, load(Ity_I8, addr)), mkU64(0));
florian6d9b9b22012-08-03 18:35:39 +000011682
11683 /* Call the helper to get the converted value and invalid byte indicator.
11684 We can pass at most 5 arguments; therefore some encoding is needed
11685 here */
11686 IRExpr *stuff = binop(Iop_Or64,
11687 binop(Iop_Shl64, mkexpr(num_src_bytes), mkU8(1)),
11688 mkU64(extended_checking));
11689 IRTemp retval2 = newTemp(Ity_I64);
florian3f8a96a2012-08-05 02:59:55 +000011690
11691 if (is_cu12) {
11692 assign(retval2, s390_call_cu12_helper2(mkexpr(byte1), byte2, byte3,
11693 byte4, stuff));
11694 } else {
11695 assign(retval2, s390_call_cu14_helper2(mkexpr(byte1), byte2, byte3,
11696 byte4, stuff));
11697 }
florian6d9b9b22012-08-03 18:35:39 +000011698
11699 /* Check for invalid character */
11700 s390_cc_set(2);
11701 is_invalid = unop(Iop_64to1, mkexpr(retval2));
11702 next_insn_if(is_invalid);
11703
11704 /* Now test whether the 1st operand is exhausted */
11705 IRTemp num_bytes = newTemp(Ity_I64);
11706 assign(num_bytes, binop(Iop_And64,
11707 binop(Iop_Shr64, mkexpr(retval2), mkU8(8)),
11708 mkU64(0xff)));
11709 s390_cc_set(1);
11710 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
11711
11712 /* Extract the bytes to be stored at addr1 */
11713 IRTemp data = newTemp(Ity_I64);
11714 assign(data, binop(Iop_Shr64, mkexpr(retval2), mkU8(16)));
11715
florian3f8a96a2012-08-05 02:59:55 +000011716 if (is_cu12) {
11717 /* To store the bytes construct 2 dirty helper calls. The helper calls
11718 are guarded (num_bytes == 2 and num_bytes == 4, respectively) such
11719 that only one of them will be called at runtime. */
florian6d9b9b22012-08-03 18:35:39 +000011720
florian3f8a96a2012-08-05 02:59:55 +000011721 Int i;
11722 for (i = 2; i <= 4; ++i) {
11723 IRDirty *d;
florian6d9b9b22012-08-03 18:35:39 +000011724
florian3f8a96a2012-08-05 02:59:55 +000011725 if (i == 3) continue; // skip this one
florian6d9b9b22012-08-03 18:35:39 +000011726
florian3f8a96a2012-08-05 02:59:55 +000011727 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
11728 &s390x_dirtyhelper_CUxy,
11729 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
11730 mkexpr(num_bytes)));
11731 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
11732 d->mFx = Ifx_Write;
11733 d->mAddr = mkexpr(addr1);
11734 d->mSize = i;
11735 stmt(IRStmt_Dirty(d));
11736 }
11737 } else {
11738 // cu14
11739 store(mkexpr(addr1), unop(Iop_64to32, mkexpr(data)));
florian6d9b9b22012-08-03 18:35:39 +000011740 }
11741
11742 /* Update source address and length */
11743 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkexpr(num_src_bytes)));
11744 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkexpr(num_src_bytes)));
11745
11746 /* Update destination address and length */
11747 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
11748 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
11749
11750 iterate();
florian3f8a96a2012-08-05 02:59:55 +000011751}
11752
11753static HChar *
11754s390_irgen_CU12(UChar m3, UChar r1, UChar r2)
11755{
11756 s390_irgen_cu12_cu14(m3, r1, r2, /* is_cu12 = */ 1);
florian6d9b9b22012-08-03 18:35:39 +000011757
11758 return "cu12";
11759}
11760
florian3f8a96a2012-08-05 02:59:55 +000011761static HChar *
11762s390_irgen_CU14(UChar m3, UChar r1, UChar r2)
11763{
11764 s390_irgen_cu12_cu14(m3, r1, r2, /* is_cu12 = */ 0);
11765
11766 return "cu14";
11767}
11768
sewardj2019a972011-03-07 16:04:07 +000011769/*------------------------------------------------------------*/
11770/*--- Build IR for special instructions ---*/
11771/*------------------------------------------------------------*/
11772
florianb4df7682011-07-05 02:09:01 +000011773static void
sewardj2019a972011-03-07 16:04:07 +000011774s390_irgen_client_request(void)
11775{
11776 if (0)
11777 vex_printf("%%R3 = client_request ( %%R2 )\n");
11778
florianf9e1ed72012-04-17 02:41:56 +000011779 Addr64 next = guest_IA_curr_instr + S390_SPECIAL_OP_PREAMBLE_SIZE
11780 + S390_SPECIAL_OP_SIZE;
sewardj2019a972011-03-07 16:04:07 +000011781
florianf9e1ed72012-04-17 02:41:56 +000011782 dis_res->jk_StopHere = Ijk_ClientReq;
sewardj2019a972011-03-07 16:04:07 +000011783 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +000011784
11785 put_IA(mkaddr_expr(next));
sewardj2019a972011-03-07 16:04:07 +000011786}
11787
florianb4df7682011-07-05 02:09:01 +000011788static void
sewardj2019a972011-03-07 16:04:07 +000011789s390_irgen_guest_NRADDR(void)
11790{
11791 if (0)
11792 vex_printf("%%R3 = guest_NRADDR\n");
11793
floriane88b3c92011-07-05 02:48:39 +000011794 put_gpr_dw0(3, IRExpr_Get(S390X_GUEST_OFFSET(guest_NRADDR), Ity_I64));
sewardj2019a972011-03-07 16:04:07 +000011795}
11796
florianb4df7682011-07-05 02:09:01 +000011797static void
sewardj2019a972011-03-07 16:04:07 +000011798s390_irgen_call_noredir(void)
11799{
florianf9e1ed72012-04-17 02:41:56 +000011800 Addr64 next = guest_IA_curr_instr + S390_SPECIAL_OP_PREAMBLE_SIZE
11801 + S390_SPECIAL_OP_SIZE;
11802
sewardj2019a972011-03-07 16:04:07 +000011803 /* Continue after special op */
florianf9e1ed72012-04-17 02:41:56 +000011804 put_gpr_dw0(14, mkaddr_expr(next));
sewardj2019a972011-03-07 16:04:07 +000011805
11806 /* The address is in REG1, all parameters are in the right (guest) places */
florianf9e1ed72012-04-17 02:41:56 +000011807 put_IA(get_gpr_dw0(1));
sewardj2019a972011-03-07 16:04:07 +000011808
11809 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +000011810 dis_res->jk_StopHere = Ijk_NoRedir;
sewardj2019a972011-03-07 16:04:07 +000011811}
11812
11813/* Force proper alignment for the structures below. */
11814#pragma pack(1)
11815
11816
11817static s390_decode_t
11818s390_decode_2byte_and_irgen(UChar *bytes)
11819{
11820 typedef union {
11821 struct {
11822 unsigned int op : 16;
11823 } E;
11824 struct {
11825 unsigned int op : 8;
11826 unsigned int i : 8;
11827 } I;
11828 struct {
11829 unsigned int op : 8;
11830 unsigned int r1 : 4;
11831 unsigned int r2 : 4;
11832 } RR;
11833 } formats;
11834 union {
11835 formats fmt;
11836 UShort value;
11837 } ovl;
11838
11839 vassert(sizeof(formats) == 2);
11840
11841 ((char *)(&ovl.value))[0] = bytes[0];
11842 ((char *)(&ovl.value))[1] = bytes[1];
11843
11844 switch (ovl.value & 0xffff) {
11845 case 0x0101: /* PR */ goto unimplemented;
11846 case 0x0102: /* UPT */ goto unimplemented;
11847 case 0x0104: /* PTFF */ goto unimplemented;
11848 case 0x0107: /* SCKPF */ goto unimplemented;
11849 case 0x010a: /* PFPO */ goto unimplemented;
11850 case 0x010b: /* TAM */ goto unimplemented;
11851 case 0x010c: /* SAM24 */ goto unimplemented;
11852 case 0x010d: /* SAM31 */ goto unimplemented;
11853 case 0x010e: /* SAM64 */ goto unimplemented;
11854 case 0x01ff: /* TRAP2 */ goto unimplemented;
11855 }
11856
11857 switch ((ovl.value & 0xff00) >> 8) {
11858 case 0x04: /* SPM */ goto unimplemented;
11859 case 0x05: /* BALR */ goto unimplemented;
11860 case 0x06: s390_format_RR_RR(s390_irgen_BCTR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
11861 goto ok;
11862 case 0x07: s390_format_RR(s390_irgen_BCR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
11863 goto ok;
11864 case 0x0a: s390_format_I(s390_irgen_SVC, ovl.fmt.I.i); goto ok;
11865 case 0x0b: /* BSM */ goto unimplemented;
11866 case 0x0c: /* BASSM */ goto unimplemented;
11867 case 0x0d: s390_format_RR_RR(s390_irgen_BASR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
11868 goto ok;
florianb0c9a132011-09-08 15:37:39 +000011869 case 0x0e: s390_format_RR(s390_irgen_MVCL, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
11870 goto ok;
11871 case 0x0f: s390_format_RR(s390_irgen_CLCL, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
11872 goto ok;
sewardj2019a972011-03-07 16:04:07 +000011873 case 0x10: s390_format_RR_RR(s390_irgen_LPR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
11874 goto ok;
11875 case 0x11: s390_format_RR_RR(s390_irgen_LNR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
11876 goto ok;
11877 case 0x12: s390_format_RR_RR(s390_irgen_LTR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
11878 goto ok;
11879 case 0x13: s390_format_RR_RR(s390_irgen_LCR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
11880 goto ok;
11881 case 0x14: s390_format_RR_RR(s390_irgen_NR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
11882 goto ok;
11883 case 0x15: s390_format_RR_RR(s390_irgen_CLR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
11884 goto ok;
11885 case 0x16: s390_format_RR_RR(s390_irgen_OR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
11886 goto ok;
11887 case 0x17: s390_format_RR_RR(s390_irgen_XR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
11888 goto ok;
11889 case 0x18: s390_format_RR_RR(s390_irgen_LR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
11890 goto ok;
11891 case 0x19: s390_format_RR_RR(s390_irgen_CR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
11892 goto ok;
11893 case 0x1a: s390_format_RR_RR(s390_irgen_AR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
11894 goto ok;
11895 case 0x1b: s390_format_RR_RR(s390_irgen_SR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
11896 goto ok;
11897 case 0x1c: s390_format_RR_RR(s390_irgen_MR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
11898 goto ok;
11899 case 0x1d: s390_format_RR_RR(s390_irgen_DR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
11900 goto ok;
11901 case 0x1e: s390_format_RR_RR(s390_irgen_ALR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
11902 goto ok;
11903 case 0x1f: s390_format_RR_RR(s390_irgen_SLR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
11904 goto ok;
11905 case 0x20: /* LPDR */ goto unimplemented;
11906 case 0x21: /* LNDR */ goto unimplemented;
11907 case 0x22: /* LTDR */ goto unimplemented;
11908 case 0x23: /* LCDR */ goto unimplemented;
11909 case 0x24: /* HDR */ goto unimplemented;
11910 case 0x25: /* LDXR */ goto unimplemented;
11911 case 0x26: /* MXR */ goto unimplemented;
11912 case 0x27: /* MXDR */ goto unimplemented;
11913 case 0x28: s390_format_RR_FF(s390_irgen_LDR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
11914 goto ok;
11915 case 0x29: /* CDR */ goto unimplemented;
11916 case 0x2a: /* ADR */ goto unimplemented;
11917 case 0x2b: /* SDR */ goto unimplemented;
11918 case 0x2c: /* MDR */ goto unimplemented;
11919 case 0x2d: /* DDR */ goto unimplemented;
11920 case 0x2e: /* AWR */ goto unimplemented;
11921 case 0x2f: /* SWR */ goto unimplemented;
11922 case 0x30: /* LPER */ goto unimplemented;
11923 case 0x31: /* LNER */ goto unimplemented;
11924 case 0x32: /* LTER */ goto unimplemented;
11925 case 0x33: /* LCER */ goto unimplemented;
11926 case 0x34: /* HER */ goto unimplemented;
11927 case 0x35: /* LEDR */ goto unimplemented;
11928 case 0x36: /* AXR */ goto unimplemented;
11929 case 0x37: /* SXR */ goto unimplemented;
11930 case 0x38: s390_format_RR_FF(s390_irgen_LER, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
11931 goto ok;
11932 case 0x39: /* CER */ goto unimplemented;
11933 case 0x3a: /* AER */ goto unimplemented;
11934 case 0x3b: /* SER */ goto unimplemented;
11935 case 0x3c: /* MDER */ goto unimplemented;
11936 case 0x3d: /* DER */ goto unimplemented;
11937 case 0x3e: /* AUR */ goto unimplemented;
11938 case 0x3f: /* SUR */ goto unimplemented;
11939 }
11940
11941 return S390_DECODE_UNKNOWN_INSN;
11942
11943ok:
11944 return S390_DECODE_OK;
11945
11946unimplemented:
11947 return S390_DECODE_UNIMPLEMENTED_INSN;
11948}
11949
11950static s390_decode_t
11951s390_decode_4byte_and_irgen(UChar *bytes)
11952{
11953 typedef union {
11954 struct {
11955 unsigned int op1 : 8;
11956 unsigned int r1 : 4;
11957 unsigned int op2 : 4;
11958 unsigned int i2 : 16;
11959 } RI;
11960 struct {
11961 unsigned int op : 16;
11962 unsigned int : 8;
11963 unsigned int r1 : 4;
11964 unsigned int r2 : 4;
11965 } RRE;
11966 struct {
11967 unsigned int op : 16;
11968 unsigned int r1 : 4;
11969 unsigned int : 4;
11970 unsigned int r3 : 4;
11971 unsigned int r2 : 4;
11972 } RRF;
11973 struct {
11974 unsigned int op : 16;
11975 unsigned int r3 : 4;
11976 unsigned int m4 : 4;
11977 unsigned int r1 : 4;
11978 unsigned int r2 : 4;
11979 } RRF2;
11980 struct {
11981 unsigned int op : 16;
11982 unsigned int r3 : 4;
11983 unsigned int : 4;
11984 unsigned int r1 : 4;
11985 unsigned int r2 : 4;
11986 } RRF3;
11987 struct {
11988 unsigned int op : 16;
11989 unsigned int r3 : 4;
11990 unsigned int : 4;
11991 unsigned int r1 : 4;
11992 unsigned int r2 : 4;
11993 } RRR;
11994 struct {
11995 unsigned int op : 16;
11996 unsigned int r3 : 4;
11997 unsigned int : 4;
11998 unsigned int r1 : 4;
11999 unsigned int r2 : 4;
12000 } RRF4;
12001 struct {
12002 unsigned int op : 8;
12003 unsigned int r1 : 4;
12004 unsigned int r3 : 4;
12005 unsigned int b2 : 4;
12006 unsigned int d2 : 12;
12007 } RS;
12008 struct {
12009 unsigned int op : 8;
12010 unsigned int r1 : 4;
12011 unsigned int r3 : 4;
12012 unsigned int i2 : 16;
12013 } RSI;
12014 struct {
12015 unsigned int op : 8;
12016 unsigned int r1 : 4;
12017 unsigned int x2 : 4;
12018 unsigned int b2 : 4;
12019 unsigned int d2 : 12;
12020 } RX;
12021 struct {
12022 unsigned int op : 16;
12023 unsigned int b2 : 4;
12024 unsigned int d2 : 12;
12025 } S;
12026 struct {
12027 unsigned int op : 8;
12028 unsigned int i2 : 8;
12029 unsigned int b1 : 4;
12030 unsigned int d1 : 12;
12031 } SI;
12032 } formats;
12033 union {
12034 formats fmt;
12035 UInt value;
12036 } ovl;
12037
12038 vassert(sizeof(formats) == 4);
12039
12040 ((char *)(&ovl.value))[0] = bytes[0];
12041 ((char *)(&ovl.value))[1] = bytes[1];
12042 ((char *)(&ovl.value))[2] = bytes[2];
12043 ((char *)(&ovl.value))[3] = bytes[3];
12044
12045 switch ((ovl.value & 0xff0f0000) >> 16) {
12046 case 0xa500: s390_format_RI_RU(s390_irgen_IIHH, ovl.fmt.RI.r1,
12047 ovl.fmt.RI.i2); goto ok;
12048 case 0xa501: s390_format_RI_RU(s390_irgen_IIHL, ovl.fmt.RI.r1,
12049 ovl.fmt.RI.i2); goto ok;
12050 case 0xa502: s390_format_RI_RU(s390_irgen_IILH, ovl.fmt.RI.r1,
12051 ovl.fmt.RI.i2); goto ok;
12052 case 0xa503: s390_format_RI_RU(s390_irgen_IILL, ovl.fmt.RI.r1,
12053 ovl.fmt.RI.i2); goto ok;
12054 case 0xa504: s390_format_RI_RU(s390_irgen_NIHH, ovl.fmt.RI.r1,
12055 ovl.fmt.RI.i2); goto ok;
12056 case 0xa505: s390_format_RI_RU(s390_irgen_NIHL, ovl.fmt.RI.r1,
12057 ovl.fmt.RI.i2); goto ok;
12058 case 0xa506: s390_format_RI_RU(s390_irgen_NILH, ovl.fmt.RI.r1,
12059 ovl.fmt.RI.i2); goto ok;
12060 case 0xa507: s390_format_RI_RU(s390_irgen_NILL, ovl.fmt.RI.r1,
12061 ovl.fmt.RI.i2); goto ok;
12062 case 0xa508: s390_format_RI_RU(s390_irgen_OIHH, ovl.fmt.RI.r1,
12063 ovl.fmt.RI.i2); goto ok;
12064 case 0xa509: s390_format_RI_RU(s390_irgen_OIHL, ovl.fmt.RI.r1,
12065 ovl.fmt.RI.i2); goto ok;
12066 case 0xa50a: s390_format_RI_RU(s390_irgen_OILH, ovl.fmt.RI.r1,
12067 ovl.fmt.RI.i2); goto ok;
12068 case 0xa50b: s390_format_RI_RU(s390_irgen_OILL, ovl.fmt.RI.r1,
12069 ovl.fmt.RI.i2); goto ok;
12070 case 0xa50c: s390_format_RI_RU(s390_irgen_LLIHH, ovl.fmt.RI.r1,
12071 ovl.fmt.RI.i2); goto ok;
12072 case 0xa50d: s390_format_RI_RU(s390_irgen_LLIHL, ovl.fmt.RI.r1,
12073 ovl.fmt.RI.i2); goto ok;
12074 case 0xa50e: s390_format_RI_RU(s390_irgen_LLILH, ovl.fmt.RI.r1,
12075 ovl.fmt.RI.i2); goto ok;
12076 case 0xa50f: s390_format_RI_RU(s390_irgen_LLILL, ovl.fmt.RI.r1,
12077 ovl.fmt.RI.i2); goto ok;
12078 case 0xa700: s390_format_RI_RU(s390_irgen_TMLH, ovl.fmt.RI.r1,
12079 ovl.fmt.RI.i2); goto ok;
12080 case 0xa701: s390_format_RI_RU(s390_irgen_TMLL, ovl.fmt.RI.r1,
12081 ovl.fmt.RI.i2); goto ok;
12082 case 0xa702: s390_format_RI_RU(s390_irgen_TMHH, ovl.fmt.RI.r1,
12083 ovl.fmt.RI.i2); goto ok;
12084 case 0xa703: s390_format_RI_RU(s390_irgen_TMHL, ovl.fmt.RI.r1,
12085 ovl.fmt.RI.i2); goto ok;
12086 case 0xa704: s390_format_RI(s390_irgen_BRC, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
12087 goto ok;
12088 case 0xa705: s390_format_RI_RP(s390_irgen_BRAS, ovl.fmt.RI.r1,
12089 ovl.fmt.RI.i2); goto ok;
12090 case 0xa706: s390_format_RI_RP(s390_irgen_BRCT, ovl.fmt.RI.r1,
12091 ovl.fmt.RI.i2); goto ok;
12092 case 0xa707: s390_format_RI_RP(s390_irgen_BRCTG, ovl.fmt.RI.r1,
12093 ovl.fmt.RI.i2); goto ok;
12094 case 0xa708: s390_format_RI_RI(s390_irgen_LHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
12095 goto ok;
12096 case 0xa709: s390_format_RI_RI(s390_irgen_LGHI, ovl.fmt.RI.r1,
12097 ovl.fmt.RI.i2); goto ok;
12098 case 0xa70a: s390_format_RI_RI(s390_irgen_AHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
12099 goto ok;
12100 case 0xa70b: s390_format_RI_RI(s390_irgen_AGHI, ovl.fmt.RI.r1,
12101 ovl.fmt.RI.i2); goto ok;
12102 case 0xa70c: s390_format_RI_RI(s390_irgen_MHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
12103 goto ok;
12104 case 0xa70d: s390_format_RI_RI(s390_irgen_MGHI, ovl.fmt.RI.r1,
12105 ovl.fmt.RI.i2); goto ok;
12106 case 0xa70e: s390_format_RI_RI(s390_irgen_CHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
12107 goto ok;
12108 case 0xa70f: s390_format_RI_RI(s390_irgen_CGHI, ovl.fmt.RI.r1,
12109 ovl.fmt.RI.i2); goto ok;
12110 }
12111
12112 switch ((ovl.value & 0xffff0000) >> 16) {
12113 case 0x8000: /* SSM */ goto unimplemented;
12114 case 0x8200: /* LPSW */ goto unimplemented;
florian7700fc92012-01-16 17:25:55 +000012115 case 0x9300: /* TS */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000012116 case 0xb202: /* STIDP */ goto unimplemented;
12117 case 0xb204: /* SCK */ goto unimplemented;
florian7700fc92012-01-16 17:25:55 +000012118 case 0xb205: s390_format_S_RD(s390_irgen_STCK, ovl.fmt.S.b2, ovl.fmt.S.d2);
12119 goto ok;
sewardj2019a972011-03-07 16:04:07 +000012120 case 0xb206: /* SCKC */ goto unimplemented;
12121 case 0xb207: /* STCKC */ goto unimplemented;
12122 case 0xb208: /* SPT */ goto unimplemented;
12123 case 0xb209: /* STPT */ goto unimplemented;
12124 case 0xb20a: /* SPKA */ goto unimplemented;
12125 case 0xb20b: /* IPK */ goto unimplemented;
12126 case 0xb20d: /* PTLB */ goto unimplemented;
12127 case 0xb210: /* SPX */ goto unimplemented;
12128 case 0xb211: /* STPX */ goto unimplemented;
12129 case 0xb212: /* STAP */ goto unimplemented;
12130 case 0xb214: /* SIE */ goto unimplemented;
12131 case 0xb218: /* PC */ goto unimplemented;
12132 case 0xb219: /* SAC */ goto unimplemented;
12133 case 0xb21a: /* CFC */ goto unimplemented;
12134 case 0xb221: /* IPTE */ goto unimplemented;
12135 case 0xb222: s390_format_RRE_R0(s390_irgen_IPM, ovl.fmt.RRE.r1); goto ok;
12136 case 0xb223: /* IVSK */ goto unimplemented;
12137 case 0xb224: /* IAC */ goto unimplemented;
12138 case 0xb225: /* SSAR */ goto unimplemented;
12139 case 0xb226: /* EPAR */ goto unimplemented;
12140 case 0xb227: /* ESAR */ goto unimplemented;
12141 case 0xb228: /* PT */ goto unimplemented;
12142 case 0xb229: /* ISKE */ goto unimplemented;
12143 case 0xb22a: /* RRBE */ goto unimplemented;
12144 case 0xb22b: /* SSKE */ goto unimplemented;
12145 case 0xb22c: /* TB */ goto unimplemented;
12146 case 0xb22d: /* DXR */ goto unimplemented;
12147 case 0xb22e: /* PGIN */ goto unimplemented;
12148 case 0xb22f: /* PGOUT */ goto unimplemented;
12149 case 0xb230: /* CSCH */ goto unimplemented;
12150 case 0xb231: /* HSCH */ goto unimplemented;
12151 case 0xb232: /* MSCH */ goto unimplemented;
12152 case 0xb233: /* SSCH */ goto unimplemented;
12153 case 0xb234: /* STSCH */ goto unimplemented;
12154 case 0xb235: /* TSCH */ goto unimplemented;
12155 case 0xb236: /* TPI */ goto unimplemented;
12156 case 0xb237: /* SAL */ goto unimplemented;
12157 case 0xb238: /* RSCH */ goto unimplemented;
12158 case 0xb239: /* STCRW */ goto unimplemented;
12159 case 0xb23a: /* STCPS */ goto unimplemented;
12160 case 0xb23b: /* RCHP */ goto unimplemented;
12161 case 0xb23c: /* SCHM */ goto unimplemented;
12162 case 0xb240: /* BAKR */ goto unimplemented;
floriana4384a32011-08-11 16:58:45 +000012163 case 0xb241: s390_format_RRE(s390_irgen_CKSM, ovl.fmt.RRE.r1,
12164 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000012165 case 0xb244: /* SQDR */ goto unimplemented;
12166 case 0xb245: /* SQER */ goto unimplemented;
12167 case 0xb246: /* STURA */ goto unimplemented;
12168 case 0xb247: /* MSTA */ goto unimplemented;
12169 case 0xb248: /* PALB */ goto unimplemented;
12170 case 0xb249: /* EREG */ goto unimplemented;
12171 case 0xb24a: /* ESTA */ goto unimplemented;
12172 case 0xb24b: /* LURA */ goto unimplemented;
12173 case 0xb24c: /* TAR */ goto unimplemented;
12174 case 0xb24d: s390_format_RRE(s390_irgen_CPYA, ovl.fmt.RRE.r1,
12175 ovl.fmt.RRE.r2); goto ok;
12176 case 0xb24e: s390_format_RRE(s390_irgen_SAR, ovl.fmt.RRE.r1, ovl.fmt.RRE.r2);
12177 goto ok;
12178 case 0xb24f: s390_format_RRE(s390_irgen_EAR, ovl.fmt.RRE.r1, ovl.fmt.RRE.r2);
12179 goto ok;
12180 case 0xb250: /* CSP */ goto unimplemented;
12181 case 0xb252: s390_format_RRE_RR(s390_irgen_MSR, ovl.fmt.RRE.r1,
12182 ovl.fmt.RRE.r2); goto ok;
12183 case 0xb254: /* MVPG */ goto unimplemented;
12184 case 0xb255: s390_format_RRE_RR(s390_irgen_MVST, ovl.fmt.RRE.r1,
12185 ovl.fmt.RRE.r2); goto ok;
12186 case 0xb257: /* CUSE */ goto unimplemented;
12187 case 0xb258: /* BSG */ goto unimplemented;
12188 case 0xb25a: /* BSA */ goto unimplemented;
12189 case 0xb25d: s390_format_RRE_RR(s390_irgen_CLST, ovl.fmt.RRE.r1,
12190 ovl.fmt.RRE.r2); goto ok;
12191 case 0xb25e: s390_format_RRE_RR(s390_irgen_SRST, ovl.fmt.RRE.r1,
12192 ovl.fmt.RRE.r2); goto ok;
12193 case 0xb263: /* CMPSC */ goto unimplemented;
12194 case 0xb274: /* SIGA */ goto unimplemented;
12195 case 0xb276: /* XSCH */ goto unimplemented;
12196 case 0xb277: /* RP */ goto unimplemented;
sewardj1e5fea62011-05-17 16:18:36 +000012197 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 +000012198 case 0xb279: /* SACF */ goto unimplemented;
sewardj1e5fea62011-05-17 16:18:36 +000012199 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 +000012200 case 0xb27d: /* STSI */ goto unimplemented;
12201 case 0xb299: s390_format_S_RD(s390_irgen_SRNM, ovl.fmt.S.b2, ovl.fmt.S.d2);
12202 goto ok;
12203 case 0xb29c: s390_format_S_RD(s390_irgen_STFPC, ovl.fmt.S.b2, ovl.fmt.S.d2);
12204 goto ok;
12205 case 0xb29d: s390_format_S_RD(s390_irgen_LFPC, ovl.fmt.S.b2, ovl.fmt.S.d2);
12206 goto ok;
florian730448f2012-02-04 17:07:07 +000012207 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 +000012208 case 0xb2a6: s390_format_RRF_M0RERE(s390_irgen_CU21, ovl.fmt.RRF3.r3,
12209 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
12210 goto ok;
florian6d9b9b22012-08-03 18:35:39 +000012211 case 0xb2a7: s390_format_RRF_M0RERE(s390_irgen_CU12, ovl.fmt.RRF3.r3,
12212 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
12213 goto ok;
florian933065d2011-07-11 01:48:02 +000012214 case 0xb2b0: s390_format_S_RD(s390_irgen_STFLE, ovl.fmt.S.b2, ovl.fmt.S.d2);
12215 goto ok;
sewardj2019a972011-03-07 16:04:07 +000012216 case 0xb2b1: /* STFL */ goto unimplemented;
12217 case 0xb2b2: /* LPSWE */ goto unimplemented;
12218 case 0xb2b8: /* SRNMB */ goto unimplemented;
12219 case 0xb2b9: /* SRNMT */ goto unimplemented;
12220 case 0xb2bd: /* LFAS */ goto unimplemented;
12221 case 0xb2ff: /* TRAP4 */ goto unimplemented;
12222 case 0xb300: s390_format_RRE_FF(s390_irgen_LPEBR, ovl.fmt.RRE.r1,
12223 ovl.fmt.RRE.r2); goto ok;
12224 case 0xb301: s390_format_RRE_FF(s390_irgen_LNEBR, ovl.fmt.RRE.r1,
12225 ovl.fmt.RRE.r2); goto ok;
12226 case 0xb302: s390_format_RRE_FF(s390_irgen_LTEBR, ovl.fmt.RRE.r1,
12227 ovl.fmt.RRE.r2); goto ok;
12228 case 0xb303: s390_format_RRE_FF(s390_irgen_LCEBR, ovl.fmt.RRE.r1,
12229 ovl.fmt.RRE.r2); goto ok;
12230 case 0xb304: s390_format_RRE_FF(s390_irgen_LDEBR, ovl.fmt.RRE.r1,
12231 ovl.fmt.RRE.r2); goto ok;
12232 case 0xb305: s390_format_RRE_FF(s390_irgen_LXDBR, ovl.fmt.RRE.r1,
12233 ovl.fmt.RRE.r2); goto ok;
12234 case 0xb306: s390_format_RRE_FF(s390_irgen_LXEBR, ovl.fmt.RRE.r1,
12235 ovl.fmt.RRE.r2); goto ok;
12236 case 0xb307: /* MXDBR */ goto unimplemented;
12237 case 0xb308: /* KEBR */ goto unimplemented;
12238 case 0xb309: s390_format_RRE_FF(s390_irgen_CEBR, ovl.fmt.RRE.r1,
12239 ovl.fmt.RRE.r2); goto ok;
12240 case 0xb30a: s390_format_RRE_FF(s390_irgen_AEBR, ovl.fmt.RRE.r1,
12241 ovl.fmt.RRE.r2); goto ok;
12242 case 0xb30b: s390_format_RRE_FF(s390_irgen_SEBR, ovl.fmt.RRE.r1,
12243 ovl.fmt.RRE.r2); goto ok;
12244 case 0xb30c: /* MDEBR */ goto unimplemented;
12245 case 0xb30d: s390_format_RRE_FF(s390_irgen_DEBR, ovl.fmt.RRE.r1,
12246 ovl.fmt.RRE.r2); goto ok;
12247 case 0xb30e: s390_format_RRF_F0FF(s390_irgen_MAEBR, ovl.fmt.RRF.r1,
12248 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
12249 case 0xb30f: s390_format_RRF_F0FF(s390_irgen_MSEBR, ovl.fmt.RRF.r1,
12250 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
12251 case 0xb310: s390_format_RRE_FF(s390_irgen_LPDBR, ovl.fmt.RRE.r1,
12252 ovl.fmt.RRE.r2); goto ok;
12253 case 0xb311: s390_format_RRE_FF(s390_irgen_LNDBR, ovl.fmt.RRE.r1,
12254 ovl.fmt.RRE.r2); goto ok;
12255 case 0xb312: s390_format_RRE_FF(s390_irgen_LTDBR, ovl.fmt.RRE.r1,
12256 ovl.fmt.RRE.r2); goto ok;
12257 case 0xb313: s390_format_RRE_FF(s390_irgen_LCDBR, ovl.fmt.RRE.r1,
12258 ovl.fmt.RRE.r2); goto ok;
12259 case 0xb314: s390_format_RRE_FF(s390_irgen_SQEBR, ovl.fmt.RRE.r1,
12260 ovl.fmt.RRE.r2); goto ok;
12261 case 0xb315: s390_format_RRE_FF(s390_irgen_SQDBR, ovl.fmt.RRE.r1,
12262 ovl.fmt.RRE.r2); goto ok;
12263 case 0xb316: s390_format_RRE_FF(s390_irgen_SQXBR, ovl.fmt.RRE.r1,
12264 ovl.fmt.RRE.r2); goto ok;
12265 case 0xb317: s390_format_RRE_FF(s390_irgen_MEEBR, ovl.fmt.RRE.r1,
12266 ovl.fmt.RRE.r2); goto ok;
12267 case 0xb318: /* KDBR */ goto unimplemented;
12268 case 0xb319: s390_format_RRE_FF(s390_irgen_CDBR, ovl.fmt.RRE.r1,
12269 ovl.fmt.RRE.r2); goto ok;
12270 case 0xb31a: s390_format_RRE_FF(s390_irgen_ADBR, ovl.fmt.RRE.r1,
12271 ovl.fmt.RRE.r2); goto ok;
12272 case 0xb31b: s390_format_RRE_FF(s390_irgen_SDBR, ovl.fmt.RRE.r1,
12273 ovl.fmt.RRE.r2); goto ok;
12274 case 0xb31c: s390_format_RRE_FF(s390_irgen_MDBR, ovl.fmt.RRE.r1,
12275 ovl.fmt.RRE.r2); goto ok;
12276 case 0xb31d: s390_format_RRE_FF(s390_irgen_DDBR, ovl.fmt.RRE.r1,
12277 ovl.fmt.RRE.r2); goto ok;
12278 case 0xb31e: s390_format_RRF_F0FF(s390_irgen_MADBR, ovl.fmt.RRF.r1,
12279 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
12280 case 0xb31f: s390_format_RRF_F0FF(s390_irgen_MSDBR, ovl.fmt.RRF.r1,
12281 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
12282 case 0xb324: /* LDER */ goto unimplemented;
12283 case 0xb325: /* LXDR */ goto unimplemented;
12284 case 0xb326: /* LXER */ goto unimplemented;
12285 case 0xb32e: /* MAER */ goto unimplemented;
12286 case 0xb32f: /* MSER */ goto unimplemented;
12287 case 0xb336: /* SQXR */ goto unimplemented;
12288 case 0xb337: /* MEER */ goto unimplemented;
12289 case 0xb338: /* MAYLR */ goto unimplemented;
12290 case 0xb339: /* MYLR */ goto unimplemented;
12291 case 0xb33a: /* MAYR */ goto unimplemented;
12292 case 0xb33b: /* MYR */ goto unimplemented;
12293 case 0xb33c: /* MAYHR */ goto unimplemented;
12294 case 0xb33d: /* MYHR */ goto unimplemented;
12295 case 0xb33e: /* MADR */ goto unimplemented;
12296 case 0xb33f: /* MSDR */ goto unimplemented;
12297 case 0xb340: s390_format_RRE_FF(s390_irgen_LPXBR, ovl.fmt.RRE.r1,
12298 ovl.fmt.RRE.r2); goto ok;
12299 case 0xb341: s390_format_RRE_FF(s390_irgen_LNXBR, ovl.fmt.RRE.r1,
12300 ovl.fmt.RRE.r2); goto ok;
12301 case 0xb342: s390_format_RRE_FF(s390_irgen_LTXBR, ovl.fmt.RRE.r1,
12302 ovl.fmt.RRE.r2); goto ok;
12303 case 0xb343: s390_format_RRE_FF(s390_irgen_LCXBR, ovl.fmt.RRE.r1,
12304 ovl.fmt.RRE.r2); goto ok;
12305 case 0xb344: s390_format_RRE_FF(s390_irgen_LEDBR, ovl.fmt.RRE.r1,
12306 ovl.fmt.RRE.r2); goto ok;
12307 case 0xb345: s390_format_RRE_FF(s390_irgen_LDXBR, ovl.fmt.RRE.r1,
12308 ovl.fmt.RRE.r2); goto ok;
12309 case 0xb346: s390_format_RRE_FF(s390_irgen_LEXBR, ovl.fmt.RRE.r1,
12310 ovl.fmt.RRE.r2); goto ok;
12311 case 0xb347: /* FIXBR */ goto unimplemented;
12312 case 0xb348: /* KXBR */ goto unimplemented;
12313 case 0xb349: s390_format_RRE_FF(s390_irgen_CXBR, ovl.fmt.RRE.r1,
12314 ovl.fmt.RRE.r2); goto ok;
12315 case 0xb34a: s390_format_RRE_FF(s390_irgen_AXBR, ovl.fmt.RRE.r1,
12316 ovl.fmt.RRE.r2); goto ok;
12317 case 0xb34b: s390_format_RRE_FF(s390_irgen_SXBR, ovl.fmt.RRE.r1,
12318 ovl.fmt.RRE.r2); goto ok;
12319 case 0xb34c: s390_format_RRE_FF(s390_irgen_MXBR, ovl.fmt.RRE.r1,
12320 ovl.fmt.RRE.r2); goto ok;
12321 case 0xb34d: s390_format_RRE_FF(s390_irgen_DXBR, ovl.fmt.RRE.r1,
12322 ovl.fmt.RRE.r2); goto ok;
12323 case 0xb350: /* TBEDR */ goto unimplemented;
12324 case 0xb351: /* TBDR */ goto unimplemented;
12325 case 0xb353: /* DIEBR */ goto unimplemented;
12326 case 0xb357: /* FIEBR */ goto unimplemented;
12327 case 0xb358: /* THDER */ goto unimplemented;
12328 case 0xb359: /* THDR */ goto unimplemented;
12329 case 0xb35b: /* DIDBR */ goto unimplemented;
12330 case 0xb35f: /* FIDBR */ goto unimplemented;
12331 case 0xb360: /* LPXR */ goto unimplemented;
12332 case 0xb361: /* LNXR */ goto unimplemented;
12333 case 0xb362: /* LTXR */ goto unimplemented;
12334 case 0xb363: /* LCXR */ goto unimplemented;
12335 case 0xb365: s390_format_RRE_FF(s390_irgen_LXR, ovl.fmt.RRE.r1,
12336 ovl.fmt.RRE.r2); goto ok;
12337 case 0xb366: /* LEXR */ goto unimplemented;
12338 case 0xb367: /* FIXR */ goto unimplemented;
12339 case 0xb369: /* CXR */ goto unimplemented;
12340 case 0xb370: s390_format_RRE_FF(s390_irgen_LPDFR, ovl.fmt.RRE.r1,
12341 ovl.fmt.RRE.r2); goto ok;
12342 case 0xb371: s390_format_RRE_FF(s390_irgen_LNDFR, ovl.fmt.RRE.r1,
12343 ovl.fmt.RRE.r2); goto ok;
12344 case 0xb372: s390_format_RRF_F0FF2(s390_irgen_CPSDR, ovl.fmt.RRF3.r3,
12345 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
12346 goto ok;
12347 case 0xb373: s390_format_RRE_FF(s390_irgen_LCDFR, ovl.fmt.RRE.r1,
12348 ovl.fmt.RRE.r2); goto ok;
12349 case 0xb374: s390_format_RRE_F0(s390_irgen_LZER, ovl.fmt.RRE.r1); goto ok;
12350 case 0xb375: s390_format_RRE_F0(s390_irgen_LZDR, ovl.fmt.RRE.r1); goto ok;
12351 case 0xb376: s390_format_RRE_F0(s390_irgen_LZXR, ovl.fmt.RRE.r1); goto ok;
12352 case 0xb377: /* FIER */ goto unimplemented;
12353 case 0xb37f: /* FIDR */ goto unimplemented;
12354 case 0xb384: s390_format_RRE_R0(s390_irgen_SFPC, ovl.fmt.RRE.r1); goto ok;
12355 case 0xb385: /* SFASR */ goto unimplemented;
12356 case 0xb38c: s390_format_RRE_R0(s390_irgen_EFPC, ovl.fmt.RRE.r1); goto ok;
12357 case 0xb390: /* CELFBR */ goto unimplemented;
12358 case 0xb391: /* CDLFBR */ goto unimplemented;
12359 case 0xb392: /* CXLFBR */ goto unimplemented;
12360 case 0xb394: s390_format_RRE_FR(s390_irgen_CEFBR, ovl.fmt.RRE.r1,
12361 ovl.fmt.RRE.r2); goto ok;
12362 case 0xb395: s390_format_RRE_FR(s390_irgen_CDFBR, ovl.fmt.RRE.r1,
12363 ovl.fmt.RRE.r2); goto ok;
12364 case 0xb396: s390_format_RRE_FR(s390_irgen_CXFBR, ovl.fmt.RRE.r1,
12365 ovl.fmt.RRE.r2); goto ok;
12366 case 0xb398: s390_format_RRF_U0RF(s390_irgen_CFEBR, ovl.fmt.RRF3.r3,
12367 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
12368 goto ok;
12369 case 0xb399: s390_format_RRF_U0RF(s390_irgen_CFDBR, ovl.fmt.RRF3.r3,
12370 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
12371 goto ok;
12372 case 0xb39a: s390_format_RRF_U0RF(s390_irgen_CFXBR, ovl.fmt.RRF3.r3,
12373 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
12374 goto ok;
12375 case 0xb3a0: /* CELGBR */ goto unimplemented;
12376 case 0xb3a1: /* CDLGBR */ goto unimplemented;
12377 case 0xb3a2: /* CXLGBR */ goto unimplemented;
12378 case 0xb3a4: s390_format_RRE_FR(s390_irgen_CEGBR, ovl.fmt.RRE.r1,
12379 ovl.fmt.RRE.r2); goto ok;
12380 case 0xb3a5: s390_format_RRE_FR(s390_irgen_CDGBR, ovl.fmt.RRE.r1,
12381 ovl.fmt.RRE.r2); goto ok;
12382 case 0xb3a6: s390_format_RRE_FR(s390_irgen_CXGBR, ovl.fmt.RRE.r1,
12383 ovl.fmt.RRE.r2); goto ok;
12384 case 0xb3a8: s390_format_RRF_U0RF(s390_irgen_CGEBR, ovl.fmt.RRF3.r3,
12385 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
12386 goto ok;
12387 case 0xb3a9: s390_format_RRF_U0RF(s390_irgen_CGDBR, ovl.fmt.RRF3.r3,
12388 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
12389 goto ok;
12390 case 0xb3aa: s390_format_RRF_U0RF(s390_irgen_CGXBR, ovl.fmt.RRF3.r3,
12391 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
12392 goto ok;
12393 case 0xb3b4: /* CEFR */ goto unimplemented;
12394 case 0xb3b5: /* CDFR */ goto unimplemented;
12395 case 0xb3b6: /* CXFR */ goto unimplemented;
12396 case 0xb3b8: /* CFER */ goto unimplemented;
12397 case 0xb3b9: /* CFDR */ goto unimplemented;
12398 case 0xb3ba: /* CFXR */ goto unimplemented;
12399 case 0xb3c1: s390_format_RRE_FR(s390_irgen_LDGR, ovl.fmt.RRE.r1,
12400 ovl.fmt.RRE.r2); goto ok;
12401 case 0xb3c4: /* CEGR */ goto unimplemented;
12402 case 0xb3c5: /* CDGR */ goto unimplemented;
12403 case 0xb3c6: /* CXGR */ goto unimplemented;
12404 case 0xb3c8: /* CGER */ goto unimplemented;
12405 case 0xb3c9: /* CGDR */ goto unimplemented;
12406 case 0xb3ca: /* CGXR */ goto unimplemented;
12407 case 0xb3cd: s390_format_RRE_RF(s390_irgen_LGDR, ovl.fmt.RRE.r1,
12408 ovl.fmt.RRE.r2); goto ok;
12409 case 0xb3d0: /* MDTR */ goto unimplemented;
12410 case 0xb3d1: /* DDTR */ goto unimplemented;
12411 case 0xb3d2: /* ADTR */ goto unimplemented;
12412 case 0xb3d3: /* SDTR */ goto unimplemented;
12413 case 0xb3d4: /* LDETR */ goto unimplemented;
12414 case 0xb3d5: /* LEDTR */ goto unimplemented;
12415 case 0xb3d6: /* LTDTR */ goto unimplemented;
12416 case 0xb3d7: /* FIDTR */ goto unimplemented;
12417 case 0xb3d8: /* MXTR */ goto unimplemented;
12418 case 0xb3d9: /* DXTR */ goto unimplemented;
12419 case 0xb3da: /* AXTR */ goto unimplemented;
12420 case 0xb3db: /* SXTR */ goto unimplemented;
12421 case 0xb3dc: /* LXDTR */ goto unimplemented;
12422 case 0xb3dd: /* LDXTR */ goto unimplemented;
12423 case 0xb3de: /* LTXTR */ goto unimplemented;
12424 case 0xb3df: /* FIXTR */ goto unimplemented;
12425 case 0xb3e0: /* KDTR */ goto unimplemented;
12426 case 0xb3e1: /* CGDTR */ goto unimplemented;
12427 case 0xb3e2: /* CUDTR */ goto unimplemented;
12428 case 0xb3e3: /* CSDTR */ goto unimplemented;
12429 case 0xb3e4: /* CDTR */ goto unimplemented;
12430 case 0xb3e5: /* EEDTR */ goto unimplemented;
12431 case 0xb3e7: /* ESDTR */ goto unimplemented;
12432 case 0xb3e8: /* KXTR */ goto unimplemented;
12433 case 0xb3e9: /* CGXTR */ goto unimplemented;
12434 case 0xb3ea: /* CUXTR */ goto unimplemented;
12435 case 0xb3eb: /* CSXTR */ goto unimplemented;
12436 case 0xb3ec: /* CXTR */ goto unimplemented;
12437 case 0xb3ed: /* EEXTR */ goto unimplemented;
12438 case 0xb3ef: /* ESXTR */ goto unimplemented;
12439 case 0xb3f1: /* CDGTR */ goto unimplemented;
12440 case 0xb3f2: /* CDUTR */ goto unimplemented;
12441 case 0xb3f3: /* CDSTR */ goto unimplemented;
12442 case 0xb3f4: /* CEDTR */ goto unimplemented;
12443 case 0xb3f5: /* QADTR */ goto unimplemented;
12444 case 0xb3f6: /* IEDTR */ goto unimplemented;
12445 case 0xb3f7: /* RRDTR */ goto unimplemented;
12446 case 0xb3f9: /* CXGTR */ goto unimplemented;
12447 case 0xb3fa: /* CXUTR */ goto unimplemented;
12448 case 0xb3fb: /* CXSTR */ goto unimplemented;
12449 case 0xb3fc: /* CEXTR */ goto unimplemented;
12450 case 0xb3fd: /* QAXTR */ goto unimplemented;
12451 case 0xb3fe: /* IEXTR */ goto unimplemented;
12452 case 0xb3ff: /* RRXTR */ goto unimplemented;
12453 case 0xb900: s390_format_RRE_RR(s390_irgen_LPGR, ovl.fmt.RRE.r1,
12454 ovl.fmt.RRE.r2); goto ok;
12455 case 0xb901: s390_format_RRE_RR(s390_irgen_LNGR, ovl.fmt.RRE.r1,
12456 ovl.fmt.RRE.r2); goto ok;
12457 case 0xb902: s390_format_RRE_RR(s390_irgen_LTGR, ovl.fmt.RRE.r1,
12458 ovl.fmt.RRE.r2); goto ok;
12459 case 0xb903: s390_format_RRE_RR(s390_irgen_LCGR, ovl.fmt.RRE.r1,
12460 ovl.fmt.RRE.r2); goto ok;
12461 case 0xb904: s390_format_RRE_RR(s390_irgen_LGR, ovl.fmt.RRE.r1,
12462 ovl.fmt.RRE.r2); goto ok;
12463 case 0xb905: /* LURAG */ goto unimplemented;
12464 case 0xb906: s390_format_RRE_RR(s390_irgen_LGBR, ovl.fmt.RRE.r1,
12465 ovl.fmt.RRE.r2); goto ok;
12466 case 0xb907: s390_format_RRE_RR(s390_irgen_LGHR, ovl.fmt.RRE.r1,
12467 ovl.fmt.RRE.r2); goto ok;
12468 case 0xb908: s390_format_RRE_RR(s390_irgen_AGR, ovl.fmt.RRE.r1,
12469 ovl.fmt.RRE.r2); goto ok;
12470 case 0xb909: s390_format_RRE_RR(s390_irgen_SGR, ovl.fmt.RRE.r1,
12471 ovl.fmt.RRE.r2); goto ok;
12472 case 0xb90a: s390_format_RRE_RR(s390_irgen_ALGR, ovl.fmt.RRE.r1,
12473 ovl.fmt.RRE.r2); goto ok;
12474 case 0xb90b: s390_format_RRE_RR(s390_irgen_SLGR, ovl.fmt.RRE.r1,
12475 ovl.fmt.RRE.r2); goto ok;
12476 case 0xb90c: s390_format_RRE_RR(s390_irgen_MSGR, ovl.fmt.RRE.r1,
12477 ovl.fmt.RRE.r2); goto ok;
12478 case 0xb90d: s390_format_RRE_RR(s390_irgen_DSGR, ovl.fmt.RRE.r1,
12479 ovl.fmt.RRE.r2); goto ok;
12480 case 0xb90e: /* EREGG */ goto unimplemented;
12481 case 0xb90f: s390_format_RRE_RR(s390_irgen_LRVGR, ovl.fmt.RRE.r1,
12482 ovl.fmt.RRE.r2); goto ok;
12483 case 0xb910: s390_format_RRE_RR(s390_irgen_LPGFR, ovl.fmt.RRE.r1,
12484 ovl.fmt.RRE.r2); goto ok;
12485 case 0xb911: s390_format_RRE_RR(s390_irgen_LNGFR, ovl.fmt.RRE.r1,
12486 ovl.fmt.RRE.r2); goto ok;
12487 case 0xb912: s390_format_RRE_RR(s390_irgen_LTGFR, ovl.fmt.RRE.r1,
12488 ovl.fmt.RRE.r2); goto ok;
12489 case 0xb913: s390_format_RRE_RR(s390_irgen_LCGFR, ovl.fmt.RRE.r1,
12490 ovl.fmt.RRE.r2); goto ok;
12491 case 0xb914: s390_format_RRE_RR(s390_irgen_LGFR, ovl.fmt.RRE.r1,
12492 ovl.fmt.RRE.r2); goto ok;
12493 case 0xb916: s390_format_RRE_RR(s390_irgen_LLGFR, ovl.fmt.RRE.r1,
12494 ovl.fmt.RRE.r2); goto ok;
12495 case 0xb917: s390_format_RRE_RR(s390_irgen_LLGTR, ovl.fmt.RRE.r1,
12496 ovl.fmt.RRE.r2); goto ok;
12497 case 0xb918: s390_format_RRE_RR(s390_irgen_AGFR, ovl.fmt.RRE.r1,
12498 ovl.fmt.RRE.r2); goto ok;
12499 case 0xb919: s390_format_RRE_RR(s390_irgen_SGFR, ovl.fmt.RRE.r1,
12500 ovl.fmt.RRE.r2); goto ok;
12501 case 0xb91a: s390_format_RRE_RR(s390_irgen_ALGFR, ovl.fmt.RRE.r1,
12502 ovl.fmt.RRE.r2); goto ok;
12503 case 0xb91b: s390_format_RRE_RR(s390_irgen_SLGFR, ovl.fmt.RRE.r1,
12504 ovl.fmt.RRE.r2); goto ok;
12505 case 0xb91c: s390_format_RRE_RR(s390_irgen_MSGFR, ovl.fmt.RRE.r1,
12506 ovl.fmt.RRE.r2); goto ok;
12507 case 0xb91d: s390_format_RRE_RR(s390_irgen_DSGFR, ovl.fmt.RRE.r1,
12508 ovl.fmt.RRE.r2); goto ok;
12509 case 0xb91e: /* KMAC */ goto unimplemented;
12510 case 0xb91f: s390_format_RRE_RR(s390_irgen_LRVR, ovl.fmt.RRE.r1,
12511 ovl.fmt.RRE.r2); goto ok;
12512 case 0xb920: s390_format_RRE_RR(s390_irgen_CGR, ovl.fmt.RRE.r1,
12513 ovl.fmt.RRE.r2); goto ok;
12514 case 0xb921: s390_format_RRE_RR(s390_irgen_CLGR, ovl.fmt.RRE.r1,
12515 ovl.fmt.RRE.r2); goto ok;
12516 case 0xb925: /* STURG */ goto unimplemented;
12517 case 0xb926: s390_format_RRE_RR(s390_irgen_LBR, ovl.fmt.RRE.r1,
12518 ovl.fmt.RRE.r2); goto ok;
12519 case 0xb927: s390_format_RRE_RR(s390_irgen_LHR, ovl.fmt.RRE.r1,
12520 ovl.fmt.RRE.r2); goto ok;
12521 case 0xb928: /* PCKMO */ goto unimplemented;
12522 case 0xb92b: /* KMO */ goto unimplemented;
12523 case 0xb92c: /* PCC */ goto unimplemented;
12524 case 0xb92d: /* KMCTR */ goto unimplemented;
12525 case 0xb92e: /* KM */ goto unimplemented;
12526 case 0xb92f: /* KMC */ goto unimplemented;
12527 case 0xb930: s390_format_RRE_RR(s390_irgen_CGFR, ovl.fmt.RRE.r1,
12528 ovl.fmt.RRE.r2); goto ok;
12529 case 0xb931: s390_format_RRE_RR(s390_irgen_CLGFR, ovl.fmt.RRE.r1,
12530 ovl.fmt.RRE.r2); goto ok;
12531 case 0xb93e: /* KIMD */ goto unimplemented;
12532 case 0xb93f: /* KLMD */ goto unimplemented;
12533 case 0xb941: /* CFDTR */ goto unimplemented;
12534 case 0xb942: /* CLGDTR */ goto unimplemented;
12535 case 0xb943: /* CLFDTR */ goto unimplemented;
12536 case 0xb946: s390_format_RRE_RR(s390_irgen_BCTGR, ovl.fmt.RRE.r1,
12537 ovl.fmt.RRE.r2); goto ok;
12538 case 0xb949: /* CFXTR */ goto unimplemented;
12539 case 0xb94a: /* CLGXTR */ goto unimplemented;
12540 case 0xb94b: /* CLFXTR */ goto unimplemented;
12541 case 0xb951: /* CDFTR */ goto unimplemented;
12542 case 0xb952: /* CDLGTR */ goto unimplemented;
12543 case 0xb953: /* CDLFTR */ goto unimplemented;
12544 case 0xb959: /* CXFTR */ goto unimplemented;
12545 case 0xb95a: /* CXLGTR */ goto unimplemented;
12546 case 0xb95b: /* CXLFTR */ goto unimplemented;
12547 case 0xb960: /* CGRT */ goto unimplemented;
12548 case 0xb961: /* CLGRT */ goto unimplemented;
12549 case 0xb972: /* CRT */ goto unimplemented;
12550 case 0xb973: /* CLRT */ goto unimplemented;
12551 case 0xb980: s390_format_RRE_RR(s390_irgen_NGR, ovl.fmt.RRE.r1,
12552 ovl.fmt.RRE.r2); goto ok;
12553 case 0xb981: s390_format_RRE_RR(s390_irgen_OGR, ovl.fmt.RRE.r1,
12554 ovl.fmt.RRE.r2); goto ok;
12555 case 0xb982: s390_format_RRE_RR(s390_irgen_XGR, ovl.fmt.RRE.r1,
12556 ovl.fmt.RRE.r2); goto ok;
12557 case 0xb983: s390_format_RRE_RR(s390_irgen_FLOGR, ovl.fmt.RRE.r1,
12558 ovl.fmt.RRE.r2); goto ok;
12559 case 0xb984: s390_format_RRE_RR(s390_irgen_LLGCR, ovl.fmt.RRE.r1,
12560 ovl.fmt.RRE.r2); goto ok;
12561 case 0xb985: s390_format_RRE_RR(s390_irgen_LLGHR, ovl.fmt.RRE.r1,
12562 ovl.fmt.RRE.r2); goto ok;
12563 case 0xb986: s390_format_RRE_RR(s390_irgen_MLGR, ovl.fmt.RRE.r1,
12564 ovl.fmt.RRE.r2); goto ok;
12565 case 0xb987: s390_format_RRE_RR(s390_irgen_DLGR, ovl.fmt.RRE.r1,
12566 ovl.fmt.RRE.r2); goto ok;
12567 case 0xb988: s390_format_RRE_RR(s390_irgen_ALCGR, ovl.fmt.RRE.r1,
12568 ovl.fmt.RRE.r2); goto ok;
12569 case 0xb989: s390_format_RRE_RR(s390_irgen_SLBGR, ovl.fmt.RRE.r1,
12570 ovl.fmt.RRE.r2); goto ok;
12571 case 0xb98a: /* CSPG */ goto unimplemented;
12572 case 0xb98d: /* EPSW */ goto unimplemented;
12573 case 0xb98e: /* IDTE */ goto unimplemented;
florian730448f2012-02-04 17:07:07 +000012574 case 0xb990: s390_format_RRF_M0RERE(s390_irgen_TRTT, ovl.fmt.RRF3.r3,
12575 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
12576 case 0xb991: s390_format_RRF_M0RERE(s390_irgen_TRTO, ovl.fmt.RRF3.r3,
12577 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
12578 case 0xb992: s390_format_RRF_M0RERE(s390_irgen_TROT, ovl.fmt.RRF3.r3,
12579 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
florian9af37692012-01-15 21:01:16 +000012580 case 0xb993: s390_format_RRF_M0RERE(s390_irgen_TROO, ovl.fmt.RRF3.r3,
12581 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000012582 case 0xb994: s390_format_RRE_RR(s390_irgen_LLCR, ovl.fmt.RRE.r1,
12583 ovl.fmt.RRE.r2); goto ok;
12584 case 0xb995: s390_format_RRE_RR(s390_irgen_LLHR, ovl.fmt.RRE.r1,
12585 ovl.fmt.RRE.r2); goto ok;
12586 case 0xb996: s390_format_RRE_RR(s390_irgen_MLR, ovl.fmt.RRE.r1,
12587 ovl.fmt.RRE.r2); goto ok;
12588 case 0xb997: s390_format_RRE_RR(s390_irgen_DLR, ovl.fmt.RRE.r1,
12589 ovl.fmt.RRE.r2); goto ok;
12590 case 0xb998: s390_format_RRE_RR(s390_irgen_ALCR, ovl.fmt.RRE.r1,
12591 ovl.fmt.RRE.r2); goto ok;
12592 case 0xb999: s390_format_RRE_RR(s390_irgen_SLBR, ovl.fmt.RRE.r1,
12593 ovl.fmt.RRE.r2); goto ok;
12594 case 0xb99a: /* EPAIR */ goto unimplemented;
12595 case 0xb99b: /* ESAIR */ goto unimplemented;
12596 case 0xb99d: /* ESEA */ goto unimplemented;
12597 case 0xb99e: /* PTI */ goto unimplemented;
12598 case 0xb99f: /* SSAIR */ goto unimplemented;
12599 case 0xb9a2: /* PTF */ goto unimplemented;
12600 case 0xb9aa: /* LPTEA */ goto unimplemented;
12601 case 0xb9ae: /* RRBM */ goto unimplemented;
12602 case 0xb9af: /* PFMF */ goto unimplemented;
florian3f8a96a2012-08-05 02:59:55 +000012603 case 0xb9b0: s390_format_RRF_M0RERE(s390_irgen_CU14, ovl.fmt.RRF3.r3,
12604 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
12605 goto ok;
florian2a415a12012-07-21 17:41:36 +000012606 case 0xb9b1: s390_format_RRF_M0RERE(s390_irgen_CU24, ovl.fmt.RRF3.r3,
12607 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
12608 goto ok;
florianaf2194f2012-08-06 00:07:54 +000012609 case 0xb9b2: s390_format_RRE_RR(s390_irgen_CU41, ovl.fmt.RRE.r1,
12610 ovl.fmt.RRE.r2); goto ok;
florian956194b2012-07-28 22:18:32 +000012611 case 0xb9b3: s390_format_RRE_RR(s390_irgen_CU42, ovl.fmt.RRE.r1,
12612 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000012613 case 0xb9bd: /* TRTRE */ goto unimplemented;
12614 case 0xb9be: /* SRSTU */ goto unimplemented;
12615 case 0xb9bf: /* TRTE */ goto unimplemented;
12616 case 0xb9c8: s390_format_RRF_R0RR2(s390_irgen_AHHHR, ovl.fmt.RRF4.r3,
12617 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12618 goto ok;
12619 case 0xb9c9: s390_format_RRF_R0RR2(s390_irgen_SHHHR, ovl.fmt.RRF4.r3,
12620 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12621 goto ok;
12622 case 0xb9ca: s390_format_RRF_R0RR2(s390_irgen_ALHHHR, ovl.fmt.RRF4.r3,
12623 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12624 goto ok;
12625 case 0xb9cb: s390_format_RRF_R0RR2(s390_irgen_SLHHHR, ovl.fmt.RRF4.r3,
12626 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12627 goto ok;
12628 case 0xb9cd: s390_format_RRE_RR(s390_irgen_CHHR, ovl.fmt.RRE.r1,
12629 ovl.fmt.RRE.r2); goto ok;
12630 case 0xb9cf: s390_format_RRE_RR(s390_irgen_CLHHR, ovl.fmt.RRE.r1,
12631 ovl.fmt.RRE.r2); goto ok;
12632 case 0xb9d8: s390_format_RRF_R0RR2(s390_irgen_AHHLR, ovl.fmt.RRF4.r3,
12633 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12634 goto ok;
12635 case 0xb9d9: s390_format_RRF_R0RR2(s390_irgen_SHHLR, ovl.fmt.RRF4.r3,
12636 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12637 goto ok;
12638 case 0xb9da: s390_format_RRF_R0RR2(s390_irgen_ALHHLR, ovl.fmt.RRF4.r3,
12639 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12640 goto ok;
12641 case 0xb9db: s390_format_RRF_R0RR2(s390_irgen_SLHHLR, ovl.fmt.RRF4.r3,
12642 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12643 goto ok;
12644 case 0xb9dd: s390_format_RRE_RR(s390_irgen_CHLR, ovl.fmt.RRE.r1,
12645 ovl.fmt.RRE.r2); goto ok;
12646 case 0xb9df: s390_format_RRE_RR(s390_irgen_CLHLR, ovl.fmt.RRE.r1,
12647 ovl.fmt.RRE.r2); goto ok;
12648 case 0xb9e1: /* POPCNT */ goto unimplemented;
sewardjd7bde722011-04-05 13:19:33 +000012649 case 0xb9e2: s390_format_RRF_U0RR(s390_irgen_LOCGR, ovl.fmt.RRF3.r3,
12650 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2,
12651 S390_XMNM_LOCGR); goto ok;
sewardj2019a972011-03-07 16:04:07 +000012652 case 0xb9e4: s390_format_RRF_R0RR2(s390_irgen_NGRK, ovl.fmt.RRF4.r3,
12653 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12654 goto ok;
12655 case 0xb9e6: s390_format_RRF_R0RR2(s390_irgen_OGRK, ovl.fmt.RRF4.r3,
12656 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12657 goto ok;
12658 case 0xb9e7: s390_format_RRF_R0RR2(s390_irgen_XGRK, ovl.fmt.RRF4.r3,
12659 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12660 goto ok;
12661 case 0xb9e8: s390_format_RRF_R0RR2(s390_irgen_AGRK, ovl.fmt.RRF4.r3,
12662 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12663 goto ok;
12664 case 0xb9e9: s390_format_RRF_R0RR2(s390_irgen_SGRK, ovl.fmt.RRF4.r3,
12665 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12666 goto ok;
12667 case 0xb9ea: s390_format_RRF_R0RR2(s390_irgen_ALGRK, ovl.fmt.RRF4.r3,
12668 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12669 goto ok;
12670 case 0xb9eb: s390_format_RRF_R0RR2(s390_irgen_SLGRK, ovl.fmt.RRF4.r3,
12671 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12672 goto ok;
sewardjd7bde722011-04-05 13:19:33 +000012673 case 0xb9f2: s390_format_RRF_U0RR(s390_irgen_LOCR, ovl.fmt.RRF3.r3,
12674 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2,
12675 S390_XMNM_LOCR); goto ok;
sewardj2019a972011-03-07 16:04:07 +000012676 case 0xb9f4: s390_format_RRF_R0RR2(s390_irgen_NRK, ovl.fmt.RRF4.r3,
12677 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12678 goto ok;
12679 case 0xb9f6: s390_format_RRF_R0RR2(s390_irgen_ORK, ovl.fmt.RRF4.r3,
12680 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12681 goto ok;
12682 case 0xb9f7: s390_format_RRF_R0RR2(s390_irgen_XRK, ovl.fmt.RRF4.r3,
12683 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12684 goto ok;
12685 case 0xb9f8: s390_format_RRF_R0RR2(s390_irgen_ARK, ovl.fmt.RRF4.r3,
12686 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12687 goto ok;
12688 case 0xb9f9: s390_format_RRF_R0RR2(s390_irgen_SRK, ovl.fmt.RRF4.r3,
12689 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12690 goto ok;
12691 case 0xb9fa: s390_format_RRF_R0RR2(s390_irgen_ALRK, ovl.fmt.RRF4.r3,
12692 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12693 goto ok;
12694 case 0xb9fb: s390_format_RRF_R0RR2(s390_irgen_SLRK, ovl.fmt.RRF4.r3,
12695 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
12696 goto ok;
12697 }
12698
12699 switch ((ovl.value & 0xff000000) >> 24) {
12700 case 0x40: s390_format_RX_RRRD(s390_irgen_STH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12701 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12702 case 0x41: s390_format_RX_RRRD(s390_irgen_LA, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12703 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12704 case 0x42: s390_format_RX_RRRD(s390_irgen_STC, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12705 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12706 case 0x43: s390_format_RX_RRRD(s390_irgen_IC, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12707 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12708 case 0x44: s390_format_RX_RRRD(s390_irgen_EX, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12709 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12710 case 0x45: /* BAL */ goto unimplemented;
12711 case 0x46: s390_format_RX_RRRD(s390_irgen_BCT, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12712 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12713 case 0x47: s390_format_RX(s390_irgen_BC, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12714 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12715 case 0x48: s390_format_RX_RRRD(s390_irgen_LH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12716 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12717 case 0x49: s390_format_RX_RRRD(s390_irgen_CH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12718 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12719 case 0x4a: s390_format_RX_RRRD(s390_irgen_AH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12720 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12721 case 0x4b: s390_format_RX_RRRD(s390_irgen_SH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12722 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12723 case 0x4c: s390_format_RX_RRRD(s390_irgen_MH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12724 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12725 case 0x4d: s390_format_RX_RRRD(s390_irgen_BAS, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12726 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12727 case 0x4e: s390_format_RX_RRRD(s390_irgen_CVD, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12728 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12729 case 0x4f: s390_format_RX_RRRD(s390_irgen_CVB, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12730 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12731 case 0x50: s390_format_RX_RRRD(s390_irgen_ST, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12732 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12733 case 0x51: s390_format_RX_RRRD(s390_irgen_LAE, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12734 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12735 case 0x54: s390_format_RX_RRRD(s390_irgen_N, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12736 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12737 case 0x55: s390_format_RX_RRRD(s390_irgen_CL, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12738 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12739 case 0x56: s390_format_RX_RRRD(s390_irgen_O, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12740 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12741 case 0x57: s390_format_RX_RRRD(s390_irgen_X, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12742 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12743 case 0x58: s390_format_RX_RRRD(s390_irgen_L, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12744 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12745 case 0x59: s390_format_RX_RRRD(s390_irgen_C, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12746 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12747 case 0x5a: s390_format_RX_RRRD(s390_irgen_A, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12748 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12749 case 0x5b: s390_format_RX_RRRD(s390_irgen_S, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12750 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12751 case 0x5c: s390_format_RX_RRRD(s390_irgen_M, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12752 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12753 case 0x5d: s390_format_RX_RRRD(s390_irgen_D, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12754 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12755 case 0x5e: s390_format_RX_RRRD(s390_irgen_AL, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12756 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12757 case 0x5f: s390_format_RX_RRRD(s390_irgen_SL, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12758 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12759 case 0x60: s390_format_RX_FRRD(s390_irgen_STD, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12760 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12761 case 0x67: /* MXD */ goto unimplemented;
12762 case 0x68: s390_format_RX_FRRD(s390_irgen_LD, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12763 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12764 case 0x69: /* CD */ goto unimplemented;
12765 case 0x6a: /* AD */ goto unimplemented;
12766 case 0x6b: /* SD */ goto unimplemented;
12767 case 0x6c: /* MD */ goto unimplemented;
12768 case 0x6d: /* DD */ goto unimplemented;
12769 case 0x6e: /* AW */ goto unimplemented;
12770 case 0x6f: /* SW */ goto unimplemented;
12771 case 0x70: s390_format_RX_FRRD(s390_irgen_STE, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12772 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12773 case 0x71: s390_format_RX_RRRD(s390_irgen_MS, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12774 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12775 case 0x78: s390_format_RX_FRRD(s390_irgen_LE, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
12776 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
12777 case 0x79: /* CE */ goto unimplemented;
12778 case 0x7a: /* AE */ goto unimplemented;
12779 case 0x7b: /* SE */ goto unimplemented;
12780 case 0x7c: /* MDE */ goto unimplemented;
12781 case 0x7d: /* DE */ goto unimplemented;
12782 case 0x7e: /* AU */ goto unimplemented;
12783 case 0x7f: /* SU */ goto unimplemented;
12784 case 0x83: /* DIAG */ goto unimplemented;
12785 case 0x84: s390_format_RSI_RRP(s390_irgen_BRXH, ovl.fmt.RSI.r1,
12786 ovl.fmt.RSI.r3, ovl.fmt.RSI.i2); goto ok;
12787 case 0x85: s390_format_RSI_RRP(s390_irgen_BRXLE, ovl.fmt.RSI.r1,
12788 ovl.fmt.RSI.r3, ovl.fmt.RSI.i2); goto ok;
12789 case 0x86: s390_format_RS_RRRD(s390_irgen_BXH, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
12790 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
12791 case 0x87: s390_format_RS_RRRD(s390_irgen_BXLE, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
12792 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
12793 case 0x88: s390_format_RS_R0RD(s390_irgen_SRL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
12794 ovl.fmt.RS.d2); goto ok;
12795 case 0x89: s390_format_RS_R0RD(s390_irgen_SLL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
12796 ovl.fmt.RS.d2); goto ok;
12797 case 0x8a: s390_format_RS_R0RD(s390_irgen_SRA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
12798 ovl.fmt.RS.d2); goto ok;
12799 case 0x8b: s390_format_RS_R0RD(s390_irgen_SLA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
12800 ovl.fmt.RS.d2); goto ok;
12801 case 0x8c: s390_format_RS_R0RD(s390_irgen_SRDL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
12802 ovl.fmt.RS.d2); goto ok;
12803 case 0x8d: s390_format_RS_R0RD(s390_irgen_SLDL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
12804 ovl.fmt.RS.d2); goto ok;
12805 case 0x8e: s390_format_RS_R0RD(s390_irgen_SRDA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
12806 ovl.fmt.RS.d2); goto ok;
12807 case 0x8f: s390_format_RS_R0RD(s390_irgen_SLDA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
12808 ovl.fmt.RS.d2); goto ok;
12809 case 0x90: s390_format_RS_RRRD(s390_irgen_STM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
12810 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
12811 case 0x91: s390_format_SI_URD(s390_irgen_TM, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
12812 ovl.fmt.SI.d1); goto ok;
12813 case 0x92: s390_format_SI_URD(s390_irgen_MVI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
12814 ovl.fmt.SI.d1); goto ok;
12815 case 0x94: s390_format_SI_URD(s390_irgen_NI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
12816 ovl.fmt.SI.d1); goto ok;
12817 case 0x95: s390_format_SI_URD(s390_irgen_CLI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
12818 ovl.fmt.SI.d1); goto ok;
12819 case 0x96: s390_format_SI_URD(s390_irgen_OI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
12820 ovl.fmt.SI.d1); goto ok;
12821 case 0x97: s390_format_SI_URD(s390_irgen_XI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
12822 ovl.fmt.SI.d1); goto ok;
12823 case 0x98: s390_format_RS_RRRD(s390_irgen_LM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
12824 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
12825 case 0x99: /* TRACE */ goto unimplemented;
12826 case 0x9a: s390_format_RS_AARD(s390_irgen_LAM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
12827 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
12828 case 0x9b: s390_format_RS_AARD(s390_irgen_STAM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
12829 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
12830 case 0xa8: s390_format_RS_RRRD(s390_irgen_MVCLE, ovl.fmt.RS.r1,
12831 ovl.fmt.RS.r3, ovl.fmt.RS.b2, ovl.fmt.RS.d2);
12832 goto ok;
12833 case 0xa9: s390_format_RS_RRRD(s390_irgen_CLCLE, ovl.fmt.RS.r1,
12834 ovl.fmt.RS.r3, ovl.fmt.RS.b2, ovl.fmt.RS.d2);
12835 goto ok;
12836 case 0xac: /* STNSM */ goto unimplemented;
12837 case 0xad: /* STOSM */ goto unimplemented;
12838 case 0xae: /* SIGP */ goto unimplemented;
12839 case 0xaf: /* MC */ goto unimplemented;
12840 case 0xb1: /* LRA */ goto unimplemented;
12841 case 0xb6: /* STCTL */ goto unimplemented;
12842 case 0xb7: /* LCTL */ goto unimplemented;
12843 case 0xba: s390_format_RS_RRRD(s390_irgen_CS, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
12844 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
florian448cbba2012-06-06 02:26:01 +000012845 case 0xbb: s390_format_RS_RRRD(s390_irgen_CDS, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
12846 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000012847 case 0xbd: s390_format_RS_RURD(s390_irgen_CLM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
12848 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
12849 case 0xbe: s390_format_RS_RURD(s390_irgen_STCM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
12850 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
12851 case 0xbf: s390_format_RS_RURD(s390_irgen_ICM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
12852 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
12853 }
12854
12855 return S390_DECODE_UNKNOWN_INSN;
12856
12857ok:
12858 return S390_DECODE_OK;
12859
12860unimplemented:
12861 return S390_DECODE_UNIMPLEMENTED_INSN;
12862}
12863
12864static s390_decode_t
12865s390_decode_6byte_and_irgen(UChar *bytes)
12866{
12867 typedef union {
12868 struct {
12869 unsigned int op1 : 8;
12870 unsigned int r1 : 4;
12871 unsigned int r3 : 4;
12872 unsigned int i2 : 16;
12873 unsigned int : 8;
12874 unsigned int op2 : 8;
12875 } RIE;
12876 struct {
12877 unsigned int op1 : 8;
12878 unsigned int r1 : 4;
12879 unsigned int r2 : 4;
12880 unsigned int i3 : 8;
12881 unsigned int i4 : 8;
12882 unsigned int i5 : 8;
12883 unsigned int op2 : 8;
12884 } RIE_RRUUU;
12885 struct {
12886 unsigned int op1 : 8;
12887 unsigned int r1 : 4;
12888 unsigned int : 4;
12889 unsigned int i2 : 16;
12890 unsigned int m3 : 4;
12891 unsigned int : 4;
12892 unsigned int op2 : 8;
12893 } RIEv1;
12894 struct {
12895 unsigned int op1 : 8;
12896 unsigned int r1 : 4;
12897 unsigned int r2 : 4;
12898 unsigned int i4 : 16;
12899 unsigned int m3 : 4;
12900 unsigned int : 4;
12901 unsigned int op2 : 8;
12902 } RIE_RRPU;
12903 struct {
12904 unsigned int op1 : 8;
12905 unsigned int r1 : 4;
12906 unsigned int m3 : 4;
12907 unsigned int i4 : 16;
12908 unsigned int i2 : 8;
12909 unsigned int op2 : 8;
12910 } RIEv3;
12911 struct {
12912 unsigned int op1 : 8;
12913 unsigned int r1 : 4;
12914 unsigned int op2 : 4;
12915 unsigned int i2 : 32;
12916 } RIL;
12917 struct {
12918 unsigned int op1 : 8;
12919 unsigned int r1 : 4;
12920 unsigned int m3 : 4;
12921 unsigned int b4 : 4;
12922 unsigned int d4 : 12;
12923 unsigned int i2 : 8;
12924 unsigned int op2 : 8;
12925 } RIS;
12926 struct {
12927 unsigned int op1 : 8;
12928 unsigned int r1 : 4;
12929 unsigned int r2 : 4;
12930 unsigned int b4 : 4;
12931 unsigned int d4 : 12;
12932 unsigned int m3 : 4;
12933 unsigned int : 4;
12934 unsigned int op2 : 8;
12935 } RRS;
12936 struct {
12937 unsigned int op1 : 8;
12938 unsigned int l1 : 4;
12939 unsigned int : 4;
12940 unsigned int b1 : 4;
12941 unsigned int d1 : 12;
12942 unsigned int : 8;
12943 unsigned int op2 : 8;
12944 } RSL;
12945 struct {
12946 unsigned int op1 : 8;
12947 unsigned int r1 : 4;
12948 unsigned int r3 : 4;
12949 unsigned int b2 : 4;
12950 unsigned int dl2 : 12;
12951 unsigned int dh2 : 8;
12952 unsigned int op2 : 8;
12953 } RSY;
12954 struct {
12955 unsigned int op1 : 8;
12956 unsigned int r1 : 4;
12957 unsigned int x2 : 4;
12958 unsigned int b2 : 4;
12959 unsigned int d2 : 12;
12960 unsigned int : 8;
12961 unsigned int op2 : 8;
12962 } RXE;
12963 struct {
12964 unsigned int op1 : 8;
12965 unsigned int r3 : 4;
12966 unsigned int x2 : 4;
12967 unsigned int b2 : 4;
12968 unsigned int d2 : 12;
12969 unsigned int r1 : 4;
12970 unsigned int : 4;
12971 unsigned int op2 : 8;
12972 } RXF;
12973 struct {
12974 unsigned int op1 : 8;
12975 unsigned int r1 : 4;
12976 unsigned int x2 : 4;
12977 unsigned int b2 : 4;
12978 unsigned int dl2 : 12;
12979 unsigned int dh2 : 8;
12980 unsigned int op2 : 8;
12981 } RXY;
12982 struct {
12983 unsigned int op1 : 8;
12984 unsigned int i2 : 8;
12985 unsigned int b1 : 4;
12986 unsigned int dl1 : 12;
12987 unsigned int dh1 : 8;
12988 unsigned int op2 : 8;
12989 } SIY;
12990 struct {
12991 unsigned int op : 8;
12992 unsigned int l : 8;
12993 unsigned int b1 : 4;
12994 unsigned int d1 : 12;
12995 unsigned int b2 : 4;
12996 unsigned int d2 : 12;
12997 } SS;
12998 struct {
12999 unsigned int op : 8;
13000 unsigned int l1 : 4;
13001 unsigned int l2 : 4;
13002 unsigned int b1 : 4;
13003 unsigned int d1 : 12;
13004 unsigned int b2 : 4;
13005 unsigned int d2 : 12;
13006 } SS_LLRDRD;
13007 struct {
13008 unsigned int op : 8;
13009 unsigned int r1 : 4;
13010 unsigned int r3 : 4;
13011 unsigned int b2 : 4;
13012 unsigned int d2 : 12;
13013 unsigned int b4 : 4;
13014 unsigned int d4 : 12;
13015 } SS_RRRDRD2;
13016 struct {
13017 unsigned int op : 16;
13018 unsigned int b1 : 4;
13019 unsigned int d1 : 12;
13020 unsigned int b2 : 4;
13021 unsigned int d2 : 12;
13022 } SSE;
13023 struct {
13024 unsigned int op1 : 8;
13025 unsigned int r3 : 4;
13026 unsigned int op2 : 4;
13027 unsigned int b1 : 4;
13028 unsigned int d1 : 12;
13029 unsigned int b2 : 4;
13030 unsigned int d2 : 12;
13031 } SSF;
13032 struct {
13033 unsigned int op : 16;
13034 unsigned int b1 : 4;
13035 unsigned int d1 : 12;
13036 unsigned int i2 : 16;
13037 } SIL;
13038 } formats;
13039 union {
13040 formats fmt;
13041 ULong value;
13042 } ovl;
13043
13044 vassert(sizeof(formats) == 6);
13045
13046 ((char *)(&ovl.value))[0] = bytes[0];
13047 ((char *)(&ovl.value))[1] = bytes[1];
13048 ((char *)(&ovl.value))[2] = bytes[2];
13049 ((char *)(&ovl.value))[3] = bytes[3];
13050 ((char *)(&ovl.value))[4] = bytes[4];
13051 ((char *)(&ovl.value))[5] = bytes[5];
13052 ((char *)(&ovl.value))[6] = 0x0;
13053 ((char *)(&ovl.value))[7] = 0x0;
13054
13055 switch ((ovl.value >> 16) & 0xff00000000ffULL) {
13056 case 0xe30000000002ULL: s390_format_RXY_RRRD(s390_irgen_LTG, 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 0xe30000000003ULL: /* LRAG */ goto unimplemented;
13061 case 0xe30000000004ULL: s390_format_RXY_RRRD(s390_irgen_LG, ovl.fmt.RXY.r1,
13062 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13063 ovl.fmt.RXY.dl2,
13064 ovl.fmt.RXY.dh2); goto ok;
13065 case 0xe30000000006ULL: s390_format_RXY_RRRD(s390_irgen_CVBY, ovl.fmt.RXY.r1,
13066 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13067 ovl.fmt.RXY.dl2,
13068 ovl.fmt.RXY.dh2); goto ok;
13069 case 0xe30000000008ULL: s390_format_RXY_RRRD(s390_irgen_AG, ovl.fmt.RXY.r1,
13070 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13071 ovl.fmt.RXY.dl2,
13072 ovl.fmt.RXY.dh2); goto ok;
13073 case 0xe30000000009ULL: s390_format_RXY_RRRD(s390_irgen_SG, ovl.fmt.RXY.r1,
13074 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13075 ovl.fmt.RXY.dl2,
13076 ovl.fmt.RXY.dh2); goto ok;
13077 case 0xe3000000000aULL: s390_format_RXY_RRRD(s390_irgen_ALG, ovl.fmt.RXY.r1,
13078 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13079 ovl.fmt.RXY.dl2,
13080 ovl.fmt.RXY.dh2); goto ok;
13081 case 0xe3000000000bULL: s390_format_RXY_RRRD(s390_irgen_SLG, ovl.fmt.RXY.r1,
13082 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13083 ovl.fmt.RXY.dl2,
13084 ovl.fmt.RXY.dh2); goto ok;
13085 case 0xe3000000000cULL: s390_format_RXY_RRRD(s390_irgen_MSG, ovl.fmt.RXY.r1,
13086 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13087 ovl.fmt.RXY.dl2,
13088 ovl.fmt.RXY.dh2); goto ok;
13089 case 0xe3000000000dULL: s390_format_RXY_RRRD(s390_irgen_DSG, ovl.fmt.RXY.r1,
13090 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13091 ovl.fmt.RXY.dl2,
13092 ovl.fmt.RXY.dh2); goto ok;
13093 case 0xe3000000000eULL: /* CVBG */ goto unimplemented;
13094 case 0xe3000000000fULL: s390_format_RXY_RRRD(s390_irgen_LRVG, ovl.fmt.RXY.r1,
13095 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13096 ovl.fmt.RXY.dl2,
13097 ovl.fmt.RXY.dh2); goto ok;
13098 case 0xe30000000012ULL: s390_format_RXY_RRRD(s390_irgen_LT, ovl.fmt.RXY.r1,
13099 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13100 ovl.fmt.RXY.dl2,
13101 ovl.fmt.RXY.dh2); goto ok;
13102 case 0xe30000000013ULL: /* LRAY */ goto unimplemented;
13103 case 0xe30000000014ULL: s390_format_RXY_RRRD(s390_irgen_LGF, ovl.fmt.RXY.r1,
13104 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13105 ovl.fmt.RXY.dl2,
13106 ovl.fmt.RXY.dh2); goto ok;
13107 case 0xe30000000015ULL: s390_format_RXY_RRRD(s390_irgen_LGH, ovl.fmt.RXY.r1,
13108 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13109 ovl.fmt.RXY.dl2,
13110 ovl.fmt.RXY.dh2); goto ok;
13111 case 0xe30000000016ULL: s390_format_RXY_RRRD(s390_irgen_LLGF, ovl.fmt.RXY.r1,
13112 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13113 ovl.fmt.RXY.dl2,
13114 ovl.fmt.RXY.dh2); goto ok;
13115 case 0xe30000000017ULL: s390_format_RXY_RRRD(s390_irgen_LLGT, ovl.fmt.RXY.r1,
13116 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13117 ovl.fmt.RXY.dl2,
13118 ovl.fmt.RXY.dh2); goto ok;
13119 case 0xe30000000018ULL: s390_format_RXY_RRRD(s390_irgen_AGF, ovl.fmt.RXY.r1,
13120 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13121 ovl.fmt.RXY.dl2,
13122 ovl.fmt.RXY.dh2); goto ok;
13123 case 0xe30000000019ULL: s390_format_RXY_RRRD(s390_irgen_SGF, ovl.fmt.RXY.r1,
13124 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13125 ovl.fmt.RXY.dl2,
13126 ovl.fmt.RXY.dh2); goto ok;
13127 case 0xe3000000001aULL: s390_format_RXY_RRRD(s390_irgen_ALGF, ovl.fmt.RXY.r1,
13128 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13129 ovl.fmt.RXY.dl2,
13130 ovl.fmt.RXY.dh2); goto ok;
13131 case 0xe3000000001bULL: s390_format_RXY_RRRD(s390_irgen_SLGF, ovl.fmt.RXY.r1,
13132 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13133 ovl.fmt.RXY.dl2,
13134 ovl.fmt.RXY.dh2); goto ok;
13135 case 0xe3000000001cULL: s390_format_RXY_RRRD(s390_irgen_MSGF, ovl.fmt.RXY.r1,
13136 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13137 ovl.fmt.RXY.dl2,
13138 ovl.fmt.RXY.dh2); goto ok;
13139 case 0xe3000000001dULL: s390_format_RXY_RRRD(s390_irgen_DSGF, ovl.fmt.RXY.r1,
13140 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13141 ovl.fmt.RXY.dl2,
13142 ovl.fmt.RXY.dh2); goto ok;
13143 case 0xe3000000001eULL: s390_format_RXY_RRRD(s390_irgen_LRV, ovl.fmt.RXY.r1,
13144 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13145 ovl.fmt.RXY.dl2,
13146 ovl.fmt.RXY.dh2); goto ok;
13147 case 0xe3000000001fULL: s390_format_RXY_RRRD(s390_irgen_LRVH, ovl.fmt.RXY.r1,
13148 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13149 ovl.fmt.RXY.dl2,
13150 ovl.fmt.RXY.dh2); goto ok;
13151 case 0xe30000000020ULL: s390_format_RXY_RRRD(s390_irgen_CG, ovl.fmt.RXY.r1,
13152 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13153 ovl.fmt.RXY.dl2,
13154 ovl.fmt.RXY.dh2); goto ok;
13155 case 0xe30000000021ULL: s390_format_RXY_RRRD(s390_irgen_CLG, ovl.fmt.RXY.r1,
13156 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13157 ovl.fmt.RXY.dl2,
13158 ovl.fmt.RXY.dh2); goto ok;
13159 case 0xe30000000024ULL: s390_format_RXY_RRRD(s390_irgen_STG, ovl.fmt.RXY.r1,
13160 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13161 ovl.fmt.RXY.dl2,
13162 ovl.fmt.RXY.dh2); goto ok;
13163 case 0xe30000000026ULL: s390_format_RXY_RRRD(s390_irgen_CVDY, ovl.fmt.RXY.r1,
13164 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13165 ovl.fmt.RXY.dl2,
13166 ovl.fmt.RXY.dh2); goto ok;
13167 case 0xe3000000002eULL: /* CVDG */ goto unimplemented;
13168 case 0xe3000000002fULL: s390_format_RXY_RRRD(s390_irgen_STRVG,
13169 ovl.fmt.RXY.r1, ovl.fmt.RXY.x2,
13170 ovl.fmt.RXY.b2, ovl.fmt.RXY.dl2,
13171 ovl.fmt.RXY.dh2); goto ok;
13172 case 0xe30000000030ULL: s390_format_RXY_RRRD(s390_irgen_CGF, ovl.fmt.RXY.r1,
13173 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13174 ovl.fmt.RXY.dl2,
13175 ovl.fmt.RXY.dh2); goto ok;
13176 case 0xe30000000031ULL: s390_format_RXY_RRRD(s390_irgen_CLGF, ovl.fmt.RXY.r1,
13177 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13178 ovl.fmt.RXY.dl2,
13179 ovl.fmt.RXY.dh2); goto ok;
13180 case 0xe30000000032ULL: s390_format_RXY_RRRD(s390_irgen_LTGF, ovl.fmt.RXY.r1,
13181 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13182 ovl.fmt.RXY.dl2,
13183 ovl.fmt.RXY.dh2); goto ok;
13184 case 0xe30000000034ULL: s390_format_RXY_RRRD(s390_irgen_CGH, ovl.fmt.RXY.r1,
13185 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13186 ovl.fmt.RXY.dl2,
13187 ovl.fmt.RXY.dh2); goto ok;
13188 case 0xe30000000036ULL: s390_format_RXY_URRD(s390_irgen_PFD, ovl.fmt.RXY.r1,
13189 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13190 ovl.fmt.RXY.dl2,
13191 ovl.fmt.RXY.dh2); goto ok;
13192 case 0xe3000000003eULL: s390_format_RXY_RRRD(s390_irgen_STRV, ovl.fmt.RXY.r1,
13193 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13194 ovl.fmt.RXY.dl2,
13195 ovl.fmt.RXY.dh2); goto ok;
13196 case 0xe3000000003fULL: s390_format_RXY_RRRD(s390_irgen_STRVH,
13197 ovl.fmt.RXY.r1, ovl.fmt.RXY.x2,
13198 ovl.fmt.RXY.b2, ovl.fmt.RXY.dl2,
13199 ovl.fmt.RXY.dh2); goto ok;
13200 case 0xe30000000046ULL: s390_format_RXY_RRRD(s390_irgen_BCTG, ovl.fmt.RXY.r1,
13201 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13202 ovl.fmt.RXY.dl2,
13203 ovl.fmt.RXY.dh2); goto ok;
13204 case 0xe30000000050ULL: s390_format_RXY_RRRD(s390_irgen_STY, ovl.fmt.RXY.r1,
13205 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13206 ovl.fmt.RXY.dl2,
13207 ovl.fmt.RXY.dh2); goto ok;
13208 case 0xe30000000051ULL: s390_format_RXY_RRRD(s390_irgen_MSY, ovl.fmt.RXY.r1,
13209 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13210 ovl.fmt.RXY.dl2,
13211 ovl.fmt.RXY.dh2); goto ok;
13212 case 0xe30000000054ULL: s390_format_RXY_RRRD(s390_irgen_NY, ovl.fmt.RXY.r1,
13213 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13214 ovl.fmt.RXY.dl2,
13215 ovl.fmt.RXY.dh2); goto ok;
13216 case 0xe30000000055ULL: s390_format_RXY_RRRD(s390_irgen_CLY, ovl.fmt.RXY.r1,
13217 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13218 ovl.fmt.RXY.dl2,
13219 ovl.fmt.RXY.dh2); goto ok;
13220 case 0xe30000000056ULL: s390_format_RXY_RRRD(s390_irgen_OY, ovl.fmt.RXY.r1,
13221 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13222 ovl.fmt.RXY.dl2,
13223 ovl.fmt.RXY.dh2); goto ok;
13224 case 0xe30000000057ULL: s390_format_RXY_RRRD(s390_irgen_XY, ovl.fmt.RXY.r1,
13225 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13226 ovl.fmt.RXY.dl2,
13227 ovl.fmt.RXY.dh2); goto ok;
13228 case 0xe30000000058ULL: s390_format_RXY_RRRD(s390_irgen_LY, ovl.fmt.RXY.r1,
13229 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13230 ovl.fmt.RXY.dl2,
13231 ovl.fmt.RXY.dh2); goto ok;
13232 case 0xe30000000059ULL: s390_format_RXY_RRRD(s390_irgen_CY, ovl.fmt.RXY.r1,
13233 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13234 ovl.fmt.RXY.dl2,
13235 ovl.fmt.RXY.dh2); goto ok;
13236 case 0xe3000000005aULL: s390_format_RXY_RRRD(s390_irgen_AY, ovl.fmt.RXY.r1,
13237 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13238 ovl.fmt.RXY.dl2,
13239 ovl.fmt.RXY.dh2); goto ok;
13240 case 0xe3000000005bULL: s390_format_RXY_RRRD(s390_irgen_SY, ovl.fmt.RXY.r1,
13241 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13242 ovl.fmt.RXY.dl2,
13243 ovl.fmt.RXY.dh2); goto ok;
13244 case 0xe3000000005cULL: s390_format_RXY_RRRD(s390_irgen_MFY, ovl.fmt.RXY.r1,
13245 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13246 ovl.fmt.RXY.dl2,
13247 ovl.fmt.RXY.dh2); goto ok;
13248 case 0xe3000000005eULL: s390_format_RXY_RRRD(s390_irgen_ALY, ovl.fmt.RXY.r1,
13249 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13250 ovl.fmt.RXY.dl2,
13251 ovl.fmt.RXY.dh2); goto ok;
13252 case 0xe3000000005fULL: s390_format_RXY_RRRD(s390_irgen_SLY, ovl.fmt.RXY.r1,
13253 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13254 ovl.fmt.RXY.dl2,
13255 ovl.fmt.RXY.dh2); goto ok;
13256 case 0xe30000000070ULL: s390_format_RXY_RRRD(s390_irgen_STHY, ovl.fmt.RXY.r1,
13257 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13258 ovl.fmt.RXY.dl2,
13259 ovl.fmt.RXY.dh2); goto ok;
13260 case 0xe30000000071ULL: s390_format_RXY_RRRD(s390_irgen_LAY, ovl.fmt.RXY.r1,
13261 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13262 ovl.fmt.RXY.dl2,
13263 ovl.fmt.RXY.dh2); goto ok;
13264 case 0xe30000000072ULL: s390_format_RXY_RRRD(s390_irgen_STCY, ovl.fmt.RXY.r1,
13265 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13266 ovl.fmt.RXY.dl2,
13267 ovl.fmt.RXY.dh2); goto ok;
13268 case 0xe30000000073ULL: s390_format_RXY_RRRD(s390_irgen_ICY, ovl.fmt.RXY.r1,
13269 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13270 ovl.fmt.RXY.dl2,
13271 ovl.fmt.RXY.dh2); goto ok;
13272 case 0xe30000000075ULL: s390_format_RXY_RRRD(s390_irgen_LAEY, ovl.fmt.RXY.r1,
13273 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13274 ovl.fmt.RXY.dl2,
13275 ovl.fmt.RXY.dh2); goto ok;
13276 case 0xe30000000076ULL: s390_format_RXY_RRRD(s390_irgen_LB, ovl.fmt.RXY.r1,
13277 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13278 ovl.fmt.RXY.dl2,
13279 ovl.fmt.RXY.dh2); goto ok;
13280 case 0xe30000000077ULL: s390_format_RXY_RRRD(s390_irgen_LGB, ovl.fmt.RXY.r1,
13281 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13282 ovl.fmt.RXY.dl2,
13283 ovl.fmt.RXY.dh2); goto ok;
13284 case 0xe30000000078ULL: s390_format_RXY_RRRD(s390_irgen_LHY, ovl.fmt.RXY.r1,
13285 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13286 ovl.fmt.RXY.dl2,
13287 ovl.fmt.RXY.dh2); goto ok;
13288 case 0xe30000000079ULL: s390_format_RXY_RRRD(s390_irgen_CHY, ovl.fmt.RXY.r1,
13289 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13290 ovl.fmt.RXY.dl2,
13291 ovl.fmt.RXY.dh2); goto ok;
13292 case 0xe3000000007aULL: s390_format_RXY_RRRD(s390_irgen_AHY, ovl.fmt.RXY.r1,
13293 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13294 ovl.fmt.RXY.dl2,
13295 ovl.fmt.RXY.dh2); goto ok;
13296 case 0xe3000000007bULL: s390_format_RXY_RRRD(s390_irgen_SHY, ovl.fmt.RXY.r1,
13297 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13298 ovl.fmt.RXY.dl2,
13299 ovl.fmt.RXY.dh2); goto ok;
13300 case 0xe3000000007cULL: s390_format_RXY_RRRD(s390_irgen_MHY, ovl.fmt.RXY.r1,
13301 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13302 ovl.fmt.RXY.dl2,
13303 ovl.fmt.RXY.dh2); goto ok;
13304 case 0xe30000000080ULL: s390_format_RXY_RRRD(s390_irgen_NG, ovl.fmt.RXY.r1,
13305 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13306 ovl.fmt.RXY.dl2,
13307 ovl.fmt.RXY.dh2); goto ok;
13308 case 0xe30000000081ULL: s390_format_RXY_RRRD(s390_irgen_OG, ovl.fmt.RXY.r1,
13309 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13310 ovl.fmt.RXY.dl2,
13311 ovl.fmt.RXY.dh2); goto ok;
13312 case 0xe30000000082ULL: s390_format_RXY_RRRD(s390_irgen_XG, ovl.fmt.RXY.r1,
13313 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13314 ovl.fmt.RXY.dl2,
13315 ovl.fmt.RXY.dh2); goto ok;
13316 case 0xe30000000086ULL: s390_format_RXY_RRRD(s390_irgen_MLG, ovl.fmt.RXY.r1,
13317 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13318 ovl.fmt.RXY.dl2,
13319 ovl.fmt.RXY.dh2); goto ok;
13320 case 0xe30000000087ULL: s390_format_RXY_RRRD(s390_irgen_DLG, ovl.fmt.RXY.r1,
13321 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13322 ovl.fmt.RXY.dl2,
13323 ovl.fmt.RXY.dh2); goto ok;
13324 case 0xe30000000088ULL: s390_format_RXY_RRRD(s390_irgen_ALCG, ovl.fmt.RXY.r1,
13325 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13326 ovl.fmt.RXY.dl2,
13327 ovl.fmt.RXY.dh2); goto ok;
13328 case 0xe30000000089ULL: s390_format_RXY_RRRD(s390_irgen_SLBG, ovl.fmt.RXY.r1,
13329 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13330 ovl.fmt.RXY.dl2,
13331 ovl.fmt.RXY.dh2); goto ok;
13332 case 0xe3000000008eULL: s390_format_RXY_RRRD(s390_irgen_STPQ, ovl.fmt.RXY.r1,
13333 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13334 ovl.fmt.RXY.dl2,
13335 ovl.fmt.RXY.dh2); goto ok;
13336 case 0xe3000000008fULL: s390_format_RXY_RRRD(s390_irgen_LPQ, ovl.fmt.RXY.r1,
13337 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13338 ovl.fmt.RXY.dl2,
13339 ovl.fmt.RXY.dh2); goto ok;
13340 case 0xe30000000090ULL: s390_format_RXY_RRRD(s390_irgen_LLGC, ovl.fmt.RXY.r1,
13341 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13342 ovl.fmt.RXY.dl2,
13343 ovl.fmt.RXY.dh2); goto ok;
13344 case 0xe30000000091ULL: s390_format_RXY_RRRD(s390_irgen_LLGH, ovl.fmt.RXY.r1,
13345 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13346 ovl.fmt.RXY.dl2,
13347 ovl.fmt.RXY.dh2); goto ok;
13348 case 0xe30000000094ULL: s390_format_RXY_RRRD(s390_irgen_LLC, ovl.fmt.RXY.r1,
13349 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13350 ovl.fmt.RXY.dl2,
13351 ovl.fmt.RXY.dh2); goto ok;
13352 case 0xe30000000095ULL: s390_format_RXY_RRRD(s390_irgen_LLH, ovl.fmt.RXY.r1,
13353 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13354 ovl.fmt.RXY.dl2,
13355 ovl.fmt.RXY.dh2); goto ok;
13356 case 0xe30000000096ULL: s390_format_RXY_RRRD(s390_irgen_ML, ovl.fmt.RXY.r1,
13357 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13358 ovl.fmt.RXY.dl2,
13359 ovl.fmt.RXY.dh2); goto ok;
13360 case 0xe30000000097ULL: s390_format_RXY_RRRD(s390_irgen_DL, ovl.fmt.RXY.r1,
13361 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13362 ovl.fmt.RXY.dl2,
13363 ovl.fmt.RXY.dh2); goto ok;
13364 case 0xe30000000098ULL: s390_format_RXY_RRRD(s390_irgen_ALC, ovl.fmt.RXY.r1,
13365 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13366 ovl.fmt.RXY.dl2,
13367 ovl.fmt.RXY.dh2); goto ok;
13368 case 0xe30000000099ULL: s390_format_RXY_RRRD(s390_irgen_SLB, ovl.fmt.RXY.r1,
13369 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13370 ovl.fmt.RXY.dl2,
13371 ovl.fmt.RXY.dh2); goto ok;
13372 case 0xe300000000c0ULL: s390_format_RXY_RRRD(s390_irgen_LBH, ovl.fmt.RXY.r1,
13373 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13374 ovl.fmt.RXY.dl2,
13375 ovl.fmt.RXY.dh2); goto ok;
13376 case 0xe300000000c2ULL: s390_format_RXY_RRRD(s390_irgen_LLCH, ovl.fmt.RXY.r1,
13377 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13378 ovl.fmt.RXY.dl2,
13379 ovl.fmt.RXY.dh2); goto ok;
13380 case 0xe300000000c3ULL: s390_format_RXY_RRRD(s390_irgen_STCH, ovl.fmt.RXY.r1,
13381 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13382 ovl.fmt.RXY.dl2,
13383 ovl.fmt.RXY.dh2); goto ok;
13384 case 0xe300000000c4ULL: s390_format_RXY_RRRD(s390_irgen_LHH, ovl.fmt.RXY.r1,
13385 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13386 ovl.fmt.RXY.dl2,
13387 ovl.fmt.RXY.dh2); goto ok;
13388 case 0xe300000000c6ULL: s390_format_RXY_RRRD(s390_irgen_LLHH, ovl.fmt.RXY.r1,
13389 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13390 ovl.fmt.RXY.dl2,
13391 ovl.fmt.RXY.dh2); goto ok;
13392 case 0xe300000000c7ULL: s390_format_RXY_RRRD(s390_irgen_STHH, ovl.fmt.RXY.r1,
13393 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13394 ovl.fmt.RXY.dl2,
13395 ovl.fmt.RXY.dh2); goto ok;
13396 case 0xe300000000caULL: s390_format_RXY_RRRD(s390_irgen_LFH, ovl.fmt.RXY.r1,
13397 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13398 ovl.fmt.RXY.dl2,
13399 ovl.fmt.RXY.dh2); goto ok;
13400 case 0xe300000000cbULL: s390_format_RXY_RRRD(s390_irgen_STFH, ovl.fmt.RXY.r1,
13401 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13402 ovl.fmt.RXY.dl2,
13403 ovl.fmt.RXY.dh2); goto ok;
13404 case 0xe300000000cdULL: s390_format_RXY_RRRD(s390_irgen_CHF, ovl.fmt.RXY.r1,
13405 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13406 ovl.fmt.RXY.dl2,
13407 ovl.fmt.RXY.dh2); goto ok;
13408 case 0xe300000000cfULL: s390_format_RXY_RRRD(s390_irgen_CLHF, ovl.fmt.RXY.r1,
13409 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13410 ovl.fmt.RXY.dl2,
13411 ovl.fmt.RXY.dh2); goto ok;
13412 case 0xeb0000000004ULL: s390_format_RSY_RRRD(s390_irgen_LMG, ovl.fmt.RSY.r1,
13413 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13414 ovl.fmt.RSY.dl2,
13415 ovl.fmt.RSY.dh2); goto ok;
13416 case 0xeb000000000aULL: s390_format_RSY_RRRD(s390_irgen_SRAG, ovl.fmt.RSY.r1,
13417 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13418 ovl.fmt.RSY.dl2,
13419 ovl.fmt.RSY.dh2); goto ok;
13420 case 0xeb000000000bULL: s390_format_RSY_RRRD(s390_irgen_SLAG, ovl.fmt.RSY.r1,
13421 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13422 ovl.fmt.RSY.dl2,
13423 ovl.fmt.RSY.dh2); goto ok;
13424 case 0xeb000000000cULL: s390_format_RSY_RRRD(s390_irgen_SRLG, ovl.fmt.RSY.r1,
13425 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13426 ovl.fmt.RSY.dl2,
13427 ovl.fmt.RSY.dh2); goto ok;
13428 case 0xeb000000000dULL: s390_format_RSY_RRRD(s390_irgen_SLLG, ovl.fmt.RSY.r1,
13429 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13430 ovl.fmt.RSY.dl2,
13431 ovl.fmt.RSY.dh2); goto ok;
13432 case 0xeb000000000fULL: /* TRACG */ goto unimplemented;
13433 case 0xeb0000000014ULL: s390_format_RSY_RRRD(s390_irgen_CSY, ovl.fmt.RSY.r1,
13434 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13435 ovl.fmt.RSY.dl2,
13436 ovl.fmt.RSY.dh2); goto ok;
13437 case 0xeb000000001cULL: s390_format_RSY_RRRD(s390_irgen_RLLG, ovl.fmt.RSY.r1,
13438 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13439 ovl.fmt.RSY.dl2,
13440 ovl.fmt.RSY.dh2); goto ok;
13441 case 0xeb000000001dULL: s390_format_RSY_RRRD(s390_irgen_RLL, ovl.fmt.RSY.r1,
13442 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13443 ovl.fmt.RSY.dl2,
13444 ovl.fmt.RSY.dh2); goto ok;
13445 case 0xeb0000000020ULL: s390_format_RSY_RURD(s390_irgen_CLMH, ovl.fmt.RSY.r1,
13446 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13447 ovl.fmt.RSY.dl2,
13448 ovl.fmt.RSY.dh2); goto ok;
13449 case 0xeb0000000021ULL: s390_format_RSY_RURD(s390_irgen_CLMY, ovl.fmt.RSY.r1,
13450 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13451 ovl.fmt.RSY.dl2,
13452 ovl.fmt.RSY.dh2); goto ok;
13453 case 0xeb0000000024ULL: s390_format_RSY_RRRD(s390_irgen_STMG, ovl.fmt.RSY.r1,
13454 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13455 ovl.fmt.RSY.dl2,
13456 ovl.fmt.RSY.dh2); goto ok;
13457 case 0xeb0000000025ULL: /* STCTG */ goto unimplemented;
13458 case 0xeb0000000026ULL: s390_format_RSY_RRRD(s390_irgen_STMH, ovl.fmt.RSY.r1,
13459 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13460 ovl.fmt.RSY.dl2,
13461 ovl.fmt.RSY.dh2); goto ok;
13462 case 0xeb000000002cULL: s390_format_RSY_RURD(s390_irgen_STCMH,
13463 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
13464 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
13465 ovl.fmt.RSY.dh2); goto ok;
13466 case 0xeb000000002dULL: s390_format_RSY_RURD(s390_irgen_STCMY,
13467 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
13468 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
13469 ovl.fmt.RSY.dh2); goto ok;
13470 case 0xeb000000002fULL: /* LCTLG */ goto unimplemented;
13471 case 0xeb0000000030ULL: s390_format_RSY_RRRD(s390_irgen_CSG, ovl.fmt.RSY.r1,
13472 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13473 ovl.fmt.RSY.dl2,
13474 ovl.fmt.RSY.dh2); goto ok;
florian448cbba2012-06-06 02:26:01 +000013475 case 0xeb0000000031ULL: s390_format_RSY_RRRD(s390_irgen_CDSY, ovl.fmt.RSY.r1,
13476 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13477 ovl.fmt.RSY.dl2,
13478 ovl.fmt.RSY.dh2); goto ok;
13479 case 0xeb000000003eULL: s390_format_RSY_RRRD(s390_irgen_CDSG, ovl.fmt.RSY.r1,
13480 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13481 ovl.fmt.RSY.dl2,
13482 ovl.fmt.RSY.dh2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013483 case 0xeb0000000044ULL: s390_format_RSY_RRRD(s390_irgen_BXHG, ovl.fmt.RSY.r1,
13484 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13485 ovl.fmt.RSY.dl2,
13486 ovl.fmt.RSY.dh2); goto ok;
13487 case 0xeb0000000045ULL: s390_format_RSY_RRRD(s390_irgen_BXLEG,
13488 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
13489 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
13490 ovl.fmt.RSY.dh2); goto ok;
13491 case 0xeb000000004cULL: /* ECAG */ goto unimplemented;
13492 case 0xeb0000000051ULL: s390_format_SIY_URD(s390_irgen_TMY, ovl.fmt.SIY.i2,
13493 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
13494 ovl.fmt.SIY.dh1); goto ok;
13495 case 0xeb0000000052ULL: s390_format_SIY_URD(s390_irgen_MVIY, ovl.fmt.SIY.i2,
13496 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
13497 ovl.fmt.SIY.dh1); goto ok;
13498 case 0xeb0000000054ULL: s390_format_SIY_URD(s390_irgen_NIY, ovl.fmt.SIY.i2,
13499 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
13500 ovl.fmt.SIY.dh1); goto ok;
13501 case 0xeb0000000055ULL: s390_format_SIY_URD(s390_irgen_CLIY, ovl.fmt.SIY.i2,
13502 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
13503 ovl.fmt.SIY.dh1); goto ok;
13504 case 0xeb0000000056ULL: s390_format_SIY_URD(s390_irgen_OIY, ovl.fmt.SIY.i2,
13505 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
13506 ovl.fmt.SIY.dh1); goto ok;
13507 case 0xeb0000000057ULL: s390_format_SIY_URD(s390_irgen_XIY, ovl.fmt.SIY.i2,
13508 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
13509 ovl.fmt.SIY.dh1); goto ok;
13510 case 0xeb000000006aULL: s390_format_SIY_IRD(s390_irgen_ASI, ovl.fmt.SIY.i2,
13511 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
13512 ovl.fmt.SIY.dh1); goto ok;
13513 case 0xeb000000006eULL: s390_format_SIY_IRD(s390_irgen_ALSI, ovl.fmt.SIY.i2,
13514 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
13515 ovl.fmt.SIY.dh1); goto ok;
13516 case 0xeb000000007aULL: s390_format_SIY_IRD(s390_irgen_AGSI, ovl.fmt.SIY.i2,
13517 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
13518 ovl.fmt.SIY.dh1); goto ok;
13519 case 0xeb000000007eULL: s390_format_SIY_IRD(s390_irgen_ALGSI, ovl.fmt.SIY.i2,
13520 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
13521 ovl.fmt.SIY.dh1); goto ok;
13522 case 0xeb0000000080ULL: s390_format_RSY_RURD(s390_irgen_ICMH, ovl.fmt.RSY.r1,
13523 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13524 ovl.fmt.RSY.dl2,
13525 ovl.fmt.RSY.dh2); goto ok;
13526 case 0xeb0000000081ULL: s390_format_RSY_RURD(s390_irgen_ICMY, ovl.fmt.RSY.r1,
13527 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13528 ovl.fmt.RSY.dl2,
13529 ovl.fmt.RSY.dh2); goto ok;
13530 case 0xeb000000008eULL: /* MVCLU */ goto unimplemented;
13531 case 0xeb000000008fULL: /* CLCLU */ goto unimplemented;
13532 case 0xeb0000000090ULL: s390_format_RSY_RRRD(s390_irgen_STMY, ovl.fmt.RSY.r1,
13533 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13534 ovl.fmt.RSY.dl2,
13535 ovl.fmt.RSY.dh2); goto ok;
13536 case 0xeb0000000096ULL: s390_format_RSY_RRRD(s390_irgen_LMH, ovl.fmt.RSY.r1,
13537 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13538 ovl.fmt.RSY.dl2,
13539 ovl.fmt.RSY.dh2); goto ok;
13540 case 0xeb0000000098ULL: s390_format_RSY_RRRD(s390_irgen_LMY, ovl.fmt.RSY.r1,
13541 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13542 ovl.fmt.RSY.dl2,
13543 ovl.fmt.RSY.dh2); goto ok;
13544 case 0xeb000000009aULL: s390_format_RSY_AARD(s390_irgen_LAMY, ovl.fmt.RSY.r1,
13545 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13546 ovl.fmt.RSY.dl2,
13547 ovl.fmt.RSY.dh2); goto ok;
13548 case 0xeb000000009bULL: s390_format_RSY_AARD(s390_irgen_STAMY,
13549 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
13550 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
13551 ovl.fmt.RSY.dh2); goto ok;
13552 case 0xeb00000000c0ULL: /* TP */ goto unimplemented;
13553 case 0xeb00000000dcULL: s390_format_RSY_RRRD(s390_irgen_SRAK, ovl.fmt.RSY.r1,
13554 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13555 ovl.fmt.RSY.dl2,
13556 ovl.fmt.RSY.dh2); goto ok;
13557 case 0xeb00000000ddULL: s390_format_RSY_RRRD(s390_irgen_SLAK, ovl.fmt.RSY.r1,
13558 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13559 ovl.fmt.RSY.dl2,
13560 ovl.fmt.RSY.dh2); goto ok;
13561 case 0xeb00000000deULL: s390_format_RSY_RRRD(s390_irgen_SRLK, ovl.fmt.RSY.r1,
13562 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13563 ovl.fmt.RSY.dl2,
13564 ovl.fmt.RSY.dh2); goto ok;
13565 case 0xeb00000000dfULL: s390_format_RSY_RRRD(s390_irgen_SLLK, ovl.fmt.RSY.r1,
13566 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13567 ovl.fmt.RSY.dl2,
13568 ovl.fmt.RSY.dh2); goto ok;
sewardjd7bde722011-04-05 13:19:33 +000013569 case 0xeb00000000e2ULL: s390_format_RSY_RDRM(s390_irgen_LOCG, ovl.fmt.RSY.r1,
13570 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13571 ovl.fmt.RSY.dl2,
13572 ovl.fmt.RSY.dh2,
13573 S390_XMNM_LOCG); goto ok;
13574 case 0xeb00000000e3ULL: s390_format_RSY_RDRM(s390_irgen_STOCG,
13575 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
13576 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
13577 ovl.fmt.RSY.dh2,
13578 S390_XMNM_STOCG); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013579 case 0xeb00000000e4ULL: s390_format_RSY_RRRD(s390_irgen_LANG, ovl.fmt.RSY.r1,
13580 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13581 ovl.fmt.RSY.dl2,
13582 ovl.fmt.RSY.dh2); goto ok;
13583 case 0xeb00000000e6ULL: s390_format_RSY_RRRD(s390_irgen_LAOG, ovl.fmt.RSY.r1,
13584 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13585 ovl.fmt.RSY.dl2,
13586 ovl.fmt.RSY.dh2); goto ok;
13587 case 0xeb00000000e7ULL: s390_format_RSY_RRRD(s390_irgen_LAXG, ovl.fmt.RSY.r1,
13588 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13589 ovl.fmt.RSY.dl2,
13590 ovl.fmt.RSY.dh2); goto ok;
13591 case 0xeb00000000e8ULL: s390_format_RSY_RRRD(s390_irgen_LAAG, ovl.fmt.RSY.r1,
13592 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13593 ovl.fmt.RSY.dl2,
13594 ovl.fmt.RSY.dh2); goto ok;
13595 case 0xeb00000000eaULL: s390_format_RSY_RRRD(s390_irgen_LAALG,
13596 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
13597 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
13598 ovl.fmt.RSY.dh2); goto ok;
sewardjd7bde722011-04-05 13:19:33 +000013599 case 0xeb00000000f2ULL: s390_format_RSY_RDRM(s390_irgen_LOC, ovl.fmt.RSY.r1,
13600 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13601 ovl.fmt.RSY.dl2,
13602 ovl.fmt.RSY.dh2, S390_XMNM_LOC);
13603 goto ok;
13604 case 0xeb00000000f3ULL: s390_format_RSY_RDRM(s390_irgen_STOC, ovl.fmt.RSY.r1,
13605 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13606 ovl.fmt.RSY.dl2,
13607 ovl.fmt.RSY.dh2,
13608 S390_XMNM_STOC); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013609 case 0xeb00000000f4ULL: s390_format_RSY_RRRD(s390_irgen_LAN, ovl.fmt.RSY.r1,
13610 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13611 ovl.fmt.RSY.dl2,
13612 ovl.fmt.RSY.dh2); goto ok;
13613 case 0xeb00000000f6ULL: s390_format_RSY_RRRD(s390_irgen_LAO, ovl.fmt.RSY.r1,
13614 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13615 ovl.fmt.RSY.dl2,
13616 ovl.fmt.RSY.dh2); goto ok;
13617 case 0xeb00000000f7ULL: s390_format_RSY_RRRD(s390_irgen_LAX, ovl.fmt.RSY.r1,
13618 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13619 ovl.fmt.RSY.dl2,
13620 ovl.fmt.RSY.dh2); goto ok;
13621 case 0xeb00000000f8ULL: s390_format_RSY_RRRD(s390_irgen_LAA, ovl.fmt.RSY.r1,
13622 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13623 ovl.fmt.RSY.dl2,
13624 ovl.fmt.RSY.dh2); goto ok;
13625 case 0xeb00000000faULL: s390_format_RSY_RRRD(s390_irgen_LAAL, ovl.fmt.RSY.r1,
13626 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13627 ovl.fmt.RSY.dl2,
13628 ovl.fmt.RSY.dh2); goto ok;
13629 case 0xec0000000044ULL: s390_format_RIE_RRP(s390_irgen_BRXHG, ovl.fmt.RIE.r1,
13630 ovl.fmt.RIE.r3, ovl.fmt.RIE.i2);
13631 goto ok;
13632 case 0xec0000000045ULL: s390_format_RIE_RRP(s390_irgen_BRXLG, ovl.fmt.RIE.r1,
13633 ovl.fmt.RIE.r3, ovl.fmt.RIE.i2);
13634 goto ok;
13635 case 0xec0000000051ULL: /* RISBLG */ goto unimplemented;
13636 case 0xec0000000054ULL: s390_format_RIE_RRUUU(s390_irgen_RNSBG,
13637 ovl.fmt.RIE_RRUUU.r1,
13638 ovl.fmt.RIE_RRUUU.r2,
13639 ovl.fmt.RIE_RRUUU.i3,
13640 ovl.fmt.RIE_RRUUU.i4,
13641 ovl.fmt.RIE_RRUUU.i5);
13642 goto ok;
13643 case 0xec0000000055ULL: s390_format_RIE_RRUUU(s390_irgen_RISBG,
13644 ovl.fmt.RIE_RRUUU.r1,
13645 ovl.fmt.RIE_RRUUU.r2,
13646 ovl.fmt.RIE_RRUUU.i3,
13647 ovl.fmt.RIE_RRUUU.i4,
13648 ovl.fmt.RIE_RRUUU.i5);
13649 goto ok;
13650 case 0xec0000000056ULL: s390_format_RIE_RRUUU(s390_irgen_ROSBG,
13651 ovl.fmt.RIE_RRUUU.r1,
13652 ovl.fmt.RIE_RRUUU.r2,
13653 ovl.fmt.RIE_RRUUU.i3,
13654 ovl.fmt.RIE_RRUUU.i4,
13655 ovl.fmt.RIE_RRUUU.i5);
13656 goto ok;
13657 case 0xec0000000057ULL: s390_format_RIE_RRUUU(s390_irgen_RXSBG,
13658 ovl.fmt.RIE_RRUUU.r1,
13659 ovl.fmt.RIE_RRUUU.r2,
13660 ovl.fmt.RIE_RRUUU.i3,
13661 ovl.fmt.RIE_RRUUU.i4,
13662 ovl.fmt.RIE_RRUUU.i5);
13663 goto ok;
13664 case 0xec000000005dULL: /* RISBHG */ goto unimplemented;
13665 case 0xec0000000064ULL: s390_format_RIE_RRPU(s390_irgen_CGRJ,
13666 ovl.fmt.RIE_RRPU.r1,
13667 ovl.fmt.RIE_RRPU.r2,
13668 ovl.fmt.RIE_RRPU.i4,
13669 ovl.fmt.RIE_RRPU.m3); goto ok;
13670 case 0xec0000000065ULL: s390_format_RIE_RRPU(s390_irgen_CLGRJ,
13671 ovl.fmt.RIE_RRPU.r1,
13672 ovl.fmt.RIE_RRPU.r2,
13673 ovl.fmt.RIE_RRPU.i4,
13674 ovl.fmt.RIE_RRPU.m3); goto ok;
13675 case 0xec0000000070ULL: /* CGIT */ goto unimplemented;
13676 case 0xec0000000071ULL: /* CLGIT */ goto unimplemented;
13677 case 0xec0000000072ULL: /* CIT */ goto unimplemented;
13678 case 0xec0000000073ULL: /* CLFIT */ goto unimplemented;
13679 case 0xec0000000076ULL: s390_format_RIE_RRPU(s390_irgen_CRJ,
13680 ovl.fmt.RIE_RRPU.r1,
13681 ovl.fmt.RIE_RRPU.r2,
13682 ovl.fmt.RIE_RRPU.i4,
13683 ovl.fmt.RIE_RRPU.m3); goto ok;
13684 case 0xec0000000077ULL: s390_format_RIE_RRPU(s390_irgen_CLRJ,
13685 ovl.fmt.RIE_RRPU.r1,
13686 ovl.fmt.RIE_RRPU.r2,
13687 ovl.fmt.RIE_RRPU.i4,
13688 ovl.fmt.RIE_RRPU.m3); goto ok;
13689 case 0xec000000007cULL: s390_format_RIE_RUPI(s390_irgen_CGIJ,
13690 ovl.fmt.RIEv3.r1,
13691 ovl.fmt.RIEv3.m3,
13692 ovl.fmt.RIEv3.i4,
13693 ovl.fmt.RIEv3.i2); goto ok;
13694 case 0xec000000007dULL: s390_format_RIE_RUPU(s390_irgen_CLGIJ,
13695 ovl.fmt.RIEv3.r1,
13696 ovl.fmt.RIEv3.m3,
13697 ovl.fmt.RIEv3.i4,
13698 ovl.fmt.RIEv3.i2); goto ok;
13699 case 0xec000000007eULL: s390_format_RIE_RUPI(s390_irgen_CIJ,
13700 ovl.fmt.RIEv3.r1,
13701 ovl.fmt.RIEv3.m3,
13702 ovl.fmt.RIEv3.i4,
13703 ovl.fmt.RIEv3.i2); goto ok;
13704 case 0xec000000007fULL: s390_format_RIE_RUPU(s390_irgen_CLIJ,
13705 ovl.fmt.RIEv3.r1,
13706 ovl.fmt.RIEv3.m3,
13707 ovl.fmt.RIEv3.i4,
13708 ovl.fmt.RIEv3.i2); goto ok;
13709 case 0xec00000000d8ULL: s390_format_RIE_RRI0(s390_irgen_AHIK, ovl.fmt.RIE.r1,
13710 ovl.fmt.RIE.r3, ovl.fmt.RIE.i2);
13711 goto ok;
13712 case 0xec00000000d9ULL: s390_format_RIE_RRI0(s390_irgen_AGHIK,
13713 ovl.fmt.RIE.r1, ovl.fmt.RIE.r3,
13714 ovl.fmt.RIE.i2); goto ok;
13715 case 0xec00000000daULL: s390_format_RIE_RRI0(s390_irgen_ALHSIK,
13716 ovl.fmt.RIE.r1, ovl.fmt.RIE.r3,
13717 ovl.fmt.RIE.i2); goto ok;
13718 case 0xec00000000dbULL: s390_format_RIE_RRI0(s390_irgen_ALGHSIK,
13719 ovl.fmt.RIE.r1, ovl.fmt.RIE.r3,
13720 ovl.fmt.RIE.i2); goto ok;
13721 case 0xec00000000e4ULL: s390_format_RRS(s390_irgen_CGRB, ovl.fmt.RRS.r1,
13722 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
13723 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
13724 goto ok;
13725 case 0xec00000000e5ULL: s390_format_RRS(s390_irgen_CLGRB, ovl.fmt.RRS.r1,
13726 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
13727 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
13728 goto ok;
13729 case 0xec00000000f6ULL: s390_format_RRS(s390_irgen_CRB, ovl.fmt.RRS.r1,
13730 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
13731 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
13732 goto ok;
13733 case 0xec00000000f7ULL: s390_format_RRS(s390_irgen_CLRB, ovl.fmt.RRS.r1,
13734 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
13735 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
13736 goto ok;
13737 case 0xec00000000fcULL: s390_format_RIS_RURDI(s390_irgen_CGIB,
13738 ovl.fmt.RIS.r1, ovl.fmt.RIS.m3,
13739 ovl.fmt.RIS.b4, ovl.fmt.RIS.d4,
13740 ovl.fmt.RIS.i2); goto ok;
13741 case 0xec00000000fdULL: s390_format_RIS_RURDU(s390_irgen_CLGIB,
13742 ovl.fmt.RIS.r1, ovl.fmt.RIS.m3,
13743 ovl.fmt.RIS.b4, ovl.fmt.RIS.d4,
13744 ovl.fmt.RIS.i2); goto ok;
13745 case 0xec00000000feULL: s390_format_RIS_RURDI(s390_irgen_CIB, ovl.fmt.RIS.r1,
13746 ovl.fmt.RIS.m3, ovl.fmt.RIS.b4,
13747 ovl.fmt.RIS.d4,
13748 ovl.fmt.RIS.i2); goto ok;
13749 case 0xec00000000ffULL: s390_format_RIS_RURDU(s390_irgen_CLIB,
13750 ovl.fmt.RIS.r1, ovl.fmt.RIS.m3,
13751 ovl.fmt.RIS.b4, ovl.fmt.RIS.d4,
13752 ovl.fmt.RIS.i2); goto ok;
13753 case 0xed0000000004ULL: s390_format_RXE_FRRD(s390_irgen_LDEB, ovl.fmt.RXE.r1,
13754 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
13755 ovl.fmt.RXE.d2); goto ok;
13756 case 0xed0000000005ULL: s390_format_RXE_FRRD(s390_irgen_LXDB, ovl.fmt.RXE.r1,
13757 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
13758 ovl.fmt.RXE.d2); goto ok;
13759 case 0xed0000000006ULL: s390_format_RXE_FRRD(s390_irgen_LXEB, ovl.fmt.RXE.r1,
13760 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
13761 ovl.fmt.RXE.d2); goto ok;
13762 case 0xed0000000007ULL: /* MXDB */ goto unimplemented;
13763 case 0xed0000000008ULL: /* KEB */ goto unimplemented;
13764 case 0xed0000000009ULL: s390_format_RXE_FRRD(s390_irgen_CEB, ovl.fmt.RXE.r1,
13765 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
13766 ovl.fmt.RXE.d2); goto ok;
13767 case 0xed000000000aULL: s390_format_RXE_FRRD(s390_irgen_AEB, ovl.fmt.RXE.r1,
13768 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
13769 ovl.fmt.RXE.d2); goto ok;
13770 case 0xed000000000bULL: s390_format_RXE_FRRD(s390_irgen_SEB, ovl.fmt.RXE.r1,
13771 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
13772 ovl.fmt.RXE.d2); goto ok;
13773 case 0xed000000000cULL: /* MDEB */ goto unimplemented;
13774 case 0xed000000000dULL: s390_format_RXE_FRRD(s390_irgen_DEB, ovl.fmt.RXE.r1,
13775 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
13776 ovl.fmt.RXE.d2); goto ok;
13777 case 0xed000000000eULL: s390_format_RXF_FRRDF(s390_irgen_MAEB,
13778 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
13779 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
13780 ovl.fmt.RXF.r1); goto ok;
13781 case 0xed000000000fULL: s390_format_RXF_FRRDF(s390_irgen_MSEB,
13782 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
13783 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
13784 ovl.fmt.RXF.r1); goto ok;
13785 case 0xed0000000010ULL: s390_format_RXE_FRRD(s390_irgen_TCEB, ovl.fmt.RXE.r1,
13786 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
13787 ovl.fmt.RXE.d2); goto ok;
13788 case 0xed0000000011ULL: s390_format_RXE_FRRD(s390_irgen_TCDB, ovl.fmt.RXE.r1,
13789 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
13790 ovl.fmt.RXE.d2); goto ok;
13791 case 0xed0000000012ULL: s390_format_RXE_FRRD(s390_irgen_TCXB, ovl.fmt.RXE.r1,
13792 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
13793 ovl.fmt.RXE.d2); goto ok;
13794 case 0xed0000000014ULL: s390_format_RXE_FRRD(s390_irgen_SQEB, ovl.fmt.RXE.r1,
13795 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
13796 ovl.fmt.RXE.d2); goto ok;
13797 case 0xed0000000015ULL: s390_format_RXE_FRRD(s390_irgen_SQDB, ovl.fmt.RXE.r1,
13798 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
13799 ovl.fmt.RXE.d2); goto ok;
13800 case 0xed0000000017ULL: s390_format_RXE_FRRD(s390_irgen_MEEB, ovl.fmt.RXE.r1,
13801 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
13802 ovl.fmt.RXE.d2); goto ok;
13803 case 0xed0000000018ULL: /* KDB */ goto unimplemented;
13804 case 0xed0000000019ULL: s390_format_RXE_FRRD(s390_irgen_CDB, ovl.fmt.RXE.r1,
13805 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
13806 ovl.fmt.RXE.d2); goto ok;
13807 case 0xed000000001aULL: s390_format_RXE_FRRD(s390_irgen_ADB, ovl.fmt.RXE.r1,
13808 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
13809 ovl.fmt.RXE.d2); goto ok;
13810 case 0xed000000001bULL: s390_format_RXE_FRRD(s390_irgen_SDB, ovl.fmt.RXE.r1,
13811 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
13812 ovl.fmt.RXE.d2); goto ok;
13813 case 0xed000000001cULL: s390_format_RXE_FRRD(s390_irgen_MDB, ovl.fmt.RXE.r1,
13814 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
13815 ovl.fmt.RXE.d2); goto ok;
13816 case 0xed000000001dULL: s390_format_RXE_FRRD(s390_irgen_DDB, ovl.fmt.RXE.r1,
13817 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
13818 ovl.fmt.RXE.d2); goto ok;
13819 case 0xed000000001eULL: s390_format_RXF_FRRDF(s390_irgen_MADB,
13820 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
13821 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
13822 ovl.fmt.RXF.r1); goto ok;
13823 case 0xed000000001fULL: s390_format_RXF_FRRDF(s390_irgen_MSDB,
13824 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
13825 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
13826 ovl.fmt.RXF.r1); goto ok;
13827 case 0xed0000000024ULL: /* LDE */ goto unimplemented;
13828 case 0xed0000000025ULL: /* LXD */ goto unimplemented;
13829 case 0xed0000000026ULL: /* LXE */ goto unimplemented;
13830 case 0xed000000002eULL: /* MAE */ goto unimplemented;
13831 case 0xed000000002fULL: /* MSE */ goto unimplemented;
13832 case 0xed0000000034ULL: /* SQE */ goto unimplemented;
13833 case 0xed0000000035ULL: /* SQD */ goto unimplemented;
13834 case 0xed0000000037ULL: /* MEE */ goto unimplemented;
13835 case 0xed0000000038ULL: /* MAYL */ goto unimplemented;
13836 case 0xed0000000039ULL: /* MYL */ goto unimplemented;
13837 case 0xed000000003aULL: /* MAY */ goto unimplemented;
13838 case 0xed000000003bULL: /* MY */ goto unimplemented;
13839 case 0xed000000003cULL: /* MAYH */ goto unimplemented;
13840 case 0xed000000003dULL: /* MYH */ goto unimplemented;
13841 case 0xed000000003eULL: /* MAD */ goto unimplemented;
13842 case 0xed000000003fULL: /* MSD */ goto unimplemented;
13843 case 0xed0000000040ULL: /* SLDT */ goto unimplemented;
13844 case 0xed0000000041ULL: /* SRDT */ goto unimplemented;
13845 case 0xed0000000048ULL: /* SLXT */ goto unimplemented;
13846 case 0xed0000000049ULL: /* SRXT */ goto unimplemented;
13847 case 0xed0000000050ULL: /* TDCET */ goto unimplemented;
13848 case 0xed0000000051ULL: /* TDGET */ goto unimplemented;
13849 case 0xed0000000054ULL: /* TDCDT */ goto unimplemented;
13850 case 0xed0000000055ULL: /* TDGDT */ goto unimplemented;
13851 case 0xed0000000058ULL: /* TDCXT */ goto unimplemented;
13852 case 0xed0000000059ULL: /* TDGXT */ goto unimplemented;
13853 case 0xed0000000064ULL: s390_format_RXY_FRRD(s390_irgen_LEY, ovl.fmt.RXY.r1,
13854 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13855 ovl.fmt.RXY.dl2,
13856 ovl.fmt.RXY.dh2); goto ok;
13857 case 0xed0000000065ULL: s390_format_RXY_FRRD(s390_irgen_LDY, ovl.fmt.RXY.r1,
13858 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13859 ovl.fmt.RXY.dl2,
13860 ovl.fmt.RXY.dh2); goto ok;
13861 case 0xed0000000066ULL: s390_format_RXY_FRRD(s390_irgen_STEY, ovl.fmt.RXY.r1,
13862 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13863 ovl.fmt.RXY.dl2,
13864 ovl.fmt.RXY.dh2); goto ok;
13865 case 0xed0000000067ULL: s390_format_RXY_FRRD(s390_irgen_STDY, ovl.fmt.RXY.r1,
13866 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13867 ovl.fmt.RXY.dl2,
13868 ovl.fmt.RXY.dh2); goto ok;
13869 }
13870
13871 switch (((ovl.value >> 16) & 0xff0f00000000ULL) >> 32) {
13872 case 0xc000ULL: s390_format_RIL_RP(s390_irgen_LARL, ovl.fmt.RIL.r1,
13873 ovl.fmt.RIL.i2); goto ok;
13874 case 0xc001ULL: s390_format_RIL_RI(s390_irgen_LGFI, ovl.fmt.RIL.r1,
13875 ovl.fmt.RIL.i2); goto ok;
13876 case 0xc004ULL: s390_format_RIL(s390_irgen_BRCL, ovl.fmt.RIL.r1,
13877 ovl.fmt.RIL.i2); goto ok;
13878 case 0xc005ULL: s390_format_RIL_RP(s390_irgen_BRASL, ovl.fmt.RIL.r1,
13879 ovl.fmt.RIL.i2); goto ok;
13880 case 0xc006ULL: s390_format_RIL_RU(s390_irgen_XIHF, ovl.fmt.RIL.r1,
13881 ovl.fmt.RIL.i2); goto ok;
13882 case 0xc007ULL: s390_format_RIL_RU(s390_irgen_XILF, ovl.fmt.RIL.r1,
13883 ovl.fmt.RIL.i2); goto ok;
13884 case 0xc008ULL: s390_format_RIL_RU(s390_irgen_IIHF, ovl.fmt.RIL.r1,
13885 ovl.fmt.RIL.i2); goto ok;
13886 case 0xc009ULL: s390_format_RIL_RU(s390_irgen_IILF, ovl.fmt.RIL.r1,
13887 ovl.fmt.RIL.i2); goto ok;
13888 case 0xc00aULL: s390_format_RIL_RU(s390_irgen_NIHF, ovl.fmt.RIL.r1,
13889 ovl.fmt.RIL.i2); goto ok;
13890 case 0xc00bULL: s390_format_RIL_RU(s390_irgen_NILF, ovl.fmt.RIL.r1,
13891 ovl.fmt.RIL.i2); goto ok;
13892 case 0xc00cULL: s390_format_RIL_RU(s390_irgen_OIHF, ovl.fmt.RIL.r1,
13893 ovl.fmt.RIL.i2); goto ok;
13894 case 0xc00dULL: s390_format_RIL_RU(s390_irgen_OILF, ovl.fmt.RIL.r1,
13895 ovl.fmt.RIL.i2); goto ok;
13896 case 0xc00eULL: s390_format_RIL_RU(s390_irgen_LLIHF, ovl.fmt.RIL.r1,
13897 ovl.fmt.RIL.i2); goto ok;
13898 case 0xc00fULL: s390_format_RIL_RU(s390_irgen_LLILF, ovl.fmt.RIL.r1,
13899 ovl.fmt.RIL.i2); goto ok;
13900 case 0xc200ULL: s390_format_RIL_RI(s390_irgen_MSGFI, ovl.fmt.RIL.r1,
13901 ovl.fmt.RIL.i2); goto ok;
13902 case 0xc201ULL: s390_format_RIL_RI(s390_irgen_MSFI, ovl.fmt.RIL.r1,
13903 ovl.fmt.RIL.i2); goto ok;
13904 case 0xc204ULL: s390_format_RIL_RU(s390_irgen_SLGFI, ovl.fmt.RIL.r1,
13905 ovl.fmt.RIL.i2); goto ok;
13906 case 0xc205ULL: s390_format_RIL_RU(s390_irgen_SLFI, ovl.fmt.RIL.r1,
13907 ovl.fmt.RIL.i2); goto ok;
13908 case 0xc208ULL: s390_format_RIL_RI(s390_irgen_AGFI, ovl.fmt.RIL.r1,
13909 ovl.fmt.RIL.i2); goto ok;
13910 case 0xc209ULL: s390_format_RIL_RI(s390_irgen_AFI, ovl.fmt.RIL.r1,
13911 ovl.fmt.RIL.i2); goto ok;
13912 case 0xc20aULL: s390_format_RIL_RU(s390_irgen_ALGFI, ovl.fmt.RIL.r1,
13913 ovl.fmt.RIL.i2); goto ok;
13914 case 0xc20bULL: s390_format_RIL_RU(s390_irgen_ALFI, ovl.fmt.RIL.r1,
13915 ovl.fmt.RIL.i2); goto ok;
13916 case 0xc20cULL: s390_format_RIL_RI(s390_irgen_CGFI, ovl.fmt.RIL.r1,
13917 ovl.fmt.RIL.i2); goto ok;
13918 case 0xc20dULL: s390_format_RIL_RI(s390_irgen_CFI, ovl.fmt.RIL.r1,
13919 ovl.fmt.RIL.i2); goto ok;
13920 case 0xc20eULL: s390_format_RIL_RU(s390_irgen_CLGFI, ovl.fmt.RIL.r1,
13921 ovl.fmt.RIL.i2); goto ok;
13922 case 0xc20fULL: s390_format_RIL_RU(s390_irgen_CLFI, ovl.fmt.RIL.r1,
13923 ovl.fmt.RIL.i2); goto ok;
13924 case 0xc402ULL: s390_format_RIL_RP(s390_irgen_LLHRL, ovl.fmt.RIL.r1,
13925 ovl.fmt.RIL.i2); goto ok;
13926 case 0xc404ULL: s390_format_RIL_RP(s390_irgen_LGHRL, ovl.fmt.RIL.r1,
13927 ovl.fmt.RIL.i2); goto ok;
13928 case 0xc405ULL: s390_format_RIL_RP(s390_irgen_LHRL, ovl.fmt.RIL.r1,
13929 ovl.fmt.RIL.i2); goto ok;
13930 case 0xc406ULL: s390_format_RIL_RP(s390_irgen_LLGHRL, ovl.fmt.RIL.r1,
13931 ovl.fmt.RIL.i2); goto ok;
13932 case 0xc407ULL: s390_format_RIL_RP(s390_irgen_STHRL, ovl.fmt.RIL.r1,
13933 ovl.fmt.RIL.i2); goto ok;
13934 case 0xc408ULL: s390_format_RIL_RP(s390_irgen_LGRL, ovl.fmt.RIL.r1,
13935 ovl.fmt.RIL.i2); goto ok;
13936 case 0xc40bULL: s390_format_RIL_RP(s390_irgen_STGRL, ovl.fmt.RIL.r1,
13937 ovl.fmt.RIL.i2); goto ok;
13938 case 0xc40cULL: s390_format_RIL_RP(s390_irgen_LGFRL, ovl.fmt.RIL.r1,
13939 ovl.fmt.RIL.i2); goto ok;
13940 case 0xc40dULL: s390_format_RIL_RP(s390_irgen_LRL, ovl.fmt.RIL.r1,
13941 ovl.fmt.RIL.i2); goto ok;
13942 case 0xc40eULL: s390_format_RIL_RP(s390_irgen_LLGFRL, ovl.fmt.RIL.r1,
13943 ovl.fmt.RIL.i2); goto ok;
13944 case 0xc40fULL: s390_format_RIL_RP(s390_irgen_STRL, ovl.fmt.RIL.r1,
13945 ovl.fmt.RIL.i2); goto ok;
13946 case 0xc600ULL: s390_format_RIL_RP(s390_irgen_EXRL, ovl.fmt.RIL.r1,
13947 ovl.fmt.RIL.i2); goto ok;
13948 case 0xc602ULL: s390_format_RIL_UP(s390_irgen_PFDRL, ovl.fmt.RIL.r1,
13949 ovl.fmt.RIL.i2); goto ok;
13950 case 0xc604ULL: s390_format_RIL_RP(s390_irgen_CGHRL, ovl.fmt.RIL.r1,
13951 ovl.fmt.RIL.i2); goto ok;
13952 case 0xc605ULL: s390_format_RIL_RP(s390_irgen_CHRL, ovl.fmt.RIL.r1,
13953 ovl.fmt.RIL.i2); goto ok;
13954 case 0xc606ULL: s390_format_RIL_RP(s390_irgen_CLGHRL, ovl.fmt.RIL.r1,
13955 ovl.fmt.RIL.i2); goto ok;
13956 case 0xc607ULL: s390_format_RIL_RP(s390_irgen_CLHRL, ovl.fmt.RIL.r1,
13957 ovl.fmt.RIL.i2); goto ok;
13958 case 0xc608ULL: s390_format_RIL_RP(s390_irgen_CGRL, ovl.fmt.RIL.r1,
13959 ovl.fmt.RIL.i2); goto ok;
13960 case 0xc60aULL: s390_format_RIL_RP(s390_irgen_CLGRL, ovl.fmt.RIL.r1,
13961 ovl.fmt.RIL.i2); goto ok;
13962 case 0xc60cULL: s390_format_RIL_RP(s390_irgen_CGFRL, ovl.fmt.RIL.r1,
13963 ovl.fmt.RIL.i2); goto ok;
13964 case 0xc60dULL: s390_format_RIL_RP(s390_irgen_CRL, ovl.fmt.RIL.r1,
13965 ovl.fmt.RIL.i2); goto ok;
13966 case 0xc60eULL: s390_format_RIL_RP(s390_irgen_CLGFRL, ovl.fmt.RIL.r1,
13967 ovl.fmt.RIL.i2); goto ok;
13968 case 0xc60fULL: s390_format_RIL_RP(s390_irgen_CLRL, ovl.fmt.RIL.r1,
13969 ovl.fmt.RIL.i2); goto ok;
13970 case 0xc800ULL: /* MVCOS */ goto unimplemented;
13971 case 0xc801ULL: /* ECTG */ goto unimplemented;
13972 case 0xc802ULL: /* CSST */ goto unimplemented;
13973 case 0xc804ULL: /* LPD */ goto unimplemented;
13974 case 0xc805ULL: /* LPDG */ goto unimplemented;
13975 case 0xcc06ULL: /* BRCTH */ goto unimplemented;
13976 case 0xcc08ULL: s390_format_RIL_RI(s390_irgen_AIH, ovl.fmt.RIL.r1,
13977 ovl.fmt.RIL.i2); goto ok;
13978 case 0xcc0aULL: s390_format_RIL_RI(s390_irgen_ALSIH, ovl.fmt.RIL.r1,
13979 ovl.fmt.RIL.i2); goto ok;
13980 case 0xcc0bULL: s390_format_RIL_RI(s390_irgen_ALSIHN, ovl.fmt.RIL.r1,
13981 ovl.fmt.RIL.i2); goto ok;
13982 case 0xcc0dULL: s390_format_RIL_RI(s390_irgen_CIH, ovl.fmt.RIL.r1,
13983 ovl.fmt.RIL.i2); goto ok;
13984 case 0xcc0fULL: s390_format_RIL_RU(s390_irgen_CLIH, ovl.fmt.RIL.r1,
13985 ovl.fmt.RIL.i2); goto ok;
13986 }
13987
13988 switch (((ovl.value >> 16) & 0xff0000000000ULL) >> 40) {
13989 case 0xd0ULL: /* TRTR */ goto unimplemented;
13990 case 0xd1ULL: /* MVN */ goto unimplemented;
13991 case 0xd2ULL: s390_format_SS_L0RDRD(s390_irgen_MVC, ovl.fmt.SS.l,
13992 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
13993 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
13994 case 0xd3ULL: /* MVZ */ goto unimplemented;
13995 case 0xd4ULL: s390_format_SS_L0RDRD(s390_irgen_NC, ovl.fmt.SS.l,
13996 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
13997 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
13998 case 0xd5ULL: s390_format_SS_L0RDRD(s390_irgen_CLC, ovl.fmt.SS.l,
13999 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
14000 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
14001 case 0xd6ULL: s390_format_SS_L0RDRD(s390_irgen_OC, ovl.fmt.SS.l,
14002 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
14003 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
sewardjb63967e2011-03-24 08:50:04 +000014004 case 0xd7ULL:
14005 if (ovl.fmt.SS.b1 == ovl.fmt.SS.b2 && ovl.fmt.SS.d1 == ovl.fmt.SS.d2)
14006 s390_irgen_XC_sameloc(ovl.fmt.SS.l, ovl.fmt.SS.b1, ovl.fmt.SS.d1);
14007 else
14008 s390_format_SS_L0RDRD(s390_irgen_XC, ovl.fmt.SS.l,
14009 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
14010 ovl.fmt.SS.b2, ovl.fmt.SS.d2);
14011 goto ok;
sewardj2019a972011-03-07 16:04:07 +000014012 case 0xd9ULL: /* MVCK */ goto unimplemented;
14013 case 0xdaULL: /* MVCP */ goto unimplemented;
14014 case 0xdbULL: /* MVCS */ goto unimplemented;
florian730448f2012-02-04 17:07:07 +000014015 case 0xdcULL: s390_format_SS_L0RDRD(s390_irgen_TR, ovl.fmt.SS.l,
14016 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
14017 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014018 case 0xddULL: /* TRT */ goto unimplemented;
14019 case 0xdeULL: /* ED */ goto unimplemented;
14020 case 0xdfULL: /* EDMK */ goto unimplemented;
14021 case 0xe1ULL: /* PKU */ goto unimplemented;
14022 case 0xe2ULL: /* UNPKU */ goto unimplemented;
14023 case 0xe8ULL: /* MVCIN */ goto unimplemented;
14024 case 0xe9ULL: /* PKA */ goto unimplemented;
14025 case 0xeaULL: /* UNPKA */ goto unimplemented;
14026 case 0xeeULL: /* PLO */ goto unimplemented;
14027 case 0xefULL: /* LMD */ goto unimplemented;
14028 case 0xf0ULL: /* SRP */ goto unimplemented;
14029 case 0xf1ULL: /* MVO */ goto unimplemented;
14030 case 0xf2ULL: /* PACK */ goto unimplemented;
14031 case 0xf3ULL: /* UNPK */ goto unimplemented;
14032 case 0xf8ULL: /* ZAP */ goto unimplemented;
14033 case 0xf9ULL: /* CP */ goto unimplemented;
14034 case 0xfaULL: /* AP */ goto unimplemented;
14035 case 0xfbULL: /* SP */ goto unimplemented;
14036 case 0xfcULL: /* MP */ goto unimplemented;
14037 case 0xfdULL: /* DP */ goto unimplemented;
14038 }
14039
14040 switch (((ovl.value >> 16) & 0xffff00000000ULL) >> 32) {
14041 case 0xe500ULL: /* LASP */ goto unimplemented;
14042 case 0xe501ULL: /* TPROT */ goto unimplemented;
14043 case 0xe502ULL: /* STRAG */ goto unimplemented;
14044 case 0xe50eULL: /* MVCSK */ goto unimplemented;
14045 case 0xe50fULL: /* MVCDK */ goto unimplemented;
14046 case 0xe544ULL: s390_format_SIL_RDI(s390_irgen_MVHHI, ovl.fmt.SIL.b1,
14047 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14048 goto ok;
14049 case 0xe548ULL: s390_format_SIL_RDI(s390_irgen_MVGHI, ovl.fmt.SIL.b1,
14050 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14051 goto ok;
14052 case 0xe54cULL: s390_format_SIL_RDI(s390_irgen_MVHI, ovl.fmt.SIL.b1,
14053 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14054 goto ok;
14055 case 0xe554ULL: s390_format_SIL_RDI(s390_irgen_CHHSI, ovl.fmt.SIL.b1,
14056 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14057 goto ok;
14058 case 0xe555ULL: s390_format_SIL_RDU(s390_irgen_CLHHSI, ovl.fmt.SIL.b1,
14059 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14060 goto ok;
14061 case 0xe558ULL: s390_format_SIL_RDI(s390_irgen_CGHSI, ovl.fmt.SIL.b1,
14062 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14063 goto ok;
14064 case 0xe559ULL: s390_format_SIL_RDU(s390_irgen_CLGHSI, ovl.fmt.SIL.b1,
14065 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14066 goto ok;
14067 case 0xe55cULL: s390_format_SIL_RDI(s390_irgen_CHSI, ovl.fmt.SIL.b1,
14068 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14069 goto ok;
14070 case 0xe55dULL: s390_format_SIL_RDU(s390_irgen_CLFHSI, ovl.fmt.SIL.b1,
14071 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14072 goto ok;
14073 }
14074
14075 return S390_DECODE_UNKNOWN_INSN;
14076
14077ok:
14078 return S390_DECODE_OK;
14079
14080unimplemented:
14081 return S390_DECODE_UNIMPLEMENTED_INSN;
14082}
14083
14084/* Handle "special" instructions. */
14085static s390_decode_t
14086s390_decode_special_and_irgen(UChar *bytes)
14087{
14088 s390_decode_t status = S390_DECODE_OK;
14089
14090 /* Got a "Special" instruction preamble. Which one is it? */
14091 if (bytes[0] == 0x18 && bytes[1] == 0x22 /* lr %r2, %r2 */) {
14092 s390_irgen_client_request();
14093 } else if (bytes[0] == 0x18 && bytes[1] == 0x33 /* lr %r3, %r3 */) {
14094 s390_irgen_guest_NRADDR();
14095 } else if (bytes[0] == 0x18 && bytes[1] == 0x44 /* lr %r4, %r4 */) {
14096 s390_irgen_call_noredir();
14097 } else {
14098 /* We don't know what it is. */
14099 return S390_DECODE_UNKNOWN_SPECIAL_INSN;
14100 }
14101
14102 dis_res->len = S390_SPECIAL_OP_PREAMBLE_SIZE + S390_SPECIAL_OP_SIZE;
14103
14104 return status;
14105}
14106
14107
14108/* Function returns # bytes that were decoded or 0 in case of failure */
florianb4df7682011-07-05 02:09:01 +000014109static UInt
sewardj2019a972011-03-07 16:04:07 +000014110s390_decode_and_irgen(UChar *bytes, UInt insn_length, DisResult *dres)
14111{
14112 s390_decode_t status;
14113
14114 dis_res = dres;
14115
14116 /* Spot the 8-byte preamble: 18ff lr r15,r15
14117 1811 lr r1,r1
14118 1822 lr r2,r2
14119 1833 lr r3,r3 */
14120 if (bytes[ 0] == 0x18 && bytes[ 1] == 0xff && bytes[ 2] == 0x18 &&
14121 bytes[ 3] == 0x11 && bytes[ 4] == 0x18 && bytes[ 5] == 0x22 &&
14122 bytes[ 6] == 0x18 && bytes[ 7] == 0x33) {
14123
14124 /* Handle special instruction that follows that preamble. */
14125 if (0) vex_printf("special function handling...\n");
florian2c8ed942011-08-01 22:07:51 +000014126
14127 insn_length = S390_SPECIAL_OP_PREAMBLE_SIZE + S390_SPECIAL_OP_SIZE;
14128 guest_IA_next_instr = guest_IA_curr_instr + insn_length;
14129
14130 status =
14131 s390_decode_special_and_irgen(bytes + S390_SPECIAL_OP_PREAMBLE_SIZE);
sewardj2019a972011-03-07 16:04:07 +000014132 } else {
14133 /* Handle normal instructions. */
14134 switch (insn_length) {
14135 case 2:
14136 status = s390_decode_2byte_and_irgen(bytes);
14137 break;
14138
14139 case 4:
14140 status = s390_decode_4byte_and_irgen(bytes);
14141 break;
14142
14143 case 6:
14144 status = s390_decode_6byte_and_irgen(bytes);
14145 break;
14146
14147 default:
14148 status = S390_DECODE_ERROR;
14149 break;
14150 }
14151 }
florian5fcbba22011-07-27 20:40:22 +000014152 /* If next instruction is execute, stop here */
florianf9e1ed72012-04-17 02:41:56 +000014153 if (dis_res->whatNext == Dis_Continue && bytes[insn_length] == 0x44) {
14154 put_IA(mkaddr_expr(guest_IA_next_instr));
sewardj2019a972011-03-07 16:04:07 +000014155 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +000014156 dis_res->jk_StopHere = Ijk_Boring;
sewardj2019a972011-03-07 16:04:07 +000014157 }
14158
14159 if (status == S390_DECODE_OK) return insn_length; /* OK */
14160
14161 /* Decoding failed somehow */
14162 vex_printf("vex s390->IR: ");
14163 switch (status) {
14164 case S390_DECODE_UNKNOWN_INSN:
14165 vex_printf("unknown insn: ");
14166 break;
14167
14168 case S390_DECODE_UNIMPLEMENTED_INSN:
14169 vex_printf("unimplemented insn: ");
14170 break;
14171
14172 case S390_DECODE_UNKNOWN_SPECIAL_INSN:
14173 vex_printf("unimplemented special insn: ");
14174 break;
14175
14176 default:
14177 case S390_DECODE_ERROR:
14178 vex_printf("decoding error: ");
14179 break;
14180 }
14181
14182 vex_printf("%02x%02x", bytes[0], bytes[1]);
14183 if (insn_length > 2) {
14184 vex_printf(" %02x%02x", bytes[2], bytes[3]);
14185 }
14186 if (insn_length > 4) {
14187 vex_printf(" %02x%02x", bytes[4], bytes[5]);
14188 }
14189 vex_printf("\n");
14190
14191 return 0; /* Failed */
14192}
14193
14194
sewardj2019a972011-03-07 16:04:07 +000014195/* Disassemble a single instruction INSN into IR. */
14196static DisResult
florian420c5012011-07-22 02:12:28 +000014197disInstr_S390_WRK(UChar *insn)
sewardj2019a972011-03-07 16:04:07 +000014198{
14199 UChar byte;
14200 UInt insn_length;
14201 DisResult dres;
14202
14203 /* ---------------------------------------------------- */
14204 /* --- Compute instruction length -- */
14205 /* ---------------------------------------------------- */
14206
14207 /* Get the first byte of the insn. */
14208 byte = insn[0];
14209
14210 /* The leftmost two bits (0:1) encode the length of the insn in bytes.
14211 00 -> 2 bytes, 01 -> 4 bytes, 10 -> 4 bytes, 11 -> 6 bytes. */
14212 insn_length = ((((byte >> 6) + 1) >> 1) + 1) << 1;
14213
14214 guest_IA_next_instr = guest_IA_curr_instr + insn_length;
14215
14216 /* ---------------------------------------------------- */
14217 /* --- Initialise the DisResult data -- */
14218 /* ---------------------------------------------------- */
14219 dres.whatNext = Dis_Continue;
14220 dres.len = insn_length;
14221 dres.continueAt = 0;
florian8844a632012-04-13 04:04:06 +000014222 dres.jk_StopHere = Ijk_INVALID;
sewardj2019a972011-03-07 16:04:07 +000014223
floriana99f20e2011-07-17 14:16:41 +000014224 /* fixs390: consider chasing of conditional jumps */
14225
sewardj2019a972011-03-07 16:04:07 +000014226 /* Normal and special instruction handling starts here. */
14227 if (s390_decode_and_irgen(insn, insn_length, &dres) == 0) {
14228 /* All decode failures end up here. The decoder has already issued an
14229 error message.
14230 Tell the dispatcher that this insn cannot be decoded, and so has
florian342e01a2012-07-26 02:37:49 +000014231 not been executed, and (is currently) the next to be executed.
14232 The insn address in the guest state needs to be set to
14233 guest_IA_curr_instr, otherwise the complaint will report an
14234 incorrect address. */
14235 put_IA(mkaddr_expr(guest_IA_curr_instr));
sewardj2019a972011-03-07 16:04:07 +000014236
florian8844a632012-04-13 04:04:06 +000014237 dres.whatNext = Dis_StopHere;
14238 dres.jk_StopHere = Ijk_NoDecode;
14239 dres.continueAt = 0;
14240 dres.len = 0;
14241 } else {
14242 /* Decode success */
14243 switch (dres.whatNext) {
14244 case Dis_Continue:
florian8559e412012-04-19 14:23:48 +000014245 put_IA(mkaddr_expr(guest_IA_next_instr));
florian8844a632012-04-13 04:04:06 +000014246 break;
14247 case Dis_ResteerU:
14248 case Dis_ResteerC:
14249 put_IA(mkaddr_expr(dres.continueAt));
14250 break;
14251 case Dis_StopHere:
14252 break;
14253 default:
14254 vassert(0);
14255 }
sewardj2019a972011-03-07 16:04:07 +000014256 }
14257
14258 return dres;
14259}
14260
14261
14262/*------------------------------------------------------------*/
14263/*--- Top-level fn ---*/
14264/*------------------------------------------------------------*/
14265
14266/* Disassemble a single instruction into IR. The instruction
14267 is located in host memory at &guest_code[delta]. */
14268
14269DisResult
14270disInstr_S390(IRSB *irsb_IN,
sewardj2019a972011-03-07 16:04:07 +000014271 Bool (*resteerOkFn)(void *, Addr64),
14272 Bool resteerCisOk,
14273 void *callback_opaque,
14274 UChar *guest_code,
14275 Long delta,
14276 Addr64 guest_IP,
14277 VexArch guest_arch,
14278 VexArchInfo *archinfo,
14279 VexAbiInfo *abiinfo,
14280 Bool host_bigendian)
14281{
14282 vassert(guest_arch == VexArchS390X);
14283
14284 /* The instruction decoder requires a big-endian machine. */
14285 vassert(host_bigendian == True);
14286
14287 /* Set globals (see top of this file) */
14288 guest_IA_curr_instr = guest_IP;
sewardj2019a972011-03-07 16:04:07 +000014289 irsb = irsb_IN;
florian420c5012011-07-22 02:12:28 +000014290 resteer_fn = resteerOkFn;
14291 resteer_data = callback_opaque;
sewardj2019a972011-03-07 16:04:07 +000014292
florian420c5012011-07-22 02:12:28 +000014293 return disInstr_S390_WRK(guest_code + delta);
sewardj2019a972011-03-07 16:04:07 +000014294}
14295
14296/*---------------------------------------------------------------*/
14297/*--- end guest_s390_toIR.c ---*/
14298/*---------------------------------------------------------------*/