blob: 566ad880a061b360aedc7c640b70ac730551a679 [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"
florian58a637b2012-09-30 20:30:17 +000037#include "libvex_emnote.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 */
florian79af5752012-09-20 01:22:10 +000043#include "s390_disasm.h"
sewardj2019a972011-03-07 16:04:07 +000044#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 +0000428static __inline__ IRExpr *get_fpr_dw0(UInt);
429static __inline__ void put_fpr_dw0(UInt, IRExpr *);
florian12390202012-11-10 22:34:14 +0000430static __inline__ IRExpr *get_dpr_dw0(UInt);
431static __inline__ void put_dpr_dw0(UInt, IRExpr *);
sewardj2019a972011-03-07 16:04:07 +0000432
433/* Read a floating point register pair and combine their contents into a
434 128-bit value */
435static IRExpr *
436get_fpr_pair(UInt archreg)
437{
438 IRExpr *high = get_fpr_dw0(archreg);
439 IRExpr *low = get_fpr_dw0(archreg + 2);
440
441 return binop(Iop_F64HLtoF128, high, low);
442}
443
444/* Write a 128-bit floating point value into a register pair. */
445static void
446put_fpr_pair(UInt archreg, IRExpr *expr)
447{
448 IRExpr *high = unop(Iop_F128HItoF64, expr);
449 IRExpr *low = unop(Iop_F128LOtoF64, expr);
450
451 put_fpr_dw0(archreg, high);
452 put_fpr_dw0(archreg + 2, low);
453}
454
floriane75dafa2012-09-01 17:54:09 +0000455/* Terminate the current IRSB with an emulation failure. */
456static void
457emulation_failure(VexEmNote fail_kind)
458{
459 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_EMNOTE), mkU32(fail_kind)));
floriane75dafa2012-09-01 17:54:09 +0000460 dis_res->whatNext = Dis_StopHere;
461 dis_res->jk_StopHere = Ijk_EmFail;
462}
sewardj2019a972011-03-07 16:04:07 +0000463
florian4b8efad2012-09-02 18:07:08 +0000464/* Terminate the current IRSB with an emulation warning. */
465static void
466emulation_warning(VexEmNote warn_kind)
467{
468 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_EMNOTE), mkU32(warn_kind)));
469 dis_res->whatNext = Dis_StopHere;
470 dis_res->jk_StopHere = Ijk_EmWarn;
471}
472
sewardj2019a972011-03-07 16:04:07 +0000473/*------------------------------------------------------------*/
florianf3410f92012-08-03 18:41:58 +0000474/*--- IR Debugging aids. ---*/
475/*------------------------------------------------------------*/
476#if 0
477
478static ULong
479s390_do_print(HChar *text, ULong value)
480{
481 vex_printf("%s %llu\n", text, value);
482 return 0;
483}
484
485static void
486s390_print(HChar *text, IRExpr *value)
487{
488 IRDirty *d;
489
490 d = unsafeIRDirty_0_N(0 /* regparms */, "s390_do_print", &s390_do_print,
491 mkIRExprVec_2(mkU64((ULong)text), value));
492 stmt(IRStmt_Dirty(d));
493}
494#endif
495
496
497/*------------------------------------------------------------*/
sewardj2019a972011-03-07 16:04:07 +0000498/*--- Build the flags thunk. ---*/
499/*------------------------------------------------------------*/
500
501/* Completely fill the flags thunk. We're always filling all fields.
502 Apparently, that is better for redundant PUT elimination. */
503static void
504s390_cc_thunk_fill(IRExpr *op, IRExpr *dep1, IRExpr *dep2, IRExpr *ndep)
505{
506 UInt op_off, dep1_off, dep2_off, ndep_off;
507
florian428dfdd2012-03-27 03:09:49 +0000508 op_off = S390X_GUEST_OFFSET(guest_CC_OP);
509 dep1_off = S390X_GUEST_OFFSET(guest_CC_DEP1);
510 dep2_off = S390X_GUEST_OFFSET(guest_CC_DEP2);
511 ndep_off = S390X_GUEST_OFFSET(guest_CC_NDEP);
sewardj2019a972011-03-07 16:04:07 +0000512
513 stmt(IRStmt_Put(op_off, op));
514 stmt(IRStmt_Put(dep1_off, dep1));
515 stmt(IRStmt_Put(dep2_off, dep2));
516 stmt(IRStmt_Put(ndep_off, ndep));
517}
518
519
520/* Create an expression for V and widen the result to 64 bit. */
521static IRExpr *
522s390_cc_widen(IRTemp v, Bool sign_extend)
523{
524 IRExpr *expr;
525
526 expr = mkexpr(v);
527
528 switch (typeOfIRTemp(irsb->tyenv, v)) {
529 case Ity_I64:
530 break;
531 case Ity_I32:
532 expr = unop(sign_extend ? Iop_32Sto64 : Iop_32Uto64, expr);
533 break;
534 case Ity_I16:
535 expr = unop(sign_extend ? Iop_16Sto64 : Iop_16Uto64, expr);
536 break;
537 case Ity_I8:
538 expr = unop(sign_extend ? Iop_8Sto64 : Iop_8Uto64, expr);
539 break;
540 default:
541 vpanic("s390_cc_widen");
542 }
543
544 return expr;
545}
546
547static void
548s390_cc_thunk_put1(UInt opc, IRTemp d1, Bool sign_extend)
549{
550 IRExpr *op, *dep1, *dep2, *ndep;
551
552 op = mkU64(opc);
553 dep1 = s390_cc_widen(d1, sign_extend);
554 dep2 = mkU64(0);
555 ndep = mkU64(0);
556
557 s390_cc_thunk_fill(op, dep1, dep2, ndep);
558}
559
560
561static void
562s390_cc_thunk_put2(UInt opc, IRTemp d1, IRTemp d2, Bool sign_extend)
563{
564 IRExpr *op, *dep1, *dep2, *ndep;
565
566 op = mkU64(opc);
567 dep1 = s390_cc_widen(d1, sign_extend);
568 dep2 = s390_cc_widen(d2, sign_extend);
569 ndep = mkU64(0);
570
571 s390_cc_thunk_fill(op, dep1, dep2, ndep);
572}
573
574
575/* memcheck believes that the NDEP field in the flags thunk is always
576 defined. But for some flag computations (e.g. add with carry) that is
577 just not true. We therefore need to convey to memcheck that the value
578 of the ndep field does matter and therefore we make the DEP2 field
579 depend on it:
580
581 DEP2 = original_DEP2 ^ NDEP
582
583 In s390_calculate_cc we exploit that (a^b)^b == a
584 I.e. we xor the DEP2 value with the NDEP value to recover the
585 original_DEP2 value. */
586static void
587s390_cc_thunk_put3(UInt opc, IRTemp d1, IRTemp d2, IRTemp nd, Bool sign_extend)
588{
589 IRExpr *op, *dep1, *dep2, *ndep, *dep2x;
590
591 op = mkU64(opc);
592 dep1 = s390_cc_widen(d1, sign_extend);
593 dep2 = s390_cc_widen(d2, sign_extend);
594 ndep = s390_cc_widen(nd, sign_extend);
595
596 dep2x = binop(Iop_Xor64, dep2, ndep);
597
598 s390_cc_thunk_fill(op, dep1, dep2x, ndep);
599}
600
601
602/* Write one floating point value into the flags thunk */
603static void
604s390_cc_thunk_put1f(UInt opc, IRTemp d1)
605{
606 IRExpr *op, *dep1, *dep2, *ndep;
607
608 op = mkU64(opc);
609 dep1 = mkexpr(d1);
610 dep2 = mkU64(0);
611 ndep = mkU64(0);
612
613 s390_cc_thunk_fill(op, dep1, dep2, ndep);
614}
615
616
617/* Write a floating point value and an integer into the flags thunk. The
618 integer value is zero-extended first. */
619static void
620s390_cc_thunk_putFZ(UInt opc, IRTemp d1, IRTemp d2)
621{
622 IRExpr *op, *dep1, *dep2, *ndep;
623
624 op = mkU64(opc);
625 dep1 = mkexpr(d1);
626 dep2 = s390_cc_widen(d2, False);
627 ndep = mkU64(0);
628
629 s390_cc_thunk_fill(op, dep1, dep2, ndep);
630}
631
632
633/* Write a 128-bit floating point value into the flags thunk. This is
634 done by splitting the value into two 64-bits values. */
635static void
636s390_cc_thunk_put1f128(UInt opc, IRTemp d1)
637{
638 IRExpr *op, *hi, *lo, *ndep;
639
640 op = mkU64(opc);
641 hi = unop(Iop_F128HItoF64, mkexpr(d1));
642 lo = unop(Iop_F128LOtoF64, mkexpr(d1));
643 ndep = mkU64(0);
644
645 s390_cc_thunk_fill(op, hi, lo, ndep);
646}
647
648
649/* Write a 128-bit floating point value and an integer into the flags thunk.
650 The integer value is zero-extended first. */
651static void
652s390_cc_thunk_put1f128Z(UInt opc, IRTemp d1, IRTemp nd)
653{
654 IRExpr *op, *hi, *lo, *lox, *ndep;
655
656 op = mkU64(opc);
657 hi = unop(Iop_F128HItoF64, mkexpr(d1));
658 lo = unop(Iop_ReinterpF64asI64, unop(Iop_F128LOtoF64, mkexpr(d1)));
659 ndep = s390_cc_widen(nd, False);
660
661 lox = binop(Iop_Xor64, lo, ndep); /* convey dependency */
662
663 s390_cc_thunk_fill(op, hi, lox, ndep);
664}
665
666
667static void
668s390_cc_set(UInt val)
669{
670 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
671 mkU64(val), mkU64(0), mkU64(0));
672}
673
674/* Build IR to calculate the condition code from flags thunk.
675 Returns an expression of type Ity_I32 */
676static IRExpr *
677s390_call_calculate_cc(void)
678{
679 IRExpr **args, *call, *op, *dep1, *dep2, *ndep;
680
florian428dfdd2012-03-27 03:09:49 +0000681 op = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_OP), Ity_I64);
682 dep1 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP1), Ity_I64);
683 dep2 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP2), Ity_I64);
684 ndep = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_NDEP), Ity_I64);
sewardj2019a972011-03-07 16:04:07 +0000685
686 args = mkIRExprVec_4(op, dep1, dep2, ndep);
687 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
688 "s390_calculate_cc", &s390_calculate_cc, args);
689
690 /* Exclude OP and NDEP from definedness checking. We're only
691 interested in DEP1 and DEP2. */
692 call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<3);
693
694 return call;
695}
696
697/* Build IR to calculate the internal condition code for a "compare and branch"
698 insn. Returns an expression of type Ity_I32 */
699static IRExpr *
florianff9613f2012-05-12 15:26:44 +0000700s390_call_calculate_icc(UInt m, UInt opc, IRTemp op1, IRTemp op2)
sewardj2019a972011-03-07 16:04:07 +0000701{
florianff9613f2012-05-12 15:26:44 +0000702 IRExpr **args, *call, *op, *dep1, *dep2, *mask;
sewardj2019a972011-03-07 16:04:07 +0000703
florianff9613f2012-05-12 15:26:44 +0000704 switch (opc) {
705 case S390_CC_OP_SIGNED_COMPARE:
706 dep1 = s390_cc_widen(op1, True);
707 dep2 = s390_cc_widen(op2, True);
708 break;
709
710 case S390_CC_OP_UNSIGNED_COMPARE:
711 dep1 = s390_cc_widen(op1, False);
712 dep2 = s390_cc_widen(op2, False);
713 break;
714
715 default:
716 vpanic("s390_call_calculate_icc");
717 }
718
719 mask = mkU64(m);
sewardj2019a972011-03-07 16:04:07 +0000720 op = mkU64(opc);
sewardj2019a972011-03-07 16:04:07 +0000721
florianff9613f2012-05-12 15:26:44 +0000722 args = mkIRExprVec_5(mask, op, dep1, dep2, mkU64(0) /* unused */);
sewardj2019a972011-03-07 16:04:07 +0000723 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
florianff9613f2012-05-12 15:26:44 +0000724 "s390_calculate_cond", &s390_calculate_cond, args);
sewardj2019a972011-03-07 16:04:07 +0000725
florianff9613f2012-05-12 15:26:44 +0000726 /* Exclude the requested condition, OP and NDEP from definedness
727 checking. We're only interested in DEP1 and DEP2. */
728 call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<1) | (1<<4);
sewardj2019a972011-03-07 16:04:07 +0000729
730 return call;
731}
732
733/* Build IR to calculate the condition code from flags thunk.
734 Returns an expression of type Ity_I32 */
735static IRExpr *
736s390_call_calculate_cond(UInt m)
737{
738 IRExpr **args, *call, *op, *dep1, *dep2, *ndep, *mask;
739
740 mask = mkU64(m);
florian428dfdd2012-03-27 03:09:49 +0000741 op = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_OP), Ity_I64);
742 dep1 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP1), Ity_I64);
743 dep2 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP2), Ity_I64);
744 ndep = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_NDEP), Ity_I64);
sewardj2019a972011-03-07 16:04:07 +0000745
746 args = mkIRExprVec_5(mask, op, dep1, dep2, ndep);
747 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
748 "s390_calculate_cond", &s390_calculate_cond, args);
749
750 /* Exclude the requested condition, OP and NDEP from definedness
751 checking. We're only interested in DEP1 and DEP2. */
752 call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<1) | (1<<4);
753
754 return call;
755}
756
757#define s390_cc_thunk_putZ(op,dep1) s390_cc_thunk_put1(op,dep1,False)
758#define s390_cc_thunk_putS(op,dep1) s390_cc_thunk_put1(op,dep1,True)
759#define s390_cc_thunk_putF(op,dep1) s390_cc_thunk_put1f(op,dep1)
760#define s390_cc_thunk_putZZ(op,dep1,dep2) s390_cc_thunk_put2(op,dep1,dep2,False)
761#define s390_cc_thunk_putSS(op,dep1,dep2) s390_cc_thunk_put2(op,dep1,dep2,True)
762#define s390_cc_thunk_putFF(op,dep1,dep2) s390_cc_thunk_put2f(op,dep1,dep2)
763#define s390_cc_thunk_putZZZ(op,dep1,dep2,ndep) \
764 s390_cc_thunk_put3(op,dep1,dep2,ndep,False)
765#define s390_cc_thunk_putSSS(op,dep1,dep2,ndep) \
766 s390_cc_thunk_put3(op,dep1,dep2,ndep,True)
sewardj2019a972011-03-07 16:04:07 +0000767
768
sewardj2019a972011-03-07 16:04:07 +0000769
770
771/*------------------------------------------------------------*/
772/*--- Guest register access ---*/
773/*------------------------------------------------------------*/
774
775
776/*------------------------------------------------------------*/
777/*--- ar registers ---*/
778/*------------------------------------------------------------*/
779
780/* Return the guest state offset of a ar register. */
781static UInt
782ar_offset(UInt archreg)
783{
784 static const UInt offset[16] = {
floriane88b3c92011-07-05 02:48:39 +0000785 S390X_GUEST_OFFSET(guest_a0),
786 S390X_GUEST_OFFSET(guest_a1),
787 S390X_GUEST_OFFSET(guest_a2),
788 S390X_GUEST_OFFSET(guest_a3),
789 S390X_GUEST_OFFSET(guest_a4),
790 S390X_GUEST_OFFSET(guest_a5),
791 S390X_GUEST_OFFSET(guest_a6),
792 S390X_GUEST_OFFSET(guest_a7),
793 S390X_GUEST_OFFSET(guest_a8),
794 S390X_GUEST_OFFSET(guest_a9),
795 S390X_GUEST_OFFSET(guest_a10),
796 S390X_GUEST_OFFSET(guest_a11),
797 S390X_GUEST_OFFSET(guest_a12),
798 S390X_GUEST_OFFSET(guest_a13),
799 S390X_GUEST_OFFSET(guest_a14),
800 S390X_GUEST_OFFSET(guest_a15),
sewardj2019a972011-03-07 16:04:07 +0000801 };
802
803 vassert(archreg < 16);
804
805 return offset[archreg];
806}
807
808
809/* Return the guest state offset of word #0 of a ar register. */
810static __inline__ UInt
811ar_w0_offset(UInt archreg)
812{
813 return ar_offset(archreg) + 0;
814}
815
816/* Write word #0 of a ar to the guest state. */
817static __inline__ void
818put_ar_w0(UInt archreg, IRExpr *expr)
819{
820 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
821
822 stmt(IRStmt_Put(ar_w0_offset(archreg), expr));
823}
824
825/* Read word #0 of a ar register. */
826static __inline__ IRExpr *
827get_ar_w0(UInt archreg)
828{
829 return IRExpr_Get(ar_w0_offset(archreg), Ity_I32);
830}
831
832
833/*------------------------------------------------------------*/
834/*--- fpr registers ---*/
835/*------------------------------------------------------------*/
836
837/* Return the guest state offset of a fpr register. */
838static UInt
839fpr_offset(UInt archreg)
840{
841 static const UInt offset[16] = {
floriane88b3c92011-07-05 02:48:39 +0000842 S390X_GUEST_OFFSET(guest_f0),
843 S390X_GUEST_OFFSET(guest_f1),
844 S390X_GUEST_OFFSET(guest_f2),
845 S390X_GUEST_OFFSET(guest_f3),
846 S390X_GUEST_OFFSET(guest_f4),
847 S390X_GUEST_OFFSET(guest_f5),
848 S390X_GUEST_OFFSET(guest_f6),
849 S390X_GUEST_OFFSET(guest_f7),
850 S390X_GUEST_OFFSET(guest_f8),
851 S390X_GUEST_OFFSET(guest_f9),
852 S390X_GUEST_OFFSET(guest_f10),
853 S390X_GUEST_OFFSET(guest_f11),
854 S390X_GUEST_OFFSET(guest_f12),
855 S390X_GUEST_OFFSET(guest_f13),
856 S390X_GUEST_OFFSET(guest_f14),
857 S390X_GUEST_OFFSET(guest_f15),
sewardj2019a972011-03-07 16:04:07 +0000858 };
859
860 vassert(archreg < 16);
861
862 return offset[archreg];
863}
864
865
866/* Return the guest state offset of word #0 of a fpr register. */
867static __inline__ UInt
868fpr_w0_offset(UInt archreg)
869{
870 return fpr_offset(archreg) + 0;
871}
872
873/* Write word #0 of a fpr to the guest state. */
874static __inline__ void
875put_fpr_w0(UInt archreg, IRExpr *expr)
876{
877 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_F32);
878
879 stmt(IRStmt_Put(fpr_w0_offset(archreg), expr));
880}
881
882/* Read word #0 of a fpr register. */
883static __inline__ IRExpr *
884get_fpr_w0(UInt archreg)
885{
886 return IRExpr_Get(fpr_w0_offset(archreg), Ity_F32);
887}
888
889/* Return the guest state offset of double word #0 of a fpr register. */
890static __inline__ UInt
891fpr_dw0_offset(UInt archreg)
892{
893 return fpr_offset(archreg) + 0;
894}
895
896/* Write double word #0 of a fpr to the guest state. */
897static __inline__ void
898put_fpr_dw0(UInt archreg, IRExpr *expr)
899{
900 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_F64);
901
902 stmt(IRStmt_Put(fpr_dw0_offset(archreg), expr));
903}
904
905/* Read double word #0 of a fpr register. */
906static __inline__ IRExpr *
907get_fpr_dw0(UInt archreg)
908{
909 return IRExpr_Get(fpr_dw0_offset(archreg), Ity_F64);
910}
911
florian12390202012-11-10 22:34:14 +0000912/* Write double word #0 of a fpr containg DFP value to the guest state. */
913static __inline__ void
914put_dpr_dw0(UInt archreg, IRExpr *expr)
915{
916 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_D64);
917
918 stmt(IRStmt_Put(fpr_dw0_offset(archreg), expr));
919}
920
921/* Read double word #0 of a fpr register containing DFP value. */
922static __inline__ IRExpr *
923get_dpr_dw0(UInt archreg)
924{
925 return IRExpr_Get(fpr_dw0_offset(archreg), Ity_D64);
926}
sewardj2019a972011-03-07 16:04:07 +0000927
928/*------------------------------------------------------------*/
929/*--- gpr registers ---*/
930/*------------------------------------------------------------*/
931
932/* Return the guest state offset of a gpr register. */
933static UInt
934gpr_offset(UInt archreg)
935{
936 static const UInt offset[16] = {
floriane88b3c92011-07-05 02:48:39 +0000937 S390X_GUEST_OFFSET(guest_r0),
938 S390X_GUEST_OFFSET(guest_r1),
939 S390X_GUEST_OFFSET(guest_r2),
940 S390X_GUEST_OFFSET(guest_r3),
941 S390X_GUEST_OFFSET(guest_r4),
942 S390X_GUEST_OFFSET(guest_r5),
943 S390X_GUEST_OFFSET(guest_r6),
944 S390X_GUEST_OFFSET(guest_r7),
945 S390X_GUEST_OFFSET(guest_r8),
946 S390X_GUEST_OFFSET(guest_r9),
947 S390X_GUEST_OFFSET(guest_r10),
948 S390X_GUEST_OFFSET(guest_r11),
949 S390X_GUEST_OFFSET(guest_r12),
950 S390X_GUEST_OFFSET(guest_r13),
951 S390X_GUEST_OFFSET(guest_r14),
952 S390X_GUEST_OFFSET(guest_r15),
sewardj2019a972011-03-07 16:04:07 +0000953 };
954
955 vassert(archreg < 16);
956
957 return offset[archreg];
958}
959
960
961/* Return the guest state offset of word #0 of a gpr register. */
962static __inline__ UInt
963gpr_w0_offset(UInt archreg)
964{
965 return gpr_offset(archreg) + 0;
966}
967
968/* Write word #0 of a gpr to the guest state. */
969static __inline__ void
970put_gpr_w0(UInt archreg, IRExpr *expr)
971{
972 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
973
974 stmt(IRStmt_Put(gpr_w0_offset(archreg), expr));
975}
976
977/* Read word #0 of a gpr register. */
978static __inline__ IRExpr *
979get_gpr_w0(UInt archreg)
980{
981 return IRExpr_Get(gpr_w0_offset(archreg), Ity_I32);
982}
983
984/* Return the guest state offset of double word #0 of a gpr register. */
985static __inline__ UInt
986gpr_dw0_offset(UInt archreg)
987{
988 return gpr_offset(archreg) + 0;
989}
990
991/* Write double word #0 of a gpr to the guest state. */
992static __inline__ void
993put_gpr_dw0(UInt archreg, IRExpr *expr)
994{
995 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I64);
996
997 stmt(IRStmt_Put(gpr_dw0_offset(archreg), expr));
998}
999
1000/* Read double word #0 of a gpr register. */
1001static __inline__ IRExpr *
1002get_gpr_dw0(UInt archreg)
1003{
1004 return IRExpr_Get(gpr_dw0_offset(archreg), Ity_I64);
1005}
1006
1007/* Return the guest state offset of half word #1 of a gpr register. */
1008static __inline__ UInt
1009gpr_hw1_offset(UInt archreg)
1010{
1011 return gpr_offset(archreg) + 2;
1012}
1013
1014/* Write half word #1 of a gpr to the guest state. */
1015static __inline__ void
1016put_gpr_hw1(UInt archreg, IRExpr *expr)
1017{
1018 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1019
1020 stmt(IRStmt_Put(gpr_hw1_offset(archreg), expr));
1021}
1022
1023/* Read half word #1 of a gpr register. */
1024static __inline__ IRExpr *
1025get_gpr_hw1(UInt archreg)
1026{
1027 return IRExpr_Get(gpr_hw1_offset(archreg), Ity_I16);
1028}
1029
1030/* Return the guest state offset of byte #6 of a gpr register. */
1031static __inline__ UInt
1032gpr_b6_offset(UInt archreg)
1033{
1034 return gpr_offset(archreg) + 6;
1035}
1036
1037/* Write byte #6 of a gpr to the guest state. */
1038static __inline__ void
1039put_gpr_b6(UInt archreg, IRExpr *expr)
1040{
1041 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1042
1043 stmt(IRStmt_Put(gpr_b6_offset(archreg), expr));
1044}
1045
1046/* Read byte #6 of a gpr register. */
1047static __inline__ IRExpr *
1048get_gpr_b6(UInt archreg)
1049{
1050 return IRExpr_Get(gpr_b6_offset(archreg), Ity_I8);
1051}
1052
1053/* Return the guest state offset of byte #3 of a gpr register. */
1054static __inline__ UInt
1055gpr_b3_offset(UInt archreg)
1056{
1057 return gpr_offset(archreg) + 3;
1058}
1059
1060/* Write byte #3 of a gpr to the guest state. */
1061static __inline__ void
1062put_gpr_b3(UInt archreg, IRExpr *expr)
1063{
1064 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1065
1066 stmt(IRStmt_Put(gpr_b3_offset(archreg), expr));
1067}
1068
1069/* Read byte #3 of a gpr register. */
1070static __inline__ IRExpr *
1071get_gpr_b3(UInt archreg)
1072{
1073 return IRExpr_Get(gpr_b3_offset(archreg), Ity_I8);
1074}
1075
1076/* Return the guest state offset of byte #0 of a gpr register. */
1077static __inline__ UInt
1078gpr_b0_offset(UInt archreg)
1079{
1080 return gpr_offset(archreg) + 0;
1081}
1082
1083/* Write byte #0 of a gpr to the guest state. */
1084static __inline__ void
1085put_gpr_b0(UInt archreg, IRExpr *expr)
1086{
1087 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1088
1089 stmt(IRStmt_Put(gpr_b0_offset(archreg), expr));
1090}
1091
1092/* Read byte #0 of a gpr register. */
1093static __inline__ IRExpr *
1094get_gpr_b0(UInt archreg)
1095{
1096 return IRExpr_Get(gpr_b0_offset(archreg), Ity_I8);
1097}
1098
1099/* Return the guest state offset of word #1 of a gpr register. */
1100static __inline__ UInt
1101gpr_w1_offset(UInt archreg)
1102{
1103 return gpr_offset(archreg) + 4;
1104}
1105
1106/* Write word #1 of a gpr to the guest state. */
1107static __inline__ void
1108put_gpr_w1(UInt archreg, IRExpr *expr)
1109{
1110 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1111
1112 stmt(IRStmt_Put(gpr_w1_offset(archreg), expr));
1113}
1114
1115/* Read word #1 of a gpr register. */
1116static __inline__ IRExpr *
1117get_gpr_w1(UInt archreg)
1118{
1119 return IRExpr_Get(gpr_w1_offset(archreg), Ity_I32);
1120}
1121
1122/* Return the guest state offset of half word #3 of a gpr register. */
1123static __inline__ UInt
1124gpr_hw3_offset(UInt archreg)
1125{
1126 return gpr_offset(archreg) + 6;
1127}
1128
1129/* Write half word #3 of a gpr to the guest state. */
1130static __inline__ void
1131put_gpr_hw3(UInt archreg, IRExpr *expr)
1132{
1133 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1134
1135 stmt(IRStmt_Put(gpr_hw3_offset(archreg), expr));
1136}
1137
1138/* Read half word #3 of a gpr register. */
1139static __inline__ IRExpr *
1140get_gpr_hw3(UInt archreg)
1141{
1142 return IRExpr_Get(gpr_hw3_offset(archreg), Ity_I16);
1143}
1144
1145/* Return the guest state offset of byte #7 of a gpr register. */
1146static __inline__ UInt
1147gpr_b7_offset(UInt archreg)
1148{
1149 return gpr_offset(archreg) + 7;
1150}
1151
1152/* Write byte #7 of a gpr to the guest state. */
1153static __inline__ void
1154put_gpr_b7(UInt archreg, IRExpr *expr)
1155{
1156 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1157
1158 stmt(IRStmt_Put(gpr_b7_offset(archreg), expr));
1159}
1160
1161/* Read byte #7 of a gpr register. */
1162static __inline__ IRExpr *
1163get_gpr_b7(UInt archreg)
1164{
1165 return IRExpr_Get(gpr_b7_offset(archreg), Ity_I8);
1166}
1167
1168/* Return the guest state offset of half word #0 of a gpr register. */
1169static __inline__ UInt
1170gpr_hw0_offset(UInt archreg)
1171{
1172 return gpr_offset(archreg) + 0;
1173}
1174
1175/* Write half word #0 of a gpr to the guest state. */
1176static __inline__ void
1177put_gpr_hw0(UInt archreg, IRExpr *expr)
1178{
1179 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1180
1181 stmt(IRStmt_Put(gpr_hw0_offset(archreg), expr));
1182}
1183
1184/* Read half word #0 of a gpr register. */
1185static __inline__ IRExpr *
1186get_gpr_hw0(UInt archreg)
1187{
1188 return IRExpr_Get(gpr_hw0_offset(archreg), Ity_I16);
1189}
1190
1191/* Return the guest state offset of byte #4 of a gpr register. */
1192static __inline__ UInt
1193gpr_b4_offset(UInt archreg)
1194{
1195 return gpr_offset(archreg) + 4;
1196}
1197
1198/* Write byte #4 of a gpr to the guest state. */
1199static __inline__ void
1200put_gpr_b4(UInt archreg, IRExpr *expr)
1201{
1202 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1203
1204 stmt(IRStmt_Put(gpr_b4_offset(archreg), expr));
1205}
1206
1207/* Read byte #4 of a gpr register. */
1208static __inline__ IRExpr *
1209get_gpr_b4(UInt archreg)
1210{
1211 return IRExpr_Get(gpr_b4_offset(archreg), Ity_I8);
1212}
1213
1214/* Return the guest state offset of byte #1 of a gpr register. */
1215static __inline__ UInt
1216gpr_b1_offset(UInt archreg)
1217{
1218 return gpr_offset(archreg) + 1;
1219}
1220
1221/* Write byte #1 of a gpr to the guest state. */
1222static __inline__ void
1223put_gpr_b1(UInt archreg, IRExpr *expr)
1224{
1225 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1226
1227 stmt(IRStmt_Put(gpr_b1_offset(archreg), expr));
1228}
1229
1230/* Read byte #1 of a gpr register. */
1231static __inline__ IRExpr *
1232get_gpr_b1(UInt archreg)
1233{
1234 return IRExpr_Get(gpr_b1_offset(archreg), Ity_I8);
1235}
1236
1237/* Return the guest state offset of half word #2 of a gpr register. */
1238static __inline__ UInt
1239gpr_hw2_offset(UInt archreg)
1240{
1241 return gpr_offset(archreg) + 4;
1242}
1243
1244/* Write half word #2 of a gpr to the guest state. */
1245static __inline__ void
1246put_gpr_hw2(UInt archreg, IRExpr *expr)
1247{
1248 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1249
1250 stmt(IRStmt_Put(gpr_hw2_offset(archreg), expr));
1251}
1252
1253/* Read half word #2 of a gpr register. */
1254static __inline__ IRExpr *
1255get_gpr_hw2(UInt archreg)
1256{
1257 return IRExpr_Get(gpr_hw2_offset(archreg), Ity_I16);
1258}
1259
1260/* Return the guest state offset of byte #5 of a gpr register. */
1261static __inline__ UInt
1262gpr_b5_offset(UInt archreg)
1263{
1264 return gpr_offset(archreg) + 5;
1265}
1266
1267/* Write byte #5 of a gpr to the guest state. */
1268static __inline__ void
1269put_gpr_b5(UInt archreg, IRExpr *expr)
1270{
1271 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1272
1273 stmt(IRStmt_Put(gpr_b5_offset(archreg), expr));
1274}
1275
1276/* Read byte #5 of a gpr register. */
1277static __inline__ IRExpr *
1278get_gpr_b5(UInt archreg)
1279{
1280 return IRExpr_Get(gpr_b5_offset(archreg), Ity_I8);
1281}
1282
1283/* Return the guest state offset of byte #2 of a gpr register. */
1284static __inline__ UInt
1285gpr_b2_offset(UInt archreg)
1286{
1287 return gpr_offset(archreg) + 2;
1288}
1289
1290/* Write byte #2 of a gpr to the guest state. */
1291static __inline__ void
1292put_gpr_b2(UInt archreg, IRExpr *expr)
1293{
1294 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1295
1296 stmt(IRStmt_Put(gpr_b2_offset(archreg), expr));
1297}
1298
1299/* Read byte #2 of a gpr register. */
1300static __inline__ IRExpr *
1301get_gpr_b2(UInt archreg)
1302{
1303 return IRExpr_Get(gpr_b2_offset(archreg), Ity_I8);
1304}
1305
1306/* Return the guest state offset of the counter register. */
1307static UInt
1308counter_offset(void)
1309{
floriane88b3c92011-07-05 02:48:39 +00001310 return S390X_GUEST_OFFSET(guest_counter);
sewardj2019a972011-03-07 16:04:07 +00001311}
1312
1313/* Return the guest state offset of double word #0 of the counter register. */
1314static __inline__ UInt
1315counter_dw0_offset(void)
1316{
1317 return counter_offset() + 0;
1318}
1319
1320/* Write double word #0 of the counter to the guest state. */
1321static __inline__ void
1322put_counter_dw0(IRExpr *expr)
1323{
1324 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I64);
1325
1326 stmt(IRStmt_Put(counter_dw0_offset(), expr));
1327}
1328
1329/* Read double word #0 of the counter register. */
1330static __inline__ IRExpr *
1331get_counter_dw0(void)
1332{
1333 return IRExpr_Get(counter_dw0_offset(), Ity_I64);
1334}
1335
1336/* Return the guest state offset of word #0 of the counter register. */
1337static __inline__ UInt
1338counter_w0_offset(void)
1339{
1340 return counter_offset() + 0;
1341}
1342
1343/* Return the guest state offset of word #1 of the counter register. */
1344static __inline__ UInt
1345counter_w1_offset(void)
1346{
1347 return counter_offset() + 4;
1348}
1349
1350/* Write word #0 of the counter to the guest state. */
1351static __inline__ void
1352put_counter_w0(IRExpr *expr)
1353{
1354 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1355
1356 stmt(IRStmt_Put(counter_w0_offset(), expr));
1357}
1358
1359/* Read word #0 of the counter register. */
1360static __inline__ IRExpr *
1361get_counter_w0(void)
1362{
1363 return IRExpr_Get(counter_w0_offset(), Ity_I32);
1364}
1365
1366/* Write word #1 of the counter to the guest state. */
1367static __inline__ void
1368put_counter_w1(IRExpr *expr)
1369{
1370 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1371
1372 stmt(IRStmt_Put(counter_w1_offset(), expr));
1373}
1374
1375/* Read word #1 of the counter register. */
1376static __inline__ IRExpr *
1377get_counter_w1(void)
1378{
1379 return IRExpr_Get(counter_w1_offset(), Ity_I32);
1380}
1381
1382/* Return the guest state offset of the fpc register. */
1383static UInt
1384fpc_offset(void)
1385{
floriane88b3c92011-07-05 02:48:39 +00001386 return S390X_GUEST_OFFSET(guest_fpc);
sewardj2019a972011-03-07 16:04:07 +00001387}
1388
1389/* Return the guest state offset of word #0 of the fpc register. */
1390static __inline__ UInt
1391fpc_w0_offset(void)
1392{
1393 return fpc_offset() + 0;
1394}
1395
1396/* Write word #0 of the fpc to the guest state. */
1397static __inline__ void
1398put_fpc_w0(IRExpr *expr)
1399{
1400 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1401
1402 stmt(IRStmt_Put(fpc_w0_offset(), expr));
1403}
1404
1405/* Read word #0 of the fpc register. */
1406static __inline__ IRExpr *
1407get_fpc_w0(void)
1408{
1409 return IRExpr_Get(fpc_w0_offset(), Ity_I32);
1410}
1411
1412
1413/*------------------------------------------------------------*/
florian2c74d242012-09-12 19:38:42 +00001414/*--- Rounding modes ---*/
1415/*------------------------------------------------------------*/
1416
florian125e20d2012-10-07 15:42:37 +00001417/* Extract the bfp rounding mode from the guest FPC reg and encode it as an
florian2c74d242012-09-12 19:38:42 +00001418 IRRoundingMode:
1419
1420 rounding mode | s390 | IR
1421 -------------------------
1422 to nearest | 00 | 00
1423 to zero | 01 | 11
1424 to +infinity | 10 | 10
1425 to -infinity | 11 | 01
1426
1427 So: IR = (4 - s390) & 3
1428*/
1429static IRExpr *
florian125e20d2012-10-07 15:42:37 +00001430get_bfp_rounding_mode_from_fpc(void)
florian2c74d242012-09-12 19:38:42 +00001431{
1432 IRTemp fpc_bits = newTemp(Ity_I32);
1433
1434 /* For z196 and later the bfp rounding mode is stored in bits [29:31].
1435 Prior to that bits [30:31] contained the bfp rounding mode with
1436 bit 29 being unused and having a value of 0. So we can always
1437 extract the least significant 3 bits. */
1438 assign(fpc_bits, binop(Iop_And32, get_fpc_w0(), mkU32(7)));
1439
1440 /* fixs390:
1441
1442
1443 if (! s390_host_has_fpext && rounding_mode > 3) {
1444 emulation warning @ runtime and
1445 set fpc to round nearest
1446 }
1447 */
1448
1449 /* For now silently adjust an unsupported rounding mode to "nearest" */
1450 IRExpr *rm_s390 = mkite(binop(Iop_CmpLE32S, mkexpr(fpc_bits), mkU32(3)),
1451 mkexpr(fpc_bits),
florian125e20d2012-10-07 15:42:37 +00001452 mkU32(S390_FPC_BFP_ROUND_NEAREST_EVEN));
florian2c74d242012-09-12 19:38:42 +00001453
1454 // rm_IR = (4 - rm_s390) & 3;
1455 return binop(Iop_And32, binop(Iop_Sub32, mkU32(4), rm_s390), mkU32(3));
1456}
1457
1458/* Encode the s390 rounding mode as it appears in the m3 field of certain
1459 instructions to VEX's IRRoundingMode. Rounding modes that cannot be
1460 represented in VEX are converted to Irrm_NEAREST. The rationale is, that
1461 Irrm_NEAREST refers to IEEE 754's roundTiesToEven which the standard
1462 considers the default rounding mode (4.3.3). */
1463static IRTemp
1464encode_bfp_rounding_mode(UChar mode)
1465{
1466 IRExpr *rm;
1467
1468 switch (mode) {
florian125e20d2012-10-07 15:42:37 +00001469 case S390_BFP_ROUND_PER_FPC:
1470 rm = get_bfp_rounding_mode_from_fpc();
1471 break;
1472 case S390_BFP_ROUND_NEAREST_AWAY: /* not supported */
1473 case S390_BFP_ROUND_PREPARE_SHORT: /* not supported */
1474 case S390_BFP_ROUND_NEAREST_EVEN: rm = mkU32(Irrm_NEAREST); break;
1475 case S390_BFP_ROUND_ZERO: rm = mkU32(Irrm_ZERO); break;
1476 case S390_BFP_ROUND_POSINF: rm = mkU32(Irrm_PosINF); break;
1477 case S390_BFP_ROUND_NEGINF: rm = mkU32(Irrm_NegINF); break;
florian2c74d242012-09-12 19:38:42 +00001478 default:
1479 vpanic("encode_bfp_rounding_mode");
1480 }
1481
1482 return mktemp(Ity_I32, rm);
1483}
1484
florianc8e4f562012-10-27 16:19:31 +00001485/* Extract the DFP rounding mode from the guest FPC reg and encode it as an
1486 IRRoundingMode:
1487
1488 rounding mode | s390 | IR
1489 ------------------------------------------------
1490 to nearest, ties to even | 000 | 000
1491 to zero | 001 | 011
1492 to +infinity | 010 | 010
1493 to -infinity | 011 | 001
1494 to nearest, ties away from 0 | 100 | 100
1495 to nearest, ties toward 0 | 101 | 111
1496 to away from 0 | 110 | 110
1497 to prepare for shorter precision | 111 | 101
1498
1499 So: IR = (s390 ^ ((s390 << 1) & 2))
1500*/
florianc8e4f562012-10-27 16:19:31 +00001501static IRExpr *
1502get_dfp_rounding_mode_from_fpc(void)
1503{
1504 IRTemp fpc_bits = newTemp(Ity_I32);
1505
1506 /* The dfp rounding mode is stored in bits [25:27].
1507 extract the bits at 25:27 and right shift 4 times. */
1508 assign(fpc_bits, binop(Iop_Shr32,
1509 binop(Iop_And32, get_fpc_w0(), mkU32(0x70)),
1510 mkU8(4)));
1511
1512 IRExpr *rm_s390 = mkexpr(fpc_bits);
1513 // rm_IR = (rm_s390 ^ ((rm_s390 << 1) & 2));
1514
1515 return binop(Iop_Xor32, rm_s390,
1516 binop( Iop_And32,
1517 binop(Iop_Shl32, rm_s390, mkU8(1)),
1518 mkU32(2)));
1519}
1520
1521/* Encode the s390 rounding mode as it appears in the m3 field of certain
1522 instructions to VEX's IRRoundingMode. */
1523static IRTemp
1524encode_dfp_rounding_mode(UChar mode)
1525{
1526 IRExpr *rm;
1527
1528 switch (mode) {
1529 case S390_DFP_ROUND_PER_FPC_0:
1530 case S390_DFP_ROUND_PER_FPC_2:
1531 rm = get_dfp_rounding_mode_from_fpc(); break;
1532 case S390_DFP_ROUND_NEAREST_EVEN_4:
1533 case S390_DFP_ROUND_NEAREST_EVEN_8:
1534 rm = mkU32(Irrm_DFP_NEAREST); break;
1535 case S390_DFP_ROUND_NEAREST_TIE_AWAY_0_1:
1536 case S390_DFP_ROUND_NEAREST_TIE_AWAY_0_12:
1537 rm = mkU32(Irrm_DFP_NEAREST_TIE_AWAY_0); break;
1538 case S390_DFP_ROUND_PREPARE_SHORT_3:
1539 case S390_DFP_ROUND_PREPARE_SHORT_15:
1540 rm = mkU32(Irrm_DFP_PREPARE_SHORTER); break;
1541 case S390_DFP_ROUND_ZERO_5:
1542 case S390_DFP_ROUND_ZERO_9:
1543 rm = mkU32(Irrm_DFP_ZERO ); break;
1544 case S390_DFP_ROUND_POSINF_6:
1545 case S390_DFP_ROUND_POSINF_10:
1546 rm = mkU32(Irrm_DFP_PosINF); break;
1547 case S390_DFP_ROUND_NEGINF_7:
1548 case S390_DFP_ROUND_NEGINF_11:
1549 rm = mkU32(Irrm_DFP_NegINF); break;
1550 case S390_DFP_ROUND_NEAREST_TIE_TOWARD_0:
1551 rm = mkU32(Irrm_DFP_NEAREST_TIE_TOWARD_0); break;
1552 case S390_DFP_ROUND_AWAY_0:
1553 rm = mkU32(Irrm_DFP_AWAY_FROM_ZERO); break;
1554 default:
1555 vpanic("encode_dfp_rounding_mode");
1556 }
1557
1558 return mktemp(Ity_I32, rm);
1559}
florian12390202012-11-10 22:34:14 +00001560
florianc8e4f562012-10-27 16:19:31 +00001561
florian2c74d242012-09-12 19:38:42 +00001562/*------------------------------------------------------------*/
sewardj2019a972011-03-07 16:04:07 +00001563/*--- Build IR for formats ---*/
1564/*------------------------------------------------------------*/
1565static void
florian55085f82012-11-21 00:36:55 +00001566s390_format_I(const HChar *(*irgen)(UChar i),
sewardj2019a972011-03-07 16:04:07 +00001567 UChar i)
1568{
florian55085f82012-11-21 00:36:55 +00001569 const HChar *mnm = irgen(i);
sewardj2019a972011-03-07 16:04:07 +00001570
sewardj7ee97522011-05-09 21:45:04 +00001571 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001572 s390_disasm(ENC2(MNM, UINT), mnm, i);
1573}
1574
1575static void
florian55085f82012-11-21 00:36:55 +00001576s390_format_RI(const HChar *(*irgen)(UChar r1, UShort i2),
sewardj2019a972011-03-07 16:04:07 +00001577 UChar r1, UShort i2)
1578{
1579 irgen(r1, i2);
1580}
1581
1582static void
florian55085f82012-11-21 00:36:55 +00001583s390_format_RI_RU(const HChar *(*irgen)(UChar r1, UShort i2),
sewardj2019a972011-03-07 16:04:07 +00001584 UChar r1, UShort i2)
1585{
florian55085f82012-11-21 00:36:55 +00001586 const HChar *mnm = irgen(r1, i2);
sewardj2019a972011-03-07 16:04:07 +00001587
sewardj7ee97522011-05-09 21:45:04 +00001588 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001589 s390_disasm(ENC3(MNM, GPR, UINT), mnm, r1, i2);
1590}
1591
1592static void
florian55085f82012-11-21 00:36:55 +00001593s390_format_RI_RI(const HChar *(*irgen)(UChar r1, UShort i2),
sewardj2019a972011-03-07 16:04:07 +00001594 UChar r1, UShort i2)
1595{
florian55085f82012-11-21 00:36:55 +00001596 const HChar *mnm = irgen(r1, i2);
sewardj2019a972011-03-07 16:04:07 +00001597
sewardj7ee97522011-05-09 21:45:04 +00001598 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001599 s390_disasm(ENC3(MNM, GPR, INT), mnm, r1, (Int)(Short)i2);
1600}
1601
1602static void
florian55085f82012-11-21 00:36:55 +00001603s390_format_RI_RP(const HChar *(*irgen)(UChar r1, UShort i2),
sewardj2019a972011-03-07 16:04:07 +00001604 UChar r1, UShort i2)
1605{
florian55085f82012-11-21 00:36:55 +00001606 const HChar *mnm = irgen(r1, i2);
sewardj2019a972011-03-07 16:04:07 +00001607
sewardj7ee97522011-05-09 21:45:04 +00001608 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001609 s390_disasm(ENC3(MNM, GPR, PCREL), mnm, r1, (Int)(Short)i2);
1610}
1611
1612static void
florian55085f82012-11-21 00:36:55 +00001613s390_format_RIE_RRP(const HChar *(*irgen)(UChar r1, UChar r3, UShort i2),
sewardj2019a972011-03-07 16:04:07 +00001614 UChar r1, UChar r3, UShort i2)
1615{
florian55085f82012-11-21 00:36:55 +00001616 const HChar *mnm = irgen(r1, r3, i2);
sewardj2019a972011-03-07 16:04:07 +00001617
sewardj7ee97522011-05-09 21:45:04 +00001618 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001619 s390_disasm(ENC4(MNM, GPR, GPR, PCREL), mnm, r1, r3, (Int)(Short)i2);
1620}
1621
1622static void
florian55085f82012-11-21 00:36:55 +00001623s390_format_RIE_RRI0(const HChar *(*irgen)(UChar r1, UChar r3, UShort i2),
sewardj2019a972011-03-07 16:04:07 +00001624 UChar r1, UChar r3, UShort i2)
1625{
florian55085f82012-11-21 00:36:55 +00001626 const HChar *mnm = irgen(r1, r3, i2);
sewardj2019a972011-03-07 16:04:07 +00001627
sewardj7ee97522011-05-09 21:45:04 +00001628 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001629 s390_disasm(ENC4(MNM, GPR, GPR, INT), mnm, r1, r3, (Int)(Short)i2);
1630}
1631
1632static void
florian55085f82012-11-21 00:36:55 +00001633s390_format_RIE_RRUUU(const HChar *(*irgen)(UChar r1, UChar r2, UChar i3,
1634 UChar i4, UChar i5),
sewardj2019a972011-03-07 16:04:07 +00001635 UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
1636{
florian55085f82012-11-21 00:36:55 +00001637 const HChar *mnm = irgen(r1, r2, i3, i4, i5);
sewardj2019a972011-03-07 16:04:07 +00001638
sewardj7ee97522011-05-09 21:45:04 +00001639 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001640 s390_disasm(ENC6(MNM, GPR, GPR, UINT, UINT, UINT), mnm, r1, r2, i3, i4,
1641 i5);
1642}
1643
1644static void
florian55085f82012-11-21 00:36:55 +00001645s390_format_RIE_RRPU(const HChar *(*irgen)(UChar r1, UChar r2, UShort i4,
1646 UChar m3),
sewardj2019a972011-03-07 16:04:07 +00001647 UChar r1, UChar r2, UShort i4, UChar m3)
1648{
florian55085f82012-11-21 00:36:55 +00001649 const HChar *mnm = irgen(r1, r2, i4, m3);
sewardj2019a972011-03-07 16:04:07 +00001650
sewardj7ee97522011-05-09 21:45:04 +00001651 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001652 s390_disasm(ENC5(XMNM, GPR, GPR, CABM, PCREL), S390_XMNM_CAB, mnm, m3, r1,
1653 r2, m3, (Int)(Short)i4);
1654}
1655
1656static void
florian55085f82012-11-21 00:36:55 +00001657s390_format_RIE_RUPU(const HChar *(*irgen)(UChar r1, UChar m3, UShort i4,
1658 UChar i2),
sewardj2019a972011-03-07 16:04:07 +00001659 UChar r1, UChar m3, UShort i4, UChar i2)
1660{
florian55085f82012-11-21 00:36:55 +00001661 const HChar *mnm = irgen(r1, m3, i4, i2);
sewardj2019a972011-03-07 16:04:07 +00001662
sewardj7ee97522011-05-09 21:45:04 +00001663 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001664 s390_disasm(ENC5(XMNM, GPR, UINT, CABM, PCREL), S390_XMNM_CAB, mnm, m3,
1665 r1, i2, m3, (Int)(Short)i4);
1666}
1667
1668static void
florian55085f82012-11-21 00:36:55 +00001669s390_format_RIE_RUPI(const HChar *(*irgen)(UChar r1, UChar m3, UShort i4,
1670 UChar i2),
sewardj2019a972011-03-07 16:04:07 +00001671 UChar r1, UChar m3, UShort i4, UChar i2)
1672{
florian55085f82012-11-21 00:36:55 +00001673 const HChar *mnm = irgen(r1, m3, i4, i2);
sewardj2019a972011-03-07 16:04:07 +00001674
sewardj7ee97522011-05-09 21:45:04 +00001675 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001676 s390_disasm(ENC5(XMNM, GPR, INT, CABM, PCREL), S390_XMNM_CAB, mnm, m3, r1,
1677 (Int)(Char)i2, m3, (Int)(Short)i4);
1678}
1679
1680static void
florian55085f82012-11-21 00:36:55 +00001681s390_format_RIL(const HChar *(*irgen)(UChar r1, UInt i2),
sewardj2019a972011-03-07 16:04:07 +00001682 UChar r1, UInt i2)
1683{
1684 irgen(r1, i2);
1685}
1686
1687static void
florian55085f82012-11-21 00:36:55 +00001688s390_format_RIL_RU(const HChar *(*irgen)(UChar r1, UInt i2),
sewardj2019a972011-03-07 16:04:07 +00001689 UChar r1, UInt i2)
1690{
florian55085f82012-11-21 00:36:55 +00001691 const HChar *mnm = irgen(r1, i2);
sewardj2019a972011-03-07 16:04:07 +00001692
sewardj7ee97522011-05-09 21:45:04 +00001693 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001694 s390_disasm(ENC3(MNM, GPR, UINT), mnm, r1, i2);
1695}
1696
1697static void
florian55085f82012-11-21 00:36:55 +00001698s390_format_RIL_RI(const HChar *(*irgen)(UChar r1, UInt i2),
sewardj2019a972011-03-07 16:04:07 +00001699 UChar r1, UInt i2)
1700{
florian55085f82012-11-21 00:36:55 +00001701 const HChar *mnm = irgen(r1, i2);
sewardj2019a972011-03-07 16:04:07 +00001702
sewardj7ee97522011-05-09 21:45:04 +00001703 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001704 s390_disasm(ENC3(MNM, GPR, INT), mnm, r1, i2);
1705}
1706
1707static void
florian55085f82012-11-21 00:36:55 +00001708s390_format_RIL_RP(const HChar *(*irgen)(UChar r1, UInt i2),
sewardj2019a972011-03-07 16:04:07 +00001709 UChar r1, UInt i2)
1710{
florian55085f82012-11-21 00:36:55 +00001711 const HChar *mnm = irgen(r1, i2);
sewardj2019a972011-03-07 16:04:07 +00001712
sewardj7ee97522011-05-09 21:45:04 +00001713 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001714 s390_disasm(ENC3(MNM, GPR, PCREL), mnm, r1, i2);
1715}
1716
1717static void
florian55085f82012-11-21 00:36:55 +00001718s390_format_RIL_UP(const HChar *(*irgen)(void),
sewardj2019a972011-03-07 16:04:07 +00001719 UChar r1, UInt i2)
1720{
florian55085f82012-11-21 00:36:55 +00001721 const HChar *mnm = irgen();
sewardj2019a972011-03-07 16:04:07 +00001722
sewardj7ee97522011-05-09 21:45:04 +00001723 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001724 s390_disasm(ENC3(MNM, UINT, PCREL), mnm, r1, i2);
1725}
1726
1727static void
florian55085f82012-11-21 00:36:55 +00001728s390_format_RIS_RURDI(const HChar *(*irgen)(UChar r1, UChar m3, UChar i2,
sewardj2019a972011-03-07 16:04:07 +00001729 IRTemp op4addr),
1730 UChar r1, UChar m3, UChar b4, UShort d4, UChar i2)
1731{
florian55085f82012-11-21 00:36:55 +00001732 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00001733 IRTemp op4addr = newTemp(Ity_I64);
1734
1735 assign(op4addr, binop(Iop_Add64, mkU64(d4), b4 != 0 ? get_gpr_dw0(b4) :
1736 mkU64(0)));
1737
1738 mnm = irgen(r1, m3, i2, op4addr);
1739
sewardj7ee97522011-05-09 21:45:04 +00001740 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001741 s390_disasm(ENC5(XMNM, GPR, INT, CABM, UDXB), S390_XMNM_CAB, mnm, m3, r1,
1742 (Int)(Char)i2, m3, d4, 0, b4);
1743}
1744
1745static void
florian55085f82012-11-21 00:36:55 +00001746s390_format_RIS_RURDU(const HChar *(*irgen)(UChar r1, UChar m3, UChar i2,
sewardj2019a972011-03-07 16:04:07 +00001747 IRTemp op4addr),
1748 UChar r1, UChar m3, UChar b4, UShort d4, UChar i2)
1749{
florian55085f82012-11-21 00:36:55 +00001750 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00001751 IRTemp op4addr = newTemp(Ity_I64);
1752
1753 assign(op4addr, binop(Iop_Add64, mkU64(d4), b4 != 0 ? get_gpr_dw0(b4) :
1754 mkU64(0)));
1755
1756 mnm = irgen(r1, m3, i2, op4addr);
1757
sewardj7ee97522011-05-09 21:45:04 +00001758 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001759 s390_disasm(ENC5(XMNM, GPR, UINT, CABM, UDXB), S390_XMNM_CAB, mnm, m3, r1,
1760 i2, m3, d4, 0, b4);
1761}
1762
1763static void
florian55085f82012-11-21 00:36:55 +00001764s390_format_RR(const HChar *(*irgen)(UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00001765 UChar r1, UChar r2)
1766{
1767 irgen(r1, r2);
1768}
1769
1770static void
florian55085f82012-11-21 00:36:55 +00001771s390_format_RR_RR(const HChar *(*irgen)(UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00001772 UChar r1, UChar r2)
1773{
florian55085f82012-11-21 00:36:55 +00001774 const HChar *mnm = irgen(r1, r2);
sewardj2019a972011-03-07 16:04:07 +00001775
sewardj7ee97522011-05-09 21:45:04 +00001776 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001777 s390_disasm(ENC3(MNM, GPR, GPR), mnm, r1, r2);
1778}
1779
1780static void
florian55085f82012-11-21 00:36:55 +00001781s390_format_RR_FF(const HChar *(*irgen)(UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00001782 UChar r1, UChar r2)
1783{
florian55085f82012-11-21 00:36:55 +00001784 const HChar *mnm = irgen(r1, r2);
sewardj2019a972011-03-07 16:04:07 +00001785
sewardj7ee97522011-05-09 21:45:04 +00001786 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001787 s390_disasm(ENC3(MNM, FPR, FPR), mnm, r1, r2);
1788}
1789
1790static void
florian55085f82012-11-21 00:36:55 +00001791s390_format_RRE(const HChar *(*irgen)(UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00001792 UChar r1, UChar r2)
1793{
1794 irgen(r1, r2);
1795}
1796
1797static void
florian55085f82012-11-21 00:36:55 +00001798s390_format_RRE_RR(const HChar *(*irgen)(UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00001799 UChar r1, UChar r2)
1800{
florian55085f82012-11-21 00:36:55 +00001801 const HChar *mnm = irgen(r1, r2);
sewardj2019a972011-03-07 16:04:07 +00001802
sewardj7ee97522011-05-09 21:45:04 +00001803 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001804 s390_disasm(ENC3(MNM, GPR, GPR), mnm, r1, r2);
1805}
1806
1807static void
florian55085f82012-11-21 00:36:55 +00001808s390_format_RRE_FF(const HChar *(*irgen)(UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00001809 UChar r1, UChar r2)
1810{
florian55085f82012-11-21 00:36:55 +00001811 const HChar *mnm = irgen(r1, r2);
sewardj2019a972011-03-07 16:04:07 +00001812
sewardj7ee97522011-05-09 21:45:04 +00001813 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001814 s390_disasm(ENC3(MNM, FPR, FPR), mnm, r1, r2);
1815}
1816
1817static void
florian55085f82012-11-21 00:36:55 +00001818s390_format_RRE_RF(const HChar *(*irgen)(UChar, UChar),
sewardj2019a972011-03-07 16:04:07 +00001819 UChar r1, UChar r2)
1820{
florian55085f82012-11-21 00:36:55 +00001821 const HChar *mnm = irgen(r1, r2);
sewardj2019a972011-03-07 16:04:07 +00001822
sewardj7ee97522011-05-09 21:45:04 +00001823 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001824 s390_disasm(ENC3(MNM, GPR, FPR), mnm, r1, r2);
1825}
1826
1827static void
florian55085f82012-11-21 00:36:55 +00001828s390_format_RRE_FR(const HChar *(*irgen)(UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00001829 UChar r1, UChar r2)
1830{
florian55085f82012-11-21 00:36:55 +00001831 const HChar *mnm = irgen(r1, r2);
sewardj2019a972011-03-07 16:04:07 +00001832
sewardj7ee97522011-05-09 21:45:04 +00001833 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001834 s390_disasm(ENC3(MNM, FPR, GPR), mnm, r1, r2);
1835}
1836
1837static void
florian55085f82012-11-21 00:36:55 +00001838s390_format_RRE_R0(const HChar *(*irgen)(UChar r1),
sewardj2019a972011-03-07 16:04:07 +00001839 UChar r1)
1840{
florian55085f82012-11-21 00:36:55 +00001841 const HChar *mnm = irgen(r1);
sewardj2019a972011-03-07 16:04:07 +00001842
sewardj7ee97522011-05-09 21:45:04 +00001843 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001844 s390_disasm(ENC2(MNM, GPR), mnm, r1);
1845}
1846
1847static void
florian55085f82012-11-21 00:36:55 +00001848s390_format_RRE_F0(const HChar *(*irgen)(UChar r1),
sewardj2019a972011-03-07 16:04:07 +00001849 UChar r1)
1850{
florian55085f82012-11-21 00:36:55 +00001851 const HChar *mnm = irgen(r1);
sewardj2019a972011-03-07 16:04:07 +00001852
sewardj7ee97522011-05-09 21:45:04 +00001853 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001854 s390_disasm(ENC2(MNM, FPR), mnm, r1);
1855}
1856
1857static void
florian55085f82012-11-21 00:36:55 +00001858s390_format_RRF_M0RERE(const HChar *(*irgen)(UChar m3, UChar r1, UChar r2),
florian9af37692012-01-15 21:01:16 +00001859 UChar m3, UChar r1, UChar r2)
1860{
florian55085f82012-11-21 00:36:55 +00001861 const HChar *mnm = irgen(m3, r1, r2);
florian9af37692012-01-15 21:01:16 +00001862
1863 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
florianfed3ea32012-07-19 14:54:03 +00001864 s390_disasm(ENC4(MNM, GPR, GPR, UINT), mnm, r1, r2, m3);
florian9af37692012-01-15 21:01:16 +00001865}
1866
1867static void
florian55085f82012-11-21 00:36:55 +00001868s390_format_RRF_F0FF(const HChar *(*irgen)(UChar, UChar, UChar),
sewardj2019a972011-03-07 16:04:07 +00001869 UChar r1, UChar r3, UChar r2)
1870{
florian55085f82012-11-21 00:36:55 +00001871 const HChar *mnm = irgen(r1, r3, r2);
sewardj2019a972011-03-07 16:04:07 +00001872
sewardj7ee97522011-05-09 21:45:04 +00001873 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001874 s390_disasm(ENC4(MNM, FPR, FPR, FPR), mnm, r1, r3, r2);
1875}
1876
1877static void
florian55085f82012-11-21 00:36:55 +00001878s390_format_RRF_UUFF(const HChar *(*irgen)(UChar m3, UChar m4, UChar r1,
1879 UChar r2),
florian4b8efad2012-09-02 18:07:08 +00001880 UChar m3, UChar m4, UChar r1, UChar r2)
1881{
florian55085f82012-11-21 00:36:55 +00001882 const HChar *mnm = irgen(m3, m4, r1, r2);
florian4b8efad2012-09-02 18:07:08 +00001883
1884 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
1885 s390_disasm(ENC5(MNM, FPR, UINT, FPR, UINT), mnm, r1, m3, r2, m4);
1886}
1887
1888static void
florian55085f82012-11-21 00:36:55 +00001889s390_format_RRF_UUFR(const HChar *(*irgen)(UChar m3, UChar m4, UChar r1,
1890 UChar r2),
florian1c8f7ff2012-09-01 00:12:11 +00001891 UChar m3, UChar m4, UChar r1, UChar r2)
1892{
florian55085f82012-11-21 00:36:55 +00001893 const HChar *mnm = irgen(m3, m4, r1, r2);
florian1c8f7ff2012-09-01 00:12:11 +00001894
1895 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
1896 s390_disasm(ENC5(MNM, FPR, UINT, GPR, UINT), mnm, r1, m3, r2, m4);
1897}
1898
1899static void
florian55085f82012-11-21 00:36:55 +00001900s390_format_RRF_UURF(const HChar *(*irgen)(UChar m3, UChar m4, UChar r1,
1901 UChar r2),
florian1c8f7ff2012-09-01 00:12:11 +00001902 UChar m3, UChar m4, UChar r1, UChar r2)
1903{
florian55085f82012-11-21 00:36:55 +00001904 const HChar *mnm = irgen(m3, m4, r1, r2);
florian1c8f7ff2012-09-01 00:12:11 +00001905
1906 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
1907 s390_disasm(ENC5(MNM, GPR, UINT, FPR, UINT), mnm, r1, m3, r2, m4);
1908}
1909
1910
1911static void
florian55085f82012-11-21 00:36:55 +00001912s390_format_RRF_U0RR(const HChar *(*irgen)(UChar m3, UChar r1, UChar r2),
sewardjd7bde722011-04-05 13:19:33 +00001913 UChar m3, UChar r1, UChar r2, Int xmnm_kind)
1914{
1915 irgen(m3, r1, r2);
1916
sewardj7ee97522011-05-09 21:45:04 +00001917 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardjd7bde722011-04-05 13:19:33 +00001918 s390_disasm(ENC3(XMNM, GPR, GPR), xmnm_kind, m3, r1, r2);
1919}
1920
1921static void
florian55085f82012-11-21 00:36:55 +00001922s390_format_RRF_F0FF2(const HChar *(*irgen)(UChar, UChar, UChar),
sewardj2019a972011-03-07 16:04:07 +00001923 UChar r3, UChar r1, UChar r2)
1924{
florian55085f82012-11-21 00:36:55 +00001925 const HChar *mnm = irgen(r3, r1, r2);
sewardj2019a972011-03-07 16:04:07 +00001926
sewardj7ee97522011-05-09 21:45:04 +00001927 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001928 s390_disasm(ENC4(MNM, FPR, FPR, FPR), mnm, r1, r3, r2);
1929}
1930
1931static void
florian55085f82012-11-21 00:36:55 +00001932s390_format_RRF_FUFF2(const HChar *(*irgen)(UChar, UChar, UChar, UChar),
florian12390202012-11-10 22:34:14 +00001933 UChar r3, UChar m4, UChar r1, UChar r2)
1934{
florian55085f82012-11-21 00:36:55 +00001935 const HChar *mnm = irgen(r3, m4, r1, r2);
florian12390202012-11-10 22:34:14 +00001936
1937 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
1938 s390_disasm(ENC5(MNM, FPR, FPR, FPR, UINT), mnm, r1, r2, r3, m4);
1939}
1940
1941static void
florian55085f82012-11-21 00:36:55 +00001942s390_format_RRF_R0RR2(const HChar *(*irgen)(UChar r3, UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00001943 UChar r3, UChar r1, UChar r2)
1944{
florian55085f82012-11-21 00:36:55 +00001945 const HChar *mnm = irgen(r3, r1, r2);
sewardj2019a972011-03-07 16:04:07 +00001946
sewardj7ee97522011-05-09 21:45:04 +00001947 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001948 s390_disasm(ENC4(MNM, GPR, GPR, GPR), mnm, r1, r2, r3);
1949}
1950
1951static void
florian55085f82012-11-21 00:36:55 +00001952s390_format_RRS(const HChar *(*irgen)(UChar r1, UChar r2, UChar m3,
1953 IRTemp op4addr),
sewardj2019a972011-03-07 16:04:07 +00001954 UChar r1, UChar r2, UChar b4, UShort d4, UChar m3)
1955{
florian55085f82012-11-21 00:36:55 +00001956 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00001957 IRTemp op4addr = newTemp(Ity_I64);
1958
1959 assign(op4addr, binop(Iop_Add64, mkU64(d4), b4 != 0 ? get_gpr_dw0(b4) :
1960 mkU64(0)));
1961
1962 mnm = irgen(r1, r2, m3, op4addr);
1963
sewardj7ee97522011-05-09 21:45:04 +00001964 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001965 s390_disasm(ENC5(XMNM, GPR, GPR, CABM, UDXB), S390_XMNM_CAB, mnm, m3, r1,
1966 r2, m3, d4, 0, b4);
1967}
1968
1969static void
florian55085f82012-11-21 00:36:55 +00001970s390_format_RS_R0RD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00001971 UChar r1, UChar b2, UShort d2)
1972{
florian55085f82012-11-21 00:36:55 +00001973 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00001974 IRTemp op2addr = newTemp(Ity_I64);
1975
1976 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
1977 mkU64(0)));
1978
1979 mnm = irgen(r1, op2addr);
1980
sewardj7ee97522011-05-09 21:45:04 +00001981 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001982 s390_disasm(ENC3(MNM, GPR, UDXB), mnm, r1, d2, 0, b2);
1983}
1984
1985static void
florian55085f82012-11-21 00:36:55 +00001986s390_format_RS_RRRD(const HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00001987 UChar r1, UChar r3, UChar b2, UShort d2)
1988{
florian55085f82012-11-21 00:36:55 +00001989 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00001990 IRTemp op2addr = newTemp(Ity_I64);
1991
1992 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
1993 mkU64(0)));
1994
1995 mnm = irgen(r1, r3, op2addr);
1996
sewardj7ee97522011-05-09 21:45:04 +00001997 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001998 s390_disasm(ENC4(MNM, GPR, GPR, UDXB), mnm, r1, r3, d2, 0, b2);
1999}
2000
2001static void
florian55085f82012-11-21 00:36:55 +00002002s390_format_RS_RURD(const HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002003 UChar r1, UChar r3, UChar b2, UShort d2)
2004{
florian55085f82012-11-21 00:36:55 +00002005 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002006 IRTemp op2addr = newTemp(Ity_I64);
2007
2008 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2009 mkU64(0)));
2010
2011 mnm = irgen(r1, r3, op2addr);
2012
sewardj7ee97522011-05-09 21:45:04 +00002013 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002014 s390_disasm(ENC4(MNM, GPR, UINT, UDXB), mnm, r1, r3, d2, 0, b2);
2015}
2016
2017static void
florian55085f82012-11-21 00:36:55 +00002018s390_format_RS_AARD(const HChar *(*irgen)(UChar, UChar, IRTemp),
sewardj2019a972011-03-07 16:04:07 +00002019 UChar r1, UChar r3, UChar b2, UShort d2)
2020{
florian55085f82012-11-21 00:36:55 +00002021 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002022 IRTemp op2addr = newTemp(Ity_I64);
2023
2024 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2025 mkU64(0)));
2026
2027 mnm = irgen(r1, r3, op2addr);
2028
sewardj7ee97522011-05-09 21:45:04 +00002029 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002030 s390_disasm(ENC4(MNM, AR, AR, UDXB), mnm, r1, r3, d2, 0, b2);
2031}
2032
2033static void
florian55085f82012-11-21 00:36:55 +00002034s390_format_RSI_RRP(const HChar *(*irgen)(UChar r1, UChar r3, UShort i2),
sewardj2019a972011-03-07 16:04:07 +00002035 UChar r1, UChar r3, UShort i2)
2036{
florian55085f82012-11-21 00:36:55 +00002037 const HChar *mnm = irgen(r1, r3, i2);
sewardj2019a972011-03-07 16:04:07 +00002038
sewardj7ee97522011-05-09 21:45:04 +00002039 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002040 s390_disasm(ENC4(MNM, GPR, GPR, PCREL), mnm, r1, r3, (Int)(Short)i2);
2041}
2042
2043static void
florian55085f82012-11-21 00:36:55 +00002044s390_format_RSY_RRRD(const HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002045 UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2)
2046{
florian55085f82012-11-21 00:36:55 +00002047 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002048 IRTemp op2addr = newTemp(Ity_I64);
2049 IRTemp d2 = newTemp(Ity_I64);
2050
2051 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2052 assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
2053 mkU64(0)));
2054
2055 mnm = irgen(r1, r3, op2addr);
2056
sewardj7ee97522011-05-09 21:45:04 +00002057 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002058 s390_disasm(ENC4(MNM, GPR, GPR, SDXB), mnm, r1, r3, dh2, dl2, 0, b2);
2059}
2060
2061static void
florian55085f82012-11-21 00:36:55 +00002062s390_format_RSY_AARD(const HChar *(*irgen)(UChar, UChar, IRTemp),
sewardj2019a972011-03-07 16:04:07 +00002063 UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2)
2064{
florian55085f82012-11-21 00:36:55 +00002065 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002066 IRTemp op2addr = newTemp(Ity_I64);
2067 IRTemp d2 = newTemp(Ity_I64);
2068
2069 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2070 assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
2071 mkU64(0)));
2072
2073 mnm = irgen(r1, r3, op2addr);
2074
sewardj7ee97522011-05-09 21:45:04 +00002075 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002076 s390_disasm(ENC4(MNM, AR, AR, SDXB), mnm, r1, r3, dh2, dl2, 0, b2);
2077}
2078
2079static void
florian55085f82012-11-21 00:36:55 +00002080s390_format_RSY_RURD(const HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002081 UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2)
2082{
florian55085f82012-11-21 00:36:55 +00002083 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002084 IRTemp op2addr = newTemp(Ity_I64);
2085 IRTemp d2 = newTemp(Ity_I64);
2086
2087 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2088 assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
2089 mkU64(0)));
2090
2091 mnm = irgen(r1, r3, op2addr);
2092
sewardj7ee97522011-05-09 21:45:04 +00002093 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002094 s390_disasm(ENC4(MNM, GPR, UINT, SDXB), mnm, r1, r3, dh2, dl2, 0, b2);
2095}
2096
2097static void
florian55085f82012-11-21 00:36:55 +00002098s390_format_RSY_RDRM(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
sewardjd7bde722011-04-05 13:19:33 +00002099 UChar r1, UChar m3, UChar b2, UShort dl2, UChar dh2,
2100 Int xmnm_kind)
2101{
2102 IRTemp op2addr = newTemp(Ity_I64);
2103 IRTemp d2 = newTemp(Ity_I64);
2104
florian6820ba52012-07-26 02:01:50 +00002105 next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0)));
2106
sewardjd7bde722011-04-05 13:19:33 +00002107 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2108 assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
2109 mkU64(0)));
2110
2111 irgen(r1, op2addr);
florian6820ba52012-07-26 02:01:50 +00002112
2113 vassert(dis_res->whatNext == Dis_Continue);
sewardjd7bde722011-04-05 13:19:33 +00002114
sewardj7ee97522011-05-09 21:45:04 +00002115 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardjd7bde722011-04-05 13:19:33 +00002116 s390_disasm(ENC3(XMNM, GPR, SDXB), xmnm_kind, m3, r1, dh2, dl2, 0, b2);
2117}
2118
2119static void
florian55085f82012-11-21 00:36:55 +00002120s390_format_RX(const HChar *(*irgen)(UChar r1, UChar x2, UChar b2, UShort d2,
sewardj2019a972011-03-07 16:04:07 +00002121 IRTemp op2addr),
2122 UChar r1, UChar x2, UChar b2, UShort d2)
2123{
2124 IRTemp op2addr = newTemp(Ity_I64);
2125
2126 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
2127 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2128 mkU64(0)));
2129
2130 irgen(r1, x2, b2, d2, op2addr);
2131}
2132
2133static void
florian55085f82012-11-21 00:36:55 +00002134s390_format_RX_RRRD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002135 UChar r1, UChar x2, UChar b2, UShort d2)
2136{
florian55085f82012-11-21 00:36:55 +00002137 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002138 IRTemp op2addr = newTemp(Ity_I64);
2139
2140 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
2141 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2142 mkU64(0)));
2143
2144 mnm = irgen(r1, op2addr);
2145
sewardj7ee97522011-05-09 21:45:04 +00002146 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002147 s390_disasm(ENC3(MNM, GPR, UDXB), mnm, r1, d2, x2, b2);
2148}
2149
2150static void
florian55085f82012-11-21 00:36:55 +00002151s390_format_RX_FRRD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002152 UChar r1, UChar x2, UChar b2, UShort d2)
2153{
florian55085f82012-11-21 00:36:55 +00002154 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002155 IRTemp op2addr = newTemp(Ity_I64);
2156
2157 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
2158 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2159 mkU64(0)));
2160
2161 mnm = irgen(r1, op2addr);
2162
sewardj7ee97522011-05-09 21:45:04 +00002163 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002164 s390_disasm(ENC3(MNM, FPR, UDXB), mnm, r1, d2, x2, b2);
2165}
2166
2167static void
florian55085f82012-11-21 00:36:55 +00002168s390_format_RXE_FRRD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002169 UChar r1, UChar x2, UChar b2, UShort d2)
2170{
florian55085f82012-11-21 00:36:55 +00002171 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002172 IRTemp op2addr = newTemp(Ity_I64);
2173
2174 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
2175 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2176 mkU64(0)));
2177
2178 mnm = irgen(r1, op2addr);
2179
sewardj7ee97522011-05-09 21:45:04 +00002180 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002181 s390_disasm(ENC3(MNM, FPR, UDXB), mnm, r1, d2, x2, b2);
2182}
2183
2184static void
florian55085f82012-11-21 00:36:55 +00002185s390_format_RXF_FRRDF(const HChar *(*irgen)(UChar, IRTemp, UChar),
sewardj2019a972011-03-07 16:04:07 +00002186 UChar r3, UChar x2, UChar b2, UShort d2, UChar r1)
2187{
florian55085f82012-11-21 00:36:55 +00002188 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002189 IRTemp op2addr = newTemp(Ity_I64);
2190
2191 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
2192 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2193 mkU64(0)));
2194
2195 mnm = irgen(r3, op2addr, r1);
2196
sewardj7ee97522011-05-09 21:45:04 +00002197 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002198 s390_disasm(ENC4(MNM, FPR, FPR, UDXB), mnm, r1, r3, d2, x2, b2);
2199}
2200
2201static void
florian55085f82012-11-21 00:36:55 +00002202s390_format_RXY_RRRD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002203 UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
2204{
florian55085f82012-11-21 00:36:55 +00002205 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002206 IRTemp op2addr = newTemp(Ity_I64);
2207 IRTemp d2 = newTemp(Ity_I64);
2208
2209 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2210 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkexpr(d2),
2211 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2212 mkU64(0)));
2213
2214 mnm = irgen(r1, op2addr);
2215
sewardj7ee97522011-05-09 21:45:04 +00002216 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002217 s390_disasm(ENC3(MNM, GPR, SDXB), mnm, r1, dh2, dl2, x2, b2);
2218}
2219
2220static void
florian55085f82012-11-21 00:36:55 +00002221s390_format_RXY_FRRD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002222 UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
2223{
florian55085f82012-11-21 00:36:55 +00002224 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002225 IRTemp op2addr = newTemp(Ity_I64);
2226 IRTemp d2 = newTemp(Ity_I64);
2227
2228 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2229 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkexpr(d2),
2230 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2231 mkU64(0)));
2232
2233 mnm = irgen(r1, op2addr);
2234
sewardj7ee97522011-05-09 21:45:04 +00002235 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002236 s390_disasm(ENC3(MNM, FPR, SDXB), mnm, r1, dh2, dl2, x2, b2);
2237}
2238
2239static void
florian55085f82012-11-21 00:36:55 +00002240s390_format_RXY_URRD(const HChar *(*irgen)(void),
sewardj2019a972011-03-07 16:04:07 +00002241 UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
2242{
florian55085f82012-11-21 00:36:55 +00002243 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002244 IRTemp op2addr = newTemp(Ity_I64);
2245 IRTemp d2 = newTemp(Ity_I64);
2246
2247 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2248 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkexpr(d2),
2249 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2250 mkU64(0)));
2251
2252 mnm = irgen();
2253
sewardj7ee97522011-05-09 21:45:04 +00002254 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002255 s390_disasm(ENC3(MNM, UINT, SDXB), mnm, r1, dh2, dl2, x2, b2);
2256}
2257
2258static void
florian55085f82012-11-21 00:36:55 +00002259s390_format_S_RD(const HChar *(*irgen)(IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002260 UChar b2, UShort d2)
2261{
florian55085f82012-11-21 00:36:55 +00002262 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002263 IRTemp op2addr = newTemp(Ity_I64);
2264
2265 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2266 mkU64(0)));
2267
2268 mnm = irgen(op2addr);
2269
sewardj7ee97522011-05-09 21:45:04 +00002270 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002271 s390_disasm(ENC2(MNM, UDXB), mnm, d2, 0, b2);
2272}
2273
2274static void
florian55085f82012-11-21 00:36:55 +00002275s390_format_SI_URD(const HChar *(*irgen)(UChar i2, IRTemp op1addr),
sewardj2019a972011-03-07 16:04:07 +00002276 UChar i2, UChar b1, UShort d1)
2277{
florian55085f82012-11-21 00:36:55 +00002278 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002279 IRTemp op1addr = newTemp(Ity_I64);
2280
2281 assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
2282 mkU64(0)));
2283
2284 mnm = irgen(i2, op1addr);
2285
sewardj7ee97522011-05-09 21:45:04 +00002286 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002287 s390_disasm(ENC3(MNM, UDXB, UINT), mnm, d1, 0, b1, i2);
2288}
2289
2290static void
florian55085f82012-11-21 00:36:55 +00002291s390_format_SIY_URD(const HChar *(*irgen)(UChar i2, IRTemp op1addr),
sewardj2019a972011-03-07 16:04:07 +00002292 UChar i2, UChar b1, UShort dl1, UChar dh1)
2293{
florian55085f82012-11-21 00:36:55 +00002294 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002295 IRTemp op1addr = newTemp(Ity_I64);
2296 IRTemp d1 = newTemp(Ity_I64);
2297
2298 assign(d1, mkU64(((ULong)(Long)(Char)dh1 << 12) | ((ULong)dl1)));
2299 assign(op1addr, binop(Iop_Add64, mkexpr(d1), b1 != 0 ? get_gpr_dw0(b1) :
2300 mkU64(0)));
2301
2302 mnm = irgen(i2, op1addr);
2303
sewardj7ee97522011-05-09 21:45:04 +00002304 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002305 s390_disasm(ENC3(MNM, SDXB, UINT), mnm, dh1, dl1, 0, b1, i2);
2306}
2307
2308static void
florian55085f82012-11-21 00:36:55 +00002309s390_format_SIY_IRD(const HChar *(*irgen)(UChar i2, IRTemp op1addr),
sewardj2019a972011-03-07 16:04:07 +00002310 UChar i2, UChar b1, UShort dl1, UChar dh1)
2311{
florian55085f82012-11-21 00:36:55 +00002312 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002313 IRTemp op1addr = newTemp(Ity_I64);
2314 IRTemp d1 = newTemp(Ity_I64);
2315
2316 assign(d1, mkU64(((ULong)(Long)(Char)dh1 << 12) | ((ULong)dl1)));
2317 assign(op1addr, binop(Iop_Add64, mkexpr(d1), b1 != 0 ? get_gpr_dw0(b1) :
2318 mkU64(0)));
2319
2320 mnm = irgen(i2, op1addr);
2321
sewardj7ee97522011-05-09 21:45:04 +00002322 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002323 s390_disasm(ENC3(MNM, SDXB, INT), mnm, dh1, dl1, 0, b1, (Int)(Char)i2);
2324}
2325
2326static void
florian55085f82012-11-21 00:36:55 +00002327s390_format_SS_L0RDRD(const HChar *(*irgen)(UChar, IRTemp, IRTemp),
sewardj2019a972011-03-07 16:04:07 +00002328 UChar l, UChar b1, UShort d1, UChar b2, UShort d2)
2329{
florian55085f82012-11-21 00:36:55 +00002330 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002331 IRTemp op1addr = newTemp(Ity_I64);
2332 IRTemp op2addr = newTemp(Ity_I64);
2333
2334 assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
2335 mkU64(0)));
2336 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2337 mkU64(0)));
2338
2339 mnm = irgen(l, op1addr, op2addr);
2340
sewardj7ee97522011-05-09 21:45:04 +00002341 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002342 s390_disasm(ENC3(MNM, UDLB, UDXB), mnm, d1, l, b1, d2, 0, b2);
2343}
2344
2345static void
florian55085f82012-11-21 00:36:55 +00002346s390_format_SIL_RDI(const HChar *(*irgen)(UShort i2, IRTemp op1addr),
sewardj2019a972011-03-07 16:04:07 +00002347 UChar b1, UShort d1, UShort i2)
2348{
florian55085f82012-11-21 00:36:55 +00002349 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002350 IRTemp op1addr = newTemp(Ity_I64);
2351
2352 assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
2353 mkU64(0)));
2354
2355 mnm = irgen(i2, op1addr);
2356
sewardj7ee97522011-05-09 21:45:04 +00002357 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002358 s390_disasm(ENC3(MNM, UDXB, INT), mnm, d1, 0, b1, (Int)(Short)i2);
2359}
2360
2361static void
florian55085f82012-11-21 00:36:55 +00002362s390_format_SIL_RDU(const HChar *(*irgen)(UShort i2, IRTemp op1addr),
sewardj2019a972011-03-07 16:04:07 +00002363 UChar b1, UShort d1, UShort i2)
2364{
florian55085f82012-11-21 00:36:55 +00002365 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002366 IRTemp op1addr = newTemp(Ity_I64);
2367
2368 assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
2369 mkU64(0)));
2370
2371 mnm = irgen(i2, op1addr);
2372
sewardj7ee97522011-05-09 21:45:04 +00002373 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002374 s390_disasm(ENC3(MNM, UDXB, UINT), mnm, d1, 0, b1, i2);
2375}
2376
2377
2378
2379/*------------------------------------------------------------*/
2380/*--- Build IR for opcodes ---*/
2381/*------------------------------------------------------------*/
2382
florian55085f82012-11-21 00:36:55 +00002383static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002384s390_irgen_AR(UChar r1, UChar r2)
2385{
2386 IRTemp op1 = newTemp(Ity_I32);
2387 IRTemp op2 = newTemp(Ity_I32);
2388 IRTemp result = newTemp(Ity_I32);
2389
2390 assign(op1, get_gpr_w1(r1));
2391 assign(op2, get_gpr_w1(r2));
2392 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2393 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2394 put_gpr_w1(r1, mkexpr(result));
2395
2396 return "ar";
2397}
2398
florian55085f82012-11-21 00:36:55 +00002399static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002400s390_irgen_AGR(UChar r1, UChar r2)
2401{
2402 IRTemp op1 = newTemp(Ity_I64);
2403 IRTemp op2 = newTemp(Ity_I64);
2404 IRTemp result = newTemp(Ity_I64);
2405
2406 assign(op1, get_gpr_dw0(r1));
2407 assign(op2, get_gpr_dw0(r2));
2408 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2409 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
2410 put_gpr_dw0(r1, mkexpr(result));
2411
2412 return "agr";
2413}
2414
florian55085f82012-11-21 00:36:55 +00002415static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002416s390_irgen_AGFR(UChar r1, UChar r2)
2417{
2418 IRTemp op1 = newTemp(Ity_I64);
2419 IRTemp op2 = newTemp(Ity_I64);
2420 IRTemp result = newTemp(Ity_I64);
2421
2422 assign(op1, get_gpr_dw0(r1));
2423 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
2424 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2425 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
2426 put_gpr_dw0(r1, mkexpr(result));
2427
2428 return "agfr";
2429}
2430
florian55085f82012-11-21 00:36:55 +00002431static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002432s390_irgen_ARK(UChar r3, UChar r1, UChar r2)
2433{
2434 IRTemp op2 = newTemp(Ity_I32);
2435 IRTemp op3 = newTemp(Ity_I32);
2436 IRTemp result = newTemp(Ity_I32);
2437
2438 assign(op2, get_gpr_w1(r2));
2439 assign(op3, get_gpr_w1(r3));
2440 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2441 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
2442 put_gpr_w1(r1, mkexpr(result));
2443
2444 return "ark";
2445}
2446
florian55085f82012-11-21 00:36:55 +00002447static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002448s390_irgen_AGRK(UChar r3, UChar r1, UChar r2)
2449{
2450 IRTemp op2 = newTemp(Ity_I64);
2451 IRTemp op3 = newTemp(Ity_I64);
2452 IRTemp result = newTemp(Ity_I64);
2453
2454 assign(op2, get_gpr_dw0(r2));
2455 assign(op3, get_gpr_dw0(r3));
2456 assign(result, binop(Iop_Add64, mkexpr(op2), mkexpr(op3)));
2457 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op2, op3);
2458 put_gpr_dw0(r1, mkexpr(result));
2459
2460 return "agrk";
2461}
2462
florian55085f82012-11-21 00:36:55 +00002463static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002464s390_irgen_A(UChar r1, IRTemp op2addr)
2465{
2466 IRTemp op1 = newTemp(Ity_I32);
2467 IRTemp op2 = newTemp(Ity_I32);
2468 IRTemp result = newTemp(Ity_I32);
2469
2470 assign(op1, get_gpr_w1(r1));
2471 assign(op2, load(Ity_I32, mkexpr(op2addr)));
2472 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2473 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2474 put_gpr_w1(r1, mkexpr(result));
2475
2476 return "a";
2477}
2478
florian55085f82012-11-21 00:36:55 +00002479static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002480s390_irgen_AY(UChar r1, IRTemp op2addr)
2481{
2482 IRTemp op1 = newTemp(Ity_I32);
2483 IRTemp op2 = newTemp(Ity_I32);
2484 IRTemp result = newTemp(Ity_I32);
2485
2486 assign(op1, get_gpr_w1(r1));
2487 assign(op2, load(Ity_I32, mkexpr(op2addr)));
2488 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2489 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2490 put_gpr_w1(r1, mkexpr(result));
2491
2492 return "ay";
2493}
2494
florian55085f82012-11-21 00:36:55 +00002495static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002496s390_irgen_AG(UChar r1, IRTemp op2addr)
2497{
2498 IRTemp op1 = newTemp(Ity_I64);
2499 IRTemp op2 = newTemp(Ity_I64);
2500 IRTemp result = newTemp(Ity_I64);
2501
2502 assign(op1, get_gpr_dw0(r1));
2503 assign(op2, load(Ity_I64, mkexpr(op2addr)));
2504 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2505 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
2506 put_gpr_dw0(r1, mkexpr(result));
2507
2508 return "ag";
2509}
2510
florian55085f82012-11-21 00:36:55 +00002511static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002512s390_irgen_AGF(UChar r1, IRTemp op2addr)
2513{
2514 IRTemp op1 = newTemp(Ity_I64);
2515 IRTemp op2 = newTemp(Ity_I64);
2516 IRTemp result = newTemp(Ity_I64);
2517
2518 assign(op1, get_gpr_dw0(r1));
2519 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
2520 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2521 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
2522 put_gpr_dw0(r1, mkexpr(result));
2523
2524 return "agf";
2525}
2526
florian55085f82012-11-21 00:36:55 +00002527static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002528s390_irgen_AFI(UChar r1, UInt i2)
2529{
2530 IRTemp op1 = newTemp(Ity_I32);
2531 Int op2;
2532 IRTemp result = newTemp(Ity_I32);
2533
2534 assign(op1, get_gpr_w1(r1));
2535 op2 = (Int)i2;
2536 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
2537 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
2538 mkU32((UInt)op2)));
2539 put_gpr_w1(r1, mkexpr(result));
2540
2541 return "afi";
2542}
2543
florian55085f82012-11-21 00:36:55 +00002544static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002545s390_irgen_AGFI(UChar r1, UInt i2)
2546{
2547 IRTemp op1 = newTemp(Ity_I64);
2548 Long op2;
2549 IRTemp result = newTemp(Ity_I64);
2550
2551 assign(op1, get_gpr_dw0(r1));
2552 op2 = (Long)(Int)i2;
2553 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64((ULong)op2)));
2554 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, mktemp(Ity_I64,
2555 mkU64((ULong)op2)));
2556 put_gpr_dw0(r1, mkexpr(result));
2557
2558 return "agfi";
2559}
2560
florian55085f82012-11-21 00:36:55 +00002561static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002562s390_irgen_AHIK(UChar r1, UChar r3, UShort i2)
2563{
2564 Int op2;
2565 IRTemp op3 = newTemp(Ity_I32);
2566 IRTemp result = newTemp(Ity_I32);
2567
2568 op2 = (Int)(Short)i2;
2569 assign(op3, get_gpr_w1(r3));
2570 assign(result, binop(Iop_Add32, mkU32((UInt)op2), mkexpr(op3)));
2571 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, mktemp(Ity_I32, mkU32((UInt)
2572 op2)), op3);
2573 put_gpr_w1(r1, mkexpr(result));
2574
2575 return "ahik";
2576}
2577
florian55085f82012-11-21 00:36:55 +00002578static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002579s390_irgen_AGHIK(UChar r1, UChar r3, UShort i2)
2580{
2581 Long op2;
2582 IRTemp op3 = newTemp(Ity_I64);
2583 IRTemp result = newTemp(Ity_I64);
2584
2585 op2 = (Long)(Short)i2;
2586 assign(op3, get_gpr_dw0(r3));
2587 assign(result, binop(Iop_Add64, mkU64((ULong)op2), mkexpr(op3)));
2588 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, mktemp(Ity_I64, mkU64((ULong)
2589 op2)), op3);
2590 put_gpr_dw0(r1, mkexpr(result));
2591
2592 return "aghik";
2593}
2594
florian55085f82012-11-21 00:36:55 +00002595static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002596s390_irgen_ASI(UChar i2, IRTemp op1addr)
2597{
2598 IRTemp op1 = newTemp(Ity_I32);
2599 Int op2;
2600 IRTemp result = newTemp(Ity_I32);
2601
2602 assign(op1, load(Ity_I32, mkexpr(op1addr)));
2603 op2 = (Int)(Char)i2;
2604 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
2605 store(mkexpr(op1addr), mkexpr(result));
2606 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
2607 mkU32((UInt)op2)));
2608
2609 return "asi";
2610}
2611
florian55085f82012-11-21 00:36:55 +00002612static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002613s390_irgen_AGSI(UChar i2, IRTemp op1addr)
2614{
2615 IRTemp op1 = newTemp(Ity_I64);
2616 Long op2;
2617 IRTemp result = newTemp(Ity_I64);
2618
2619 assign(op1, load(Ity_I64, mkexpr(op1addr)));
2620 op2 = (Long)(Char)i2;
2621 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64((ULong)op2)));
2622 store(mkexpr(op1addr), mkexpr(result));
2623 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, mktemp(Ity_I64,
2624 mkU64((ULong)op2)));
2625
2626 return "agsi";
2627}
2628
florian55085f82012-11-21 00:36:55 +00002629static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002630s390_irgen_AH(UChar r1, IRTemp op2addr)
2631{
2632 IRTemp op1 = newTemp(Ity_I32);
2633 IRTemp op2 = newTemp(Ity_I32);
2634 IRTemp result = newTemp(Ity_I32);
2635
2636 assign(op1, get_gpr_w1(r1));
2637 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
2638 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2639 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2640 put_gpr_w1(r1, mkexpr(result));
2641
2642 return "ah";
2643}
2644
florian55085f82012-11-21 00:36:55 +00002645static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002646s390_irgen_AHY(UChar r1, IRTemp op2addr)
2647{
2648 IRTemp op1 = newTemp(Ity_I32);
2649 IRTemp op2 = newTemp(Ity_I32);
2650 IRTemp result = newTemp(Ity_I32);
2651
2652 assign(op1, get_gpr_w1(r1));
2653 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
2654 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2655 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2656 put_gpr_w1(r1, mkexpr(result));
2657
2658 return "ahy";
2659}
2660
florian55085f82012-11-21 00:36:55 +00002661static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002662s390_irgen_AHI(UChar r1, UShort i2)
2663{
2664 IRTemp op1 = newTemp(Ity_I32);
2665 Int op2;
2666 IRTemp result = newTemp(Ity_I32);
2667
2668 assign(op1, get_gpr_w1(r1));
2669 op2 = (Int)(Short)i2;
2670 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
2671 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
2672 mkU32((UInt)op2)));
2673 put_gpr_w1(r1, mkexpr(result));
2674
2675 return "ahi";
2676}
2677
florian55085f82012-11-21 00:36:55 +00002678static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002679s390_irgen_AGHI(UChar r1, UShort i2)
2680{
2681 IRTemp op1 = newTemp(Ity_I64);
2682 Long op2;
2683 IRTemp result = newTemp(Ity_I64);
2684
2685 assign(op1, get_gpr_dw0(r1));
2686 op2 = (Long)(Short)i2;
2687 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64((ULong)op2)));
2688 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, mktemp(Ity_I64,
2689 mkU64((ULong)op2)));
2690 put_gpr_dw0(r1, mkexpr(result));
2691
2692 return "aghi";
2693}
2694
florian55085f82012-11-21 00:36:55 +00002695static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002696s390_irgen_AHHHR(UChar r3, UChar r1, UChar r2)
2697{
2698 IRTemp op2 = newTemp(Ity_I32);
2699 IRTemp op3 = newTemp(Ity_I32);
2700 IRTemp result = newTemp(Ity_I32);
2701
2702 assign(op2, get_gpr_w0(r2));
2703 assign(op3, get_gpr_w0(r3));
2704 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2705 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
2706 put_gpr_w0(r1, mkexpr(result));
2707
2708 return "ahhhr";
2709}
2710
florian55085f82012-11-21 00:36:55 +00002711static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002712s390_irgen_AHHLR(UChar r3, UChar r1, UChar r2)
2713{
2714 IRTemp op2 = newTemp(Ity_I32);
2715 IRTemp op3 = newTemp(Ity_I32);
2716 IRTemp result = newTemp(Ity_I32);
2717
2718 assign(op2, get_gpr_w0(r2));
2719 assign(op3, get_gpr_w1(r3));
2720 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2721 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
2722 put_gpr_w0(r1, mkexpr(result));
2723
2724 return "ahhlr";
2725}
2726
florian55085f82012-11-21 00:36:55 +00002727static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002728s390_irgen_AIH(UChar r1, UInt i2)
2729{
2730 IRTemp op1 = newTemp(Ity_I32);
2731 Int op2;
2732 IRTemp result = newTemp(Ity_I32);
2733
2734 assign(op1, get_gpr_w0(r1));
2735 op2 = (Int)i2;
2736 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
2737 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
2738 mkU32((UInt)op2)));
2739 put_gpr_w0(r1, mkexpr(result));
2740
2741 return "aih";
2742}
2743
florian55085f82012-11-21 00:36:55 +00002744static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002745s390_irgen_ALR(UChar r1, UChar r2)
2746{
2747 IRTemp op1 = newTemp(Ity_I32);
2748 IRTemp op2 = newTemp(Ity_I32);
2749 IRTemp result = newTemp(Ity_I32);
2750
2751 assign(op1, get_gpr_w1(r1));
2752 assign(op2, get_gpr_w1(r2));
2753 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2754 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, op2);
2755 put_gpr_w1(r1, mkexpr(result));
2756
2757 return "alr";
2758}
2759
florian55085f82012-11-21 00:36:55 +00002760static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002761s390_irgen_ALGR(UChar r1, UChar r2)
2762{
2763 IRTemp op1 = newTemp(Ity_I64);
2764 IRTemp op2 = newTemp(Ity_I64);
2765 IRTemp result = newTemp(Ity_I64);
2766
2767 assign(op1, get_gpr_dw0(r1));
2768 assign(op2, get_gpr_dw0(r2));
2769 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2770 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
2771 put_gpr_dw0(r1, mkexpr(result));
2772
2773 return "algr";
2774}
2775
florian55085f82012-11-21 00:36:55 +00002776static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002777s390_irgen_ALGFR(UChar r1, UChar r2)
2778{
2779 IRTemp op1 = newTemp(Ity_I64);
2780 IRTemp op2 = newTemp(Ity_I64);
2781 IRTemp result = newTemp(Ity_I64);
2782
2783 assign(op1, get_gpr_dw0(r1));
2784 assign(op2, unop(Iop_32Uto64, get_gpr_w1(r2)));
2785 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2786 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
2787 put_gpr_dw0(r1, mkexpr(result));
2788
2789 return "algfr";
2790}
2791
florian55085f82012-11-21 00:36:55 +00002792static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002793s390_irgen_ALRK(UChar r3, UChar r1, UChar r2)
2794{
2795 IRTemp op2 = newTemp(Ity_I32);
2796 IRTemp op3 = newTemp(Ity_I32);
2797 IRTemp result = newTemp(Ity_I32);
2798
2799 assign(op2, get_gpr_w1(r2));
2800 assign(op3, get_gpr_w1(r3));
2801 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2802 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
2803 put_gpr_w1(r1, mkexpr(result));
2804
2805 return "alrk";
2806}
2807
florian55085f82012-11-21 00:36:55 +00002808static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002809s390_irgen_ALGRK(UChar r3, UChar r1, UChar r2)
2810{
2811 IRTemp op2 = newTemp(Ity_I64);
2812 IRTemp op3 = newTemp(Ity_I64);
2813 IRTemp result = newTemp(Ity_I64);
2814
2815 assign(op2, get_gpr_dw0(r2));
2816 assign(op3, get_gpr_dw0(r3));
2817 assign(result, binop(Iop_Add64, mkexpr(op2), mkexpr(op3)));
2818 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op2, op3);
2819 put_gpr_dw0(r1, mkexpr(result));
2820
2821 return "algrk";
2822}
2823
florian55085f82012-11-21 00:36:55 +00002824static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002825s390_irgen_AL(UChar r1, IRTemp op2addr)
2826{
2827 IRTemp op1 = newTemp(Ity_I32);
2828 IRTemp op2 = newTemp(Ity_I32);
2829 IRTemp result = newTemp(Ity_I32);
2830
2831 assign(op1, get_gpr_w1(r1));
2832 assign(op2, load(Ity_I32, mkexpr(op2addr)));
2833 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2834 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, op2);
2835 put_gpr_w1(r1, mkexpr(result));
2836
2837 return "al";
2838}
2839
florian55085f82012-11-21 00:36:55 +00002840static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002841s390_irgen_ALY(UChar r1, IRTemp op2addr)
2842{
2843 IRTemp op1 = newTemp(Ity_I32);
2844 IRTemp op2 = newTemp(Ity_I32);
2845 IRTemp result = newTemp(Ity_I32);
2846
2847 assign(op1, get_gpr_w1(r1));
2848 assign(op2, load(Ity_I32, mkexpr(op2addr)));
2849 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2850 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, op2);
2851 put_gpr_w1(r1, mkexpr(result));
2852
2853 return "aly";
2854}
2855
florian55085f82012-11-21 00:36:55 +00002856static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002857s390_irgen_ALG(UChar r1, IRTemp op2addr)
2858{
2859 IRTemp op1 = newTemp(Ity_I64);
2860 IRTemp op2 = newTemp(Ity_I64);
2861 IRTemp result = newTemp(Ity_I64);
2862
2863 assign(op1, get_gpr_dw0(r1));
2864 assign(op2, load(Ity_I64, mkexpr(op2addr)));
2865 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2866 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
2867 put_gpr_dw0(r1, mkexpr(result));
2868
2869 return "alg";
2870}
2871
florian55085f82012-11-21 00:36:55 +00002872static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002873s390_irgen_ALGF(UChar r1, IRTemp op2addr)
2874{
2875 IRTemp op1 = newTemp(Ity_I64);
2876 IRTemp op2 = newTemp(Ity_I64);
2877 IRTemp result = newTemp(Ity_I64);
2878
2879 assign(op1, get_gpr_dw0(r1));
2880 assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
2881 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2882 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
2883 put_gpr_dw0(r1, mkexpr(result));
2884
2885 return "algf";
2886}
2887
florian55085f82012-11-21 00:36:55 +00002888static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002889s390_irgen_ALFI(UChar r1, UInt i2)
2890{
2891 IRTemp op1 = newTemp(Ity_I32);
2892 UInt op2;
2893 IRTemp result = newTemp(Ity_I32);
2894
2895 assign(op1, get_gpr_w1(r1));
2896 op2 = i2;
2897 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
2898 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, mktemp(Ity_I32,
2899 mkU32(op2)));
2900 put_gpr_w1(r1, mkexpr(result));
2901
2902 return "alfi";
2903}
2904
florian55085f82012-11-21 00:36:55 +00002905static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002906s390_irgen_ALGFI(UChar r1, UInt i2)
2907{
2908 IRTemp op1 = newTemp(Ity_I64);
2909 ULong op2;
2910 IRTemp result = newTemp(Ity_I64);
2911
2912 assign(op1, get_gpr_dw0(r1));
2913 op2 = (ULong)i2;
2914 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64(op2)));
2915 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, mktemp(Ity_I64,
2916 mkU64(op2)));
2917 put_gpr_dw0(r1, mkexpr(result));
2918
2919 return "algfi";
2920}
2921
florian55085f82012-11-21 00:36:55 +00002922static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002923s390_irgen_ALHHHR(UChar r3, UChar r1, UChar r2)
2924{
2925 IRTemp op2 = newTemp(Ity_I32);
2926 IRTemp op3 = newTemp(Ity_I32);
2927 IRTemp result = newTemp(Ity_I32);
2928
2929 assign(op2, get_gpr_w0(r2));
2930 assign(op3, get_gpr_w0(r3));
2931 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2932 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
2933 put_gpr_w0(r1, mkexpr(result));
2934
2935 return "alhhhr";
2936}
2937
florian55085f82012-11-21 00:36:55 +00002938static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002939s390_irgen_ALHHLR(UChar r3, UChar r1, UChar r2)
2940{
2941 IRTemp op2 = newTemp(Ity_I32);
2942 IRTemp op3 = newTemp(Ity_I32);
2943 IRTemp result = newTemp(Ity_I32);
2944
2945 assign(op2, get_gpr_w0(r2));
2946 assign(op3, get_gpr_w1(r3));
2947 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2948 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
2949 put_gpr_w0(r1, mkexpr(result));
2950
2951 return "alhhlr";
2952}
2953
florian55085f82012-11-21 00:36:55 +00002954static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002955s390_irgen_ALCR(UChar r1, UChar r2)
2956{
2957 IRTemp op1 = newTemp(Ity_I32);
2958 IRTemp op2 = newTemp(Ity_I32);
2959 IRTemp result = newTemp(Ity_I32);
2960 IRTemp carry_in = newTemp(Ity_I32);
2961
2962 assign(op1, get_gpr_w1(r1));
2963 assign(op2, get_gpr_w1(r2));
2964 assign(carry_in, binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)));
2965 assign(result, binop(Iop_Add32, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)),
2966 mkexpr(carry_in)));
2967 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_32, op1, op2, carry_in);
2968 put_gpr_w1(r1, mkexpr(result));
2969
2970 return "alcr";
2971}
2972
florian55085f82012-11-21 00:36:55 +00002973static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002974s390_irgen_ALCGR(UChar r1, UChar r2)
2975{
2976 IRTemp op1 = newTemp(Ity_I64);
2977 IRTemp op2 = newTemp(Ity_I64);
2978 IRTemp result = newTemp(Ity_I64);
2979 IRTemp carry_in = newTemp(Ity_I64);
2980
2981 assign(op1, get_gpr_dw0(r1));
2982 assign(op2, get_gpr_dw0(r2));
2983 assign(carry_in, unop(Iop_32Uto64, binop(Iop_Shr32, s390_call_calculate_cc(),
2984 mkU8(1))));
2985 assign(result, binop(Iop_Add64, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)),
2986 mkexpr(carry_in)));
2987 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_64, op1, op2, carry_in);
2988 put_gpr_dw0(r1, mkexpr(result));
2989
2990 return "alcgr";
2991}
2992
florian55085f82012-11-21 00:36:55 +00002993static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002994s390_irgen_ALC(UChar r1, IRTemp op2addr)
2995{
2996 IRTemp op1 = newTemp(Ity_I32);
2997 IRTemp op2 = newTemp(Ity_I32);
2998 IRTemp result = newTemp(Ity_I32);
2999 IRTemp carry_in = newTemp(Ity_I32);
3000
3001 assign(op1, get_gpr_w1(r1));
3002 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3003 assign(carry_in, binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)));
3004 assign(result, binop(Iop_Add32, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)),
3005 mkexpr(carry_in)));
3006 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_32, op1, op2, carry_in);
3007 put_gpr_w1(r1, mkexpr(result));
3008
3009 return "alc";
3010}
3011
florian55085f82012-11-21 00:36:55 +00003012static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003013s390_irgen_ALCG(UChar r1, IRTemp op2addr)
3014{
3015 IRTemp op1 = newTemp(Ity_I64);
3016 IRTemp op2 = newTemp(Ity_I64);
3017 IRTemp result = newTemp(Ity_I64);
3018 IRTemp carry_in = newTemp(Ity_I64);
3019
3020 assign(op1, get_gpr_dw0(r1));
3021 assign(op2, load(Ity_I64, mkexpr(op2addr)));
3022 assign(carry_in, unop(Iop_32Uto64, binop(Iop_Shr32, s390_call_calculate_cc(),
3023 mkU8(1))));
3024 assign(result, binop(Iop_Add64, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)),
3025 mkexpr(carry_in)));
3026 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_64, op1, op2, carry_in);
3027 put_gpr_dw0(r1, mkexpr(result));
3028
3029 return "alcg";
3030}
3031
florian55085f82012-11-21 00:36:55 +00003032static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003033s390_irgen_ALSI(UChar i2, IRTemp op1addr)
3034{
3035 IRTemp op1 = newTemp(Ity_I32);
3036 UInt op2;
3037 IRTemp result = newTemp(Ity_I32);
3038
3039 assign(op1, load(Ity_I32, mkexpr(op1addr)));
3040 op2 = (UInt)(Int)(Char)i2;
3041 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
3042 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, mktemp(Ity_I32,
3043 mkU32(op2)));
3044 store(mkexpr(op1addr), mkexpr(result));
3045
3046 return "alsi";
3047}
3048
florian55085f82012-11-21 00:36:55 +00003049static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003050s390_irgen_ALGSI(UChar i2, IRTemp op1addr)
3051{
3052 IRTemp op1 = newTemp(Ity_I64);
3053 ULong op2;
3054 IRTemp result = newTemp(Ity_I64);
3055
3056 assign(op1, load(Ity_I64, mkexpr(op1addr)));
3057 op2 = (ULong)(Long)(Char)i2;
3058 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64(op2)));
3059 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, mktemp(Ity_I64,
3060 mkU64(op2)));
3061 store(mkexpr(op1addr), mkexpr(result));
3062
3063 return "algsi";
3064}
3065
florian55085f82012-11-21 00:36:55 +00003066static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003067s390_irgen_ALHSIK(UChar r1, UChar r3, UShort i2)
3068{
3069 UInt op2;
3070 IRTemp op3 = newTemp(Ity_I32);
3071 IRTemp result = newTemp(Ity_I32);
3072
3073 op2 = (UInt)(Int)(Short)i2;
3074 assign(op3, get_gpr_w1(r3));
3075 assign(result, binop(Iop_Add32, mkU32(op2), mkexpr(op3)));
3076 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, mktemp(Ity_I32, mkU32(op2)),
3077 op3);
3078 put_gpr_w1(r1, mkexpr(result));
3079
3080 return "alhsik";
3081}
3082
florian55085f82012-11-21 00:36:55 +00003083static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003084s390_irgen_ALGHSIK(UChar r1, UChar r3, UShort i2)
3085{
3086 ULong op2;
3087 IRTemp op3 = newTemp(Ity_I64);
3088 IRTemp result = newTemp(Ity_I64);
3089
3090 op2 = (ULong)(Long)(Short)i2;
3091 assign(op3, get_gpr_dw0(r3));
3092 assign(result, binop(Iop_Add64, mkU64(op2), mkexpr(op3)));
3093 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, mktemp(Ity_I64, mkU64(op2)),
3094 op3);
3095 put_gpr_dw0(r1, mkexpr(result));
3096
3097 return "alghsik";
3098}
3099
florian55085f82012-11-21 00:36:55 +00003100static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003101s390_irgen_ALSIH(UChar r1, UInt i2)
3102{
3103 IRTemp op1 = newTemp(Ity_I32);
3104 UInt op2;
3105 IRTemp result = newTemp(Ity_I32);
3106
3107 assign(op1, get_gpr_w0(r1));
3108 op2 = i2;
3109 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
3110 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, mktemp(Ity_I32,
3111 mkU32(op2)));
3112 put_gpr_w0(r1, mkexpr(result));
3113
3114 return "alsih";
3115}
3116
florian55085f82012-11-21 00:36:55 +00003117static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003118s390_irgen_ALSIHN(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_w0(r1));
3125 op2 = i2;
3126 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
3127 put_gpr_w0(r1, mkexpr(result));
3128
3129 return "alsihn";
3130}
3131
florian55085f82012-11-21 00:36:55 +00003132static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003133s390_irgen_NR(UChar r1, UChar r2)
3134{
3135 IRTemp op1 = newTemp(Ity_I32);
3136 IRTemp op2 = newTemp(Ity_I32);
3137 IRTemp result = newTemp(Ity_I32);
3138
3139 assign(op1, get_gpr_w1(r1));
3140 assign(op2, get_gpr_w1(r2));
3141 assign(result, binop(Iop_And32, mkexpr(op1), mkexpr(op2)));
3142 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3143 put_gpr_w1(r1, mkexpr(result));
3144
3145 return "nr";
3146}
3147
florian55085f82012-11-21 00:36:55 +00003148static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003149s390_irgen_NGR(UChar r1, UChar r2)
3150{
3151 IRTemp op1 = newTemp(Ity_I64);
3152 IRTemp op2 = newTemp(Ity_I64);
3153 IRTemp result = newTemp(Ity_I64);
3154
3155 assign(op1, get_gpr_dw0(r1));
3156 assign(op2, get_gpr_dw0(r2));
3157 assign(result, binop(Iop_And64, mkexpr(op1), mkexpr(op2)));
3158 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3159 put_gpr_dw0(r1, mkexpr(result));
3160
3161 return "ngr";
3162}
3163
florian55085f82012-11-21 00:36:55 +00003164static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003165s390_irgen_NRK(UChar r3, UChar r1, UChar r2)
3166{
3167 IRTemp op2 = newTemp(Ity_I32);
3168 IRTemp op3 = newTemp(Ity_I32);
3169 IRTemp result = newTemp(Ity_I32);
3170
3171 assign(op2, get_gpr_w1(r2));
3172 assign(op3, get_gpr_w1(r3));
3173 assign(result, binop(Iop_And32, mkexpr(op2), mkexpr(op3)));
3174 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3175 put_gpr_w1(r1, mkexpr(result));
3176
3177 return "nrk";
3178}
3179
florian55085f82012-11-21 00:36:55 +00003180static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003181s390_irgen_NGRK(UChar r3, UChar r1, UChar r2)
3182{
3183 IRTemp op2 = newTemp(Ity_I64);
3184 IRTemp op3 = newTemp(Ity_I64);
3185 IRTemp result = newTemp(Ity_I64);
3186
3187 assign(op2, get_gpr_dw0(r2));
3188 assign(op3, get_gpr_dw0(r3));
3189 assign(result, binop(Iop_And64, mkexpr(op2), mkexpr(op3)));
3190 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3191 put_gpr_dw0(r1, mkexpr(result));
3192
3193 return "ngrk";
3194}
3195
florian55085f82012-11-21 00:36:55 +00003196static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003197s390_irgen_N(UChar r1, IRTemp op2addr)
3198{
3199 IRTemp op1 = newTemp(Ity_I32);
3200 IRTemp op2 = newTemp(Ity_I32);
3201 IRTemp result = newTemp(Ity_I32);
3202
3203 assign(op1, get_gpr_w1(r1));
3204 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3205 assign(result, binop(Iop_And32, mkexpr(op1), mkexpr(op2)));
3206 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3207 put_gpr_w1(r1, mkexpr(result));
3208
3209 return "n";
3210}
3211
florian55085f82012-11-21 00:36:55 +00003212static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003213s390_irgen_NY(UChar r1, IRTemp op2addr)
3214{
3215 IRTemp op1 = newTemp(Ity_I32);
3216 IRTemp op2 = newTemp(Ity_I32);
3217 IRTemp result = newTemp(Ity_I32);
3218
3219 assign(op1, get_gpr_w1(r1));
3220 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3221 assign(result, binop(Iop_And32, mkexpr(op1), mkexpr(op2)));
3222 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3223 put_gpr_w1(r1, mkexpr(result));
3224
3225 return "ny";
3226}
3227
florian55085f82012-11-21 00:36:55 +00003228static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003229s390_irgen_NG(UChar r1, IRTemp op2addr)
3230{
3231 IRTemp op1 = newTemp(Ity_I64);
3232 IRTemp op2 = newTemp(Ity_I64);
3233 IRTemp result = newTemp(Ity_I64);
3234
3235 assign(op1, get_gpr_dw0(r1));
3236 assign(op2, load(Ity_I64, mkexpr(op2addr)));
3237 assign(result, binop(Iop_And64, mkexpr(op1), mkexpr(op2)));
3238 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3239 put_gpr_dw0(r1, mkexpr(result));
3240
3241 return "ng";
3242}
3243
florian55085f82012-11-21 00:36:55 +00003244static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003245s390_irgen_NI(UChar i2, IRTemp op1addr)
3246{
3247 IRTemp op1 = newTemp(Ity_I8);
3248 UChar op2;
3249 IRTemp result = newTemp(Ity_I8);
3250
3251 assign(op1, load(Ity_I8, mkexpr(op1addr)));
3252 op2 = i2;
3253 assign(result, binop(Iop_And8, mkexpr(op1), mkU8(op2)));
3254 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3255 store(mkexpr(op1addr), mkexpr(result));
3256
3257 return "ni";
3258}
3259
florian55085f82012-11-21 00:36:55 +00003260static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003261s390_irgen_NIY(UChar i2, IRTemp op1addr)
3262{
3263 IRTemp op1 = newTemp(Ity_I8);
3264 UChar op2;
3265 IRTemp result = newTemp(Ity_I8);
3266
3267 assign(op1, load(Ity_I8, mkexpr(op1addr)));
3268 op2 = i2;
3269 assign(result, binop(Iop_And8, mkexpr(op1), mkU8(op2)));
3270 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3271 store(mkexpr(op1addr), mkexpr(result));
3272
3273 return "niy";
3274}
3275
florian55085f82012-11-21 00:36:55 +00003276static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003277s390_irgen_NIHF(UChar r1, UInt i2)
3278{
3279 IRTemp op1 = newTemp(Ity_I32);
3280 UInt op2;
3281 IRTemp result = newTemp(Ity_I32);
3282
3283 assign(op1, get_gpr_w0(r1));
3284 op2 = i2;
3285 assign(result, binop(Iop_And32, mkexpr(op1), mkU32(op2)));
3286 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3287 put_gpr_w0(r1, mkexpr(result));
3288
3289 return "nihf";
3290}
3291
florian55085f82012-11-21 00:36:55 +00003292static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003293s390_irgen_NIHH(UChar r1, UShort i2)
3294{
3295 IRTemp op1 = newTemp(Ity_I16);
3296 UShort op2;
3297 IRTemp result = newTemp(Ity_I16);
3298
3299 assign(op1, get_gpr_hw0(r1));
3300 op2 = i2;
3301 assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
3302 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3303 put_gpr_hw0(r1, mkexpr(result));
3304
3305 return "nihh";
3306}
3307
florian55085f82012-11-21 00:36:55 +00003308static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003309s390_irgen_NIHL(UChar r1, UShort i2)
3310{
3311 IRTemp op1 = newTemp(Ity_I16);
3312 UShort op2;
3313 IRTemp result = newTemp(Ity_I16);
3314
3315 assign(op1, get_gpr_hw1(r1));
3316 op2 = i2;
3317 assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
3318 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3319 put_gpr_hw1(r1, mkexpr(result));
3320
3321 return "nihl";
3322}
3323
florian55085f82012-11-21 00:36:55 +00003324static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003325s390_irgen_NILF(UChar r1, UInt i2)
3326{
3327 IRTemp op1 = newTemp(Ity_I32);
3328 UInt op2;
3329 IRTemp result = newTemp(Ity_I32);
3330
3331 assign(op1, get_gpr_w1(r1));
3332 op2 = i2;
3333 assign(result, binop(Iop_And32, mkexpr(op1), mkU32(op2)));
3334 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3335 put_gpr_w1(r1, mkexpr(result));
3336
3337 return "nilf";
3338}
3339
florian55085f82012-11-21 00:36:55 +00003340static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003341s390_irgen_NILH(UChar r1, UShort i2)
3342{
3343 IRTemp op1 = newTemp(Ity_I16);
3344 UShort op2;
3345 IRTemp result = newTemp(Ity_I16);
3346
3347 assign(op1, get_gpr_hw2(r1));
3348 op2 = i2;
3349 assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
3350 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3351 put_gpr_hw2(r1, mkexpr(result));
3352
3353 return "nilh";
3354}
3355
florian55085f82012-11-21 00:36:55 +00003356static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003357s390_irgen_NILL(UChar r1, UShort i2)
3358{
3359 IRTemp op1 = newTemp(Ity_I16);
3360 UShort op2;
3361 IRTemp result = newTemp(Ity_I16);
3362
3363 assign(op1, get_gpr_hw3(r1));
3364 op2 = i2;
3365 assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
3366 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3367 put_gpr_hw3(r1, mkexpr(result));
3368
3369 return "nill";
3370}
3371
florian55085f82012-11-21 00:36:55 +00003372static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003373s390_irgen_BASR(UChar r1, UChar r2)
3374{
3375 IRTemp target = newTemp(Ity_I64);
3376
3377 if (r2 == 0) {
3378 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 2ULL));
3379 } else {
3380 if (r1 != r2) {
3381 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 2ULL));
3382 call_function(get_gpr_dw0(r2));
3383 } else {
3384 assign(target, get_gpr_dw0(r2));
3385 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 2ULL));
3386 call_function(mkexpr(target));
3387 }
3388 }
3389
3390 return "basr";
3391}
3392
florian55085f82012-11-21 00:36:55 +00003393static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003394s390_irgen_BAS(UChar r1, IRTemp op2addr)
3395{
3396 IRTemp target = newTemp(Ity_I64);
3397
3398 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 4ULL));
3399 assign(target, mkexpr(op2addr));
3400 call_function(mkexpr(target));
3401
3402 return "bas";
3403}
3404
florian55085f82012-11-21 00:36:55 +00003405static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003406s390_irgen_BCR(UChar r1, UChar r2)
3407{
3408 IRTemp cond = newTemp(Ity_I32);
3409
sewardja52e37e2011-04-28 18:48:06 +00003410 if (r2 == 0 && (r1 >= 14)) { /* serialization */
3411 stmt(IRStmt_MBE(Imbe_Fence));
3412 }
3413
sewardj2019a972011-03-07 16:04:07 +00003414 if ((r2 == 0) || (r1 == 0)) {
3415 } else {
3416 if (r1 == 15) {
3417 return_from_function(get_gpr_dw0(r2));
3418 } else {
3419 assign(cond, s390_call_calculate_cond(r1));
florianf321da72012-07-21 20:32:57 +00003420 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3421 get_gpr_dw0(r2));
sewardj2019a972011-03-07 16:04:07 +00003422 }
3423 }
sewardj7ee97522011-05-09 21:45:04 +00003424 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00003425 s390_disasm(ENC2(XMNM, GPR), S390_XMNM_BCR, r1, r2);
3426
3427 return "bcr";
3428}
3429
florian55085f82012-11-21 00:36:55 +00003430static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003431s390_irgen_BC(UChar r1, UChar x2, UChar b2, UShort d2, IRTemp op2addr)
3432{
3433 IRTemp cond = newTemp(Ity_I32);
3434
3435 if (r1 == 0) {
3436 } else {
3437 if (r1 == 15) {
3438 always_goto(mkexpr(op2addr));
3439 } else {
3440 assign(cond, s390_call_calculate_cond(r1));
florianf321da72012-07-21 20:32:57 +00003441 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3442 mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003443 }
3444 }
sewardj7ee97522011-05-09 21:45:04 +00003445 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00003446 s390_disasm(ENC2(XMNM, UDXB), S390_XMNM_BC, r1, d2, x2, b2);
3447
3448 return "bc";
3449}
3450
florian55085f82012-11-21 00:36:55 +00003451static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003452s390_irgen_BCTR(UChar r1, UChar r2)
3453{
3454 put_gpr_w1(r1, binop(Iop_Sub32, get_gpr_w1(r1), mkU32(1)));
3455 if (r2 != 0) {
florianf321da72012-07-21 20:32:57 +00003456 if_condition_goto_computed(binop(Iop_CmpNE32, get_gpr_w1(r1), mkU32(0)),
3457 get_gpr_dw0(r2));
sewardj2019a972011-03-07 16:04:07 +00003458 }
3459
3460 return "bctr";
3461}
3462
florian55085f82012-11-21 00:36:55 +00003463static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003464s390_irgen_BCTGR(UChar r1, UChar r2)
3465{
3466 put_gpr_dw0(r1, binop(Iop_Sub64, get_gpr_dw0(r1), mkU64(1)));
3467 if (r2 != 0) {
florianf321da72012-07-21 20:32:57 +00003468 if_condition_goto_computed(binop(Iop_CmpNE64, get_gpr_dw0(r1), mkU64(0)),
3469 get_gpr_dw0(r2));
sewardj2019a972011-03-07 16:04:07 +00003470 }
3471
3472 return "bctgr";
3473}
3474
florian55085f82012-11-21 00:36:55 +00003475static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003476s390_irgen_BCT(UChar r1, IRTemp op2addr)
3477{
3478 put_gpr_w1(r1, binop(Iop_Sub32, get_gpr_w1(r1), mkU32(1)));
florianf321da72012-07-21 20:32:57 +00003479 if_condition_goto_computed(binop(Iop_CmpNE32, get_gpr_w1(r1), mkU32(0)),
3480 mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003481
3482 return "bct";
3483}
3484
florian55085f82012-11-21 00:36:55 +00003485static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003486s390_irgen_BCTG(UChar r1, IRTemp op2addr)
3487{
3488 put_gpr_dw0(r1, binop(Iop_Sub64, get_gpr_dw0(r1), mkU64(1)));
florianf321da72012-07-21 20:32:57 +00003489 if_condition_goto_computed(binop(Iop_CmpNE64, get_gpr_dw0(r1), mkU64(0)),
3490 mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003491
3492 return "bctg";
3493}
3494
florian55085f82012-11-21 00:36:55 +00003495static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003496s390_irgen_BXH(UChar r1, UChar r3, IRTemp op2addr)
3497{
3498 IRTemp value = newTemp(Ity_I32);
3499
3500 assign(value, get_gpr_w1(r3 | 1));
3501 put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
florianf321da72012-07-21 20:32:57 +00003502 if_condition_goto_computed(binop(Iop_CmpLT32S, mkexpr(value),
3503 get_gpr_w1(r1)), mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003504
3505 return "bxh";
3506}
3507
florian55085f82012-11-21 00:36:55 +00003508static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003509s390_irgen_BXHG(UChar r1, UChar r3, IRTemp op2addr)
3510{
3511 IRTemp value = newTemp(Ity_I64);
3512
3513 assign(value, get_gpr_dw0(r3 | 1));
3514 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
florianf321da72012-07-21 20:32:57 +00003515 if_condition_goto_computed(binop(Iop_CmpLT64S, mkexpr(value),
3516 get_gpr_dw0(r1)), mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003517
3518 return "bxhg";
3519}
3520
florian55085f82012-11-21 00:36:55 +00003521static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003522s390_irgen_BXLE(UChar r1, UChar r3, IRTemp op2addr)
3523{
3524 IRTemp value = newTemp(Ity_I32);
3525
3526 assign(value, get_gpr_w1(r3 | 1));
3527 put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
florianf321da72012-07-21 20:32:57 +00003528 if_condition_goto_computed(binop(Iop_CmpLE32S, get_gpr_w1(r1),
3529 mkexpr(value)), mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003530
3531 return "bxle";
3532}
3533
florian55085f82012-11-21 00:36:55 +00003534static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003535s390_irgen_BXLEG(UChar r1, UChar r3, IRTemp op2addr)
3536{
3537 IRTemp value = newTemp(Ity_I64);
3538
3539 assign(value, get_gpr_dw0(r3 | 1));
3540 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
florianf321da72012-07-21 20:32:57 +00003541 if_condition_goto_computed(binop(Iop_CmpLE64S, get_gpr_dw0(r1),
3542 mkexpr(value)), mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003543
3544 return "bxleg";
3545}
3546
florian55085f82012-11-21 00:36:55 +00003547static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003548s390_irgen_BRAS(UChar r1, UShort i2)
3549{
3550 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 4ULL));
floriana64c2432011-07-16 02:11:50 +00003551 call_function_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
sewardj2019a972011-03-07 16:04:07 +00003552
3553 return "bras";
3554}
3555
florian55085f82012-11-21 00:36:55 +00003556static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003557s390_irgen_BRASL(UChar r1, UInt i2)
3558{
3559 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 6ULL));
floriana64c2432011-07-16 02:11:50 +00003560 call_function_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1));
sewardj2019a972011-03-07 16:04:07 +00003561
3562 return "brasl";
3563}
3564
florian55085f82012-11-21 00:36:55 +00003565static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003566s390_irgen_BRC(UChar r1, UShort i2)
3567{
3568 IRTemp cond = newTemp(Ity_I32);
3569
3570 if (r1 == 0) {
3571 } else {
3572 if (r1 == 15) {
floriana64c2432011-07-16 02:11:50 +00003573 always_goto_and_chase(
3574 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
sewardj2019a972011-03-07 16:04:07 +00003575 } else {
3576 assign(cond, s390_call_calculate_cond(r1));
3577 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3578 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3579
3580 }
3581 }
sewardj7ee97522011-05-09 21:45:04 +00003582 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00003583 s390_disasm(ENC2(XMNM, PCREL), S390_XMNM_BRC, r1, (Int)(Short)i2);
3584
3585 return "brc";
3586}
3587
florian55085f82012-11-21 00:36:55 +00003588static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003589s390_irgen_BRCL(UChar r1, UInt i2)
3590{
3591 IRTemp cond = newTemp(Ity_I32);
3592
3593 if (r1 == 0) {
3594 } else {
3595 if (r1 == 15) {
floriana64c2432011-07-16 02:11:50 +00003596 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1));
sewardj2019a972011-03-07 16:04:07 +00003597 } else {
3598 assign(cond, s390_call_calculate_cond(r1));
3599 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3600 guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1));
3601 }
3602 }
sewardj7ee97522011-05-09 21:45:04 +00003603 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00003604 s390_disasm(ENC2(XMNM, PCREL), S390_XMNM_BRCL, r1, i2);
3605
3606 return "brcl";
3607}
3608
florian55085f82012-11-21 00:36:55 +00003609static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003610s390_irgen_BRCT(UChar r1, UShort i2)
3611{
3612 put_gpr_w1(r1, binop(Iop_Sub32, get_gpr_w1(r1), mkU32(1)));
3613 if_condition_goto(binop(Iop_CmpNE32, get_gpr_w1(r1), mkU32(0)),
3614 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3615
3616 return "brct";
3617}
3618
florian55085f82012-11-21 00:36:55 +00003619static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003620s390_irgen_BRCTG(UChar r1, UShort i2)
3621{
3622 put_gpr_dw0(r1, binop(Iop_Sub64, get_gpr_dw0(r1), mkU64(1)));
3623 if_condition_goto(binop(Iop_CmpNE64, get_gpr_dw0(r1), mkU64(0)),
3624 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3625
3626 return "brctg";
3627}
3628
florian55085f82012-11-21 00:36:55 +00003629static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003630s390_irgen_BRXH(UChar r1, UChar r3, UShort i2)
3631{
3632 IRTemp value = newTemp(Ity_I32);
3633
3634 assign(value, get_gpr_w1(r3 | 1));
3635 put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
3636 if_condition_goto(binop(Iop_CmpLT32S, mkexpr(value), get_gpr_w1(r1)),
3637 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3638
3639 return "brxh";
3640}
3641
florian55085f82012-11-21 00:36:55 +00003642static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003643s390_irgen_BRXHG(UChar r1, UChar r3, UShort i2)
3644{
3645 IRTemp value = newTemp(Ity_I64);
3646
3647 assign(value, get_gpr_dw0(r3 | 1));
3648 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
3649 if_condition_goto(binop(Iop_CmpLT64S, mkexpr(value), get_gpr_dw0(r1)),
3650 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3651
3652 return "brxhg";
3653}
3654
florian55085f82012-11-21 00:36:55 +00003655static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003656s390_irgen_BRXLE(UChar r1, UChar r3, UShort i2)
3657{
3658 IRTemp value = newTemp(Ity_I32);
3659
3660 assign(value, get_gpr_w1(r3 | 1));
3661 put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
3662 if_condition_goto(binop(Iop_CmpLE32S, get_gpr_w1(r1), mkexpr(value)),
3663 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3664
3665 return "brxle";
3666}
3667
florian55085f82012-11-21 00:36:55 +00003668static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003669s390_irgen_BRXLG(UChar r1, UChar r3, UShort i2)
3670{
3671 IRTemp value = newTemp(Ity_I64);
3672
3673 assign(value, get_gpr_dw0(r3 | 1));
3674 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
3675 if_condition_goto(binop(Iop_CmpLE64S, get_gpr_dw0(r1), mkexpr(value)),
3676 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3677
3678 return "brxlg";
3679}
3680
florian55085f82012-11-21 00:36:55 +00003681static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003682s390_irgen_CR(UChar r1, UChar r2)
3683{
3684 IRTemp op1 = newTemp(Ity_I32);
3685 IRTemp op2 = newTemp(Ity_I32);
3686
3687 assign(op1, get_gpr_w1(r1));
3688 assign(op2, get_gpr_w1(r2));
3689 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3690
3691 return "cr";
3692}
3693
florian55085f82012-11-21 00:36:55 +00003694static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003695s390_irgen_CGR(UChar r1, UChar r2)
3696{
3697 IRTemp op1 = newTemp(Ity_I64);
3698 IRTemp op2 = newTemp(Ity_I64);
3699
3700 assign(op1, get_gpr_dw0(r1));
3701 assign(op2, get_gpr_dw0(r2));
3702 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3703
3704 return "cgr";
3705}
3706
florian55085f82012-11-21 00:36:55 +00003707static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003708s390_irgen_CGFR(UChar r1, UChar r2)
3709{
3710 IRTemp op1 = newTemp(Ity_I64);
3711 IRTemp op2 = newTemp(Ity_I64);
3712
3713 assign(op1, get_gpr_dw0(r1));
3714 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
3715 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3716
3717 return "cgfr";
3718}
3719
florian55085f82012-11-21 00:36:55 +00003720static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003721s390_irgen_C(UChar r1, IRTemp op2addr)
3722{
3723 IRTemp op1 = newTemp(Ity_I32);
3724 IRTemp op2 = newTemp(Ity_I32);
3725
3726 assign(op1, get_gpr_w1(r1));
3727 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3728 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3729
3730 return "c";
3731}
3732
florian55085f82012-11-21 00:36:55 +00003733static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003734s390_irgen_CY(UChar r1, IRTemp op2addr)
3735{
3736 IRTemp op1 = newTemp(Ity_I32);
3737 IRTemp op2 = newTemp(Ity_I32);
3738
3739 assign(op1, get_gpr_w1(r1));
3740 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3741 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3742
3743 return "cy";
3744}
3745
florian55085f82012-11-21 00:36:55 +00003746static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003747s390_irgen_CG(UChar r1, IRTemp op2addr)
3748{
3749 IRTemp op1 = newTemp(Ity_I64);
3750 IRTemp op2 = newTemp(Ity_I64);
3751
3752 assign(op1, get_gpr_dw0(r1));
3753 assign(op2, load(Ity_I64, mkexpr(op2addr)));
3754 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3755
3756 return "cg";
3757}
3758
florian55085f82012-11-21 00:36:55 +00003759static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003760s390_irgen_CGF(UChar r1, IRTemp op2addr)
3761{
3762 IRTemp op1 = newTemp(Ity_I64);
3763 IRTemp op2 = newTemp(Ity_I64);
3764
3765 assign(op1, get_gpr_dw0(r1));
3766 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
3767 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3768
3769 return "cgf";
3770}
3771
florian55085f82012-11-21 00:36:55 +00003772static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003773s390_irgen_CFI(UChar r1, UInt i2)
3774{
3775 IRTemp op1 = newTemp(Ity_I32);
3776 Int op2;
3777
3778 assign(op1, get_gpr_w1(r1));
3779 op2 = (Int)i2;
3780 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
3781 mkU32((UInt)op2)));
3782
3783 return "cfi";
3784}
3785
florian55085f82012-11-21 00:36:55 +00003786static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003787s390_irgen_CGFI(UChar r1, UInt i2)
3788{
3789 IRTemp op1 = newTemp(Ity_I64);
3790 Long op2;
3791
3792 assign(op1, get_gpr_dw0(r1));
3793 op2 = (Long)(Int)i2;
3794 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I64,
3795 mkU64((ULong)op2)));
3796
3797 return "cgfi";
3798}
3799
florian55085f82012-11-21 00:36:55 +00003800static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003801s390_irgen_CRL(UChar r1, UInt i2)
3802{
3803 IRTemp op1 = newTemp(Ity_I32);
3804 IRTemp op2 = newTemp(Ity_I32);
3805
3806 assign(op1, get_gpr_w1(r1));
3807 assign(op2, load(Ity_I32, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
3808 i2 << 1))));
3809 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3810
3811 return "crl";
3812}
3813
florian55085f82012-11-21 00:36:55 +00003814static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003815s390_irgen_CGRL(UChar r1, UInt i2)
3816{
3817 IRTemp op1 = newTemp(Ity_I64);
3818 IRTemp op2 = newTemp(Ity_I64);
3819
3820 assign(op1, get_gpr_dw0(r1));
3821 assign(op2, load(Ity_I64, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
3822 i2 << 1))));
3823 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3824
3825 return "cgrl";
3826}
3827
florian55085f82012-11-21 00:36:55 +00003828static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003829s390_irgen_CGFRL(UChar r1, UInt i2)
3830{
3831 IRTemp op1 = newTemp(Ity_I64);
3832 IRTemp op2 = newTemp(Ity_I64);
3833
3834 assign(op1, get_gpr_dw0(r1));
3835 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
3836 ((ULong)(Long)(Int)i2 << 1)))));
3837 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3838
3839 return "cgfrl";
3840}
3841
florian55085f82012-11-21 00:36:55 +00003842static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003843s390_irgen_CRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
3844{
3845 IRTemp op1 = newTemp(Ity_I32);
3846 IRTemp op2 = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00003847 IRTemp cond = newTemp(Ity_I32);
3848
3849 if (m3 == 0) {
3850 } else {
3851 if (m3 == 14) {
3852 always_goto(mkexpr(op4addr));
3853 } else {
3854 assign(op1, get_gpr_w1(r1));
3855 assign(op2, get_gpr_w1(r2));
florianff9613f2012-05-12 15:26:44 +00003856 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
3857 op1, op2));
florianf321da72012-07-21 20:32:57 +00003858 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond),
3859 mkU32(0)), mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00003860 }
3861 }
3862
3863 return "crb";
3864}
3865
florian55085f82012-11-21 00:36:55 +00003866static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003867s390_irgen_CGRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
3868{
3869 IRTemp op1 = newTemp(Ity_I64);
3870 IRTemp op2 = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00003871 IRTemp cond = newTemp(Ity_I32);
3872
3873 if (m3 == 0) {
3874 } else {
3875 if (m3 == 14) {
3876 always_goto(mkexpr(op4addr));
3877 } else {
3878 assign(op1, get_gpr_dw0(r1));
3879 assign(op2, get_gpr_dw0(r2));
florianff9613f2012-05-12 15:26:44 +00003880 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
3881 op1, op2));
florianf321da72012-07-21 20:32:57 +00003882 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond),
3883 mkU32(0)), mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00003884 }
3885 }
3886
3887 return "cgrb";
3888}
3889
florian55085f82012-11-21 00:36:55 +00003890static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003891s390_irgen_CRJ(UChar r1, UChar r2, UShort i4, UChar m3)
3892{
3893 IRTemp op1 = newTemp(Ity_I32);
3894 IRTemp op2 = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00003895 IRTemp cond = newTemp(Ity_I32);
3896
3897 if (m3 == 0) {
3898 } else {
3899 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00003900 always_goto_and_chase(
3901 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00003902 } else {
3903 assign(op1, get_gpr_w1(r1));
3904 assign(op2, get_gpr_w1(r2));
florianff9613f2012-05-12 15:26:44 +00003905 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
3906 op1, op2));
sewardj2019a972011-03-07 16:04:07 +00003907 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3908 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
3909
3910 }
3911 }
3912
3913 return "crj";
3914}
3915
florian55085f82012-11-21 00:36:55 +00003916static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003917s390_irgen_CGRJ(UChar r1, UChar r2, UShort i4, UChar m3)
3918{
3919 IRTemp op1 = newTemp(Ity_I64);
3920 IRTemp op2 = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00003921 IRTemp cond = newTemp(Ity_I32);
3922
3923 if (m3 == 0) {
3924 } else {
3925 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00003926 always_goto_and_chase(
3927 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00003928 } else {
3929 assign(op1, get_gpr_dw0(r1));
3930 assign(op2, get_gpr_dw0(r2));
florianff9613f2012-05-12 15:26:44 +00003931 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
3932 op1, op2));
sewardj2019a972011-03-07 16:04:07 +00003933 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3934 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
3935
3936 }
3937 }
3938
3939 return "cgrj";
3940}
3941
florian55085f82012-11-21 00:36:55 +00003942static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003943s390_irgen_CIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
3944{
3945 IRTemp op1 = newTemp(Ity_I32);
3946 Int op2;
sewardj2019a972011-03-07 16:04:07 +00003947 IRTemp cond = newTemp(Ity_I32);
3948
3949 if (m3 == 0) {
3950 } else {
3951 if (m3 == 14) {
3952 always_goto(mkexpr(op4addr));
3953 } else {
3954 assign(op1, get_gpr_w1(r1));
3955 op2 = (Int)(Char)i2;
florianff9613f2012-05-12 15:26:44 +00003956 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
3957 mktemp(Ity_I32, mkU32((UInt)op2))));
florianf321da72012-07-21 20:32:57 +00003958 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3959 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00003960 }
3961 }
3962
3963 return "cib";
3964}
3965
florian55085f82012-11-21 00:36:55 +00003966static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003967s390_irgen_CGIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
3968{
3969 IRTemp op1 = newTemp(Ity_I64);
3970 Long op2;
sewardj2019a972011-03-07 16:04:07 +00003971 IRTemp cond = newTemp(Ity_I32);
3972
3973 if (m3 == 0) {
3974 } else {
3975 if (m3 == 14) {
3976 always_goto(mkexpr(op4addr));
3977 } else {
3978 assign(op1, get_gpr_dw0(r1));
3979 op2 = (Long)(Char)i2;
florianff9613f2012-05-12 15:26:44 +00003980 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
3981 mktemp(Ity_I64, mkU64((ULong)op2))));
florianf321da72012-07-21 20:32:57 +00003982 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3983 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00003984 }
3985 }
3986
3987 return "cgib";
3988}
3989
florian55085f82012-11-21 00:36:55 +00003990static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003991s390_irgen_CIJ(UChar r1, UChar m3, UShort i4, UChar i2)
3992{
3993 IRTemp op1 = newTemp(Ity_I32);
3994 Int op2;
sewardj2019a972011-03-07 16:04:07 +00003995 IRTemp cond = newTemp(Ity_I32);
3996
3997 if (m3 == 0) {
3998 } else {
3999 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004000 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004001 } else {
4002 assign(op1, get_gpr_w1(r1));
4003 op2 = (Int)(Char)i2;
florianff9613f2012-05-12 15:26:44 +00004004 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
4005 mktemp(Ity_I32, mkU32((UInt)op2))));
sewardj2019a972011-03-07 16:04:07 +00004006 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4007 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4008
4009 }
4010 }
4011
4012 return "cij";
4013}
4014
florian55085f82012-11-21 00:36:55 +00004015static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004016s390_irgen_CGIJ(UChar r1, UChar m3, UShort i4, UChar i2)
4017{
4018 IRTemp op1 = newTemp(Ity_I64);
4019 Long op2;
sewardj2019a972011-03-07 16:04:07 +00004020 IRTemp cond = newTemp(Ity_I32);
4021
4022 if (m3 == 0) {
4023 } else {
4024 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004025 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004026 } else {
4027 assign(op1, get_gpr_dw0(r1));
4028 op2 = (Long)(Char)i2;
florianff9613f2012-05-12 15:26:44 +00004029 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
4030 mktemp(Ity_I64, mkU64((ULong)op2))));
sewardj2019a972011-03-07 16:04:07 +00004031 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4032 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4033
4034 }
4035 }
4036
4037 return "cgij";
4038}
4039
florian55085f82012-11-21 00:36:55 +00004040static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004041s390_irgen_CH(UChar r1, IRTemp op2addr)
4042{
4043 IRTemp op1 = newTemp(Ity_I32);
4044 IRTemp op2 = newTemp(Ity_I32);
4045
4046 assign(op1, get_gpr_w1(r1));
4047 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
4048 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4049
4050 return "ch";
4051}
4052
florian55085f82012-11-21 00:36:55 +00004053static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004054s390_irgen_CHY(UChar r1, IRTemp op2addr)
4055{
4056 IRTemp op1 = newTemp(Ity_I32);
4057 IRTemp op2 = newTemp(Ity_I32);
4058
4059 assign(op1, get_gpr_w1(r1));
4060 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
4061 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4062
4063 return "chy";
4064}
4065
florian55085f82012-11-21 00:36:55 +00004066static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004067s390_irgen_CGH(UChar r1, IRTemp op2addr)
4068{
4069 IRTemp op1 = newTemp(Ity_I64);
4070 IRTemp op2 = newTemp(Ity_I64);
4071
4072 assign(op1, get_gpr_dw0(r1));
4073 assign(op2, unop(Iop_16Sto64, load(Ity_I16, mkexpr(op2addr))));
4074 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4075
4076 return "cgh";
4077}
4078
florian55085f82012-11-21 00:36:55 +00004079static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004080s390_irgen_CHI(UChar r1, UShort i2)
4081{
4082 IRTemp op1 = newTemp(Ity_I32);
4083 Int op2;
4084
4085 assign(op1, get_gpr_w1(r1));
4086 op2 = (Int)(Short)i2;
4087 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
4088 mkU32((UInt)op2)));
4089
4090 return "chi";
4091}
4092
florian55085f82012-11-21 00:36:55 +00004093static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004094s390_irgen_CGHI(UChar r1, UShort i2)
4095{
4096 IRTemp op1 = newTemp(Ity_I64);
4097 Long op2;
4098
4099 assign(op1, get_gpr_dw0(r1));
4100 op2 = (Long)(Short)i2;
4101 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I64,
4102 mkU64((ULong)op2)));
4103
4104 return "cghi";
4105}
4106
florian55085f82012-11-21 00:36:55 +00004107static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004108s390_irgen_CHHSI(UShort i2, IRTemp op1addr)
4109{
4110 IRTemp op1 = newTemp(Ity_I16);
4111 Short op2;
4112
4113 assign(op1, load(Ity_I16, mkexpr(op1addr)));
4114 op2 = (Short)i2;
4115 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I16,
4116 mkU16((UShort)op2)));
4117
4118 return "chhsi";
4119}
4120
florian55085f82012-11-21 00:36:55 +00004121static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004122s390_irgen_CHSI(UShort i2, IRTemp op1addr)
4123{
4124 IRTemp op1 = newTemp(Ity_I32);
4125 Int op2;
4126
4127 assign(op1, load(Ity_I32, mkexpr(op1addr)));
4128 op2 = (Int)(Short)i2;
4129 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
4130 mkU32((UInt)op2)));
4131
4132 return "chsi";
4133}
4134
florian55085f82012-11-21 00:36:55 +00004135static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004136s390_irgen_CGHSI(UShort i2, IRTemp op1addr)
4137{
4138 IRTemp op1 = newTemp(Ity_I64);
4139 Long op2;
4140
4141 assign(op1, load(Ity_I64, mkexpr(op1addr)));
4142 op2 = (Long)(Short)i2;
4143 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I64,
4144 mkU64((ULong)op2)));
4145
4146 return "cghsi";
4147}
4148
florian55085f82012-11-21 00:36:55 +00004149static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004150s390_irgen_CHRL(UChar r1, UInt i2)
4151{
4152 IRTemp op1 = newTemp(Ity_I32);
4153 IRTemp op2 = newTemp(Ity_I32);
4154
4155 assign(op1, get_gpr_w1(r1));
4156 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
4157 ((ULong)(Long)(Int)i2 << 1)))));
4158 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4159
4160 return "chrl";
4161}
4162
florian55085f82012-11-21 00:36:55 +00004163static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004164s390_irgen_CGHRL(UChar r1, UInt i2)
4165{
4166 IRTemp op1 = newTemp(Ity_I64);
4167 IRTemp op2 = newTemp(Ity_I64);
4168
4169 assign(op1, get_gpr_dw0(r1));
4170 assign(op2, unop(Iop_16Sto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
4171 ((ULong)(Long)(Int)i2 << 1)))));
4172 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4173
4174 return "cghrl";
4175}
4176
florian55085f82012-11-21 00:36:55 +00004177static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004178s390_irgen_CHHR(UChar r1, UChar r2)
4179{
4180 IRTemp op1 = newTemp(Ity_I32);
4181 IRTemp op2 = newTemp(Ity_I32);
4182
4183 assign(op1, get_gpr_w0(r1));
4184 assign(op2, get_gpr_w0(r2));
4185 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4186
4187 return "chhr";
4188}
4189
florian55085f82012-11-21 00:36:55 +00004190static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004191s390_irgen_CHLR(UChar r1, UChar r2)
4192{
4193 IRTemp op1 = newTemp(Ity_I32);
4194 IRTemp op2 = newTemp(Ity_I32);
4195
4196 assign(op1, get_gpr_w0(r1));
4197 assign(op2, get_gpr_w1(r2));
4198 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4199
4200 return "chlr";
4201}
4202
florian55085f82012-11-21 00:36:55 +00004203static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004204s390_irgen_CHF(UChar r1, IRTemp op2addr)
4205{
4206 IRTemp op1 = newTemp(Ity_I32);
4207 IRTemp op2 = newTemp(Ity_I32);
4208
4209 assign(op1, get_gpr_w0(r1));
4210 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4211 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4212
4213 return "chf";
4214}
4215
florian55085f82012-11-21 00:36:55 +00004216static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004217s390_irgen_CIH(UChar r1, UInt i2)
4218{
4219 IRTemp op1 = newTemp(Ity_I32);
4220 Int op2;
4221
4222 assign(op1, get_gpr_w0(r1));
4223 op2 = (Int)i2;
4224 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
4225 mkU32((UInt)op2)));
4226
4227 return "cih";
4228}
4229
florian55085f82012-11-21 00:36:55 +00004230static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004231s390_irgen_CLR(UChar r1, UChar r2)
4232{
4233 IRTemp op1 = newTemp(Ity_I32);
4234 IRTemp op2 = newTemp(Ity_I32);
4235
4236 assign(op1, get_gpr_w1(r1));
4237 assign(op2, get_gpr_w1(r2));
4238 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4239
4240 return "clr";
4241}
4242
florian55085f82012-11-21 00:36:55 +00004243static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004244s390_irgen_CLGR(UChar r1, UChar r2)
4245{
4246 IRTemp op1 = newTemp(Ity_I64);
4247 IRTemp op2 = newTemp(Ity_I64);
4248
4249 assign(op1, get_gpr_dw0(r1));
4250 assign(op2, get_gpr_dw0(r2));
4251 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4252
4253 return "clgr";
4254}
4255
florian55085f82012-11-21 00:36:55 +00004256static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004257s390_irgen_CLGFR(UChar r1, UChar r2)
4258{
4259 IRTemp op1 = newTemp(Ity_I64);
4260 IRTemp op2 = newTemp(Ity_I64);
4261
4262 assign(op1, get_gpr_dw0(r1));
4263 assign(op2, unop(Iop_32Uto64, get_gpr_w1(r2)));
4264 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4265
4266 return "clgfr";
4267}
4268
florian55085f82012-11-21 00:36:55 +00004269static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004270s390_irgen_CL(UChar r1, IRTemp op2addr)
4271{
4272 IRTemp op1 = newTemp(Ity_I32);
4273 IRTemp op2 = newTemp(Ity_I32);
4274
4275 assign(op1, get_gpr_w1(r1));
4276 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4277 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4278
4279 return "cl";
4280}
4281
florian55085f82012-11-21 00:36:55 +00004282static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004283s390_irgen_CLY(UChar r1, IRTemp op2addr)
4284{
4285 IRTemp op1 = newTemp(Ity_I32);
4286 IRTemp op2 = newTemp(Ity_I32);
4287
4288 assign(op1, get_gpr_w1(r1));
4289 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4290 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4291
4292 return "cly";
4293}
4294
florian55085f82012-11-21 00:36:55 +00004295static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004296s390_irgen_CLG(UChar r1, IRTemp op2addr)
4297{
4298 IRTemp op1 = newTemp(Ity_I64);
4299 IRTemp op2 = newTemp(Ity_I64);
4300
4301 assign(op1, get_gpr_dw0(r1));
4302 assign(op2, load(Ity_I64, mkexpr(op2addr)));
4303 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4304
4305 return "clg";
4306}
4307
florian55085f82012-11-21 00:36:55 +00004308static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004309s390_irgen_CLGF(UChar r1, IRTemp op2addr)
4310{
4311 IRTemp op1 = newTemp(Ity_I64);
4312 IRTemp op2 = newTemp(Ity_I64);
4313
4314 assign(op1, get_gpr_dw0(r1));
4315 assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
4316 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4317
4318 return "clgf";
4319}
4320
florian55085f82012-11-21 00:36:55 +00004321static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004322s390_irgen_CLFI(UChar r1, UInt i2)
4323{
4324 IRTemp op1 = newTemp(Ity_I32);
4325 UInt op2;
4326
4327 assign(op1, get_gpr_w1(r1));
4328 op2 = i2;
4329 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I32,
4330 mkU32(op2)));
4331
4332 return "clfi";
4333}
4334
florian55085f82012-11-21 00:36:55 +00004335static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004336s390_irgen_CLGFI(UChar r1, UInt i2)
4337{
4338 IRTemp op1 = newTemp(Ity_I64);
4339 ULong op2;
4340
4341 assign(op1, get_gpr_dw0(r1));
4342 op2 = (ULong)i2;
4343 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I64,
4344 mkU64(op2)));
4345
4346 return "clgfi";
4347}
4348
florian55085f82012-11-21 00:36:55 +00004349static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004350s390_irgen_CLI(UChar i2, IRTemp op1addr)
4351{
4352 IRTemp op1 = newTemp(Ity_I8);
4353 UChar op2;
4354
4355 assign(op1, load(Ity_I8, mkexpr(op1addr)));
4356 op2 = i2;
4357 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I8,
4358 mkU8(op2)));
4359
4360 return "cli";
4361}
4362
florian55085f82012-11-21 00:36:55 +00004363static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004364s390_irgen_CLIY(UChar i2, IRTemp op1addr)
4365{
4366 IRTemp op1 = newTemp(Ity_I8);
4367 UChar op2;
4368
4369 assign(op1, load(Ity_I8, mkexpr(op1addr)));
4370 op2 = i2;
4371 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I8,
4372 mkU8(op2)));
4373
4374 return "cliy";
4375}
4376
florian55085f82012-11-21 00:36:55 +00004377static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004378s390_irgen_CLFHSI(UShort i2, IRTemp op1addr)
4379{
4380 IRTemp op1 = newTemp(Ity_I32);
4381 UInt op2;
4382
4383 assign(op1, load(Ity_I32, mkexpr(op1addr)));
4384 op2 = (UInt)i2;
4385 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I32,
4386 mkU32(op2)));
4387
4388 return "clfhsi";
4389}
4390
florian55085f82012-11-21 00:36:55 +00004391static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004392s390_irgen_CLGHSI(UShort i2, IRTemp op1addr)
4393{
4394 IRTemp op1 = newTemp(Ity_I64);
4395 ULong op2;
4396
4397 assign(op1, load(Ity_I64, mkexpr(op1addr)));
4398 op2 = (ULong)i2;
4399 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I64,
4400 mkU64(op2)));
4401
4402 return "clghsi";
4403}
4404
florian55085f82012-11-21 00:36:55 +00004405static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004406s390_irgen_CLHHSI(UShort i2, IRTemp op1addr)
4407{
4408 IRTemp op1 = newTemp(Ity_I16);
4409 UShort op2;
4410
4411 assign(op1, load(Ity_I16, mkexpr(op1addr)));
4412 op2 = i2;
4413 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I16,
4414 mkU16(op2)));
4415
4416 return "clhhsi";
4417}
4418
florian55085f82012-11-21 00:36:55 +00004419static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004420s390_irgen_CLRL(UChar r1, UInt i2)
4421{
4422 IRTemp op1 = newTemp(Ity_I32);
4423 IRTemp op2 = newTemp(Ity_I32);
4424
4425 assign(op1, get_gpr_w1(r1));
4426 assign(op2, load(Ity_I32, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
4427 i2 << 1))));
4428 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4429
4430 return "clrl";
4431}
4432
florian55085f82012-11-21 00:36:55 +00004433static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004434s390_irgen_CLGRL(UChar r1, UInt i2)
4435{
4436 IRTemp op1 = newTemp(Ity_I64);
4437 IRTemp op2 = newTemp(Ity_I64);
4438
4439 assign(op1, get_gpr_dw0(r1));
4440 assign(op2, load(Ity_I64, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
4441 i2 << 1))));
4442 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4443
4444 return "clgrl";
4445}
4446
florian55085f82012-11-21 00:36:55 +00004447static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004448s390_irgen_CLGFRL(UChar r1, UInt i2)
4449{
4450 IRTemp op1 = newTemp(Ity_I64);
4451 IRTemp op2 = newTemp(Ity_I64);
4452
4453 assign(op1, get_gpr_dw0(r1));
4454 assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
4455 ((ULong)(Long)(Int)i2 << 1)))));
4456 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4457
4458 return "clgfrl";
4459}
4460
florian55085f82012-11-21 00:36:55 +00004461static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004462s390_irgen_CLHRL(UChar r1, UInt i2)
4463{
4464 IRTemp op1 = newTemp(Ity_I32);
4465 IRTemp op2 = newTemp(Ity_I32);
4466
4467 assign(op1, get_gpr_w1(r1));
4468 assign(op2, unop(Iop_16Uto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
4469 ((ULong)(Long)(Int)i2 << 1)))));
4470 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4471
4472 return "clhrl";
4473}
4474
florian55085f82012-11-21 00:36:55 +00004475static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004476s390_irgen_CLGHRL(UChar r1, UInt i2)
4477{
4478 IRTemp op1 = newTemp(Ity_I64);
4479 IRTemp op2 = newTemp(Ity_I64);
4480
4481 assign(op1, get_gpr_dw0(r1));
4482 assign(op2, unop(Iop_16Uto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
4483 ((ULong)(Long)(Int)i2 << 1)))));
4484 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4485
4486 return "clghrl";
4487}
4488
florian55085f82012-11-21 00:36:55 +00004489static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004490s390_irgen_CLRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
4491{
4492 IRTemp op1 = newTemp(Ity_I32);
4493 IRTemp op2 = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00004494 IRTemp cond = newTemp(Ity_I32);
4495
4496 if (m3 == 0) {
4497 } else {
4498 if (m3 == 14) {
4499 always_goto(mkexpr(op4addr));
4500 } else {
4501 assign(op1, get_gpr_w1(r1));
4502 assign(op2, get_gpr_w1(r2));
florianff9613f2012-05-12 15:26:44 +00004503 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4504 op1, op2));
florianf321da72012-07-21 20:32:57 +00004505 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4506 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004507 }
4508 }
4509
4510 return "clrb";
4511}
4512
florian55085f82012-11-21 00:36:55 +00004513static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004514s390_irgen_CLGRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
4515{
4516 IRTemp op1 = newTemp(Ity_I64);
4517 IRTemp op2 = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00004518 IRTemp cond = newTemp(Ity_I32);
4519
4520 if (m3 == 0) {
4521 } else {
4522 if (m3 == 14) {
4523 always_goto(mkexpr(op4addr));
4524 } else {
4525 assign(op1, get_gpr_dw0(r1));
4526 assign(op2, get_gpr_dw0(r2));
florianff9613f2012-05-12 15:26:44 +00004527 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4528 op1, op2));
florianf321da72012-07-21 20:32:57 +00004529 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4530 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004531 }
4532 }
4533
4534 return "clgrb";
4535}
4536
florian55085f82012-11-21 00:36:55 +00004537static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004538s390_irgen_CLRJ(UChar r1, UChar r2, UShort i4, UChar m3)
4539{
4540 IRTemp op1 = newTemp(Ity_I32);
4541 IRTemp op2 = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00004542 IRTemp cond = newTemp(Ity_I32);
4543
4544 if (m3 == 0) {
4545 } else {
4546 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004547 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004548 } else {
4549 assign(op1, get_gpr_w1(r1));
4550 assign(op2, get_gpr_w1(r2));
florianff9613f2012-05-12 15:26:44 +00004551 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4552 op1, op2));
sewardj2019a972011-03-07 16:04:07 +00004553 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4554 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4555
4556 }
4557 }
4558
4559 return "clrj";
4560}
4561
florian55085f82012-11-21 00:36:55 +00004562static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004563s390_irgen_CLGRJ(UChar r1, UChar r2, UShort i4, UChar m3)
4564{
4565 IRTemp op1 = newTemp(Ity_I64);
4566 IRTemp op2 = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00004567 IRTemp cond = newTemp(Ity_I32);
4568
4569 if (m3 == 0) {
4570 } else {
4571 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004572 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004573 } else {
4574 assign(op1, get_gpr_dw0(r1));
4575 assign(op2, get_gpr_dw0(r2));
florianff9613f2012-05-12 15:26:44 +00004576 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4577 op1, op2));
sewardj2019a972011-03-07 16:04:07 +00004578 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4579 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4580
4581 }
4582 }
4583
4584 return "clgrj";
4585}
4586
florian55085f82012-11-21 00:36:55 +00004587static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004588s390_irgen_CLIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
4589{
4590 IRTemp op1 = newTemp(Ity_I32);
4591 UInt op2;
sewardj2019a972011-03-07 16:04:07 +00004592 IRTemp cond = newTemp(Ity_I32);
4593
4594 if (m3 == 0) {
4595 } else {
4596 if (m3 == 14) {
4597 always_goto(mkexpr(op4addr));
4598 } else {
4599 assign(op1, get_gpr_w1(r1));
4600 op2 = (UInt)i2;
florianff9613f2012-05-12 15:26:44 +00004601 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4602 mktemp(Ity_I32, mkU32(op2))));
florianf321da72012-07-21 20:32:57 +00004603 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4604 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004605 }
4606 }
4607
4608 return "clib";
4609}
4610
florian55085f82012-11-21 00:36:55 +00004611static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004612s390_irgen_CLGIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
4613{
4614 IRTemp op1 = newTemp(Ity_I64);
4615 ULong op2;
sewardj2019a972011-03-07 16:04:07 +00004616 IRTemp cond = newTemp(Ity_I32);
4617
4618 if (m3 == 0) {
4619 } else {
4620 if (m3 == 14) {
4621 always_goto(mkexpr(op4addr));
4622 } else {
4623 assign(op1, get_gpr_dw0(r1));
4624 op2 = (ULong)i2;
florianff9613f2012-05-12 15:26:44 +00004625 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4626 mktemp(Ity_I64, mkU64(op2))));
florianf321da72012-07-21 20:32:57 +00004627 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4628 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004629 }
4630 }
4631
4632 return "clgib";
4633}
4634
florian55085f82012-11-21 00:36:55 +00004635static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004636s390_irgen_CLIJ(UChar r1, UChar m3, UShort i4, UChar i2)
4637{
4638 IRTemp op1 = newTemp(Ity_I32);
4639 UInt op2;
sewardj2019a972011-03-07 16:04:07 +00004640 IRTemp cond = newTemp(Ity_I32);
4641
4642 if (m3 == 0) {
4643 } else {
4644 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004645 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004646 } else {
4647 assign(op1, get_gpr_w1(r1));
4648 op2 = (UInt)i2;
florianff9613f2012-05-12 15:26:44 +00004649 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4650 mktemp(Ity_I32, mkU32(op2))));
sewardj2019a972011-03-07 16:04:07 +00004651 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4652 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4653
4654 }
4655 }
4656
4657 return "clij";
4658}
4659
florian55085f82012-11-21 00:36:55 +00004660static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004661s390_irgen_CLGIJ(UChar r1, UChar m3, UShort i4, UChar i2)
4662{
4663 IRTemp op1 = newTemp(Ity_I64);
4664 ULong op2;
sewardj2019a972011-03-07 16:04:07 +00004665 IRTemp cond = newTemp(Ity_I32);
4666
4667 if (m3 == 0) {
4668 } else {
4669 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004670 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004671 } else {
4672 assign(op1, get_gpr_dw0(r1));
4673 op2 = (ULong)i2;
florianff9613f2012-05-12 15:26:44 +00004674 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4675 mktemp(Ity_I64, mkU64(op2))));
sewardj2019a972011-03-07 16:04:07 +00004676 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4677 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4678
4679 }
4680 }
4681
4682 return "clgij";
4683}
4684
florian55085f82012-11-21 00:36:55 +00004685static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004686s390_irgen_CLM(UChar r1, UChar r3, IRTemp op2addr)
4687{
4688 IRTemp op1 = newTemp(Ity_I32);
4689 IRTemp op2 = newTemp(Ity_I32);
4690 IRTemp b0 = newTemp(Ity_I32);
4691 IRTemp b1 = newTemp(Ity_I32);
4692 IRTemp b2 = newTemp(Ity_I32);
4693 IRTemp b3 = newTemp(Ity_I32);
4694 IRTemp c0 = newTemp(Ity_I32);
4695 IRTemp c1 = newTemp(Ity_I32);
4696 IRTemp c2 = newTemp(Ity_I32);
4697 IRTemp c3 = newTemp(Ity_I32);
4698 UChar n;
4699
4700 n = 0;
4701 if ((r3 & 8) != 0) {
4702 assign(b0, unop(Iop_8Uto32, get_gpr_b4(r1)));
4703 assign(c0, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
4704 n = n + 1;
4705 } else {
4706 assign(b0, mkU32(0));
4707 assign(c0, mkU32(0));
4708 }
4709 if ((r3 & 4) != 0) {
4710 assign(b1, unop(Iop_8Uto32, get_gpr_b5(r1)));
4711 assign(c1, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4712 mkU64(n)))));
4713 n = n + 1;
4714 } else {
4715 assign(b1, mkU32(0));
4716 assign(c1, mkU32(0));
4717 }
4718 if ((r3 & 2) != 0) {
4719 assign(b2, unop(Iop_8Uto32, get_gpr_b6(r1)));
4720 assign(c2, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4721 mkU64(n)))));
4722 n = n + 1;
4723 } else {
4724 assign(b2, mkU32(0));
4725 assign(c2, mkU32(0));
4726 }
4727 if ((r3 & 1) != 0) {
4728 assign(b3, unop(Iop_8Uto32, get_gpr_b7(r1)));
4729 assign(c3, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4730 mkU64(n)))));
4731 n = n + 1;
4732 } else {
4733 assign(b3, mkU32(0));
4734 assign(c3, mkU32(0));
4735 }
4736 assign(op1, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4737 mkexpr(b0), mkU8(24)), binop(Iop_Shl32, mkexpr(b1), mkU8(16))),
4738 binop(Iop_Shl32, mkexpr(b2), mkU8(8))), mkexpr(b3)));
4739 assign(op2, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4740 mkexpr(c0), mkU8(24)), binop(Iop_Shl32, mkexpr(c1), mkU8(16))),
4741 binop(Iop_Shl32, mkexpr(c2), mkU8(8))), mkexpr(c3)));
4742 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4743
4744 return "clm";
4745}
4746
florian55085f82012-11-21 00:36:55 +00004747static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004748s390_irgen_CLMY(UChar r1, UChar r3, IRTemp op2addr)
4749{
4750 IRTemp op1 = newTemp(Ity_I32);
4751 IRTemp op2 = newTemp(Ity_I32);
4752 IRTemp b0 = newTemp(Ity_I32);
4753 IRTemp b1 = newTemp(Ity_I32);
4754 IRTemp b2 = newTemp(Ity_I32);
4755 IRTemp b3 = newTemp(Ity_I32);
4756 IRTemp c0 = newTemp(Ity_I32);
4757 IRTemp c1 = newTemp(Ity_I32);
4758 IRTemp c2 = newTemp(Ity_I32);
4759 IRTemp c3 = newTemp(Ity_I32);
4760 UChar n;
4761
4762 n = 0;
4763 if ((r3 & 8) != 0) {
4764 assign(b0, unop(Iop_8Uto32, get_gpr_b4(r1)));
4765 assign(c0, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
4766 n = n + 1;
4767 } else {
4768 assign(b0, mkU32(0));
4769 assign(c0, mkU32(0));
4770 }
4771 if ((r3 & 4) != 0) {
4772 assign(b1, unop(Iop_8Uto32, get_gpr_b5(r1)));
4773 assign(c1, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4774 mkU64(n)))));
4775 n = n + 1;
4776 } else {
4777 assign(b1, mkU32(0));
4778 assign(c1, mkU32(0));
4779 }
4780 if ((r3 & 2) != 0) {
4781 assign(b2, unop(Iop_8Uto32, get_gpr_b6(r1)));
4782 assign(c2, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4783 mkU64(n)))));
4784 n = n + 1;
4785 } else {
4786 assign(b2, mkU32(0));
4787 assign(c2, mkU32(0));
4788 }
4789 if ((r3 & 1) != 0) {
4790 assign(b3, unop(Iop_8Uto32, get_gpr_b7(r1)));
4791 assign(c3, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4792 mkU64(n)))));
4793 n = n + 1;
4794 } else {
4795 assign(b3, mkU32(0));
4796 assign(c3, mkU32(0));
4797 }
4798 assign(op1, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4799 mkexpr(b0), mkU8(24)), binop(Iop_Shl32, mkexpr(b1), mkU8(16))),
4800 binop(Iop_Shl32, mkexpr(b2), mkU8(8))), mkexpr(b3)));
4801 assign(op2, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4802 mkexpr(c0), mkU8(24)), binop(Iop_Shl32, mkexpr(c1), mkU8(16))),
4803 binop(Iop_Shl32, mkexpr(c2), mkU8(8))), mkexpr(c3)));
4804 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4805
4806 return "clmy";
4807}
4808
florian55085f82012-11-21 00:36:55 +00004809static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004810s390_irgen_CLMH(UChar r1, UChar r3, IRTemp op2addr)
4811{
4812 IRTemp op1 = newTemp(Ity_I32);
4813 IRTemp op2 = newTemp(Ity_I32);
4814 IRTemp b0 = newTemp(Ity_I32);
4815 IRTemp b1 = newTemp(Ity_I32);
4816 IRTemp b2 = newTemp(Ity_I32);
4817 IRTemp b3 = newTemp(Ity_I32);
4818 IRTemp c0 = newTemp(Ity_I32);
4819 IRTemp c1 = newTemp(Ity_I32);
4820 IRTemp c2 = newTemp(Ity_I32);
4821 IRTemp c3 = newTemp(Ity_I32);
4822 UChar n;
4823
4824 n = 0;
4825 if ((r3 & 8) != 0) {
4826 assign(b0, unop(Iop_8Uto32, get_gpr_b0(r1)));
4827 assign(c0, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
4828 n = n + 1;
4829 } else {
4830 assign(b0, mkU32(0));
4831 assign(c0, mkU32(0));
4832 }
4833 if ((r3 & 4) != 0) {
4834 assign(b1, unop(Iop_8Uto32, get_gpr_b1(r1)));
4835 assign(c1, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4836 mkU64(n)))));
4837 n = n + 1;
4838 } else {
4839 assign(b1, mkU32(0));
4840 assign(c1, mkU32(0));
4841 }
4842 if ((r3 & 2) != 0) {
4843 assign(b2, unop(Iop_8Uto32, get_gpr_b2(r1)));
4844 assign(c2, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4845 mkU64(n)))));
4846 n = n + 1;
4847 } else {
4848 assign(b2, mkU32(0));
4849 assign(c2, mkU32(0));
4850 }
4851 if ((r3 & 1) != 0) {
4852 assign(b3, unop(Iop_8Uto32, get_gpr_b3(r1)));
4853 assign(c3, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4854 mkU64(n)))));
4855 n = n + 1;
4856 } else {
4857 assign(b3, mkU32(0));
4858 assign(c3, mkU32(0));
4859 }
4860 assign(op1, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4861 mkexpr(b0), mkU8(24)), binop(Iop_Shl32, mkexpr(b1), mkU8(16))),
4862 binop(Iop_Shl32, mkexpr(b2), mkU8(8))), mkexpr(b3)));
4863 assign(op2, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4864 mkexpr(c0), mkU8(24)), binop(Iop_Shl32, mkexpr(c1), mkU8(16))),
4865 binop(Iop_Shl32, mkexpr(c2), mkU8(8))), mkexpr(c3)));
4866 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4867
4868 return "clmh";
4869}
4870
florian55085f82012-11-21 00:36:55 +00004871static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004872s390_irgen_CLHHR(UChar r1, UChar r2)
4873{
4874 IRTemp op1 = newTemp(Ity_I32);
4875 IRTemp op2 = newTemp(Ity_I32);
4876
4877 assign(op1, get_gpr_w0(r1));
4878 assign(op2, get_gpr_w0(r2));
4879 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4880
4881 return "clhhr";
4882}
4883
florian55085f82012-11-21 00:36:55 +00004884static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004885s390_irgen_CLHLR(UChar r1, UChar r2)
4886{
4887 IRTemp op1 = newTemp(Ity_I32);
4888 IRTemp op2 = newTemp(Ity_I32);
4889
4890 assign(op1, get_gpr_w0(r1));
4891 assign(op2, get_gpr_w1(r2));
4892 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4893
4894 return "clhlr";
4895}
4896
florian55085f82012-11-21 00:36:55 +00004897static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004898s390_irgen_CLHF(UChar r1, IRTemp op2addr)
4899{
4900 IRTemp op1 = newTemp(Ity_I32);
4901 IRTemp op2 = newTemp(Ity_I32);
4902
4903 assign(op1, get_gpr_w0(r1));
4904 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4905 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4906
4907 return "clhf";
4908}
4909
florian55085f82012-11-21 00:36:55 +00004910static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004911s390_irgen_CLIH(UChar r1, UInt i2)
4912{
4913 IRTemp op1 = newTemp(Ity_I32);
4914 UInt op2;
4915
4916 assign(op1, get_gpr_w0(r1));
4917 op2 = i2;
4918 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I32,
4919 mkU32(op2)));
4920
4921 return "clih";
4922}
4923
florian55085f82012-11-21 00:36:55 +00004924static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004925s390_irgen_CPYA(UChar r1, UChar r2)
4926{
4927 put_ar_w0(r1, get_ar_w0(r2));
sewardj7ee97522011-05-09 21:45:04 +00004928 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00004929 s390_disasm(ENC3(MNM, AR, AR), "cpya", r1, r2);
4930
4931 return "cpya";
4932}
4933
florian55085f82012-11-21 00:36:55 +00004934static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004935s390_irgen_XR(UChar r1, UChar r2)
4936{
4937 IRTemp op1 = newTemp(Ity_I32);
4938 IRTemp op2 = newTemp(Ity_I32);
4939 IRTemp result = newTemp(Ity_I32);
4940
4941 if (r1 == r2) {
4942 assign(result, mkU32(0));
4943 } else {
4944 assign(op1, get_gpr_w1(r1));
4945 assign(op2, get_gpr_w1(r2));
4946 assign(result, binop(Iop_Xor32, mkexpr(op1), mkexpr(op2)));
4947 }
4948 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4949 put_gpr_w1(r1, mkexpr(result));
4950
4951 return "xr";
4952}
4953
florian55085f82012-11-21 00:36:55 +00004954static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004955s390_irgen_XGR(UChar r1, UChar r2)
4956{
4957 IRTemp op1 = newTemp(Ity_I64);
4958 IRTemp op2 = newTemp(Ity_I64);
4959 IRTemp result = newTemp(Ity_I64);
4960
4961 if (r1 == r2) {
4962 assign(result, mkU64(0));
4963 } else {
4964 assign(op1, get_gpr_dw0(r1));
4965 assign(op2, get_gpr_dw0(r2));
4966 assign(result, binop(Iop_Xor64, mkexpr(op1), mkexpr(op2)));
4967 }
4968 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4969 put_gpr_dw0(r1, mkexpr(result));
4970
4971 return "xgr";
4972}
4973
florian55085f82012-11-21 00:36:55 +00004974static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004975s390_irgen_XRK(UChar r3, UChar r1, UChar r2)
4976{
4977 IRTemp op2 = newTemp(Ity_I32);
4978 IRTemp op3 = newTemp(Ity_I32);
4979 IRTemp result = newTemp(Ity_I32);
4980
4981 assign(op2, get_gpr_w1(r2));
4982 assign(op3, get_gpr_w1(r3));
4983 assign(result, binop(Iop_Xor32, mkexpr(op2), mkexpr(op3)));
4984 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4985 put_gpr_w1(r1, mkexpr(result));
4986
4987 return "xrk";
4988}
4989
florian55085f82012-11-21 00:36:55 +00004990static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004991s390_irgen_XGRK(UChar r3, UChar r1, UChar r2)
4992{
4993 IRTemp op2 = newTemp(Ity_I64);
4994 IRTemp op3 = newTemp(Ity_I64);
4995 IRTemp result = newTemp(Ity_I64);
4996
4997 assign(op2, get_gpr_dw0(r2));
4998 assign(op3, get_gpr_dw0(r3));
4999 assign(result, binop(Iop_Xor64, mkexpr(op2), mkexpr(op3)));
5000 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5001 put_gpr_dw0(r1, mkexpr(result));
5002
5003 return "xgrk";
5004}
5005
florian55085f82012-11-21 00:36:55 +00005006static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005007s390_irgen_X(UChar r1, IRTemp op2addr)
5008{
5009 IRTemp op1 = newTemp(Ity_I32);
5010 IRTemp op2 = newTemp(Ity_I32);
5011 IRTemp result = newTemp(Ity_I32);
5012
5013 assign(op1, get_gpr_w1(r1));
5014 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5015 assign(result, binop(Iop_Xor32, mkexpr(op1), mkexpr(op2)));
5016 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5017 put_gpr_w1(r1, mkexpr(result));
5018
5019 return "x";
5020}
5021
florian55085f82012-11-21 00:36:55 +00005022static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005023s390_irgen_XY(UChar r1, IRTemp op2addr)
5024{
5025 IRTemp op1 = newTemp(Ity_I32);
5026 IRTemp op2 = newTemp(Ity_I32);
5027 IRTemp result = newTemp(Ity_I32);
5028
5029 assign(op1, get_gpr_w1(r1));
5030 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5031 assign(result, binop(Iop_Xor32, mkexpr(op1), mkexpr(op2)));
5032 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5033 put_gpr_w1(r1, mkexpr(result));
5034
5035 return "xy";
5036}
5037
florian55085f82012-11-21 00:36:55 +00005038static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005039s390_irgen_XG(UChar r1, IRTemp op2addr)
5040{
5041 IRTemp op1 = newTemp(Ity_I64);
5042 IRTemp op2 = newTemp(Ity_I64);
5043 IRTemp result = newTemp(Ity_I64);
5044
5045 assign(op1, get_gpr_dw0(r1));
5046 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5047 assign(result, binop(Iop_Xor64, mkexpr(op1), mkexpr(op2)));
5048 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5049 put_gpr_dw0(r1, mkexpr(result));
5050
5051 return "xg";
5052}
5053
florian55085f82012-11-21 00:36:55 +00005054static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005055s390_irgen_XI(UChar i2, IRTemp op1addr)
5056{
5057 IRTemp op1 = newTemp(Ity_I8);
5058 UChar op2;
5059 IRTemp result = newTemp(Ity_I8);
5060
5061 assign(op1, load(Ity_I8, mkexpr(op1addr)));
5062 op2 = i2;
5063 assign(result, binop(Iop_Xor8, mkexpr(op1), mkU8(op2)));
5064 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5065 store(mkexpr(op1addr), mkexpr(result));
5066
5067 return "xi";
5068}
5069
florian55085f82012-11-21 00:36:55 +00005070static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005071s390_irgen_XIY(UChar i2, IRTemp op1addr)
5072{
5073 IRTemp op1 = newTemp(Ity_I8);
5074 UChar op2;
5075 IRTemp result = newTemp(Ity_I8);
5076
5077 assign(op1, load(Ity_I8, mkexpr(op1addr)));
5078 op2 = i2;
5079 assign(result, binop(Iop_Xor8, mkexpr(op1), mkU8(op2)));
5080 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5081 store(mkexpr(op1addr), mkexpr(result));
5082
5083 return "xiy";
5084}
5085
florian55085f82012-11-21 00:36:55 +00005086static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005087s390_irgen_XIHF(UChar r1, UInt i2)
5088{
5089 IRTemp op1 = newTemp(Ity_I32);
5090 UInt op2;
5091 IRTemp result = newTemp(Ity_I32);
5092
5093 assign(op1, get_gpr_w0(r1));
5094 op2 = i2;
5095 assign(result, binop(Iop_Xor32, mkexpr(op1), mkU32(op2)));
5096 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5097 put_gpr_w0(r1, mkexpr(result));
5098
5099 return "xihf";
5100}
5101
florian55085f82012-11-21 00:36:55 +00005102static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005103s390_irgen_XILF(UChar r1, UInt i2)
5104{
5105 IRTemp op1 = newTemp(Ity_I32);
5106 UInt op2;
5107 IRTemp result = newTemp(Ity_I32);
5108
5109 assign(op1, get_gpr_w1(r1));
5110 op2 = i2;
5111 assign(result, binop(Iop_Xor32, mkexpr(op1), mkU32(op2)));
5112 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5113 put_gpr_w1(r1, mkexpr(result));
5114
5115 return "xilf";
5116}
5117
florian55085f82012-11-21 00:36:55 +00005118static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005119s390_irgen_EAR(UChar r1, UChar r2)
5120{
5121 put_gpr_w1(r1, get_ar_w0(r2));
sewardj7ee97522011-05-09 21:45:04 +00005122 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00005123 s390_disasm(ENC3(MNM, GPR, AR), "ear", r1, r2);
5124
5125 return "ear";
5126}
5127
florian55085f82012-11-21 00:36:55 +00005128static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005129s390_irgen_IC(UChar r1, IRTemp op2addr)
5130{
5131 put_gpr_b7(r1, load(Ity_I8, mkexpr(op2addr)));
5132
5133 return "ic";
5134}
5135
florian55085f82012-11-21 00:36:55 +00005136static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005137s390_irgen_ICY(UChar r1, IRTemp op2addr)
5138{
5139 put_gpr_b7(r1, load(Ity_I8, mkexpr(op2addr)));
5140
5141 return "icy";
5142}
5143
florian55085f82012-11-21 00:36:55 +00005144static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005145s390_irgen_ICM(UChar r1, UChar r3, IRTemp op2addr)
5146{
5147 UChar n;
5148 IRTemp result = newTemp(Ity_I32);
5149 UInt mask;
5150
5151 n = 0;
5152 mask = (UInt)r3;
5153 if ((mask & 8) != 0) {
5154 put_gpr_b4(r1, load(Ity_I8, mkexpr(op2addr)));
5155 n = n + 1;
5156 }
5157 if ((mask & 4) != 0) {
5158 put_gpr_b5(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5159
5160 n = n + 1;
5161 }
5162 if ((mask & 2) != 0) {
5163 put_gpr_b6(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5164
5165 n = n + 1;
5166 }
5167 if ((mask & 1) != 0) {
5168 put_gpr_b7(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5169
5170 n = n + 1;
5171 }
5172 assign(result, get_gpr_w1(r1));
5173 s390_cc_thunk_putZZ(S390_CC_OP_INSERT_CHAR_MASK_32, result, mktemp(Ity_I32,
5174 mkU32(mask)));
5175
5176 return "icm";
5177}
5178
florian55085f82012-11-21 00:36:55 +00005179static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005180s390_irgen_ICMY(UChar r1, UChar r3, IRTemp op2addr)
5181{
5182 UChar n;
5183 IRTemp result = newTemp(Ity_I32);
5184 UInt mask;
5185
5186 n = 0;
5187 mask = (UInt)r3;
5188 if ((mask & 8) != 0) {
5189 put_gpr_b4(r1, load(Ity_I8, mkexpr(op2addr)));
5190 n = n + 1;
5191 }
5192 if ((mask & 4) != 0) {
5193 put_gpr_b5(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5194
5195 n = n + 1;
5196 }
5197 if ((mask & 2) != 0) {
5198 put_gpr_b6(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5199
5200 n = n + 1;
5201 }
5202 if ((mask & 1) != 0) {
5203 put_gpr_b7(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5204
5205 n = n + 1;
5206 }
5207 assign(result, get_gpr_w1(r1));
5208 s390_cc_thunk_putZZ(S390_CC_OP_INSERT_CHAR_MASK_32, result, mktemp(Ity_I32,
5209 mkU32(mask)));
5210
5211 return "icmy";
5212}
5213
florian55085f82012-11-21 00:36:55 +00005214static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005215s390_irgen_ICMH(UChar r1, UChar r3, IRTemp op2addr)
5216{
5217 UChar n;
5218 IRTemp result = newTemp(Ity_I32);
5219 UInt mask;
5220
5221 n = 0;
5222 mask = (UInt)r3;
5223 if ((mask & 8) != 0) {
5224 put_gpr_b0(r1, load(Ity_I8, mkexpr(op2addr)));
5225 n = n + 1;
5226 }
5227 if ((mask & 4) != 0) {
5228 put_gpr_b1(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5229
5230 n = n + 1;
5231 }
5232 if ((mask & 2) != 0) {
5233 put_gpr_b2(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5234
5235 n = n + 1;
5236 }
5237 if ((mask & 1) != 0) {
5238 put_gpr_b3(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5239
5240 n = n + 1;
5241 }
5242 assign(result, get_gpr_w0(r1));
5243 s390_cc_thunk_putZZ(S390_CC_OP_INSERT_CHAR_MASK_32, result, mktemp(Ity_I32,
5244 mkU32(mask)));
5245
5246 return "icmh";
5247}
5248
florian55085f82012-11-21 00:36:55 +00005249static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005250s390_irgen_IIHF(UChar r1, UInt i2)
5251{
5252 put_gpr_w0(r1, mkU32(i2));
5253
5254 return "iihf";
5255}
5256
florian55085f82012-11-21 00:36:55 +00005257static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005258s390_irgen_IIHH(UChar r1, UShort i2)
5259{
5260 put_gpr_hw0(r1, mkU16(i2));
5261
5262 return "iihh";
5263}
5264
florian55085f82012-11-21 00:36:55 +00005265static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005266s390_irgen_IIHL(UChar r1, UShort i2)
5267{
5268 put_gpr_hw1(r1, mkU16(i2));
5269
5270 return "iihl";
5271}
5272
florian55085f82012-11-21 00:36:55 +00005273static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005274s390_irgen_IILF(UChar r1, UInt i2)
5275{
5276 put_gpr_w1(r1, mkU32(i2));
5277
5278 return "iilf";
5279}
5280
florian55085f82012-11-21 00:36:55 +00005281static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005282s390_irgen_IILH(UChar r1, UShort i2)
5283{
5284 put_gpr_hw2(r1, mkU16(i2));
5285
5286 return "iilh";
5287}
5288
florian55085f82012-11-21 00:36:55 +00005289static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005290s390_irgen_IILL(UChar r1, UShort i2)
5291{
5292 put_gpr_hw3(r1, mkU16(i2));
5293
5294 return "iill";
5295}
5296
florian55085f82012-11-21 00:36:55 +00005297static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005298s390_irgen_LR(UChar r1, UChar r2)
5299{
5300 put_gpr_w1(r1, get_gpr_w1(r2));
5301
5302 return "lr";
5303}
5304
florian55085f82012-11-21 00:36:55 +00005305static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005306s390_irgen_LGR(UChar r1, UChar r2)
5307{
5308 put_gpr_dw0(r1, get_gpr_dw0(r2));
5309
5310 return "lgr";
5311}
5312
florian55085f82012-11-21 00:36:55 +00005313static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005314s390_irgen_LGFR(UChar r1, UChar r2)
5315{
5316 put_gpr_dw0(r1, unop(Iop_32Sto64, get_gpr_w1(r2)));
5317
5318 return "lgfr";
5319}
5320
florian55085f82012-11-21 00:36:55 +00005321static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005322s390_irgen_L(UChar r1, IRTemp op2addr)
5323{
5324 put_gpr_w1(r1, load(Ity_I32, mkexpr(op2addr)));
5325
5326 return "l";
5327}
5328
florian55085f82012-11-21 00:36:55 +00005329static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005330s390_irgen_LY(UChar r1, IRTemp op2addr)
5331{
5332 put_gpr_w1(r1, load(Ity_I32, mkexpr(op2addr)));
5333
5334 return "ly";
5335}
5336
florian55085f82012-11-21 00:36:55 +00005337static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005338s390_irgen_LG(UChar r1, IRTemp op2addr)
5339{
5340 put_gpr_dw0(r1, load(Ity_I64, mkexpr(op2addr)));
5341
5342 return "lg";
5343}
5344
florian55085f82012-11-21 00:36:55 +00005345static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005346s390_irgen_LGF(UChar r1, IRTemp op2addr)
5347{
5348 put_gpr_dw0(r1, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
5349
5350 return "lgf";
5351}
5352
florian55085f82012-11-21 00:36:55 +00005353static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005354s390_irgen_LGFI(UChar r1, UInt i2)
5355{
5356 put_gpr_dw0(r1, mkU64((ULong)(Long)(Int)i2));
5357
5358 return "lgfi";
5359}
5360
florian55085f82012-11-21 00:36:55 +00005361static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005362s390_irgen_LRL(UChar r1, UInt i2)
5363{
5364 put_gpr_w1(r1, load(Ity_I32, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
5365 i2 << 1))));
5366
5367 return "lrl";
5368}
5369
florian55085f82012-11-21 00:36:55 +00005370static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005371s390_irgen_LGRL(UChar r1, UInt i2)
5372{
5373 put_gpr_dw0(r1, load(Ity_I64, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
5374 i2 << 1))));
5375
5376 return "lgrl";
5377}
5378
florian55085f82012-11-21 00:36:55 +00005379static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005380s390_irgen_LGFRL(UChar r1, UInt i2)
5381{
5382 put_gpr_dw0(r1, unop(Iop_32Sto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
5383 ((ULong)(Long)(Int)i2 << 1)))));
5384
5385 return "lgfrl";
5386}
5387
florian55085f82012-11-21 00:36:55 +00005388static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005389s390_irgen_LA(UChar r1, IRTemp op2addr)
5390{
5391 put_gpr_dw0(r1, mkexpr(op2addr));
5392
5393 return "la";
5394}
5395
florian55085f82012-11-21 00:36:55 +00005396static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005397s390_irgen_LAY(UChar r1, IRTemp op2addr)
5398{
5399 put_gpr_dw0(r1, mkexpr(op2addr));
5400
5401 return "lay";
5402}
5403
florian55085f82012-11-21 00:36:55 +00005404static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005405s390_irgen_LAE(UChar r1, IRTemp op2addr)
5406{
5407 put_gpr_dw0(r1, mkexpr(op2addr));
5408
5409 return "lae";
5410}
5411
florian55085f82012-11-21 00:36:55 +00005412static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005413s390_irgen_LAEY(UChar r1, IRTemp op2addr)
5414{
5415 put_gpr_dw0(r1, mkexpr(op2addr));
5416
5417 return "laey";
5418}
5419
florian55085f82012-11-21 00:36:55 +00005420static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005421s390_irgen_LARL(UChar r1, UInt i2)
5422{
5423 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)));
5424
5425 return "larl";
5426}
5427
floriana265ee72012-12-02 20:58:17 +00005428/* The IR representation of LAA and friends is an approximation of what
5429 happens natively. Essentially a loop containing a compare-and-swap is
5430 constructed which will iterate until the CAS succeeds. As a consequence,
5431 instrumenters may see more memory accesses than happen natively. See also
5432 discussion here: https://bugs.kde.org/show_bug.cgi?id=306035 */
florian55085f82012-11-21 00:36:55 +00005433static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005434s390_irgen_LAA(UChar r1, UChar r3, IRTemp op2addr)
5435{
floriana265ee72012-12-02 20:58:17 +00005436 IRCAS *cas;
5437 IRTemp old_mem = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00005438 IRTemp op2 = newTemp(Ity_I32);
5439 IRTemp op3 = newTemp(Ity_I32);
5440 IRTemp result = newTemp(Ity_I32);
5441
5442 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5443 assign(op3, get_gpr_w1(r3));
5444 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
floriana265ee72012-12-02 20:58:17 +00005445
5446 /* Place the addition of second operand and third operand at the
5447 second-operand location everytime */
5448 cas = mkIRCAS(IRTemp_INVALID, old_mem,
5449 Iend_BE, mkexpr(op2addr),
5450 NULL, mkexpr(op2), /* expected value */
5451 NULL, mkexpr(result) /* new value */);
5452 stmt(IRStmt_CAS(cas));
5453
5454 /* Set CC according to 32-bit signed addition */
sewardj2019a972011-03-07 16:04:07 +00005455 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
floriana265ee72012-12-02 20:58:17 +00005456
5457 /* If old_mem contains the expected value, then the CAS succeeded.
5458 Otherwise, it did not */
5459 yield_if(binop(Iop_CmpNE32, mkexpr(old_mem), mkexpr(op2)));
5460 put_gpr_w1(r1, mkexpr(old_mem));
sewardj2019a972011-03-07 16:04:07 +00005461
5462 return "laa";
5463}
5464
florian55085f82012-11-21 00:36:55 +00005465static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005466s390_irgen_LAAG(UChar r1, UChar r3, IRTemp op2addr)
5467{
5468 IRTemp op2 = newTemp(Ity_I64);
5469 IRTemp op3 = newTemp(Ity_I64);
5470 IRTemp result = newTemp(Ity_I64);
5471
5472 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5473 assign(op3, get_gpr_dw0(r3));
5474 assign(result, binop(Iop_Add64, mkexpr(op2), mkexpr(op3)));
5475 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op2, op3);
5476 store(mkexpr(op2addr), mkexpr(result));
5477 put_gpr_dw0(r1, mkexpr(op2));
5478
5479 return "laag";
5480}
5481
florian55085f82012-11-21 00:36:55 +00005482static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005483s390_irgen_LAAL(UChar r1, UChar r3, IRTemp op2addr)
5484{
5485 IRTemp op2 = newTemp(Ity_I32);
5486 IRTemp op3 = newTemp(Ity_I32);
5487 IRTemp result = newTemp(Ity_I32);
5488
5489 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5490 assign(op3, get_gpr_w1(r3));
5491 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
5492 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
5493 store(mkexpr(op2addr), mkexpr(result));
5494 put_gpr_w1(r1, mkexpr(op2));
5495
5496 return "laal";
5497}
5498
florian55085f82012-11-21 00:36:55 +00005499static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005500s390_irgen_LAALG(UChar r1, UChar r3, IRTemp op2addr)
5501{
5502 IRTemp op2 = newTemp(Ity_I64);
5503 IRTemp op3 = newTemp(Ity_I64);
5504 IRTemp result = newTemp(Ity_I64);
5505
5506 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5507 assign(op3, get_gpr_dw0(r3));
5508 assign(result, binop(Iop_Add64, mkexpr(op2), mkexpr(op3)));
5509 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op2, op3);
5510 store(mkexpr(op2addr), mkexpr(result));
5511 put_gpr_dw0(r1, mkexpr(op2));
5512
5513 return "laalg";
5514}
5515
florian55085f82012-11-21 00:36:55 +00005516static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005517s390_irgen_LAN(UChar r1, UChar r3, IRTemp op2addr)
5518{
5519 IRTemp op2 = newTemp(Ity_I32);
5520 IRTemp op3 = newTemp(Ity_I32);
5521 IRTemp result = newTemp(Ity_I32);
5522
5523 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5524 assign(op3, get_gpr_w1(r3));
5525 assign(result, binop(Iop_And32, mkexpr(op2), mkexpr(op3)));
5526 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5527 store(mkexpr(op2addr), mkexpr(result));
5528 put_gpr_w1(r1, mkexpr(op2));
5529
5530 return "lan";
5531}
5532
florian55085f82012-11-21 00:36:55 +00005533static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005534s390_irgen_LANG(UChar r1, UChar r3, IRTemp op2addr)
5535{
5536 IRTemp op2 = newTemp(Ity_I64);
5537 IRTemp op3 = newTemp(Ity_I64);
5538 IRTemp result = newTemp(Ity_I64);
5539
5540 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5541 assign(op3, get_gpr_dw0(r3));
5542 assign(result, binop(Iop_And64, mkexpr(op2), mkexpr(op3)));
5543 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5544 store(mkexpr(op2addr), mkexpr(result));
5545 put_gpr_dw0(r1, mkexpr(op2));
5546
5547 return "lang";
5548}
5549
florian55085f82012-11-21 00:36:55 +00005550static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005551s390_irgen_LAX(UChar r1, UChar r3, IRTemp op2addr)
5552{
5553 IRTemp op2 = newTemp(Ity_I32);
5554 IRTemp op3 = newTemp(Ity_I32);
5555 IRTemp result = newTemp(Ity_I32);
5556
5557 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5558 assign(op3, get_gpr_w1(r3));
5559 assign(result, binop(Iop_Xor32, mkexpr(op2), mkexpr(op3)));
5560 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5561 store(mkexpr(op2addr), mkexpr(result));
5562 put_gpr_w1(r1, mkexpr(op2));
5563
5564 return "lax";
5565}
5566
florian55085f82012-11-21 00:36:55 +00005567static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005568s390_irgen_LAXG(UChar r1, UChar r3, IRTemp op2addr)
5569{
5570 IRTemp op2 = newTemp(Ity_I64);
5571 IRTemp op3 = newTemp(Ity_I64);
5572 IRTemp result = newTemp(Ity_I64);
5573
5574 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5575 assign(op3, get_gpr_dw0(r3));
5576 assign(result, binop(Iop_Xor64, mkexpr(op2), mkexpr(op3)));
5577 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5578 store(mkexpr(op2addr), mkexpr(result));
5579 put_gpr_dw0(r1, mkexpr(op2));
5580
5581 return "laxg";
5582}
5583
florian55085f82012-11-21 00:36:55 +00005584static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005585s390_irgen_LAO(UChar r1, UChar r3, IRTemp op2addr)
5586{
5587 IRTemp op2 = newTemp(Ity_I32);
5588 IRTemp op3 = newTemp(Ity_I32);
5589 IRTemp result = newTemp(Ity_I32);
5590
5591 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5592 assign(op3, get_gpr_w1(r3));
5593 assign(result, binop(Iop_Or32, mkexpr(op2), mkexpr(op3)));
5594 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5595 store(mkexpr(op2addr), mkexpr(result));
5596 put_gpr_w1(r1, mkexpr(op2));
5597
5598 return "lao";
5599}
5600
florian55085f82012-11-21 00:36:55 +00005601static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005602s390_irgen_LAOG(UChar r1, UChar r3, IRTemp op2addr)
5603{
5604 IRTemp op2 = newTemp(Ity_I64);
5605 IRTemp op3 = newTemp(Ity_I64);
5606 IRTemp result = newTemp(Ity_I64);
5607
5608 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5609 assign(op3, get_gpr_dw0(r3));
5610 assign(result, binop(Iop_Or64, mkexpr(op2), mkexpr(op3)));
5611 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5612 store(mkexpr(op2addr), mkexpr(result));
5613 put_gpr_dw0(r1, mkexpr(op2));
5614
5615 return "laog";
5616}
5617
florian55085f82012-11-21 00:36:55 +00005618static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005619s390_irgen_LTR(UChar r1, UChar r2)
5620{
5621 IRTemp op2 = newTemp(Ity_I32);
5622
5623 assign(op2, get_gpr_w1(r2));
5624 put_gpr_w1(r1, mkexpr(op2));
5625 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5626
5627 return "ltr";
5628}
5629
florian55085f82012-11-21 00:36:55 +00005630static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005631s390_irgen_LTGR(UChar r1, UChar r2)
5632{
5633 IRTemp op2 = newTemp(Ity_I64);
5634
5635 assign(op2, get_gpr_dw0(r2));
5636 put_gpr_dw0(r1, mkexpr(op2));
5637 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5638
5639 return "ltgr";
5640}
5641
florian55085f82012-11-21 00:36:55 +00005642static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005643s390_irgen_LTGFR(UChar r1, UChar r2)
5644{
5645 IRTemp op2 = newTemp(Ity_I64);
5646
5647 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
5648 put_gpr_dw0(r1, mkexpr(op2));
5649 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5650
5651 return "ltgfr";
5652}
5653
florian55085f82012-11-21 00:36:55 +00005654static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005655s390_irgen_LT(UChar r1, IRTemp op2addr)
5656{
5657 IRTemp op2 = newTemp(Ity_I32);
5658
5659 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5660 put_gpr_w1(r1, mkexpr(op2));
5661 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5662
5663 return "lt";
5664}
5665
florian55085f82012-11-21 00:36:55 +00005666static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005667s390_irgen_LTG(UChar r1, IRTemp op2addr)
5668{
5669 IRTemp op2 = newTemp(Ity_I64);
5670
5671 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5672 put_gpr_dw0(r1, mkexpr(op2));
5673 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5674
5675 return "ltg";
5676}
5677
florian55085f82012-11-21 00:36:55 +00005678static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005679s390_irgen_LTGF(UChar r1, IRTemp op2addr)
5680{
5681 IRTemp op2 = newTemp(Ity_I64);
5682
5683 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
5684 put_gpr_dw0(r1, mkexpr(op2));
5685 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5686
5687 return "ltgf";
5688}
5689
florian55085f82012-11-21 00:36:55 +00005690static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005691s390_irgen_LBR(UChar r1, UChar r2)
5692{
5693 put_gpr_w1(r1, unop(Iop_8Sto32, get_gpr_b7(r2)));
5694
5695 return "lbr";
5696}
5697
florian55085f82012-11-21 00:36:55 +00005698static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005699s390_irgen_LGBR(UChar r1, UChar r2)
5700{
5701 put_gpr_dw0(r1, unop(Iop_8Sto64, get_gpr_b7(r2)));
5702
5703 return "lgbr";
5704}
5705
florian55085f82012-11-21 00:36:55 +00005706static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005707s390_irgen_LB(UChar r1, IRTemp op2addr)
5708{
5709 put_gpr_w1(r1, unop(Iop_8Sto32, load(Ity_I8, mkexpr(op2addr))));
5710
5711 return "lb";
5712}
5713
florian55085f82012-11-21 00:36:55 +00005714static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005715s390_irgen_LGB(UChar r1, IRTemp op2addr)
5716{
5717 put_gpr_dw0(r1, unop(Iop_8Sto64, load(Ity_I8, mkexpr(op2addr))));
5718
5719 return "lgb";
5720}
5721
florian55085f82012-11-21 00:36:55 +00005722static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005723s390_irgen_LBH(UChar r1, IRTemp op2addr)
5724{
5725 put_gpr_w0(r1, unop(Iop_8Sto32, load(Ity_I8, mkexpr(op2addr))));
5726
5727 return "lbh";
5728}
5729
florian55085f82012-11-21 00:36:55 +00005730static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005731s390_irgen_LCR(UChar r1, UChar r2)
5732{
5733 Int op1;
5734 IRTemp op2 = newTemp(Ity_I32);
5735 IRTemp result = newTemp(Ity_I32);
5736
5737 op1 = 0;
5738 assign(op2, get_gpr_w1(r2));
5739 assign(result, binop(Iop_Sub32, mkU32((UInt)op1), mkexpr(op2)));
5740 put_gpr_w1(r1, mkexpr(result));
5741 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, mktemp(Ity_I32, mkU32((UInt)
5742 op1)), op2);
5743
5744 return "lcr";
5745}
5746
florian55085f82012-11-21 00:36:55 +00005747static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005748s390_irgen_LCGR(UChar r1, UChar r2)
5749{
5750 Long op1;
5751 IRTemp op2 = newTemp(Ity_I64);
5752 IRTemp result = newTemp(Ity_I64);
5753
5754 op1 = 0ULL;
5755 assign(op2, get_gpr_dw0(r2));
5756 assign(result, binop(Iop_Sub64, mkU64((ULong)op1), mkexpr(op2)));
5757 put_gpr_dw0(r1, mkexpr(result));
5758 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, mktemp(Ity_I64, mkU64((ULong)
5759 op1)), op2);
5760
5761 return "lcgr";
5762}
5763
florian55085f82012-11-21 00:36:55 +00005764static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005765s390_irgen_LCGFR(UChar r1, UChar r2)
5766{
5767 Long op1;
5768 IRTemp op2 = newTemp(Ity_I64);
5769 IRTemp result = newTemp(Ity_I64);
5770
5771 op1 = 0ULL;
5772 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
5773 assign(result, binop(Iop_Sub64, mkU64((ULong)op1), mkexpr(op2)));
5774 put_gpr_dw0(r1, mkexpr(result));
5775 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, mktemp(Ity_I64, mkU64((ULong)
5776 op1)), op2);
5777
5778 return "lcgfr";
5779}
5780
florian55085f82012-11-21 00:36:55 +00005781static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005782s390_irgen_LHR(UChar r1, UChar r2)
5783{
5784 put_gpr_w1(r1, unop(Iop_16Sto32, get_gpr_hw3(r2)));
5785
5786 return "lhr";
5787}
5788
florian55085f82012-11-21 00:36:55 +00005789static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005790s390_irgen_LGHR(UChar r1, UChar r2)
5791{
5792 put_gpr_dw0(r1, unop(Iop_16Sto64, get_gpr_hw3(r2)));
5793
5794 return "lghr";
5795}
5796
florian55085f82012-11-21 00:36:55 +00005797static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005798s390_irgen_LH(UChar r1, IRTemp op2addr)
5799{
5800 put_gpr_w1(r1, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
5801
5802 return "lh";
5803}
5804
florian55085f82012-11-21 00:36:55 +00005805static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005806s390_irgen_LHY(UChar r1, IRTemp op2addr)
5807{
5808 put_gpr_w1(r1, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
5809
5810 return "lhy";
5811}
5812
florian55085f82012-11-21 00:36:55 +00005813static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005814s390_irgen_LGH(UChar r1, IRTemp op2addr)
5815{
5816 put_gpr_dw0(r1, unop(Iop_16Sto64, load(Ity_I16, mkexpr(op2addr))));
5817
5818 return "lgh";
5819}
5820
florian55085f82012-11-21 00:36:55 +00005821static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005822s390_irgen_LHI(UChar r1, UShort i2)
5823{
5824 put_gpr_w1(r1, mkU32((UInt)(Int)(Short)i2));
5825
5826 return "lhi";
5827}
5828
florian55085f82012-11-21 00:36:55 +00005829static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005830s390_irgen_LGHI(UChar r1, UShort i2)
5831{
5832 put_gpr_dw0(r1, mkU64((ULong)(Long)(Short)i2));
5833
5834 return "lghi";
5835}
5836
florian55085f82012-11-21 00:36:55 +00005837static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005838s390_irgen_LHRL(UChar r1, UInt i2)
5839{
5840 put_gpr_w1(r1, unop(Iop_16Sto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
5841 ((ULong)(Long)(Int)i2 << 1)))));
5842
5843 return "lhrl";
5844}
5845
florian55085f82012-11-21 00:36:55 +00005846static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005847s390_irgen_LGHRL(UChar r1, UInt i2)
5848{
5849 put_gpr_dw0(r1, unop(Iop_16Sto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
5850 ((ULong)(Long)(Int)i2 << 1)))));
5851
5852 return "lghrl";
5853}
5854
florian55085f82012-11-21 00:36:55 +00005855static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005856s390_irgen_LHH(UChar r1, IRTemp op2addr)
5857{
5858 put_gpr_w0(r1, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
5859
5860 return "lhh";
5861}
5862
florian55085f82012-11-21 00:36:55 +00005863static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005864s390_irgen_LFH(UChar r1, IRTemp op2addr)
5865{
5866 put_gpr_w0(r1, load(Ity_I32, mkexpr(op2addr)));
5867
5868 return "lfh";
5869}
5870
florian55085f82012-11-21 00:36:55 +00005871static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005872s390_irgen_LLGFR(UChar r1, UChar r2)
5873{
5874 put_gpr_dw0(r1, unop(Iop_32Uto64, get_gpr_w1(r2)));
5875
5876 return "llgfr";
5877}
5878
florian55085f82012-11-21 00:36:55 +00005879static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005880s390_irgen_LLGF(UChar r1, IRTemp op2addr)
5881{
5882 put_gpr_dw0(r1, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
5883
5884 return "llgf";
5885}
5886
florian55085f82012-11-21 00:36:55 +00005887static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005888s390_irgen_LLGFRL(UChar r1, UInt i2)
5889{
5890 put_gpr_dw0(r1, unop(Iop_32Uto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
5891 ((ULong)(Long)(Int)i2 << 1)))));
5892
5893 return "llgfrl";
5894}
5895
florian55085f82012-11-21 00:36:55 +00005896static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005897s390_irgen_LLCR(UChar r1, UChar r2)
5898{
5899 put_gpr_w1(r1, unop(Iop_8Uto32, get_gpr_b7(r2)));
5900
5901 return "llcr";
5902}
5903
florian55085f82012-11-21 00:36:55 +00005904static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005905s390_irgen_LLGCR(UChar r1, UChar r2)
5906{
5907 put_gpr_dw0(r1, unop(Iop_8Uto64, get_gpr_b7(r2)));
5908
5909 return "llgcr";
5910}
5911
florian55085f82012-11-21 00:36:55 +00005912static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005913s390_irgen_LLC(UChar r1, IRTemp op2addr)
5914{
5915 put_gpr_w1(r1, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
5916
5917 return "llc";
5918}
5919
florian55085f82012-11-21 00:36:55 +00005920static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005921s390_irgen_LLGC(UChar r1, IRTemp op2addr)
5922{
5923 put_gpr_dw0(r1, unop(Iop_8Uto64, load(Ity_I8, mkexpr(op2addr))));
5924
5925 return "llgc";
5926}
5927
florian55085f82012-11-21 00:36:55 +00005928static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005929s390_irgen_LLCH(UChar r1, IRTemp op2addr)
5930{
5931 put_gpr_w0(r1, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
5932
5933 return "llch";
5934}
5935
florian55085f82012-11-21 00:36:55 +00005936static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005937s390_irgen_LLHR(UChar r1, UChar r2)
5938{
5939 put_gpr_w1(r1, unop(Iop_16Uto32, get_gpr_hw3(r2)));
5940
5941 return "llhr";
5942}
5943
florian55085f82012-11-21 00:36:55 +00005944static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005945s390_irgen_LLGHR(UChar r1, UChar r2)
5946{
5947 put_gpr_dw0(r1, unop(Iop_16Uto64, get_gpr_hw3(r2)));
5948
5949 return "llghr";
5950}
5951
florian55085f82012-11-21 00:36:55 +00005952static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005953s390_irgen_LLH(UChar r1, IRTemp op2addr)
5954{
5955 put_gpr_w1(r1, unop(Iop_16Uto32, load(Ity_I16, mkexpr(op2addr))));
5956
5957 return "llh";
5958}
5959
florian55085f82012-11-21 00:36:55 +00005960static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005961s390_irgen_LLGH(UChar r1, IRTemp op2addr)
5962{
5963 put_gpr_dw0(r1, unop(Iop_16Uto64, load(Ity_I16, mkexpr(op2addr))));
5964
5965 return "llgh";
5966}
5967
florian55085f82012-11-21 00:36:55 +00005968static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005969s390_irgen_LLHRL(UChar r1, UInt i2)
5970{
5971 put_gpr_w1(r1, unop(Iop_16Uto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
5972 ((ULong)(Long)(Int)i2 << 1)))));
5973
5974 return "llhrl";
5975}
5976
florian55085f82012-11-21 00:36:55 +00005977static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005978s390_irgen_LLGHRL(UChar r1, UInt i2)
5979{
5980 put_gpr_dw0(r1, unop(Iop_16Uto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
5981 ((ULong)(Long)(Int)i2 << 1)))));
5982
5983 return "llghrl";
5984}
5985
florian55085f82012-11-21 00:36:55 +00005986static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005987s390_irgen_LLHH(UChar r1, IRTemp op2addr)
5988{
5989 put_gpr_w0(r1, unop(Iop_16Uto32, load(Ity_I16, mkexpr(op2addr))));
5990
5991 return "llhh";
5992}
5993
florian55085f82012-11-21 00:36:55 +00005994static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005995s390_irgen_LLIHF(UChar r1, UInt i2)
5996{
5997 put_gpr_dw0(r1, mkU64(((ULong)i2) << 32));
5998
5999 return "llihf";
6000}
6001
florian55085f82012-11-21 00:36:55 +00006002static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006003s390_irgen_LLIHH(UChar r1, UShort i2)
6004{
6005 put_gpr_dw0(r1, mkU64(((ULong)i2) << 48));
6006
6007 return "llihh";
6008}
6009
florian55085f82012-11-21 00:36:55 +00006010static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006011s390_irgen_LLIHL(UChar r1, UShort i2)
6012{
6013 put_gpr_dw0(r1, mkU64(((ULong)i2) << 32));
6014
6015 return "llihl";
6016}
6017
florian55085f82012-11-21 00:36:55 +00006018static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006019s390_irgen_LLILF(UChar r1, UInt i2)
6020{
6021 put_gpr_dw0(r1, mkU64(i2));
6022
6023 return "llilf";
6024}
6025
florian55085f82012-11-21 00:36:55 +00006026static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006027s390_irgen_LLILH(UChar r1, UShort i2)
6028{
6029 put_gpr_dw0(r1, mkU64(((ULong)i2) << 16));
6030
6031 return "llilh";
6032}
6033
florian55085f82012-11-21 00:36:55 +00006034static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006035s390_irgen_LLILL(UChar r1, UShort i2)
6036{
6037 put_gpr_dw0(r1, mkU64(i2));
6038
6039 return "llill";
6040}
6041
florian55085f82012-11-21 00:36:55 +00006042static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006043s390_irgen_LLGTR(UChar r1, UChar r2)
6044{
6045 put_gpr_dw0(r1, unop(Iop_32Uto64, binop(Iop_And32, get_gpr_w1(r2),
6046 mkU32(2147483647))));
6047
6048 return "llgtr";
6049}
6050
florian55085f82012-11-21 00:36:55 +00006051static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006052s390_irgen_LLGT(UChar r1, IRTemp op2addr)
6053{
6054 put_gpr_dw0(r1, unop(Iop_32Uto64, binop(Iop_And32, load(Ity_I32,
6055 mkexpr(op2addr)), mkU32(2147483647))));
6056
6057 return "llgt";
6058}
6059
florian55085f82012-11-21 00:36:55 +00006060static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006061s390_irgen_LNR(UChar r1, UChar r2)
6062{
6063 IRTemp op2 = newTemp(Ity_I32);
6064 IRTemp result = newTemp(Ity_I32);
6065
6066 assign(op2, get_gpr_w1(r2));
6067 assign(result, mkite(binop(Iop_CmpLE32S, mkexpr(op2), mkU32(0)), mkexpr(op2),
6068 binop(Iop_Sub32, mkU32(0), mkexpr(op2))));
6069 put_gpr_w1(r1, mkexpr(result));
6070 s390_cc_thunk_putS(S390_CC_OP_BITWISE, result);
6071
6072 return "lnr";
6073}
6074
florian55085f82012-11-21 00:36:55 +00006075static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006076s390_irgen_LNGR(UChar r1, UChar r2)
6077{
6078 IRTemp op2 = newTemp(Ity_I64);
6079 IRTemp result = newTemp(Ity_I64);
6080
6081 assign(op2, get_gpr_dw0(r2));
6082 assign(result, mkite(binop(Iop_CmpLE64S, mkexpr(op2), mkU64(0)), mkexpr(op2),
6083 binop(Iop_Sub64, mkU64(0), mkexpr(op2))));
6084 put_gpr_dw0(r1, mkexpr(result));
6085 s390_cc_thunk_putS(S390_CC_OP_BITWISE, result);
6086
6087 return "lngr";
6088}
6089
florian55085f82012-11-21 00:36:55 +00006090static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006091s390_irgen_LNGFR(UChar r1, UChar r2 __attribute__((unused)))
6092{
6093 IRTemp op2 = newTemp(Ity_I64);
6094 IRTemp result = newTemp(Ity_I64);
6095
6096 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r1)));
6097 assign(result, mkite(binop(Iop_CmpLE64S, mkexpr(op2), mkU64(0)), mkexpr(op2),
6098 binop(Iop_Sub64, mkU64(0), mkexpr(op2))));
6099 put_gpr_dw0(r1, mkexpr(result));
6100 s390_cc_thunk_putS(S390_CC_OP_BITWISE, result);
6101
6102 return "lngfr";
6103}
6104
florian55085f82012-11-21 00:36:55 +00006105static const HChar *
sewardjd7bde722011-04-05 13:19:33 +00006106s390_irgen_LOCR(UChar m3, UChar r1, UChar r2)
6107{
florian6820ba52012-07-26 02:01:50 +00006108 next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0)));
sewardjd7bde722011-04-05 13:19:33 +00006109 put_gpr_w1(r1, get_gpr_w1(r2));
6110
6111 return "locr";
6112}
6113
florian55085f82012-11-21 00:36:55 +00006114static const HChar *
sewardjd7bde722011-04-05 13:19:33 +00006115s390_irgen_LOCGR(UChar m3, UChar r1, UChar r2)
6116{
florian6820ba52012-07-26 02:01:50 +00006117 next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0)));
sewardjd7bde722011-04-05 13:19:33 +00006118 put_gpr_dw0(r1, get_gpr_dw0(r2));
6119
6120 return "locgr";
6121}
6122
florian55085f82012-11-21 00:36:55 +00006123static const HChar *
sewardjd7bde722011-04-05 13:19:33 +00006124s390_irgen_LOC(UChar r1, IRTemp op2addr)
6125{
6126 /* condition is checked in format handler */
6127 put_gpr_w1(r1, load(Ity_I32, mkexpr(op2addr)));
6128
6129 return "loc";
6130}
6131
florian55085f82012-11-21 00:36:55 +00006132static const HChar *
sewardjd7bde722011-04-05 13:19:33 +00006133s390_irgen_LOCG(UChar r1, IRTemp op2addr)
6134{
6135 /* condition is checked in format handler */
6136 put_gpr_dw0(r1, load(Ity_I64, mkexpr(op2addr)));
6137
6138 return "locg";
6139}
6140
florian55085f82012-11-21 00:36:55 +00006141static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006142s390_irgen_LPQ(UChar r1, IRTemp op2addr)
6143{
6144 put_gpr_dw0(r1, load(Ity_I64, mkexpr(op2addr)));
6145 put_gpr_dw0(r1 + 1, load(Ity_I64, binop(Iop_Add64, mkexpr(op2addr), mkU64(8))
6146 ));
6147
6148 return "lpq";
6149}
6150
florian55085f82012-11-21 00:36:55 +00006151static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006152s390_irgen_LPR(UChar r1, UChar r2)
6153{
6154 IRTemp op2 = newTemp(Ity_I32);
6155 IRTemp result = newTemp(Ity_I32);
6156
6157 assign(op2, get_gpr_w1(r2));
6158 assign(result, mkite(binop(Iop_CmpLT32S, mkexpr(op2), mkU32(0)),
6159 binop(Iop_Sub32, mkU32(0), mkexpr(op2)), mkexpr(op2)));
6160 put_gpr_w1(r1, mkexpr(result));
6161 s390_cc_thunk_putS(S390_CC_OP_LOAD_POSITIVE_32, op2);
6162
6163 return "lpr";
6164}
6165
florian55085f82012-11-21 00:36:55 +00006166static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006167s390_irgen_LPGR(UChar r1, UChar r2)
6168{
6169 IRTemp op2 = newTemp(Ity_I64);
6170 IRTemp result = newTemp(Ity_I64);
6171
6172 assign(op2, get_gpr_dw0(r2));
6173 assign(result, mkite(binop(Iop_CmpLT64S, mkexpr(op2), mkU64(0)),
6174 binop(Iop_Sub64, mkU64(0), mkexpr(op2)), mkexpr(op2)));
6175 put_gpr_dw0(r1, mkexpr(result));
6176 s390_cc_thunk_putS(S390_CC_OP_LOAD_POSITIVE_64, op2);
6177
6178 return "lpgr";
6179}
6180
florian55085f82012-11-21 00:36:55 +00006181static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006182s390_irgen_LPGFR(UChar r1, UChar r2)
6183{
6184 IRTemp op2 = newTemp(Ity_I64);
6185 IRTemp result = newTemp(Ity_I64);
6186
6187 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
6188 assign(result, mkite(binop(Iop_CmpLT64S, mkexpr(op2), mkU64(0)),
6189 binop(Iop_Sub64, mkU64(0), mkexpr(op2)), mkexpr(op2)));
6190 put_gpr_dw0(r1, mkexpr(result));
6191 s390_cc_thunk_putS(S390_CC_OP_LOAD_POSITIVE_64, op2);
6192
6193 return "lpgfr";
6194}
6195
florian55085f82012-11-21 00:36:55 +00006196static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006197s390_irgen_LRVR(UChar r1, UChar r2)
6198{
6199 IRTemp b0 = newTemp(Ity_I8);
6200 IRTemp b1 = newTemp(Ity_I8);
6201 IRTemp b2 = newTemp(Ity_I8);
6202 IRTemp b3 = newTemp(Ity_I8);
6203
6204 assign(b3, get_gpr_b7(r2));
6205 assign(b2, get_gpr_b6(r2));
6206 assign(b1, get_gpr_b5(r2));
6207 assign(b0, get_gpr_b4(r2));
6208 put_gpr_b4(r1, mkexpr(b3));
6209 put_gpr_b5(r1, mkexpr(b2));
6210 put_gpr_b6(r1, mkexpr(b1));
6211 put_gpr_b7(r1, mkexpr(b0));
6212
6213 return "lrvr";
6214}
6215
florian55085f82012-11-21 00:36:55 +00006216static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006217s390_irgen_LRVGR(UChar r1, UChar r2)
6218{
6219 IRTemp b0 = newTemp(Ity_I8);
6220 IRTemp b1 = newTemp(Ity_I8);
6221 IRTemp b2 = newTemp(Ity_I8);
6222 IRTemp b3 = newTemp(Ity_I8);
6223 IRTemp b4 = newTemp(Ity_I8);
6224 IRTemp b5 = newTemp(Ity_I8);
6225 IRTemp b6 = newTemp(Ity_I8);
6226 IRTemp b7 = newTemp(Ity_I8);
6227
6228 assign(b7, get_gpr_b7(r2));
6229 assign(b6, get_gpr_b6(r2));
6230 assign(b5, get_gpr_b5(r2));
6231 assign(b4, get_gpr_b4(r2));
6232 assign(b3, get_gpr_b3(r2));
6233 assign(b2, get_gpr_b2(r2));
6234 assign(b1, get_gpr_b1(r2));
6235 assign(b0, get_gpr_b0(r2));
6236 put_gpr_b0(r1, mkexpr(b7));
6237 put_gpr_b1(r1, mkexpr(b6));
6238 put_gpr_b2(r1, mkexpr(b5));
6239 put_gpr_b3(r1, mkexpr(b4));
6240 put_gpr_b4(r1, mkexpr(b3));
6241 put_gpr_b5(r1, mkexpr(b2));
6242 put_gpr_b6(r1, mkexpr(b1));
6243 put_gpr_b7(r1, mkexpr(b0));
6244
6245 return "lrvgr";
6246}
6247
florian55085f82012-11-21 00:36:55 +00006248static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006249s390_irgen_LRVH(UChar r1, IRTemp op2addr)
6250{
6251 IRTemp op2 = newTemp(Ity_I16);
6252
6253 assign(op2, load(Ity_I16, mkexpr(op2addr)));
6254 put_gpr_b6(r1, unop(Iop_16to8, mkexpr(op2)));
6255 put_gpr_b7(r1, unop(Iop_16HIto8, mkexpr(op2)));
6256
6257 return "lrvh";
6258}
6259
florian55085f82012-11-21 00:36:55 +00006260static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006261s390_irgen_LRV(UChar r1, IRTemp op2addr)
6262{
6263 IRTemp op2 = newTemp(Ity_I32);
6264
6265 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6266 put_gpr_b4(r1, unop(Iop_32to8, binop(Iop_And32, mkexpr(op2), mkU32(255))));
6267 put_gpr_b5(r1, unop(Iop_32to8, binop(Iop_And32, binop(Iop_Shr32, mkexpr(op2),
6268 mkU8(8)), mkU32(255))));
6269 put_gpr_b6(r1, unop(Iop_32to8, binop(Iop_And32, binop(Iop_Shr32, mkexpr(op2),
6270 mkU8(16)), mkU32(255))));
6271 put_gpr_b7(r1, unop(Iop_32to8, binop(Iop_And32, binop(Iop_Shr32, mkexpr(op2),
6272 mkU8(24)), mkU32(255))));
6273
6274 return "lrv";
6275}
6276
florian55085f82012-11-21 00:36:55 +00006277static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006278s390_irgen_LRVG(UChar r1, IRTemp op2addr)
6279{
6280 IRTemp op2 = newTemp(Ity_I64);
6281
6282 assign(op2, load(Ity_I64, mkexpr(op2addr)));
6283 put_gpr_b0(r1, unop(Iop_64to8, binop(Iop_And64, mkexpr(op2), mkU64(255))));
6284 put_gpr_b1(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6285 mkU8(8)), mkU64(255))));
6286 put_gpr_b2(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6287 mkU8(16)), mkU64(255))));
6288 put_gpr_b3(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6289 mkU8(24)), mkU64(255))));
6290 put_gpr_b4(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6291 mkU8(32)), mkU64(255))));
6292 put_gpr_b5(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6293 mkU8(40)), mkU64(255))));
6294 put_gpr_b6(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6295 mkU8(48)), mkU64(255))));
6296 put_gpr_b7(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6297 mkU8(56)), mkU64(255))));
6298
6299 return "lrvg";
6300}
6301
florian55085f82012-11-21 00:36:55 +00006302static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006303s390_irgen_MVHHI(UShort i2, IRTemp op1addr)
6304{
6305 store(mkexpr(op1addr), mkU16(i2));
6306
6307 return "mvhhi";
6308}
6309
florian55085f82012-11-21 00:36:55 +00006310static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006311s390_irgen_MVHI(UShort i2, IRTemp op1addr)
6312{
6313 store(mkexpr(op1addr), mkU32((UInt)(Int)(Short)i2));
6314
6315 return "mvhi";
6316}
6317
florian55085f82012-11-21 00:36:55 +00006318static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006319s390_irgen_MVGHI(UShort i2, IRTemp op1addr)
6320{
6321 store(mkexpr(op1addr), mkU64((ULong)(Long)(Short)i2));
6322
6323 return "mvghi";
6324}
6325
florian55085f82012-11-21 00:36:55 +00006326static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006327s390_irgen_MVI(UChar i2, IRTemp op1addr)
6328{
6329 store(mkexpr(op1addr), mkU8(i2));
6330
6331 return "mvi";
6332}
6333
florian55085f82012-11-21 00:36:55 +00006334static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006335s390_irgen_MVIY(UChar i2, IRTemp op1addr)
6336{
6337 store(mkexpr(op1addr), mkU8(i2));
6338
6339 return "mviy";
6340}
6341
florian55085f82012-11-21 00:36:55 +00006342static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006343s390_irgen_MR(UChar r1, UChar r2)
6344{
6345 IRTemp op1 = newTemp(Ity_I32);
6346 IRTemp op2 = newTemp(Ity_I32);
6347 IRTemp result = newTemp(Ity_I64);
6348
6349 assign(op1, get_gpr_w1(r1 + 1));
6350 assign(op2, get_gpr_w1(r2));
6351 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6352 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6353 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6354
6355 return "mr";
6356}
6357
florian55085f82012-11-21 00:36:55 +00006358static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006359s390_irgen_M(UChar r1, IRTemp op2addr)
6360{
6361 IRTemp op1 = newTemp(Ity_I32);
6362 IRTemp op2 = newTemp(Ity_I32);
6363 IRTemp result = newTemp(Ity_I64);
6364
6365 assign(op1, get_gpr_w1(r1 + 1));
6366 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6367 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6368 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6369 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6370
6371 return "m";
6372}
6373
florian55085f82012-11-21 00:36:55 +00006374static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006375s390_irgen_MFY(UChar r1, IRTemp op2addr)
6376{
6377 IRTemp op1 = newTemp(Ity_I32);
6378 IRTemp op2 = newTemp(Ity_I32);
6379 IRTemp result = newTemp(Ity_I64);
6380
6381 assign(op1, get_gpr_w1(r1 + 1));
6382 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6383 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6384 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6385 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6386
6387 return "mfy";
6388}
6389
florian55085f82012-11-21 00:36:55 +00006390static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006391s390_irgen_MH(UChar r1, IRTemp op2addr)
6392{
6393 IRTemp op1 = newTemp(Ity_I32);
6394 IRTemp op2 = newTemp(Ity_I16);
6395 IRTemp result = newTemp(Ity_I64);
6396
6397 assign(op1, get_gpr_w1(r1));
6398 assign(op2, load(Ity_I16, mkexpr(op2addr)));
6399 assign(result, binop(Iop_MullS32, mkexpr(op1), unop(Iop_16Sto32, mkexpr(op2))
6400 ));
6401 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6402
6403 return "mh";
6404}
6405
florian55085f82012-11-21 00:36:55 +00006406static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006407s390_irgen_MHY(UChar r1, IRTemp op2addr)
6408{
6409 IRTemp op1 = newTemp(Ity_I32);
6410 IRTemp op2 = newTemp(Ity_I16);
6411 IRTemp result = newTemp(Ity_I64);
6412
6413 assign(op1, get_gpr_w1(r1));
6414 assign(op2, load(Ity_I16, mkexpr(op2addr)));
6415 assign(result, binop(Iop_MullS32, mkexpr(op1), unop(Iop_16Sto32, mkexpr(op2))
6416 ));
6417 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6418
6419 return "mhy";
6420}
6421
florian55085f82012-11-21 00:36:55 +00006422static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006423s390_irgen_MHI(UChar r1, UShort i2)
6424{
6425 IRTemp op1 = newTemp(Ity_I32);
6426 Short op2;
6427 IRTemp result = newTemp(Ity_I64);
6428
6429 assign(op1, get_gpr_w1(r1));
6430 op2 = (Short)i2;
6431 assign(result, binop(Iop_MullS32, mkexpr(op1), unop(Iop_16Sto32,
6432 mkU16((UShort)op2))));
6433 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6434
6435 return "mhi";
6436}
6437
florian55085f82012-11-21 00:36:55 +00006438static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006439s390_irgen_MGHI(UChar r1, UShort i2)
6440{
6441 IRTemp op1 = newTemp(Ity_I64);
6442 Short op2;
6443 IRTemp result = newTemp(Ity_I128);
6444
6445 assign(op1, get_gpr_dw0(r1));
6446 op2 = (Short)i2;
6447 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_16Sto64,
6448 mkU16((UShort)op2))));
6449 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6450
6451 return "mghi";
6452}
6453
florian55085f82012-11-21 00:36:55 +00006454static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006455s390_irgen_MLR(UChar r1, UChar r2)
6456{
6457 IRTemp op1 = newTemp(Ity_I32);
6458 IRTemp op2 = newTemp(Ity_I32);
6459 IRTemp result = newTemp(Ity_I64);
6460
6461 assign(op1, get_gpr_w1(r1 + 1));
6462 assign(op2, get_gpr_w1(r2));
6463 assign(result, binop(Iop_MullU32, mkexpr(op1), mkexpr(op2)));
6464 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6465 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6466
6467 return "mlr";
6468}
6469
florian55085f82012-11-21 00:36:55 +00006470static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006471s390_irgen_MLGR(UChar r1, UChar r2)
6472{
6473 IRTemp op1 = newTemp(Ity_I64);
6474 IRTemp op2 = newTemp(Ity_I64);
6475 IRTemp result = newTemp(Ity_I128);
6476
6477 assign(op1, get_gpr_dw0(r1 + 1));
6478 assign(op2, get_gpr_dw0(r2));
6479 assign(result, binop(Iop_MullU64, mkexpr(op1), mkexpr(op2)));
6480 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result)));
6481 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result)));
6482
6483 return "mlgr";
6484}
6485
florian55085f82012-11-21 00:36:55 +00006486static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006487s390_irgen_ML(UChar r1, IRTemp op2addr)
6488{
6489 IRTemp op1 = newTemp(Ity_I32);
6490 IRTemp op2 = newTemp(Ity_I32);
6491 IRTemp result = newTemp(Ity_I64);
6492
6493 assign(op1, get_gpr_w1(r1 + 1));
6494 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6495 assign(result, binop(Iop_MullU32, mkexpr(op1), mkexpr(op2)));
6496 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6497 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6498
6499 return "ml";
6500}
6501
florian55085f82012-11-21 00:36:55 +00006502static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006503s390_irgen_MLG(UChar r1, IRTemp op2addr)
6504{
6505 IRTemp op1 = newTemp(Ity_I64);
6506 IRTemp op2 = newTemp(Ity_I64);
6507 IRTemp result = newTemp(Ity_I128);
6508
6509 assign(op1, get_gpr_dw0(r1 + 1));
6510 assign(op2, load(Ity_I64, mkexpr(op2addr)));
6511 assign(result, binop(Iop_MullU64, mkexpr(op1), mkexpr(op2)));
6512 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result)));
6513 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result)));
6514
6515 return "mlg";
6516}
6517
florian55085f82012-11-21 00:36:55 +00006518static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006519s390_irgen_MSR(UChar r1, UChar r2)
6520{
6521 IRTemp op1 = newTemp(Ity_I32);
6522 IRTemp op2 = newTemp(Ity_I32);
6523 IRTemp result = newTemp(Ity_I64);
6524
6525 assign(op1, get_gpr_w1(r1));
6526 assign(op2, get_gpr_w1(r2));
6527 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6528 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6529
6530 return "msr";
6531}
6532
florian55085f82012-11-21 00:36:55 +00006533static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006534s390_irgen_MSGR(UChar r1, UChar r2)
6535{
6536 IRTemp op1 = newTemp(Ity_I64);
6537 IRTemp op2 = newTemp(Ity_I64);
6538 IRTemp result = newTemp(Ity_I128);
6539
6540 assign(op1, get_gpr_dw0(r1));
6541 assign(op2, get_gpr_dw0(r2));
6542 assign(result, binop(Iop_MullS64, mkexpr(op1), mkexpr(op2)));
6543 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6544
6545 return "msgr";
6546}
6547
florian55085f82012-11-21 00:36:55 +00006548static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006549s390_irgen_MSGFR(UChar r1, UChar r2)
6550{
6551 IRTemp op1 = newTemp(Ity_I64);
6552 IRTemp op2 = newTemp(Ity_I32);
6553 IRTemp result = newTemp(Ity_I128);
6554
6555 assign(op1, get_gpr_dw0(r1));
6556 assign(op2, get_gpr_w1(r2));
6557 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_32Sto64, mkexpr(op2))
6558 ));
6559 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6560
6561 return "msgfr";
6562}
6563
florian55085f82012-11-21 00:36:55 +00006564static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006565s390_irgen_MS(UChar r1, IRTemp op2addr)
6566{
6567 IRTemp op1 = newTemp(Ity_I32);
6568 IRTemp op2 = newTemp(Ity_I32);
6569 IRTemp result = newTemp(Ity_I64);
6570
6571 assign(op1, get_gpr_w1(r1));
6572 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6573 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6574 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6575
6576 return "ms";
6577}
6578
florian55085f82012-11-21 00:36:55 +00006579static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006580s390_irgen_MSY(UChar r1, IRTemp op2addr)
6581{
6582 IRTemp op1 = newTemp(Ity_I32);
6583 IRTemp op2 = newTemp(Ity_I32);
6584 IRTemp result = newTemp(Ity_I64);
6585
6586 assign(op1, get_gpr_w1(r1));
6587 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6588 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6589 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6590
6591 return "msy";
6592}
6593
florian55085f82012-11-21 00:36:55 +00006594static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006595s390_irgen_MSG(UChar r1, IRTemp op2addr)
6596{
6597 IRTemp op1 = newTemp(Ity_I64);
6598 IRTemp op2 = newTemp(Ity_I64);
6599 IRTemp result = newTemp(Ity_I128);
6600
6601 assign(op1, get_gpr_dw0(r1));
6602 assign(op2, load(Ity_I64, mkexpr(op2addr)));
6603 assign(result, binop(Iop_MullS64, mkexpr(op1), mkexpr(op2)));
6604 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6605
6606 return "msg";
6607}
6608
florian55085f82012-11-21 00:36:55 +00006609static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006610s390_irgen_MSGF(UChar r1, IRTemp op2addr)
6611{
6612 IRTemp op1 = newTemp(Ity_I64);
6613 IRTemp op2 = newTemp(Ity_I32);
6614 IRTemp result = newTemp(Ity_I128);
6615
6616 assign(op1, get_gpr_dw0(r1));
6617 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6618 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_32Sto64, mkexpr(op2))
6619 ));
6620 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6621
6622 return "msgf";
6623}
6624
florian55085f82012-11-21 00:36:55 +00006625static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006626s390_irgen_MSFI(UChar r1, UInt i2)
6627{
6628 IRTemp op1 = newTemp(Ity_I32);
6629 Int op2;
6630 IRTemp result = newTemp(Ity_I64);
6631
6632 assign(op1, get_gpr_w1(r1));
6633 op2 = (Int)i2;
6634 assign(result, binop(Iop_MullS32, mkexpr(op1), mkU32((UInt)op2)));
6635 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6636
6637 return "msfi";
6638}
6639
florian55085f82012-11-21 00:36:55 +00006640static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006641s390_irgen_MSGFI(UChar r1, UInt i2)
6642{
6643 IRTemp op1 = newTemp(Ity_I64);
6644 Int op2;
6645 IRTemp result = newTemp(Ity_I128);
6646
6647 assign(op1, get_gpr_dw0(r1));
6648 op2 = (Int)i2;
6649 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_32Sto64, mkU32((UInt)
6650 op2))));
6651 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6652
6653 return "msgfi";
6654}
6655
florian55085f82012-11-21 00:36:55 +00006656static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006657s390_irgen_OR(UChar r1, UChar r2)
6658{
6659 IRTemp op1 = newTemp(Ity_I32);
6660 IRTemp op2 = newTemp(Ity_I32);
6661 IRTemp result = newTemp(Ity_I32);
6662
6663 assign(op1, get_gpr_w1(r1));
6664 assign(op2, get_gpr_w1(r2));
6665 assign(result, binop(Iop_Or32, mkexpr(op1), mkexpr(op2)));
6666 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6667 put_gpr_w1(r1, mkexpr(result));
6668
6669 return "or";
6670}
6671
florian55085f82012-11-21 00:36:55 +00006672static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006673s390_irgen_OGR(UChar r1, UChar r2)
6674{
6675 IRTemp op1 = newTemp(Ity_I64);
6676 IRTemp op2 = newTemp(Ity_I64);
6677 IRTemp result = newTemp(Ity_I64);
6678
6679 assign(op1, get_gpr_dw0(r1));
6680 assign(op2, get_gpr_dw0(r2));
6681 assign(result, binop(Iop_Or64, mkexpr(op1), mkexpr(op2)));
6682 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6683 put_gpr_dw0(r1, mkexpr(result));
6684
6685 return "ogr";
6686}
6687
florian55085f82012-11-21 00:36:55 +00006688static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006689s390_irgen_ORK(UChar r3, UChar r1, UChar r2)
6690{
6691 IRTemp op2 = newTemp(Ity_I32);
6692 IRTemp op3 = newTemp(Ity_I32);
6693 IRTemp result = newTemp(Ity_I32);
6694
6695 assign(op2, get_gpr_w1(r2));
6696 assign(op3, get_gpr_w1(r3));
6697 assign(result, binop(Iop_Or32, mkexpr(op2), mkexpr(op3)));
6698 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6699 put_gpr_w1(r1, mkexpr(result));
6700
6701 return "ork";
6702}
6703
florian55085f82012-11-21 00:36:55 +00006704static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006705s390_irgen_OGRK(UChar r3, UChar r1, UChar r2)
6706{
6707 IRTemp op2 = newTemp(Ity_I64);
6708 IRTemp op3 = newTemp(Ity_I64);
6709 IRTemp result = newTemp(Ity_I64);
6710
6711 assign(op2, get_gpr_dw0(r2));
6712 assign(op3, get_gpr_dw0(r3));
6713 assign(result, binop(Iop_Or64, mkexpr(op2), mkexpr(op3)));
6714 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6715 put_gpr_dw0(r1, mkexpr(result));
6716
6717 return "ogrk";
6718}
6719
florian55085f82012-11-21 00:36:55 +00006720static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006721s390_irgen_O(UChar r1, IRTemp op2addr)
6722{
6723 IRTemp op1 = newTemp(Ity_I32);
6724 IRTemp op2 = newTemp(Ity_I32);
6725 IRTemp result = newTemp(Ity_I32);
6726
6727 assign(op1, get_gpr_w1(r1));
6728 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6729 assign(result, binop(Iop_Or32, mkexpr(op1), mkexpr(op2)));
6730 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6731 put_gpr_w1(r1, mkexpr(result));
6732
6733 return "o";
6734}
6735
florian55085f82012-11-21 00:36:55 +00006736static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006737s390_irgen_OY(UChar r1, IRTemp op2addr)
6738{
6739 IRTemp op1 = newTemp(Ity_I32);
6740 IRTemp op2 = newTemp(Ity_I32);
6741 IRTemp result = newTemp(Ity_I32);
6742
6743 assign(op1, get_gpr_w1(r1));
6744 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6745 assign(result, binop(Iop_Or32, mkexpr(op1), mkexpr(op2)));
6746 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6747 put_gpr_w1(r1, mkexpr(result));
6748
6749 return "oy";
6750}
6751
florian55085f82012-11-21 00:36:55 +00006752static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006753s390_irgen_OG(UChar r1, IRTemp op2addr)
6754{
6755 IRTemp op1 = newTemp(Ity_I64);
6756 IRTemp op2 = newTemp(Ity_I64);
6757 IRTemp result = newTemp(Ity_I64);
6758
6759 assign(op1, get_gpr_dw0(r1));
6760 assign(op2, load(Ity_I64, mkexpr(op2addr)));
6761 assign(result, binop(Iop_Or64, mkexpr(op1), mkexpr(op2)));
6762 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6763 put_gpr_dw0(r1, mkexpr(result));
6764
6765 return "og";
6766}
6767
florian55085f82012-11-21 00:36:55 +00006768static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006769s390_irgen_OI(UChar i2, IRTemp op1addr)
6770{
6771 IRTemp op1 = newTemp(Ity_I8);
6772 UChar op2;
6773 IRTemp result = newTemp(Ity_I8);
6774
6775 assign(op1, load(Ity_I8, mkexpr(op1addr)));
6776 op2 = i2;
6777 assign(result, binop(Iop_Or8, mkexpr(op1), mkU8(op2)));
6778 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6779 store(mkexpr(op1addr), mkexpr(result));
6780
6781 return "oi";
6782}
6783
florian55085f82012-11-21 00:36:55 +00006784static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006785s390_irgen_OIY(UChar i2, IRTemp op1addr)
6786{
6787 IRTemp op1 = newTemp(Ity_I8);
6788 UChar op2;
6789 IRTemp result = newTemp(Ity_I8);
6790
6791 assign(op1, load(Ity_I8, mkexpr(op1addr)));
6792 op2 = i2;
6793 assign(result, binop(Iop_Or8, mkexpr(op1), mkU8(op2)));
6794 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6795 store(mkexpr(op1addr), mkexpr(result));
6796
6797 return "oiy";
6798}
6799
florian55085f82012-11-21 00:36:55 +00006800static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006801s390_irgen_OIHF(UChar r1, UInt i2)
6802{
6803 IRTemp op1 = newTemp(Ity_I32);
6804 UInt op2;
6805 IRTemp result = newTemp(Ity_I32);
6806
6807 assign(op1, get_gpr_w0(r1));
6808 op2 = i2;
6809 assign(result, binop(Iop_Or32, mkexpr(op1), mkU32(op2)));
6810 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6811 put_gpr_w0(r1, mkexpr(result));
6812
6813 return "oihf";
6814}
6815
florian55085f82012-11-21 00:36:55 +00006816static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006817s390_irgen_OIHH(UChar r1, UShort i2)
6818{
6819 IRTemp op1 = newTemp(Ity_I16);
6820 UShort op2;
6821 IRTemp result = newTemp(Ity_I16);
6822
6823 assign(op1, get_gpr_hw0(r1));
6824 op2 = i2;
6825 assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
6826 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6827 put_gpr_hw0(r1, mkexpr(result));
6828
6829 return "oihh";
6830}
6831
florian55085f82012-11-21 00:36:55 +00006832static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006833s390_irgen_OIHL(UChar r1, UShort i2)
6834{
6835 IRTemp op1 = newTemp(Ity_I16);
6836 UShort op2;
6837 IRTemp result = newTemp(Ity_I16);
6838
6839 assign(op1, get_gpr_hw1(r1));
6840 op2 = i2;
6841 assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
6842 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6843 put_gpr_hw1(r1, mkexpr(result));
6844
6845 return "oihl";
6846}
6847
florian55085f82012-11-21 00:36:55 +00006848static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006849s390_irgen_OILF(UChar r1, UInt i2)
6850{
6851 IRTemp op1 = newTemp(Ity_I32);
6852 UInt op2;
6853 IRTemp result = newTemp(Ity_I32);
6854
6855 assign(op1, get_gpr_w1(r1));
6856 op2 = i2;
6857 assign(result, binop(Iop_Or32, mkexpr(op1), mkU32(op2)));
6858 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6859 put_gpr_w1(r1, mkexpr(result));
6860
6861 return "oilf";
6862}
6863
florian55085f82012-11-21 00:36:55 +00006864static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006865s390_irgen_OILH(UChar r1, UShort i2)
6866{
6867 IRTemp op1 = newTemp(Ity_I16);
6868 UShort op2;
6869 IRTemp result = newTemp(Ity_I16);
6870
6871 assign(op1, get_gpr_hw2(r1));
6872 op2 = i2;
6873 assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
6874 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6875 put_gpr_hw2(r1, mkexpr(result));
6876
6877 return "oilh";
6878}
6879
florian55085f82012-11-21 00:36:55 +00006880static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006881s390_irgen_OILL(UChar r1, UShort i2)
6882{
6883 IRTemp op1 = newTemp(Ity_I16);
6884 UShort op2;
6885 IRTemp result = newTemp(Ity_I16);
6886
6887 assign(op1, get_gpr_hw3(r1));
6888 op2 = i2;
6889 assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
6890 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6891 put_gpr_hw3(r1, mkexpr(result));
6892
6893 return "oill";
6894}
6895
florian55085f82012-11-21 00:36:55 +00006896static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006897s390_irgen_PFD(void)
6898{
6899
6900 return "pfd";
6901}
6902
florian55085f82012-11-21 00:36:55 +00006903static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006904s390_irgen_PFDRL(void)
6905{
6906
6907 return "pfdrl";
6908}
6909
florian55085f82012-11-21 00:36:55 +00006910static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006911s390_irgen_RLL(UChar r1, UChar r3, IRTemp op2addr)
6912{
6913 IRTemp amount = newTemp(Ity_I64);
6914 IRTemp op = newTemp(Ity_I32);
6915
6916 assign(amount, binop(Iop_And64, mkexpr(op2addr), mkU64(31)));
6917 assign(op, get_gpr_w1(r3));
6918 put_gpr_w1(r1, binop(Iop_Or32, binop(Iop_Shl32, mkexpr(op), unop(Iop_64to8,
6919 mkexpr(amount))), binop(Iop_Shr32, mkexpr(op), unop(Iop_64to8,
6920 binop(Iop_Sub64, mkU64(32), mkexpr(amount))))));
6921
6922 return "rll";
6923}
6924
florian55085f82012-11-21 00:36:55 +00006925static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006926s390_irgen_RLLG(UChar r1, UChar r3, IRTemp op2addr)
6927{
6928 IRTemp amount = newTemp(Ity_I64);
6929 IRTemp op = newTemp(Ity_I64);
6930
6931 assign(amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
6932 assign(op, get_gpr_dw0(r3));
6933 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(op), unop(Iop_64to8,
6934 mkexpr(amount))), binop(Iop_Shr64, mkexpr(op), unop(Iop_64to8,
6935 binop(Iop_Sub64, mkU64(64), mkexpr(amount))))));
6936
6937 return "rllg";
6938}
6939
florian55085f82012-11-21 00:36:55 +00006940static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006941s390_irgen_RNSBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
6942{
6943 UChar from;
6944 UChar to;
6945 UChar rot;
6946 UChar t_bit;
6947 ULong mask;
6948 ULong maskc;
6949 IRTemp result = newTemp(Ity_I64);
6950 IRTemp op2 = newTemp(Ity_I64);
6951
6952 from = i3 & 63;
6953 to = i4 & 63;
6954 rot = i5 & 63;
6955 t_bit = i3 & 128;
6956 assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
6957 get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
6958 mkU8(64 - rot))));
6959 if (from <= to) {
6960 mask = ~0ULL;
6961 mask = (mask >> from) & (mask << (63 - to));
6962 maskc = ~mask;
6963 } else {
6964 maskc = ~0ULL;
6965 maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
6966 mask = ~maskc;
6967 }
6968 assign(result, binop(Iop_And64, binop(Iop_And64, get_gpr_dw0(r1), mkexpr(op2)
6969 ), mkU64(mask)));
6970 if (t_bit == 0) {
6971 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
6972 mkU64(maskc)), mkexpr(result)));
6973 }
6974 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6975
6976 return "rnsbg";
6977}
6978
florian55085f82012-11-21 00:36:55 +00006979static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006980s390_irgen_RXSBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
6981{
6982 UChar from;
6983 UChar to;
6984 UChar rot;
6985 UChar t_bit;
6986 ULong mask;
6987 ULong maskc;
6988 IRTemp result = newTemp(Ity_I64);
6989 IRTemp op2 = newTemp(Ity_I64);
6990
6991 from = i3 & 63;
6992 to = i4 & 63;
6993 rot = i5 & 63;
6994 t_bit = i3 & 128;
6995 assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
6996 get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
6997 mkU8(64 - rot))));
6998 if (from <= to) {
6999 mask = ~0ULL;
7000 mask = (mask >> from) & (mask << (63 - to));
7001 maskc = ~mask;
7002 } else {
7003 maskc = ~0ULL;
7004 maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
7005 mask = ~maskc;
7006 }
7007 assign(result, binop(Iop_And64, binop(Iop_Xor64, get_gpr_dw0(r1), mkexpr(op2)
7008 ), mkU64(mask)));
7009 if (t_bit == 0) {
7010 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
7011 mkU64(maskc)), mkexpr(result)));
7012 }
7013 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7014
7015 return "rxsbg";
7016}
7017
florian55085f82012-11-21 00:36:55 +00007018static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007019s390_irgen_ROSBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
7020{
7021 UChar from;
7022 UChar to;
7023 UChar rot;
7024 UChar t_bit;
7025 ULong mask;
7026 ULong maskc;
7027 IRTemp result = newTemp(Ity_I64);
7028 IRTemp op2 = newTemp(Ity_I64);
7029
7030 from = i3 & 63;
7031 to = i4 & 63;
7032 rot = i5 & 63;
7033 t_bit = i3 & 128;
7034 assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
7035 get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
7036 mkU8(64 - rot))));
7037 if (from <= to) {
7038 mask = ~0ULL;
7039 mask = (mask >> from) & (mask << (63 - to));
7040 maskc = ~mask;
7041 } else {
7042 maskc = ~0ULL;
7043 maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
7044 mask = ~maskc;
7045 }
7046 assign(result, binop(Iop_And64, binop(Iop_Or64, get_gpr_dw0(r1), mkexpr(op2)
7047 ), mkU64(mask)));
7048 if (t_bit == 0) {
7049 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
7050 mkU64(maskc)), mkexpr(result)));
7051 }
7052 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7053
7054 return "rosbg";
7055}
7056
florian55085f82012-11-21 00:36:55 +00007057static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007058s390_irgen_RISBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
7059{
7060 UChar from;
7061 UChar to;
7062 UChar rot;
7063 UChar z_bit;
7064 ULong mask;
7065 ULong maskc;
7066 IRTemp op2 = newTemp(Ity_I64);
7067 IRTemp result = newTemp(Ity_I64);
7068
7069 from = i3 & 63;
7070 to = i4 & 63;
7071 rot = i5 & 63;
7072 z_bit = i4 & 128;
7073 assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
7074 get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
7075 mkU8(64 - rot))));
7076 if (from <= to) {
7077 mask = ~0ULL;
7078 mask = (mask >> from) & (mask << (63 - to));
7079 maskc = ~mask;
7080 } else {
7081 maskc = ~0ULL;
7082 maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
7083 mask = ~maskc;
7084 }
7085 if (z_bit == 0) {
7086 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
7087 mkU64(maskc)), binop(Iop_And64, mkexpr(op2), mkU64(mask))));
7088 } else {
7089 put_gpr_dw0(r1, binop(Iop_And64, mkexpr(op2), mkU64(mask)));
7090 }
7091 assign(result, get_gpr_dw0(r1));
7092 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
7093
7094 return "risbg";
7095}
7096
florian55085f82012-11-21 00:36:55 +00007097static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007098s390_irgen_SAR(UChar r1, UChar r2)
7099{
7100 put_ar_w0(r1, get_gpr_w1(r2));
sewardj7ee97522011-05-09 21:45:04 +00007101 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00007102 s390_disasm(ENC3(MNM, AR, GPR), "sar", r1, r2);
7103
7104 return "sar";
7105}
7106
florian55085f82012-11-21 00:36:55 +00007107static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007108s390_irgen_SLDA(UChar r1, IRTemp op2addr)
7109{
7110 IRTemp p1 = newTemp(Ity_I64);
7111 IRTemp p2 = newTemp(Ity_I64);
7112 IRTemp op = newTemp(Ity_I64);
7113 IRTemp result = newTemp(Ity_I64);
florian417b22d2012-07-13 13:41:41 +00007114 ULong sign_mask;
sewardj2019a972011-03-07 16:04:07 +00007115 IRTemp shift_amount = newTemp(Ity_I64);
7116
7117 assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
7118 assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
7119 assign(op, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1), mkU8(32)), mkexpr(p2)
7120 ));
7121 sign_mask = 1ULL << 63;
7122 assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7123 assign(result, binop(Iop_Or64, binop(Iop_And64, binop(Iop_Shl64, mkexpr(op),
florian417b22d2012-07-13 13:41:41 +00007124 unop(Iop_64to8, mkexpr(shift_amount))), mkU64(~sign_mask)),
7125 binop(Iop_And64, mkexpr(op), mkU64(sign_mask))));
sewardj2019a972011-03-07 16:04:07 +00007126 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
7127 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
7128 s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_64, op, shift_amount);
7129
7130 return "slda";
7131}
7132
florian55085f82012-11-21 00:36:55 +00007133static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007134s390_irgen_SLDL(UChar r1, IRTemp op2addr)
7135{
7136 IRTemp p1 = newTemp(Ity_I64);
7137 IRTemp p2 = newTemp(Ity_I64);
7138 IRTemp result = newTemp(Ity_I64);
7139
7140 assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
7141 assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
7142 assign(result, binop(Iop_Shl64, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1),
7143 mkU8(32)), mkexpr(p2)), unop(Iop_64to8, binop(Iop_And64,
7144 mkexpr(op2addr), mkU64(63)))));
7145 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
7146 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
7147
7148 return "sldl";
7149}
7150
florian55085f82012-11-21 00:36:55 +00007151static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007152s390_irgen_SLA(UChar r1, IRTemp op2addr)
7153{
7154 IRTemp uop = newTemp(Ity_I32);
7155 IRTemp result = newTemp(Ity_I32);
7156 UInt sign_mask;
7157 IRTemp shift_amount = newTemp(Ity_I64);
7158 IRTemp op = newTemp(Ity_I32);
7159
7160 assign(op, get_gpr_w1(r1));
7161 assign(uop, get_gpr_w1(r1));
7162 sign_mask = 2147483648U;
7163 assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7164 assign(result, binop(Iop_Or32, binop(Iop_And32, binop(Iop_Shl32, mkexpr(uop),
7165 unop(Iop_64to8, mkexpr(shift_amount))), mkU32(~sign_mask)),
7166 binop(Iop_And32, mkexpr(uop), mkU32(sign_mask))));
7167 put_gpr_w1(r1, mkexpr(result));
7168 s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_32, op, shift_amount);
7169
7170 return "sla";
7171}
7172
florian55085f82012-11-21 00:36:55 +00007173static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007174s390_irgen_SLAK(UChar r1, UChar r3, IRTemp op2addr)
7175{
7176 IRTemp uop = newTemp(Ity_I32);
7177 IRTemp result = newTemp(Ity_I32);
7178 UInt sign_mask;
7179 IRTemp shift_amount = newTemp(Ity_I64);
7180 IRTemp op = newTemp(Ity_I32);
7181
7182 assign(op, get_gpr_w1(r3));
7183 assign(uop, get_gpr_w1(r3));
7184 sign_mask = 2147483648U;
7185 assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7186 assign(result, binop(Iop_Or32, binop(Iop_And32, binop(Iop_Shl32, mkexpr(uop),
7187 unop(Iop_64to8, mkexpr(shift_amount))), mkU32(~sign_mask)),
7188 binop(Iop_And32, mkexpr(uop), mkU32(sign_mask))));
7189 put_gpr_w1(r1, mkexpr(result));
7190 s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_32, op, shift_amount);
7191
7192 return "slak";
7193}
7194
florian55085f82012-11-21 00:36:55 +00007195static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007196s390_irgen_SLAG(UChar r1, UChar r3, IRTemp op2addr)
7197{
7198 IRTemp uop = newTemp(Ity_I64);
7199 IRTemp result = newTemp(Ity_I64);
7200 ULong sign_mask;
7201 IRTemp shift_amount = newTemp(Ity_I64);
7202 IRTemp op = newTemp(Ity_I64);
7203
7204 assign(op, get_gpr_dw0(r3));
7205 assign(uop, get_gpr_dw0(r3));
7206 sign_mask = 9223372036854775808ULL;
7207 assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7208 assign(result, binop(Iop_Or64, binop(Iop_And64, binop(Iop_Shl64, mkexpr(uop),
7209 unop(Iop_64to8, mkexpr(shift_amount))), mkU64(~sign_mask)),
7210 binop(Iop_And64, mkexpr(uop), mkU64(sign_mask))));
7211 put_gpr_dw0(r1, mkexpr(result));
7212 s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_64, op, shift_amount);
7213
7214 return "slag";
7215}
7216
florian55085f82012-11-21 00:36:55 +00007217static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007218s390_irgen_SLL(UChar r1, IRTemp op2addr)
7219{
7220 put_gpr_w1(r1, binop(Iop_Shl32, get_gpr_w1(r1), unop(Iop_64to8,
7221 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
7222
7223 return "sll";
7224}
7225
florian55085f82012-11-21 00:36:55 +00007226static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007227s390_irgen_SLLK(UChar r1, UChar r3, IRTemp op2addr)
7228{
7229 put_gpr_w1(r1, binop(Iop_Shl32, get_gpr_w1(r3), unop(Iop_64to8,
7230 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
7231
7232 return "sllk";
7233}
7234
florian55085f82012-11-21 00:36:55 +00007235static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007236s390_irgen_SLLG(UChar r1, UChar r3, IRTemp op2addr)
7237{
7238 put_gpr_dw0(r1, binop(Iop_Shl64, get_gpr_dw0(r3), unop(Iop_64to8,
7239 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
7240
7241 return "sllg";
7242}
7243
florian55085f82012-11-21 00:36:55 +00007244static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007245s390_irgen_SRDA(UChar r1, IRTemp op2addr)
7246{
7247 IRTemp p1 = newTemp(Ity_I64);
7248 IRTemp p2 = newTemp(Ity_I64);
7249 IRTemp result = newTemp(Ity_I64);
7250
7251 assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
7252 assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
7253 assign(result, binop(Iop_Sar64, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1),
7254 mkU8(32)), mkexpr(p2)), unop(Iop_64to8, binop(Iop_And64,
7255 mkexpr(op2addr), mkU64(63)))));
7256 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
7257 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
7258 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7259
7260 return "srda";
7261}
7262
florian55085f82012-11-21 00:36:55 +00007263static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007264s390_irgen_SRDL(UChar r1, IRTemp op2addr)
7265{
7266 IRTemp p1 = newTemp(Ity_I64);
7267 IRTemp p2 = newTemp(Ity_I64);
7268 IRTemp result = newTemp(Ity_I64);
7269
7270 assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
7271 assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
7272 assign(result, binop(Iop_Shr64, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1),
7273 mkU8(32)), mkexpr(p2)), unop(Iop_64to8, binop(Iop_And64,
7274 mkexpr(op2addr), mkU64(63)))));
7275 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
7276 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
7277
7278 return "srdl";
7279}
7280
florian55085f82012-11-21 00:36:55 +00007281static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007282s390_irgen_SRA(UChar r1, IRTemp op2addr)
7283{
7284 IRTemp result = newTemp(Ity_I32);
7285 IRTemp op = newTemp(Ity_I32);
7286
7287 assign(op, get_gpr_w1(r1));
7288 assign(result, binop(Iop_Sar32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7289 mkexpr(op2addr), mkU64(63)))));
7290 put_gpr_w1(r1, mkexpr(result));
7291 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7292
7293 return "sra";
7294}
7295
florian55085f82012-11-21 00:36:55 +00007296static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007297s390_irgen_SRAK(UChar r1, UChar r3, IRTemp op2addr)
7298{
7299 IRTemp result = newTemp(Ity_I32);
7300 IRTemp op = newTemp(Ity_I32);
7301
7302 assign(op, get_gpr_w1(r3));
7303 assign(result, binop(Iop_Sar32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7304 mkexpr(op2addr), mkU64(63)))));
7305 put_gpr_w1(r1, mkexpr(result));
7306 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7307
7308 return "srak";
7309}
7310
florian55085f82012-11-21 00:36:55 +00007311static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007312s390_irgen_SRAG(UChar r1, UChar r3, IRTemp op2addr)
7313{
7314 IRTemp result = newTemp(Ity_I64);
7315 IRTemp op = newTemp(Ity_I64);
7316
7317 assign(op, get_gpr_dw0(r3));
7318 assign(result, binop(Iop_Sar64, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7319 mkexpr(op2addr), mkU64(63)))));
7320 put_gpr_dw0(r1, mkexpr(result));
7321 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7322
7323 return "srag";
7324}
7325
florian55085f82012-11-21 00:36:55 +00007326static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007327s390_irgen_SRL(UChar r1, IRTemp op2addr)
7328{
7329 IRTemp op = newTemp(Ity_I32);
7330
7331 assign(op, get_gpr_w1(r1));
7332 put_gpr_w1(r1, binop(Iop_Shr32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7333 mkexpr(op2addr), mkU64(63)))));
7334
7335 return "srl";
7336}
7337
florian55085f82012-11-21 00:36:55 +00007338static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007339s390_irgen_SRLK(UChar r1, UChar r3, IRTemp op2addr)
7340{
7341 IRTemp op = newTemp(Ity_I32);
7342
7343 assign(op, get_gpr_w1(r3));
7344 put_gpr_w1(r1, binop(Iop_Shr32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7345 mkexpr(op2addr), mkU64(63)))));
7346
7347 return "srlk";
7348}
7349
florian55085f82012-11-21 00:36:55 +00007350static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007351s390_irgen_SRLG(UChar r1, UChar r3, IRTemp op2addr)
7352{
7353 IRTemp op = newTemp(Ity_I64);
7354
7355 assign(op, get_gpr_dw0(r3));
7356 put_gpr_dw0(r1, binop(Iop_Shr64, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7357 mkexpr(op2addr), mkU64(63)))));
7358
7359 return "srlg";
7360}
7361
florian55085f82012-11-21 00:36:55 +00007362static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007363s390_irgen_ST(UChar r1, IRTemp op2addr)
7364{
7365 store(mkexpr(op2addr), get_gpr_w1(r1));
7366
7367 return "st";
7368}
7369
florian55085f82012-11-21 00:36:55 +00007370static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007371s390_irgen_STY(UChar r1, IRTemp op2addr)
7372{
7373 store(mkexpr(op2addr), get_gpr_w1(r1));
7374
7375 return "sty";
7376}
7377
florian55085f82012-11-21 00:36:55 +00007378static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007379s390_irgen_STG(UChar r1, IRTemp op2addr)
7380{
7381 store(mkexpr(op2addr), get_gpr_dw0(r1));
7382
7383 return "stg";
7384}
7385
florian55085f82012-11-21 00:36:55 +00007386static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007387s390_irgen_STRL(UChar r1, UInt i2)
7388{
7389 store(mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)),
7390 get_gpr_w1(r1));
7391
7392 return "strl";
7393}
7394
florian55085f82012-11-21 00:36:55 +00007395static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007396s390_irgen_STGRL(UChar r1, UInt i2)
7397{
7398 store(mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)),
7399 get_gpr_dw0(r1));
7400
7401 return "stgrl";
7402}
7403
florian55085f82012-11-21 00:36:55 +00007404static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007405s390_irgen_STC(UChar r1, IRTemp op2addr)
7406{
7407 store(mkexpr(op2addr), get_gpr_b7(r1));
7408
7409 return "stc";
7410}
7411
florian55085f82012-11-21 00:36:55 +00007412static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007413s390_irgen_STCY(UChar r1, IRTemp op2addr)
7414{
7415 store(mkexpr(op2addr), get_gpr_b7(r1));
7416
7417 return "stcy";
7418}
7419
florian55085f82012-11-21 00:36:55 +00007420static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007421s390_irgen_STCH(UChar r1, IRTemp op2addr)
7422{
7423 store(mkexpr(op2addr), get_gpr_b3(r1));
7424
7425 return "stch";
7426}
7427
florian55085f82012-11-21 00:36:55 +00007428static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007429s390_irgen_STCM(UChar r1, UChar r3, IRTemp op2addr)
7430{
7431 UChar mask;
7432 UChar n;
7433
7434 mask = (UChar)r3;
7435 n = 0;
7436 if ((mask & 8) != 0) {
7437 store(mkexpr(op2addr), get_gpr_b4(r1));
7438 n = n + 1;
7439 }
7440 if ((mask & 4) != 0) {
7441 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b5(r1));
7442 n = n + 1;
7443 }
7444 if ((mask & 2) != 0) {
7445 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b6(r1));
7446 n = n + 1;
7447 }
7448 if ((mask & 1) != 0) {
7449 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b7(r1));
7450 }
7451
7452 return "stcm";
7453}
7454
florian55085f82012-11-21 00:36:55 +00007455static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007456s390_irgen_STCMY(UChar r1, UChar r3, IRTemp op2addr)
7457{
7458 UChar mask;
7459 UChar n;
7460
7461 mask = (UChar)r3;
7462 n = 0;
7463 if ((mask & 8) != 0) {
7464 store(mkexpr(op2addr), get_gpr_b4(r1));
7465 n = n + 1;
7466 }
7467 if ((mask & 4) != 0) {
7468 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b5(r1));
7469 n = n + 1;
7470 }
7471 if ((mask & 2) != 0) {
7472 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b6(r1));
7473 n = n + 1;
7474 }
7475 if ((mask & 1) != 0) {
7476 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b7(r1));
7477 }
7478
7479 return "stcmy";
7480}
7481
florian55085f82012-11-21 00:36:55 +00007482static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007483s390_irgen_STCMH(UChar r1, UChar r3, IRTemp op2addr)
7484{
7485 UChar mask;
7486 UChar n;
7487
7488 mask = (UChar)r3;
7489 n = 0;
7490 if ((mask & 8) != 0) {
7491 store(mkexpr(op2addr), get_gpr_b0(r1));
7492 n = n + 1;
7493 }
7494 if ((mask & 4) != 0) {
7495 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b1(r1));
7496 n = n + 1;
7497 }
7498 if ((mask & 2) != 0) {
7499 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b2(r1));
7500 n = n + 1;
7501 }
7502 if ((mask & 1) != 0) {
7503 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b3(r1));
7504 }
7505
7506 return "stcmh";
7507}
7508
florian55085f82012-11-21 00:36:55 +00007509static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007510s390_irgen_STH(UChar r1, IRTemp op2addr)
7511{
7512 store(mkexpr(op2addr), get_gpr_hw3(r1));
7513
7514 return "sth";
7515}
7516
florian55085f82012-11-21 00:36:55 +00007517static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007518s390_irgen_STHY(UChar r1, IRTemp op2addr)
7519{
7520 store(mkexpr(op2addr), get_gpr_hw3(r1));
7521
7522 return "sthy";
7523}
7524
florian55085f82012-11-21 00:36:55 +00007525static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007526s390_irgen_STHRL(UChar r1, UInt i2)
7527{
7528 store(mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)),
7529 get_gpr_hw3(r1));
7530
7531 return "sthrl";
7532}
7533
florian55085f82012-11-21 00:36:55 +00007534static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007535s390_irgen_STHH(UChar r1, IRTemp op2addr)
7536{
7537 store(mkexpr(op2addr), get_gpr_hw1(r1));
7538
7539 return "sthh";
7540}
7541
florian55085f82012-11-21 00:36:55 +00007542static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007543s390_irgen_STFH(UChar r1, IRTemp op2addr)
7544{
7545 store(mkexpr(op2addr), get_gpr_w0(r1));
7546
7547 return "stfh";
7548}
7549
florian55085f82012-11-21 00:36:55 +00007550static const HChar *
sewardjd7bde722011-04-05 13:19:33 +00007551s390_irgen_STOC(UChar r1, IRTemp op2addr)
7552{
7553 /* condition is checked in format handler */
7554 store(mkexpr(op2addr), get_gpr_w1(r1));
7555
7556 return "stoc";
7557}
7558
florian55085f82012-11-21 00:36:55 +00007559static const HChar *
sewardjd7bde722011-04-05 13:19:33 +00007560s390_irgen_STOCG(UChar r1, IRTemp op2addr)
7561{
7562 /* condition is checked in format handler */
7563 store(mkexpr(op2addr), get_gpr_dw0(r1));
7564
7565 return "stocg";
7566}
7567
florian55085f82012-11-21 00:36:55 +00007568static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007569s390_irgen_STPQ(UChar r1, IRTemp op2addr)
7570{
7571 store(mkexpr(op2addr), get_gpr_dw0(r1));
7572 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(8)), get_gpr_dw0(r1 + 1));
7573
7574 return "stpq";
7575}
7576
florian55085f82012-11-21 00:36:55 +00007577static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007578s390_irgen_STRVH(UChar r1, IRTemp op2addr)
7579{
7580 store(mkexpr(op2addr), get_gpr_b7(r1));
7581 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(1)), get_gpr_b6(r1));
7582
7583 return "strvh";
7584}
7585
florian55085f82012-11-21 00:36:55 +00007586static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007587s390_irgen_STRV(UChar r1, IRTemp op2addr)
7588{
7589 store(mkexpr(op2addr), get_gpr_b7(r1));
7590 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(1)), get_gpr_b6(r1));
7591 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(2)), get_gpr_b5(r1));
7592 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(3)), get_gpr_b4(r1));
7593
7594 return "strv";
7595}
7596
florian55085f82012-11-21 00:36:55 +00007597static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007598s390_irgen_STRVG(UChar r1, IRTemp op2addr)
7599{
7600 store(mkexpr(op2addr), get_gpr_b7(r1));
7601 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(1)), get_gpr_b6(r1));
7602 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(2)), get_gpr_b5(r1));
7603 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(3)), get_gpr_b4(r1));
7604 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(4)), get_gpr_b3(r1));
7605 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(5)), get_gpr_b2(r1));
7606 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(6)), get_gpr_b1(r1));
7607 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(7)), get_gpr_b0(r1));
7608
7609 return "strvg";
7610}
7611
florian55085f82012-11-21 00:36:55 +00007612static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007613s390_irgen_SR(UChar r1, UChar r2)
7614{
7615 IRTemp op1 = newTemp(Ity_I32);
7616 IRTemp op2 = newTemp(Ity_I32);
7617 IRTemp result = newTemp(Ity_I32);
7618
7619 assign(op1, get_gpr_w1(r1));
7620 assign(op2, get_gpr_w1(r2));
7621 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7622 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
7623 put_gpr_w1(r1, mkexpr(result));
7624
7625 return "sr";
7626}
7627
florian55085f82012-11-21 00:36:55 +00007628static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007629s390_irgen_SGR(UChar r1, UChar r2)
7630{
7631 IRTemp op1 = newTemp(Ity_I64);
7632 IRTemp op2 = newTemp(Ity_I64);
7633 IRTemp result = newTemp(Ity_I64);
7634
7635 assign(op1, get_gpr_dw0(r1));
7636 assign(op2, get_gpr_dw0(r2));
7637 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7638 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
7639 put_gpr_dw0(r1, mkexpr(result));
7640
7641 return "sgr";
7642}
7643
florian55085f82012-11-21 00:36:55 +00007644static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007645s390_irgen_SGFR(UChar r1, UChar r2)
7646{
7647 IRTemp op1 = newTemp(Ity_I64);
7648 IRTemp op2 = newTemp(Ity_I64);
7649 IRTemp result = newTemp(Ity_I64);
7650
7651 assign(op1, get_gpr_dw0(r1));
7652 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
7653 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7654 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
7655 put_gpr_dw0(r1, mkexpr(result));
7656
7657 return "sgfr";
7658}
7659
florian55085f82012-11-21 00:36:55 +00007660static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007661s390_irgen_SRK(UChar r3, UChar r1, UChar r2)
7662{
7663 IRTemp op2 = newTemp(Ity_I32);
7664 IRTemp op3 = newTemp(Ity_I32);
7665 IRTemp result = newTemp(Ity_I32);
7666
7667 assign(op2, get_gpr_w1(r2));
7668 assign(op3, get_gpr_w1(r3));
7669 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
7670 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op2, op3);
7671 put_gpr_w1(r1, mkexpr(result));
7672
7673 return "srk";
7674}
7675
florian55085f82012-11-21 00:36:55 +00007676static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007677s390_irgen_SGRK(UChar r3, UChar r1, UChar r2)
7678{
7679 IRTemp op2 = newTemp(Ity_I64);
7680 IRTemp op3 = newTemp(Ity_I64);
7681 IRTemp result = newTemp(Ity_I64);
7682
7683 assign(op2, get_gpr_dw0(r2));
7684 assign(op3, get_gpr_dw0(r3));
7685 assign(result, binop(Iop_Sub64, mkexpr(op2), mkexpr(op3)));
7686 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op2, op3);
7687 put_gpr_dw0(r1, mkexpr(result));
7688
7689 return "sgrk";
7690}
7691
florian55085f82012-11-21 00:36:55 +00007692static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007693s390_irgen_S(UChar r1, IRTemp op2addr)
7694{
7695 IRTemp op1 = newTemp(Ity_I32);
7696 IRTemp op2 = newTemp(Ity_I32);
7697 IRTemp result = newTemp(Ity_I32);
7698
7699 assign(op1, get_gpr_w1(r1));
7700 assign(op2, load(Ity_I32, mkexpr(op2addr)));
7701 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7702 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
7703 put_gpr_w1(r1, mkexpr(result));
7704
7705 return "s";
7706}
7707
florian55085f82012-11-21 00:36:55 +00007708static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007709s390_irgen_SY(UChar r1, IRTemp op2addr)
7710{
7711 IRTemp op1 = newTemp(Ity_I32);
7712 IRTemp op2 = newTemp(Ity_I32);
7713 IRTemp result = newTemp(Ity_I32);
7714
7715 assign(op1, get_gpr_w1(r1));
7716 assign(op2, load(Ity_I32, mkexpr(op2addr)));
7717 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7718 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
7719 put_gpr_w1(r1, mkexpr(result));
7720
7721 return "sy";
7722}
7723
florian55085f82012-11-21 00:36:55 +00007724static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007725s390_irgen_SG(UChar r1, IRTemp op2addr)
7726{
7727 IRTemp op1 = newTemp(Ity_I64);
7728 IRTemp op2 = newTemp(Ity_I64);
7729 IRTemp result = newTemp(Ity_I64);
7730
7731 assign(op1, get_gpr_dw0(r1));
7732 assign(op2, load(Ity_I64, mkexpr(op2addr)));
7733 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7734 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
7735 put_gpr_dw0(r1, mkexpr(result));
7736
7737 return "sg";
7738}
7739
florian55085f82012-11-21 00:36:55 +00007740static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007741s390_irgen_SGF(UChar r1, IRTemp op2addr)
7742{
7743 IRTemp op1 = newTemp(Ity_I64);
7744 IRTemp op2 = newTemp(Ity_I64);
7745 IRTemp result = newTemp(Ity_I64);
7746
7747 assign(op1, get_gpr_dw0(r1));
7748 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
7749 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7750 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
7751 put_gpr_dw0(r1, mkexpr(result));
7752
7753 return "sgf";
7754}
7755
florian55085f82012-11-21 00:36:55 +00007756static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007757s390_irgen_SH(UChar r1, IRTemp op2addr)
7758{
7759 IRTemp op1 = newTemp(Ity_I32);
7760 IRTemp op2 = newTemp(Ity_I32);
7761 IRTemp result = newTemp(Ity_I32);
7762
7763 assign(op1, get_gpr_w1(r1));
7764 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
7765 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7766 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
7767 put_gpr_w1(r1, mkexpr(result));
7768
7769 return "sh";
7770}
7771
florian55085f82012-11-21 00:36:55 +00007772static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007773s390_irgen_SHY(UChar r1, IRTemp op2addr)
7774{
7775 IRTemp op1 = newTemp(Ity_I32);
7776 IRTemp op2 = newTemp(Ity_I32);
7777 IRTemp result = newTemp(Ity_I32);
7778
7779 assign(op1, get_gpr_w1(r1));
7780 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
7781 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7782 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
7783 put_gpr_w1(r1, mkexpr(result));
7784
7785 return "shy";
7786}
7787
florian55085f82012-11-21 00:36:55 +00007788static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007789s390_irgen_SHHHR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
7790{
7791 IRTemp op2 = newTemp(Ity_I32);
7792 IRTemp op3 = newTemp(Ity_I32);
7793 IRTemp result = newTemp(Ity_I32);
7794
7795 assign(op2, get_gpr_w0(r1));
7796 assign(op3, get_gpr_w0(r2));
7797 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
7798 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op2, op3);
7799 put_gpr_w0(r1, mkexpr(result));
7800
7801 return "shhhr";
7802}
7803
florian55085f82012-11-21 00:36:55 +00007804static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007805s390_irgen_SHHLR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
7806{
7807 IRTemp op2 = newTemp(Ity_I32);
7808 IRTemp op3 = newTemp(Ity_I32);
7809 IRTemp result = newTemp(Ity_I32);
7810
7811 assign(op2, get_gpr_w0(r1));
7812 assign(op3, get_gpr_w1(r2));
7813 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
7814 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op2, op3);
7815 put_gpr_w0(r1, mkexpr(result));
7816
7817 return "shhlr";
7818}
7819
florian55085f82012-11-21 00:36:55 +00007820static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007821s390_irgen_SLR(UChar r1, UChar r2)
7822{
7823 IRTemp op1 = newTemp(Ity_I32);
7824 IRTemp op2 = newTemp(Ity_I32);
7825 IRTemp result = newTemp(Ity_I32);
7826
7827 assign(op1, get_gpr_w1(r1));
7828 assign(op2, get_gpr_w1(r2));
7829 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7830 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, op2);
7831 put_gpr_w1(r1, mkexpr(result));
7832
7833 return "slr";
7834}
7835
florian55085f82012-11-21 00:36:55 +00007836static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007837s390_irgen_SLGR(UChar r1, UChar r2)
7838{
7839 IRTemp op1 = newTemp(Ity_I64);
7840 IRTemp op2 = newTemp(Ity_I64);
7841 IRTemp result = newTemp(Ity_I64);
7842
7843 assign(op1, get_gpr_dw0(r1));
7844 assign(op2, get_gpr_dw0(r2));
7845 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7846 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
7847 put_gpr_dw0(r1, mkexpr(result));
7848
7849 return "slgr";
7850}
7851
florian55085f82012-11-21 00:36:55 +00007852static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007853s390_irgen_SLGFR(UChar r1, UChar r2)
7854{
7855 IRTemp op1 = newTemp(Ity_I64);
7856 IRTemp op2 = newTemp(Ity_I64);
7857 IRTemp result = newTemp(Ity_I64);
7858
7859 assign(op1, get_gpr_dw0(r1));
7860 assign(op2, unop(Iop_32Uto64, get_gpr_w1(r2)));
7861 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7862 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
7863 put_gpr_dw0(r1, mkexpr(result));
7864
7865 return "slgfr";
7866}
7867
florian55085f82012-11-21 00:36:55 +00007868static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007869s390_irgen_SLRK(UChar r3, UChar r1, UChar r2)
7870{
7871 IRTemp op2 = newTemp(Ity_I32);
7872 IRTemp op3 = newTemp(Ity_I32);
7873 IRTemp result = newTemp(Ity_I32);
7874
7875 assign(op2, get_gpr_w1(r2));
7876 assign(op3, get_gpr_w1(r3));
7877 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
7878 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op2, op3);
7879 put_gpr_w1(r1, mkexpr(result));
7880
7881 return "slrk";
7882}
7883
florian55085f82012-11-21 00:36:55 +00007884static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007885s390_irgen_SLGRK(UChar r3, UChar r1, UChar r2)
7886{
7887 IRTemp op2 = newTemp(Ity_I64);
7888 IRTemp op3 = newTemp(Ity_I64);
7889 IRTemp result = newTemp(Ity_I64);
7890
7891 assign(op2, get_gpr_dw0(r2));
7892 assign(op3, get_gpr_dw0(r3));
7893 assign(result, binop(Iop_Sub64, mkexpr(op2), mkexpr(op3)));
7894 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op2, op3);
7895 put_gpr_dw0(r1, mkexpr(result));
7896
7897 return "slgrk";
7898}
7899
florian55085f82012-11-21 00:36:55 +00007900static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007901s390_irgen_SL(UChar r1, IRTemp op2addr)
7902{
7903 IRTemp op1 = newTemp(Ity_I32);
7904 IRTemp op2 = newTemp(Ity_I32);
7905 IRTemp result = newTemp(Ity_I32);
7906
7907 assign(op1, get_gpr_w1(r1));
7908 assign(op2, load(Ity_I32, mkexpr(op2addr)));
7909 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7910 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, op2);
7911 put_gpr_w1(r1, mkexpr(result));
7912
7913 return "sl";
7914}
7915
florian55085f82012-11-21 00:36:55 +00007916static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007917s390_irgen_SLY(UChar r1, IRTemp op2addr)
7918{
7919 IRTemp op1 = newTemp(Ity_I32);
7920 IRTemp op2 = newTemp(Ity_I32);
7921 IRTemp result = newTemp(Ity_I32);
7922
7923 assign(op1, get_gpr_w1(r1));
7924 assign(op2, load(Ity_I32, mkexpr(op2addr)));
7925 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7926 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, op2);
7927 put_gpr_w1(r1, mkexpr(result));
7928
7929 return "sly";
7930}
7931
florian55085f82012-11-21 00:36:55 +00007932static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007933s390_irgen_SLG(UChar r1, IRTemp op2addr)
7934{
7935 IRTemp op1 = newTemp(Ity_I64);
7936 IRTemp op2 = newTemp(Ity_I64);
7937 IRTemp result = newTemp(Ity_I64);
7938
7939 assign(op1, get_gpr_dw0(r1));
7940 assign(op2, load(Ity_I64, mkexpr(op2addr)));
7941 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7942 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
7943 put_gpr_dw0(r1, mkexpr(result));
7944
7945 return "slg";
7946}
7947
florian55085f82012-11-21 00:36:55 +00007948static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007949s390_irgen_SLGF(UChar r1, IRTemp op2addr)
7950{
7951 IRTemp op1 = newTemp(Ity_I64);
7952 IRTemp op2 = newTemp(Ity_I64);
7953 IRTemp result = newTemp(Ity_I64);
7954
7955 assign(op1, get_gpr_dw0(r1));
7956 assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
7957 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7958 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
7959 put_gpr_dw0(r1, mkexpr(result));
7960
7961 return "slgf";
7962}
7963
florian55085f82012-11-21 00:36:55 +00007964static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007965s390_irgen_SLFI(UChar r1, UInt i2)
7966{
7967 IRTemp op1 = newTemp(Ity_I32);
7968 UInt op2;
7969 IRTemp result = newTemp(Ity_I32);
7970
7971 assign(op1, get_gpr_w1(r1));
7972 op2 = i2;
7973 assign(result, binop(Iop_Sub32, mkexpr(op1), mkU32(op2)));
7974 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, mktemp(Ity_I32,
7975 mkU32(op2)));
7976 put_gpr_w1(r1, mkexpr(result));
7977
7978 return "slfi";
7979}
7980
florian55085f82012-11-21 00:36:55 +00007981static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007982s390_irgen_SLGFI(UChar r1, UInt i2)
7983{
7984 IRTemp op1 = newTemp(Ity_I64);
7985 ULong op2;
7986 IRTemp result = newTemp(Ity_I64);
7987
7988 assign(op1, get_gpr_dw0(r1));
7989 op2 = (ULong)i2;
7990 assign(result, binop(Iop_Sub64, mkexpr(op1), mkU64(op2)));
7991 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, mktemp(Ity_I64,
7992 mkU64(op2)));
7993 put_gpr_dw0(r1, mkexpr(result));
7994
7995 return "slgfi";
7996}
7997
florian55085f82012-11-21 00:36:55 +00007998static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007999s390_irgen_SLHHHR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
8000{
8001 IRTemp op2 = newTemp(Ity_I32);
8002 IRTemp op3 = newTemp(Ity_I32);
8003 IRTemp result = newTemp(Ity_I32);
8004
8005 assign(op2, get_gpr_w0(r1));
8006 assign(op3, get_gpr_w0(r2));
8007 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
8008 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op2, op3);
8009 put_gpr_w0(r1, mkexpr(result));
8010
8011 return "slhhhr";
8012}
8013
florian55085f82012-11-21 00:36:55 +00008014static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008015s390_irgen_SLHHLR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
8016{
8017 IRTemp op2 = newTemp(Ity_I32);
8018 IRTemp op3 = newTemp(Ity_I32);
8019 IRTemp result = newTemp(Ity_I32);
8020
8021 assign(op2, get_gpr_w0(r1));
8022 assign(op3, get_gpr_w1(r2));
8023 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
8024 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op2, op3);
8025 put_gpr_w0(r1, mkexpr(result));
8026
8027 return "slhhlr";
8028}
8029
florian55085f82012-11-21 00:36:55 +00008030static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008031s390_irgen_SLBR(UChar r1, UChar r2)
8032{
8033 IRTemp op1 = newTemp(Ity_I32);
8034 IRTemp op2 = newTemp(Ity_I32);
8035 IRTemp result = newTemp(Ity_I32);
8036 IRTemp borrow_in = newTemp(Ity_I32);
8037
8038 assign(op1, get_gpr_w1(r1));
8039 assign(op2, get_gpr_w1(r2));
8040 assign(borrow_in, binop(Iop_Sub32, mkU32(1), binop(Iop_Shr32,
8041 s390_call_calculate_cc(), mkU8(1))));
8042 assign(result, binop(Iop_Sub32, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)),
8043 mkexpr(borrow_in)));
8044 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_32, op1, op2, borrow_in);
8045 put_gpr_w1(r1, mkexpr(result));
8046
8047 return "slbr";
8048}
8049
florian55085f82012-11-21 00:36:55 +00008050static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008051s390_irgen_SLBGR(UChar r1, UChar r2)
8052{
8053 IRTemp op1 = newTemp(Ity_I64);
8054 IRTemp op2 = newTemp(Ity_I64);
8055 IRTemp result = newTemp(Ity_I64);
8056 IRTemp borrow_in = newTemp(Ity_I64);
8057
8058 assign(op1, get_gpr_dw0(r1));
8059 assign(op2, get_gpr_dw0(r2));
8060 assign(borrow_in, unop(Iop_32Uto64, binop(Iop_Sub32, mkU32(1),
8061 binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)))));
8062 assign(result, binop(Iop_Sub64, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)),
8063 mkexpr(borrow_in)));
8064 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_64, op1, op2, borrow_in);
8065 put_gpr_dw0(r1, mkexpr(result));
8066
8067 return "slbgr";
8068}
8069
florian55085f82012-11-21 00:36:55 +00008070static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008071s390_irgen_SLB(UChar r1, IRTemp op2addr)
8072{
8073 IRTemp op1 = newTemp(Ity_I32);
8074 IRTemp op2 = newTemp(Ity_I32);
8075 IRTemp result = newTemp(Ity_I32);
8076 IRTemp borrow_in = newTemp(Ity_I32);
8077
8078 assign(op1, get_gpr_w1(r1));
8079 assign(op2, load(Ity_I32, mkexpr(op2addr)));
8080 assign(borrow_in, binop(Iop_Sub32, mkU32(1), binop(Iop_Shr32,
8081 s390_call_calculate_cc(), mkU8(1))));
8082 assign(result, binop(Iop_Sub32, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)),
8083 mkexpr(borrow_in)));
8084 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_32, op1, op2, borrow_in);
8085 put_gpr_w1(r1, mkexpr(result));
8086
8087 return "slb";
8088}
8089
florian55085f82012-11-21 00:36:55 +00008090static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008091s390_irgen_SLBG(UChar r1, IRTemp op2addr)
8092{
8093 IRTemp op1 = newTemp(Ity_I64);
8094 IRTemp op2 = newTemp(Ity_I64);
8095 IRTemp result = newTemp(Ity_I64);
8096 IRTemp borrow_in = newTemp(Ity_I64);
8097
8098 assign(op1, get_gpr_dw0(r1));
8099 assign(op2, load(Ity_I64, mkexpr(op2addr)));
8100 assign(borrow_in, unop(Iop_32Uto64, binop(Iop_Sub32, mkU32(1),
8101 binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)))));
8102 assign(result, binop(Iop_Sub64, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)),
8103 mkexpr(borrow_in)));
8104 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_64, op1, op2, borrow_in);
8105 put_gpr_dw0(r1, mkexpr(result));
8106
8107 return "slbg";
8108}
8109
florian55085f82012-11-21 00:36:55 +00008110static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008111s390_irgen_SVC(UChar i)
8112{
8113 IRTemp sysno = newTemp(Ity_I64);
8114
8115 if (i != 0) {
8116 assign(sysno, mkU64(i));
8117 } else {
8118 assign(sysno, unop(Iop_32Uto64, get_gpr_w1(1)));
8119 }
8120 system_call(mkexpr(sysno));
8121
8122 return "svc";
8123}
8124
florian55085f82012-11-21 00:36:55 +00008125static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008126s390_irgen_TM(UChar i2, IRTemp op1addr)
8127{
8128 UChar mask;
8129 IRTemp value = newTemp(Ity_I8);
8130
8131 mask = i2;
8132 assign(value, load(Ity_I8, mkexpr(op1addr)));
8133 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_8, value, mktemp(Ity_I8,
8134 mkU8(mask)));
8135
8136 return "tm";
8137}
8138
florian55085f82012-11-21 00:36:55 +00008139static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008140s390_irgen_TMY(UChar i2, IRTemp op1addr)
8141{
8142 UChar mask;
8143 IRTemp value = newTemp(Ity_I8);
8144
8145 mask = i2;
8146 assign(value, load(Ity_I8, mkexpr(op1addr)));
8147 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_8, value, mktemp(Ity_I8,
8148 mkU8(mask)));
8149
8150 return "tmy";
8151}
8152
florian55085f82012-11-21 00:36:55 +00008153static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008154s390_irgen_TMHH(UChar r1, UShort i2)
8155{
8156 UShort mask;
8157 IRTemp value = newTemp(Ity_I16);
8158
8159 mask = i2;
8160 assign(value, get_gpr_hw0(r1));
8161 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
8162 mkU16(mask)));
8163
8164 return "tmhh";
8165}
8166
florian55085f82012-11-21 00:36:55 +00008167static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008168s390_irgen_TMHL(UChar r1, UShort i2)
8169{
8170 UShort mask;
8171 IRTemp value = newTemp(Ity_I16);
8172
8173 mask = i2;
8174 assign(value, get_gpr_hw1(r1));
8175 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
8176 mkU16(mask)));
8177
8178 return "tmhl";
8179}
8180
florian55085f82012-11-21 00:36:55 +00008181static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008182s390_irgen_TMLH(UChar r1, UShort i2)
8183{
8184 UShort mask;
8185 IRTemp value = newTemp(Ity_I16);
8186
8187 mask = i2;
8188 assign(value, get_gpr_hw2(r1));
8189 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
8190 mkU16(mask)));
8191
8192 return "tmlh";
8193}
8194
florian55085f82012-11-21 00:36:55 +00008195static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008196s390_irgen_TMLL(UChar r1, UShort i2)
8197{
8198 UShort mask;
8199 IRTemp value = newTemp(Ity_I16);
8200
8201 mask = i2;
8202 assign(value, get_gpr_hw3(r1));
8203 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
8204 mkU16(mask)));
8205
8206 return "tmll";
8207}
8208
florian55085f82012-11-21 00:36:55 +00008209static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008210s390_irgen_EFPC(UChar r1)
8211{
8212 put_gpr_w1(r1, get_fpc_w0());
8213
8214 return "efpc";
8215}
8216
florian55085f82012-11-21 00:36:55 +00008217static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008218s390_irgen_LER(UChar r1, UChar r2)
8219{
8220 put_fpr_w0(r1, get_fpr_w0(r2));
8221
8222 return "ler";
8223}
8224
florian55085f82012-11-21 00:36:55 +00008225static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008226s390_irgen_LDR(UChar r1, UChar r2)
8227{
8228 put_fpr_dw0(r1, get_fpr_dw0(r2));
8229
8230 return "ldr";
8231}
8232
florian55085f82012-11-21 00:36:55 +00008233static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008234s390_irgen_LXR(UChar r1, UChar r2)
8235{
8236 put_fpr_dw0(r1, get_fpr_dw0(r2));
8237 put_fpr_dw0(r1 + 2, get_fpr_dw0(r2 + 2));
8238
8239 return "lxr";
8240}
8241
florian55085f82012-11-21 00:36:55 +00008242static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008243s390_irgen_LE(UChar r1, IRTemp op2addr)
8244{
8245 put_fpr_w0(r1, load(Ity_F32, mkexpr(op2addr)));
8246
8247 return "le";
8248}
8249
florian55085f82012-11-21 00:36:55 +00008250static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008251s390_irgen_LD(UChar r1, IRTemp op2addr)
8252{
8253 put_fpr_dw0(r1, load(Ity_F64, mkexpr(op2addr)));
8254
8255 return "ld";
8256}
8257
florian55085f82012-11-21 00:36:55 +00008258static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008259s390_irgen_LEY(UChar r1, IRTemp op2addr)
8260{
8261 put_fpr_w0(r1, load(Ity_F32, mkexpr(op2addr)));
8262
8263 return "ley";
8264}
8265
florian55085f82012-11-21 00:36:55 +00008266static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008267s390_irgen_LDY(UChar r1, IRTemp op2addr)
8268{
8269 put_fpr_dw0(r1, load(Ity_F64, mkexpr(op2addr)));
8270
8271 return "ldy";
8272}
8273
florian55085f82012-11-21 00:36:55 +00008274static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008275s390_irgen_LFPC(IRTemp op2addr)
8276{
8277 put_fpc_w0(load(Ity_I32, mkexpr(op2addr)));
8278
8279 return "lfpc";
8280}
8281
florian55085f82012-11-21 00:36:55 +00008282static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008283s390_irgen_LZER(UChar r1)
8284{
8285 put_fpr_w0(r1, mkF32i(0x0));
8286
8287 return "lzer";
8288}
8289
florian55085f82012-11-21 00:36:55 +00008290static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008291s390_irgen_LZDR(UChar r1)
8292{
8293 put_fpr_dw0(r1, mkF64i(0x0));
8294
8295 return "lzdr";
8296}
8297
florian55085f82012-11-21 00:36:55 +00008298static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008299s390_irgen_LZXR(UChar r1)
8300{
8301 put_fpr_dw0(r1, mkF64i(0x0));
8302 put_fpr_dw0(r1 + 2, mkF64i(0x0));
8303
8304 return "lzxr";
8305}
8306
florian55085f82012-11-21 00:36:55 +00008307static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008308s390_irgen_SRNM(IRTemp op2addr)
8309{
florianf0fa1be2012-09-18 20:24:38 +00008310 UInt input_mask, fpc_mask;
sewardj2019a972011-03-07 16:04:07 +00008311
florianf0fa1be2012-09-18 20:24:38 +00008312 input_mask = 3;
8313 fpc_mask = s390_host_has_fpext ? 7 : 3;
sewardj2019a972011-03-07 16:04:07 +00008314
florianf0fa1be2012-09-18 20:24:38 +00008315 put_fpc_w0(binop(Iop_Or32,
8316 binop(Iop_And32, get_fpc_w0(), mkU32(~fpc_mask)),
8317 binop(Iop_And32, unop(Iop_64to32, mkexpr(op2addr)),
8318 mkU32(input_mask))));
sewardj2019a972011-03-07 16:04:07 +00008319 return "srnm";
8320}
8321
florian55085f82012-11-21 00:36:55 +00008322static const HChar *
florianf0fa1be2012-09-18 20:24:38 +00008323s390_irgen_SRNMB(IRTemp op2addr)
8324{
8325 UInt input_mask, fpc_mask;
8326
8327 input_mask = 7;
8328 fpc_mask = 7;
8329
8330 put_fpc_w0(binop(Iop_Or32,
8331 binop(Iop_And32, get_fpc_w0(), mkU32(~fpc_mask)),
8332 binop(Iop_And32, unop(Iop_64to32, mkexpr(op2addr)),
8333 mkU32(input_mask))));
8334 return "srnmb";
8335}
8336
florian81a4bfe2012-09-20 01:25:28 +00008337static void
florianf0fa1be2012-09-18 20:24:38 +00008338s390_irgen_srnmb_wrapper(UChar b2, UShort d2)
8339{
8340 if (b2 == 0) { /* This is the typical case */
8341 if (d2 > 3) {
8342 if (s390_host_has_fpext && d2 == 7) {
8343 /* ok */
8344 } else {
8345 emulation_warning(EmWarn_S390X_invalid_rounding);
florian125e20d2012-10-07 15:42:37 +00008346 d2 = S390_FPC_BFP_ROUND_NEAREST_EVEN;
florianf0fa1be2012-09-18 20:24:38 +00008347 }
8348 }
8349 }
8350
8351 s390_format_S_RD(s390_irgen_SRNMB, b2, d2);
8352}
8353
8354
florian55085f82012-11-21 00:36:55 +00008355static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008356s390_irgen_SFPC(UChar r1)
8357{
8358 put_fpc_w0(get_gpr_w1(r1));
8359
8360 return "sfpc";
8361}
8362
florian55085f82012-11-21 00:36:55 +00008363static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008364s390_irgen_STE(UChar r1, IRTemp op2addr)
8365{
8366 store(mkexpr(op2addr), get_fpr_w0(r1));
8367
8368 return "ste";
8369}
8370
florian55085f82012-11-21 00:36:55 +00008371static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008372s390_irgen_STD(UChar r1, IRTemp op2addr)
8373{
8374 store(mkexpr(op2addr), get_fpr_dw0(r1));
8375
8376 return "std";
8377}
8378
florian55085f82012-11-21 00:36:55 +00008379static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008380s390_irgen_STEY(UChar r1, IRTemp op2addr)
8381{
8382 store(mkexpr(op2addr), get_fpr_w0(r1));
8383
8384 return "stey";
8385}
8386
florian55085f82012-11-21 00:36:55 +00008387static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008388s390_irgen_STDY(UChar r1, IRTemp op2addr)
8389{
8390 store(mkexpr(op2addr), get_fpr_dw0(r1));
8391
8392 return "stdy";
8393}
8394
florian55085f82012-11-21 00:36:55 +00008395static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008396s390_irgen_STFPC(IRTemp op2addr)
8397{
8398 store(mkexpr(op2addr), get_fpc_w0());
8399
8400 return "stfpc";
8401}
8402
florian55085f82012-11-21 00:36:55 +00008403static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008404s390_irgen_AEBR(UChar r1, UChar r2)
8405{
8406 IRTemp op1 = newTemp(Ity_F32);
8407 IRTemp op2 = newTemp(Ity_F32);
8408 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00008409 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008410
8411 assign(op1, get_fpr_w0(r1));
8412 assign(op2, get_fpr_w0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008413 assign(result, triop(Iop_AddF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008414 mkexpr(op2)));
8415 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
8416 put_fpr_w0(r1, mkexpr(result));
8417
8418 return "aebr";
8419}
8420
florian55085f82012-11-21 00:36:55 +00008421static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008422s390_irgen_ADBR(UChar r1, UChar r2)
8423{
8424 IRTemp op1 = newTemp(Ity_F64);
8425 IRTemp op2 = newTemp(Ity_F64);
8426 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00008427 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008428
8429 assign(op1, get_fpr_dw0(r1));
8430 assign(op2, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008431 assign(result, triop(Iop_AddF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008432 mkexpr(op2)));
8433 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
8434 put_fpr_dw0(r1, mkexpr(result));
8435
8436 return "adbr";
8437}
8438
florian55085f82012-11-21 00:36:55 +00008439static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008440s390_irgen_AEB(UChar r1, IRTemp op2addr)
8441{
8442 IRTemp op1 = newTemp(Ity_F32);
8443 IRTemp op2 = newTemp(Ity_F32);
8444 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00008445 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008446
8447 assign(op1, get_fpr_w0(r1));
8448 assign(op2, load(Ity_F32, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00008449 assign(result, triop(Iop_AddF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008450 mkexpr(op2)));
8451 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
8452 put_fpr_w0(r1, mkexpr(result));
8453
8454 return "aeb";
8455}
8456
florian55085f82012-11-21 00:36:55 +00008457static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008458s390_irgen_ADB(UChar r1, IRTemp op2addr)
8459{
8460 IRTemp op1 = newTemp(Ity_F64);
8461 IRTemp op2 = newTemp(Ity_F64);
8462 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00008463 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008464
8465 assign(op1, get_fpr_dw0(r1));
8466 assign(op2, load(Ity_F64, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00008467 assign(result, triop(Iop_AddF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008468 mkexpr(op2)));
8469 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
8470 put_fpr_dw0(r1, mkexpr(result));
8471
8472 return "adb";
8473}
8474
florian55085f82012-11-21 00:36:55 +00008475static const HChar *
florian4b8efad2012-09-02 18:07:08 +00008476s390_irgen_CEFBR(UChar m3, UChar m4 __attribute__((unused)),
8477 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008478{
florian125e20d2012-10-07 15:42:37 +00008479 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian4b8efad2012-09-02 18:07:08 +00008480 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +00008481 m3 = S390_BFP_ROUND_PER_FPC;
florian4b8efad2012-09-02 18:07:08 +00008482 }
sewardj2019a972011-03-07 16:04:07 +00008483 IRTemp op2 = newTemp(Ity_I32);
8484
8485 assign(op2, get_gpr_w1(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008486 put_fpr_w0(r1, binop(Iop_I32StoF32, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +00008487 mkexpr(op2)));
sewardj2019a972011-03-07 16:04:07 +00008488
8489 return "cefbr";
8490}
8491
florian55085f82012-11-21 00:36:55 +00008492static const HChar *
florian4b8efad2012-09-02 18:07:08 +00008493s390_irgen_CDFBR(UChar m3 __attribute__((unused)),
8494 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008495{
8496 IRTemp op2 = newTemp(Ity_I32);
8497
8498 assign(op2, get_gpr_w1(r2));
8499 put_fpr_dw0(r1, unop(Iop_I32StoF64, mkexpr(op2)));
8500
8501 return "cdfbr";
8502}
8503
florian55085f82012-11-21 00:36:55 +00008504static const HChar *
florian4b8efad2012-09-02 18:07:08 +00008505s390_irgen_CEGBR(UChar m3, UChar m4 __attribute__((unused)),
8506 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008507{
florian125e20d2012-10-07 15:42:37 +00008508 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian4b8efad2012-09-02 18:07:08 +00008509 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +00008510 m3 = S390_BFP_ROUND_PER_FPC;
florian4b8efad2012-09-02 18:07:08 +00008511 }
sewardj2019a972011-03-07 16:04:07 +00008512 IRTemp op2 = newTemp(Ity_I64);
8513
8514 assign(op2, get_gpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008515 put_fpr_w0(r1, binop(Iop_I64StoF32, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +00008516 mkexpr(op2)));
sewardj2019a972011-03-07 16:04:07 +00008517
8518 return "cegbr";
8519}
8520
florian55085f82012-11-21 00:36:55 +00008521static const HChar *
florian4b8efad2012-09-02 18:07:08 +00008522s390_irgen_CDGBR(UChar m3, UChar m4 __attribute__((unused)),
8523 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008524{
florian125e20d2012-10-07 15:42:37 +00008525 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian4b8efad2012-09-02 18:07:08 +00008526 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +00008527 m3 = S390_BFP_ROUND_PER_FPC;
florian4b8efad2012-09-02 18:07:08 +00008528 }
sewardj2019a972011-03-07 16:04:07 +00008529 IRTemp op2 = newTemp(Ity_I64);
8530
8531 assign(op2, get_gpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008532 put_fpr_dw0(r1, binop(Iop_I64StoF64, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +00008533 mkexpr(op2)));
sewardj2019a972011-03-07 16:04:07 +00008534
8535 return "cdgbr";
8536}
8537
florian55085f82012-11-21 00:36:55 +00008538static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00008539s390_irgen_CELFBR(UChar m3, UChar m4 __attribute__((unused)),
8540 UChar r1, UChar r2)
8541{
floriane75dafa2012-09-01 17:54:09 +00008542 if (! s390_host_has_fpext) {
8543 emulation_failure(EmFail_S390X_fpext);
8544 } else {
8545 IRTemp op2 = newTemp(Ity_I32);
florian1c8f7ff2012-09-01 00:12:11 +00008546
floriane75dafa2012-09-01 17:54:09 +00008547 assign(op2, get_gpr_w1(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008548 put_fpr_w0(r1, binop(Iop_I32UtoF32, mkexpr(encode_bfp_rounding_mode(m3)),
floriane75dafa2012-09-01 17:54:09 +00008549 mkexpr(op2)));
8550 }
florian1c8f7ff2012-09-01 00:12:11 +00008551 return "celfbr";
8552}
8553
florian55085f82012-11-21 00:36:55 +00008554static const HChar *
floriand2129202012-09-01 20:01:39 +00008555s390_irgen_CDLFBR(UChar m3 __attribute__((unused)),
8556 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
florian1c8f7ff2012-09-01 00:12:11 +00008557{
floriane75dafa2012-09-01 17:54:09 +00008558 if (! s390_host_has_fpext) {
8559 emulation_failure(EmFail_S390X_fpext);
8560 } else {
8561 IRTemp op2 = newTemp(Ity_I32);
florian1c8f7ff2012-09-01 00:12:11 +00008562
floriane75dafa2012-09-01 17:54:09 +00008563 assign(op2, get_gpr_w1(r2));
8564 put_fpr_dw0(r1, unop(Iop_I32UtoF64, mkexpr(op2)));
8565 }
florian1c8f7ff2012-09-01 00:12:11 +00008566 return "cdlfbr";
8567}
8568
florian55085f82012-11-21 00:36:55 +00008569static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00008570s390_irgen_CELGBR(UChar m3, UChar m4 __attribute__((unused)),
8571 UChar r1, UChar r2)
8572{
floriane75dafa2012-09-01 17:54:09 +00008573 if (! s390_host_has_fpext) {
8574 emulation_failure(EmFail_S390X_fpext);
8575 } else {
8576 IRTemp op2 = newTemp(Ity_I64);
florian1c8f7ff2012-09-01 00:12:11 +00008577
floriane75dafa2012-09-01 17:54:09 +00008578 assign(op2, get_gpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008579 put_fpr_w0(r1, binop(Iop_I64UtoF32, mkexpr(encode_bfp_rounding_mode(m3)),
floriane75dafa2012-09-01 17:54:09 +00008580 mkexpr(op2)));
8581 }
florian1c8f7ff2012-09-01 00:12:11 +00008582 return "celgbr";
8583}
8584
florian55085f82012-11-21 00:36:55 +00008585static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00008586s390_irgen_CDLGBR(UChar m3, UChar m4 __attribute__((unused)),
8587 UChar r1, UChar r2)
8588{
floriane75dafa2012-09-01 17:54:09 +00008589 if (! s390_host_has_fpext) {
8590 emulation_failure(EmFail_S390X_fpext);
8591 } else {
8592 IRTemp op2 = newTemp(Ity_I64);
florian1c8f7ff2012-09-01 00:12:11 +00008593
floriane75dafa2012-09-01 17:54:09 +00008594 assign(op2, get_gpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008595 put_fpr_dw0(r1, binop(Iop_I64UtoF64,
8596 mkexpr(encode_bfp_rounding_mode(m3)),
floriane75dafa2012-09-01 17:54:09 +00008597 mkexpr(op2)));
8598 }
florian1c8f7ff2012-09-01 00:12:11 +00008599 return "cdlgbr";
8600}
8601
florian55085f82012-11-21 00:36:55 +00008602static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00008603s390_irgen_CLFEBR(UChar m3, UChar m4 __attribute__((unused)),
8604 UChar r1, UChar r2)
8605{
floriane75dafa2012-09-01 17:54:09 +00008606 if (! s390_host_has_fpext) {
8607 emulation_failure(EmFail_S390X_fpext);
8608 } else {
8609 IRTemp op = newTemp(Ity_F32);
8610 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +00008611 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +00008612
floriane75dafa2012-09-01 17:54:09 +00008613 assign(op, get_fpr_w0(r2));
florian19e00772012-09-06 03:13:22 +00008614 assign(result, binop(Iop_F32toI32U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +00008615 mkexpr(op)));
8616 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008617 s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_UINT_32, op, rounding_mode);
floriane75dafa2012-09-01 17:54:09 +00008618 }
florian1c8f7ff2012-09-01 00:12:11 +00008619 return "clfebr";
8620}
8621
florian55085f82012-11-21 00:36:55 +00008622static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00008623s390_irgen_CLFDBR(UChar m3, UChar m4 __attribute__((unused)),
8624 UChar r1, UChar r2)
8625{
floriane75dafa2012-09-01 17:54:09 +00008626 if (! s390_host_has_fpext) {
8627 emulation_failure(EmFail_S390X_fpext);
8628 } else {
8629 IRTemp op = newTemp(Ity_F64);
8630 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +00008631 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +00008632
floriane75dafa2012-09-01 17:54:09 +00008633 assign(op, get_fpr_dw0(r2));
florian19e00772012-09-06 03:13:22 +00008634 assign(result, binop(Iop_F64toI32U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +00008635 mkexpr(op)));
8636 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008637 s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_UINT_32, op, rounding_mode);
floriane75dafa2012-09-01 17:54:09 +00008638 }
florian1c8f7ff2012-09-01 00:12:11 +00008639 return "clfdbr";
8640}
8641
florian55085f82012-11-21 00:36:55 +00008642static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00008643s390_irgen_CLGEBR(UChar m3, UChar m4 __attribute__((unused)),
8644 UChar r1, UChar r2)
8645{
floriane75dafa2012-09-01 17:54:09 +00008646 if (! s390_host_has_fpext) {
8647 emulation_failure(EmFail_S390X_fpext);
8648 } else {
8649 IRTemp op = newTemp(Ity_F32);
8650 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +00008651 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +00008652
floriane75dafa2012-09-01 17:54:09 +00008653 assign(op, get_fpr_w0(r2));
florian19e00772012-09-06 03:13:22 +00008654 assign(result, binop(Iop_F32toI64U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +00008655 mkexpr(op)));
8656 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008657 s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_UINT_64, op, rounding_mode);
floriane75dafa2012-09-01 17:54:09 +00008658 }
florian1c8f7ff2012-09-01 00:12:11 +00008659 return "clgebr";
8660}
8661
florian55085f82012-11-21 00:36:55 +00008662static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00008663s390_irgen_CLGDBR(UChar m3, UChar m4 __attribute__((unused)),
8664 UChar r1, UChar r2)
8665{
floriane75dafa2012-09-01 17:54:09 +00008666 if (! s390_host_has_fpext) {
8667 emulation_failure(EmFail_S390X_fpext);
8668 } else {
8669 IRTemp op = newTemp(Ity_F64);
8670 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +00008671 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +00008672
floriane75dafa2012-09-01 17:54:09 +00008673 assign(op, get_fpr_dw0(r2));
florian19e00772012-09-06 03:13:22 +00008674 assign(result, binop(Iop_F64toI64U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +00008675 mkexpr(op)));
8676 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008677 s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_UINT_64, op, rounding_mode);
floriane75dafa2012-09-01 17:54:09 +00008678 }
florian1c8f7ff2012-09-01 00:12:11 +00008679 return "clgdbr";
8680}
8681
florian55085f82012-11-21 00:36:55 +00008682static const HChar *
florian4b8efad2012-09-02 18:07:08 +00008683s390_irgen_CFEBR(UChar m3, UChar m4 __attribute__((unused)),
8684 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008685{
8686 IRTemp op = newTemp(Ity_F32);
8687 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +00008688 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +00008689
8690 assign(op, get_fpr_w0(r2));
florian19e00772012-09-06 03:13:22 +00008691 assign(result, binop(Iop_F32toI32S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +00008692 mkexpr(op)));
8693 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008694 s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_INT_32, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +00008695
8696 return "cfebr";
8697}
8698
florian55085f82012-11-21 00:36:55 +00008699static const HChar *
florian4b8efad2012-09-02 18:07:08 +00008700s390_irgen_CFDBR(UChar m3, UChar m4 __attribute__((unused)),
8701 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008702{
8703 IRTemp op = newTemp(Ity_F64);
8704 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +00008705 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +00008706
8707 assign(op, get_fpr_dw0(r2));
florian19e00772012-09-06 03:13:22 +00008708 assign(result, binop(Iop_F64toI32S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +00008709 mkexpr(op)));
8710 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008711 s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_INT_32, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +00008712
8713 return "cfdbr";
8714}
8715
florian55085f82012-11-21 00:36:55 +00008716static const HChar *
florian4b8efad2012-09-02 18:07:08 +00008717s390_irgen_CGEBR(UChar m3, UChar m4 __attribute__((unused)),
8718 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008719{
8720 IRTemp op = newTemp(Ity_F32);
8721 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +00008722 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +00008723
8724 assign(op, get_fpr_w0(r2));
florian19e00772012-09-06 03:13:22 +00008725 assign(result, binop(Iop_F32toI64S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +00008726 mkexpr(op)));
8727 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008728 s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_INT_64, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +00008729
8730 return "cgebr";
8731}
8732
florian55085f82012-11-21 00:36:55 +00008733static const HChar *
florian4b8efad2012-09-02 18:07:08 +00008734s390_irgen_CGDBR(UChar m3, UChar m4 __attribute__((unused)),
8735 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008736{
8737 IRTemp op = newTemp(Ity_F64);
8738 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +00008739 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +00008740
8741 assign(op, get_fpr_dw0(r2));
florian19e00772012-09-06 03:13:22 +00008742 assign(result, binop(Iop_F64toI64S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +00008743 mkexpr(op)));
8744 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008745 s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_INT_64, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +00008746
8747 return "cgdbr";
8748}
8749
florian55085f82012-11-21 00:36:55 +00008750static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008751s390_irgen_DEBR(UChar r1, UChar r2)
8752{
8753 IRTemp op1 = newTemp(Ity_F32);
8754 IRTemp op2 = newTemp(Ity_F32);
8755 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00008756 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008757
8758 assign(op1, get_fpr_w0(r1));
8759 assign(op2, get_fpr_w0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008760 assign(result, triop(Iop_DivF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008761 mkexpr(op2)));
8762 put_fpr_w0(r1, mkexpr(result));
8763
8764 return "debr";
8765}
8766
florian55085f82012-11-21 00:36:55 +00008767static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008768s390_irgen_DDBR(UChar r1, UChar r2)
8769{
8770 IRTemp op1 = newTemp(Ity_F64);
8771 IRTemp op2 = newTemp(Ity_F64);
8772 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00008773 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008774
8775 assign(op1, get_fpr_dw0(r1));
8776 assign(op2, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008777 assign(result, triop(Iop_DivF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008778 mkexpr(op2)));
8779 put_fpr_dw0(r1, mkexpr(result));
8780
8781 return "ddbr";
8782}
8783
florian55085f82012-11-21 00:36:55 +00008784static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008785s390_irgen_DEB(UChar r1, IRTemp op2addr)
8786{
8787 IRTemp op1 = newTemp(Ity_F32);
8788 IRTemp op2 = newTemp(Ity_F32);
8789 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00008790 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008791
8792 assign(op1, get_fpr_w0(r1));
8793 assign(op2, load(Ity_F32, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00008794 assign(result, triop(Iop_DivF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008795 mkexpr(op2)));
8796 put_fpr_w0(r1, mkexpr(result));
8797
8798 return "deb";
8799}
8800
florian55085f82012-11-21 00:36:55 +00008801static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008802s390_irgen_DDB(UChar r1, IRTemp op2addr)
8803{
8804 IRTemp op1 = newTemp(Ity_F64);
8805 IRTemp op2 = newTemp(Ity_F64);
8806 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00008807 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008808
8809 assign(op1, get_fpr_dw0(r1));
8810 assign(op2, load(Ity_F64, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00008811 assign(result, triop(Iop_DivF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008812 mkexpr(op2)));
8813 put_fpr_dw0(r1, mkexpr(result));
8814
8815 return "ddb";
8816}
8817
florian55085f82012-11-21 00:36:55 +00008818static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008819s390_irgen_LTEBR(UChar r1, UChar r2)
8820{
8821 IRTemp result = newTemp(Ity_F32);
8822
8823 assign(result, get_fpr_w0(r2));
8824 put_fpr_w0(r1, mkexpr(result));
8825 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
8826
8827 return "ltebr";
8828}
8829
florian55085f82012-11-21 00:36:55 +00008830static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008831s390_irgen_LTDBR(UChar r1, UChar r2)
8832{
8833 IRTemp result = newTemp(Ity_F64);
8834
8835 assign(result, get_fpr_dw0(r2));
8836 put_fpr_dw0(r1, mkexpr(result));
8837 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
8838
8839 return "ltdbr";
8840}
8841
florian55085f82012-11-21 00:36:55 +00008842static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008843s390_irgen_LCEBR(UChar r1, UChar r2)
8844{
8845 IRTemp result = newTemp(Ity_F32);
8846
8847 assign(result, unop(Iop_NegF32, get_fpr_w0(r2)));
8848 put_fpr_w0(r1, mkexpr(result));
8849 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
8850
8851 return "lcebr";
8852}
8853
florian55085f82012-11-21 00:36:55 +00008854static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008855s390_irgen_LCDBR(UChar r1, UChar r2)
8856{
8857 IRTemp result = newTemp(Ity_F64);
8858
8859 assign(result, unop(Iop_NegF64, get_fpr_dw0(r2)));
8860 put_fpr_dw0(r1, mkexpr(result));
8861 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
8862
8863 return "lcdbr";
8864}
8865
florian55085f82012-11-21 00:36:55 +00008866static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008867s390_irgen_LDEBR(UChar r1, UChar r2)
8868{
8869 IRTemp op = newTemp(Ity_F32);
8870
8871 assign(op, get_fpr_w0(r2));
8872 put_fpr_dw0(r1, unop(Iop_F32toF64, mkexpr(op)));
8873
8874 return "ldebr";
8875}
8876
florian55085f82012-11-21 00:36:55 +00008877static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008878s390_irgen_LDEB(UChar r1, IRTemp op2addr)
8879{
8880 IRTemp op = newTemp(Ity_F32);
8881
8882 assign(op, load(Ity_F32, mkexpr(op2addr)));
8883 put_fpr_dw0(r1, unop(Iop_F32toF64, mkexpr(op)));
8884
8885 return "ldeb";
8886}
8887
florian55085f82012-11-21 00:36:55 +00008888static const HChar *
florian4b8efad2012-09-02 18:07:08 +00008889s390_irgen_LEDBR(UChar m3, UChar m4 __attribute__((unused)),
8890 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008891{
florian125e20d2012-10-07 15:42:37 +00008892 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian12b0bca2012-09-05 20:05:20 +00008893 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +00008894 m3 = S390_BFP_ROUND_PER_FPC;
florian12b0bca2012-09-05 20:05:20 +00008895 }
sewardj2019a972011-03-07 16:04:07 +00008896 IRTemp op = newTemp(Ity_F64);
8897
8898 assign(op, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008899 put_fpr_w0(r1, binop(Iop_F64toF32, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +00008900 mkexpr(op)));
sewardj2019a972011-03-07 16:04:07 +00008901
8902 return "ledbr";
8903}
8904
florian55085f82012-11-21 00:36:55 +00008905static const HChar *
florian12390202012-11-10 22:34:14 +00008906s390_irgen_LTDTR(UChar r1, UChar r2)
8907{
8908 IRTemp result = newTemp(Ity_D64);
8909
8910 assign(result, get_dpr_dw0(r2));
8911 put_dpr_dw0(r1, mkexpr(result));
8912 s390_cc_thunk_putF(S390_CC_OP_DFP_RESULT_64, result);
8913
8914 return "ltdtr";
8915}
8916
florian55085f82012-11-21 00:36:55 +00008917static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008918s390_irgen_MEEBR(UChar r1, UChar r2)
8919{
8920 IRTemp op1 = newTemp(Ity_F32);
8921 IRTemp op2 = newTemp(Ity_F32);
8922 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00008923 IRRoundingMode rounding_mode =
8924 encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008925
8926 assign(op1, get_fpr_w0(r1));
8927 assign(op2, get_fpr_w0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008928 assign(result, triop(Iop_MulF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008929 mkexpr(op2)));
8930 put_fpr_w0(r1, mkexpr(result));
8931
8932 return "meebr";
8933}
8934
florian55085f82012-11-21 00:36:55 +00008935static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008936s390_irgen_MDBR(UChar r1, UChar r2)
8937{
8938 IRTemp op1 = newTemp(Ity_F64);
8939 IRTemp op2 = newTemp(Ity_F64);
8940 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00008941 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008942
8943 assign(op1, get_fpr_dw0(r1));
8944 assign(op2, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008945 assign(result, triop(Iop_MulF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008946 mkexpr(op2)));
8947 put_fpr_dw0(r1, mkexpr(result));
8948
8949 return "mdbr";
8950}
8951
florian55085f82012-11-21 00:36:55 +00008952static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008953s390_irgen_MEEB(UChar r1, IRTemp op2addr)
8954{
8955 IRTemp op1 = newTemp(Ity_F32);
8956 IRTemp op2 = newTemp(Ity_F32);
8957 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00008958 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008959
8960 assign(op1, get_fpr_w0(r1));
8961 assign(op2, load(Ity_F32, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00008962 assign(result, triop(Iop_MulF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008963 mkexpr(op2)));
8964 put_fpr_w0(r1, mkexpr(result));
8965
8966 return "meeb";
8967}
8968
florian55085f82012-11-21 00:36:55 +00008969static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008970s390_irgen_MDB(UChar r1, IRTemp op2addr)
8971{
8972 IRTemp op1 = newTemp(Ity_F64);
8973 IRTemp op2 = newTemp(Ity_F64);
8974 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00008975 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008976
8977 assign(op1, get_fpr_dw0(r1));
8978 assign(op2, load(Ity_F64, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00008979 assign(result, triop(Iop_MulF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008980 mkexpr(op2)));
8981 put_fpr_dw0(r1, mkexpr(result));
8982
8983 return "mdb";
8984}
8985
florian55085f82012-11-21 00:36:55 +00008986static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008987s390_irgen_SEBR(UChar r1, UChar r2)
8988{
8989 IRTemp op1 = newTemp(Ity_F32);
8990 IRTemp op2 = newTemp(Ity_F32);
8991 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00008992 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008993
8994 assign(op1, get_fpr_w0(r1));
8995 assign(op2, get_fpr_w0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008996 assign(result, triop(Iop_SubF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008997 mkexpr(op2)));
8998 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
8999 put_fpr_w0(r1, mkexpr(result));
9000
9001 return "sebr";
9002}
9003
florian55085f82012-11-21 00:36:55 +00009004static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009005s390_irgen_SDBR(UChar r1, UChar r2)
9006{
9007 IRTemp op1 = newTemp(Ity_F64);
9008 IRTemp op2 = newTemp(Ity_F64);
9009 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00009010 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009011
9012 assign(op1, get_fpr_dw0(r1));
9013 assign(op2, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009014 assign(result, triop(Iop_SubF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009015 mkexpr(op2)));
9016 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
9017 put_fpr_dw0(r1, mkexpr(result));
9018
9019 return "sdbr";
9020}
9021
florian55085f82012-11-21 00:36:55 +00009022static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009023s390_irgen_SEB(UChar r1, IRTemp op2addr)
9024{
9025 IRTemp op1 = newTemp(Ity_F32);
9026 IRTemp op2 = newTemp(Ity_F32);
9027 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00009028 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009029
9030 assign(op1, get_fpr_w0(r1));
9031 assign(op2, load(Ity_F32, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00009032 assign(result, triop(Iop_SubF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009033 mkexpr(op2)));
9034 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
9035 put_fpr_w0(r1, mkexpr(result));
9036
9037 return "seb";
9038}
9039
florian55085f82012-11-21 00:36:55 +00009040static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009041s390_irgen_SDB(UChar r1, IRTemp op2addr)
9042{
9043 IRTemp op1 = newTemp(Ity_F64);
9044 IRTemp op2 = newTemp(Ity_F64);
9045 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00009046 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009047
9048 assign(op1, get_fpr_dw0(r1));
9049 assign(op2, load(Ity_F64, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00009050 assign(result, triop(Iop_SubF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009051 mkexpr(op2)));
9052 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
9053 put_fpr_dw0(r1, mkexpr(result));
9054
9055 return "sdb";
9056}
9057
florian55085f82012-11-21 00:36:55 +00009058static const HChar *
florian12390202012-11-10 22:34:14 +00009059s390_irgen_ADTRA(UChar r3, UChar m4, UChar r1, UChar r2)
9060{
9061 IRTemp op1 = newTemp(Ity_D64);
9062 IRTemp op2 = newTemp(Ity_D64);
9063 IRTemp result = newTemp(Ity_D64);
9064 IRTemp rounding_mode;
9065
9066 vassert(s390_host_has_dfp);
9067 vassert(m4 == 0 || s390_host_has_fpext);
9068 /* when m4 = 0, S390_DFP_ROUND_PER_FPC_0 should be set.
9069 since S390_DFP_ROUND_PER_FPC_0 is also 0, passing m4 is sufficient */
9070 rounding_mode = encode_dfp_rounding_mode(m4);
9071 assign(op1, get_dpr_dw0(r2));
9072 assign(op2, get_dpr_dw0(r3));
9073 assign(result, triop(Iop_AddD64, mkexpr(rounding_mode), mkexpr(op1),
9074 mkexpr(op2)));
9075 s390_cc_thunk_putF(S390_CC_OP_DFP_RESULT_64, result);
9076 put_dpr_dw0(r1, mkexpr(result));
9077
9078 return (m4 == 0) ? "adtr" : "adtra";
9079}
9080
florian55085f82012-11-21 00:36:55 +00009081static const HChar *
florian12390202012-11-10 22:34:14 +00009082s390_irgen_DDTRA(UChar r3, UChar m4, UChar r1, UChar r2)
9083{
9084 IRTemp op1 = newTemp(Ity_D64);
9085 IRTemp op2 = newTemp(Ity_D64);
9086 IRTemp result = newTemp(Ity_D64);
9087 IRTemp rounding_mode;
9088
9089 vassert(s390_host_has_dfp);
9090 vassert(m4 == 0 || s390_host_has_fpext);
9091 /* when m4 = 0, S390_DFP_ROUND_PER_FPC_0 should be set.
9092 since S390_DFP_ROUND_PER_FPC_0 is also 0, passing m4 is sufficient */
9093 rounding_mode = encode_dfp_rounding_mode(m4);
9094 assign(op1, get_dpr_dw0(r2));
9095 assign(op2, get_dpr_dw0(r3));
9096 assign(result, triop(Iop_DivD64, mkexpr(rounding_mode), mkexpr(op1),
9097 mkexpr(op2)));
9098 s390_cc_thunk_putF(S390_CC_OP_DFP_RESULT_64, result);
9099 put_dpr_dw0(r1, mkexpr(result));
9100
9101 return (m4 == 0) ? "ddtr" : "ddtra";
9102}
9103
florian55085f82012-11-21 00:36:55 +00009104static const HChar *
florian12390202012-11-10 22:34:14 +00009105s390_irgen_MDTRA(UChar r3, UChar m4, UChar r1, UChar r2)
9106{
9107 IRTemp op1 = newTemp(Ity_D64);
9108 IRTemp op2 = newTemp(Ity_D64);
9109 IRTemp result = newTemp(Ity_D64);
9110 IRTemp rounding_mode;
9111
9112 vassert(s390_host_has_dfp);
9113 vassert(m4 == 0 || s390_host_has_fpext);
9114 /* when m4 = 0, S390_DFP_ROUND_PER_FPC_0 should be set.
9115 since S390_DFP_ROUND_PER_FPC_0 is also 0, passing m4 is sufficient */
9116 rounding_mode = encode_dfp_rounding_mode(m4);
9117 assign(op1, get_dpr_dw0(r2));
9118 assign(op2, get_dpr_dw0(r3));
9119 assign(result, triop(Iop_MulD64, mkexpr(rounding_mode), mkexpr(op1),
9120 mkexpr(op2)));
9121 s390_cc_thunk_putF(S390_CC_OP_DFP_RESULT_64, result);
9122 put_dpr_dw0(r1, mkexpr(result));
9123
9124 return (m4 == 0) ? "mdtr" : "mdtra";
9125}
9126
florian55085f82012-11-21 00:36:55 +00009127static const HChar *
florian12390202012-11-10 22:34:14 +00009128s390_irgen_SDTRA(UChar r3, UChar m4, UChar r1, UChar r2)
9129{
9130 IRTemp op1 = newTemp(Ity_D64);
9131 IRTemp op2 = newTemp(Ity_D64);
9132 IRTemp result = newTemp(Ity_D64);
9133 IRTemp rounding_mode;
9134
9135 vassert(s390_host_has_dfp);
9136 vassert(m4 == 0 || s390_host_has_fpext);
9137 /* when m4 = 0, S390_DFP_ROUND_PER_FPC_0 should be set.
9138 since S390_DFP_ROUND_PER_FPC_0 is also 0, passing m4 is sufficient */
9139 rounding_mode = encode_dfp_rounding_mode(m4);
9140 assign(op1, get_dpr_dw0(r2));
9141 assign(op2, get_dpr_dw0(r3));
9142 assign(result, triop(Iop_SubD64, mkexpr(rounding_mode), mkexpr(op1),
9143 mkexpr(op2)));
9144 s390_cc_thunk_putF(S390_CC_OP_DFP_RESULT_64, result);
9145 put_dpr_dw0(r1, mkexpr(result));
9146
9147 return (m4 == 0) ? "sdtr" : "sdtra";
9148}
9149
sewardj2019a972011-03-07 16:04:07 +00009150
florian55085f82012-11-21 00:36:55 +00009151static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009152s390_irgen_CLC(UChar length, IRTemp start1, IRTemp start2)
9153{
florian79e839e2012-05-05 02:20:30 +00009154 IRTemp len = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00009155
florian79e839e2012-05-05 02:20:30 +00009156 assign(len, mkU64(length));
9157 s390_irgen_CLC_EX(len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +00009158
9159 return "clc";
9160}
9161
florian55085f82012-11-21 00:36:55 +00009162static const HChar *
florianb0c9a132011-09-08 15:37:39 +00009163s390_irgen_CLCL(UChar r1, UChar r2)
9164{
9165 IRTemp addr1 = newTemp(Ity_I64);
9166 IRTemp addr2 = newTemp(Ity_I64);
9167 IRTemp addr1_load = newTemp(Ity_I64);
9168 IRTemp addr2_load = newTemp(Ity_I64);
9169 IRTemp len1 = newTemp(Ity_I32);
9170 IRTemp len2 = newTemp(Ity_I32);
9171 IRTemp r1p1 = newTemp(Ity_I32); /* contents of r1 + 1 */
9172 IRTemp r2p1 = newTemp(Ity_I32); /* contents of r2 + 1 */
9173 IRTemp single1 = newTemp(Ity_I8);
9174 IRTemp single2 = newTemp(Ity_I8);
9175 IRTemp pad = newTemp(Ity_I8);
9176
9177 assign(addr1, get_gpr_dw0(r1));
9178 assign(r1p1, get_gpr_w1(r1 + 1));
9179 assign(len1, binop(Iop_And32, mkexpr(r1p1), mkU32(0x00ffffff)));
9180 assign(addr2, get_gpr_dw0(r2));
9181 assign(r2p1, get_gpr_w1(r2 + 1));
9182 assign(len2, binop(Iop_And32, mkexpr(r2p1), mkU32(0x00ffffff)));
9183 assign(pad, get_gpr_b4(r2 + 1));
9184
9185 /* len1 == 0 and len2 == 0? Exit */
9186 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +00009187 next_insn_if(binop(Iop_CmpEQ32, binop(Iop_Or32, mkexpr(len1),
9188 mkexpr(len2)), mkU32(0)));
florianb0c9a132011-09-08 15:37:39 +00009189
9190 /* Because mkite evaluates both the then-clause and the else-clause
9191 we cannot load directly from addr1 here. If len1 is 0, then adddr1
9192 may be NULL and loading from there would segfault. So we provide a
9193 valid dummy address in that case. Loading from there does no harm and
9194 the value will be discarded at runtime. */
9195 assign(addr1_load,
9196 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
9197 mkU64(guest_IA_curr_instr), mkexpr(addr1)));
9198 assign(single1,
9199 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
9200 mkexpr(pad), load(Ity_I8, mkexpr(addr1_load))));
9201
9202 assign(addr2_load,
9203 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
9204 mkU64(guest_IA_curr_instr), mkexpr(addr2)));
9205 assign(single2,
9206 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
9207 mkexpr(pad), load(Ity_I8, mkexpr(addr2_load))));
9208
9209 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, single1, single2, False);
9210 /* Fields differ ? */
florian6820ba52012-07-26 02:01:50 +00009211 next_insn_if(binop(Iop_CmpNE8, mkexpr(single1), mkexpr(single2)));
florianb0c9a132011-09-08 15:37:39 +00009212
9213 /* Update len1 and addr1, unless len1 == 0. */
9214 put_gpr_dw0(r1,
9215 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
9216 mkexpr(addr1),
9217 binop(Iop_Add64, mkexpr(addr1), mkU64(1))));
9218
9219 /* When updating len1 we must not modify bits (r1+1)[0:39] */
9220 put_gpr_w1(r1 + 1,
9221 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
9222 binop(Iop_And32, mkexpr(r1p1), mkU32(0xFF000000u)),
9223 binop(Iop_Sub32, mkexpr(r1p1), mkU32(1))));
9224
9225 /* Update len2 and addr2, unless len2 == 0. */
9226 put_gpr_dw0(r2,
9227 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
9228 mkexpr(addr2),
9229 binop(Iop_Add64, mkexpr(addr2), mkU64(1))));
9230
9231 /* When updating len2 we must not modify bits (r2+1)[0:39] */
9232 put_gpr_w1(r2 + 1,
9233 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
9234 binop(Iop_And32, mkexpr(r2p1), mkU32(0xFF000000u)),
9235 binop(Iop_Sub32, mkexpr(r2p1), mkU32(1))));
9236
florian6820ba52012-07-26 02:01:50 +00009237 iterate();
florianb0c9a132011-09-08 15:37:39 +00009238
9239 return "clcl";
9240}
9241
florian55085f82012-11-21 00:36:55 +00009242static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009243s390_irgen_CLCLE(UChar r1, UChar r3, IRTemp pad2)
9244{
9245 IRTemp addr1, addr3, addr1_load, addr3_load, len1, len3, single1, single3;
9246
9247 addr1 = newTemp(Ity_I64);
9248 addr3 = newTemp(Ity_I64);
9249 addr1_load = newTemp(Ity_I64);
9250 addr3_load = newTemp(Ity_I64);
9251 len1 = newTemp(Ity_I64);
9252 len3 = newTemp(Ity_I64);
9253 single1 = newTemp(Ity_I8);
9254 single3 = newTemp(Ity_I8);
9255
9256 assign(addr1, get_gpr_dw0(r1));
9257 assign(len1, get_gpr_dw0(r1 + 1));
9258 assign(addr3, get_gpr_dw0(r3));
9259 assign(len3, get_gpr_dw0(r3 + 1));
9260
9261 /* len1 == 0 and len3 == 0? Exit */
9262 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +00009263 next_insn_if(binop(Iop_CmpEQ64,binop(Iop_Or64, mkexpr(len1),
9264 mkexpr(len3)), mkU64(0)));
sewardj2019a972011-03-07 16:04:07 +00009265
9266 /* A mux requires both ways to be possible. This is a way to prevent clcle
9267 from reading from addr1 if it should read from the pad. Since the pad
9268 has no address, just read from the instruction, we discard that anyway */
9269 assign(addr1_load,
florian6ad49522011-09-09 02:38:55 +00009270 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
9271 mkU64(guest_IA_curr_instr), mkexpr(addr1)));
sewardj2019a972011-03-07 16:04:07 +00009272
9273 /* same for addr3 */
9274 assign(addr3_load,
florian6ad49522011-09-09 02:38:55 +00009275 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
9276 mkU64(guest_IA_curr_instr), mkexpr(addr3)));
sewardj2019a972011-03-07 16:04:07 +00009277
9278 assign(single1,
florian6ad49522011-09-09 02:38:55 +00009279 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
9280 unop(Iop_64to8, mkexpr(pad2)),
9281 load(Ity_I8, mkexpr(addr1_load))));
sewardj2019a972011-03-07 16:04:07 +00009282
9283 assign(single3,
florian6ad49522011-09-09 02:38:55 +00009284 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
9285 unop(Iop_64to8, mkexpr(pad2)),
9286 load(Ity_I8, mkexpr(addr3_load))));
sewardj2019a972011-03-07 16:04:07 +00009287
9288 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, single1, single3, False);
9289 /* Both fields differ ? */
florian6820ba52012-07-26 02:01:50 +00009290 next_insn_if(binop(Iop_CmpNE8, mkexpr(single1), mkexpr(single3)));
sewardj2019a972011-03-07 16:04:07 +00009291
9292 /* If a length in 0 we must not change this length and the address */
9293 put_gpr_dw0(r1,
florian6ad49522011-09-09 02:38:55 +00009294 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
9295 mkexpr(addr1),
9296 binop(Iop_Add64, mkexpr(addr1), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +00009297
9298 put_gpr_dw0(r1 + 1,
florian6ad49522011-09-09 02:38:55 +00009299 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
9300 mkU64(0), binop(Iop_Sub64, mkexpr(len1), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +00009301
9302 put_gpr_dw0(r3,
florian6ad49522011-09-09 02:38:55 +00009303 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
9304 mkexpr(addr3),
9305 binop(Iop_Add64, mkexpr(addr3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +00009306
9307 put_gpr_dw0(r3 + 1,
florian6ad49522011-09-09 02:38:55 +00009308 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
9309 mkU64(0), binop(Iop_Sub64, mkexpr(len3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +00009310
florian6820ba52012-07-26 02:01:50 +00009311 iterate();
sewardj2019a972011-03-07 16:04:07 +00009312
9313 return "clcle";
9314}
floriana64c2432011-07-16 02:11:50 +00009315
florianb0bf6602012-05-05 00:01:16 +00009316
sewardj2019a972011-03-07 16:04:07 +00009317static void
9318s390_irgen_XC_EX(IRTemp length, IRTemp start1, IRTemp start2)
9319{
florianb0bf6602012-05-05 00:01:16 +00009320 s390_irgen_xonc(Iop_Xor8, length, start1, start2);
9321}
sewardj2019a972011-03-07 16:04:07 +00009322
sewardj2019a972011-03-07 16:04:07 +00009323
florianb0bf6602012-05-05 00:01:16 +00009324static void
9325s390_irgen_NC_EX(IRTemp length, IRTemp start1, IRTemp start2)
9326{
9327 s390_irgen_xonc(Iop_And8, length, start1, start2);
9328}
sewardj2019a972011-03-07 16:04:07 +00009329
sewardj2019a972011-03-07 16:04:07 +00009330
florianb0bf6602012-05-05 00:01:16 +00009331static void
9332s390_irgen_OC_EX(IRTemp length, IRTemp start1, IRTemp start2)
9333{
9334 s390_irgen_xonc(Iop_Or8, length, start1, start2);
sewardj2019a972011-03-07 16:04:07 +00009335}
9336
9337
9338static void
9339s390_irgen_CLC_EX(IRTemp length, IRTemp start1, IRTemp start2)
9340{
9341 IRTemp current1 = newTemp(Ity_I8);
9342 IRTemp current2 = newTemp(Ity_I8);
9343 IRTemp counter = newTemp(Ity_I64);
9344
9345 assign(counter, get_counter_dw0());
9346 put_counter_dw0(mkU64(0));
9347
9348 assign(current1, load(Ity_I8, binop(Iop_Add64, mkexpr(start1),
9349 mkexpr(counter))));
9350 assign(current2, load(Ity_I8, binop(Iop_Add64, mkexpr(start2),
9351 mkexpr(counter))));
9352 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, current1, current2,
9353 False);
9354
9355 /* Both fields differ ? */
florian6820ba52012-07-26 02:01:50 +00009356 next_insn_if(binop(Iop_CmpNE8, mkexpr(current1), mkexpr(current2)));
sewardj2019a972011-03-07 16:04:07 +00009357
9358 /* Check for end of field */
9359 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
florian6820ba52012-07-26 02:01:50 +00009360 iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)));
sewardj2019a972011-03-07 16:04:07 +00009361 put_counter_dw0(mkU64(0));
9362}
9363
9364static void
9365s390_irgen_MVC_EX(IRTemp length, IRTemp start1, IRTemp start2)
9366{
9367 IRTemp counter = newTemp(Ity_I64);
9368
9369 assign(counter, get_counter_dw0());
9370
9371 store(binop(Iop_Add64, mkexpr(start1), mkexpr(counter)),
9372 load(Ity_I8, binop(Iop_Add64, mkexpr(start2), mkexpr(counter))));
9373
9374 /* Check for end of field */
9375 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
florian6820ba52012-07-26 02:01:50 +00009376 iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)));
sewardj2019a972011-03-07 16:04:07 +00009377 put_counter_dw0(mkU64(0));
9378}
9379
florianf87d4fb2012-05-05 02:55:24 +00009380static void
9381s390_irgen_TR_EX(IRTemp length, IRTemp start1, IRTemp start2)
9382{
9383 IRTemp op = newTemp(Ity_I8);
9384 IRTemp op1 = newTemp(Ity_I8);
9385 IRTemp result = newTemp(Ity_I64);
9386 IRTemp counter = newTemp(Ity_I64);
9387
9388 assign(counter, get_counter_dw0());
9389
9390 assign(op, load(Ity_I8, binop(Iop_Add64, mkexpr(start1), mkexpr(counter))));
9391
9392 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)), mkexpr(start2)));
9393
9394 assign(op1, load(Ity_I8, mkexpr(result)));
9395 store(binop(Iop_Add64, mkexpr(start1), mkexpr(counter)), mkexpr(op1));
9396
9397 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
florian6820ba52012-07-26 02:01:50 +00009398 iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)));
florianf87d4fb2012-05-05 02:55:24 +00009399 put_counter_dw0(mkU64(0));
9400}
sewardj2019a972011-03-07 16:04:07 +00009401
9402
9403static void
9404s390_irgen_EX_SS(UChar r, IRTemp addr2,
florian6820ba52012-07-26 02:01:50 +00009405 void (*irgen)(IRTemp length, IRTemp start1, IRTemp start2),
9406 int lensize)
sewardj2019a972011-03-07 16:04:07 +00009407{
9408 struct SS {
9409 unsigned int op : 8;
9410 unsigned int l : 8;
9411 unsigned int b1 : 4;
9412 unsigned int d1 : 12;
9413 unsigned int b2 : 4;
9414 unsigned int d2 : 12;
9415 };
9416 union {
9417 struct SS dec;
9418 unsigned long bytes;
9419 } ss;
9420 IRTemp cond;
9421 IRDirty *d;
9422 IRTemp torun;
9423
9424 IRTemp start1 = newTemp(Ity_I64);
9425 IRTemp start2 = newTemp(Ity_I64);
9426 IRTemp len = newTemp(lensize == 64 ? Ity_I64 : Ity_I32);
9427 cond = newTemp(Ity_I1);
9428 torun = newTemp(Ity_I64);
9429
9430 assign(torun, load(Ity_I64, mkexpr(addr2)));
9431 /* Start with a check that the saved code is still correct */
9432 assign(cond, binop(Iop_CmpNE64, mkexpr(torun), mkU64(last_execute_target)));
9433 /* If not, save the new value */
9434 d = unsafeIRDirty_0_N (0, "s390x_dirtyhelper_EX", &s390x_dirtyhelper_EX,
9435 mkIRExprVec_1(mkexpr(torun)));
9436 d->guard = mkexpr(cond);
9437 stmt(IRStmt_Dirty(d));
9438
9439 /* and restart */
florian428dfdd2012-03-27 03:09:49 +00009440 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TISTART),
9441 mkU64(guest_IA_curr_instr)));
9442 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TILEN), mkU64(4)));
florian6820ba52012-07-26 02:01:50 +00009443 restart_if(mkexpr(cond));
sewardj2019a972011-03-07 16:04:07 +00009444
9445 ss.bytes = last_execute_target;
9446 assign(start1, binop(Iop_Add64, mkU64(ss.dec.d1),
9447 ss.dec.b1 != 0 ? get_gpr_dw0(ss.dec.b1) : mkU64(0)));
9448 assign(start2, binop(Iop_Add64, mkU64(ss.dec.d2),
9449 ss.dec.b2 != 0 ? get_gpr_dw0(ss.dec.b2) : mkU64(0)));
9450 assign(len, unop(lensize == 64 ? Iop_8Uto64 : Iop_8Uto32, binop(Iop_Or8,
9451 r != 0 ? get_gpr_b7(r): mkU8(0), mkU8(ss.dec.l))));
9452 irgen(len, start1, start2);
florian8844a632012-04-13 04:04:06 +00009453
sewardj2019a972011-03-07 16:04:07 +00009454 last_execute_target = 0;
9455}
9456
florian55085f82012-11-21 00:36:55 +00009457static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009458s390_irgen_EX(UChar r1, IRTemp addr2)
9459{
9460 switch(last_execute_target & 0xff00000000000000ULL) {
9461 case 0:
9462 {
9463 /* no code information yet */
9464 IRDirty *d;
9465
9466 /* so safe the code... */
9467 d = unsafeIRDirty_0_N (0, "s390x_dirtyhelper_EX", &s390x_dirtyhelper_EX,
9468 mkIRExprVec_1(load(Ity_I64, mkexpr(addr2))));
9469 stmt(IRStmt_Dirty(d));
9470 /* and restart */
florian428dfdd2012-03-27 03:09:49 +00009471 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TISTART),
9472 mkU64(guest_IA_curr_instr)));
9473 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TILEN), mkU64(4)));
florian6820ba52012-07-26 02:01:50 +00009474 restart_if(IRExpr_Const(IRConst_U1(True)));
9475
sewardj2019a972011-03-07 16:04:07 +00009476 /* we know that this will be invalidated */
florianf9e1ed72012-04-17 02:41:56 +00009477 put_IA(mkaddr_expr(guest_IA_next_instr));
sewardj2019a972011-03-07 16:04:07 +00009478 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +00009479 dis_res->jk_StopHere = Ijk_TInval;
sewardj2019a972011-03-07 16:04:07 +00009480 break;
9481 }
9482
9483 case 0xd200000000000000ULL:
9484 /* special case MVC */
9485 s390_irgen_EX_SS(r1, addr2, s390_irgen_MVC_EX, 64);
9486 return "mvc via ex";
9487
9488 case 0xd500000000000000ULL:
9489 /* special case CLC */
9490 s390_irgen_EX_SS(r1, addr2, s390_irgen_CLC_EX, 64);
9491 return "clc via ex";
9492
9493 case 0xd700000000000000ULL:
9494 /* special case XC */
9495 s390_irgen_EX_SS(r1, addr2, s390_irgen_XC_EX, 32);
9496 return "xc via ex";
9497
florianb0bf6602012-05-05 00:01:16 +00009498 case 0xd600000000000000ULL:
9499 /* special case OC */
9500 s390_irgen_EX_SS(r1, addr2, s390_irgen_OC_EX, 32);
9501 return "oc via ex";
9502
9503 case 0xd400000000000000ULL:
9504 /* special case NC */
9505 s390_irgen_EX_SS(r1, addr2, s390_irgen_NC_EX, 32);
9506 return "nc via ex";
sewardj2019a972011-03-07 16:04:07 +00009507
florianf87d4fb2012-05-05 02:55:24 +00009508 case 0xdc00000000000000ULL:
9509 /* special case TR */
9510 s390_irgen_EX_SS(r1, addr2, s390_irgen_TR_EX, 64);
9511 return "tr via ex";
9512
sewardj2019a972011-03-07 16:04:07 +00009513 default:
9514 {
9515 /* everything else will get a self checking prefix that also checks the
9516 register content */
9517 IRDirty *d;
9518 UChar *bytes;
9519 IRTemp cond;
9520 IRTemp orperand;
9521 IRTemp torun;
9522
9523 cond = newTemp(Ity_I1);
9524 orperand = newTemp(Ity_I64);
9525 torun = newTemp(Ity_I64);
9526
9527 if (r1 == 0)
9528 assign(orperand, mkU64(0));
9529 else
9530 assign(orperand, unop(Iop_8Uto64,get_gpr_b7(r1)));
9531 /* This code is going to be translated */
9532 assign(torun, binop(Iop_Or64, load(Ity_I64, mkexpr(addr2)),
9533 binop(Iop_Shl64, mkexpr(orperand), mkU8(48))));
9534
9535 /* Start with a check that saved code is still correct */
9536 assign(cond, binop(Iop_CmpNE64, mkexpr(torun),
9537 mkU64(last_execute_target)));
9538 /* If not, save the new value */
9539 d = unsafeIRDirty_0_N (0, "s390x_dirtyhelper_EX", &s390x_dirtyhelper_EX,
9540 mkIRExprVec_1(mkexpr(torun)));
9541 d->guard = mkexpr(cond);
9542 stmt(IRStmt_Dirty(d));
9543
9544 /* and restart */
florian428dfdd2012-03-27 03:09:49 +00009545 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TISTART), mkU64(guest_IA_curr_instr)));
9546 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TILEN), mkU64(4)));
florian6820ba52012-07-26 02:01:50 +00009547 restart_if(mkexpr(cond));
sewardj2019a972011-03-07 16:04:07 +00009548
9549 /* Now comes the actual translation */
9550 bytes = (UChar *) &last_execute_target;
9551 s390_decode_and_irgen(bytes, ((((bytes[0] >> 6) + 1) >> 1) + 1) << 1,
9552 dis_res);
sewardj7ee97522011-05-09 21:45:04 +00009553 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00009554 vex_printf(" which was executed by\n");
9555 /* dont make useless translations in the next execute */
9556 last_execute_target = 0;
9557 }
9558 }
9559 return "ex";
9560}
9561
florian55085f82012-11-21 00:36:55 +00009562static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009563s390_irgen_EXRL(UChar r1, UInt offset)
9564{
9565 IRTemp addr = newTemp(Ity_I64);
9566 /* we might save one round trip because we know the target */
9567 if (!last_execute_target)
9568 last_execute_target = *(ULong *)(HWord)
9569 (guest_IA_curr_instr + offset * 2UL);
9570 assign(addr, mkU64(guest_IA_curr_instr + offset * 2UL));
9571 s390_irgen_EX(r1, addr);
9572 return "exrl";
9573}
9574
florian55085f82012-11-21 00:36:55 +00009575static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009576s390_irgen_IPM(UChar r1)
9577{
9578 // As long as we dont support SPM, lets just assume 0 as program mask
9579 put_gpr_b4(r1, unop(Iop_32to8, binop(Iop_Or32, mkU32(0 /* program mask */),
9580 binop(Iop_Shl32, s390_call_calculate_cc(), mkU8(4)))));
9581
9582 return "ipm";
9583}
9584
9585
florian55085f82012-11-21 00:36:55 +00009586static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009587s390_irgen_SRST(UChar r1, UChar r2)
9588{
9589 IRTemp address = newTemp(Ity_I64);
9590 IRTemp next = newTemp(Ity_I64);
9591 IRTemp delim = newTemp(Ity_I8);
9592 IRTemp counter = newTemp(Ity_I64);
9593 IRTemp byte = newTemp(Ity_I8);
9594
9595 assign(address, get_gpr_dw0(r2));
9596 assign(next, get_gpr_dw0(r1));
9597
9598 assign(counter, get_counter_dw0());
9599 put_counter_dw0(mkU64(0));
9600
9601 // start = next? CC=2 and out r1 and r2 unchanged
9602 s390_cc_set(2);
9603 put_gpr_dw0(r2, binop(Iop_Sub64, mkexpr(address), mkexpr(counter)));
florian6820ba52012-07-26 02:01:50 +00009604 next_insn_if(binop(Iop_CmpEQ64, mkexpr(address), mkexpr(next)));
sewardj2019a972011-03-07 16:04:07 +00009605
9606 assign(byte, load(Ity_I8, mkexpr(address)));
9607 assign(delim, get_gpr_b7(0));
9608
9609 // byte = delim? CC=1, R1=address
9610 s390_cc_set(1);
9611 put_gpr_dw0(r1, mkexpr(address));
florian6820ba52012-07-26 02:01:50 +00009612 next_insn_if(binop(Iop_CmpEQ8, mkexpr(delim), mkexpr(byte)));
sewardj2019a972011-03-07 16:04:07 +00009613
9614 // else: all equal, no end yet, loop
9615 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
9616 put_gpr_dw0(r1, mkexpr(next));
9617 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(address), mkU64(1)));
floriancf87c942012-07-25 00:52:21 +00009618
florian6820ba52012-07-26 02:01:50 +00009619 iterate();
sewardj2019a972011-03-07 16:04:07 +00009620
9621 return "srst";
9622}
9623
florian55085f82012-11-21 00:36:55 +00009624static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009625s390_irgen_CLST(UChar r1, UChar r2)
9626{
9627 IRTemp address1 = newTemp(Ity_I64);
9628 IRTemp address2 = newTemp(Ity_I64);
9629 IRTemp end = newTemp(Ity_I8);
9630 IRTemp counter = newTemp(Ity_I64);
9631 IRTemp byte1 = newTemp(Ity_I8);
9632 IRTemp byte2 = newTemp(Ity_I8);
9633
9634 assign(address1, get_gpr_dw0(r1));
9635 assign(address2, get_gpr_dw0(r2));
9636 assign(end, get_gpr_b7(0));
9637 assign(counter, get_counter_dw0());
9638 put_counter_dw0(mkU64(0));
9639 assign(byte1, load(Ity_I8, mkexpr(address1)));
9640 assign(byte2, load(Ity_I8, mkexpr(address2)));
9641
9642 // end in both? all equal, reset r1 and r2 to start values
9643 s390_cc_set(0);
9644 put_gpr_dw0(r1, binop(Iop_Sub64, mkexpr(address1), mkexpr(counter)));
9645 put_gpr_dw0(r2, binop(Iop_Sub64, mkexpr(address2), mkexpr(counter)));
florian6820ba52012-07-26 02:01:50 +00009646 next_insn_if(binop(Iop_CmpEQ8, mkU8(0),
9647 binop(Iop_Or8,
9648 binop(Iop_Xor8, mkexpr(byte1), mkexpr(end)),
9649 binop(Iop_Xor8, mkexpr(byte2), mkexpr(end)))));
sewardj2019a972011-03-07 16:04:07 +00009650
9651 put_gpr_dw0(r1, mkexpr(address1));
9652 put_gpr_dw0(r2, mkexpr(address2));
9653
9654 // End found in string1
9655 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +00009656 next_insn_if(binop(Iop_CmpEQ8, mkexpr(end), mkexpr(byte1)));
sewardj2019a972011-03-07 16:04:07 +00009657
9658 // End found in string2
9659 s390_cc_set(2);
florian6820ba52012-07-26 02:01:50 +00009660 next_insn_if(binop(Iop_CmpEQ8, mkexpr(end), mkexpr(byte2)));
sewardj2019a972011-03-07 16:04:07 +00009661
9662 // string1 < string2
9663 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +00009664 next_insn_if(binop(Iop_CmpLT32U, unop(Iop_8Uto32, mkexpr(byte1)),
9665 unop(Iop_8Uto32, mkexpr(byte2))));
sewardj2019a972011-03-07 16:04:07 +00009666
9667 // string2 < string1
9668 s390_cc_set(2);
florian6820ba52012-07-26 02:01:50 +00009669 next_insn_if(binop(Iop_CmpLT32U, unop(Iop_8Uto32, mkexpr(byte2)),
9670 unop(Iop_8Uto32, mkexpr(byte1))));
sewardj2019a972011-03-07 16:04:07 +00009671
9672 // else: all equal, no end yet, loop
9673 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
9674 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), mkU64(1)));
9675 put_gpr_dw0(r2, binop(Iop_Add64, get_gpr_dw0(r2), mkU64(1)));
floriancf87c942012-07-25 00:52:21 +00009676
florian6820ba52012-07-26 02:01:50 +00009677 iterate();
sewardj2019a972011-03-07 16:04:07 +00009678
9679 return "clst";
9680}
9681
9682static void
9683s390_irgen_load_multiple_32bit(UChar r1, UChar r3, IRTemp op2addr)
9684{
9685 UChar reg;
9686 IRTemp addr = newTemp(Ity_I64);
9687
9688 assign(addr, mkexpr(op2addr));
9689 reg = r1;
9690 do {
9691 IRTemp old = addr;
9692
9693 reg %= 16;
9694 put_gpr_w1(reg, load(Ity_I32, mkexpr(addr)));
9695 addr = newTemp(Ity_I64);
9696 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
9697 reg++;
9698 } while (reg != (r3 + 1));
9699}
9700
florian55085f82012-11-21 00:36:55 +00009701static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009702s390_irgen_LM(UChar r1, UChar r3, IRTemp op2addr)
9703{
9704 s390_irgen_load_multiple_32bit(r1, r3, op2addr);
9705
9706 return "lm";
9707}
9708
florian55085f82012-11-21 00:36:55 +00009709static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009710s390_irgen_LMY(UChar r1, UChar r3, IRTemp op2addr)
9711{
9712 s390_irgen_load_multiple_32bit(r1, r3, op2addr);
9713
9714 return "lmy";
9715}
9716
florian55085f82012-11-21 00:36:55 +00009717static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009718s390_irgen_LMH(UChar r1, UChar r3, IRTemp op2addr)
9719{
9720 UChar reg;
9721 IRTemp addr = newTemp(Ity_I64);
9722
9723 assign(addr, mkexpr(op2addr));
9724 reg = r1;
9725 do {
9726 IRTemp old = addr;
9727
9728 reg %= 16;
9729 put_gpr_w0(reg, load(Ity_I32, mkexpr(addr)));
9730 addr = newTemp(Ity_I64);
9731 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
9732 reg++;
9733 } while (reg != (r3 + 1));
9734
9735 return "lmh";
9736}
9737
florian55085f82012-11-21 00:36:55 +00009738static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009739s390_irgen_LMG(UChar r1, UChar r3, IRTemp op2addr)
9740{
9741 UChar reg;
9742 IRTemp addr = newTemp(Ity_I64);
9743
9744 assign(addr, mkexpr(op2addr));
9745 reg = r1;
9746 do {
9747 IRTemp old = addr;
9748
9749 reg %= 16;
9750 put_gpr_dw0(reg, load(Ity_I64, mkexpr(addr)));
9751 addr = newTemp(Ity_I64);
9752 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(8)));
9753 reg++;
9754 } while (reg != (r3 + 1));
9755
9756 return "lmg";
9757}
9758
9759static void
9760s390_irgen_store_multiple_32bit(UChar r1, UChar r3, IRTemp op2addr)
9761{
9762 UChar reg;
9763 IRTemp addr = newTemp(Ity_I64);
9764
9765 assign(addr, mkexpr(op2addr));
9766 reg = r1;
9767 do {
9768 IRTemp old = addr;
9769
9770 reg %= 16;
9771 store(mkexpr(addr), get_gpr_w1(reg));
9772 addr = newTemp(Ity_I64);
9773 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
9774 reg++;
9775 } while( reg != (r3 + 1));
9776}
9777
florian55085f82012-11-21 00:36:55 +00009778static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009779s390_irgen_STM(UChar r1, UChar r3, IRTemp op2addr)
9780{
9781 s390_irgen_store_multiple_32bit(r1, r3, op2addr);
9782
9783 return "stm";
9784}
9785
florian55085f82012-11-21 00:36:55 +00009786static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009787s390_irgen_STMY(UChar r1, UChar r3, IRTemp op2addr)
9788{
9789 s390_irgen_store_multiple_32bit(r1, r3, op2addr);
9790
9791 return "stmy";
9792}
9793
florian55085f82012-11-21 00:36:55 +00009794static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009795s390_irgen_STMH(UChar r1, UChar r3, IRTemp op2addr)
9796{
9797 UChar reg;
9798 IRTemp addr = newTemp(Ity_I64);
9799
9800 assign(addr, mkexpr(op2addr));
9801 reg = r1;
9802 do {
9803 IRTemp old = addr;
9804
9805 reg %= 16;
9806 store(mkexpr(addr), get_gpr_w0(reg));
9807 addr = newTemp(Ity_I64);
9808 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
9809 reg++;
9810 } while( reg != (r3 + 1));
9811
9812 return "stmh";
9813}
9814
florian55085f82012-11-21 00:36:55 +00009815static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009816s390_irgen_STMG(UChar r1, UChar r3, IRTemp op2addr)
9817{
9818 UChar reg;
9819 IRTemp addr = newTemp(Ity_I64);
9820
9821 assign(addr, mkexpr(op2addr));
9822 reg = r1;
9823 do {
9824 IRTemp old = addr;
9825
9826 reg %= 16;
9827 store(mkexpr(addr), get_gpr_dw0(reg));
9828 addr = newTemp(Ity_I64);
9829 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(8)));
9830 reg++;
9831 } while( reg != (r3 + 1));
9832
9833 return "stmg";
9834}
9835
9836static void
florianb0bf6602012-05-05 00:01:16 +00009837s390_irgen_xonc(IROp op, IRTemp length, IRTemp start1, IRTemp start2)
sewardj2019a972011-03-07 16:04:07 +00009838{
9839 IRTemp old1 = newTemp(Ity_I8);
9840 IRTemp old2 = newTemp(Ity_I8);
9841 IRTemp new1 = newTemp(Ity_I8);
9842 IRTemp counter = newTemp(Ity_I32);
9843 IRTemp addr1 = newTemp(Ity_I64);
9844
9845 assign(counter, get_counter_w0());
9846
9847 assign(addr1, binop(Iop_Add64, mkexpr(start1),
9848 unop(Iop_32Uto64, mkexpr(counter))));
9849
9850 assign(old1, load(Ity_I8, mkexpr(addr1)));
9851 assign(old2, load(Ity_I8, binop(Iop_Add64, mkexpr(start2),
9852 unop(Iop_32Uto64,mkexpr(counter)))));
9853 assign(new1, binop(op, mkexpr(old1), mkexpr(old2)));
9854
9855 /* Special case: xc is used to zero memory */
sewardj2019a972011-03-07 16:04:07 +00009856 if (op == Iop_Xor8) {
9857 store(mkexpr(addr1),
florian6ad49522011-09-09 02:38:55 +00009858 mkite(binop(Iop_CmpEQ64, mkexpr(start1), mkexpr(start2)),
9859 mkU8(0), mkexpr(new1)));
sewardj2019a972011-03-07 16:04:07 +00009860 } else
9861 store(mkexpr(addr1), mkexpr(new1));
9862 put_counter_w1(binop(Iop_Or32, unop(Iop_8Uto32, mkexpr(new1)),
9863 get_counter_w1()));
9864
9865 /* Check for end of field */
9866 put_counter_w0(binop(Iop_Add32, mkexpr(counter), mkU32(1)));
florian6820ba52012-07-26 02:01:50 +00009867 iterate_if(binop(Iop_CmpNE32, mkexpr(counter), mkexpr(length)));
sewardj2019a972011-03-07 16:04:07 +00009868 s390_cc_thunk_put1(S390_CC_OP_BITWISE, mktemp(Ity_I32, get_counter_w1()),
9869 False);
9870 put_counter_dw0(mkU64(0));
9871}
9872
florian55085f82012-11-21 00:36:55 +00009873static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009874s390_irgen_XC(UChar length, IRTemp start1, IRTemp start2)
9875{
florianb0bf6602012-05-05 00:01:16 +00009876 IRTemp len = newTemp(Ity_I32);
9877
9878 assign(len, mkU32(length));
9879 s390_irgen_xonc(Iop_Xor8, len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +00009880
9881 return "xc";
9882}
9883
sewardjb63967e2011-03-24 08:50:04 +00009884static void
9885s390_irgen_XC_sameloc(UChar length, UChar b, UShort d)
9886{
9887 IRTemp counter = newTemp(Ity_I32);
9888 IRTemp start = newTemp(Ity_I64);
9889 IRTemp addr = newTemp(Ity_I64);
9890
9891 assign(start,
9892 binop(Iop_Add64, mkU64(d), b != 0 ? get_gpr_dw0(b) : mkU64(0)));
9893
9894 if (length < 8) {
9895 UInt i;
9896
9897 for (i = 0; i <= length; ++i) {
9898 store(binop(Iop_Add64, mkexpr(start), mkU64(i)), mkU8(0));
9899 }
9900 } else {
9901 assign(counter, get_counter_w0());
9902
9903 assign(addr, binop(Iop_Add64, mkexpr(start),
9904 unop(Iop_32Uto64, mkexpr(counter))));
9905
9906 store(mkexpr(addr), mkU8(0));
9907
9908 /* Check for end of field */
9909 put_counter_w0(binop(Iop_Add32, mkexpr(counter), mkU32(1)));
florian6820ba52012-07-26 02:01:50 +00009910 iterate_if(binop(Iop_CmpNE32, mkexpr(counter), mkU32(length)));
sewardjb63967e2011-03-24 08:50:04 +00009911
9912 /* Reset counter */
9913 put_counter_dw0(mkU64(0));
9914 }
9915
9916 s390_cc_thunk_put1(S390_CC_OP_BITWISE, mktemp(Ity_I32, mkU32(0)), False);
9917
sewardj7ee97522011-05-09 21:45:04 +00009918 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardjb63967e2011-03-24 08:50:04 +00009919 s390_disasm(ENC3(MNM, UDLB, UDXB), "xc", d, length, b, d, 0, b);
9920}
9921
florian55085f82012-11-21 00:36:55 +00009922static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009923s390_irgen_NC(UChar length, IRTemp start1, IRTemp start2)
9924{
florianb0bf6602012-05-05 00:01:16 +00009925 IRTemp len = newTemp(Ity_I32);
9926
9927 assign(len, mkU32(length));
9928 s390_irgen_xonc(Iop_And8, len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +00009929
9930 return "nc";
9931}
9932
florian55085f82012-11-21 00:36:55 +00009933static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009934s390_irgen_OC(UChar length, IRTemp start1, IRTemp start2)
9935{
florianb0bf6602012-05-05 00:01:16 +00009936 IRTemp len = newTemp(Ity_I32);
9937
9938 assign(len, mkU32(length));
9939 s390_irgen_xonc(Iop_Or8, len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +00009940
9941 return "oc";
9942}
9943
9944
florian55085f82012-11-21 00:36:55 +00009945static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009946s390_irgen_MVC(UChar length, IRTemp start1, IRTemp start2)
9947{
florian79e839e2012-05-05 02:20:30 +00009948 IRTemp len = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00009949
florian79e839e2012-05-05 02:20:30 +00009950 assign(len, mkU64(length));
9951 s390_irgen_MVC_EX(len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +00009952
9953 return "mvc";
9954}
9955
florian55085f82012-11-21 00:36:55 +00009956static const HChar *
florianb0c9a132011-09-08 15:37:39 +00009957s390_irgen_MVCL(UChar r1, UChar r2)
9958{
9959 IRTemp addr1 = newTemp(Ity_I64);
9960 IRTemp addr2 = newTemp(Ity_I64);
9961 IRTemp addr2_load = newTemp(Ity_I64);
9962 IRTemp r1p1 = newTemp(Ity_I32); /* contents of r1 + 1 */
9963 IRTemp r2p1 = newTemp(Ity_I32); /* contents of r2 + 1 */
9964 IRTemp len1 = newTemp(Ity_I32);
9965 IRTemp len2 = newTemp(Ity_I32);
9966 IRTemp pad = newTemp(Ity_I8);
9967 IRTemp single = newTemp(Ity_I8);
9968
9969 assign(addr1, get_gpr_dw0(r1));
9970 assign(r1p1, get_gpr_w1(r1 + 1));
9971 assign(len1, binop(Iop_And32, mkexpr(r1p1), mkU32(0x00ffffff)));
9972 assign(addr2, get_gpr_dw0(r2));
9973 assign(r2p1, get_gpr_w1(r2 + 1));
9974 assign(len2, binop(Iop_And32, mkexpr(r2p1), mkU32(0x00ffffff)));
9975 assign(pad, get_gpr_b4(r2 + 1));
9976
9977 /* len1 == 0 ? */
9978 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len2, False);
florian6820ba52012-07-26 02:01:50 +00009979 next_insn_if(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)));
florianb0c9a132011-09-08 15:37:39 +00009980
9981 /* Check for destructive overlap:
9982 addr1 > addr2 && addr2 + len1 > addr1 && (addr2 + len2) > addr1 */
9983 s390_cc_set(3);
9984 IRTemp cond1 = newTemp(Ity_I32);
9985 assign(cond1, unop(Iop_1Uto32,
9986 binop(Iop_CmpLT64U, mkexpr(addr2), mkexpr(addr1))));
9987 IRTemp cond2 = newTemp(Ity_I32);
9988 assign(cond2, unop(Iop_1Uto32,
9989 binop(Iop_CmpLT64U, mkexpr(addr1),
9990 binop(Iop_Add64, mkexpr(addr2),
9991 unop(Iop_32Uto64, mkexpr(len1))))));
9992 IRTemp cond3 = newTemp(Ity_I32);
9993 assign(cond3, unop(Iop_1Uto32,
9994 binop(Iop_CmpLT64U,
9995 mkexpr(addr1),
9996 binop(Iop_Add64, mkexpr(addr2),
9997 unop(Iop_32Uto64, mkexpr(len2))))));
9998
florian6820ba52012-07-26 02:01:50 +00009999 next_insn_if(binop(Iop_CmpEQ32,
10000 binop(Iop_And32,
10001 binop(Iop_And32, mkexpr(cond1), mkexpr(cond2)),
10002 mkexpr(cond3)),
10003 mkU32(1)));
florianb0c9a132011-09-08 15:37:39 +000010004
10005 /* See s390_irgen_CLCL for explanation why we cannot load directly
10006 and need two steps. */
10007 assign(addr2_load,
10008 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
10009 mkU64(guest_IA_curr_instr), mkexpr(addr2)));
10010 assign(single,
10011 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
10012 mkexpr(pad), load(Ity_I8, mkexpr(addr2_load))));
10013
10014 store(mkexpr(addr1), mkexpr(single));
10015
10016 /* Update addr1 and len1 */
10017 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkU64(1)));
10018 put_gpr_w1(r1 + 1, binop(Iop_Sub32, mkexpr(r1p1), mkU32(1)));
10019
10020 /* Update addr2 and len2 */
10021 put_gpr_dw0(r2,
10022 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
10023 mkexpr(addr2),
10024 binop(Iop_Add64, mkexpr(addr2), mkU64(1))));
10025
10026 /* When updating len2 we must not modify bits (r2+1)[0:39] */
10027 put_gpr_w1(r2 + 1,
10028 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
10029 binop(Iop_And32, mkexpr(r2p1), mkU32(0xFF000000u)),
10030 binop(Iop_Sub32, mkexpr(r2p1), mkU32(1))));
10031
10032 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len2, False);
florian6820ba52012-07-26 02:01:50 +000010033 iterate_if(binop(Iop_CmpNE32, mkexpr(len1), mkU32(1)));
florianb0c9a132011-09-08 15:37:39 +000010034
10035 return "mvcl";
10036}
10037
10038
florian55085f82012-11-21 00:36:55 +000010039static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010040s390_irgen_MVCLE(UChar r1, UChar r3, IRTemp pad2)
10041{
10042 IRTemp addr1, addr3, addr3_load, len1, len3, single;
10043
10044 addr1 = newTemp(Ity_I64);
10045 addr3 = newTemp(Ity_I64);
10046 addr3_load = newTemp(Ity_I64);
10047 len1 = newTemp(Ity_I64);
10048 len3 = newTemp(Ity_I64);
10049 single = newTemp(Ity_I8);
10050
10051 assign(addr1, get_gpr_dw0(r1));
10052 assign(len1, get_gpr_dw0(r1 + 1));
10053 assign(addr3, get_gpr_dw0(r3));
10054 assign(len3, get_gpr_dw0(r3 + 1));
10055
10056 // len1 == 0 ?
10057 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len3, False);
florian6820ba52012-07-26 02:01:50 +000010058 next_insn_if(binop(Iop_CmpEQ64,mkexpr(len1), mkU64(0)));
sewardj2019a972011-03-07 16:04:07 +000010059
10060 /* This is a hack to prevent mvcle from reading from addr3 if it
10061 should read from the pad. Since the pad has no address, just
10062 read from the instruction, we discard that anyway */
10063 assign(addr3_load,
florian6ad49522011-09-09 02:38:55 +000010064 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
10065 mkU64(guest_IA_curr_instr), mkexpr(addr3)));
sewardj2019a972011-03-07 16:04:07 +000010066
10067 assign(single,
florian6ad49522011-09-09 02:38:55 +000010068 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
10069 unop(Iop_64to8, mkexpr(pad2)),
10070 load(Ity_I8, mkexpr(addr3_load))));
sewardj2019a972011-03-07 16:04:07 +000010071 store(mkexpr(addr1), mkexpr(single));
10072
10073 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkU64(1)));
10074
10075 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkU64(1)));
10076
10077 put_gpr_dw0(r3,
florian6ad49522011-09-09 02:38:55 +000010078 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
10079 mkexpr(addr3),
10080 binop(Iop_Add64, mkexpr(addr3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +000010081
10082 put_gpr_dw0(r3 + 1,
florian6ad49522011-09-09 02:38:55 +000010083 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
10084 mkU64(0), binop(Iop_Sub64, mkexpr(len3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +000010085
sewardj2019a972011-03-07 16:04:07 +000010086 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len3, False);
florian6820ba52012-07-26 02:01:50 +000010087 iterate_if(binop(Iop_CmpNE64, mkexpr(len1), mkU64(1)));
sewardj2019a972011-03-07 16:04:07 +000010088
10089 return "mvcle";
10090}
10091
florian55085f82012-11-21 00:36:55 +000010092static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010093s390_irgen_MVST(UChar r1, UChar r2)
10094{
10095 IRTemp addr1 = newTemp(Ity_I64);
10096 IRTemp addr2 = newTemp(Ity_I64);
10097 IRTemp end = newTemp(Ity_I8);
10098 IRTemp byte = newTemp(Ity_I8);
10099 IRTemp counter = newTemp(Ity_I64);
10100
10101 assign(addr1, get_gpr_dw0(r1));
10102 assign(addr2, get_gpr_dw0(r2));
10103 assign(counter, get_counter_dw0());
10104 assign(end, get_gpr_b7(0));
10105 assign(byte, load(Ity_I8, binop(Iop_Add64, mkexpr(addr2),mkexpr(counter))));
10106 store(binop(Iop_Add64,mkexpr(addr1),mkexpr(counter)), mkexpr(byte));
10107
10108 // We use unlimited as cpu-determined number
10109 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
florian6820ba52012-07-26 02:01:50 +000010110 iterate_if(binop(Iop_CmpNE8, mkexpr(end), mkexpr(byte)));
sewardj2019a972011-03-07 16:04:07 +000010111
10112 // and always set cc=1 at the end + update r1
10113 s390_cc_set(1);
10114 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(counter)));
10115 put_counter_dw0(mkU64(0));
10116
10117 return "mvst";
10118}
10119
10120static void
10121s390_irgen_divide_64to32(IROp op, UChar r1, IRTemp op2)
10122{
10123 IRTemp op1 = newTemp(Ity_I64);
10124 IRTemp result = newTemp(Ity_I64);
10125
10126 assign(op1, binop(Iop_32HLto64,
10127 get_gpr_w1(r1), // high 32 bits
10128 get_gpr_w1(r1 + 1))); // low 32 bits
10129 assign(result, binop(op, mkexpr(op1), mkexpr(op2)));
10130 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result))); // remainder
10131 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result))); // quotient
10132}
10133
10134static void
10135s390_irgen_divide_128to64(IROp op, UChar r1, IRTemp op2)
10136{
10137 IRTemp op1 = newTemp(Ity_I128);
10138 IRTemp result = newTemp(Ity_I128);
10139
10140 assign(op1, binop(Iop_64HLto128,
10141 get_gpr_dw0(r1), // high 64 bits
10142 get_gpr_dw0(r1 + 1))); // low 64 bits
10143 assign(result, binop(op, mkexpr(op1), mkexpr(op2)));
10144 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result))); // remainder
10145 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result))); // quotient
10146}
10147
10148static void
10149s390_irgen_divide_64to64(IROp op, UChar r1, IRTemp op2)
10150{
10151 IRTemp op1 = newTemp(Ity_I64);
10152 IRTemp result = newTemp(Ity_I128);
10153
10154 assign(op1, get_gpr_dw0(r1 + 1));
10155 assign(result, binop(op, mkexpr(op1), mkexpr(op2)));
10156 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result))); // remainder
10157 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result))); // quotient
10158}
10159
florian55085f82012-11-21 00:36:55 +000010160static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010161s390_irgen_DR(UChar r1, UChar r2)
10162{
10163 IRTemp op2 = newTemp(Ity_I32);
10164
10165 assign(op2, get_gpr_w1(r2));
10166
10167 s390_irgen_divide_64to32(Iop_DivModS64to32, r1, op2);
10168
10169 return "dr";
10170}
10171
florian55085f82012-11-21 00:36:55 +000010172static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010173s390_irgen_D(UChar r1, IRTemp op2addr)
10174{
10175 IRTemp op2 = newTemp(Ity_I32);
10176
10177 assign(op2, load(Ity_I32, mkexpr(op2addr)));
10178
10179 s390_irgen_divide_64to32(Iop_DivModS64to32, r1, op2);
10180
10181 return "d";
10182}
10183
florian55085f82012-11-21 00:36:55 +000010184static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010185s390_irgen_DLR(UChar r1, UChar r2)
10186{
10187 IRTemp op2 = newTemp(Ity_I32);
10188
10189 assign(op2, get_gpr_w1(r2));
10190
10191 s390_irgen_divide_64to32(Iop_DivModU64to32, r1, op2);
10192
florian7cd1cde2012-08-16 23:57:43 +000010193 return "dlr";
sewardj2019a972011-03-07 16:04:07 +000010194}
10195
florian55085f82012-11-21 00:36:55 +000010196static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010197s390_irgen_DL(UChar r1, IRTemp op2addr)
10198{
10199 IRTemp op2 = newTemp(Ity_I32);
10200
10201 assign(op2, load(Ity_I32, mkexpr(op2addr)));
10202
10203 s390_irgen_divide_64to32(Iop_DivModU64to32, r1, op2);
10204
10205 return "dl";
10206}
10207
florian55085f82012-11-21 00:36:55 +000010208static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010209s390_irgen_DLG(UChar r1, IRTemp op2addr)
10210{
10211 IRTemp op2 = newTemp(Ity_I64);
10212
10213 assign(op2, load(Ity_I64, mkexpr(op2addr)));
10214
10215 s390_irgen_divide_128to64(Iop_DivModU128to64, r1, op2);
10216
10217 return "dlg";
10218}
10219
florian55085f82012-11-21 00:36:55 +000010220static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010221s390_irgen_DLGR(UChar r1, UChar r2)
10222{
10223 IRTemp op2 = newTemp(Ity_I64);
10224
10225 assign(op2, get_gpr_dw0(r2));
10226
10227 s390_irgen_divide_128to64(Iop_DivModU128to64, r1, op2);
10228
10229 return "dlgr";
10230}
10231
florian55085f82012-11-21 00:36:55 +000010232static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010233s390_irgen_DSGR(UChar r1, UChar r2)
10234{
10235 IRTemp op2 = newTemp(Ity_I64);
10236
10237 assign(op2, get_gpr_dw0(r2));
10238
10239 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
10240
10241 return "dsgr";
10242}
10243
florian55085f82012-11-21 00:36:55 +000010244static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010245s390_irgen_DSG(UChar r1, IRTemp op2addr)
10246{
10247 IRTemp op2 = newTemp(Ity_I64);
10248
10249 assign(op2, load(Ity_I64, mkexpr(op2addr)));
10250
10251 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
10252
10253 return "dsg";
10254}
10255
florian55085f82012-11-21 00:36:55 +000010256static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010257s390_irgen_DSGFR(UChar r1, UChar r2)
10258{
10259 IRTemp op2 = newTemp(Ity_I64);
10260
10261 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
10262
10263 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
10264
10265 return "dsgfr";
10266}
10267
florian55085f82012-11-21 00:36:55 +000010268static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010269s390_irgen_DSGF(UChar r1, IRTemp op2addr)
10270{
10271 IRTemp op2 = newTemp(Ity_I64);
10272
10273 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
10274
10275 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
10276
10277 return "dsgf";
10278}
10279
10280static void
10281s390_irgen_load_ar_multiple(UChar r1, UChar r3, IRTemp op2addr)
10282{
10283 UChar reg;
10284 IRTemp addr = newTemp(Ity_I64);
10285
10286 assign(addr, mkexpr(op2addr));
10287 reg = r1;
10288 do {
10289 IRTemp old = addr;
10290
10291 reg %= 16;
10292 put_ar_w0(reg, load(Ity_I32, mkexpr(addr)));
10293 addr = newTemp(Ity_I64);
10294 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
10295 reg++;
10296 } while (reg != (r3 + 1));
10297}
10298
florian55085f82012-11-21 00:36:55 +000010299static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010300s390_irgen_LAM(UChar r1, UChar r3, IRTemp op2addr)
10301{
10302 s390_irgen_load_ar_multiple(r1, r3, op2addr);
10303
10304 return "lam";
10305}
10306
florian55085f82012-11-21 00:36:55 +000010307static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010308s390_irgen_LAMY(UChar r1, UChar r3, IRTemp op2addr)
10309{
10310 s390_irgen_load_ar_multiple(r1, r3, op2addr);
10311
10312 return "lamy";
10313}
10314
10315static void
10316s390_irgen_store_ar_multiple(UChar r1, UChar r3, IRTemp op2addr)
10317{
10318 UChar reg;
10319 IRTemp addr = newTemp(Ity_I64);
10320
10321 assign(addr, mkexpr(op2addr));
10322 reg = r1;
10323 do {
10324 IRTemp old = addr;
10325
10326 reg %= 16;
10327 store(mkexpr(addr), get_ar_w0(reg));
10328 addr = newTemp(Ity_I64);
10329 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
10330 reg++;
10331 } while (reg != (r3 + 1));
10332}
10333
florian55085f82012-11-21 00:36:55 +000010334static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010335s390_irgen_STAM(UChar r1, UChar r3, IRTemp op2addr)
10336{
10337 s390_irgen_store_ar_multiple(r1, r3, op2addr);
10338
10339 return "stam";
10340}
10341
florian55085f82012-11-21 00:36:55 +000010342static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010343s390_irgen_STAMY(UChar r1, UChar r3, IRTemp op2addr)
10344{
10345 s390_irgen_store_ar_multiple(r1, r3, op2addr);
10346
10347 return "stamy";
10348}
10349
10350
10351/* Implementation for 32-bit compare-and-swap */
10352static void
10353s390_irgen_cas_32(UChar r1, UChar r3, IRTemp op2addr)
10354{
10355 IRCAS *cas;
10356 IRTemp op1 = newTemp(Ity_I32);
10357 IRTemp old_mem = newTemp(Ity_I32);
10358 IRTemp op3 = newTemp(Ity_I32);
10359 IRTemp result = newTemp(Ity_I32);
10360 IRTemp nequal = newTemp(Ity_I1);
10361
10362 assign(op1, get_gpr_w1(r1));
10363 assign(op3, get_gpr_w1(r3));
10364
10365 /* The first and second operands are compared. If they are equal,
10366 the third operand is stored at the second- operand location. */
10367 cas = mkIRCAS(IRTemp_INVALID, old_mem,
10368 Iend_BE, mkexpr(op2addr),
10369 NULL, mkexpr(op1), /* expected value */
10370 NULL, mkexpr(op3) /* new value */);
10371 stmt(IRStmt_CAS(cas));
10372
10373 /* Set CC. Operands compared equal -> 0, else 1. */
10374 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(old_mem)));
10375 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
10376
10377 /* If operands were equal (cc == 0) just store the old value op1 in r1.
10378 Otherwise, store the old_value from memory in r1 and yield. */
10379 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
10380 put_gpr_w1(r1, mkite(mkexpr(nequal), mkexpr(old_mem), mkexpr(op1)));
florian6820ba52012-07-26 02:01:50 +000010381 yield_if(mkexpr(nequal));
sewardj2019a972011-03-07 16:04:07 +000010382}
10383
florian55085f82012-11-21 00:36:55 +000010384static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010385s390_irgen_CS(UChar r1, UChar r3, IRTemp op2addr)
10386{
10387 s390_irgen_cas_32(r1, r3, op2addr);
10388
10389 return "cs";
10390}
10391
florian55085f82012-11-21 00:36:55 +000010392static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010393s390_irgen_CSY(UChar r1, UChar r3, IRTemp op2addr)
10394{
10395 s390_irgen_cas_32(r1, r3, op2addr);
10396
10397 return "csy";
10398}
10399
florian55085f82012-11-21 00:36:55 +000010400static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010401s390_irgen_CSG(UChar r1, UChar r3, IRTemp op2addr)
10402{
10403 IRCAS *cas;
10404 IRTemp op1 = newTemp(Ity_I64);
10405 IRTemp old_mem = newTemp(Ity_I64);
10406 IRTemp op3 = newTemp(Ity_I64);
10407 IRTemp result = newTemp(Ity_I64);
10408 IRTemp nequal = newTemp(Ity_I1);
10409
10410 assign(op1, get_gpr_dw0(r1));
10411 assign(op3, get_gpr_dw0(r3));
10412
10413 /* The first and second operands are compared. If they are equal,
10414 the third operand is stored at the second- operand location. */
10415 cas = mkIRCAS(IRTemp_INVALID, old_mem,
10416 Iend_BE, mkexpr(op2addr),
10417 NULL, mkexpr(op1), /* expected value */
10418 NULL, mkexpr(op3) /* new value */);
10419 stmt(IRStmt_CAS(cas));
10420
10421 /* Set CC. Operands compared equal -> 0, else 1. */
10422 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(old_mem)));
10423 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
10424
10425 /* If operands were equal (cc == 0) just store the old value op1 in r1.
10426 Otherwise, store the old_value from memory in r1 and yield. */
10427 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
10428 put_gpr_dw0(r1, mkite(mkexpr(nequal), mkexpr(old_mem), mkexpr(op1)));
florian6820ba52012-07-26 02:01:50 +000010429 yield_if(mkexpr(nequal));
sewardj2019a972011-03-07 16:04:07 +000010430
10431 return "csg";
10432}
10433
florian448cbba2012-06-06 02:26:01 +000010434/* Implementation for 32-bit compare-double-and-swap */
10435static void
10436s390_irgen_cdas_32(UChar r1, UChar r3, IRTemp op2addr)
10437{
10438 IRCAS *cas;
10439 IRTemp op1_high = newTemp(Ity_I32);
10440 IRTemp op1_low = newTemp(Ity_I32);
10441 IRTemp old_mem_high = newTemp(Ity_I32);
10442 IRTemp old_mem_low = newTemp(Ity_I32);
10443 IRTemp op3_high = newTemp(Ity_I32);
10444 IRTemp op3_low = newTemp(Ity_I32);
10445 IRTemp result = newTemp(Ity_I32);
10446 IRTemp nequal = newTemp(Ity_I1);
10447
10448 assign(op1_high, get_gpr_w1(r1));
10449 assign(op1_low, get_gpr_w1(r1+1));
10450 assign(op3_high, get_gpr_w1(r3));
10451 assign(op3_low, get_gpr_w1(r3+1));
10452
10453 /* The first and second operands are compared. If they are equal,
10454 the third operand is stored at the second-operand location. */
10455 cas = mkIRCAS(old_mem_high, old_mem_low,
10456 Iend_BE, mkexpr(op2addr),
10457 mkexpr(op1_high), mkexpr(op1_low), /* expected value */
10458 mkexpr(op3_high), mkexpr(op3_low) /* new value */);
10459 stmt(IRStmt_CAS(cas));
10460
10461 /* Set CC. Operands compared equal -> 0, else 1. */
10462 assign(result, unop(Iop_1Uto32,
10463 binop(Iop_CmpNE32,
10464 binop(Iop_Or32,
10465 binop(Iop_Xor32, mkexpr(op1_high), mkexpr(old_mem_high)),
10466 binop(Iop_Xor32, mkexpr(op1_low), mkexpr(old_mem_low))),
10467 mkU32(0))));
10468
10469 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
10470
10471 /* If operands were equal (cc == 0) just store the old value op1 in r1.
10472 Otherwise, store the old_value from memory in r1 and yield. */
10473 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
10474 put_gpr_w1(r1, mkite(mkexpr(nequal), mkexpr(old_mem_high), mkexpr(op1_high)));
10475 put_gpr_w1(r1+1, mkite(mkexpr(nequal), mkexpr(old_mem_low), mkexpr(op1_low)));
florian6820ba52012-07-26 02:01:50 +000010476 yield_if(mkexpr(nequal));
florian448cbba2012-06-06 02:26:01 +000010477}
10478
florian55085f82012-11-21 00:36:55 +000010479static const HChar *
florian448cbba2012-06-06 02:26:01 +000010480s390_irgen_CDS(UChar r1, UChar r3, IRTemp op2addr)
10481{
10482 s390_irgen_cdas_32(r1, r3, op2addr);
10483
10484 return "cds";
10485}
10486
florian55085f82012-11-21 00:36:55 +000010487static const HChar *
florian448cbba2012-06-06 02:26:01 +000010488s390_irgen_CDSY(UChar r1, UChar r3, IRTemp op2addr)
10489{
10490 s390_irgen_cdas_32(r1, r3, op2addr);
10491
10492 return "cdsy";
10493}
10494
florian55085f82012-11-21 00:36:55 +000010495static const HChar *
florian448cbba2012-06-06 02:26:01 +000010496s390_irgen_CDSG(UChar r1, UChar r3, IRTemp op2addr)
10497{
10498 IRCAS *cas;
10499 IRTemp op1_high = newTemp(Ity_I64);
10500 IRTemp op1_low = newTemp(Ity_I64);
10501 IRTemp old_mem_high = newTemp(Ity_I64);
10502 IRTemp old_mem_low = newTemp(Ity_I64);
10503 IRTemp op3_high = newTemp(Ity_I64);
10504 IRTemp op3_low = newTemp(Ity_I64);
10505 IRTemp result = newTemp(Ity_I64);
10506 IRTemp nequal = newTemp(Ity_I1);
10507
10508 assign(op1_high, get_gpr_dw0(r1));
10509 assign(op1_low, get_gpr_dw0(r1+1));
10510 assign(op3_high, get_gpr_dw0(r3));
10511 assign(op3_low, get_gpr_dw0(r3+1));
10512
10513 /* The first and second operands are compared. If they are equal,
10514 the third operand is stored at the second-operand location. */
10515 cas = mkIRCAS(old_mem_high, old_mem_low,
10516 Iend_BE, mkexpr(op2addr),
10517 mkexpr(op1_high), mkexpr(op1_low), /* expected value */
10518 mkexpr(op3_high), mkexpr(op3_low) /* new value */);
10519 stmt(IRStmt_CAS(cas));
10520
10521 /* Set CC. Operands compared equal -> 0, else 1. */
10522 assign(result, unop(Iop_1Uto64,
10523 binop(Iop_CmpNE64,
10524 binop(Iop_Or64,
10525 binop(Iop_Xor64, mkexpr(op1_high), mkexpr(old_mem_high)),
10526 binop(Iop_Xor64, mkexpr(op1_low), mkexpr(old_mem_low))),
10527 mkU64(0))));
10528
10529 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
10530
10531 /* If operands were equal (cc == 0) just store the old value op1 in r1.
10532 Otherwise, store the old_value from memory in r1 and yield. */
10533 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
10534 put_gpr_dw0(r1, mkite(mkexpr(nequal), mkexpr(old_mem_high), mkexpr(op1_high)));
10535 put_gpr_dw0(r1+1, mkite(mkexpr(nequal), mkexpr(old_mem_low), mkexpr(op1_low)));
florian6820ba52012-07-26 02:01:50 +000010536 yield_if(mkexpr(nequal));
10537
florian448cbba2012-06-06 02:26:01 +000010538 return "cdsg";
10539}
10540
sewardj2019a972011-03-07 16:04:07 +000010541
10542/* Binary floating point */
10543
florian55085f82012-11-21 00:36:55 +000010544static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010545s390_irgen_AXBR(UChar r1, UChar r2)
10546{
10547 IRTemp op1 = newTemp(Ity_F128);
10548 IRTemp op2 = newTemp(Ity_F128);
10549 IRTemp result = newTemp(Ity_F128);
florian125e20d2012-10-07 15:42:37 +000010550 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000010551
10552 assign(op1, get_fpr_pair(r1));
10553 assign(op2, get_fpr_pair(r2));
floriandb4fcaa2012-09-05 19:54:08 +000010554 assign(result, triop(Iop_AddF128, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +000010555 mkexpr(op2)));
10556 put_fpr_pair(r1, mkexpr(result));
10557
10558 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
10559
10560 return "axbr";
10561}
10562
10563/* The result of a Iop_CmdFxx operation is a condition code. It is
10564 encoded using the values defined in type IRCmpFxxResult.
10565 Before we can store the condition code into the guest state (or do
10566 anything else with it for that matter) we need to convert it to
10567 the encoding that s390 uses. This is what this function does.
10568
10569 s390 VEX b6 b2 b0 cc.1 cc.0
10570 0 0x40 EQ 1 0 0 0 0
10571 1 0x01 LT 0 0 1 0 1
10572 2 0x00 GT 0 0 0 1 0
10573 3 0x45 Unordered 1 1 1 1 1
10574
10575 The following bits from the VEX encoding are interesting:
10576 b0, b2, b6 with b0 being the LSB. We observe:
10577
10578 cc.0 = b0;
10579 cc.1 = b2 | (~b0 & ~b6)
10580
10581 with cc being the s390 condition code.
10582*/
10583static IRExpr *
10584convert_vex_fpcc_to_s390(IRTemp vex_cc)
10585{
10586 IRTemp cc0 = newTemp(Ity_I32);
10587 IRTemp cc1 = newTemp(Ity_I32);
10588 IRTemp b0 = newTemp(Ity_I32);
10589 IRTemp b2 = newTemp(Ity_I32);
10590 IRTemp b6 = newTemp(Ity_I32);
10591
10592 assign(b0, binop(Iop_And32, mkexpr(vex_cc), mkU32(1)));
10593 assign(b2, binop(Iop_And32, binop(Iop_Shr32, mkexpr(vex_cc), mkU8(2)),
10594 mkU32(1)));
10595 assign(b6, binop(Iop_And32, binop(Iop_Shr32, mkexpr(vex_cc), mkU8(6)),
10596 mkU32(1)));
10597
10598 assign(cc0, mkexpr(b0));
10599 assign(cc1, binop(Iop_Or32, mkexpr(b2),
10600 binop(Iop_And32,
10601 binop(Iop_Sub32, mkU32(1), mkexpr(b0)), /* ~b0 */
10602 binop(Iop_Sub32, mkU32(1), mkexpr(b6)) /* ~b6 */
10603 )));
10604
10605 return binop(Iop_Or32, mkexpr(cc0), binop(Iop_Shl32, mkexpr(cc1), mkU8(1)));
10606}
10607
florian55085f82012-11-21 00:36:55 +000010608static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010609s390_irgen_CEBR(UChar r1, UChar r2)
10610{
10611 IRTemp op1 = newTemp(Ity_F32);
10612 IRTemp op2 = newTemp(Ity_F32);
10613 IRTemp cc_vex = newTemp(Ity_I32);
10614 IRTemp cc_s390 = newTemp(Ity_I32);
10615
10616 assign(op1, get_fpr_w0(r1));
10617 assign(op2, get_fpr_w0(r2));
10618 assign(cc_vex, binop(Iop_CmpF32, mkexpr(op1), mkexpr(op2)));
10619
10620 assign(cc_s390, convert_vex_fpcc_to_s390(cc_vex));
10621 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
10622
10623 return "cebr";
10624}
10625
florian55085f82012-11-21 00:36:55 +000010626static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010627s390_irgen_CDBR(UChar r1, UChar r2)
10628{
10629 IRTemp op1 = newTemp(Ity_F64);
10630 IRTemp op2 = newTemp(Ity_F64);
10631 IRTemp cc_vex = newTemp(Ity_I32);
10632 IRTemp cc_s390 = newTemp(Ity_I32);
10633
10634 assign(op1, get_fpr_dw0(r1));
10635 assign(op2, get_fpr_dw0(r2));
10636 assign(cc_vex, binop(Iop_CmpF64, mkexpr(op1), mkexpr(op2)));
10637
10638 assign(cc_s390, convert_vex_fpcc_to_s390(cc_vex));
10639 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
10640
10641 return "cdbr";
10642}
10643
florian55085f82012-11-21 00:36:55 +000010644static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010645s390_irgen_CXBR(UChar r1, UChar r2)
10646{
10647 IRTemp op1 = newTemp(Ity_F128);
10648 IRTemp op2 = newTemp(Ity_F128);
10649 IRTemp cc_vex = newTemp(Ity_I32);
10650 IRTemp cc_s390 = newTemp(Ity_I32);
10651
10652 assign(op1, get_fpr_pair(r1));
10653 assign(op2, get_fpr_pair(r2));
10654 assign(cc_vex, binop(Iop_CmpF128, mkexpr(op1), mkexpr(op2)));
10655
10656 assign(cc_s390, convert_vex_fpcc_to_s390(cc_vex));
10657 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
10658
10659 return "cxbr";
10660}
10661
florian55085f82012-11-21 00:36:55 +000010662static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010663s390_irgen_CEB(UChar r1, IRTemp op2addr)
10664{
10665 IRTemp op1 = newTemp(Ity_F32);
10666 IRTemp op2 = newTemp(Ity_F32);
10667 IRTemp cc_vex = newTemp(Ity_I32);
10668 IRTemp cc_s390 = newTemp(Ity_I32);
10669
10670 assign(op1, get_fpr_w0(r1));
10671 assign(op2, load(Ity_F32, mkexpr(op2addr)));
10672 assign(cc_vex, binop(Iop_CmpF32, mkexpr(op1), mkexpr(op2)));
10673
10674 assign(cc_s390, convert_vex_fpcc_to_s390(cc_vex));
10675 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
10676
10677 return "ceb";
10678}
10679
florian55085f82012-11-21 00:36:55 +000010680static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010681s390_irgen_CDB(UChar r1, IRTemp op2addr)
10682{
10683 IRTemp op1 = newTemp(Ity_F64);
10684 IRTemp op2 = newTemp(Ity_F64);
10685 IRTemp cc_vex = newTemp(Ity_I32);
10686 IRTemp cc_s390 = newTemp(Ity_I32);
10687
10688 assign(op1, get_fpr_dw0(r1));
10689 assign(op2, load(Ity_F64, mkexpr(op2addr)));
10690 assign(cc_vex, binop(Iop_CmpF64, mkexpr(op1), mkexpr(op2)));
10691
10692 assign(cc_s390, convert_vex_fpcc_to_s390(cc_vex));
10693 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
10694
10695 return "cdb";
10696}
10697
florian55085f82012-11-21 00:36:55 +000010698static const HChar *
florian4b8efad2012-09-02 18:07:08 +000010699s390_irgen_CXFBR(UChar m3 __attribute__((unused)),
10700 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000010701{
10702 IRTemp op2 = newTemp(Ity_I32);
10703
10704 assign(op2, get_gpr_w1(r2));
10705 put_fpr_pair(r1, unop(Iop_I32StoF128, mkexpr(op2)));
10706
10707 return "cxfbr";
10708}
10709
florian55085f82012-11-21 00:36:55 +000010710static const HChar *
floriand2129202012-09-01 20:01:39 +000010711s390_irgen_CXLFBR(UChar m3 __attribute__((unused)),
10712 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
florian1c8f7ff2012-09-01 00:12:11 +000010713{
floriane75dafa2012-09-01 17:54:09 +000010714 if (! s390_host_has_fpext) {
10715 emulation_failure(EmFail_S390X_fpext);
10716 } else {
10717 IRTemp op2 = newTemp(Ity_I32);
florian1c8f7ff2012-09-01 00:12:11 +000010718
floriane75dafa2012-09-01 17:54:09 +000010719 assign(op2, get_gpr_w1(r2));
10720 put_fpr_pair(r1, unop(Iop_I32UtoF128, mkexpr(op2)));
10721 }
florian1c8f7ff2012-09-01 00:12:11 +000010722 return "cxlfbr";
10723}
10724
10725
florian55085f82012-11-21 00:36:55 +000010726static const HChar *
florian4b8efad2012-09-02 18:07:08 +000010727s390_irgen_CXGBR(UChar m3 __attribute__((unused)),
10728 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000010729{
10730 IRTemp op2 = newTemp(Ity_I64);
10731
10732 assign(op2, get_gpr_dw0(r2));
10733 put_fpr_pair(r1, unop(Iop_I64StoF128, mkexpr(op2)));
10734
10735 return "cxgbr";
10736}
10737
florian55085f82012-11-21 00:36:55 +000010738static const HChar *
floriand2129202012-09-01 20:01:39 +000010739s390_irgen_CXLGBR(UChar m3 __attribute__((unused)),
10740 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
florian1c8f7ff2012-09-01 00:12:11 +000010741{
floriane75dafa2012-09-01 17:54:09 +000010742 if (! s390_host_has_fpext) {
10743 emulation_failure(EmFail_S390X_fpext);
10744 } else {
10745 IRTemp op2 = newTemp(Ity_I64);
florian1c8f7ff2012-09-01 00:12:11 +000010746
floriane75dafa2012-09-01 17:54:09 +000010747 assign(op2, get_gpr_dw0(r2));
10748 put_fpr_pair(r1, unop(Iop_I64UtoF128, mkexpr(op2)));
10749 }
florian1c8f7ff2012-09-01 00:12:11 +000010750 return "cxlgbr";
10751}
10752
florian55085f82012-11-21 00:36:55 +000010753static const HChar *
florian4b8efad2012-09-02 18:07:08 +000010754s390_irgen_CFXBR(UChar m3, UChar m4 __attribute__((unused)),
10755 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000010756{
10757 IRTemp op = newTemp(Ity_F128);
10758 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +000010759 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +000010760
10761 assign(op, get_fpr_pair(r2));
florian19e00772012-09-06 03:13:22 +000010762 assign(result, binop(Iop_F128toI32S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +000010763 mkexpr(op)));
10764 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +000010765 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_INT_32, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +000010766
10767 return "cfxbr";
10768}
10769
florian55085f82012-11-21 00:36:55 +000010770static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +000010771s390_irgen_CLFXBR(UChar m3, UChar m4 __attribute__((unused)),
10772 UChar r1, UChar r2)
10773{
floriane75dafa2012-09-01 17:54:09 +000010774 if (! s390_host_has_fpext) {
10775 emulation_failure(EmFail_S390X_fpext);
10776 } else {
10777 IRTemp op = newTemp(Ity_F128);
10778 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +000010779 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +000010780
floriane75dafa2012-09-01 17:54:09 +000010781 assign(op, get_fpr_pair(r2));
florian19e00772012-09-06 03:13:22 +000010782 assign(result, binop(Iop_F128toI32U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +000010783 mkexpr(op)));
10784 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +000010785 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_UINT_32, op, rounding_mode);
floriane75dafa2012-09-01 17:54:09 +000010786 }
florian1c8f7ff2012-09-01 00:12:11 +000010787 return "clfxbr";
10788}
10789
10790
florian55085f82012-11-21 00:36:55 +000010791static const HChar *
florian4b8efad2012-09-02 18:07:08 +000010792s390_irgen_CGXBR(UChar m3, UChar m4 __attribute__((unused)),
10793 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000010794{
10795 IRTemp op = newTemp(Ity_F128);
10796 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +000010797 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +000010798
10799 assign(op, get_fpr_pair(r2));
florian19e00772012-09-06 03:13:22 +000010800 assign(result, binop(Iop_F128toI64S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +000010801 mkexpr(op)));
10802 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +000010803 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_INT_64, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +000010804
10805 return "cgxbr";
10806}
10807
florian55085f82012-11-21 00:36:55 +000010808static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +000010809s390_irgen_CLGXBR(UChar m3, UChar m4 __attribute__((unused)),
10810 UChar r1, UChar r2)
10811{
floriane75dafa2012-09-01 17:54:09 +000010812 if (! s390_host_has_fpext) {
10813 emulation_failure(EmFail_S390X_fpext);
10814 } else {
10815 IRTemp op = newTemp(Ity_F128);
10816 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +000010817 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +000010818
floriane75dafa2012-09-01 17:54:09 +000010819 assign(op, get_fpr_pair(r2));
florian19e00772012-09-06 03:13:22 +000010820 assign(result, binop(Iop_F128toI64U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +000010821 mkexpr(op)));
10822 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +000010823 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_UINT_64, op,
10824 rounding_mode);
floriane75dafa2012-09-01 17:54:09 +000010825 }
florian1c8f7ff2012-09-01 00:12:11 +000010826 return "clgxbr";
10827}
10828
florian55085f82012-11-21 00:36:55 +000010829static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010830s390_irgen_DXBR(UChar r1, UChar r2)
10831{
10832 IRTemp op1 = newTemp(Ity_F128);
10833 IRTemp op2 = newTemp(Ity_F128);
10834 IRTemp result = newTemp(Ity_F128);
florian125e20d2012-10-07 15:42:37 +000010835 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000010836
10837 assign(op1, get_fpr_pair(r1));
10838 assign(op2, get_fpr_pair(r2));
floriandb4fcaa2012-09-05 19:54:08 +000010839 assign(result, triop(Iop_DivF128, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +000010840 mkexpr(op2)));
10841 put_fpr_pair(r1, mkexpr(result));
10842
10843 return "dxbr";
10844}
10845
florian55085f82012-11-21 00:36:55 +000010846static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010847s390_irgen_LTXBR(UChar r1, UChar r2)
10848{
10849 IRTemp result = newTemp(Ity_F128);
10850
10851 assign(result, get_fpr_pair(r2));
10852 put_fpr_pair(r1, mkexpr(result));
10853 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
10854
10855 return "ltxbr";
10856}
10857
florian55085f82012-11-21 00:36:55 +000010858static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010859s390_irgen_LCXBR(UChar r1, UChar r2)
10860{
10861 IRTemp result = newTemp(Ity_F128);
10862
10863 assign(result, unop(Iop_NegF128, get_fpr_pair(r2)));
10864 put_fpr_pair(r1, mkexpr(result));
10865 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
10866
10867 return "lcxbr";
10868}
10869
florian55085f82012-11-21 00:36:55 +000010870static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010871s390_irgen_LXDBR(UChar r1, UChar r2)
10872{
10873 IRTemp op = newTemp(Ity_F64);
10874
10875 assign(op, get_fpr_dw0(r2));
10876 put_fpr_pair(r1, unop(Iop_F64toF128, mkexpr(op)));
10877
10878 return "lxdbr";
10879}
10880
florian55085f82012-11-21 00:36:55 +000010881static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010882s390_irgen_LXEBR(UChar r1, UChar r2)
10883{
10884 IRTemp op = newTemp(Ity_F32);
10885
10886 assign(op, get_fpr_w0(r2));
10887 put_fpr_pair(r1, unop(Iop_F32toF128, mkexpr(op)));
10888
10889 return "lxebr";
10890}
10891
florian55085f82012-11-21 00:36:55 +000010892static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010893s390_irgen_LXDB(UChar r1, IRTemp op2addr)
10894{
10895 IRTemp op = newTemp(Ity_F64);
10896
10897 assign(op, load(Ity_F64, mkexpr(op2addr)));
10898 put_fpr_pair(r1, unop(Iop_F64toF128, mkexpr(op)));
10899
10900 return "lxdb";
10901}
10902
florian55085f82012-11-21 00:36:55 +000010903static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010904s390_irgen_LXEB(UChar r1, IRTemp op2addr)
10905{
10906 IRTemp op = newTemp(Ity_F32);
10907
10908 assign(op, load(Ity_F32, mkexpr(op2addr)));
10909 put_fpr_pair(r1, unop(Iop_F32toF128, mkexpr(op)));
10910
10911 return "lxeb";
10912}
10913
florian55085f82012-11-21 00:36:55 +000010914static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010915s390_irgen_LNEBR(UChar r1, UChar r2)
10916{
10917 IRTemp result = newTemp(Ity_F32);
10918
10919 assign(result, unop(Iop_NegF32, unop(Iop_AbsF32, get_fpr_w0(r2))));
10920 put_fpr_w0(r1, mkexpr(result));
10921 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_32, result);
10922
10923 return "lnebr";
10924}
10925
florian55085f82012-11-21 00:36:55 +000010926static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010927s390_irgen_LNDBR(UChar r1, UChar r2)
10928{
10929 IRTemp result = newTemp(Ity_F64);
10930
10931 assign(result, unop(Iop_NegF64, unop(Iop_AbsF64, get_fpr_dw0(r2))));
10932 put_fpr_dw0(r1, mkexpr(result));
10933 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_64, result);
10934
10935 return "lndbr";
10936}
10937
florian55085f82012-11-21 00:36:55 +000010938static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010939s390_irgen_LNXBR(UChar r1, UChar r2)
10940{
10941 IRTemp result = newTemp(Ity_F128);
10942
10943 assign(result, unop(Iop_NegF128, unop(Iop_AbsF128, get_fpr_pair(r2))));
10944 put_fpr_pair(r1, mkexpr(result));
10945 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
10946
10947 return "lnxbr";
10948}
10949
florian55085f82012-11-21 00:36:55 +000010950static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010951s390_irgen_LPEBR(UChar r1, UChar r2)
10952{
10953 IRTemp result = newTemp(Ity_F32);
10954
10955 assign(result, unop(Iop_AbsF32, get_fpr_w0(r2)));
10956 put_fpr_w0(r1, mkexpr(result));
10957 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_32, result);
10958
10959 return "lpebr";
10960}
10961
florian55085f82012-11-21 00:36:55 +000010962static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010963s390_irgen_LPDBR(UChar r1, UChar r2)
10964{
10965 IRTemp result = newTemp(Ity_F64);
10966
10967 assign(result, unop(Iop_AbsF64, get_fpr_dw0(r2)));
10968 put_fpr_dw0(r1, mkexpr(result));
10969 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_64, result);
10970
10971 return "lpdbr";
10972}
10973
florian55085f82012-11-21 00:36:55 +000010974static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010975s390_irgen_LPXBR(UChar r1, UChar r2)
10976{
10977 IRTemp result = newTemp(Ity_F128);
10978
10979 assign(result, unop(Iop_AbsF128, get_fpr_pair(r2)));
10980 put_fpr_pair(r1, mkexpr(result));
10981 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
10982
10983 return "lpxbr";
10984}
10985
florian55085f82012-11-21 00:36:55 +000010986static const HChar *
florian4b8efad2012-09-02 18:07:08 +000010987s390_irgen_LDXBR(UChar m3, UChar m4 __attribute__((unused)),
10988 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000010989{
florian125e20d2012-10-07 15:42:37 +000010990 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian12b0bca2012-09-05 20:05:20 +000010991 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +000010992 m3 = S390_BFP_ROUND_PER_FPC;
florian12b0bca2012-09-05 20:05:20 +000010993 }
sewardj2019a972011-03-07 16:04:07 +000010994 IRTemp result = newTemp(Ity_F64);
10995
floriandb4fcaa2012-09-05 19:54:08 +000010996 assign(result, binop(Iop_F128toF64, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +000010997 get_fpr_pair(r2)));
sewardj2019a972011-03-07 16:04:07 +000010998 put_fpr_dw0(r1, mkexpr(result));
10999
11000 return "ldxbr";
11001}
11002
florian55085f82012-11-21 00:36:55 +000011003static const HChar *
florian4b8efad2012-09-02 18:07:08 +000011004s390_irgen_LEXBR(UChar m3, UChar m4 __attribute__((unused)),
11005 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000011006{
florian125e20d2012-10-07 15:42:37 +000011007 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian12b0bca2012-09-05 20:05:20 +000011008 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +000011009 m3 = S390_BFP_ROUND_PER_FPC;
florian12b0bca2012-09-05 20:05:20 +000011010 }
sewardj2019a972011-03-07 16:04:07 +000011011 IRTemp result = newTemp(Ity_F32);
11012
floriandb4fcaa2012-09-05 19:54:08 +000011013 assign(result, binop(Iop_F128toF32, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +000011014 get_fpr_pair(r2)));
sewardj2019a972011-03-07 16:04:07 +000011015 put_fpr_w0(r1, mkexpr(result));
11016
11017 return "lexbr";
11018}
11019
florian55085f82012-11-21 00:36:55 +000011020static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011021s390_irgen_MXBR(UChar r1, UChar r2)
11022{
11023 IRTemp op1 = newTemp(Ity_F128);
11024 IRTemp op2 = newTemp(Ity_F128);
11025 IRTemp result = newTemp(Ity_F128);
florian125e20d2012-10-07 15:42:37 +000011026 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011027
11028 assign(op1, get_fpr_pair(r1));
11029 assign(op2, get_fpr_pair(r2));
floriandb4fcaa2012-09-05 19:54:08 +000011030 assign(result, triop(Iop_MulF128, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +000011031 mkexpr(op2)));
11032 put_fpr_pair(r1, mkexpr(result));
11033
11034 return "mxbr";
11035}
11036
florian55085f82012-11-21 00:36:55 +000011037static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011038s390_irgen_MAEBR(UChar r1, UChar r3, UChar r2)
11039{
florian125e20d2012-10-07 15:42:37 +000011040 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
florian847684d2012-09-05 04:19:09 +000011041
floriandb4fcaa2012-09-05 19:54:08 +000011042 put_fpr_w0(r1, qop(Iop_MAddF32, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000011043 get_fpr_w0(r3), get_fpr_w0(r2), get_fpr_w0(r1)));
sewardj2019a972011-03-07 16:04:07 +000011044
11045 return "maebr";
11046}
11047
florian55085f82012-11-21 00:36:55 +000011048static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011049s390_irgen_MADBR(UChar r1, UChar r3, UChar r2)
11050{
florian125e20d2012-10-07 15:42:37 +000011051 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
florian847684d2012-09-05 04:19:09 +000011052
floriandb4fcaa2012-09-05 19:54:08 +000011053 put_fpr_dw0(r1, qop(Iop_MAddF64, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000011054 get_fpr_dw0(r3), get_fpr_dw0(r2), get_fpr_dw0(r1)));
sewardj2019a972011-03-07 16:04:07 +000011055
11056 return "madbr";
11057}
11058
florian55085f82012-11-21 00:36:55 +000011059static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011060s390_irgen_MAEB(UChar r3, IRTemp op2addr, UChar r1)
11061{
11062 IRExpr *op2 = load(Ity_F32, mkexpr(op2addr));
florian125e20d2012-10-07 15:42:37 +000011063 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011064
floriandb4fcaa2012-09-05 19:54:08 +000011065 put_fpr_w0(r1, qop(Iop_MAddF32, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000011066 get_fpr_w0(r3), op2, get_fpr_w0(r1)));
sewardj2019a972011-03-07 16:04:07 +000011067
11068 return "maeb";
11069}
11070
florian55085f82012-11-21 00:36:55 +000011071static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011072s390_irgen_MADB(UChar r3, IRTemp op2addr, UChar r1)
11073{
11074 IRExpr *op2 = load(Ity_F64, mkexpr(op2addr));
florian125e20d2012-10-07 15:42:37 +000011075 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011076
floriandb4fcaa2012-09-05 19:54:08 +000011077 put_fpr_dw0(r1, qop(Iop_MAddF64, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000011078 get_fpr_dw0(r3), op2, get_fpr_dw0(r1)));
sewardj2019a972011-03-07 16:04:07 +000011079
11080 return "madb";
11081}
11082
florian55085f82012-11-21 00:36:55 +000011083static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011084s390_irgen_MSEBR(UChar r1, UChar r3, UChar r2)
11085{
florian125e20d2012-10-07 15:42:37 +000011086 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
florian847684d2012-09-05 04:19:09 +000011087
floriandb4fcaa2012-09-05 19:54:08 +000011088 put_fpr_w0(r1, qop(Iop_MSubF32, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000011089 get_fpr_w0(r3), get_fpr_w0(r2), get_fpr_w0(r1)));
sewardj2019a972011-03-07 16:04:07 +000011090
11091 return "msebr";
11092}
11093
florian55085f82012-11-21 00:36:55 +000011094static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011095s390_irgen_MSDBR(UChar r1, UChar r3, UChar r2)
11096{
florian125e20d2012-10-07 15:42:37 +000011097 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
florian847684d2012-09-05 04:19:09 +000011098
floriandb4fcaa2012-09-05 19:54:08 +000011099 put_fpr_dw0(r1, qop(Iop_MSubF64, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000011100 get_fpr_dw0(r3), get_fpr_dw0(r2), get_fpr_dw0(r1)));
sewardj2019a972011-03-07 16:04:07 +000011101
11102 return "msdbr";
11103}
11104
florian55085f82012-11-21 00:36:55 +000011105static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011106s390_irgen_MSEB(UChar r3, IRTemp op2addr, UChar r1)
11107{
11108 IRExpr *op2 = load(Ity_F32, mkexpr(op2addr));
florian125e20d2012-10-07 15:42:37 +000011109 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011110
floriandb4fcaa2012-09-05 19:54:08 +000011111 put_fpr_w0(r1, qop(Iop_MSubF32, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000011112 get_fpr_w0(r3), op2, get_fpr_w0(r1)));
sewardj2019a972011-03-07 16:04:07 +000011113
11114 return "mseb";
11115}
11116
florian55085f82012-11-21 00:36:55 +000011117static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011118s390_irgen_MSDB(UChar r3, IRTemp op2addr, UChar r1)
11119{
11120 IRExpr *op2 = load(Ity_F64, mkexpr(op2addr));
florian125e20d2012-10-07 15:42:37 +000011121 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011122
floriandb4fcaa2012-09-05 19:54:08 +000011123 put_fpr_dw0(r1, qop(Iop_MSubF64, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000011124 get_fpr_dw0(r3), op2, get_fpr_dw0(r1)));
sewardj2019a972011-03-07 16:04:07 +000011125
11126 return "msdb";
11127}
11128
florian55085f82012-11-21 00:36:55 +000011129static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011130s390_irgen_SQEBR(UChar r1, UChar r2)
11131{
11132 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +000011133 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011134
floriandb4fcaa2012-09-05 19:54:08 +000011135 assign(result, binop(Iop_SqrtF32, mkexpr(rounding_mode), get_fpr_w0(r2)));
sewardj2019a972011-03-07 16:04:07 +000011136 put_fpr_w0(r1, mkexpr(result));
11137
11138 return "sqebr";
11139}
11140
florian55085f82012-11-21 00:36:55 +000011141static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011142s390_irgen_SQDBR(UChar r1, UChar r2)
11143{
11144 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +000011145 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011146
floriandb4fcaa2012-09-05 19:54:08 +000011147 assign(result, binop(Iop_SqrtF64, mkexpr(rounding_mode), get_fpr_dw0(r2)));
sewardj2019a972011-03-07 16:04:07 +000011148 put_fpr_dw0(r1, mkexpr(result));
11149
11150 return "sqdbr";
11151}
11152
florian55085f82012-11-21 00:36:55 +000011153static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011154s390_irgen_SQXBR(UChar r1, UChar r2)
11155{
11156 IRTemp result = newTemp(Ity_F128);
florian125e20d2012-10-07 15:42:37 +000011157 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011158
floriandb4fcaa2012-09-05 19:54:08 +000011159 assign(result, binop(Iop_SqrtF128, mkexpr(rounding_mode),
11160 get_fpr_pair(r2)));
sewardj2019a972011-03-07 16:04:07 +000011161 put_fpr_pair(r1, mkexpr(result));
11162
11163 return "sqxbr";
11164}
11165
florian55085f82012-11-21 00:36:55 +000011166static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011167s390_irgen_SQEB(UChar r1, IRTemp op2addr)
11168{
11169 IRTemp op = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +000011170 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011171
11172 assign(op, load(Ity_F32, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +000011173 put_fpr_w0(r1, binop(Iop_SqrtF32, mkexpr(rounding_mode), mkexpr(op)));
sewardj2019a972011-03-07 16:04:07 +000011174
11175 return "sqeb";
11176}
11177
florian55085f82012-11-21 00:36:55 +000011178static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011179s390_irgen_SQDB(UChar r1, IRTemp op2addr)
11180{
11181 IRTemp op = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +000011182 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011183
11184 assign(op, load(Ity_F64, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +000011185 put_fpr_dw0(r1, binop(Iop_SqrtF64, mkexpr(rounding_mode), mkexpr(op)));
sewardj2019a972011-03-07 16:04:07 +000011186
11187 return "sqdb";
11188}
11189
florian55085f82012-11-21 00:36:55 +000011190static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011191s390_irgen_SXBR(UChar r1, UChar r2)
11192{
11193 IRTemp op1 = newTemp(Ity_F128);
11194 IRTemp op2 = newTemp(Ity_F128);
11195 IRTemp result = newTemp(Ity_F128);
florian125e20d2012-10-07 15:42:37 +000011196 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011197
11198 assign(op1, get_fpr_pair(r1));
11199 assign(op2, get_fpr_pair(r2));
floriandb4fcaa2012-09-05 19:54:08 +000011200 assign(result, triop(Iop_SubF128, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +000011201 mkexpr(op2)));
11202 put_fpr_pair(r1, mkexpr(result));
11203 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
11204
11205 return "sxbr";
11206}
11207
florian55085f82012-11-21 00:36:55 +000011208static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011209s390_irgen_TCEB(UChar r1, IRTemp op2addr)
11210{
11211 IRTemp value = newTemp(Ity_F32);
11212
11213 assign(value, get_fpr_w0(r1));
11214
11215 s390_cc_thunk_putFZ(S390_CC_OP_BFP_TDC_32, value, op2addr);
11216
11217 return "tceb";
11218}
11219
florian55085f82012-11-21 00:36:55 +000011220static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011221s390_irgen_TCDB(UChar r1, IRTemp op2addr)
11222{
11223 IRTemp value = newTemp(Ity_F64);
11224
11225 assign(value, get_fpr_dw0(r1));
11226
11227 s390_cc_thunk_putFZ(S390_CC_OP_BFP_TDC_64, value, op2addr);
11228
11229 return "tcdb";
11230}
11231
florian55085f82012-11-21 00:36:55 +000011232static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011233s390_irgen_TCXB(UChar r1, IRTemp op2addr)
11234{
11235 IRTemp value = newTemp(Ity_F128);
11236
11237 assign(value, get_fpr_pair(r1));
11238
11239 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_TDC_128, value, op2addr);
11240
11241 return "tcxb";
11242}
11243
florian55085f82012-11-21 00:36:55 +000011244static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011245s390_irgen_LCDFR(UChar r1, UChar r2)
11246{
11247 IRTemp result = newTemp(Ity_F64);
11248
11249 assign(result, unop(Iop_NegF64, get_fpr_dw0(r2)));
11250 put_fpr_dw0(r1, mkexpr(result));
11251
11252 return "lcdfr";
11253}
11254
florian55085f82012-11-21 00:36:55 +000011255static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011256s390_irgen_LNDFR(UChar r1, UChar r2)
11257{
11258 IRTemp result = newTemp(Ity_F64);
11259
11260 assign(result, unop(Iop_NegF64, unop(Iop_AbsF64, get_fpr_dw0(r2))));
11261 put_fpr_dw0(r1, mkexpr(result));
11262
11263 return "lndfr";
11264}
11265
florian55085f82012-11-21 00:36:55 +000011266static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011267s390_irgen_LPDFR(UChar r1, UChar r2)
11268{
11269 IRTemp result = newTemp(Ity_F64);
11270
11271 assign(result, unop(Iop_AbsF64, get_fpr_dw0(r2)));
11272 put_fpr_dw0(r1, mkexpr(result));
11273
11274 return "lpdfr";
11275}
11276
florian55085f82012-11-21 00:36:55 +000011277static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011278s390_irgen_LDGR(UChar r1, UChar r2)
11279{
11280 put_fpr_dw0(r1, unop(Iop_ReinterpI64asF64, get_gpr_dw0(r2)));
11281
11282 return "ldgr";
11283}
11284
florian55085f82012-11-21 00:36:55 +000011285static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011286s390_irgen_LGDR(UChar r1, UChar r2)
11287{
11288 put_gpr_dw0(r1, unop(Iop_ReinterpF64asI64, get_fpr_dw0(r2)));
11289
11290 return "lgdr";
11291}
11292
11293
florian55085f82012-11-21 00:36:55 +000011294static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011295s390_irgen_CPSDR(UChar r3, UChar r1, UChar r2)
11296{
11297 IRTemp sign = newTemp(Ity_I64);
11298 IRTemp value = newTemp(Ity_I64);
11299
11300 assign(sign, binop(Iop_And64, unop(Iop_ReinterpF64asI64, get_fpr_dw0(r3)),
11301 mkU64(1ULL << 63)));
11302 assign(value, binop(Iop_And64, unop(Iop_ReinterpF64asI64, get_fpr_dw0(r2)),
11303 mkU64((1ULL << 63) - 1)));
11304 put_fpr_dw0(r1, unop(Iop_ReinterpI64asF64, binop(Iop_Or64, mkexpr(value),
11305 mkexpr(sign))));
11306
11307 return "cpsdr";
11308}
11309
11310
sewardj2019a972011-03-07 16:04:07 +000011311static IRExpr *
11312s390_call_cvb(IRExpr *in)
11313{
11314 IRExpr **args, *call;
11315
11316 args = mkIRExprVec_1(in);
11317 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
11318 "s390_do_cvb", &s390_do_cvb, args);
11319
11320 /* Nothing is excluded from definedness checking. */
11321 call->Iex.CCall.cee->mcx_mask = 0;
11322
11323 return call;
11324}
11325
florian55085f82012-11-21 00:36:55 +000011326static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011327s390_irgen_CVB(UChar r1, IRTemp op2addr)
11328{
11329 put_gpr_w1(r1, s390_call_cvb(load(Ity_I64, mkexpr(op2addr))));
11330
11331 return "cvb";
11332}
11333
florian55085f82012-11-21 00:36:55 +000011334static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011335s390_irgen_CVBY(UChar r1, IRTemp op2addr)
11336{
11337 put_gpr_w1(r1, s390_call_cvb(load(Ity_I64, mkexpr(op2addr))));
11338
11339 return "cvby";
11340}
11341
11342
sewardj2019a972011-03-07 16:04:07 +000011343static IRExpr *
11344s390_call_cvd(IRExpr *in)
11345{
11346 IRExpr **args, *call;
11347
11348 args = mkIRExprVec_1(in);
11349 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
11350 "s390_do_cvd", &s390_do_cvd, args);
11351
11352 /* Nothing is excluded from definedness checking. */
11353 call->Iex.CCall.cee->mcx_mask = 0;
11354
11355 return call;
11356}
11357
florian55085f82012-11-21 00:36:55 +000011358static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011359s390_irgen_CVD(UChar r1, IRTemp op2addr)
11360{
florian11b8ee82012-08-06 13:35:33 +000011361 store(mkexpr(op2addr), s390_call_cvd(unop(Iop_32Uto64, get_gpr_w1(r1))));
sewardj2019a972011-03-07 16:04:07 +000011362
11363 return "cvd";
11364}
11365
florian55085f82012-11-21 00:36:55 +000011366static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011367s390_irgen_CVDY(UChar r1, IRTemp op2addr)
11368{
11369 store(mkexpr(op2addr), s390_call_cvd(get_gpr_w1(r1)));
11370
11371 return "cvdy";
11372}
11373
florian55085f82012-11-21 00:36:55 +000011374static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011375s390_irgen_FLOGR(UChar r1, UChar r2)
11376{
11377 IRTemp input = newTemp(Ity_I64);
11378 IRTemp not_zero = newTemp(Ity_I64);
11379 IRTemp tmpnum = newTemp(Ity_I64);
11380 IRTemp num = newTemp(Ity_I64);
11381 IRTemp shift_amount = newTemp(Ity_I8);
11382
11383 /* We use the "count leading zeroes" operator because the number of
11384 leading zeroes is identical with the bit position of the first '1' bit.
11385 However, that operator does not work when the input value is zero.
11386 Therefore, we set the LSB of the input value to 1 and use Clz64 on
11387 the modified value. If input == 0, then the result is 64. Otherwise,
11388 the result of Clz64 is what we want. */
11389
11390 assign(input, get_gpr_dw0(r2));
11391 assign(not_zero, binop(Iop_Or64, mkexpr(input), mkU64(1)));
11392 assign(tmpnum, unop(Iop_Clz64, mkexpr(not_zero)));
11393
11394 /* num = (input == 0) ? 64 : tmpnum */
11395 assign(num, mkite(binop(Iop_CmpEQ64, mkexpr(input), mkU64(0)),
11396 /* == 0 */ mkU64(64),
11397 /* != 0 */ mkexpr(tmpnum)));
11398
11399 put_gpr_dw0(r1, mkexpr(num));
11400
11401 /* Set the leftmost '1' bit of the input value to zero. The general scheme
11402 is to first shift the input value by NUM + 1 bits to the left which
11403 causes the leftmost '1' bit to disappear. Then we shift logically to
11404 the right by NUM + 1 bits. Because the semantics of Iop_Shl64 and
11405 Iop_Shr64 are undefined if the shift-amount is greater than or equal to
11406 the width of the value-to-be-shifted, we need to special case
11407 NUM + 1 >= 64. This is equivalent to INPUT != 0 && INPUT != 1.
11408 For both such INPUT values the result will be 0. */
11409
11410 assign(shift_amount, unop(Iop_64to8, binop(Iop_Add64, mkexpr(num),
11411 mkU64(1))));
11412
11413 put_gpr_dw0(r1 + 1,
florian6ad49522011-09-09 02:38:55 +000011414 mkite(binop(Iop_CmpLE64U, mkexpr(input), mkU64(1)),
11415 /* == 0 || == 1*/ mkU64(0),
11416 /* otherwise */
11417 binop(Iop_Shr64,
11418 binop(Iop_Shl64, mkexpr(input),
11419 mkexpr(shift_amount)),
11420 mkexpr(shift_amount))));
sewardj2019a972011-03-07 16:04:07 +000011421
11422 /* Compare the original value as an unsigned integer with 0. */
11423 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, input,
11424 mktemp(Ity_I64, mkU64(0)), False);
11425
11426 return "flogr";
11427}
11428
florian55085f82012-11-21 00:36:55 +000011429static const HChar *
sewardj1e5fea62011-05-17 16:18:36 +000011430s390_irgen_STCK(IRTemp op2addr)
11431{
11432 IRDirty *d;
11433 IRTemp cc = newTemp(Ity_I64);
11434
11435 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STCK",
11436 &s390x_dirtyhelper_STCK,
11437 mkIRExprVec_1(mkexpr(op2addr)));
11438 d->mFx = Ifx_Write;
11439 d->mAddr = mkexpr(op2addr);
11440 d->mSize = 8;
11441 stmt(IRStmt_Dirty(d));
11442 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
11443 mkexpr(cc), mkU64(0), mkU64(0));
11444 return "stck";
11445}
11446
florian55085f82012-11-21 00:36:55 +000011447static const HChar *
sewardj1e5fea62011-05-17 16:18:36 +000011448s390_irgen_STCKF(IRTemp op2addr)
11449{
florianc5c669b2012-08-26 14:32:28 +000011450 if (! s390_host_has_stckf) {
floriane75dafa2012-09-01 17:54:09 +000011451 emulation_failure(EmFail_S390X_stckf);
florianc5c669b2012-08-26 14:32:28 +000011452 } else {
11453 IRTemp cc = newTemp(Ity_I64);
sewardj1e5fea62011-05-17 16:18:36 +000011454
florianc5c669b2012-08-26 14:32:28 +000011455 IRDirty *d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STCKF",
11456 &s390x_dirtyhelper_STCKF,
11457 mkIRExprVec_1(mkexpr(op2addr)));
11458 d->mFx = Ifx_Write;
11459 d->mAddr = mkexpr(op2addr);
11460 d->mSize = 8;
11461 stmt(IRStmt_Dirty(d));
11462 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
11463 mkexpr(cc), mkU64(0), mkU64(0));
11464 }
sewardj1e5fea62011-05-17 16:18:36 +000011465 return "stckf";
11466}
11467
florian55085f82012-11-21 00:36:55 +000011468static const HChar *
sewardj1e5fea62011-05-17 16:18:36 +000011469s390_irgen_STCKE(IRTemp op2addr)
11470{
11471 IRDirty *d;
11472 IRTemp cc = newTemp(Ity_I64);
11473
11474 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STCKE",
11475 &s390x_dirtyhelper_STCKE,
11476 mkIRExprVec_1(mkexpr(op2addr)));
11477 d->mFx = Ifx_Write;
11478 d->mAddr = mkexpr(op2addr);
11479 d->mSize = 16;
11480 stmt(IRStmt_Dirty(d));
11481 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
11482 mkexpr(cc), mkU64(0), mkU64(0));
11483 return "stcke";
11484}
11485
florian55085f82012-11-21 00:36:55 +000011486static const HChar *
florian933065d2011-07-11 01:48:02 +000011487s390_irgen_STFLE(IRTemp op2addr)
11488{
florian4e0083e2012-08-26 03:41:56 +000011489 if (! s390_host_has_stfle) {
floriane75dafa2012-09-01 17:54:09 +000011490 emulation_failure(EmFail_S390X_stfle);
florian4e0083e2012-08-26 03:41:56 +000011491 return "stfle";
11492 }
11493
florian933065d2011-07-11 01:48:02 +000011494 IRDirty *d;
11495 IRTemp cc = newTemp(Ity_I64);
11496
11497 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STFLE",
11498 &s390x_dirtyhelper_STFLE,
11499 mkIRExprVec_1(mkexpr(op2addr)));
11500
11501 d->needsBBP = 1; /* Need to pass pointer to guest state to helper */
11502
sewardjc9069f22012-06-01 16:09:50 +000011503 d->nFxState = 1;
11504 vex_bzero(&d->fxState, sizeof(d->fxState));
11505
florian933065d2011-07-11 01:48:02 +000011506 d->fxState[0].fx = Ifx_Modify; /* read then write */
11507 d->fxState[0].offset = S390X_GUEST_OFFSET(guest_r0);
11508 d->fxState[0].size = sizeof(ULong);
florian933065d2011-07-11 01:48:02 +000011509
11510 d->mAddr = mkexpr(op2addr);
11511 /* Pretend all double words are written */
11512 d->mSize = S390_NUM_FACILITY_DW * sizeof(ULong);
11513 d->mFx = Ifx_Write;
11514
11515 stmt(IRStmt_Dirty(d));
11516
11517 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET), mkexpr(cc), mkU64(0), mkU64(0));
11518
11519 return "stfle";
11520}
11521
florian55085f82012-11-21 00:36:55 +000011522static const HChar *
floriana4384a32011-08-11 16:58:45 +000011523s390_irgen_CKSM(UChar r1,UChar r2)
11524{
11525 IRTemp addr = newTemp(Ity_I64);
11526 IRTemp op = newTemp(Ity_I32);
11527 IRTemp len = newTemp(Ity_I64);
11528 IRTemp oldval = newTemp(Ity_I32);
11529 IRTemp mask = newTemp(Ity_I32);
11530 IRTemp newop = newTemp(Ity_I32);
11531 IRTemp result = newTemp(Ity_I32);
11532 IRTemp result1 = newTemp(Ity_I32);
11533 IRTemp inc = newTemp(Ity_I64);
11534
11535 assign(oldval, get_gpr_w1(r1));
11536 assign(addr, get_gpr_dw0(r2));
11537 assign(len, get_gpr_dw0(r2+1));
11538
11539 /* Condition code is always zero. */
11540 s390_cc_set(0);
11541
11542 /* If length is zero, there is no need to calculate the checksum */
florian6820ba52012-07-26 02:01:50 +000011543 next_insn_if(binop(Iop_CmpEQ64, mkexpr(len), mkU64(0)));
floriana4384a32011-08-11 16:58:45 +000011544
11545 /* Assiging the increment variable to adjust address and length
11546 later on. */
11547 assign(inc, mkite(binop(Iop_CmpLT64U, mkexpr(len), mkU64(4)),
11548 mkexpr(len), mkU64(4)));
11549
11550 /* If length < 4 the final 4-byte 2nd operand value is computed by
11551 appending the remaining bytes to the right with 0. This is done
11552 by AND'ing the 4 bytes loaded from memory with an appropriate
11553 mask. If length >= 4, that mask is simply 0xffffffff. */
11554
11555 assign(mask, mkite(binop(Iop_CmpLT64U, mkexpr(len), mkU64(4)),
11556 /* Mask computation when len < 4:
11557 0xffffffff << (32 - (len % 4)*8) */
11558 binop(Iop_Shl32, mkU32(0xffffffff),
11559 unop(Iop_32to8,
11560 binop(Iop_Sub32, mkU32(32),
11561 binop(Iop_Shl32,
11562 unop(Iop_64to32,
11563 binop(Iop_And64,
11564 mkexpr(len), mkU64(3))),
11565 mkU8(3))))),
11566 mkU32(0xffffffff)));
11567
11568 assign(op, load(Ity_I32, mkexpr(addr)));
11569 assign(newop, binop(Iop_And32, mkexpr(op), mkexpr(mask)));
11570 assign(result, binop(Iop_Add32, mkexpr(newop), mkexpr(oldval)));
11571
11572 /* Checking for carry */
11573 assign(result1, mkite(binop(Iop_CmpLT32U, mkexpr(result), mkexpr(newop)),
11574 binop(Iop_Add32, mkexpr(result), mkU32(1)),
11575 mkexpr(result)));
11576
11577 put_gpr_w1(r1, mkexpr(result1));
11578 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr), mkexpr(inc)));
11579 put_gpr_dw0(r2+1, binop(Iop_Sub64, mkexpr(len), mkexpr(inc)));
11580
florian6820ba52012-07-26 02:01:50 +000011581 iterate_if(binop(Iop_CmpNE64, mkexpr(len), mkU64(0)));
floriana4384a32011-08-11 16:58:45 +000011582
11583 return "cksm";
11584}
11585
florian55085f82012-11-21 00:36:55 +000011586static const HChar *
florian9af37692012-01-15 21:01:16 +000011587s390_irgen_TROO(UChar m3, UChar r1, UChar r2)
11588{
11589 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
11590 src_addr = newTemp(Ity_I64);
11591 des_addr = newTemp(Ity_I64);
11592 tab_addr = newTemp(Ity_I64);
11593 test_byte = newTemp(Ity_I8);
11594 src_len = newTemp(Ity_I64);
11595
11596 assign(src_addr, get_gpr_dw0(r2));
11597 assign(des_addr, get_gpr_dw0(r1));
11598 assign(tab_addr, get_gpr_dw0(1));
florian53518532012-01-18 14:00:31 +000011599 assign(src_len, get_gpr_dw0(r1+1));
florian9af37692012-01-15 21:01:16 +000011600 assign(test_byte, get_gpr_b7(0));
11601
11602 IRTemp op = newTemp(Ity_I8);
11603 IRTemp op1 = newTemp(Ity_I8);
11604 IRTemp result = newTemp(Ity_I64);
11605
11606 /* End of source string? We're done; proceed to next insn */
11607 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000011608 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian9af37692012-01-15 21:01:16 +000011609
11610 /* Load character from source string, index translation table and
11611 store translated character in op1. */
11612 assign(op, load(Ity_I8, mkexpr(src_addr)));
11613
11614 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)),
11615 mkexpr(tab_addr)));
11616 assign(op1, load(Ity_I8, mkexpr(result)));
11617
11618 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
11619 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000011620 next_insn_if(binop(Iop_CmpEQ8, mkexpr(op1), mkexpr(test_byte)));
florian9af37692012-01-15 21:01:16 +000011621 }
11622 store(get_gpr_dw0(r1), mkexpr(op1));
11623
11624 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(1)));
11625 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(1)));
11626 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(1)));
11627
florian6820ba52012-07-26 02:01:50 +000011628 iterate();
florian9af37692012-01-15 21:01:16 +000011629
11630 return "troo";
11631}
11632
florian55085f82012-11-21 00:36:55 +000011633static const HChar *
florian730448f2012-02-04 17:07:07 +000011634s390_irgen_TRTO(UChar m3, UChar r1, UChar r2)
11635{
11636 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
11637 src_addr = newTemp(Ity_I64);
11638 des_addr = newTemp(Ity_I64);
11639 tab_addr = newTemp(Ity_I64);
11640 test_byte = newTemp(Ity_I8);
11641 src_len = newTemp(Ity_I64);
11642
11643 assign(src_addr, get_gpr_dw0(r2));
11644 assign(des_addr, get_gpr_dw0(r1));
11645 assign(tab_addr, get_gpr_dw0(1));
11646 assign(src_len, get_gpr_dw0(r1+1));
11647 assign(test_byte, get_gpr_b7(0));
11648
11649 IRTemp op = newTemp(Ity_I16);
11650 IRTemp op1 = newTemp(Ity_I8);
11651 IRTemp result = newTemp(Ity_I64);
11652
11653 /* End of source string? We're done; proceed to next insn */
11654 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000011655 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian730448f2012-02-04 17:07:07 +000011656
11657 /* Load character from source string, index translation table and
11658 store translated character in op1. */
11659 assign(op, load(Ity_I16, mkexpr(src_addr)));
11660
11661 assign(result, binop(Iop_Add64, unop(Iop_16Uto64, mkexpr(op)),
11662 mkexpr(tab_addr)));
11663
11664 assign(op1, load(Ity_I8, mkexpr(result)));
11665
11666 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
11667 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000011668 next_insn_if(binop(Iop_CmpEQ8, mkexpr(op1), mkexpr(test_byte)));
florian730448f2012-02-04 17:07:07 +000011669 }
11670 store(get_gpr_dw0(r1), mkexpr(op1));
11671
11672 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(2)));
11673 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(1)));
11674 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(2)));
11675
florian6820ba52012-07-26 02:01:50 +000011676 iterate();
florian730448f2012-02-04 17:07:07 +000011677
11678 return "trto";
11679}
11680
florian55085f82012-11-21 00:36:55 +000011681static const HChar *
florian730448f2012-02-04 17:07:07 +000011682s390_irgen_TROT(UChar m3, UChar r1, UChar r2)
11683{
11684 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
11685 src_addr = newTemp(Ity_I64);
11686 des_addr = newTemp(Ity_I64);
11687 tab_addr = newTemp(Ity_I64);
11688 test_byte = newTemp(Ity_I16);
11689 src_len = newTemp(Ity_I64);
11690
11691 assign(src_addr, get_gpr_dw0(r2));
11692 assign(des_addr, get_gpr_dw0(r1));
11693 assign(tab_addr, get_gpr_dw0(1));
11694 assign(src_len, get_gpr_dw0(r1+1));
11695 assign(test_byte, get_gpr_hw3(0));
11696
11697 IRTemp op = newTemp(Ity_I8);
11698 IRTemp op1 = newTemp(Ity_I16);
11699 IRTemp result = newTemp(Ity_I64);
11700
11701 /* End of source string? We're done; proceed to next insn */
11702 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000011703 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian730448f2012-02-04 17:07:07 +000011704
11705 /* Load character from source string, index translation table and
11706 store translated character in op1. */
11707 assign(op, binop(Iop_Shl8, load(Ity_I8, mkexpr(src_addr)), mkU8(1)));
11708
11709 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)),
11710 mkexpr(tab_addr)));
11711 assign(op1, load(Ity_I16, mkexpr(result)));
11712
11713 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
11714 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000011715 next_insn_if(binop(Iop_CmpEQ16, mkexpr(op1), mkexpr(test_byte)));
florian730448f2012-02-04 17:07:07 +000011716 }
11717 store(get_gpr_dw0(r1), mkexpr(op1));
11718
11719 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(1)));
11720 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(2)));
11721 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(1)));
11722
florian6820ba52012-07-26 02:01:50 +000011723 iterate();
florian730448f2012-02-04 17:07:07 +000011724
11725 return "trot";
11726}
11727
florian55085f82012-11-21 00:36:55 +000011728static const HChar *
florian730448f2012-02-04 17:07:07 +000011729s390_irgen_TRTT(UChar m3, UChar r1, UChar r2)
11730{
11731 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
11732 src_addr = newTemp(Ity_I64);
11733 des_addr = newTemp(Ity_I64);
11734 tab_addr = newTemp(Ity_I64);
11735 test_byte = newTemp(Ity_I16);
11736 src_len = newTemp(Ity_I64);
11737
11738 assign(src_addr, get_gpr_dw0(r2));
11739 assign(des_addr, get_gpr_dw0(r1));
11740 assign(tab_addr, get_gpr_dw0(1));
11741 assign(src_len, get_gpr_dw0(r1+1));
11742 assign(test_byte, get_gpr_hw3(0));
11743
11744 IRTemp op = newTemp(Ity_I16);
11745 IRTemp op1 = newTemp(Ity_I16);
11746 IRTemp result = newTemp(Ity_I64);
11747
11748 /* End of source string? We're done; proceed to next insn */
11749 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000011750 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian730448f2012-02-04 17:07:07 +000011751
11752 /* Load character from source string, index translation table and
11753 store translated character in op1. */
11754 assign(op, binop(Iop_Shl16, load(Ity_I16, mkexpr(src_addr)), mkU8(1)));
11755
11756 assign(result, binop(Iop_Add64, unop(Iop_16Uto64, mkexpr(op)),
11757 mkexpr(tab_addr)));
11758 assign(op1, load(Ity_I16, mkexpr(result)));
11759
11760 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
11761 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000011762 next_insn_if(binop(Iop_CmpEQ16, mkexpr(op1), mkexpr(test_byte)));
florian730448f2012-02-04 17:07:07 +000011763 }
11764
11765 store(get_gpr_dw0(r1), mkexpr(op1));
11766
11767 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(2)));
11768 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(2)));
11769 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(2)));
11770
florian6820ba52012-07-26 02:01:50 +000011771 iterate();
florian730448f2012-02-04 17:07:07 +000011772
11773 return "trtt";
11774}
11775
florian55085f82012-11-21 00:36:55 +000011776static const HChar *
florian730448f2012-02-04 17:07:07 +000011777s390_irgen_TR(UChar length, IRTemp start1, IRTemp start2)
11778{
florianf87d4fb2012-05-05 02:55:24 +000011779 IRTemp len = newTemp(Ity_I64);
florian730448f2012-02-04 17:07:07 +000011780
florianf87d4fb2012-05-05 02:55:24 +000011781 assign(len, mkU64(length));
11782 s390_irgen_TR_EX(len, start1, start2);
florian730448f2012-02-04 17:07:07 +000011783
11784 return "tr";
11785}
11786
florian55085f82012-11-21 00:36:55 +000011787static const HChar *
florian730448f2012-02-04 17:07:07 +000011788s390_irgen_TRE(UChar r1,UChar r2)
11789{
11790 IRTemp src_addr, tab_addr, src_len, test_byte;
11791 src_addr = newTemp(Ity_I64);
11792 tab_addr = newTemp(Ity_I64);
11793 src_len = newTemp(Ity_I64);
11794 test_byte = newTemp(Ity_I8);
11795
11796 assign(src_addr, get_gpr_dw0(r1));
11797 assign(src_len, get_gpr_dw0(r1+1));
11798 assign(tab_addr, get_gpr_dw0(r2));
11799 assign(test_byte, get_gpr_b7(0));
11800
11801 IRTemp op = newTemp(Ity_I8);
11802 IRTemp op1 = newTemp(Ity_I8);
11803 IRTemp result = newTemp(Ity_I64);
11804
11805 /* End of source string? We're done; proceed to next insn */
11806 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000011807 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian730448f2012-02-04 17:07:07 +000011808
11809 /* Load character from source string and compare with test byte */
11810 assign(op, load(Ity_I8, mkexpr(src_addr)));
11811
11812 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000011813 next_insn_if(binop(Iop_CmpEQ8, mkexpr(op), mkexpr(test_byte)));
florian730448f2012-02-04 17:07:07 +000011814
11815 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)),
11816 mkexpr(tab_addr)));
11817
11818 assign(op1, load(Ity_I8, mkexpr(result)));
11819
11820 store(get_gpr_dw0(r1), mkexpr(op1));
11821 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(src_addr), mkU64(1)));
11822 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(1)));
11823
florian6820ba52012-07-26 02:01:50 +000011824 iterate();
florian730448f2012-02-04 17:07:07 +000011825
11826 return "tre";
11827}
11828
floriana0100c92012-07-20 00:06:35 +000011829static IRExpr *
11830s390_call_cu21(IRExpr *srcval, IRExpr *low_surrogate)
11831{
11832 IRExpr **args, *call;
11833 args = mkIRExprVec_2(srcval, low_surrogate);
11834 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
11835 "s390_do_cu21", &s390_do_cu21, args);
11836
11837 /* Nothing is excluded from definedness checking. */
11838 call->Iex.CCall.cee->mcx_mask = 0;
11839
11840 return call;
11841}
11842
florian55085f82012-11-21 00:36:55 +000011843static const HChar *
floriana0100c92012-07-20 00:06:35 +000011844s390_irgen_CU21(UChar m3, UChar r1, UChar r2)
11845{
11846 IRTemp addr1 = newTemp(Ity_I64);
11847 IRTemp addr2 = newTemp(Ity_I64);
11848 IRTemp len1 = newTemp(Ity_I64);
11849 IRTemp len2 = newTemp(Ity_I64);
11850
11851 assign(addr1, get_gpr_dw0(r1));
11852 assign(addr2, get_gpr_dw0(r2));
11853 assign(len1, get_gpr_dw0(r1 + 1));
11854 assign(len2, get_gpr_dw0(r2 + 1));
11855
11856 /* We're processing the 2nd operand 2 bytes at a time. Therefore, if
11857 there are less than 2 bytes left, then the 2nd operand is exhausted
11858 and we're done here. cc = 0 */
11859 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000011860 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(2)));
floriana0100c92012-07-20 00:06:35 +000011861
11862 /* There are at least two bytes there. Read them. */
11863 IRTemp srcval = newTemp(Ity_I32);
11864 assign(srcval, unop(Iop_16Uto32, load(Ity_I16, mkexpr(addr2))));
11865
11866 /* Find out whether this is a high surrogate. I.e. SRCVAL lies
11867 inside the interval [0xd800 - 0xdbff] */
11868 IRTemp is_high_surrogate = newTemp(Ity_I32);
11869 IRExpr *flag1 = mkite(binop(Iop_CmpLE32U, mkU32(0xd800), mkexpr(srcval)),
11870 mkU32(1), mkU32(0));
11871 IRExpr *flag2 = mkite(binop(Iop_CmpLE32U, mkexpr(srcval), mkU32(0xdbff)),
11872 mkU32(1), mkU32(0));
11873 assign(is_high_surrogate, binop(Iop_And32, flag1, flag2));
11874
11875 /* If SRCVAL is a high surrogate and there are less than 4 bytes left,
11876 then the 2nd operand is exhausted and we're done here. cc = 0 */
11877 IRExpr *not_enough_bytes =
11878 mkite(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)), mkU32(1), mkU32(0));
11879
florian6820ba52012-07-26 02:01:50 +000011880 next_insn_if(binop(Iop_CmpEQ32,
11881 binop(Iop_And32, mkexpr(is_high_surrogate),
11882 not_enough_bytes), mkU32(1)));
floriana0100c92012-07-20 00:06:35 +000011883
11884 /* The 2nd operand is not exhausted. If the first 2 bytes are a high
11885 surrogate, read the next two bytes (low surrogate). */
11886 IRTemp low_surrogate = newTemp(Ity_I32);
11887 IRExpr *low_surrogate_addr = binop(Iop_Add64, mkexpr(addr2), mkU64(2));
11888
11889 assign(low_surrogate,
11890 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
11891 unop(Iop_16Uto32, load(Ity_I16, low_surrogate_addr)),
11892 mkU32(0))); // any value is fine; it will not be used
11893
11894 /* Call the helper */
11895 IRTemp retval = newTemp(Ity_I64);
florian11b8ee82012-08-06 13:35:33 +000011896 assign(retval, s390_call_cu21(unop(Iop_32Uto64, mkexpr(srcval)),
11897 unop(Iop_32Uto64, mkexpr(low_surrogate))));
floriana0100c92012-07-20 00:06:35 +000011898
11899 /* Before we can test whether the 1st operand is exhausted we need to
11900 test for an invalid low surrogate. Because cc=2 outranks cc=1. */
11901 if (s390_host_has_etf3 && (m3 & 0x1) == 1) {
11902 IRExpr *invalid_low_surrogate =
11903 binop(Iop_And64, mkexpr(retval), mkU64(0xff));
11904
11905 s390_cc_set(2);
florian6820ba52012-07-26 02:01:50 +000011906 next_insn_if(binop(Iop_CmpEQ64, invalid_low_surrogate, mkU64(1)));
floriana0100c92012-07-20 00:06:35 +000011907 }
11908
11909 /* Now test whether the 1st operand is exhausted */
11910 IRTemp num_bytes = newTemp(Ity_I64);
11911 assign(num_bytes, binop(Iop_And64,
11912 binop(Iop_Shr64, mkexpr(retval), mkU8(8)),
11913 mkU64(0xff)));
11914 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000011915 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
floriana0100c92012-07-20 00:06:35 +000011916
11917 /* Extract the bytes to be stored at addr1 */
11918 IRTemp data = newTemp(Ity_I64);
11919 assign(data, binop(Iop_Shr64, mkexpr(retval), mkU8(16)));
11920
11921 /* To store the bytes construct 4 dirty helper calls. The helper calls
11922 are guarded (num_bytes == 1, num_bytes == 2, etc) such that only
11923 one of them will be called at runtime. */
11924 int i;
11925 for (i = 1; i <= 4; ++i) {
11926 IRDirty *d;
11927
11928 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
11929 &s390x_dirtyhelper_CUxy,
11930 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
11931 mkexpr(num_bytes)));
11932 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
11933 d->mFx = Ifx_Write;
11934 d->mAddr = mkexpr(addr1);
11935 d->mSize = i;
11936 stmt(IRStmt_Dirty(d));
11937 }
11938
11939 /* Update source address and length */
11940 IRTemp num_src_bytes = newTemp(Ity_I64);
11941 assign(num_src_bytes,
11942 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
11943 mkU64(4), mkU64(2)));
11944 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkexpr(num_src_bytes)));
11945 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkexpr(num_src_bytes)));
11946
11947 /* Update destination address and length */
11948 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
11949 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
11950
florian6820ba52012-07-26 02:01:50 +000011951 iterate();
floriana0100c92012-07-20 00:06:35 +000011952
11953 return "cu21";
11954}
11955
florian2a415a12012-07-21 17:41:36 +000011956static IRExpr *
11957s390_call_cu24(IRExpr *srcval, IRExpr *low_surrogate)
11958{
11959 IRExpr **args, *call;
11960 args = mkIRExprVec_2(srcval, low_surrogate);
11961 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
11962 "s390_do_cu24", &s390_do_cu24, args);
11963
11964 /* Nothing is excluded from definedness checking. */
11965 call->Iex.CCall.cee->mcx_mask = 0;
11966
11967 return call;
11968}
11969
florian55085f82012-11-21 00:36:55 +000011970static const HChar *
florian2a415a12012-07-21 17:41:36 +000011971s390_irgen_CU24(UChar m3, UChar r1, UChar r2)
11972{
11973 IRTemp addr1 = newTemp(Ity_I64);
11974 IRTemp addr2 = newTemp(Ity_I64);
11975 IRTemp len1 = newTemp(Ity_I64);
11976 IRTemp len2 = newTemp(Ity_I64);
11977
11978 assign(addr1, get_gpr_dw0(r1));
11979 assign(addr2, get_gpr_dw0(r2));
11980 assign(len1, get_gpr_dw0(r1 + 1));
11981 assign(len2, get_gpr_dw0(r2 + 1));
11982
11983 /* We're processing the 2nd operand 2 bytes at a time. Therefore, if
11984 there are less than 2 bytes left, then the 2nd operand is exhausted
11985 and we're done here. cc = 0 */
11986 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000011987 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(2)));
florian2a415a12012-07-21 17:41:36 +000011988
11989 /* There are at least two bytes there. Read them. */
11990 IRTemp srcval = newTemp(Ity_I32);
11991 assign(srcval, unop(Iop_16Uto32, load(Ity_I16, mkexpr(addr2))));
11992
11993 /* Find out whether this is a high surrogate. I.e. SRCVAL lies
11994 inside the interval [0xd800 - 0xdbff] */
11995 IRTemp is_high_surrogate = newTemp(Ity_I32);
11996 IRExpr *flag1 = mkite(binop(Iop_CmpLE32U, mkU32(0xd800), mkexpr(srcval)),
11997 mkU32(1), mkU32(0));
11998 IRExpr *flag2 = mkite(binop(Iop_CmpLE32U, mkexpr(srcval), mkU32(0xdbff)),
11999 mkU32(1), mkU32(0));
12000 assign(is_high_surrogate, binop(Iop_And32, flag1, flag2));
12001
12002 /* If SRCVAL is a high surrogate and there are less than 4 bytes left,
12003 then the 2nd operand is exhausted and we're done here. cc = 0 */
12004 IRExpr *not_enough_bytes =
12005 mkite(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)), mkU32(1), mkU32(0));
12006
florian6820ba52012-07-26 02:01:50 +000012007 next_insn_if(binop(Iop_CmpEQ32,
12008 binop(Iop_And32, mkexpr(is_high_surrogate),
12009 not_enough_bytes),
12010 mkU32(1)));
florian2a415a12012-07-21 17:41:36 +000012011
12012 /* The 2nd operand is not exhausted. If the first 2 bytes are a high
12013 surrogate, read the next two bytes (low surrogate). */
12014 IRTemp low_surrogate = newTemp(Ity_I32);
12015 IRExpr *low_surrogate_addr = binop(Iop_Add64, mkexpr(addr2), mkU64(2));
12016
12017 assign(low_surrogate,
12018 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
12019 unop(Iop_16Uto32, load(Ity_I16, low_surrogate_addr)),
12020 mkU32(0))); // any value is fine; it will not be used
12021
12022 /* Call the helper */
12023 IRTemp retval = newTemp(Ity_I64);
florian11b8ee82012-08-06 13:35:33 +000012024 assign(retval, s390_call_cu24(unop(Iop_32Uto64, mkexpr(srcval)),
12025 unop(Iop_32Uto64, mkexpr(low_surrogate))));
florian2a415a12012-07-21 17:41:36 +000012026
12027 /* Before we can test whether the 1st operand is exhausted we need to
12028 test for an invalid low surrogate. Because cc=2 outranks cc=1. */
12029 if (s390_host_has_etf3 && (m3 & 0x1) == 1) {
12030 IRExpr *invalid_low_surrogate =
12031 binop(Iop_And64, mkexpr(retval), mkU64(0xff));
12032
12033 s390_cc_set(2);
florian6820ba52012-07-26 02:01:50 +000012034 next_insn_if(binop(Iop_CmpEQ64, invalid_low_surrogate, mkU64(1)));
florian2a415a12012-07-21 17:41:36 +000012035 }
12036
12037 /* Now test whether the 1st operand is exhausted */
12038 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000012039 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkU64(4)));
florian2a415a12012-07-21 17:41:36 +000012040
12041 /* Extract the bytes to be stored at addr1 */
12042 IRExpr *data = unop(Iop_64to32, binop(Iop_Shr64, mkexpr(retval), mkU8(8)));
12043
12044 store(mkexpr(addr1), data);
12045
12046 /* Update source address and length */
12047 IRTemp num_src_bytes = newTemp(Ity_I64);
12048 assign(num_src_bytes,
12049 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
12050 mkU64(4), mkU64(2)));
12051 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkexpr(num_src_bytes)));
12052 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkexpr(num_src_bytes)));
12053
12054 /* Update destination address and length */
12055 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkU64(4)));
12056 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkU64(4)));
12057
florian6820ba52012-07-26 02:01:50 +000012058 iterate();
florian2a415a12012-07-21 17:41:36 +000012059
12060 return "cu24";
12061}
floriana4384a32011-08-11 16:58:45 +000012062
florian956194b2012-07-28 22:18:32 +000012063static IRExpr *
12064s390_call_cu42(IRExpr *srcval)
12065{
12066 IRExpr **args, *call;
12067 args = mkIRExprVec_1(srcval);
12068 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
12069 "s390_do_cu42", &s390_do_cu42, args);
12070
12071 /* Nothing is excluded from definedness checking. */
12072 call->Iex.CCall.cee->mcx_mask = 0;
12073
12074 return call;
12075}
12076
florian55085f82012-11-21 00:36:55 +000012077static const HChar *
florian956194b2012-07-28 22:18:32 +000012078s390_irgen_CU42(UChar r1, UChar r2)
12079{
12080 IRTemp addr1 = newTemp(Ity_I64);
12081 IRTemp addr2 = newTemp(Ity_I64);
12082 IRTemp len1 = newTemp(Ity_I64);
12083 IRTemp len2 = newTemp(Ity_I64);
12084
12085 assign(addr1, get_gpr_dw0(r1));
12086 assign(addr2, get_gpr_dw0(r2));
12087 assign(len1, get_gpr_dw0(r1 + 1));
12088 assign(len2, get_gpr_dw0(r2 + 1));
12089
12090 /* We're processing the 2nd operand 4 bytes at a time. Therefore, if
12091 there are less than 4 bytes left, then the 2nd operand is exhausted
12092 and we're done here. cc = 0 */
12093 s390_cc_set(0);
12094 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)));
12095
12096 /* Read the 2nd operand. */
12097 IRTemp srcval = newTemp(Ity_I32);
12098 assign(srcval, load(Ity_I32, mkexpr(addr2)));
12099
12100 /* Call the helper */
12101 IRTemp retval = newTemp(Ity_I64);
florian11b8ee82012-08-06 13:35:33 +000012102 assign(retval, s390_call_cu42(unop(Iop_32Uto64, mkexpr(srcval))));
florian956194b2012-07-28 22:18:32 +000012103
12104 /* If the UTF-32 character was invalid, set cc=2 and we're done.
12105 cc=2 outranks cc=1 (1st operand exhausted) */
12106 IRExpr *invalid_character = binop(Iop_And64, mkexpr(retval), mkU64(0xff));
12107
12108 s390_cc_set(2);
12109 next_insn_if(binop(Iop_CmpEQ64, invalid_character, mkU64(1)));
12110
12111 /* Now test whether the 1st operand is exhausted */
12112 IRTemp num_bytes = newTemp(Ity_I64);
12113 assign(num_bytes, binop(Iop_And64,
12114 binop(Iop_Shr64, mkexpr(retval), mkU8(8)),
12115 mkU64(0xff)));
12116 s390_cc_set(1);
12117 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
12118
12119 /* Extract the bytes to be stored at addr1 */
12120 IRTemp data = newTemp(Ity_I64);
12121 assign(data, binop(Iop_Shr64, mkexpr(retval), mkU8(16)));
12122
12123 /* To store the bytes construct 2 dirty helper calls. The helper calls
12124 are guarded (num_bytes == 2 and num_bytes == 4, respectively) such
12125 that only one of them will be called at runtime. */
12126
12127 Int i;
12128 for (i = 2; i <= 4; ++i) {
12129 IRDirty *d;
12130
12131 if (i == 3) continue; // skip this one
12132
12133 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
12134 &s390x_dirtyhelper_CUxy,
12135 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
12136 mkexpr(num_bytes)));
12137 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
12138 d->mFx = Ifx_Write;
12139 d->mAddr = mkexpr(addr1);
12140 d->mSize = i;
12141 stmt(IRStmt_Dirty(d));
12142 }
12143
12144 /* Update source address and length */
12145 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkU64(4)));
12146 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkU64(4)));
12147
12148 /* Update destination address and length */
12149 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
12150 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
12151
12152 iterate();
12153
12154 return "cu42";
12155}
12156
florian6d9b9b22012-08-03 18:35:39 +000012157static IRExpr *
florianaf2194f2012-08-06 00:07:54 +000012158s390_call_cu41(IRExpr *srcval)
12159{
12160 IRExpr **args, *call;
12161 args = mkIRExprVec_1(srcval);
12162 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
12163 "s390_do_cu41", &s390_do_cu41, args);
12164
12165 /* Nothing is excluded from definedness checking. */
12166 call->Iex.CCall.cee->mcx_mask = 0;
12167
12168 return call;
12169}
12170
florian55085f82012-11-21 00:36:55 +000012171static const HChar *
florianaf2194f2012-08-06 00:07:54 +000012172s390_irgen_CU41(UChar r1, UChar r2)
12173{
12174 IRTemp addr1 = newTemp(Ity_I64);
12175 IRTemp addr2 = newTemp(Ity_I64);
12176 IRTemp len1 = newTemp(Ity_I64);
12177 IRTemp len2 = newTemp(Ity_I64);
12178
12179 assign(addr1, get_gpr_dw0(r1));
12180 assign(addr2, get_gpr_dw0(r2));
12181 assign(len1, get_gpr_dw0(r1 + 1));
12182 assign(len2, get_gpr_dw0(r2 + 1));
12183
12184 /* We're processing the 2nd operand 4 bytes at a time. Therefore, if
12185 there are less than 4 bytes left, then the 2nd operand is exhausted
12186 and we're done here. cc = 0 */
12187 s390_cc_set(0);
12188 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)));
12189
12190 /* Read the 2nd operand. */
12191 IRTemp srcval = newTemp(Ity_I32);
12192 assign(srcval, load(Ity_I32, mkexpr(addr2)));
12193
12194 /* Call the helper */
12195 IRTemp retval = newTemp(Ity_I64);
florian11b8ee82012-08-06 13:35:33 +000012196 assign(retval, s390_call_cu41(unop(Iop_32Uto64, mkexpr(srcval))));
florianaf2194f2012-08-06 00:07:54 +000012197
12198 /* If the UTF-32 character was invalid, set cc=2 and we're done.
12199 cc=2 outranks cc=1 (1st operand exhausted) */
12200 IRExpr *invalid_character = binop(Iop_And64, mkexpr(retval), mkU64(0xff));
12201
12202 s390_cc_set(2);
12203 next_insn_if(binop(Iop_CmpEQ64, invalid_character, mkU64(1)));
12204
12205 /* Now test whether the 1st operand is exhausted */
12206 IRTemp num_bytes = newTemp(Ity_I64);
12207 assign(num_bytes, binop(Iop_And64,
12208 binop(Iop_Shr64, mkexpr(retval), mkU8(8)),
12209 mkU64(0xff)));
12210 s390_cc_set(1);
12211 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
12212
12213 /* Extract the bytes to be stored at addr1 */
12214 IRTemp data = newTemp(Ity_I64);
12215 assign(data, binop(Iop_Shr64, mkexpr(retval), mkU8(16)));
12216
12217 /* To store the bytes construct 4 dirty helper calls. The helper calls
12218 are guarded (num_bytes == 1, num_bytes == 2, etc) such that only
12219 one of them will be called at runtime. */
12220 int i;
12221 for (i = 1; i <= 4; ++i) {
12222 IRDirty *d;
12223
12224 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
12225 &s390x_dirtyhelper_CUxy,
12226 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
12227 mkexpr(num_bytes)));
12228 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
12229 d->mFx = Ifx_Write;
12230 d->mAddr = mkexpr(addr1);
12231 d->mSize = i;
12232 stmt(IRStmt_Dirty(d));
12233 }
12234
12235 /* Update source address and length */
12236 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkU64(4)));
12237 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkU64(4)));
12238
12239 /* Update destination address and length */
12240 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
12241 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
12242
12243 iterate();
12244
12245 return "cu41";
12246}
12247
12248static IRExpr *
florian3f8a96a2012-08-05 02:59:55 +000012249s390_call_cu12_cu14_helper1(IRExpr *byte1, IRExpr *etf3_and_m3_is_1)
florian6d9b9b22012-08-03 18:35:39 +000012250{
12251 IRExpr **args, *call;
12252 args = mkIRExprVec_2(byte1, etf3_and_m3_is_1);
florian3f8a96a2012-08-05 02:59:55 +000012253 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/, "s390_do_cu12_cu14_helper1",
12254 &s390_do_cu12_cu14_helper1, args);
florian6d9b9b22012-08-03 18:35:39 +000012255
12256 /* Nothing is excluded from definedness checking. */
12257 call->Iex.CCall.cee->mcx_mask = 0;
12258
12259 return call;
12260}
12261
12262static IRExpr *
12263s390_call_cu12_helper2(IRExpr *byte1, IRExpr *byte2, IRExpr *byte3,
12264 IRExpr *byte4, IRExpr *stuff)
12265{
12266 IRExpr **args, *call;
12267 args = mkIRExprVec_5(byte1, byte2, byte3, byte4, stuff);
12268 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
12269 "s390_do_cu12_helper2", &s390_do_cu12_helper2, args);
12270
12271 /* Nothing is excluded from definedness checking. */
12272 call->Iex.CCall.cee->mcx_mask = 0;
12273
12274 return call;
12275}
12276
florian3f8a96a2012-08-05 02:59:55 +000012277static IRExpr *
12278s390_call_cu14_helper2(IRExpr *byte1, IRExpr *byte2, IRExpr *byte3,
12279 IRExpr *byte4, IRExpr *stuff)
12280{
12281 IRExpr **args, *call;
12282 args = mkIRExprVec_5(byte1, byte2, byte3, byte4, stuff);
12283 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
12284 "s390_do_cu14_helper2", &s390_do_cu14_helper2, args);
12285
12286 /* Nothing is excluded from definedness checking. */
12287 call->Iex.CCall.cee->mcx_mask = 0;
12288
12289 return call;
12290}
12291
12292static void
12293s390_irgen_cu12_cu14(UChar m3, UChar r1, UChar r2, Bool is_cu12)
florian6d9b9b22012-08-03 18:35:39 +000012294{
12295 IRTemp addr1 = newTemp(Ity_I64);
12296 IRTemp addr2 = newTemp(Ity_I64);
12297 IRTemp len1 = newTemp(Ity_I64);
12298 IRTemp len2 = newTemp(Ity_I64);
12299
12300 assign(addr1, get_gpr_dw0(r1));
12301 assign(addr2, get_gpr_dw0(r2));
12302 assign(len1, get_gpr_dw0(r1 + 1));
12303 assign(len2, get_gpr_dw0(r2 + 1));
12304
12305 UInt extended_checking = s390_host_has_etf3 && (m3 & 0x1) == 1;
12306
12307 /* We're processing the 2nd operand 1 byte at a time. Therefore, if
12308 there is less than 1 byte left, then the 2nd operand is exhausted
12309 and we're done here. cc = 0 */
12310 s390_cc_set(0);
12311 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(1)));
12312
12313 /* There is at least one byte there. Read it. */
florian11b8ee82012-08-06 13:35:33 +000012314 IRTemp byte1 = newTemp(Ity_I64);
12315 assign(byte1, unop(Iop_8Uto64, load(Ity_I8, mkexpr(addr2))));
florian6d9b9b22012-08-03 18:35:39 +000012316
12317 /* Call the helper to get number of bytes and invalid byte indicator */
12318 IRTemp retval1 = newTemp(Ity_I64);
florian3f8a96a2012-08-05 02:59:55 +000012319 assign(retval1, s390_call_cu12_cu14_helper1(mkexpr(byte1),
florian11b8ee82012-08-06 13:35:33 +000012320 mkU64(extended_checking)));
florian6d9b9b22012-08-03 18:35:39 +000012321
12322 /* Check for invalid 1st byte */
12323 IRExpr *is_invalid = unop(Iop_64to1, mkexpr(retval1));
12324 s390_cc_set(2);
12325 next_insn_if(is_invalid);
12326
12327 /* How many bytes do we have to read? */
12328 IRTemp num_src_bytes = newTemp(Ity_I64);
12329 assign(num_src_bytes, binop(Iop_Shr64, mkexpr(retval1), mkU8(8)));
12330
12331 /* Now test whether the 2nd operand is exhausted */
12332 s390_cc_set(0);
12333 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkexpr(num_src_bytes)));
12334
12335 /* Read the remaining bytes */
12336 IRExpr *cond, *addr, *byte2, *byte3, *byte4;
12337
12338 cond = binop(Iop_CmpLE64U, mkU64(2), mkexpr(num_src_bytes));
12339 addr = binop(Iop_Add64, mkexpr(addr2), mkU64(1));
florian11b8ee82012-08-06 13:35:33 +000012340 byte2 = mkite(cond, unop(Iop_8Uto64, load(Ity_I8, addr)), mkU64(0));
florian6d9b9b22012-08-03 18:35:39 +000012341 cond = binop(Iop_CmpLE64U, mkU64(3), mkexpr(num_src_bytes));
12342 addr = binop(Iop_Add64, mkexpr(addr2), mkU64(2));
florian11b8ee82012-08-06 13:35:33 +000012343 byte3 = mkite(cond, unop(Iop_8Uto64, load(Ity_I8, addr)), mkU64(0));
florian6d9b9b22012-08-03 18:35:39 +000012344 cond = binop(Iop_CmpLE64U, mkU64(4), mkexpr(num_src_bytes));
12345 addr = binop(Iop_Add64, mkexpr(addr2), mkU64(3));
florian11b8ee82012-08-06 13:35:33 +000012346 byte4 = mkite(cond, unop(Iop_8Uto64, load(Ity_I8, addr)), mkU64(0));
florian6d9b9b22012-08-03 18:35:39 +000012347
12348 /* Call the helper to get the converted value and invalid byte indicator.
12349 We can pass at most 5 arguments; therefore some encoding is needed
12350 here */
12351 IRExpr *stuff = binop(Iop_Or64,
12352 binop(Iop_Shl64, mkexpr(num_src_bytes), mkU8(1)),
12353 mkU64(extended_checking));
12354 IRTemp retval2 = newTemp(Ity_I64);
florian3f8a96a2012-08-05 02:59:55 +000012355
12356 if (is_cu12) {
12357 assign(retval2, s390_call_cu12_helper2(mkexpr(byte1), byte2, byte3,
12358 byte4, stuff));
12359 } else {
12360 assign(retval2, s390_call_cu14_helper2(mkexpr(byte1), byte2, byte3,
12361 byte4, stuff));
12362 }
florian6d9b9b22012-08-03 18:35:39 +000012363
12364 /* Check for invalid character */
12365 s390_cc_set(2);
12366 is_invalid = unop(Iop_64to1, mkexpr(retval2));
12367 next_insn_if(is_invalid);
12368
12369 /* Now test whether the 1st operand is exhausted */
12370 IRTemp num_bytes = newTemp(Ity_I64);
12371 assign(num_bytes, binop(Iop_And64,
12372 binop(Iop_Shr64, mkexpr(retval2), mkU8(8)),
12373 mkU64(0xff)));
12374 s390_cc_set(1);
12375 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
12376
12377 /* Extract the bytes to be stored at addr1 */
12378 IRTemp data = newTemp(Ity_I64);
12379 assign(data, binop(Iop_Shr64, mkexpr(retval2), mkU8(16)));
12380
florian3f8a96a2012-08-05 02:59:55 +000012381 if (is_cu12) {
12382 /* To store the bytes construct 2 dirty helper calls. The helper calls
12383 are guarded (num_bytes == 2 and num_bytes == 4, respectively) such
12384 that only one of them will be called at runtime. */
florian6d9b9b22012-08-03 18:35:39 +000012385
florian3f8a96a2012-08-05 02:59:55 +000012386 Int i;
12387 for (i = 2; i <= 4; ++i) {
12388 IRDirty *d;
florian6d9b9b22012-08-03 18:35:39 +000012389
florian3f8a96a2012-08-05 02:59:55 +000012390 if (i == 3) continue; // skip this one
florian6d9b9b22012-08-03 18:35:39 +000012391
florian3f8a96a2012-08-05 02:59:55 +000012392 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
12393 &s390x_dirtyhelper_CUxy,
12394 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
12395 mkexpr(num_bytes)));
12396 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
12397 d->mFx = Ifx_Write;
12398 d->mAddr = mkexpr(addr1);
12399 d->mSize = i;
12400 stmt(IRStmt_Dirty(d));
12401 }
12402 } else {
12403 // cu14
12404 store(mkexpr(addr1), unop(Iop_64to32, mkexpr(data)));
florian6d9b9b22012-08-03 18:35:39 +000012405 }
12406
12407 /* Update source address and length */
12408 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkexpr(num_src_bytes)));
12409 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkexpr(num_src_bytes)));
12410
12411 /* Update destination address and length */
12412 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
12413 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
12414
12415 iterate();
florian3f8a96a2012-08-05 02:59:55 +000012416}
12417
florian55085f82012-11-21 00:36:55 +000012418static const HChar *
florian3f8a96a2012-08-05 02:59:55 +000012419s390_irgen_CU12(UChar m3, UChar r1, UChar r2)
12420{
12421 s390_irgen_cu12_cu14(m3, r1, r2, /* is_cu12 = */ 1);
florian6d9b9b22012-08-03 18:35:39 +000012422
12423 return "cu12";
12424}
12425
florian55085f82012-11-21 00:36:55 +000012426static const HChar *
florian3f8a96a2012-08-05 02:59:55 +000012427s390_irgen_CU14(UChar m3, UChar r1, UChar r2)
12428{
12429 s390_irgen_cu12_cu14(m3, r1, r2, /* is_cu12 = */ 0);
12430
12431 return "cu14";
12432}
12433
florian8c88cb62012-08-26 18:58:13 +000012434static IRExpr *
12435s390_call_ecag(IRExpr *op2addr)
12436{
12437 IRExpr **args, *call;
12438
12439 args = mkIRExprVec_1(op2addr);
12440 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
12441 "s390_do_ecag", &s390_do_ecag, args);
12442
12443 /* Nothing is excluded from definedness checking. */
12444 call->Iex.CCall.cee->mcx_mask = 0;
12445
12446 return call;
12447}
12448
florian55085f82012-11-21 00:36:55 +000012449static const HChar *
floriand2129202012-09-01 20:01:39 +000012450s390_irgen_ECAG(UChar r1, UChar r3 __attribute__((unused)), IRTemp op2addr)
florian8c88cb62012-08-26 18:58:13 +000012451{
12452 if (! s390_host_has_gie) {
floriane75dafa2012-09-01 17:54:09 +000012453 emulation_failure(EmFail_S390X_ecag);
florian8c88cb62012-08-26 18:58:13 +000012454 } else {
12455 put_gpr_dw0(r1, s390_call_ecag(mkexpr(op2addr)));
12456 }
12457
12458 return "ecag";
12459}
12460
12461
sewardj2019a972011-03-07 16:04:07 +000012462/*------------------------------------------------------------*/
12463/*--- Build IR for special instructions ---*/
12464/*------------------------------------------------------------*/
12465
florianb4df7682011-07-05 02:09:01 +000012466static void
sewardj2019a972011-03-07 16:04:07 +000012467s390_irgen_client_request(void)
12468{
12469 if (0)
12470 vex_printf("%%R3 = client_request ( %%R2 )\n");
12471
florianf9e1ed72012-04-17 02:41:56 +000012472 Addr64 next = guest_IA_curr_instr + S390_SPECIAL_OP_PREAMBLE_SIZE
12473 + S390_SPECIAL_OP_SIZE;
sewardj2019a972011-03-07 16:04:07 +000012474
florianf9e1ed72012-04-17 02:41:56 +000012475 dis_res->jk_StopHere = Ijk_ClientReq;
sewardj2019a972011-03-07 16:04:07 +000012476 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +000012477
12478 put_IA(mkaddr_expr(next));
sewardj2019a972011-03-07 16:04:07 +000012479}
12480
florianb4df7682011-07-05 02:09:01 +000012481static void
sewardj2019a972011-03-07 16:04:07 +000012482s390_irgen_guest_NRADDR(void)
12483{
12484 if (0)
12485 vex_printf("%%R3 = guest_NRADDR\n");
12486
floriane88b3c92011-07-05 02:48:39 +000012487 put_gpr_dw0(3, IRExpr_Get(S390X_GUEST_OFFSET(guest_NRADDR), Ity_I64));
sewardj2019a972011-03-07 16:04:07 +000012488}
12489
florianb4df7682011-07-05 02:09:01 +000012490static void
sewardj2019a972011-03-07 16:04:07 +000012491s390_irgen_call_noredir(void)
12492{
florianf9e1ed72012-04-17 02:41:56 +000012493 Addr64 next = guest_IA_curr_instr + S390_SPECIAL_OP_PREAMBLE_SIZE
12494 + S390_SPECIAL_OP_SIZE;
12495
sewardj2019a972011-03-07 16:04:07 +000012496 /* Continue after special op */
florianf9e1ed72012-04-17 02:41:56 +000012497 put_gpr_dw0(14, mkaddr_expr(next));
sewardj2019a972011-03-07 16:04:07 +000012498
12499 /* The address is in REG1, all parameters are in the right (guest) places */
florianf9e1ed72012-04-17 02:41:56 +000012500 put_IA(get_gpr_dw0(1));
sewardj2019a972011-03-07 16:04:07 +000012501
12502 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +000012503 dis_res->jk_StopHere = Ijk_NoRedir;
sewardj2019a972011-03-07 16:04:07 +000012504}
12505
12506/* Force proper alignment for the structures below. */
12507#pragma pack(1)
12508
12509
12510static s390_decode_t
12511s390_decode_2byte_and_irgen(UChar *bytes)
12512{
12513 typedef union {
12514 struct {
12515 unsigned int op : 16;
12516 } E;
12517 struct {
12518 unsigned int op : 8;
12519 unsigned int i : 8;
12520 } I;
12521 struct {
12522 unsigned int op : 8;
12523 unsigned int r1 : 4;
12524 unsigned int r2 : 4;
12525 } RR;
12526 } formats;
12527 union {
12528 formats fmt;
12529 UShort value;
12530 } ovl;
12531
12532 vassert(sizeof(formats) == 2);
12533
12534 ((char *)(&ovl.value))[0] = bytes[0];
12535 ((char *)(&ovl.value))[1] = bytes[1];
12536
12537 switch (ovl.value & 0xffff) {
12538 case 0x0101: /* PR */ goto unimplemented;
12539 case 0x0102: /* UPT */ goto unimplemented;
12540 case 0x0104: /* PTFF */ goto unimplemented;
12541 case 0x0107: /* SCKPF */ goto unimplemented;
12542 case 0x010a: /* PFPO */ goto unimplemented;
12543 case 0x010b: /* TAM */ goto unimplemented;
12544 case 0x010c: /* SAM24 */ goto unimplemented;
12545 case 0x010d: /* SAM31 */ goto unimplemented;
12546 case 0x010e: /* SAM64 */ goto unimplemented;
12547 case 0x01ff: /* TRAP2 */ goto unimplemented;
12548 }
12549
12550 switch ((ovl.value & 0xff00) >> 8) {
12551 case 0x04: /* SPM */ goto unimplemented;
12552 case 0x05: /* BALR */ goto unimplemented;
12553 case 0x06: s390_format_RR_RR(s390_irgen_BCTR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12554 goto ok;
12555 case 0x07: s390_format_RR(s390_irgen_BCR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12556 goto ok;
12557 case 0x0a: s390_format_I(s390_irgen_SVC, ovl.fmt.I.i); goto ok;
12558 case 0x0b: /* BSM */ goto unimplemented;
12559 case 0x0c: /* BASSM */ goto unimplemented;
12560 case 0x0d: s390_format_RR_RR(s390_irgen_BASR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12561 goto ok;
florianb0c9a132011-09-08 15:37:39 +000012562 case 0x0e: s390_format_RR(s390_irgen_MVCL, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12563 goto ok;
12564 case 0x0f: s390_format_RR(s390_irgen_CLCL, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12565 goto ok;
sewardj2019a972011-03-07 16:04:07 +000012566 case 0x10: s390_format_RR_RR(s390_irgen_LPR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12567 goto ok;
12568 case 0x11: s390_format_RR_RR(s390_irgen_LNR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12569 goto ok;
12570 case 0x12: s390_format_RR_RR(s390_irgen_LTR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12571 goto ok;
12572 case 0x13: s390_format_RR_RR(s390_irgen_LCR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12573 goto ok;
12574 case 0x14: s390_format_RR_RR(s390_irgen_NR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12575 goto ok;
12576 case 0x15: s390_format_RR_RR(s390_irgen_CLR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12577 goto ok;
12578 case 0x16: s390_format_RR_RR(s390_irgen_OR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12579 goto ok;
12580 case 0x17: s390_format_RR_RR(s390_irgen_XR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12581 goto ok;
12582 case 0x18: s390_format_RR_RR(s390_irgen_LR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12583 goto ok;
12584 case 0x19: s390_format_RR_RR(s390_irgen_CR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12585 goto ok;
12586 case 0x1a: s390_format_RR_RR(s390_irgen_AR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12587 goto ok;
12588 case 0x1b: s390_format_RR_RR(s390_irgen_SR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12589 goto ok;
12590 case 0x1c: s390_format_RR_RR(s390_irgen_MR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12591 goto ok;
12592 case 0x1d: s390_format_RR_RR(s390_irgen_DR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12593 goto ok;
12594 case 0x1e: s390_format_RR_RR(s390_irgen_ALR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12595 goto ok;
12596 case 0x1f: s390_format_RR_RR(s390_irgen_SLR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12597 goto ok;
12598 case 0x20: /* LPDR */ goto unimplemented;
12599 case 0x21: /* LNDR */ goto unimplemented;
12600 case 0x22: /* LTDR */ goto unimplemented;
12601 case 0x23: /* LCDR */ goto unimplemented;
12602 case 0x24: /* HDR */ goto unimplemented;
12603 case 0x25: /* LDXR */ goto unimplemented;
12604 case 0x26: /* MXR */ goto unimplemented;
12605 case 0x27: /* MXDR */ goto unimplemented;
12606 case 0x28: s390_format_RR_FF(s390_irgen_LDR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12607 goto ok;
12608 case 0x29: /* CDR */ goto unimplemented;
12609 case 0x2a: /* ADR */ goto unimplemented;
12610 case 0x2b: /* SDR */ goto unimplemented;
12611 case 0x2c: /* MDR */ goto unimplemented;
12612 case 0x2d: /* DDR */ goto unimplemented;
12613 case 0x2e: /* AWR */ goto unimplemented;
12614 case 0x2f: /* SWR */ goto unimplemented;
12615 case 0x30: /* LPER */ goto unimplemented;
12616 case 0x31: /* LNER */ goto unimplemented;
12617 case 0x32: /* LTER */ goto unimplemented;
12618 case 0x33: /* LCER */ goto unimplemented;
12619 case 0x34: /* HER */ goto unimplemented;
12620 case 0x35: /* LEDR */ goto unimplemented;
12621 case 0x36: /* AXR */ goto unimplemented;
12622 case 0x37: /* SXR */ goto unimplemented;
12623 case 0x38: s390_format_RR_FF(s390_irgen_LER, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12624 goto ok;
12625 case 0x39: /* CER */ goto unimplemented;
12626 case 0x3a: /* AER */ goto unimplemented;
12627 case 0x3b: /* SER */ goto unimplemented;
12628 case 0x3c: /* MDER */ goto unimplemented;
12629 case 0x3d: /* DER */ goto unimplemented;
12630 case 0x3e: /* AUR */ goto unimplemented;
12631 case 0x3f: /* SUR */ goto unimplemented;
12632 }
12633
12634 return S390_DECODE_UNKNOWN_INSN;
12635
12636ok:
12637 return S390_DECODE_OK;
12638
12639unimplemented:
12640 return S390_DECODE_UNIMPLEMENTED_INSN;
12641}
12642
12643static s390_decode_t
12644s390_decode_4byte_and_irgen(UChar *bytes)
12645{
12646 typedef union {
12647 struct {
12648 unsigned int op1 : 8;
12649 unsigned int r1 : 4;
12650 unsigned int op2 : 4;
12651 unsigned int i2 : 16;
12652 } RI;
12653 struct {
12654 unsigned int op : 16;
12655 unsigned int : 8;
12656 unsigned int r1 : 4;
12657 unsigned int r2 : 4;
12658 } RRE;
12659 struct {
12660 unsigned int op : 16;
12661 unsigned int r1 : 4;
12662 unsigned int : 4;
12663 unsigned int r3 : 4;
12664 unsigned int r2 : 4;
12665 } RRF;
12666 struct {
12667 unsigned int op : 16;
florian1c8f7ff2012-09-01 00:12:11 +000012668 unsigned int m3 : 4;
sewardj2019a972011-03-07 16:04:07 +000012669 unsigned int m4 : 4;
12670 unsigned int r1 : 4;
12671 unsigned int r2 : 4;
12672 } RRF2;
12673 struct {
12674 unsigned int op : 16;
12675 unsigned int r3 : 4;
12676 unsigned int : 4;
12677 unsigned int r1 : 4;
12678 unsigned int r2 : 4;
12679 } RRF3;
12680 struct {
12681 unsigned int op : 16;
12682 unsigned int r3 : 4;
12683 unsigned int : 4;
12684 unsigned int r1 : 4;
12685 unsigned int r2 : 4;
12686 } RRR;
12687 struct {
12688 unsigned int op : 16;
12689 unsigned int r3 : 4;
florian12390202012-11-10 22:34:14 +000012690 unsigned int m4 : 4;
sewardj2019a972011-03-07 16:04:07 +000012691 unsigned int r1 : 4;
12692 unsigned int r2 : 4;
12693 } RRF4;
12694 struct {
12695 unsigned int op : 8;
12696 unsigned int r1 : 4;
12697 unsigned int r3 : 4;
12698 unsigned int b2 : 4;
12699 unsigned int d2 : 12;
12700 } RS;
12701 struct {
12702 unsigned int op : 8;
12703 unsigned int r1 : 4;
12704 unsigned int r3 : 4;
12705 unsigned int i2 : 16;
12706 } RSI;
12707 struct {
12708 unsigned int op : 8;
12709 unsigned int r1 : 4;
12710 unsigned int x2 : 4;
12711 unsigned int b2 : 4;
12712 unsigned int d2 : 12;
12713 } RX;
12714 struct {
12715 unsigned int op : 16;
12716 unsigned int b2 : 4;
12717 unsigned int d2 : 12;
12718 } S;
12719 struct {
12720 unsigned int op : 8;
12721 unsigned int i2 : 8;
12722 unsigned int b1 : 4;
12723 unsigned int d1 : 12;
12724 } SI;
12725 } formats;
12726 union {
12727 formats fmt;
12728 UInt value;
12729 } ovl;
12730
12731 vassert(sizeof(formats) == 4);
12732
12733 ((char *)(&ovl.value))[0] = bytes[0];
12734 ((char *)(&ovl.value))[1] = bytes[1];
12735 ((char *)(&ovl.value))[2] = bytes[2];
12736 ((char *)(&ovl.value))[3] = bytes[3];
12737
12738 switch ((ovl.value & 0xff0f0000) >> 16) {
12739 case 0xa500: s390_format_RI_RU(s390_irgen_IIHH, ovl.fmt.RI.r1,
12740 ovl.fmt.RI.i2); goto ok;
12741 case 0xa501: s390_format_RI_RU(s390_irgen_IIHL, ovl.fmt.RI.r1,
12742 ovl.fmt.RI.i2); goto ok;
12743 case 0xa502: s390_format_RI_RU(s390_irgen_IILH, ovl.fmt.RI.r1,
12744 ovl.fmt.RI.i2); goto ok;
12745 case 0xa503: s390_format_RI_RU(s390_irgen_IILL, ovl.fmt.RI.r1,
12746 ovl.fmt.RI.i2); goto ok;
12747 case 0xa504: s390_format_RI_RU(s390_irgen_NIHH, ovl.fmt.RI.r1,
12748 ovl.fmt.RI.i2); goto ok;
12749 case 0xa505: s390_format_RI_RU(s390_irgen_NIHL, ovl.fmt.RI.r1,
12750 ovl.fmt.RI.i2); goto ok;
12751 case 0xa506: s390_format_RI_RU(s390_irgen_NILH, ovl.fmt.RI.r1,
12752 ovl.fmt.RI.i2); goto ok;
12753 case 0xa507: s390_format_RI_RU(s390_irgen_NILL, ovl.fmt.RI.r1,
12754 ovl.fmt.RI.i2); goto ok;
12755 case 0xa508: s390_format_RI_RU(s390_irgen_OIHH, ovl.fmt.RI.r1,
12756 ovl.fmt.RI.i2); goto ok;
12757 case 0xa509: s390_format_RI_RU(s390_irgen_OIHL, ovl.fmt.RI.r1,
12758 ovl.fmt.RI.i2); goto ok;
12759 case 0xa50a: s390_format_RI_RU(s390_irgen_OILH, ovl.fmt.RI.r1,
12760 ovl.fmt.RI.i2); goto ok;
12761 case 0xa50b: s390_format_RI_RU(s390_irgen_OILL, ovl.fmt.RI.r1,
12762 ovl.fmt.RI.i2); goto ok;
12763 case 0xa50c: s390_format_RI_RU(s390_irgen_LLIHH, ovl.fmt.RI.r1,
12764 ovl.fmt.RI.i2); goto ok;
12765 case 0xa50d: s390_format_RI_RU(s390_irgen_LLIHL, ovl.fmt.RI.r1,
12766 ovl.fmt.RI.i2); goto ok;
12767 case 0xa50e: s390_format_RI_RU(s390_irgen_LLILH, ovl.fmt.RI.r1,
12768 ovl.fmt.RI.i2); goto ok;
12769 case 0xa50f: s390_format_RI_RU(s390_irgen_LLILL, ovl.fmt.RI.r1,
12770 ovl.fmt.RI.i2); goto ok;
12771 case 0xa700: s390_format_RI_RU(s390_irgen_TMLH, ovl.fmt.RI.r1,
12772 ovl.fmt.RI.i2); goto ok;
12773 case 0xa701: s390_format_RI_RU(s390_irgen_TMLL, ovl.fmt.RI.r1,
12774 ovl.fmt.RI.i2); goto ok;
12775 case 0xa702: s390_format_RI_RU(s390_irgen_TMHH, ovl.fmt.RI.r1,
12776 ovl.fmt.RI.i2); goto ok;
12777 case 0xa703: s390_format_RI_RU(s390_irgen_TMHL, ovl.fmt.RI.r1,
12778 ovl.fmt.RI.i2); goto ok;
12779 case 0xa704: s390_format_RI(s390_irgen_BRC, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
12780 goto ok;
12781 case 0xa705: s390_format_RI_RP(s390_irgen_BRAS, ovl.fmt.RI.r1,
12782 ovl.fmt.RI.i2); goto ok;
12783 case 0xa706: s390_format_RI_RP(s390_irgen_BRCT, ovl.fmt.RI.r1,
12784 ovl.fmt.RI.i2); goto ok;
12785 case 0xa707: s390_format_RI_RP(s390_irgen_BRCTG, ovl.fmt.RI.r1,
12786 ovl.fmt.RI.i2); goto ok;
12787 case 0xa708: s390_format_RI_RI(s390_irgen_LHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
12788 goto ok;
12789 case 0xa709: s390_format_RI_RI(s390_irgen_LGHI, ovl.fmt.RI.r1,
12790 ovl.fmt.RI.i2); goto ok;
12791 case 0xa70a: s390_format_RI_RI(s390_irgen_AHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
12792 goto ok;
12793 case 0xa70b: s390_format_RI_RI(s390_irgen_AGHI, ovl.fmt.RI.r1,
12794 ovl.fmt.RI.i2); goto ok;
12795 case 0xa70c: s390_format_RI_RI(s390_irgen_MHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
12796 goto ok;
12797 case 0xa70d: s390_format_RI_RI(s390_irgen_MGHI, ovl.fmt.RI.r1,
12798 ovl.fmt.RI.i2); goto ok;
12799 case 0xa70e: s390_format_RI_RI(s390_irgen_CHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
12800 goto ok;
12801 case 0xa70f: s390_format_RI_RI(s390_irgen_CGHI, ovl.fmt.RI.r1,
12802 ovl.fmt.RI.i2); goto ok;
12803 }
12804
12805 switch ((ovl.value & 0xffff0000) >> 16) {
12806 case 0x8000: /* SSM */ goto unimplemented;
12807 case 0x8200: /* LPSW */ goto unimplemented;
florian7700fc92012-01-16 17:25:55 +000012808 case 0x9300: /* TS */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000012809 case 0xb202: /* STIDP */ goto unimplemented;
12810 case 0xb204: /* SCK */ goto unimplemented;
florian7700fc92012-01-16 17:25:55 +000012811 case 0xb205: s390_format_S_RD(s390_irgen_STCK, ovl.fmt.S.b2, ovl.fmt.S.d2);
12812 goto ok;
sewardj2019a972011-03-07 16:04:07 +000012813 case 0xb206: /* SCKC */ goto unimplemented;
12814 case 0xb207: /* STCKC */ goto unimplemented;
12815 case 0xb208: /* SPT */ goto unimplemented;
12816 case 0xb209: /* STPT */ goto unimplemented;
12817 case 0xb20a: /* SPKA */ goto unimplemented;
12818 case 0xb20b: /* IPK */ goto unimplemented;
12819 case 0xb20d: /* PTLB */ goto unimplemented;
12820 case 0xb210: /* SPX */ goto unimplemented;
12821 case 0xb211: /* STPX */ goto unimplemented;
12822 case 0xb212: /* STAP */ goto unimplemented;
12823 case 0xb214: /* SIE */ goto unimplemented;
12824 case 0xb218: /* PC */ goto unimplemented;
12825 case 0xb219: /* SAC */ goto unimplemented;
12826 case 0xb21a: /* CFC */ goto unimplemented;
12827 case 0xb221: /* IPTE */ goto unimplemented;
12828 case 0xb222: s390_format_RRE_R0(s390_irgen_IPM, ovl.fmt.RRE.r1); goto ok;
12829 case 0xb223: /* IVSK */ goto unimplemented;
12830 case 0xb224: /* IAC */ goto unimplemented;
12831 case 0xb225: /* SSAR */ goto unimplemented;
12832 case 0xb226: /* EPAR */ goto unimplemented;
12833 case 0xb227: /* ESAR */ goto unimplemented;
12834 case 0xb228: /* PT */ goto unimplemented;
12835 case 0xb229: /* ISKE */ goto unimplemented;
12836 case 0xb22a: /* RRBE */ goto unimplemented;
12837 case 0xb22b: /* SSKE */ goto unimplemented;
12838 case 0xb22c: /* TB */ goto unimplemented;
12839 case 0xb22d: /* DXR */ goto unimplemented;
12840 case 0xb22e: /* PGIN */ goto unimplemented;
12841 case 0xb22f: /* PGOUT */ goto unimplemented;
12842 case 0xb230: /* CSCH */ goto unimplemented;
12843 case 0xb231: /* HSCH */ goto unimplemented;
12844 case 0xb232: /* MSCH */ goto unimplemented;
12845 case 0xb233: /* SSCH */ goto unimplemented;
12846 case 0xb234: /* STSCH */ goto unimplemented;
12847 case 0xb235: /* TSCH */ goto unimplemented;
12848 case 0xb236: /* TPI */ goto unimplemented;
12849 case 0xb237: /* SAL */ goto unimplemented;
12850 case 0xb238: /* RSCH */ goto unimplemented;
12851 case 0xb239: /* STCRW */ goto unimplemented;
12852 case 0xb23a: /* STCPS */ goto unimplemented;
12853 case 0xb23b: /* RCHP */ goto unimplemented;
12854 case 0xb23c: /* SCHM */ goto unimplemented;
12855 case 0xb240: /* BAKR */ goto unimplemented;
floriana4384a32011-08-11 16:58:45 +000012856 case 0xb241: s390_format_RRE(s390_irgen_CKSM, ovl.fmt.RRE.r1,
12857 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000012858 case 0xb244: /* SQDR */ goto unimplemented;
12859 case 0xb245: /* SQER */ goto unimplemented;
12860 case 0xb246: /* STURA */ goto unimplemented;
12861 case 0xb247: /* MSTA */ goto unimplemented;
12862 case 0xb248: /* PALB */ goto unimplemented;
12863 case 0xb249: /* EREG */ goto unimplemented;
12864 case 0xb24a: /* ESTA */ goto unimplemented;
12865 case 0xb24b: /* LURA */ goto unimplemented;
12866 case 0xb24c: /* TAR */ goto unimplemented;
12867 case 0xb24d: s390_format_RRE(s390_irgen_CPYA, ovl.fmt.RRE.r1,
12868 ovl.fmt.RRE.r2); goto ok;
12869 case 0xb24e: s390_format_RRE(s390_irgen_SAR, ovl.fmt.RRE.r1, ovl.fmt.RRE.r2);
12870 goto ok;
12871 case 0xb24f: s390_format_RRE(s390_irgen_EAR, ovl.fmt.RRE.r1, ovl.fmt.RRE.r2);
12872 goto ok;
12873 case 0xb250: /* CSP */ goto unimplemented;
12874 case 0xb252: s390_format_RRE_RR(s390_irgen_MSR, ovl.fmt.RRE.r1,
12875 ovl.fmt.RRE.r2); goto ok;
12876 case 0xb254: /* MVPG */ goto unimplemented;
12877 case 0xb255: s390_format_RRE_RR(s390_irgen_MVST, ovl.fmt.RRE.r1,
12878 ovl.fmt.RRE.r2); goto ok;
12879 case 0xb257: /* CUSE */ goto unimplemented;
12880 case 0xb258: /* BSG */ goto unimplemented;
12881 case 0xb25a: /* BSA */ goto unimplemented;
12882 case 0xb25d: s390_format_RRE_RR(s390_irgen_CLST, ovl.fmt.RRE.r1,
12883 ovl.fmt.RRE.r2); goto ok;
12884 case 0xb25e: s390_format_RRE_RR(s390_irgen_SRST, ovl.fmt.RRE.r1,
12885 ovl.fmt.RRE.r2); goto ok;
12886 case 0xb263: /* CMPSC */ goto unimplemented;
12887 case 0xb274: /* SIGA */ goto unimplemented;
12888 case 0xb276: /* XSCH */ goto unimplemented;
12889 case 0xb277: /* RP */ goto unimplemented;
sewardj1e5fea62011-05-17 16:18:36 +000012890 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 +000012891 case 0xb279: /* SACF */ goto unimplemented;
sewardj1e5fea62011-05-17 16:18:36 +000012892 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 +000012893 case 0xb27d: /* STSI */ goto unimplemented;
12894 case 0xb299: s390_format_S_RD(s390_irgen_SRNM, ovl.fmt.S.b2, ovl.fmt.S.d2);
12895 goto ok;
12896 case 0xb29c: s390_format_S_RD(s390_irgen_STFPC, ovl.fmt.S.b2, ovl.fmt.S.d2);
12897 goto ok;
12898 case 0xb29d: s390_format_S_RD(s390_irgen_LFPC, ovl.fmt.S.b2, ovl.fmt.S.d2);
12899 goto ok;
florian730448f2012-02-04 17:07:07 +000012900 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 +000012901 case 0xb2a6: s390_format_RRF_M0RERE(s390_irgen_CU21, ovl.fmt.RRF3.r3,
12902 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
12903 goto ok;
florian6d9b9b22012-08-03 18:35:39 +000012904 case 0xb2a7: s390_format_RRF_M0RERE(s390_irgen_CU12, ovl.fmt.RRF3.r3,
12905 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
12906 goto ok;
florian933065d2011-07-11 01:48:02 +000012907 case 0xb2b0: s390_format_S_RD(s390_irgen_STFLE, ovl.fmt.S.b2, ovl.fmt.S.d2);
12908 goto ok;
sewardj2019a972011-03-07 16:04:07 +000012909 case 0xb2b1: /* STFL */ goto unimplemented;
12910 case 0xb2b2: /* LPSWE */ goto unimplemented;
florianf0fa1be2012-09-18 20:24:38 +000012911 case 0xb2b8: s390_irgen_srnmb_wrapper(ovl.fmt.S.b2, ovl.fmt.S.d2);
12912 goto ok;
sewardj2019a972011-03-07 16:04:07 +000012913 case 0xb2b9: /* SRNMT */ goto unimplemented;
12914 case 0xb2bd: /* LFAS */ goto unimplemented;
12915 case 0xb2ff: /* TRAP4 */ goto unimplemented;
12916 case 0xb300: s390_format_RRE_FF(s390_irgen_LPEBR, ovl.fmt.RRE.r1,
12917 ovl.fmt.RRE.r2); goto ok;
12918 case 0xb301: s390_format_RRE_FF(s390_irgen_LNEBR, ovl.fmt.RRE.r1,
12919 ovl.fmt.RRE.r2); goto ok;
12920 case 0xb302: s390_format_RRE_FF(s390_irgen_LTEBR, ovl.fmt.RRE.r1,
12921 ovl.fmt.RRE.r2); goto ok;
12922 case 0xb303: s390_format_RRE_FF(s390_irgen_LCEBR, ovl.fmt.RRE.r1,
12923 ovl.fmt.RRE.r2); goto ok;
12924 case 0xb304: s390_format_RRE_FF(s390_irgen_LDEBR, ovl.fmt.RRE.r1,
12925 ovl.fmt.RRE.r2); goto ok;
12926 case 0xb305: s390_format_RRE_FF(s390_irgen_LXDBR, ovl.fmt.RRE.r1,
12927 ovl.fmt.RRE.r2); goto ok;
12928 case 0xb306: s390_format_RRE_FF(s390_irgen_LXEBR, ovl.fmt.RRE.r1,
12929 ovl.fmt.RRE.r2); goto ok;
12930 case 0xb307: /* MXDBR */ goto unimplemented;
12931 case 0xb308: /* KEBR */ goto unimplemented;
12932 case 0xb309: s390_format_RRE_FF(s390_irgen_CEBR, ovl.fmt.RRE.r1,
12933 ovl.fmt.RRE.r2); goto ok;
12934 case 0xb30a: s390_format_RRE_FF(s390_irgen_AEBR, ovl.fmt.RRE.r1,
12935 ovl.fmt.RRE.r2); goto ok;
12936 case 0xb30b: s390_format_RRE_FF(s390_irgen_SEBR, ovl.fmt.RRE.r1,
12937 ovl.fmt.RRE.r2); goto ok;
12938 case 0xb30c: /* MDEBR */ goto unimplemented;
12939 case 0xb30d: s390_format_RRE_FF(s390_irgen_DEBR, ovl.fmt.RRE.r1,
12940 ovl.fmt.RRE.r2); goto ok;
12941 case 0xb30e: s390_format_RRF_F0FF(s390_irgen_MAEBR, ovl.fmt.RRF.r1,
12942 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
12943 case 0xb30f: s390_format_RRF_F0FF(s390_irgen_MSEBR, ovl.fmt.RRF.r1,
12944 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
12945 case 0xb310: s390_format_RRE_FF(s390_irgen_LPDBR, ovl.fmt.RRE.r1,
12946 ovl.fmt.RRE.r2); goto ok;
12947 case 0xb311: s390_format_RRE_FF(s390_irgen_LNDBR, ovl.fmt.RRE.r1,
12948 ovl.fmt.RRE.r2); goto ok;
12949 case 0xb312: s390_format_RRE_FF(s390_irgen_LTDBR, ovl.fmt.RRE.r1,
12950 ovl.fmt.RRE.r2); goto ok;
12951 case 0xb313: s390_format_RRE_FF(s390_irgen_LCDBR, ovl.fmt.RRE.r1,
12952 ovl.fmt.RRE.r2); goto ok;
12953 case 0xb314: s390_format_RRE_FF(s390_irgen_SQEBR, ovl.fmt.RRE.r1,
12954 ovl.fmt.RRE.r2); goto ok;
12955 case 0xb315: s390_format_RRE_FF(s390_irgen_SQDBR, ovl.fmt.RRE.r1,
12956 ovl.fmt.RRE.r2); goto ok;
12957 case 0xb316: s390_format_RRE_FF(s390_irgen_SQXBR, ovl.fmt.RRE.r1,
12958 ovl.fmt.RRE.r2); goto ok;
12959 case 0xb317: s390_format_RRE_FF(s390_irgen_MEEBR, ovl.fmt.RRE.r1,
12960 ovl.fmt.RRE.r2); goto ok;
12961 case 0xb318: /* KDBR */ goto unimplemented;
12962 case 0xb319: s390_format_RRE_FF(s390_irgen_CDBR, ovl.fmt.RRE.r1,
12963 ovl.fmt.RRE.r2); goto ok;
12964 case 0xb31a: s390_format_RRE_FF(s390_irgen_ADBR, ovl.fmt.RRE.r1,
12965 ovl.fmt.RRE.r2); goto ok;
12966 case 0xb31b: s390_format_RRE_FF(s390_irgen_SDBR, ovl.fmt.RRE.r1,
12967 ovl.fmt.RRE.r2); goto ok;
12968 case 0xb31c: s390_format_RRE_FF(s390_irgen_MDBR, ovl.fmt.RRE.r1,
12969 ovl.fmt.RRE.r2); goto ok;
12970 case 0xb31d: s390_format_RRE_FF(s390_irgen_DDBR, ovl.fmt.RRE.r1,
12971 ovl.fmt.RRE.r2); goto ok;
12972 case 0xb31e: s390_format_RRF_F0FF(s390_irgen_MADBR, ovl.fmt.RRF.r1,
12973 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
12974 case 0xb31f: s390_format_RRF_F0FF(s390_irgen_MSDBR, ovl.fmt.RRF.r1,
12975 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
12976 case 0xb324: /* LDER */ goto unimplemented;
12977 case 0xb325: /* LXDR */ goto unimplemented;
12978 case 0xb326: /* LXER */ goto unimplemented;
12979 case 0xb32e: /* MAER */ goto unimplemented;
12980 case 0xb32f: /* MSER */ goto unimplemented;
12981 case 0xb336: /* SQXR */ goto unimplemented;
12982 case 0xb337: /* MEER */ goto unimplemented;
12983 case 0xb338: /* MAYLR */ goto unimplemented;
12984 case 0xb339: /* MYLR */ goto unimplemented;
12985 case 0xb33a: /* MAYR */ goto unimplemented;
12986 case 0xb33b: /* MYR */ goto unimplemented;
12987 case 0xb33c: /* MAYHR */ goto unimplemented;
12988 case 0xb33d: /* MYHR */ goto unimplemented;
12989 case 0xb33e: /* MADR */ goto unimplemented;
12990 case 0xb33f: /* MSDR */ goto unimplemented;
12991 case 0xb340: s390_format_RRE_FF(s390_irgen_LPXBR, ovl.fmt.RRE.r1,
12992 ovl.fmt.RRE.r2); goto ok;
12993 case 0xb341: s390_format_RRE_FF(s390_irgen_LNXBR, ovl.fmt.RRE.r1,
12994 ovl.fmt.RRE.r2); goto ok;
12995 case 0xb342: s390_format_RRE_FF(s390_irgen_LTXBR, ovl.fmt.RRE.r1,
12996 ovl.fmt.RRE.r2); goto ok;
12997 case 0xb343: s390_format_RRE_FF(s390_irgen_LCXBR, ovl.fmt.RRE.r1,
12998 ovl.fmt.RRE.r2); goto ok;
florian4b8efad2012-09-02 18:07:08 +000012999 case 0xb344: s390_format_RRF_UUFF(s390_irgen_LEDBR, ovl.fmt.RRF2.m3,
13000 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13001 ovl.fmt.RRF2.r2); goto ok;
13002 case 0xb345: s390_format_RRF_UUFF(s390_irgen_LDXBR, ovl.fmt.RRF2.m3,
13003 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13004 ovl.fmt.RRF2.r2); goto ok;
13005 case 0xb346: s390_format_RRF_UUFF(s390_irgen_LEXBR, ovl.fmt.RRF2.m3,
13006 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13007 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013008 case 0xb347: /* FIXBR */ goto unimplemented;
13009 case 0xb348: /* KXBR */ goto unimplemented;
13010 case 0xb349: s390_format_RRE_FF(s390_irgen_CXBR, ovl.fmt.RRE.r1,
13011 ovl.fmt.RRE.r2); goto ok;
13012 case 0xb34a: s390_format_RRE_FF(s390_irgen_AXBR, ovl.fmt.RRE.r1,
13013 ovl.fmt.RRE.r2); goto ok;
13014 case 0xb34b: s390_format_RRE_FF(s390_irgen_SXBR, ovl.fmt.RRE.r1,
13015 ovl.fmt.RRE.r2); goto ok;
13016 case 0xb34c: s390_format_RRE_FF(s390_irgen_MXBR, ovl.fmt.RRE.r1,
13017 ovl.fmt.RRE.r2); goto ok;
13018 case 0xb34d: s390_format_RRE_FF(s390_irgen_DXBR, ovl.fmt.RRE.r1,
13019 ovl.fmt.RRE.r2); goto ok;
13020 case 0xb350: /* TBEDR */ goto unimplemented;
13021 case 0xb351: /* TBDR */ goto unimplemented;
13022 case 0xb353: /* DIEBR */ goto unimplemented;
13023 case 0xb357: /* FIEBR */ goto unimplemented;
13024 case 0xb358: /* THDER */ goto unimplemented;
13025 case 0xb359: /* THDR */ goto unimplemented;
13026 case 0xb35b: /* DIDBR */ goto unimplemented;
13027 case 0xb35f: /* FIDBR */ goto unimplemented;
13028 case 0xb360: /* LPXR */ goto unimplemented;
13029 case 0xb361: /* LNXR */ goto unimplemented;
13030 case 0xb362: /* LTXR */ goto unimplemented;
13031 case 0xb363: /* LCXR */ goto unimplemented;
13032 case 0xb365: s390_format_RRE_FF(s390_irgen_LXR, ovl.fmt.RRE.r1,
13033 ovl.fmt.RRE.r2); goto ok;
13034 case 0xb366: /* LEXR */ goto unimplemented;
13035 case 0xb367: /* FIXR */ goto unimplemented;
13036 case 0xb369: /* CXR */ goto unimplemented;
13037 case 0xb370: s390_format_RRE_FF(s390_irgen_LPDFR, ovl.fmt.RRE.r1,
13038 ovl.fmt.RRE.r2); goto ok;
13039 case 0xb371: s390_format_RRE_FF(s390_irgen_LNDFR, ovl.fmt.RRE.r1,
13040 ovl.fmt.RRE.r2); goto ok;
13041 case 0xb372: s390_format_RRF_F0FF2(s390_irgen_CPSDR, ovl.fmt.RRF3.r3,
13042 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
13043 goto ok;
13044 case 0xb373: s390_format_RRE_FF(s390_irgen_LCDFR, ovl.fmt.RRE.r1,
13045 ovl.fmt.RRE.r2); goto ok;
13046 case 0xb374: s390_format_RRE_F0(s390_irgen_LZER, ovl.fmt.RRE.r1); goto ok;
13047 case 0xb375: s390_format_RRE_F0(s390_irgen_LZDR, ovl.fmt.RRE.r1); goto ok;
13048 case 0xb376: s390_format_RRE_F0(s390_irgen_LZXR, ovl.fmt.RRE.r1); goto ok;
13049 case 0xb377: /* FIER */ goto unimplemented;
13050 case 0xb37f: /* FIDR */ goto unimplemented;
13051 case 0xb384: s390_format_RRE_R0(s390_irgen_SFPC, ovl.fmt.RRE.r1); goto ok;
13052 case 0xb385: /* SFASR */ goto unimplemented;
13053 case 0xb38c: s390_format_RRE_R0(s390_irgen_EFPC, ovl.fmt.RRE.r1); goto ok;
florian1c8f7ff2012-09-01 00:12:11 +000013054 case 0xb390: s390_format_RRF_UUFR(s390_irgen_CELFBR, ovl.fmt.RRF2.m3,
13055 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13056 ovl.fmt.RRF2.r2); goto ok;
13057 case 0xb391: s390_format_RRF_UUFR(s390_irgen_CDLFBR, ovl.fmt.RRF2.m3,
13058 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13059 ovl.fmt.RRF2.r2); goto ok;
13060 case 0xb392: s390_format_RRF_UUFR(s390_irgen_CXLFBR, ovl.fmt.RRF2.m3,
13061 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13062 ovl.fmt.RRF2.r2); goto ok;
florian4b8efad2012-09-02 18:07:08 +000013063 case 0xb394: s390_format_RRF_UUFR(s390_irgen_CEFBR, ovl.fmt.RRF2.m3,
13064 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13065 ovl.fmt.RRF2.r2); goto ok;
13066 case 0xb395: s390_format_RRF_UUFR(s390_irgen_CDFBR, ovl.fmt.RRF2.m3,
13067 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13068 ovl.fmt.RRF2.r2); goto ok;
13069 case 0xb396: s390_format_RRF_UUFR(s390_irgen_CXFBR, ovl.fmt.RRF2.m3,
13070 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13071 ovl.fmt.RRF2.r2); goto ok;
13072 case 0xb398: s390_format_RRF_UURF(s390_irgen_CFEBR, ovl.fmt.RRF2.m3,
13073 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13074 ovl.fmt.RRF2.r2); goto ok;
13075 case 0xb399: s390_format_RRF_UURF(s390_irgen_CFDBR, ovl.fmt.RRF2.m3,
13076 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13077 ovl.fmt.RRF2.r2); goto ok;
13078 case 0xb39a: s390_format_RRF_UURF(s390_irgen_CFXBR, ovl.fmt.RRF2.m3,
13079 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13080 ovl.fmt.RRF2.r2); goto ok;
florian1c8f7ff2012-09-01 00:12:11 +000013081 case 0xb39c: s390_format_RRF_UURF(s390_irgen_CLFEBR, ovl.fmt.RRF2.m3,
13082 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13083 ovl.fmt.RRF2.r2); goto ok;
13084 case 0xb39d: s390_format_RRF_UURF(s390_irgen_CLFDBR, ovl.fmt.RRF2.m3,
13085 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13086 ovl.fmt.RRF2.r2); goto ok;
13087 case 0xb39e: s390_format_RRF_UURF(s390_irgen_CLFXBR, ovl.fmt.RRF2.m3,
13088 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13089 ovl.fmt.RRF2.r2); goto ok;
13090 case 0xb3a0: s390_format_RRF_UUFR(s390_irgen_CELGBR, ovl.fmt.RRF2.m3,
13091 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13092 ovl.fmt.RRF2.r2); goto ok;
13093 case 0xb3a1: s390_format_RRF_UUFR(s390_irgen_CDLGBR, ovl.fmt.RRF2.m3,
13094 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13095 ovl.fmt.RRF2.r2); goto ok;
13096 case 0xb3a2: s390_format_RRF_UUFR(s390_irgen_CXLGBR, ovl.fmt.RRF2.m3,
13097 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13098 ovl.fmt.RRF2.r2); goto ok;
florian4b8efad2012-09-02 18:07:08 +000013099 case 0xb3a4: s390_format_RRF_UUFR(s390_irgen_CEGBR, ovl.fmt.RRF2.m3,
13100 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13101 ovl.fmt.RRF2.r2); goto ok;
13102 case 0xb3a5: s390_format_RRF_UUFR(s390_irgen_CDGBR, ovl.fmt.RRF2.m3,
13103 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13104 ovl.fmt.RRF2.r2); goto ok;
13105 case 0xb3a6: s390_format_RRF_UUFR(s390_irgen_CXGBR, ovl.fmt.RRF2.m3,
13106 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13107 ovl.fmt.RRF2.r2); goto ok;
13108 case 0xb3a8: s390_format_RRF_UURF(s390_irgen_CGEBR, ovl.fmt.RRF2.m3,
13109 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13110 ovl.fmt.RRF2.r2); goto ok;
13111 case 0xb3a9: s390_format_RRF_UURF(s390_irgen_CGDBR, ovl.fmt.RRF2.m3,
13112 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13113 ovl.fmt.RRF2.r2); goto ok;
13114 case 0xb3aa: s390_format_RRF_UURF(s390_irgen_CGXBR, ovl.fmt.RRF2.m3,
13115 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13116 ovl.fmt.RRF2.r2); goto ok;
florian1c8f7ff2012-09-01 00:12:11 +000013117 case 0xb3ac: s390_format_RRF_UURF(s390_irgen_CLGEBR, ovl.fmt.RRF2.m3,
13118 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13119 ovl.fmt.RRF2.r2); goto ok;
13120 case 0xb3ad: s390_format_RRF_UURF(s390_irgen_CLGDBR, ovl.fmt.RRF2.m3,
13121 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13122 ovl.fmt.RRF2.r2); goto ok;
13123 case 0xb3ae: s390_format_RRF_UURF(s390_irgen_CLGXBR, ovl.fmt.RRF2.m3,
13124 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13125 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013126 case 0xb3b4: /* CEFR */ goto unimplemented;
13127 case 0xb3b5: /* CDFR */ goto unimplemented;
13128 case 0xb3b6: /* CXFR */ goto unimplemented;
13129 case 0xb3b8: /* CFER */ goto unimplemented;
13130 case 0xb3b9: /* CFDR */ goto unimplemented;
13131 case 0xb3ba: /* CFXR */ goto unimplemented;
13132 case 0xb3c1: s390_format_RRE_FR(s390_irgen_LDGR, ovl.fmt.RRE.r1,
13133 ovl.fmt.RRE.r2); goto ok;
13134 case 0xb3c4: /* CEGR */ goto unimplemented;
13135 case 0xb3c5: /* CDGR */ goto unimplemented;
13136 case 0xb3c6: /* CXGR */ goto unimplemented;
13137 case 0xb3c8: /* CGER */ goto unimplemented;
13138 case 0xb3c9: /* CGDR */ goto unimplemented;
13139 case 0xb3ca: /* CGXR */ goto unimplemented;
13140 case 0xb3cd: s390_format_RRE_RF(s390_irgen_LGDR, ovl.fmt.RRE.r1,
13141 ovl.fmt.RRE.r2); goto ok;
florian12390202012-11-10 22:34:14 +000013142 case 0xb3d0: s390_format_RRF_FUFF2(s390_irgen_MDTRA, ovl.fmt.RRF4.r3,
13143 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
13144 ovl.fmt.RRF4.r2); goto ok;
13145 case 0xb3d1: s390_format_RRF_FUFF2(s390_irgen_DDTRA, ovl.fmt.RRF4.r3,
13146 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
13147 ovl.fmt.RRF4.r2); goto ok;
13148 case 0xb3d2: s390_format_RRF_FUFF2(s390_irgen_ADTRA, ovl.fmt.RRF4.r3,
13149 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
13150 ovl.fmt.RRF4.r2); goto ok;
13151 case 0xb3d3: s390_format_RRF_FUFF2(s390_irgen_SDTRA, ovl.fmt.RRF4.r3,
13152 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
13153 ovl.fmt.RRF4.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013154 case 0xb3d4: /* LDETR */ goto unimplemented;
13155 case 0xb3d5: /* LEDTR */ goto unimplemented;
florian12390202012-11-10 22:34:14 +000013156 case 0xb3d6: s390_format_RRE_FF(s390_irgen_LTDTR, ovl.fmt.RRE.r1,
13157 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013158 case 0xb3d7: /* FIDTR */ goto unimplemented;
13159 case 0xb3d8: /* MXTR */ goto unimplemented;
13160 case 0xb3d9: /* DXTR */ goto unimplemented;
13161 case 0xb3da: /* AXTR */ goto unimplemented;
13162 case 0xb3db: /* SXTR */ goto unimplemented;
13163 case 0xb3dc: /* LXDTR */ goto unimplemented;
13164 case 0xb3dd: /* LDXTR */ goto unimplemented;
13165 case 0xb3de: /* LTXTR */ goto unimplemented;
13166 case 0xb3df: /* FIXTR */ goto unimplemented;
13167 case 0xb3e0: /* KDTR */ goto unimplemented;
13168 case 0xb3e1: /* CGDTR */ goto unimplemented;
13169 case 0xb3e2: /* CUDTR */ goto unimplemented;
13170 case 0xb3e3: /* CSDTR */ goto unimplemented;
13171 case 0xb3e4: /* CDTR */ goto unimplemented;
13172 case 0xb3e5: /* EEDTR */ goto unimplemented;
13173 case 0xb3e7: /* ESDTR */ goto unimplemented;
13174 case 0xb3e8: /* KXTR */ goto unimplemented;
13175 case 0xb3e9: /* CGXTR */ goto unimplemented;
13176 case 0xb3ea: /* CUXTR */ goto unimplemented;
13177 case 0xb3eb: /* CSXTR */ goto unimplemented;
13178 case 0xb3ec: /* CXTR */ goto unimplemented;
13179 case 0xb3ed: /* EEXTR */ goto unimplemented;
13180 case 0xb3ef: /* ESXTR */ goto unimplemented;
13181 case 0xb3f1: /* CDGTR */ goto unimplemented;
13182 case 0xb3f2: /* CDUTR */ goto unimplemented;
13183 case 0xb3f3: /* CDSTR */ goto unimplemented;
13184 case 0xb3f4: /* CEDTR */ goto unimplemented;
13185 case 0xb3f5: /* QADTR */ goto unimplemented;
13186 case 0xb3f6: /* IEDTR */ goto unimplemented;
13187 case 0xb3f7: /* RRDTR */ goto unimplemented;
13188 case 0xb3f9: /* CXGTR */ goto unimplemented;
13189 case 0xb3fa: /* CXUTR */ goto unimplemented;
13190 case 0xb3fb: /* CXSTR */ goto unimplemented;
13191 case 0xb3fc: /* CEXTR */ goto unimplemented;
13192 case 0xb3fd: /* QAXTR */ goto unimplemented;
13193 case 0xb3fe: /* IEXTR */ goto unimplemented;
13194 case 0xb3ff: /* RRXTR */ goto unimplemented;
13195 case 0xb900: s390_format_RRE_RR(s390_irgen_LPGR, ovl.fmt.RRE.r1,
13196 ovl.fmt.RRE.r2); goto ok;
13197 case 0xb901: s390_format_RRE_RR(s390_irgen_LNGR, ovl.fmt.RRE.r1,
13198 ovl.fmt.RRE.r2); goto ok;
13199 case 0xb902: s390_format_RRE_RR(s390_irgen_LTGR, ovl.fmt.RRE.r1,
13200 ovl.fmt.RRE.r2); goto ok;
13201 case 0xb903: s390_format_RRE_RR(s390_irgen_LCGR, ovl.fmt.RRE.r1,
13202 ovl.fmt.RRE.r2); goto ok;
13203 case 0xb904: s390_format_RRE_RR(s390_irgen_LGR, ovl.fmt.RRE.r1,
13204 ovl.fmt.RRE.r2); goto ok;
13205 case 0xb905: /* LURAG */ goto unimplemented;
13206 case 0xb906: s390_format_RRE_RR(s390_irgen_LGBR, ovl.fmt.RRE.r1,
13207 ovl.fmt.RRE.r2); goto ok;
13208 case 0xb907: s390_format_RRE_RR(s390_irgen_LGHR, ovl.fmt.RRE.r1,
13209 ovl.fmt.RRE.r2); goto ok;
13210 case 0xb908: s390_format_RRE_RR(s390_irgen_AGR, ovl.fmt.RRE.r1,
13211 ovl.fmt.RRE.r2); goto ok;
13212 case 0xb909: s390_format_RRE_RR(s390_irgen_SGR, ovl.fmt.RRE.r1,
13213 ovl.fmt.RRE.r2); goto ok;
13214 case 0xb90a: s390_format_RRE_RR(s390_irgen_ALGR, ovl.fmt.RRE.r1,
13215 ovl.fmt.RRE.r2); goto ok;
13216 case 0xb90b: s390_format_RRE_RR(s390_irgen_SLGR, ovl.fmt.RRE.r1,
13217 ovl.fmt.RRE.r2); goto ok;
13218 case 0xb90c: s390_format_RRE_RR(s390_irgen_MSGR, ovl.fmt.RRE.r1,
13219 ovl.fmt.RRE.r2); goto ok;
13220 case 0xb90d: s390_format_RRE_RR(s390_irgen_DSGR, ovl.fmt.RRE.r1,
13221 ovl.fmt.RRE.r2); goto ok;
13222 case 0xb90e: /* EREGG */ goto unimplemented;
13223 case 0xb90f: s390_format_RRE_RR(s390_irgen_LRVGR, ovl.fmt.RRE.r1,
13224 ovl.fmt.RRE.r2); goto ok;
13225 case 0xb910: s390_format_RRE_RR(s390_irgen_LPGFR, ovl.fmt.RRE.r1,
13226 ovl.fmt.RRE.r2); goto ok;
13227 case 0xb911: s390_format_RRE_RR(s390_irgen_LNGFR, ovl.fmt.RRE.r1,
13228 ovl.fmt.RRE.r2); goto ok;
13229 case 0xb912: s390_format_RRE_RR(s390_irgen_LTGFR, ovl.fmt.RRE.r1,
13230 ovl.fmt.RRE.r2); goto ok;
13231 case 0xb913: s390_format_RRE_RR(s390_irgen_LCGFR, ovl.fmt.RRE.r1,
13232 ovl.fmt.RRE.r2); goto ok;
13233 case 0xb914: s390_format_RRE_RR(s390_irgen_LGFR, ovl.fmt.RRE.r1,
13234 ovl.fmt.RRE.r2); goto ok;
13235 case 0xb916: s390_format_RRE_RR(s390_irgen_LLGFR, ovl.fmt.RRE.r1,
13236 ovl.fmt.RRE.r2); goto ok;
13237 case 0xb917: s390_format_RRE_RR(s390_irgen_LLGTR, ovl.fmt.RRE.r1,
13238 ovl.fmt.RRE.r2); goto ok;
13239 case 0xb918: s390_format_RRE_RR(s390_irgen_AGFR, ovl.fmt.RRE.r1,
13240 ovl.fmt.RRE.r2); goto ok;
13241 case 0xb919: s390_format_RRE_RR(s390_irgen_SGFR, ovl.fmt.RRE.r1,
13242 ovl.fmt.RRE.r2); goto ok;
13243 case 0xb91a: s390_format_RRE_RR(s390_irgen_ALGFR, ovl.fmt.RRE.r1,
13244 ovl.fmt.RRE.r2); goto ok;
13245 case 0xb91b: s390_format_RRE_RR(s390_irgen_SLGFR, ovl.fmt.RRE.r1,
13246 ovl.fmt.RRE.r2); goto ok;
13247 case 0xb91c: s390_format_RRE_RR(s390_irgen_MSGFR, ovl.fmt.RRE.r1,
13248 ovl.fmt.RRE.r2); goto ok;
13249 case 0xb91d: s390_format_RRE_RR(s390_irgen_DSGFR, ovl.fmt.RRE.r1,
13250 ovl.fmt.RRE.r2); goto ok;
13251 case 0xb91e: /* KMAC */ goto unimplemented;
13252 case 0xb91f: s390_format_RRE_RR(s390_irgen_LRVR, ovl.fmt.RRE.r1,
13253 ovl.fmt.RRE.r2); goto ok;
13254 case 0xb920: s390_format_RRE_RR(s390_irgen_CGR, ovl.fmt.RRE.r1,
13255 ovl.fmt.RRE.r2); goto ok;
13256 case 0xb921: s390_format_RRE_RR(s390_irgen_CLGR, ovl.fmt.RRE.r1,
13257 ovl.fmt.RRE.r2); goto ok;
13258 case 0xb925: /* STURG */ goto unimplemented;
13259 case 0xb926: s390_format_RRE_RR(s390_irgen_LBR, ovl.fmt.RRE.r1,
13260 ovl.fmt.RRE.r2); goto ok;
13261 case 0xb927: s390_format_RRE_RR(s390_irgen_LHR, ovl.fmt.RRE.r1,
13262 ovl.fmt.RRE.r2); goto ok;
13263 case 0xb928: /* PCKMO */ goto unimplemented;
13264 case 0xb92b: /* KMO */ goto unimplemented;
13265 case 0xb92c: /* PCC */ goto unimplemented;
13266 case 0xb92d: /* KMCTR */ goto unimplemented;
13267 case 0xb92e: /* KM */ goto unimplemented;
13268 case 0xb92f: /* KMC */ goto unimplemented;
13269 case 0xb930: s390_format_RRE_RR(s390_irgen_CGFR, ovl.fmt.RRE.r1,
13270 ovl.fmt.RRE.r2); goto ok;
13271 case 0xb931: s390_format_RRE_RR(s390_irgen_CLGFR, ovl.fmt.RRE.r1,
13272 ovl.fmt.RRE.r2); goto ok;
13273 case 0xb93e: /* KIMD */ goto unimplemented;
13274 case 0xb93f: /* KLMD */ goto unimplemented;
13275 case 0xb941: /* CFDTR */ goto unimplemented;
13276 case 0xb942: /* CLGDTR */ goto unimplemented;
13277 case 0xb943: /* CLFDTR */ goto unimplemented;
13278 case 0xb946: s390_format_RRE_RR(s390_irgen_BCTGR, ovl.fmt.RRE.r1,
13279 ovl.fmt.RRE.r2); goto ok;
13280 case 0xb949: /* CFXTR */ goto unimplemented;
13281 case 0xb94a: /* CLGXTR */ goto unimplemented;
13282 case 0xb94b: /* CLFXTR */ goto unimplemented;
13283 case 0xb951: /* CDFTR */ goto unimplemented;
13284 case 0xb952: /* CDLGTR */ goto unimplemented;
13285 case 0xb953: /* CDLFTR */ goto unimplemented;
13286 case 0xb959: /* CXFTR */ goto unimplemented;
13287 case 0xb95a: /* CXLGTR */ goto unimplemented;
13288 case 0xb95b: /* CXLFTR */ goto unimplemented;
13289 case 0xb960: /* CGRT */ goto unimplemented;
13290 case 0xb961: /* CLGRT */ goto unimplemented;
13291 case 0xb972: /* CRT */ goto unimplemented;
13292 case 0xb973: /* CLRT */ goto unimplemented;
13293 case 0xb980: s390_format_RRE_RR(s390_irgen_NGR, ovl.fmt.RRE.r1,
13294 ovl.fmt.RRE.r2); goto ok;
13295 case 0xb981: s390_format_RRE_RR(s390_irgen_OGR, ovl.fmt.RRE.r1,
13296 ovl.fmt.RRE.r2); goto ok;
13297 case 0xb982: s390_format_RRE_RR(s390_irgen_XGR, ovl.fmt.RRE.r1,
13298 ovl.fmt.RRE.r2); goto ok;
13299 case 0xb983: s390_format_RRE_RR(s390_irgen_FLOGR, ovl.fmt.RRE.r1,
13300 ovl.fmt.RRE.r2); goto ok;
13301 case 0xb984: s390_format_RRE_RR(s390_irgen_LLGCR, ovl.fmt.RRE.r1,
13302 ovl.fmt.RRE.r2); goto ok;
13303 case 0xb985: s390_format_RRE_RR(s390_irgen_LLGHR, ovl.fmt.RRE.r1,
13304 ovl.fmt.RRE.r2); goto ok;
13305 case 0xb986: s390_format_RRE_RR(s390_irgen_MLGR, ovl.fmt.RRE.r1,
13306 ovl.fmt.RRE.r2); goto ok;
13307 case 0xb987: s390_format_RRE_RR(s390_irgen_DLGR, ovl.fmt.RRE.r1,
13308 ovl.fmt.RRE.r2); goto ok;
13309 case 0xb988: s390_format_RRE_RR(s390_irgen_ALCGR, ovl.fmt.RRE.r1,
13310 ovl.fmt.RRE.r2); goto ok;
13311 case 0xb989: s390_format_RRE_RR(s390_irgen_SLBGR, ovl.fmt.RRE.r1,
13312 ovl.fmt.RRE.r2); goto ok;
13313 case 0xb98a: /* CSPG */ goto unimplemented;
13314 case 0xb98d: /* EPSW */ goto unimplemented;
13315 case 0xb98e: /* IDTE */ goto unimplemented;
florian730448f2012-02-04 17:07:07 +000013316 case 0xb990: s390_format_RRF_M0RERE(s390_irgen_TRTT, ovl.fmt.RRF3.r3,
13317 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
13318 case 0xb991: s390_format_RRF_M0RERE(s390_irgen_TRTO, ovl.fmt.RRF3.r3,
13319 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
13320 case 0xb992: s390_format_RRF_M0RERE(s390_irgen_TROT, ovl.fmt.RRF3.r3,
13321 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
florian9af37692012-01-15 21:01:16 +000013322 case 0xb993: s390_format_RRF_M0RERE(s390_irgen_TROO, ovl.fmt.RRF3.r3,
13323 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013324 case 0xb994: s390_format_RRE_RR(s390_irgen_LLCR, ovl.fmt.RRE.r1,
13325 ovl.fmt.RRE.r2); goto ok;
13326 case 0xb995: s390_format_RRE_RR(s390_irgen_LLHR, ovl.fmt.RRE.r1,
13327 ovl.fmt.RRE.r2); goto ok;
13328 case 0xb996: s390_format_RRE_RR(s390_irgen_MLR, ovl.fmt.RRE.r1,
13329 ovl.fmt.RRE.r2); goto ok;
13330 case 0xb997: s390_format_RRE_RR(s390_irgen_DLR, ovl.fmt.RRE.r1,
13331 ovl.fmt.RRE.r2); goto ok;
13332 case 0xb998: s390_format_RRE_RR(s390_irgen_ALCR, ovl.fmt.RRE.r1,
13333 ovl.fmt.RRE.r2); goto ok;
13334 case 0xb999: s390_format_RRE_RR(s390_irgen_SLBR, ovl.fmt.RRE.r1,
13335 ovl.fmt.RRE.r2); goto ok;
13336 case 0xb99a: /* EPAIR */ goto unimplemented;
13337 case 0xb99b: /* ESAIR */ goto unimplemented;
13338 case 0xb99d: /* ESEA */ goto unimplemented;
13339 case 0xb99e: /* PTI */ goto unimplemented;
13340 case 0xb99f: /* SSAIR */ goto unimplemented;
13341 case 0xb9a2: /* PTF */ goto unimplemented;
13342 case 0xb9aa: /* LPTEA */ goto unimplemented;
13343 case 0xb9ae: /* RRBM */ goto unimplemented;
13344 case 0xb9af: /* PFMF */ goto unimplemented;
florian3f8a96a2012-08-05 02:59:55 +000013345 case 0xb9b0: s390_format_RRF_M0RERE(s390_irgen_CU14, ovl.fmt.RRF3.r3,
13346 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
13347 goto ok;
florian2a415a12012-07-21 17:41:36 +000013348 case 0xb9b1: s390_format_RRF_M0RERE(s390_irgen_CU24, ovl.fmt.RRF3.r3,
13349 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
13350 goto ok;
florianaf2194f2012-08-06 00:07:54 +000013351 case 0xb9b2: s390_format_RRE_RR(s390_irgen_CU41, ovl.fmt.RRE.r1,
13352 ovl.fmt.RRE.r2); goto ok;
florian956194b2012-07-28 22:18:32 +000013353 case 0xb9b3: s390_format_RRE_RR(s390_irgen_CU42, ovl.fmt.RRE.r1,
13354 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013355 case 0xb9bd: /* TRTRE */ goto unimplemented;
13356 case 0xb9be: /* SRSTU */ goto unimplemented;
13357 case 0xb9bf: /* TRTE */ goto unimplemented;
13358 case 0xb9c8: s390_format_RRF_R0RR2(s390_irgen_AHHHR, ovl.fmt.RRF4.r3,
13359 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13360 goto ok;
13361 case 0xb9c9: s390_format_RRF_R0RR2(s390_irgen_SHHHR, ovl.fmt.RRF4.r3,
13362 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13363 goto ok;
13364 case 0xb9ca: s390_format_RRF_R0RR2(s390_irgen_ALHHHR, ovl.fmt.RRF4.r3,
13365 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13366 goto ok;
13367 case 0xb9cb: s390_format_RRF_R0RR2(s390_irgen_SLHHHR, ovl.fmt.RRF4.r3,
13368 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13369 goto ok;
13370 case 0xb9cd: s390_format_RRE_RR(s390_irgen_CHHR, ovl.fmt.RRE.r1,
13371 ovl.fmt.RRE.r2); goto ok;
13372 case 0xb9cf: s390_format_RRE_RR(s390_irgen_CLHHR, ovl.fmt.RRE.r1,
13373 ovl.fmt.RRE.r2); goto ok;
13374 case 0xb9d8: s390_format_RRF_R0RR2(s390_irgen_AHHLR, ovl.fmt.RRF4.r3,
13375 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13376 goto ok;
13377 case 0xb9d9: s390_format_RRF_R0RR2(s390_irgen_SHHLR, ovl.fmt.RRF4.r3,
13378 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13379 goto ok;
13380 case 0xb9da: s390_format_RRF_R0RR2(s390_irgen_ALHHLR, ovl.fmt.RRF4.r3,
13381 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13382 goto ok;
13383 case 0xb9db: s390_format_RRF_R0RR2(s390_irgen_SLHHLR, ovl.fmt.RRF4.r3,
13384 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13385 goto ok;
13386 case 0xb9dd: s390_format_RRE_RR(s390_irgen_CHLR, ovl.fmt.RRE.r1,
13387 ovl.fmt.RRE.r2); goto ok;
13388 case 0xb9df: s390_format_RRE_RR(s390_irgen_CLHLR, ovl.fmt.RRE.r1,
13389 ovl.fmt.RRE.r2); goto ok;
13390 case 0xb9e1: /* POPCNT */ goto unimplemented;
sewardjd7bde722011-04-05 13:19:33 +000013391 case 0xb9e2: s390_format_RRF_U0RR(s390_irgen_LOCGR, ovl.fmt.RRF3.r3,
13392 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2,
13393 S390_XMNM_LOCGR); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013394 case 0xb9e4: s390_format_RRF_R0RR2(s390_irgen_NGRK, ovl.fmt.RRF4.r3,
13395 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13396 goto ok;
13397 case 0xb9e6: s390_format_RRF_R0RR2(s390_irgen_OGRK, ovl.fmt.RRF4.r3,
13398 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13399 goto ok;
13400 case 0xb9e7: s390_format_RRF_R0RR2(s390_irgen_XGRK, ovl.fmt.RRF4.r3,
13401 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13402 goto ok;
13403 case 0xb9e8: s390_format_RRF_R0RR2(s390_irgen_AGRK, ovl.fmt.RRF4.r3,
13404 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13405 goto ok;
13406 case 0xb9e9: s390_format_RRF_R0RR2(s390_irgen_SGRK, ovl.fmt.RRF4.r3,
13407 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13408 goto ok;
13409 case 0xb9ea: s390_format_RRF_R0RR2(s390_irgen_ALGRK, ovl.fmt.RRF4.r3,
13410 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13411 goto ok;
13412 case 0xb9eb: s390_format_RRF_R0RR2(s390_irgen_SLGRK, ovl.fmt.RRF4.r3,
13413 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13414 goto ok;
sewardjd7bde722011-04-05 13:19:33 +000013415 case 0xb9f2: s390_format_RRF_U0RR(s390_irgen_LOCR, ovl.fmt.RRF3.r3,
13416 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2,
13417 S390_XMNM_LOCR); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013418 case 0xb9f4: s390_format_RRF_R0RR2(s390_irgen_NRK, ovl.fmt.RRF4.r3,
13419 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13420 goto ok;
13421 case 0xb9f6: s390_format_RRF_R0RR2(s390_irgen_ORK, ovl.fmt.RRF4.r3,
13422 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13423 goto ok;
13424 case 0xb9f7: s390_format_RRF_R0RR2(s390_irgen_XRK, ovl.fmt.RRF4.r3,
13425 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13426 goto ok;
13427 case 0xb9f8: s390_format_RRF_R0RR2(s390_irgen_ARK, ovl.fmt.RRF4.r3,
13428 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13429 goto ok;
13430 case 0xb9f9: s390_format_RRF_R0RR2(s390_irgen_SRK, ovl.fmt.RRF4.r3,
13431 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13432 goto ok;
13433 case 0xb9fa: s390_format_RRF_R0RR2(s390_irgen_ALRK, ovl.fmt.RRF4.r3,
13434 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13435 goto ok;
13436 case 0xb9fb: s390_format_RRF_R0RR2(s390_irgen_SLRK, ovl.fmt.RRF4.r3,
13437 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13438 goto ok;
13439 }
13440
13441 switch ((ovl.value & 0xff000000) >> 24) {
13442 case 0x40: s390_format_RX_RRRD(s390_irgen_STH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13443 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13444 case 0x41: s390_format_RX_RRRD(s390_irgen_LA, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13445 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13446 case 0x42: s390_format_RX_RRRD(s390_irgen_STC, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13447 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13448 case 0x43: s390_format_RX_RRRD(s390_irgen_IC, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13449 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13450 case 0x44: s390_format_RX_RRRD(s390_irgen_EX, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13451 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13452 case 0x45: /* BAL */ goto unimplemented;
13453 case 0x46: s390_format_RX_RRRD(s390_irgen_BCT, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13454 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13455 case 0x47: s390_format_RX(s390_irgen_BC, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13456 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13457 case 0x48: s390_format_RX_RRRD(s390_irgen_LH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13458 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13459 case 0x49: s390_format_RX_RRRD(s390_irgen_CH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13460 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13461 case 0x4a: s390_format_RX_RRRD(s390_irgen_AH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13462 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13463 case 0x4b: s390_format_RX_RRRD(s390_irgen_SH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13464 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13465 case 0x4c: s390_format_RX_RRRD(s390_irgen_MH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13466 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13467 case 0x4d: s390_format_RX_RRRD(s390_irgen_BAS, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13468 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13469 case 0x4e: s390_format_RX_RRRD(s390_irgen_CVD, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13470 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13471 case 0x4f: s390_format_RX_RRRD(s390_irgen_CVB, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13472 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13473 case 0x50: s390_format_RX_RRRD(s390_irgen_ST, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13474 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13475 case 0x51: s390_format_RX_RRRD(s390_irgen_LAE, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13476 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13477 case 0x54: s390_format_RX_RRRD(s390_irgen_N, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13478 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13479 case 0x55: s390_format_RX_RRRD(s390_irgen_CL, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13480 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13481 case 0x56: s390_format_RX_RRRD(s390_irgen_O, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13482 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13483 case 0x57: s390_format_RX_RRRD(s390_irgen_X, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13484 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13485 case 0x58: s390_format_RX_RRRD(s390_irgen_L, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13486 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13487 case 0x59: s390_format_RX_RRRD(s390_irgen_C, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13488 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13489 case 0x5a: s390_format_RX_RRRD(s390_irgen_A, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13490 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13491 case 0x5b: s390_format_RX_RRRD(s390_irgen_S, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13492 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13493 case 0x5c: s390_format_RX_RRRD(s390_irgen_M, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13494 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13495 case 0x5d: s390_format_RX_RRRD(s390_irgen_D, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13496 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13497 case 0x5e: s390_format_RX_RRRD(s390_irgen_AL, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13498 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13499 case 0x5f: s390_format_RX_RRRD(s390_irgen_SL, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13500 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13501 case 0x60: s390_format_RX_FRRD(s390_irgen_STD, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13502 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13503 case 0x67: /* MXD */ goto unimplemented;
13504 case 0x68: s390_format_RX_FRRD(s390_irgen_LD, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13505 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13506 case 0x69: /* CD */ goto unimplemented;
13507 case 0x6a: /* AD */ goto unimplemented;
13508 case 0x6b: /* SD */ goto unimplemented;
13509 case 0x6c: /* MD */ goto unimplemented;
13510 case 0x6d: /* DD */ goto unimplemented;
13511 case 0x6e: /* AW */ goto unimplemented;
13512 case 0x6f: /* SW */ goto unimplemented;
13513 case 0x70: s390_format_RX_FRRD(s390_irgen_STE, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13514 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13515 case 0x71: s390_format_RX_RRRD(s390_irgen_MS, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13516 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13517 case 0x78: s390_format_RX_FRRD(s390_irgen_LE, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13518 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13519 case 0x79: /* CE */ goto unimplemented;
13520 case 0x7a: /* AE */ goto unimplemented;
13521 case 0x7b: /* SE */ goto unimplemented;
13522 case 0x7c: /* MDE */ goto unimplemented;
13523 case 0x7d: /* DE */ goto unimplemented;
13524 case 0x7e: /* AU */ goto unimplemented;
13525 case 0x7f: /* SU */ goto unimplemented;
13526 case 0x83: /* DIAG */ goto unimplemented;
13527 case 0x84: s390_format_RSI_RRP(s390_irgen_BRXH, ovl.fmt.RSI.r1,
13528 ovl.fmt.RSI.r3, ovl.fmt.RSI.i2); goto ok;
13529 case 0x85: s390_format_RSI_RRP(s390_irgen_BRXLE, ovl.fmt.RSI.r1,
13530 ovl.fmt.RSI.r3, ovl.fmt.RSI.i2); goto ok;
13531 case 0x86: s390_format_RS_RRRD(s390_irgen_BXH, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13532 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13533 case 0x87: s390_format_RS_RRRD(s390_irgen_BXLE, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13534 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13535 case 0x88: s390_format_RS_R0RD(s390_irgen_SRL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
13536 ovl.fmt.RS.d2); goto ok;
13537 case 0x89: s390_format_RS_R0RD(s390_irgen_SLL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
13538 ovl.fmt.RS.d2); goto ok;
13539 case 0x8a: s390_format_RS_R0RD(s390_irgen_SRA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
13540 ovl.fmt.RS.d2); goto ok;
13541 case 0x8b: s390_format_RS_R0RD(s390_irgen_SLA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
13542 ovl.fmt.RS.d2); goto ok;
13543 case 0x8c: s390_format_RS_R0RD(s390_irgen_SRDL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
13544 ovl.fmt.RS.d2); goto ok;
13545 case 0x8d: s390_format_RS_R0RD(s390_irgen_SLDL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
13546 ovl.fmt.RS.d2); goto ok;
13547 case 0x8e: s390_format_RS_R0RD(s390_irgen_SRDA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
13548 ovl.fmt.RS.d2); goto ok;
13549 case 0x8f: s390_format_RS_R0RD(s390_irgen_SLDA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
13550 ovl.fmt.RS.d2); goto ok;
13551 case 0x90: s390_format_RS_RRRD(s390_irgen_STM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13552 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13553 case 0x91: s390_format_SI_URD(s390_irgen_TM, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
13554 ovl.fmt.SI.d1); goto ok;
13555 case 0x92: s390_format_SI_URD(s390_irgen_MVI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
13556 ovl.fmt.SI.d1); goto ok;
13557 case 0x94: s390_format_SI_URD(s390_irgen_NI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
13558 ovl.fmt.SI.d1); goto ok;
13559 case 0x95: s390_format_SI_URD(s390_irgen_CLI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
13560 ovl.fmt.SI.d1); goto ok;
13561 case 0x96: s390_format_SI_URD(s390_irgen_OI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
13562 ovl.fmt.SI.d1); goto ok;
13563 case 0x97: s390_format_SI_URD(s390_irgen_XI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
13564 ovl.fmt.SI.d1); goto ok;
13565 case 0x98: s390_format_RS_RRRD(s390_irgen_LM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13566 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13567 case 0x99: /* TRACE */ goto unimplemented;
13568 case 0x9a: s390_format_RS_AARD(s390_irgen_LAM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13569 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13570 case 0x9b: s390_format_RS_AARD(s390_irgen_STAM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13571 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13572 case 0xa8: s390_format_RS_RRRD(s390_irgen_MVCLE, ovl.fmt.RS.r1,
13573 ovl.fmt.RS.r3, ovl.fmt.RS.b2, ovl.fmt.RS.d2);
13574 goto ok;
13575 case 0xa9: s390_format_RS_RRRD(s390_irgen_CLCLE, ovl.fmt.RS.r1,
13576 ovl.fmt.RS.r3, ovl.fmt.RS.b2, ovl.fmt.RS.d2);
13577 goto ok;
13578 case 0xac: /* STNSM */ goto unimplemented;
13579 case 0xad: /* STOSM */ goto unimplemented;
13580 case 0xae: /* SIGP */ goto unimplemented;
13581 case 0xaf: /* MC */ goto unimplemented;
13582 case 0xb1: /* LRA */ goto unimplemented;
13583 case 0xb6: /* STCTL */ goto unimplemented;
13584 case 0xb7: /* LCTL */ goto unimplemented;
13585 case 0xba: s390_format_RS_RRRD(s390_irgen_CS, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13586 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
florian448cbba2012-06-06 02:26:01 +000013587 case 0xbb: s390_format_RS_RRRD(s390_irgen_CDS, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13588 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013589 case 0xbd: s390_format_RS_RURD(s390_irgen_CLM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13590 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13591 case 0xbe: s390_format_RS_RURD(s390_irgen_STCM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13592 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13593 case 0xbf: s390_format_RS_RURD(s390_irgen_ICM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13594 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13595 }
13596
13597 return S390_DECODE_UNKNOWN_INSN;
13598
13599ok:
13600 return S390_DECODE_OK;
13601
13602unimplemented:
13603 return S390_DECODE_UNIMPLEMENTED_INSN;
13604}
13605
13606static s390_decode_t
13607s390_decode_6byte_and_irgen(UChar *bytes)
13608{
13609 typedef union {
13610 struct {
13611 unsigned int op1 : 8;
13612 unsigned int r1 : 4;
13613 unsigned int r3 : 4;
13614 unsigned int i2 : 16;
13615 unsigned int : 8;
13616 unsigned int op2 : 8;
13617 } RIE;
13618 struct {
13619 unsigned int op1 : 8;
13620 unsigned int r1 : 4;
13621 unsigned int r2 : 4;
13622 unsigned int i3 : 8;
13623 unsigned int i4 : 8;
13624 unsigned int i5 : 8;
13625 unsigned int op2 : 8;
13626 } RIE_RRUUU;
13627 struct {
13628 unsigned int op1 : 8;
13629 unsigned int r1 : 4;
13630 unsigned int : 4;
13631 unsigned int i2 : 16;
13632 unsigned int m3 : 4;
13633 unsigned int : 4;
13634 unsigned int op2 : 8;
13635 } RIEv1;
13636 struct {
13637 unsigned int op1 : 8;
13638 unsigned int r1 : 4;
13639 unsigned int r2 : 4;
13640 unsigned int i4 : 16;
13641 unsigned int m3 : 4;
13642 unsigned int : 4;
13643 unsigned int op2 : 8;
13644 } RIE_RRPU;
13645 struct {
13646 unsigned int op1 : 8;
13647 unsigned int r1 : 4;
13648 unsigned int m3 : 4;
13649 unsigned int i4 : 16;
13650 unsigned int i2 : 8;
13651 unsigned int op2 : 8;
13652 } RIEv3;
13653 struct {
13654 unsigned int op1 : 8;
13655 unsigned int r1 : 4;
13656 unsigned int op2 : 4;
13657 unsigned int i2 : 32;
13658 } RIL;
13659 struct {
13660 unsigned int op1 : 8;
13661 unsigned int r1 : 4;
13662 unsigned int m3 : 4;
13663 unsigned int b4 : 4;
13664 unsigned int d4 : 12;
13665 unsigned int i2 : 8;
13666 unsigned int op2 : 8;
13667 } RIS;
13668 struct {
13669 unsigned int op1 : 8;
13670 unsigned int r1 : 4;
13671 unsigned int r2 : 4;
13672 unsigned int b4 : 4;
13673 unsigned int d4 : 12;
13674 unsigned int m3 : 4;
13675 unsigned int : 4;
13676 unsigned int op2 : 8;
13677 } RRS;
13678 struct {
13679 unsigned int op1 : 8;
13680 unsigned int l1 : 4;
13681 unsigned int : 4;
13682 unsigned int b1 : 4;
13683 unsigned int d1 : 12;
13684 unsigned int : 8;
13685 unsigned int op2 : 8;
13686 } RSL;
13687 struct {
13688 unsigned int op1 : 8;
13689 unsigned int r1 : 4;
13690 unsigned int r3 : 4;
13691 unsigned int b2 : 4;
13692 unsigned int dl2 : 12;
13693 unsigned int dh2 : 8;
13694 unsigned int op2 : 8;
13695 } RSY;
13696 struct {
13697 unsigned int op1 : 8;
13698 unsigned int r1 : 4;
13699 unsigned int x2 : 4;
13700 unsigned int b2 : 4;
13701 unsigned int d2 : 12;
13702 unsigned int : 8;
13703 unsigned int op2 : 8;
13704 } RXE;
13705 struct {
13706 unsigned int op1 : 8;
13707 unsigned int r3 : 4;
13708 unsigned int x2 : 4;
13709 unsigned int b2 : 4;
13710 unsigned int d2 : 12;
13711 unsigned int r1 : 4;
13712 unsigned int : 4;
13713 unsigned int op2 : 8;
13714 } RXF;
13715 struct {
13716 unsigned int op1 : 8;
13717 unsigned int r1 : 4;
13718 unsigned int x2 : 4;
13719 unsigned int b2 : 4;
13720 unsigned int dl2 : 12;
13721 unsigned int dh2 : 8;
13722 unsigned int op2 : 8;
13723 } RXY;
13724 struct {
13725 unsigned int op1 : 8;
13726 unsigned int i2 : 8;
13727 unsigned int b1 : 4;
13728 unsigned int dl1 : 12;
13729 unsigned int dh1 : 8;
13730 unsigned int op2 : 8;
13731 } SIY;
13732 struct {
13733 unsigned int op : 8;
13734 unsigned int l : 8;
13735 unsigned int b1 : 4;
13736 unsigned int d1 : 12;
13737 unsigned int b2 : 4;
13738 unsigned int d2 : 12;
13739 } SS;
13740 struct {
13741 unsigned int op : 8;
13742 unsigned int l1 : 4;
13743 unsigned int l2 : 4;
13744 unsigned int b1 : 4;
13745 unsigned int d1 : 12;
13746 unsigned int b2 : 4;
13747 unsigned int d2 : 12;
13748 } SS_LLRDRD;
13749 struct {
13750 unsigned int op : 8;
13751 unsigned int r1 : 4;
13752 unsigned int r3 : 4;
13753 unsigned int b2 : 4;
13754 unsigned int d2 : 12;
13755 unsigned int b4 : 4;
13756 unsigned int d4 : 12;
13757 } SS_RRRDRD2;
13758 struct {
13759 unsigned int op : 16;
13760 unsigned int b1 : 4;
13761 unsigned int d1 : 12;
13762 unsigned int b2 : 4;
13763 unsigned int d2 : 12;
13764 } SSE;
13765 struct {
13766 unsigned int op1 : 8;
13767 unsigned int r3 : 4;
13768 unsigned int op2 : 4;
13769 unsigned int b1 : 4;
13770 unsigned int d1 : 12;
13771 unsigned int b2 : 4;
13772 unsigned int d2 : 12;
13773 } SSF;
13774 struct {
13775 unsigned int op : 16;
13776 unsigned int b1 : 4;
13777 unsigned int d1 : 12;
13778 unsigned int i2 : 16;
13779 } SIL;
13780 } formats;
13781 union {
13782 formats fmt;
13783 ULong value;
13784 } ovl;
13785
13786 vassert(sizeof(formats) == 6);
13787
13788 ((char *)(&ovl.value))[0] = bytes[0];
13789 ((char *)(&ovl.value))[1] = bytes[1];
13790 ((char *)(&ovl.value))[2] = bytes[2];
13791 ((char *)(&ovl.value))[3] = bytes[3];
13792 ((char *)(&ovl.value))[4] = bytes[4];
13793 ((char *)(&ovl.value))[5] = bytes[5];
13794 ((char *)(&ovl.value))[6] = 0x0;
13795 ((char *)(&ovl.value))[7] = 0x0;
13796
13797 switch ((ovl.value >> 16) & 0xff00000000ffULL) {
13798 case 0xe30000000002ULL: s390_format_RXY_RRRD(s390_irgen_LTG, ovl.fmt.RXY.r1,
13799 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13800 ovl.fmt.RXY.dl2,
13801 ovl.fmt.RXY.dh2); goto ok;
13802 case 0xe30000000003ULL: /* LRAG */ goto unimplemented;
13803 case 0xe30000000004ULL: s390_format_RXY_RRRD(s390_irgen_LG, ovl.fmt.RXY.r1,
13804 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13805 ovl.fmt.RXY.dl2,
13806 ovl.fmt.RXY.dh2); goto ok;
13807 case 0xe30000000006ULL: s390_format_RXY_RRRD(s390_irgen_CVBY, ovl.fmt.RXY.r1,
13808 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13809 ovl.fmt.RXY.dl2,
13810 ovl.fmt.RXY.dh2); goto ok;
13811 case 0xe30000000008ULL: s390_format_RXY_RRRD(s390_irgen_AG, ovl.fmt.RXY.r1,
13812 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13813 ovl.fmt.RXY.dl2,
13814 ovl.fmt.RXY.dh2); goto ok;
13815 case 0xe30000000009ULL: s390_format_RXY_RRRD(s390_irgen_SG, ovl.fmt.RXY.r1,
13816 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13817 ovl.fmt.RXY.dl2,
13818 ovl.fmt.RXY.dh2); goto ok;
13819 case 0xe3000000000aULL: s390_format_RXY_RRRD(s390_irgen_ALG, ovl.fmt.RXY.r1,
13820 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13821 ovl.fmt.RXY.dl2,
13822 ovl.fmt.RXY.dh2); goto ok;
13823 case 0xe3000000000bULL: s390_format_RXY_RRRD(s390_irgen_SLG, ovl.fmt.RXY.r1,
13824 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13825 ovl.fmt.RXY.dl2,
13826 ovl.fmt.RXY.dh2); goto ok;
13827 case 0xe3000000000cULL: s390_format_RXY_RRRD(s390_irgen_MSG, ovl.fmt.RXY.r1,
13828 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13829 ovl.fmt.RXY.dl2,
13830 ovl.fmt.RXY.dh2); goto ok;
13831 case 0xe3000000000dULL: s390_format_RXY_RRRD(s390_irgen_DSG, ovl.fmt.RXY.r1,
13832 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13833 ovl.fmt.RXY.dl2,
13834 ovl.fmt.RXY.dh2); goto ok;
13835 case 0xe3000000000eULL: /* CVBG */ goto unimplemented;
13836 case 0xe3000000000fULL: s390_format_RXY_RRRD(s390_irgen_LRVG, ovl.fmt.RXY.r1,
13837 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13838 ovl.fmt.RXY.dl2,
13839 ovl.fmt.RXY.dh2); goto ok;
13840 case 0xe30000000012ULL: s390_format_RXY_RRRD(s390_irgen_LT, ovl.fmt.RXY.r1,
13841 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13842 ovl.fmt.RXY.dl2,
13843 ovl.fmt.RXY.dh2); goto ok;
13844 case 0xe30000000013ULL: /* LRAY */ goto unimplemented;
13845 case 0xe30000000014ULL: s390_format_RXY_RRRD(s390_irgen_LGF, ovl.fmt.RXY.r1,
13846 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13847 ovl.fmt.RXY.dl2,
13848 ovl.fmt.RXY.dh2); goto ok;
13849 case 0xe30000000015ULL: s390_format_RXY_RRRD(s390_irgen_LGH, ovl.fmt.RXY.r1,
13850 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13851 ovl.fmt.RXY.dl2,
13852 ovl.fmt.RXY.dh2); goto ok;
13853 case 0xe30000000016ULL: s390_format_RXY_RRRD(s390_irgen_LLGF, 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 0xe30000000017ULL: s390_format_RXY_RRRD(s390_irgen_LLGT, 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 0xe30000000018ULL: s390_format_RXY_RRRD(s390_irgen_AGF, 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 0xe30000000019ULL: s390_format_RXY_RRRD(s390_irgen_SGF, 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 case 0xe3000000001aULL: s390_format_RXY_RRRD(s390_irgen_ALGF, ovl.fmt.RXY.r1,
13870 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13871 ovl.fmt.RXY.dl2,
13872 ovl.fmt.RXY.dh2); goto ok;
13873 case 0xe3000000001bULL: s390_format_RXY_RRRD(s390_irgen_SLGF, ovl.fmt.RXY.r1,
13874 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13875 ovl.fmt.RXY.dl2,
13876 ovl.fmt.RXY.dh2); goto ok;
13877 case 0xe3000000001cULL: s390_format_RXY_RRRD(s390_irgen_MSGF, ovl.fmt.RXY.r1,
13878 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13879 ovl.fmt.RXY.dl2,
13880 ovl.fmt.RXY.dh2); goto ok;
13881 case 0xe3000000001dULL: s390_format_RXY_RRRD(s390_irgen_DSGF, ovl.fmt.RXY.r1,
13882 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13883 ovl.fmt.RXY.dl2,
13884 ovl.fmt.RXY.dh2); goto ok;
13885 case 0xe3000000001eULL: s390_format_RXY_RRRD(s390_irgen_LRV, ovl.fmt.RXY.r1,
13886 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13887 ovl.fmt.RXY.dl2,
13888 ovl.fmt.RXY.dh2); goto ok;
13889 case 0xe3000000001fULL: s390_format_RXY_RRRD(s390_irgen_LRVH, ovl.fmt.RXY.r1,
13890 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13891 ovl.fmt.RXY.dl2,
13892 ovl.fmt.RXY.dh2); goto ok;
13893 case 0xe30000000020ULL: s390_format_RXY_RRRD(s390_irgen_CG, ovl.fmt.RXY.r1,
13894 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13895 ovl.fmt.RXY.dl2,
13896 ovl.fmt.RXY.dh2); goto ok;
13897 case 0xe30000000021ULL: s390_format_RXY_RRRD(s390_irgen_CLG, ovl.fmt.RXY.r1,
13898 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13899 ovl.fmt.RXY.dl2,
13900 ovl.fmt.RXY.dh2); goto ok;
13901 case 0xe30000000024ULL: s390_format_RXY_RRRD(s390_irgen_STG, ovl.fmt.RXY.r1,
13902 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13903 ovl.fmt.RXY.dl2,
13904 ovl.fmt.RXY.dh2); goto ok;
13905 case 0xe30000000026ULL: s390_format_RXY_RRRD(s390_irgen_CVDY, ovl.fmt.RXY.r1,
13906 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13907 ovl.fmt.RXY.dl2,
13908 ovl.fmt.RXY.dh2); goto ok;
13909 case 0xe3000000002eULL: /* CVDG */ goto unimplemented;
13910 case 0xe3000000002fULL: s390_format_RXY_RRRD(s390_irgen_STRVG,
13911 ovl.fmt.RXY.r1, ovl.fmt.RXY.x2,
13912 ovl.fmt.RXY.b2, ovl.fmt.RXY.dl2,
13913 ovl.fmt.RXY.dh2); goto ok;
13914 case 0xe30000000030ULL: s390_format_RXY_RRRD(s390_irgen_CGF, ovl.fmt.RXY.r1,
13915 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13916 ovl.fmt.RXY.dl2,
13917 ovl.fmt.RXY.dh2); goto ok;
13918 case 0xe30000000031ULL: s390_format_RXY_RRRD(s390_irgen_CLGF, ovl.fmt.RXY.r1,
13919 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13920 ovl.fmt.RXY.dl2,
13921 ovl.fmt.RXY.dh2); goto ok;
13922 case 0xe30000000032ULL: s390_format_RXY_RRRD(s390_irgen_LTGF, ovl.fmt.RXY.r1,
13923 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13924 ovl.fmt.RXY.dl2,
13925 ovl.fmt.RXY.dh2); goto ok;
13926 case 0xe30000000034ULL: s390_format_RXY_RRRD(s390_irgen_CGH, ovl.fmt.RXY.r1,
13927 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13928 ovl.fmt.RXY.dl2,
13929 ovl.fmt.RXY.dh2); goto ok;
13930 case 0xe30000000036ULL: s390_format_RXY_URRD(s390_irgen_PFD, ovl.fmt.RXY.r1,
13931 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13932 ovl.fmt.RXY.dl2,
13933 ovl.fmt.RXY.dh2); goto ok;
13934 case 0xe3000000003eULL: s390_format_RXY_RRRD(s390_irgen_STRV, ovl.fmt.RXY.r1,
13935 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13936 ovl.fmt.RXY.dl2,
13937 ovl.fmt.RXY.dh2); goto ok;
13938 case 0xe3000000003fULL: s390_format_RXY_RRRD(s390_irgen_STRVH,
13939 ovl.fmt.RXY.r1, ovl.fmt.RXY.x2,
13940 ovl.fmt.RXY.b2, ovl.fmt.RXY.dl2,
13941 ovl.fmt.RXY.dh2); goto ok;
13942 case 0xe30000000046ULL: s390_format_RXY_RRRD(s390_irgen_BCTG, ovl.fmt.RXY.r1,
13943 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13944 ovl.fmt.RXY.dl2,
13945 ovl.fmt.RXY.dh2); goto ok;
13946 case 0xe30000000050ULL: s390_format_RXY_RRRD(s390_irgen_STY, ovl.fmt.RXY.r1,
13947 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13948 ovl.fmt.RXY.dl2,
13949 ovl.fmt.RXY.dh2); goto ok;
13950 case 0xe30000000051ULL: s390_format_RXY_RRRD(s390_irgen_MSY, ovl.fmt.RXY.r1,
13951 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13952 ovl.fmt.RXY.dl2,
13953 ovl.fmt.RXY.dh2); goto ok;
13954 case 0xe30000000054ULL: s390_format_RXY_RRRD(s390_irgen_NY, ovl.fmt.RXY.r1,
13955 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13956 ovl.fmt.RXY.dl2,
13957 ovl.fmt.RXY.dh2); goto ok;
13958 case 0xe30000000055ULL: s390_format_RXY_RRRD(s390_irgen_CLY, ovl.fmt.RXY.r1,
13959 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13960 ovl.fmt.RXY.dl2,
13961 ovl.fmt.RXY.dh2); goto ok;
13962 case 0xe30000000056ULL: s390_format_RXY_RRRD(s390_irgen_OY, ovl.fmt.RXY.r1,
13963 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13964 ovl.fmt.RXY.dl2,
13965 ovl.fmt.RXY.dh2); goto ok;
13966 case 0xe30000000057ULL: s390_format_RXY_RRRD(s390_irgen_XY, ovl.fmt.RXY.r1,
13967 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13968 ovl.fmt.RXY.dl2,
13969 ovl.fmt.RXY.dh2); goto ok;
13970 case 0xe30000000058ULL: s390_format_RXY_RRRD(s390_irgen_LY, ovl.fmt.RXY.r1,
13971 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13972 ovl.fmt.RXY.dl2,
13973 ovl.fmt.RXY.dh2); goto ok;
13974 case 0xe30000000059ULL: s390_format_RXY_RRRD(s390_irgen_CY, ovl.fmt.RXY.r1,
13975 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13976 ovl.fmt.RXY.dl2,
13977 ovl.fmt.RXY.dh2); goto ok;
13978 case 0xe3000000005aULL: s390_format_RXY_RRRD(s390_irgen_AY, ovl.fmt.RXY.r1,
13979 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13980 ovl.fmt.RXY.dl2,
13981 ovl.fmt.RXY.dh2); goto ok;
13982 case 0xe3000000005bULL: s390_format_RXY_RRRD(s390_irgen_SY, ovl.fmt.RXY.r1,
13983 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13984 ovl.fmt.RXY.dl2,
13985 ovl.fmt.RXY.dh2); goto ok;
13986 case 0xe3000000005cULL: s390_format_RXY_RRRD(s390_irgen_MFY, ovl.fmt.RXY.r1,
13987 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13988 ovl.fmt.RXY.dl2,
13989 ovl.fmt.RXY.dh2); goto ok;
13990 case 0xe3000000005eULL: s390_format_RXY_RRRD(s390_irgen_ALY, ovl.fmt.RXY.r1,
13991 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13992 ovl.fmt.RXY.dl2,
13993 ovl.fmt.RXY.dh2); goto ok;
13994 case 0xe3000000005fULL: s390_format_RXY_RRRD(s390_irgen_SLY, ovl.fmt.RXY.r1,
13995 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13996 ovl.fmt.RXY.dl2,
13997 ovl.fmt.RXY.dh2); goto ok;
13998 case 0xe30000000070ULL: s390_format_RXY_RRRD(s390_irgen_STHY, ovl.fmt.RXY.r1,
13999 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14000 ovl.fmt.RXY.dl2,
14001 ovl.fmt.RXY.dh2); goto ok;
14002 case 0xe30000000071ULL: s390_format_RXY_RRRD(s390_irgen_LAY, ovl.fmt.RXY.r1,
14003 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14004 ovl.fmt.RXY.dl2,
14005 ovl.fmt.RXY.dh2); goto ok;
14006 case 0xe30000000072ULL: s390_format_RXY_RRRD(s390_irgen_STCY, ovl.fmt.RXY.r1,
14007 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14008 ovl.fmt.RXY.dl2,
14009 ovl.fmt.RXY.dh2); goto ok;
14010 case 0xe30000000073ULL: s390_format_RXY_RRRD(s390_irgen_ICY, ovl.fmt.RXY.r1,
14011 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14012 ovl.fmt.RXY.dl2,
14013 ovl.fmt.RXY.dh2); goto ok;
14014 case 0xe30000000075ULL: s390_format_RXY_RRRD(s390_irgen_LAEY, ovl.fmt.RXY.r1,
14015 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14016 ovl.fmt.RXY.dl2,
14017 ovl.fmt.RXY.dh2); goto ok;
14018 case 0xe30000000076ULL: s390_format_RXY_RRRD(s390_irgen_LB, ovl.fmt.RXY.r1,
14019 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14020 ovl.fmt.RXY.dl2,
14021 ovl.fmt.RXY.dh2); goto ok;
14022 case 0xe30000000077ULL: s390_format_RXY_RRRD(s390_irgen_LGB, ovl.fmt.RXY.r1,
14023 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14024 ovl.fmt.RXY.dl2,
14025 ovl.fmt.RXY.dh2); goto ok;
14026 case 0xe30000000078ULL: s390_format_RXY_RRRD(s390_irgen_LHY, ovl.fmt.RXY.r1,
14027 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14028 ovl.fmt.RXY.dl2,
14029 ovl.fmt.RXY.dh2); goto ok;
14030 case 0xe30000000079ULL: s390_format_RXY_RRRD(s390_irgen_CHY, ovl.fmt.RXY.r1,
14031 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14032 ovl.fmt.RXY.dl2,
14033 ovl.fmt.RXY.dh2); goto ok;
14034 case 0xe3000000007aULL: s390_format_RXY_RRRD(s390_irgen_AHY, ovl.fmt.RXY.r1,
14035 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14036 ovl.fmt.RXY.dl2,
14037 ovl.fmt.RXY.dh2); goto ok;
14038 case 0xe3000000007bULL: s390_format_RXY_RRRD(s390_irgen_SHY, ovl.fmt.RXY.r1,
14039 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14040 ovl.fmt.RXY.dl2,
14041 ovl.fmt.RXY.dh2); goto ok;
14042 case 0xe3000000007cULL: s390_format_RXY_RRRD(s390_irgen_MHY, ovl.fmt.RXY.r1,
14043 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14044 ovl.fmt.RXY.dl2,
14045 ovl.fmt.RXY.dh2); goto ok;
14046 case 0xe30000000080ULL: s390_format_RXY_RRRD(s390_irgen_NG, ovl.fmt.RXY.r1,
14047 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14048 ovl.fmt.RXY.dl2,
14049 ovl.fmt.RXY.dh2); goto ok;
14050 case 0xe30000000081ULL: s390_format_RXY_RRRD(s390_irgen_OG, ovl.fmt.RXY.r1,
14051 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14052 ovl.fmt.RXY.dl2,
14053 ovl.fmt.RXY.dh2); goto ok;
14054 case 0xe30000000082ULL: s390_format_RXY_RRRD(s390_irgen_XG, ovl.fmt.RXY.r1,
14055 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14056 ovl.fmt.RXY.dl2,
14057 ovl.fmt.RXY.dh2); goto ok;
14058 case 0xe30000000086ULL: s390_format_RXY_RRRD(s390_irgen_MLG, ovl.fmt.RXY.r1,
14059 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14060 ovl.fmt.RXY.dl2,
14061 ovl.fmt.RXY.dh2); goto ok;
14062 case 0xe30000000087ULL: s390_format_RXY_RRRD(s390_irgen_DLG, ovl.fmt.RXY.r1,
14063 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14064 ovl.fmt.RXY.dl2,
14065 ovl.fmt.RXY.dh2); goto ok;
14066 case 0xe30000000088ULL: s390_format_RXY_RRRD(s390_irgen_ALCG, ovl.fmt.RXY.r1,
14067 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14068 ovl.fmt.RXY.dl2,
14069 ovl.fmt.RXY.dh2); goto ok;
14070 case 0xe30000000089ULL: s390_format_RXY_RRRD(s390_irgen_SLBG, ovl.fmt.RXY.r1,
14071 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14072 ovl.fmt.RXY.dl2,
14073 ovl.fmt.RXY.dh2); goto ok;
14074 case 0xe3000000008eULL: s390_format_RXY_RRRD(s390_irgen_STPQ, ovl.fmt.RXY.r1,
14075 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14076 ovl.fmt.RXY.dl2,
14077 ovl.fmt.RXY.dh2); goto ok;
14078 case 0xe3000000008fULL: s390_format_RXY_RRRD(s390_irgen_LPQ, ovl.fmt.RXY.r1,
14079 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14080 ovl.fmt.RXY.dl2,
14081 ovl.fmt.RXY.dh2); goto ok;
14082 case 0xe30000000090ULL: s390_format_RXY_RRRD(s390_irgen_LLGC, ovl.fmt.RXY.r1,
14083 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14084 ovl.fmt.RXY.dl2,
14085 ovl.fmt.RXY.dh2); goto ok;
14086 case 0xe30000000091ULL: s390_format_RXY_RRRD(s390_irgen_LLGH, ovl.fmt.RXY.r1,
14087 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14088 ovl.fmt.RXY.dl2,
14089 ovl.fmt.RXY.dh2); goto ok;
14090 case 0xe30000000094ULL: s390_format_RXY_RRRD(s390_irgen_LLC, ovl.fmt.RXY.r1,
14091 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14092 ovl.fmt.RXY.dl2,
14093 ovl.fmt.RXY.dh2); goto ok;
14094 case 0xe30000000095ULL: s390_format_RXY_RRRD(s390_irgen_LLH, ovl.fmt.RXY.r1,
14095 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14096 ovl.fmt.RXY.dl2,
14097 ovl.fmt.RXY.dh2); goto ok;
14098 case 0xe30000000096ULL: s390_format_RXY_RRRD(s390_irgen_ML, ovl.fmt.RXY.r1,
14099 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14100 ovl.fmt.RXY.dl2,
14101 ovl.fmt.RXY.dh2); goto ok;
14102 case 0xe30000000097ULL: s390_format_RXY_RRRD(s390_irgen_DL, ovl.fmt.RXY.r1,
14103 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14104 ovl.fmt.RXY.dl2,
14105 ovl.fmt.RXY.dh2); goto ok;
14106 case 0xe30000000098ULL: s390_format_RXY_RRRD(s390_irgen_ALC, ovl.fmt.RXY.r1,
14107 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14108 ovl.fmt.RXY.dl2,
14109 ovl.fmt.RXY.dh2); goto ok;
14110 case 0xe30000000099ULL: s390_format_RXY_RRRD(s390_irgen_SLB, ovl.fmt.RXY.r1,
14111 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14112 ovl.fmt.RXY.dl2,
14113 ovl.fmt.RXY.dh2); goto ok;
14114 case 0xe300000000c0ULL: s390_format_RXY_RRRD(s390_irgen_LBH, ovl.fmt.RXY.r1,
14115 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14116 ovl.fmt.RXY.dl2,
14117 ovl.fmt.RXY.dh2); goto ok;
14118 case 0xe300000000c2ULL: s390_format_RXY_RRRD(s390_irgen_LLCH, ovl.fmt.RXY.r1,
14119 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14120 ovl.fmt.RXY.dl2,
14121 ovl.fmt.RXY.dh2); goto ok;
14122 case 0xe300000000c3ULL: s390_format_RXY_RRRD(s390_irgen_STCH, ovl.fmt.RXY.r1,
14123 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14124 ovl.fmt.RXY.dl2,
14125 ovl.fmt.RXY.dh2); goto ok;
14126 case 0xe300000000c4ULL: s390_format_RXY_RRRD(s390_irgen_LHH, ovl.fmt.RXY.r1,
14127 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14128 ovl.fmt.RXY.dl2,
14129 ovl.fmt.RXY.dh2); goto ok;
14130 case 0xe300000000c6ULL: s390_format_RXY_RRRD(s390_irgen_LLHH, ovl.fmt.RXY.r1,
14131 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14132 ovl.fmt.RXY.dl2,
14133 ovl.fmt.RXY.dh2); goto ok;
14134 case 0xe300000000c7ULL: s390_format_RXY_RRRD(s390_irgen_STHH, ovl.fmt.RXY.r1,
14135 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14136 ovl.fmt.RXY.dl2,
14137 ovl.fmt.RXY.dh2); goto ok;
14138 case 0xe300000000caULL: s390_format_RXY_RRRD(s390_irgen_LFH, ovl.fmt.RXY.r1,
14139 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14140 ovl.fmt.RXY.dl2,
14141 ovl.fmt.RXY.dh2); goto ok;
14142 case 0xe300000000cbULL: s390_format_RXY_RRRD(s390_irgen_STFH, ovl.fmt.RXY.r1,
14143 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14144 ovl.fmt.RXY.dl2,
14145 ovl.fmt.RXY.dh2); goto ok;
14146 case 0xe300000000cdULL: s390_format_RXY_RRRD(s390_irgen_CHF, ovl.fmt.RXY.r1,
14147 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14148 ovl.fmt.RXY.dl2,
14149 ovl.fmt.RXY.dh2); goto ok;
14150 case 0xe300000000cfULL: s390_format_RXY_RRRD(s390_irgen_CLHF, ovl.fmt.RXY.r1,
14151 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14152 ovl.fmt.RXY.dl2,
14153 ovl.fmt.RXY.dh2); goto ok;
14154 case 0xeb0000000004ULL: s390_format_RSY_RRRD(s390_irgen_LMG, ovl.fmt.RSY.r1,
14155 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14156 ovl.fmt.RSY.dl2,
14157 ovl.fmt.RSY.dh2); goto ok;
14158 case 0xeb000000000aULL: s390_format_RSY_RRRD(s390_irgen_SRAG, ovl.fmt.RSY.r1,
14159 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14160 ovl.fmt.RSY.dl2,
14161 ovl.fmt.RSY.dh2); goto ok;
14162 case 0xeb000000000bULL: s390_format_RSY_RRRD(s390_irgen_SLAG, ovl.fmt.RSY.r1,
14163 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14164 ovl.fmt.RSY.dl2,
14165 ovl.fmt.RSY.dh2); goto ok;
14166 case 0xeb000000000cULL: s390_format_RSY_RRRD(s390_irgen_SRLG, ovl.fmt.RSY.r1,
14167 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14168 ovl.fmt.RSY.dl2,
14169 ovl.fmt.RSY.dh2); goto ok;
14170 case 0xeb000000000dULL: s390_format_RSY_RRRD(s390_irgen_SLLG, ovl.fmt.RSY.r1,
14171 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14172 ovl.fmt.RSY.dl2,
14173 ovl.fmt.RSY.dh2); goto ok;
14174 case 0xeb000000000fULL: /* TRACG */ goto unimplemented;
14175 case 0xeb0000000014ULL: s390_format_RSY_RRRD(s390_irgen_CSY, ovl.fmt.RSY.r1,
14176 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14177 ovl.fmt.RSY.dl2,
14178 ovl.fmt.RSY.dh2); goto ok;
14179 case 0xeb000000001cULL: s390_format_RSY_RRRD(s390_irgen_RLLG, ovl.fmt.RSY.r1,
14180 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14181 ovl.fmt.RSY.dl2,
14182 ovl.fmt.RSY.dh2); goto ok;
14183 case 0xeb000000001dULL: s390_format_RSY_RRRD(s390_irgen_RLL, ovl.fmt.RSY.r1,
14184 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14185 ovl.fmt.RSY.dl2,
14186 ovl.fmt.RSY.dh2); goto ok;
14187 case 0xeb0000000020ULL: s390_format_RSY_RURD(s390_irgen_CLMH, ovl.fmt.RSY.r1,
14188 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14189 ovl.fmt.RSY.dl2,
14190 ovl.fmt.RSY.dh2); goto ok;
14191 case 0xeb0000000021ULL: s390_format_RSY_RURD(s390_irgen_CLMY, ovl.fmt.RSY.r1,
14192 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14193 ovl.fmt.RSY.dl2,
14194 ovl.fmt.RSY.dh2); goto ok;
14195 case 0xeb0000000024ULL: s390_format_RSY_RRRD(s390_irgen_STMG, ovl.fmt.RSY.r1,
14196 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14197 ovl.fmt.RSY.dl2,
14198 ovl.fmt.RSY.dh2); goto ok;
14199 case 0xeb0000000025ULL: /* STCTG */ goto unimplemented;
14200 case 0xeb0000000026ULL: s390_format_RSY_RRRD(s390_irgen_STMH, ovl.fmt.RSY.r1,
14201 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14202 ovl.fmt.RSY.dl2,
14203 ovl.fmt.RSY.dh2); goto ok;
14204 case 0xeb000000002cULL: s390_format_RSY_RURD(s390_irgen_STCMH,
14205 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
14206 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
14207 ovl.fmt.RSY.dh2); goto ok;
14208 case 0xeb000000002dULL: s390_format_RSY_RURD(s390_irgen_STCMY,
14209 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
14210 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
14211 ovl.fmt.RSY.dh2); goto ok;
14212 case 0xeb000000002fULL: /* LCTLG */ goto unimplemented;
14213 case 0xeb0000000030ULL: s390_format_RSY_RRRD(s390_irgen_CSG, ovl.fmt.RSY.r1,
14214 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14215 ovl.fmt.RSY.dl2,
14216 ovl.fmt.RSY.dh2); goto ok;
florian448cbba2012-06-06 02:26:01 +000014217 case 0xeb0000000031ULL: s390_format_RSY_RRRD(s390_irgen_CDSY, ovl.fmt.RSY.r1,
14218 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14219 ovl.fmt.RSY.dl2,
14220 ovl.fmt.RSY.dh2); goto ok;
14221 case 0xeb000000003eULL: s390_format_RSY_RRRD(s390_irgen_CDSG, ovl.fmt.RSY.r1,
14222 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14223 ovl.fmt.RSY.dl2,
14224 ovl.fmt.RSY.dh2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014225 case 0xeb0000000044ULL: s390_format_RSY_RRRD(s390_irgen_BXHG, ovl.fmt.RSY.r1,
14226 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14227 ovl.fmt.RSY.dl2,
14228 ovl.fmt.RSY.dh2); goto ok;
14229 case 0xeb0000000045ULL: s390_format_RSY_RRRD(s390_irgen_BXLEG,
14230 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
14231 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
14232 ovl.fmt.RSY.dh2); goto ok;
florian8c88cb62012-08-26 18:58:13 +000014233 case 0xeb000000004cULL: s390_format_RSY_RRRD(s390_irgen_ECAG, ovl.fmt.RSY.r1,
14234 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14235 ovl.fmt.RSY.dl2,
14236 ovl.fmt.RSY.dh2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014237 case 0xeb0000000051ULL: s390_format_SIY_URD(s390_irgen_TMY, ovl.fmt.SIY.i2,
14238 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
14239 ovl.fmt.SIY.dh1); goto ok;
14240 case 0xeb0000000052ULL: s390_format_SIY_URD(s390_irgen_MVIY, ovl.fmt.SIY.i2,
14241 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
14242 ovl.fmt.SIY.dh1); goto ok;
14243 case 0xeb0000000054ULL: s390_format_SIY_URD(s390_irgen_NIY, ovl.fmt.SIY.i2,
14244 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
14245 ovl.fmt.SIY.dh1); goto ok;
14246 case 0xeb0000000055ULL: s390_format_SIY_URD(s390_irgen_CLIY, ovl.fmt.SIY.i2,
14247 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
14248 ovl.fmt.SIY.dh1); goto ok;
14249 case 0xeb0000000056ULL: s390_format_SIY_URD(s390_irgen_OIY, ovl.fmt.SIY.i2,
14250 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
14251 ovl.fmt.SIY.dh1); goto ok;
14252 case 0xeb0000000057ULL: s390_format_SIY_URD(s390_irgen_XIY, ovl.fmt.SIY.i2,
14253 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
14254 ovl.fmt.SIY.dh1); goto ok;
14255 case 0xeb000000006aULL: s390_format_SIY_IRD(s390_irgen_ASI, ovl.fmt.SIY.i2,
14256 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
14257 ovl.fmt.SIY.dh1); goto ok;
14258 case 0xeb000000006eULL: s390_format_SIY_IRD(s390_irgen_ALSI, ovl.fmt.SIY.i2,
14259 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
14260 ovl.fmt.SIY.dh1); goto ok;
14261 case 0xeb000000007aULL: s390_format_SIY_IRD(s390_irgen_AGSI, ovl.fmt.SIY.i2,
14262 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
14263 ovl.fmt.SIY.dh1); goto ok;
14264 case 0xeb000000007eULL: s390_format_SIY_IRD(s390_irgen_ALGSI, ovl.fmt.SIY.i2,
14265 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
14266 ovl.fmt.SIY.dh1); goto ok;
14267 case 0xeb0000000080ULL: s390_format_RSY_RURD(s390_irgen_ICMH, ovl.fmt.RSY.r1,
14268 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14269 ovl.fmt.RSY.dl2,
14270 ovl.fmt.RSY.dh2); goto ok;
14271 case 0xeb0000000081ULL: s390_format_RSY_RURD(s390_irgen_ICMY, ovl.fmt.RSY.r1,
14272 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14273 ovl.fmt.RSY.dl2,
14274 ovl.fmt.RSY.dh2); goto ok;
14275 case 0xeb000000008eULL: /* MVCLU */ goto unimplemented;
14276 case 0xeb000000008fULL: /* CLCLU */ goto unimplemented;
14277 case 0xeb0000000090ULL: s390_format_RSY_RRRD(s390_irgen_STMY, ovl.fmt.RSY.r1,
14278 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14279 ovl.fmt.RSY.dl2,
14280 ovl.fmt.RSY.dh2); goto ok;
14281 case 0xeb0000000096ULL: s390_format_RSY_RRRD(s390_irgen_LMH, ovl.fmt.RSY.r1,
14282 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14283 ovl.fmt.RSY.dl2,
14284 ovl.fmt.RSY.dh2); goto ok;
14285 case 0xeb0000000098ULL: s390_format_RSY_RRRD(s390_irgen_LMY, ovl.fmt.RSY.r1,
14286 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14287 ovl.fmt.RSY.dl2,
14288 ovl.fmt.RSY.dh2); goto ok;
14289 case 0xeb000000009aULL: s390_format_RSY_AARD(s390_irgen_LAMY, ovl.fmt.RSY.r1,
14290 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14291 ovl.fmt.RSY.dl2,
14292 ovl.fmt.RSY.dh2); goto ok;
14293 case 0xeb000000009bULL: s390_format_RSY_AARD(s390_irgen_STAMY,
14294 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
14295 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
14296 ovl.fmt.RSY.dh2); goto ok;
14297 case 0xeb00000000c0ULL: /* TP */ goto unimplemented;
14298 case 0xeb00000000dcULL: s390_format_RSY_RRRD(s390_irgen_SRAK, ovl.fmt.RSY.r1,
14299 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14300 ovl.fmt.RSY.dl2,
14301 ovl.fmt.RSY.dh2); goto ok;
14302 case 0xeb00000000ddULL: s390_format_RSY_RRRD(s390_irgen_SLAK, ovl.fmt.RSY.r1,
14303 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14304 ovl.fmt.RSY.dl2,
14305 ovl.fmt.RSY.dh2); goto ok;
14306 case 0xeb00000000deULL: s390_format_RSY_RRRD(s390_irgen_SRLK, ovl.fmt.RSY.r1,
14307 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14308 ovl.fmt.RSY.dl2,
14309 ovl.fmt.RSY.dh2); goto ok;
14310 case 0xeb00000000dfULL: s390_format_RSY_RRRD(s390_irgen_SLLK, ovl.fmt.RSY.r1,
14311 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14312 ovl.fmt.RSY.dl2,
14313 ovl.fmt.RSY.dh2); goto ok;
sewardjd7bde722011-04-05 13:19:33 +000014314 case 0xeb00000000e2ULL: s390_format_RSY_RDRM(s390_irgen_LOCG, ovl.fmt.RSY.r1,
14315 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14316 ovl.fmt.RSY.dl2,
14317 ovl.fmt.RSY.dh2,
14318 S390_XMNM_LOCG); goto ok;
14319 case 0xeb00000000e3ULL: s390_format_RSY_RDRM(s390_irgen_STOCG,
14320 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
14321 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
14322 ovl.fmt.RSY.dh2,
14323 S390_XMNM_STOCG); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014324 case 0xeb00000000e4ULL: s390_format_RSY_RRRD(s390_irgen_LANG, ovl.fmt.RSY.r1,
14325 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14326 ovl.fmt.RSY.dl2,
14327 ovl.fmt.RSY.dh2); goto ok;
14328 case 0xeb00000000e6ULL: s390_format_RSY_RRRD(s390_irgen_LAOG, ovl.fmt.RSY.r1,
14329 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14330 ovl.fmt.RSY.dl2,
14331 ovl.fmt.RSY.dh2); goto ok;
14332 case 0xeb00000000e7ULL: s390_format_RSY_RRRD(s390_irgen_LAXG, ovl.fmt.RSY.r1,
14333 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14334 ovl.fmt.RSY.dl2,
14335 ovl.fmt.RSY.dh2); goto ok;
14336 case 0xeb00000000e8ULL: s390_format_RSY_RRRD(s390_irgen_LAAG, ovl.fmt.RSY.r1,
14337 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14338 ovl.fmt.RSY.dl2,
14339 ovl.fmt.RSY.dh2); goto ok;
14340 case 0xeb00000000eaULL: s390_format_RSY_RRRD(s390_irgen_LAALG,
14341 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
14342 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
14343 ovl.fmt.RSY.dh2); goto ok;
sewardjd7bde722011-04-05 13:19:33 +000014344 case 0xeb00000000f2ULL: s390_format_RSY_RDRM(s390_irgen_LOC, ovl.fmt.RSY.r1,
14345 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14346 ovl.fmt.RSY.dl2,
14347 ovl.fmt.RSY.dh2, S390_XMNM_LOC);
14348 goto ok;
14349 case 0xeb00000000f3ULL: s390_format_RSY_RDRM(s390_irgen_STOC, ovl.fmt.RSY.r1,
14350 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14351 ovl.fmt.RSY.dl2,
14352 ovl.fmt.RSY.dh2,
14353 S390_XMNM_STOC); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014354 case 0xeb00000000f4ULL: s390_format_RSY_RRRD(s390_irgen_LAN, ovl.fmt.RSY.r1,
14355 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14356 ovl.fmt.RSY.dl2,
14357 ovl.fmt.RSY.dh2); goto ok;
14358 case 0xeb00000000f6ULL: s390_format_RSY_RRRD(s390_irgen_LAO, ovl.fmt.RSY.r1,
14359 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14360 ovl.fmt.RSY.dl2,
14361 ovl.fmt.RSY.dh2); goto ok;
14362 case 0xeb00000000f7ULL: s390_format_RSY_RRRD(s390_irgen_LAX, ovl.fmt.RSY.r1,
14363 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14364 ovl.fmt.RSY.dl2,
14365 ovl.fmt.RSY.dh2); goto ok;
14366 case 0xeb00000000f8ULL: s390_format_RSY_RRRD(s390_irgen_LAA, ovl.fmt.RSY.r1,
14367 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14368 ovl.fmt.RSY.dl2,
14369 ovl.fmt.RSY.dh2); goto ok;
14370 case 0xeb00000000faULL: s390_format_RSY_RRRD(s390_irgen_LAAL, ovl.fmt.RSY.r1,
14371 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14372 ovl.fmt.RSY.dl2,
14373 ovl.fmt.RSY.dh2); goto ok;
14374 case 0xec0000000044ULL: s390_format_RIE_RRP(s390_irgen_BRXHG, ovl.fmt.RIE.r1,
14375 ovl.fmt.RIE.r3, ovl.fmt.RIE.i2);
14376 goto ok;
14377 case 0xec0000000045ULL: s390_format_RIE_RRP(s390_irgen_BRXLG, ovl.fmt.RIE.r1,
14378 ovl.fmt.RIE.r3, ovl.fmt.RIE.i2);
14379 goto ok;
14380 case 0xec0000000051ULL: /* RISBLG */ goto unimplemented;
14381 case 0xec0000000054ULL: s390_format_RIE_RRUUU(s390_irgen_RNSBG,
14382 ovl.fmt.RIE_RRUUU.r1,
14383 ovl.fmt.RIE_RRUUU.r2,
14384 ovl.fmt.RIE_RRUUU.i3,
14385 ovl.fmt.RIE_RRUUU.i4,
14386 ovl.fmt.RIE_RRUUU.i5);
14387 goto ok;
14388 case 0xec0000000055ULL: s390_format_RIE_RRUUU(s390_irgen_RISBG,
14389 ovl.fmt.RIE_RRUUU.r1,
14390 ovl.fmt.RIE_RRUUU.r2,
14391 ovl.fmt.RIE_RRUUU.i3,
14392 ovl.fmt.RIE_RRUUU.i4,
14393 ovl.fmt.RIE_RRUUU.i5);
14394 goto ok;
14395 case 0xec0000000056ULL: s390_format_RIE_RRUUU(s390_irgen_ROSBG,
14396 ovl.fmt.RIE_RRUUU.r1,
14397 ovl.fmt.RIE_RRUUU.r2,
14398 ovl.fmt.RIE_RRUUU.i3,
14399 ovl.fmt.RIE_RRUUU.i4,
14400 ovl.fmt.RIE_RRUUU.i5);
14401 goto ok;
14402 case 0xec0000000057ULL: s390_format_RIE_RRUUU(s390_irgen_RXSBG,
14403 ovl.fmt.RIE_RRUUU.r1,
14404 ovl.fmt.RIE_RRUUU.r2,
14405 ovl.fmt.RIE_RRUUU.i3,
14406 ovl.fmt.RIE_RRUUU.i4,
14407 ovl.fmt.RIE_RRUUU.i5);
14408 goto ok;
14409 case 0xec000000005dULL: /* RISBHG */ goto unimplemented;
14410 case 0xec0000000064ULL: s390_format_RIE_RRPU(s390_irgen_CGRJ,
14411 ovl.fmt.RIE_RRPU.r1,
14412 ovl.fmt.RIE_RRPU.r2,
14413 ovl.fmt.RIE_RRPU.i4,
14414 ovl.fmt.RIE_RRPU.m3); goto ok;
14415 case 0xec0000000065ULL: s390_format_RIE_RRPU(s390_irgen_CLGRJ,
14416 ovl.fmt.RIE_RRPU.r1,
14417 ovl.fmt.RIE_RRPU.r2,
14418 ovl.fmt.RIE_RRPU.i4,
14419 ovl.fmt.RIE_RRPU.m3); goto ok;
14420 case 0xec0000000070ULL: /* CGIT */ goto unimplemented;
14421 case 0xec0000000071ULL: /* CLGIT */ goto unimplemented;
14422 case 0xec0000000072ULL: /* CIT */ goto unimplemented;
14423 case 0xec0000000073ULL: /* CLFIT */ goto unimplemented;
14424 case 0xec0000000076ULL: s390_format_RIE_RRPU(s390_irgen_CRJ,
14425 ovl.fmt.RIE_RRPU.r1,
14426 ovl.fmt.RIE_RRPU.r2,
14427 ovl.fmt.RIE_RRPU.i4,
14428 ovl.fmt.RIE_RRPU.m3); goto ok;
14429 case 0xec0000000077ULL: s390_format_RIE_RRPU(s390_irgen_CLRJ,
14430 ovl.fmt.RIE_RRPU.r1,
14431 ovl.fmt.RIE_RRPU.r2,
14432 ovl.fmt.RIE_RRPU.i4,
14433 ovl.fmt.RIE_RRPU.m3); goto ok;
14434 case 0xec000000007cULL: s390_format_RIE_RUPI(s390_irgen_CGIJ,
14435 ovl.fmt.RIEv3.r1,
14436 ovl.fmt.RIEv3.m3,
14437 ovl.fmt.RIEv3.i4,
14438 ovl.fmt.RIEv3.i2); goto ok;
14439 case 0xec000000007dULL: s390_format_RIE_RUPU(s390_irgen_CLGIJ,
14440 ovl.fmt.RIEv3.r1,
14441 ovl.fmt.RIEv3.m3,
14442 ovl.fmt.RIEv3.i4,
14443 ovl.fmt.RIEv3.i2); goto ok;
14444 case 0xec000000007eULL: s390_format_RIE_RUPI(s390_irgen_CIJ,
14445 ovl.fmt.RIEv3.r1,
14446 ovl.fmt.RIEv3.m3,
14447 ovl.fmt.RIEv3.i4,
14448 ovl.fmt.RIEv3.i2); goto ok;
14449 case 0xec000000007fULL: s390_format_RIE_RUPU(s390_irgen_CLIJ,
14450 ovl.fmt.RIEv3.r1,
14451 ovl.fmt.RIEv3.m3,
14452 ovl.fmt.RIEv3.i4,
14453 ovl.fmt.RIEv3.i2); goto ok;
14454 case 0xec00000000d8ULL: s390_format_RIE_RRI0(s390_irgen_AHIK, ovl.fmt.RIE.r1,
14455 ovl.fmt.RIE.r3, ovl.fmt.RIE.i2);
14456 goto ok;
14457 case 0xec00000000d9ULL: s390_format_RIE_RRI0(s390_irgen_AGHIK,
14458 ovl.fmt.RIE.r1, ovl.fmt.RIE.r3,
14459 ovl.fmt.RIE.i2); goto ok;
14460 case 0xec00000000daULL: s390_format_RIE_RRI0(s390_irgen_ALHSIK,
14461 ovl.fmt.RIE.r1, ovl.fmt.RIE.r3,
14462 ovl.fmt.RIE.i2); goto ok;
14463 case 0xec00000000dbULL: s390_format_RIE_RRI0(s390_irgen_ALGHSIK,
14464 ovl.fmt.RIE.r1, ovl.fmt.RIE.r3,
14465 ovl.fmt.RIE.i2); goto ok;
14466 case 0xec00000000e4ULL: s390_format_RRS(s390_irgen_CGRB, ovl.fmt.RRS.r1,
14467 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
14468 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
14469 goto ok;
14470 case 0xec00000000e5ULL: s390_format_RRS(s390_irgen_CLGRB, ovl.fmt.RRS.r1,
14471 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
14472 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
14473 goto ok;
14474 case 0xec00000000f6ULL: s390_format_RRS(s390_irgen_CRB, ovl.fmt.RRS.r1,
14475 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
14476 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
14477 goto ok;
14478 case 0xec00000000f7ULL: s390_format_RRS(s390_irgen_CLRB, ovl.fmt.RRS.r1,
14479 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
14480 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
14481 goto ok;
14482 case 0xec00000000fcULL: s390_format_RIS_RURDI(s390_irgen_CGIB,
14483 ovl.fmt.RIS.r1, ovl.fmt.RIS.m3,
14484 ovl.fmt.RIS.b4, ovl.fmt.RIS.d4,
14485 ovl.fmt.RIS.i2); goto ok;
14486 case 0xec00000000fdULL: s390_format_RIS_RURDU(s390_irgen_CLGIB,
14487 ovl.fmt.RIS.r1, ovl.fmt.RIS.m3,
14488 ovl.fmt.RIS.b4, ovl.fmt.RIS.d4,
14489 ovl.fmt.RIS.i2); goto ok;
14490 case 0xec00000000feULL: s390_format_RIS_RURDI(s390_irgen_CIB, ovl.fmt.RIS.r1,
14491 ovl.fmt.RIS.m3, ovl.fmt.RIS.b4,
14492 ovl.fmt.RIS.d4,
14493 ovl.fmt.RIS.i2); goto ok;
14494 case 0xec00000000ffULL: s390_format_RIS_RURDU(s390_irgen_CLIB,
14495 ovl.fmt.RIS.r1, ovl.fmt.RIS.m3,
14496 ovl.fmt.RIS.b4, ovl.fmt.RIS.d4,
14497 ovl.fmt.RIS.i2); goto ok;
14498 case 0xed0000000004ULL: s390_format_RXE_FRRD(s390_irgen_LDEB, ovl.fmt.RXE.r1,
14499 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14500 ovl.fmt.RXE.d2); goto ok;
14501 case 0xed0000000005ULL: s390_format_RXE_FRRD(s390_irgen_LXDB, ovl.fmt.RXE.r1,
14502 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14503 ovl.fmt.RXE.d2); goto ok;
14504 case 0xed0000000006ULL: s390_format_RXE_FRRD(s390_irgen_LXEB, ovl.fmt.RXE.r1,
14505 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14506 ovl.fmt.RXE.d2); goto ok;
14507 case 0xed0000000007ULL: /* MXDB */ goto unimplemented;
14508 case 0xed0000000008ULL: /* KEB */ goto unimplemented;
14509 case 0xed0000000009ULL: s390_format_RXE_FRRD(s390_irgen_CEB, ovl.fmt.RXE.r1,
14510 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14511 ovl.fmt.RXE.d2); goto ok;
14512 case 0xed000000000aULL: s390_format_RXE_FRRD(s390_irgen_AEB, ovl.fmt.RXE.r1,
14513 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14514 ovl.fmt.RXE.d2); goto ok;
14515 case 0xed000000000bULL: s390_format_RXE_FRRD(s390_irgen_SEB, ovl.fmt.RXE.r1,
14516 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14517 ovl.fmt.RXE.d2); goto ok;
14518 case 0xed000000000cULL: /* MDEB */ goto unimplemented;
14519 case 0xed000000000dULL: s390_format_RXE_FRRD(s390_irgen_DEB, ovl.fmt.RXE.r1,
14520 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14521 ovl.fmt.RXE.d2); goto ok;
14522 case 0xed000000000eULL: s390_format_RXF_FRRDF(s390_irgen_MAEB,
14523 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
14524 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
14525 ovl.fmt.RXF.r1); goto ok;
14526 case 0xed000000000fULL: s390_format_RXF_FRRDF(s390_irgen_MSEB,
14527 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
14528 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
14529 ovl.fmt.RXF.r1); goto ok;
14530 case 0xed0000000010ULL: s390_format_RXE_FRRD(s390_irgen_TCEB, ovl.fmt.RXE.r1,
14531 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14532 ovl.fmt.RXE.d2); goto ok;
14533 case 0xed0000000011ULL: s390_format_RXE_FRRD(s390_irgen_TCDB, ovl.fmt.RXE.r1,
14534 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14535 ovl.fmt.RXE.d2); goto ok;
14536 case 0xed0000000012ULL: s390_format_RXE_FRRD(s390_irgen_TCXB, ovl.fmt.RXE.r1,
14537 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14538 ovl.fmt.RXE.d2); goto ok;
14539 case 0xed0000000014ULL: s390_format_RXE_FRRD(s390_irgen_SQEB, ovl.fmt.RXE.r1,
14540 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14541 ovl.fmt.RXE.d2); goto ok;
14542 case 0xed0000000015ULL: s390_format_RXE_FRRD(s390_irgen_SQDB, ovl.fmt.RXE.r1,
14543 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14544 ovl.fmt.RXE.d2); goto ok;
14545 case 0xed0000000017ULL: s390_format_RXE_FRRD(s390_irgen_MEEB, ovl.fmt.RXE.r1,
14546 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14547 ovl.fmt.RXE.d2); goto ok;
14548 case 0xed0000000018ULL: /* KDB */ goto unimplemented;
14549 case 0xed0000000019ULL: s390_format_RXE_FRRD(s390_irgen_CDB, ovl.fmt.RXE.r1,
14550 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14551 ovl.fmt.RXE.d2); goto ok;
14552 case 0xed000000001aULL: s390_format_RXE_FRRD(s390_irgen_ADB, ovl.fmt.RXE.r1,
14553 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14554 ovl.fmt.RXE.d2); goto ok;
14555 case 0xed000000001bULL: s390_format_RXE_FRRD(s390_irgen_SDB, ovl.fmt.RXE.r1,
14556 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14557 ovl.fmt.RXE.d2); goto ok;
14558 case 0xed000000001cULL: s390_format_RXE_FRRD(s390_irgen_MDB, ovl.fmt.RXE.r1,
14559 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14560 ovl.fmt.RXE.d2); goto ok;
14561 case 0xed000000001dULL: s390_format_RXE_FRRD(s390_irgen_DDB, ovl.fmt.RXE.r1,
14562 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14563 ovl.fmt.RXE.d2); goto ok;
14564 case 0xed000000001eULL: s390_format_RXF_FRRDF(s390_irgen_MADB,
14565 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
14566 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
14567 ovl.fmt.RXF.r1); goto ok;
14568 case 0xed000000001fULL: s390_format_RXF_FRRDF(s390_irgen_MSDB,
14569 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
14570 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
14571 ovl.fmt.RXF.r1); goto ok;
14572 case 0xed0000000024ULL: /* LDE */ goto unimplemented;
14573 case 0xed0000000025ULL: /* LXD */ goto unimplemented;
14574 case 0xed0000000026ULL: /* LXE */ goto unimplemented;
14575 case 0xed000000002eULL: /* MAE */ goto unimplemented;
14576 case 0xed000000002fULL: /* MSE */ goto unimplemented;
14577 case 0xed0000000034ULL: /* SQE */ goto unimplemented;
14578 case 0xed0000000035ULL: /* SQD */ goto unimplemented;
14579 case 0xed0000000037ULL: /* MEE */ goto unimplemented;
14580 case 0xed0000000038ULL: /* MAYL */ goto unimplemented;
14581 case 0xed0000000039ULL: /* MYL */ goto unimplemented;
14582 case 0xed000000003aULL: /* MAY */ goto unimplemented;
14583 case 0xed000000003bULL: /* MY */ goto unimplemented;
14584 case 0xed000000003cULL: /* MAYH */ goto unimplemented;
14585 case 0xed000000003dULL: /* MYH */ goto unimplemented;
14586 case 0xed000000003eULL: /* MAD */ goto unimplemented;
14587 case 0xed000000003fULL: /* MSD */ goto unimplemented;
14588 case 0xed0000000040ULL: /* SLDT */ goto unimplemented;
14589 case 0xed0000000041ULL: /* SRDT */ goto unimplemented;
14590 case 0xed0000000048ULL: /* SLXT */ goto unimplemented;
14591 case 0xed0000000049ULL: /* SRXT */ goto unimplemented;
14592 case 0xed0000000050ULL: /* TDCET */ goto unimplemented;
14593 case 0xed0000000051ULL: /* TDGET */ goto unimplemented;
14594 case 0xed0000000054ULL: /* TDCDT */ goto unimplemented;
14595 case 0xed0000000055ULL: /* TDGDT */ goto unimplemented;
14596 case 0xed0000000058ULL: /* TDCXT */ goto unimplemented;
14597 case 0xed0000000059ULL: /* TDGXT */ goto unimplemented;
14598 case 0xed0000000064ULL: s390_format_RXY_FRRD(s390_irgen_LEY, ovl.fmt.RXY.r1,
14599 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14600 ovl.fmt.RXY.dl2,
14601 ovl.fmt.RXY.dh2); goto ok;
14602 case 0xed0000000065ULL: s390_format_RXY_FRRD(s390_irgen_LDY, ovl.fmt.RXY.r1,
14603 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14604 ovl.fmt.RXY.dl2,
14605 ovl.fmt.RXY.dh2); goto ok;
14606 case 0xed0000000066ULL: s390_format_RXY_FRRD(s390_irgen_STEY, ovl.fmt.RXY.r1,
14607 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14608 ovl.fmt.RXY.dl2,
14609 ovl.fmt.RXY.dh2); goto ok;
14610 case 0xed0000000067ULL: s390_format_RXY_FRRD(s390_irgen_STDY, ovl.fmt.RXY.r1,
14611 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14612 ovl.fmt.RXY.dl2,
14613 ovl.fmt.RXY.dh2); goto ok;
14614 }
14615
14616 switch (((ovl.value >> 16) & 0xff0f00000000ULL) >> 32) {
14617 case 0xc000ULL: s390_format_RIL_RP(s390_irgen_LARL, ovl.fmt.RIL.r1,
14618 ovl.fmt.RIL.i2); goto ok;
14619 case 0xc001ULL: s390_format_RIL_RI(s390_irgen_LGFI, ovl.fmt.RIL.r1,
14620 ovl.fmt.RIL.i2); goto ok;
14621 case 0xc004ULL: s390_format_RIL(s390_irgen_BRCL, ovl.fmt.RIL.r1,
14622 ovl.fmt.RIL.i2); goto ok;
14623 case 0xc005ULL: s390_format_RIL_RP(s390_irgen_BRASL, ovl.fmt.RIL.r1,
14624 ovl.fmt.RIL.i2); goto ok;
14625 case 0xc006ULL: s390_format_RIL_RU(s390_irgen_XIHF, ovl.fmt.RIL.r1,
14626 ovl.fmt.RIL.i2); goto ok;
14627 case 0xc007ULL: s390_format_RIL_RU(s390_irgen_XILF, ovl.fmt.RIL.r1,
14628 ovl.fmt.RIL.i2); goto ok;
14629 case 0xc008ULL: s390_format_RIL_RU(s390_irgen_IIHF, ovl.fmt.RIL.r1,
14630 ovl.fmt.RIL.i2); goto ok;
14631 case 0xc009ULL: s390_format_RIL_RU(s390_irgen_IILF, ovl.fmt.RIL.r1,
14632 ovl.fmt.RIL.i2); goto ok;
14633 case 0xc00aULL: s390_format_RIL_RU(s390_irgen_NIHF, ovl.fmt.RIL.r1,
14634 ovl.fmt.RIL.i2); goto ok;
14635 case 0xc00bULL: s390_format_RIL_RU(s390_irgen_NILF, ovl.fmt.RIL.r1,
14636 ovl.fmt.RIL.i2); goto ok;
14637 case 0xc00cULL: s390_format_RIL_RU(s390_irgen_OIHF, ovl.fmt.RIL.r1,
14638 ovl.fmt.RIL.i2); goto ok;
14639 case 0xc00dULL: s390_format_RIL_RU(s390_irgen_OILF, ovl.fmt.RIL.r1,
14640 ovl.fmt.RIL.i2); goto ok;
14641 case 0xc00eULL: s390_format_RIL_RU(s390_irgen_LLIHF, ovl.fmt.RIL.r1,
14642 ovl.fmt.RIL.i2); goto ok;
14643 case 0xc00fULL: s390_format_RIL_RU(s390_irgen_LLILF, ovl.fmt.RIL.r1,
14644 ovl.fmt.RIL.i2); goto ok;
14645 case 0xc200ULL: s390_format_RIL_RI(s390_irgen_MSGFI, ovl.fmt.RIL.r1,
14646 ovl.fmt.RIL.i2); goto ok;
14647 case 0xc201ULL: s390_format_RIL_RI(s390_irgen_MSFI, ovl.fmt.RIL.r1,
14648 ovl.fmt.RIL.i2); goto ok;
14649 case 0xc204ULL: s390_format_RIL_RU(s390_irgen_SLGFI, ovl.fmt.RIL.r1,
14650 ovl.fmt.RIL.i2); goto ok;
14651 case 0xc205ULL: s390_format_RIL_RU(s390_irgen_SLFI, ovl.fmt.RIL.r1,
14652 ovl.fmt.RIL.i2); goto ok;
14653 case 0xc208ULL: s390_format_RIL_RI(s390_irgen_AGFI, ovl.fmt.RIL.r1,
14654 ovl.fmt.RIL.i2); goto ok;
14655 case 0xc209ULL: s390_format_RIL_RI(s390_irgen_AFI, ovl.fmt.RIL.r1,
14656 ovl.fmt.RIL.i2); goto ok;
14657 case 0xc20aULL: s390_format_RIL_RU(s390_irgen_ALGFI, ovl.fmt.RIL.r1,
14658 ovl.fmt.RIL.i2); goto ok;
14659 case 0xc20bULL: s390_format_RIL_RU(s390_irgen_ALFI, ovl.fmt.RIL.r1,
14660 ovl.fmt.RIL.i2); goto ok;
14661 case 0xc20cULL: s390_format_RIL_RI(s390_irgen_CGFI, ovl.fmt.RIL.r1,
14662 ovl.fmt.RIL.i2); goto ok;
14663 case 0xc20dULL: s390_format_RIL_RI(s390_irgen_CFI, ovl.fmt.RIL.r1,
14664 ovl.fmt.RIL.i2); goto ok;
14665 case 0xc20eULL: s390_format_RIL_RU(s390_irgen_CLGFI, ovl.fmt.RIL.r1,
14666 ovl.fmt.RIL.i2); goto ok;
14667 case 0xc20fULL: s390_format_RIL_RU(s390_irgen_CLFI, ovl.fmt.RIL.r1,
14668 ovl.fmt.RIL.i2); goto ok;
14669 case 0xc402ULL: s390_format_RIL_RP(s390_irgen_LLHRL, ovl.fmt.RIL.r1,
14670 ovl.fmt.RIL.i2); goto ok;
14671 case 0xc404ULL: s390_format_RIL_RP(s390_irgen_LGHRL, ovl.fmt.RIL.r1,
14672 ovl.fmt.RIL.i2); goto ok;
14673 case 0xc405ULL: s390_format_RIL_RP(s390_irgen_LHRL, ovl.fmt.RIL.r1,
14674 ovl.fmt.RIL.i2); goto ok;
14675 case 0xc406ULL: s390_format_RIL_RP(s390_irgen_LLGHRL, ovl.fmt.RIL.r1,
14676 ovl.fmt.RIL.i2); goto ok;
14677 case 0xc407ULL: s390_format_RIL_RP(s390_irgen_STHRL, ovl.fmt.RIL.r1,
14678 ovl.fmt.RIL.i2); goto ok;
14679 case 0xc408ULL: s390_format_RIL_RP(s390_irgen_LGRL, ovl.fmt.RIL.r1,
14680 ovl.fmt.RIL.i2); goto ok;
14681 case 0xc40bULL: s390_format_RIL_RP(s390_irgen_STGRL, ovl.fmt.RIL.r1,
14682 ovl.fmt.RIL.i2); goto ok;
14683 case 0xc40cULL: s390_format_RIL_RP(s390_irgen_LGFRL, ovl.fmt.RIL.r1,
14684 ovl.fmt.RIL.i2); goto ok;
14685 case 0xc40dULL: s390_format_RIL_RP(s390_irgen_LRL, ovl.fmt.RIL.r1,
14686 ovl.fmt.RIL.i2); goto ok;
14687 case 0xc40eULL: s390_format_RIL_RP(s390_irgen_LLGFRL, ovl.fmt.RIL.r1,
14688 ovl.fmt.RIL.i2); goto ok;
14689 case 0xc40fULL: s390_format_RIL_RP(s390_irgen_STRL, ovl.fmt.RIL.r1,
14690 ovl.fmt.RIL.i2); goto ok;
14691 case 0xc600ULL: s390_format_RIL_RP(s390_irgen_EXRL, ovl.fmt.RIL.r1,
14692 ovl.fmt.RIL.i2); goto ok;
14693 case 0xc602ULL: s390_format_RIL_UP(s390_irgen_PFDRL, ovl.fmt.RIL.r1,
14694 ovl.fmt.RIL.i2); goto ok;
14695 case 0xc604ULL: s390_format_RIL_RP(s390_irgen_CGHRL, ovl.fmt.RIL.r1,
14696 ovl.fmt.RIL.i2); goto ok;
14697 case 0xc605ULL: s390_format_RIL_RP(s390_irgen_CHRL, ovl.fmt.RIL.r1,
14698 ovl.fmt.RIL.i2); goto ok;
14699 case 0xc606ULL: s390_format_RIL_RP(s390_irgen_CLGHRL, ovl.fmt.RIL.r1,
14700 ovl.fmt.RIL.i2); goto ok;
14701 case 0xc607ULL: s390_format_RIL_RP(s390_irgen_CLHRL, ovl.fmt.RIL.r1,
14702 ovl.fmt.RIL.i2); goto ok;
14703 case 0xc608ULL: s390_format_RIL_RP(s390_irgen_CGRL, ovl.fmt.RIL.r1,
14704 ovl.fmt.RIL.i2); goto ok;
14705 case 0xc60aULL: s390_format_RIL_RP(s390_irgen_CLGRL, ovl.fmt.RIL.r1,
14706 ovl.fmt.RIL.i2); goto ok;
14707 case 0xc60cULL: s390_format_RIL_RP(s390_irgen_CGFRL, ovl.fmt.RIL.r1,
14708 ovl.fmt.RIL.i2); goto ok;
14709 case 0xc60dULL: s390_format_RIL_RP(s390_irgen_CRL, ovl.fmt.RIL.r1,
14710 ovl.fmt.RIL.i2); goto ok;
14711 case 0xc60eULL: s390_format_RIL_RP(s390_irgen_CLGFRL, ovl.fmt.RIL.r1,
14712 ovl.fmt.RIL.i2); goto ok;
14713 case 0xc60fULL: s390_format_RIL_RP(s390_irgen_CLRL, ovl.fmt.RIL.r1,
14714 ovl.fmt.RIL.i2); goto ok;
14715 case 0xc800ULL: /* MVCOS */ goto unimplemented;
14716 case 0xc801ULL: /* ECTG */ goto unimplemented;
14717 case 0xc802ULL: /* CSST */ goto unimplemented;
14718 case 0xc804ULL: /* LPD */ goto unimplemented;
14719 case 0xc805ULL: /* LPDG */ goto unimplemented;
14720 case 0xcc06ULL: /* BRCTH */ goto unimplemented;
14721 case 0xcc08ULL: s390_format_RIL_RI(s390_irgen_AIH, ovl.fmt.RIL.r1,
14722 ovl.fmt.RIL.i2); goto ok;
14723 case 0xcc0aULL: s390_format_RIL_RI(s390_irgen_ALSIH, ovl.fmt.RIL.r1,
14724 ovl.fmt.RIL.i2); goto ok;
14725 case 0xcc0bULL: s390_format_RIL_RI(s390_irgen_ALSIHN, ovl.fmt.RIL.r1,
14726 ovl.fmt.RIL.i2); goto ok;
14727 case 0xcc0dULL: s390_format_RIL_RI(s390_irgen_CIH, ovl.fmt.RIL.r1,
14728 ovl.fmt.RIL.i2); goto ok;
14729 case 0xcc0fULL: s390_format_RIL_RU(s390_irgen_CLIH, ovl.fmt.RIL.r1,
14730 ovl.fmt.RIL.i2); goto ok;
14731 }
14732
14733 switch (((ovl.value >> 16) & 0xff0000000000ULL) >> 40) {
14734 case 0xd0ULL: /* TRTR */ goto unimplemented;
14735 case 0xd1ULL: /* MVN */ goto unimplemented;
14736 case 0xd2ULL: s390_format_SS_L0RDRD(s390_irgen_MVC, ovl.fmt.SS.l,
14737 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
14738 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
14739 case 0xd3ULL: /* MVZ */ goto unimplemented;
14740 case 0xd4ULL: s390_format_SS_L0RDRD(s390_irgen_NC, ovl.fmt.SS.l,
14741 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
14742 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
14743 case 0xd5ULL: s390_format_SS_L0RDRD(s390_irgen_CLC, ovl.fmt.SS.l,
14744 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
14745 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
14746 case 0xd6ULL: s390_format_SS_L0RDRD(s390_irgen_OC, ovl.fmt.SS.l,
14747 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
14748 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
sewardjb63967e2011-03-24 08:50:04 +000014749 case 0xd7ULL:
14750 if (ovl.fmt.SS.b1 == ovl.fmt.SS.b2 && ovl.fmt.SS.d1 == ovl.fmt.SS.d2)
14751 s390_irgen_XC_sameloc(ovl.fmt.SS.l, ovl.fmt.SS.b1, ovl.fmt.SS.d1);
14752 else
14753 s390_format_SS_L0RDRD(s390_irgen_XC, ovl.fmt.SS.l,
14754 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
14755 ovl.fmt.SS.b2, ovl.fmt.SS.d2);
14756 goto ok;
sewardj2019a972011-03-07 16:04:07 +000014757 case 0xd9ULL: /* MVCK */ goto unimplemented;
14758 case 0xdaULL: /* MVCP */ goto unimplemented;
14759 case 0xdbULL: /* MVCS */ goto unimplemented;
florian730448f2012-02-04 17:07:07 +000014760 case 0xdcULL: s390_format_SS_L0RDRD(s390_irgen_TR, ovl.fmt.SS.l,
14761 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
14762 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014763 case 0xddULL: /* TRT */ goto unimplemented;
14764 case 0xdeULL: /* ED */ goto unimplemented;
14765 case 0xdfULL: /* EDMK */ goto unimplemented;
14766 case 0xe1ULL: /* PKU */ goto unimplemented;
14767 case 0xe2ULL: /* UNPKU */ goto unimplemented;
14768 case 0xe8ULL: /* MVCIN */ goto unimplemented;
14769 case 0xe9ULL: /* PKA */ goto unimplemented;
14770 case 0xeaULL: /* UNPKA */ goto unimplemented;
14771 case 0xeeULL: /* PLO */ goto unimplemented;
14772 case 0xefULL: /* LMD */ goto unimplemented;
14773 case 0xf0ULL: /* SRP */ goto unimplemented;
14774 case 0xf1ULL: /* MVO */ goto unimplemented;
14775 case 0xf2ULL: /* PACK */ goto unimplemented;
14776 case 0xf3ULL: /* UNPK */ goto unimplemented;
14777 case 0xf8ULL: /* ZAP */ goto unimplemented;
14778 case 0xf9ULL: /* CP */ goto unimplemented;
14779 case 0xfaULL: /* AP */ goto unimplemented;
14780 case 0xfbULL: /* SP */ goto unimplemented;
14781 case 0xfcULL: /* MP */ goto unimplemented;
14782 case 0xfdULL: /* DP */ goto unimplemented;
14783 }
14784
14785 switch (((ovl.value >> 16) & 0xffff00000000ULL) >> 32) {
14786 case 0xe500ULL: /* LASP */ goto unimplemented;
14787 case 0xe501ULL: /* TPROT */ goto unimplemented;
14788 case 0xe502ULL: /* STRAG */ goto unimplemented;
14789 case 0xe50eULL: /* MVCSK */ goto unimplemented;
14790 case 0xe50fULL: /* MVCDK */ goto unimplemented;
14791 case 0xe544ULL: s390_format_SIL_RDI(s390_irgen_MVHHI, ovl.fmt.SIL.b1,
14792 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14793 goto ok;
14794 case 0xe548ULL: s390_format_SIL_RDI(s390_irgen_MVGHI, ovl.fmt.SIL.b1,
14795 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14796 goto ok;
14797 case 0xe54cULL: s390_format_SIL_RDI(s390_irgen_MVHI, ovl.fmt.SIL.b1,
14798 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14799 goto ok;
14800 case 0xe554ULL: s390_format_SIL_RDI(s390_irgen_CHHSI, ovl.fmt.SIL.b1,
14801 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14802 goto ok;
14803 case 0xe555ULL: s390_format_SIL_RDU(s390_irgen_CLHHSI, ovl.fmt.SIL.b1,
14804 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14805 goto ok;
14806 case 0xe558ULL: s390_format_SIL_RDI(s390_irgen_CGHSI, ovl.fmt.SIL.b1,
14807 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14808 goto ok;
14809 case 0xe559ULL: s390_format_SIL_RDU(s390_irgen_CLGHSI, ovl.fmt.SIL.b1,
14810 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14811 goto ok;
14812 case 0xe55cULL: s390_format_SIL_RDI(s390_irgen_CHSI, ovl.fmt.SIL.b1,
14813 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14814 goto ok;
14815 case 0xe55dULL: s390_format_SIL_RDU(s390_irgen_CLFHSI, ovl.fmt.SIL.b1,
14816 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14817 goto ok;
14818 }
14819
14820 return S390_DECODE_UNKNOWN_INSN;
14821
14822ok:
14823 return S390_DECODE_OK;
14824
14825unimplemented:
14826 return S390_DECODE_UNIMPLEMENTED_INSN;
14827}
14828
14829/* Handle "special" instructions. */
14830static s390_decode_t
14831s390_decode_special_and_irgen(UChar *bytes)
14832{
14833 s390_decode_t status = S390_DECODE_OK;
14834
14835 /* Got a "Special" instruction preamble. Which one is it? */
14836 if (bytes[0] == 0x18 && bytes[1] == 0x22 /* lr %r2, %r2 */) {
14837 s390_irgen_client_request();
14838 } else if (bytes[0] == 0x18 && bytes[1] == 0x33 /* lr %r3, %r3 */) {
14839 s390_irgen_guest_NRADDR();
14840 } else if (bytes[0] == 0x18 && bytes[1] == 0x44 /* lr %r4, %r4 */) {
14841 s390_irgen_call_noredir();
florian2245ce92012-08-28 16:49:30 +000014842 } else if (bytes[0] == 0x18 && bytes[1] == 0x55 /* lr %r5, %r5 */) {
14843 vex_inject_ir(irsb, Iend_BE);
14844
14845 /* Invalidate the current insn. The reason is that the IRop we're
14846 injecting here can change. In which case the translation has to
14847 be redone. For ease of handling, we simply invalidate all the
14848 time. */
14849 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TISTART),
14850 mkU64(guest_IA_curr_instr)));
14851 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TILEN),
14852 mkU64(guest_IA_next_instr - guest_IA_curr_instr)));
14853 vassert(guest_IA_next_instr - guest_IA_curr_instr ==
14854 S390_SPECIAL_OP_PREAMBLE_SIZE + S390_SPECIAL_OP_SIZE);
14855
14856 put_IA(mkaddr_expr(guest_IA_next_instr));
14857 dis_res->whatNext = Dis_StopHere;
14858 dis_res->jk_StopHere = Ijk_TInval;
sewardj2019a972011-03-07 16:04:07 +000014859 } else {
14860 /* We don't know what it is. */
14861 return S390_DECODE_UNKNOWN_SPECIAL_INSN;
14862 }
14863
14864 dis_res->len = S390_SPECIAL_OP_PREAMBLE_SIZE + S390_SPECIAL_OP_SIZE;
14865
14866 return status;
14867}
14868
14869
14870/* Function returns # bytes that were decoded or 0 in case of failure */
florianb4df7682011-07-05 02:09:01 +000014871static UInt
sewardj2019a972011-03-07 16:04:07 +000014872s390_decode_and_irgen(UChar *bytes, UInt insn_length, DisResult *dres)
14873{
14874 s390_decode_t status;
14875
14876 dis_res = dres;
14877
14878 /* Spot the 8-byte preamble: 18ff lr r15,r15
14879 1811 lr r1,r1
14880 1822 lr r2,r2
14881 1833 lr r3,r3 */
14882 if (bytes[ 0] == 0x18 && bytes[ 1] == 0xff && bytes[ 2] == 0x18 &&
14883 bytes[ 3] == 0x11 && bytes[ 4] == 0x18 && bytes[ 5] == 0x22 &&
14884 bytes[ 6] == 0x18 && bytes[ 7] == 0x33) {
14885
14886 /* Handle special instruction that follows that preamble. */
14887 if (0) vex_printf("special function handling...\n");
florian2c8ed942011-08-01 22:07:51 +000014888
14889 insn_length = S390_SPECIAL_OP_PREAMBLE_SIZE + S390_SPECIAL_OP_SIZE;
14890 guest_IA_next_instr = guest_IA_curr_instr + insn_length;
14891
14892 status =
14893 s390_decode_special_and_irgen(bytes + S390_SPECIAL_OP_PREAMBLE_SIZE);
sewardj2019a972011-03-07 16:04:07 +000014894 } else {
14895 /* Handle normal instructions. */
14896 switch (insn_length) {
14897 case 2:
14898 status = s390_decode_2byte_and_irgen(bytes);
14899 break;
14900
14901 case 4:
14902 status = s390_decode_4byte_and_irgen(bytes);
14903 break;
14904
14905 case 6:
14906 status = s390_decode_6byte_and_irgen(bytes);
14907 break;
14908
14909 default:
14910 status = S390_DECODE_ERROR;
14911 break;
14912 }
14913 }
florian5fcbba22011-07-27 20:40:22 +000014914 /* If next instruction is execute, stop here */
florianf9e1ed72012-04-17 02:41:56 +000014915 if (dis_res->whatNext == Dis_Continue && bytes[insn_length] == 0x44) {
14916 put_IA(mkaddr_expr(guest_IA_next_instr));
sewardj2019a972011-03-07 16:04:07 +000014917 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +000014918 dis_res->jk_StopHere = Ijk_Boring;
sewardj2019a972011-03-07 16:04:07 +000014919 }
14920
14921 if (status == S390_DECODE_OK) return insn_length; /* OK */
14922
14923 /* Decoding failed somehow */
14924 vex_printf("vex s390->IR: ");
14925 switch (status) {
14926 case S390_DECODE_UNKNOWN_INSN:
14927 vex_printf("unknown insn: ");
14928 break;
14929
14930 case S390_DECODE_UNIMPLEMENTED_INSN:
14931 vex_printf("unimplemented insn: ");
14932 break;
14933
14934 case S390_DECODE_UNKNOWN_SPECIAL_INSN:
14935 vex_printf("unimplemented special insn: ");
14936 break;
14937
14938 default:
14939 case S390_DECODE_ERROR:
14940 vex_printf("decoding error: ");
14941 break;
14942 }
14943
14944 vex_printf("%02x%02x", bytes[0], bytes[1]);
14945 if (insn_length > 2) {
14946 vex_printf(" %02x%02x", bytes[2], bytes[3]);
14947 }
14948 if (insn_length > 4) {
14949 vex_printf(" %02x%02x", bytes[4], bytes[5]);
14950 }
14951 vex_printf("\n");
14952
14953 return 0; /* Failed */
14954}
14955
14956
sewardj2019a972011-03-07 16:04:07 +000014957/* Disassemble a single instruction INSN into IR. */
14958static DisResult
florian420c5012011-07-22 02:12:28 +000014959disInstr_S390_WRK(UChar *insn)
sewardj2019a972011-03-07 16:04:07 +000014960{
14961 UChar byte;
14962 UInt insn_length;
14963 DisResult dres;
14964
14965 /* ---------------------------------------------------- */
14966 /* --- Compute instruction length -- */
14967 /* ---------------------------------------------------- */
14968
14969 /* Get the first byte of the insn. */
14970 byte = insn[0];
14971
14972 /* The leftmost two bits (0:1) encode the length of the insn in bytes.
14973 00 -> 2 bytes, 01 -> 4 bytes, 10 -> 4 bytes, 11 -> 6 bytes. */
14974 insn_length = ((((byte >> 6) + 1) >> 1) + 1) << 1;
14975
14976 guest_IA_next_instr = guest_IA_curr_instr + insn_length;
14977
14978 /* ---------------------------------------------------- */
14979 /* --- Initialise the DisResult data -- */
14980 /* ---------------------------------------------------- */
14981 dres.whatNext = Dis_Continue;
14982 dres.len = insn_length;
14983 dres.continueAt = 0;
florian8844a632012-04-13 04:04:06 +000014984 dres.jk_StopHere = Ijk_INVALID;
sewardj2019a972011-03-07 16:04:07 +000014985
floriana99f20e2011-07-17 14:16:41 +000014986 /* fixs390: consider chasing of conditional jumps */
14987
sewardj2019a972011-03-07 16:04:07 +000014988 /* Normal and special instruction handling starts here. */
14989 if (s390_decode_and_irgen(insn, insn_length, &dres) == 0) {
14990 /* All decode failures end up here. The decoder has already issued an
14991 error message.
14992 Tell the dispatcher that this insn cannot be decoded, and so has
florian342e01a2012-07-26 02:37:49 +000014993 not been executed, and (is currently) the next to be executed.
14994 The insn address in the guest state needs to be set to
14995 guest_IA_curr_instr, otherwise the complaint will report an
14996 incorrect address. */
14997 put_IA(mkaddr_expr(guest_IA_curr_instr));
sewardj2019a972011-03-07 16:04:07 +000014998
florian8844a632012-04-13 04:04:06 +000014999 dres.whatNext = Dis_StopHere;
15000 dres.jk_StopHere = Ijk_NoDecode;
15001 dres.continueAt = 0;
15002 dres.len = 0;
15003 } else {
15004 /* Decode success */
15005 switch (dres.whatNext) {
15006 case Dis_Continue:
florian8559e412012-04-19 14:23:48 +000015007 put_IA(mkaddr_expr(guest_IA_next_instr));
florian8844a632012-04-13 04:04:06 +000015008 break;
15009 case Dis_ResteerU:
15010 case Dis_ResteerC:
15011 put_IA(mkaddr_expr(dres.continueAt));
15012 break;
15013 case Dis_StopHere:
florian4b8efad2012-09-02 18:07:08 +000015014 if (dres.jk_StopHere == Ijk_EmWarn ||
15015 dres.jk_StopHere == Ijk_EmFail) {
15016 /* We assume here, that emulation warnings are not given for
15017 insns that transfer control. There is no good way to
15018 do that. */
15019 put_IA(mkaddr_expr(guest_IA_next_instr));
15020 }
florian8844a632012-04-13 04:04:06 +000015021 break;
15022 default:
15023 vassert(0);
15024 }
sewardj2019a972011-03-07 16:04:07 +000015025 }
15026
15027 return dres;
15028}
15029
15030
15031/*------------------------------------------------------------*/
15032/*--- Top-level fn ---*/
15033/*------------------------------------------------------------*/
15034
15035/* Disassemble a single instruction into IR. The instruction
15036 is located in host memory at &guest_code[delta]. */
15037
15038DisResult
15039disInstr_S390(IRSB *irsb_IN,
sewardj2019a972011-03-07 16:04:07 +000015040 Bool (*resteerOkFn)(void *, Addr64),
15041 Bool resteerCisOk,
15042 void *callback_opaque,
15043 UChar *guest_code,
15044 Long delta,
15045 Addr64 guest_IP,
15046 VexArch guest_arch,
15047 VexArchInfo *archinfo,
15048 VexAbiInfo *abiinfo,
15049 Bool host_bigendian)
15050{
15051 vassert(guest_arch == VexArchS390X);
15052
15053 /* The instruction decoder requires a big-endian machine. */
15054 vassert(host_bigendian == True);
15055
15056 /* Set globals (see top of this file) */
15057 guest_IA_curr_instr = guest_IP;
sewardj2019a972011-03-07 16:04:07 +000015058 irsb = irsb_IN;
florian420c5012011-07-22 02:12:28 +000015059 resteer_fn = resteerOkFn;
15060 resteer_data = callback_opaque;
sewardj2019a972011-03-07 16:04:07 +000015061
florian420c5012011-07-22 02:12:28 +000015062 return disInstr_S390_WRK(guest_code + delta);
sewardj2019a972011-03-07 16:04:07 +000015063}
15064
15065/*---------------------------------------------------------------*/
15066/*--- end guest_s390_toIR.c ---*/
15067/*---------------------------------------------------------------*/