blob: 4d94281dd929e791db99108247e58c82fc474f61 [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
florian55085f82012-11-21 00:36:55 +00005428static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005429s390_irgen_LAA(UChar r1, UChar r3, IRTemp op2addr)
5430{
5431 IRTemp op2 = newTemp(Ity_I32);
5432 IRTemp op3 = newTemp(Ity_I32);
5433 IRTemp result = newTemp(Ity_I32);
5434
5435 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5436 assign(op3, get_gpr_w1(r3));
5437 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
5438 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
5439 store(mkexpr(op2addr), mkexpr(result));
5440 put_gpr_w1(r1, mkexpr(op2));
5441
5442 return "laa";
5443}
5444
florian55085f82012-11-21 00:36:55 +00005445static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005446s390_irgen_LAAG(UChar r1, UChar r3, IRTemp op2addr)
5447{
5448 IRTemp op2 = newTemp(Ity_I64);
5449 IRTemp op3 = newTemp(Ity_I64);
5450 IRTemp result = newTemp(Ity_I64);
5451
5452 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5453 assign(op3, get_gpr_dw0(r3));
5454 assign(result, binop(Iop_Add64, mkexpr(op2), mkexpr(op3)));
5455 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op2, op3);
5456 store(mkexpr(op2addr), mkexpr(result));
5457 put_gpr_dw0(r1, mkexpr(op2));
5458
5459 return "laag";
5460}
5461
florian55085f82012-11-21 00:36:55 +00005462static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005463s390_irgen_LAAL(UChar r1, UChar r3, IRTemp op2addr)
5464{
5465 IRTemp op2 = newTemp(Ity_I32);
5466 IRTemp op3 = newTemp(Ity_I32);
5467 IRTemp result = newTemp(Ity_I32);
5468
5469 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5470 assign(op3, get_gpr_w1(r3));
5471 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
5472 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
5473 store(mkexpr(op2addr), mkexpr(result));
5474 put_gpr_w1(r1, mkexpr(op2));
5475
5476 return "laal";
5477}
5478
florian55085f82012-11-21 00:36:55 +00005479static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005480s390_irgen_LAALG(UChar r1, UChar r3, IRTemp op2addr)
5481{
5482 IRTemp op2 = newTemp(Ity_I64);
5483 IRTemp op3 = newTemp(Ity_I64);
5484 IRTemp result = newTemp(Ity_I64);
5485
5486 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5487 assign(op3, get_gpr_dw0(r3));
5488 assign(result, binop(Iop_Add64, mkexpr(op2), mkexpr(op3)));
5489 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op2, op3);
5490 store(mkexpr(op2addr), mkexpr(result));
5491 put_gpr_dw0(r1, mkexpr(op2));
5492
5493 return "laalg";
5494}
5495
florian55085f82012-11-21 00:36:55 +00005496static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005497s390_irgen_LAN(UChar r1, UChar r3, IRTemp op2addr)
5498{
5499 IRTemp op2 = newTemp(Ity_I32);
5500 IRTemp op3 = newTemp(Ity_I32);
5501 IRTemp result = newTemp(Ity_I32);
5502
5503 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5504 assign(op3, get_gpr_w1(r3));
5505 assign(result, binop(Iop_And32, mkexpr(op2), mkexpr(op3)));
5506 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5507 store(mkexpr(op2addr), mkexpr(result));
5508 put_gpr_w1(r1, mkexpr(op2));
5509
5510 return "lan";
5511}
5512
florian55085f82012-11-21 00:36:55 +00005513static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005514s390_irgen_LANG(UChar r1, UChar r3, IRTemp op2addr)
5515{
5516 IRTemp op2 = newTemp(Ity_I64);
5517 IRTemp op3 = newTemp(Ity_I64);
5518 IRTemp result = newTemp(Ity_I64);
5519
5520 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5521 assign(op3, get_gpr_dw0(r3));
5522 assign(result, binop(Iop_And64, mkexpr(op2), mkexpr(op3)));
5523 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5524 store(mkexpr(op2addr), mkexpr(result));
5525 put_gpr_dw0(r1, mkexpr(op2));
5526
5527 return "lang";
5528}
5529
florian55085f82012-11-21 00:36:55 +00005530static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005531s390_irgen_LAX(UChar r1, UChar r3, IRTemp op2addr)
5532{
5533 IRTemp op2 = newTemp(Ity_I32);
5534 IRTemp op3 = newTemp(Ity_I32);
5535 IRTemp result = newTemp(Ity_I32);
5536
5537 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5538 assign(op3, get_gpr_w1(r3));
5539 assign(result, binop(Iop_Xor32, mkexpr(op2), mkexpr(op3)));
5540 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5541 store(mkexpr(op2addr), mkexpr(result));
5542 put_gpr_w1(r1, mkexpr(op2));
5543
5544 return "lax";
5545}
5546
florian55085f82012-11-21 00:36:55 +00005547static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005548s390_irgen_LAXG(UChar r1, UChar r3, IRTemp op2addr)
5549{
5550 IRTemp op2 = newTemp(Ity_I64);
5551 IRTemp op3 = newTemp(Ity_I64);
5552 IRTemp result = newTemp(Ity_I64);
5553
5554 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5555 assign(op3, get_gpr_dw0(r3));
5556 assign(result, binop(Iop_Xor64, mkexpr(op2), mkexpr(op3)));
5557 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5558 store(mkexpr(op2addr), mkexpr(result));
5559 put_gpr_dw0(r1, mkexpr(op2));
5560
5561 return "laxg";
5562}
5563
florian55085f82012-11-21 00:36:55 +00005564static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005565s390_irgen_LAO(UChar r1, UChar r3, IRTemp op2addr)
5566{
5567 IRTemp op2 = newTemp(Ity_I32);
5568 IRTemp op3 = newTemp(Ity_I32);
5569 IRTemp result = newTemp(Ity_I32);
5570
5571 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5572 assign(op3, get_gpr_w1(r3));
5573 assign(result, binop(Iop_Or32, mkexpr(op2), mkexpr(op3)));
5574 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5575 store(mkexpr(op2addr), mkexpr(result));
5576 put_gpr_w1(r1, mkexpr(op2));
5577
5578 return "lao";
5579}
5580
florian55085f82012-11-21 00:36:55 +00005581static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005582s390_irgen_LAOG(UChar r1, UChar r3, IRTemp op2addr)
5583{
5584 IRTemp op2 = newTemp(Ity_I64);
5585 IRTemp op3 = newTemp(Ity_I64);
5586 IRTemp result = newTemp(Ity_I64);
5587
5588 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5589 assign(op3, get_gpr_dw0(r3));
5590 assign(result, binop(Iop_Or64, mkexpr(op2), mkexpr(op3)));
5591 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5592 store(mkexpr(op2addr), mkexpr(result));
5593 put_gpr_dw0(r1, mkexpr(op2));
5594
5595 return "laog";
5596}
5597
florian55085f82012-11-21 00:36:55 +00005598static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005599s390_irgen_LTR(UChar r1, UChar r2)
5600{
5601 IRTemp op2 = newTemp(Ity_I32);
5602
5603 assign(op2, get_gpr_w1(r2));
5604 put_gpr_w1(r1, mkexpr(op2));
5605 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5606
5607 return "ltr";
5608}
5609
florian55085f82012-11-21 00:36:55 +00005610static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005611s390_irgen_LTGR(UChar r1, UChar r2)
5612{
5613 IRTemp op2 = newTemp(Ity_I64);
5614
5615 assign(op2, get_gpr_dw0(r2));
5616 put_gpr_dw0(r1, mkexpr(op2));
5617 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5618
5619 return "ltgr";
5620}
5621
florian55085f82012-11-21 00:36:55 +00005622static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005623s390_irgen_LTGFR(UChar r1, UChar r2)
5624{
5625 IRTemp op2 = newTemp(Ity_I64);
5626
5627 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
5628 put_gpr_dw0(r1, mkexpr(op2));
5629 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5630
5631 return "ltgfr";
5632}
5633
florian55085f82012-11-21 00:36:55 +00005634static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005635s390_irgen_LT(UChar r1, IRTemp op2addr)
5636{
5637 IRTemp op2 = newTemp(Ity_I32);
5638
5639 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5640 put_gpr_w1(r1, mkexpr(op2));
5641 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5642
5643 return "lt";
5644}
5645
florian55085f82012-11-21 00:36:55 +00005646static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005647s390_irgen_LTG(UChar r1, IRTemp op2addr)
5648{
5649 IRTemp op2 = newTemp(Ity_I64);
5650
5651 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5652 put_gpr_dw0(r1, mkexpr(op2));
5653 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5654
5655 return "ltg";
5656}
5657
florian55085f82012-11-21 00:36:55 +00005658static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005659s390_irgen_LTGF(UChar r1, IRTemp op2addr)
5660{
5661 IRTemp op2 = newTemp(Ity_I64);
5662
5663 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
5664 put_gpr_dw0(r1, mkexpr(op2));
5665 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5666
5667 return "ltgf";
5668}
5669
florian55085f82012-11-21 00:36:55 +00005670static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005671s390_irgen_LBR(UChar r1, UChar r2)
5672{
5673 put_gpr_w1(r1, unop(Iop_8Sto32, get_gpr_b7(r2)));
5674
5675 return "lbr";
5676}
5677
florian55085f82012-11-21 00:36:55 +00005678static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005679s390_irgen_LGBR(UChar r1, UChar r2)
5680{
5681 put_gpr_dw0(r1, unop(Iop_8Sto64, get_gpr_b7(r2)));
5682
5683 return "lgbr";
5684}
5685
florian55085f82012-11-21 00:36:55 +00005686static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005687s390_irgen_LB(UChar r1, IRTemp op2addr)
5688{
5689 put_gpr_w1(r1, unop(Iop_8Sto32, load(Ity_I8, mkexpr(op2addr))));
5690
5691 return "lb";
5692}
5693
florian55085f82012-11-21 00:36:55 +00005694static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005695s390_irgen_LGB(UChar r1, IRTemp op2addr)
5696{
5697 put_gpr_dw0(r1, unop(Iop_8Sto64, load(Ity_I8, mkexpr(op2addr))));
5698
5699 return "lgb";
5700}
5701
florian55085f82012-11-21 00:36:55 +00005702static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005703s390_irgen_LBH(UChar r1, IRTemp op2addr)
5704{
5705 put_gpr_w0(r1, unop(Iop_8Sto32, load(Ity_I8, mkexpr(op2addr))));
5706
5707 return "lbh";
5708}
5709
florian55085f82012-11-21 00:36:55 +00005710static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005711s390_irgen_LCR(UChar r1, UChar r2)
5712{
5713 Int op1;
5714 IRTemp op2 = newTemp(Ity_I32);
5715 IRTemp result = newTemp(Ity_I32);
5716
5717 op1 = 0;
5718 assign(op2, get_gpr_w1(r2));
5719 assign(result, binop(Iop_Sub32, mkU32((UInt)op1), mkexpr(op2)));
5720 put_gpr_w1(r1, mkexpr(result));
5721 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, mktemp(Ity_I32, mkU32((UInt)
5722 op1)), op2);
5723
5724 return "lcr";
5725}
5726
florian55085f82012-11-21 00:36:55 +00005727static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005728s390_irgen_LCGR(UChar r1, UChar r2)
5729{
5730 Long op1;
5731 IRTemp op2 = newTemp(Ity_I64);
5732 IRTemp result = newTemp(Ity_I64);
5733
5734 op1 = 0ULL;
5735 assign(op2, get_gpr_dw0(r2));
5736 assign(result, binop(Iop_Sub64, mkU64((ULong)op1), mkexpr(op2)));
5737 put_gpr_dw0(r1, mkexpr(result));
5738 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, mktemp(Ity_I64, mkU64((ULong)
5739 op1)), op2);
5740
5741 return "lcgr";
5742}
5743
florian55085f82012-11-21 00:36:55 +00005744static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005745s390_irgen_LCGFR(UChar r1, UChar r2)
5746{
5747 Long op1;
5748 IRTemp op2 = newTemp(Ity_I64);
5749 IRTemp result = newTemp(Ity_I64);
5750
5751 op1 = 0ULL;
5752 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
5753 assign(result, binop(Iop_Sub64, mkU64((ULong)op1), mkexpr(op2)));
5754 put_gpr_dw0(r1, mkexpr(result));
5755 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, mktemp(Ity_I64, mkU64((ULong)
5756 op1)), op2);
5757
5758 return "lcgfr";
5759}
5760
florian55085f82012-11-21 00:36:55 +00005761static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005762s390_irgen_LHR(UChar r1, UChar r2)
5763{
5764 put_gpr_w1(r1, unop(Iop_16Sto32, get_gpr_hw3(r2)));
5765
5766 return "lhr";
5767}
5768
florian55085f82012-11-21 00:36:55 +00005769static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005770s390_irgen_LGHR(UChar r1, UChar r2)
5771{
5772 put_gpr_dw0(r1, unop(Iop_16Sto64, get_gpr_hw3(r2)));
5773
5774 return "lghr";
5775}
5776
florian55085f82012-11-21 00:36:55 +00005777static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005778s390_irgen_LH(UChar r1, IRTemp op2addr)
5779{
5780 put_gpr_w1(r1, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
5781
5782 return "lh";
5783}
5784
florian55085f82012-11-21 00:36:55 +00005785static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005786s390_irgen_LHY(UChar r1, IRTemp op2addr)
5787{
5788 put_gpr_w1(r1, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
5789
5790 return "lhy";
5791}
5792
florian55085f82012-11-21 00:36:55 +00005793static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005794s390_irgen_LGH(UChar r1, IRTemp op2addr)
5795{
5796 put_gpr_dw0(r1, unop(Iop_16Sto64, load(Ity_I16, mkexpr(op2addr))));
5797
5798 return "lgh";
5799}
5800
florian55085f82012-11-21 00:36:55 +00005801static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005802s390_irgen_LHI(UChar r1, UShort i2)
5803{
5804 put_gpr_w1(r1, mkU32((UInt)(Int)(Short)i2));
5805
5806 return "lhi";
5807}
5808
florian55085f82012-11-21 00:36:55 +00005809static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005810s390_irgen_LGHI(UChar r1, UShort i2)
5811{
5812 put_gpr_dw0(r1, mkU64((ULong)(Long)(Short)i2));
5813
5814 return "lghi";
5815}
5816
florian55085f82012-11-21 00:36:55 +00005817static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005818s390_irgen_LHRL(UChar r1, UInt i2)
5819{
5820 put_gpr_w1(r1, unop(Iop_16Sto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
5821 ((ULong)(Long)(Int)i2 << 1)))));
5822
5823 return "lhrl";
5824}
5825
florian55085f82012-11-21 00:36:55 +00005826static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005827s390_irgen_LGHRL(UChar r1, UInt i2)
5828{
5829 put_gpr_dw0(r1, unop(Iop_16Sto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
5830 ((ULong)(Long)(Int)i2 << 1)))));
5831
5832 return "lghrl";
5833}
5834
florian55085f82012-11-21 00:36:55 +00005835static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005836s390_irgen_LHH(UChar r1, IRTemp op2addr)
5837{
5838 put_gpr_w0(r1, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
5839
5840 return "lhh";
5841}
5842
florian55085f82012-11-21 00:36:55 +00005843static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005844s390_irgen_LFH(UChar r1, IRTemp op2addr)
5845{
5846 put_gpr_w0(r1, load(Ity_I32, mkexpr(op2addr)));
5847
5848 return "lfh";
5849}
5850
florian55085f82012-11-21 00:36:55 +00005851static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005852s390_irgen_LLGFR(UChar r1, UChar r2)
5853{
5854 put_gpr_dw0(r1, unop(Iop_32Uto64, get_gpr_w1(r2)));
5855
5856 return "llgfr";
5857}
5858
florian55085f82012-11-21 00:36:55 +00005859static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005860s390_irgen_LLGF(UChar r1, IRTemp op2addr)
5861{
5862 put_gpr_dw0(r1, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
5863
5864 return "llgf";
5865}
5866
florian55085f82012-11-21 00:36:55 +00005867static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005868s390_irgen_LLGFRL(UChar r1, UInt i2)
5869{
5870 put_gpr_dw0(r1, unop(Iop_32Uto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
5871 ((ULong)(Long)(Int)i2 << 1)))));
5872
5873 return "llgfrl";
5874}
5875
florian55085f82012-11-21 00:36:55 +00005876static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005877s390_irgen_LLCR(UChar r1, UChar r2)
5878{
5879 put_gpr_w1(r1, unop(Iop_8Uto32, get_gpr_b7(r2)));
5880
5881 return "llcr";
5882}
5883
florian55085f82012-11-21 00:36:55 +00005884static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005885s390_irgen_LLGCR(UChar r1, UChar r2)
5886{
5887 put_gpr_dw0(r1, unop(Iop_8Uto64, get_gpr_b7(r2)));
5888
5889 return "llgcr";
5890}
5891
florian55085f82012-11-21 00:36:55 +00005892static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005893s390_irgen_LLC(UChar r1, IRTemp op2addr)
5894{
5895 put_gpr_w1(r1, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
5896
5897 return "llc";
5898}
5899
florian55085f82012-11-21 00:36:55 +00005900static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005901s390_irgen_LLGC(UChar r1, IRTemp op2addr)
5902{
5903 put_gpr_dw0(r1, unop(Iop_8Uto64, load(Ity_I8, mkexpr(op2addr))));
5904
5905 return "llgc";
5906}
5907
florian55085f82012-11-21 00:36:55 +00005908static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005909s390_irgen_LLCH(UChar r1, IRTemp op2addr)
5910{
5911 put_gpr_w0(r1, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
5912
5913 return "llch";
5914}
5915
florian55085f82012-11-21 00:36:55 +00005916static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005917s390_irgen_LLHR(UChar r1, UChar r2)
5918{
5919 put_gpr_w1(r1, unop(Iop_16Uto32, get_gpr_hw3(r2)));
5920
5921 return "llhr";
5922}
5923
florian55085f82012-11-21 00:36:55 +00005924static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005925s390_irgen_LLGHR(UChar r1, UChar r2)
5926{
5927 put_gpr_dw0(r1, unop(Iop_16Uto64, get_gpr_hw3(r2)));
5928
5929 return "llghr";
5930}
5931
florian55085f82012-11-21 00:36:55 +00005932static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005933s390_irgen_LLH(UChar r1, IRTemp op2addr)
5934{
5935 put_gpr_w1(r1, unop(Iop_16Uto32, load(Ity_I16, mkexpr(op2addr))));
5936
5937 return "llh";
5938}
5939
florian55085f82012-11-21 00:36:55 +00005940static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005941s390_irgen_LLGH(UChar r1, IRTemp op2addr)
5942{
5943 put_gpr_dw0(r1, unop(Iop_16Uto64, load(Ity_I16, mkexpr(op2addr))));
5944
5945 return "llgh";
5946}
5947
florian55085f82012-11-21 00:36:55 +00005948static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005949s390_irgen_LLHRL(UChar r1, UInt i2)
5950{
5951 put_gpr_w1(r1, unop(Iop_16Uto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
5952 ((ULong)(Long)(Int)i2 << 1)))));
5953
5954 return "llhrl";
5955}
5956
florian55085f82012-11-21 00:36:55 +00005957static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005958s390_irgen_LLGHRL(UChar r1, UInt i2)
5959{
5960 put_gpr_dw0(r1, unop(Iop_16Uto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
5961 ((ULong)(Long)(Int)i2 << 1)))));
5962
5963 return "llghrl";
5964}
5965
florian55085f82012-11-21 00:36:55 +00005966static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005967s390_irgen_LLHH(UChar r1, IRTemp op2addr)
5968{
5969 put_gpr_w0(r1, unop(Iop_16Uto32, load(Ity_I16, mkexpr(op2addr))));
5970
5971 return "llhh";
5972}
5973
florian55085f82012-11-21 00:36:55 +00005974static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005975s390_irgen_LLIHF(UChar r1, UInt i2)
5976{
5977 put_gpr_dw0(r1, mkU64(((ULong)i2) << 32));
5978
5979 return "llihf";
5980}
5981
florian55085f82012-11-21 00:36:55 +00005982static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005983s390_irgen_LLIHH(UChar r1, UShort i2)
5984{
5985 put_gpr_dw0(r1, mkU64(((ULong)i2) << 48));
5986
5987 return "llihh";
5988}
5989
florian55085f82012-11-21 00:36:55 +00005990static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005991s390_irgen_LLIHL(UChar r1, UShort i2)
5992{
5993 put_gpr_dw0(r1, mkU64(((ULong)i2) << 32));
5994
5995 return "llihl";
5996}
5997
florian55085f82012-11-21 00:36:55 +00005998static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005999s390_irgen_LLILF(UChar r1, UInt i2)
6000{
6001 put_gpr_dw0(r1, mkU64(i2));
6002
6003 return "llilf";
6004}
6005
florian55085f82012-11-21 00:36:55 +00006006static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006007s390_irgen_LLILH(UChar r1, UShort i2)
6008{
6009 put_gpr_dw0(r1, mkU64(((ULong)i2) << 16));
6010
6011 return "llilh";
6012}
6013
florian55085f82012-11-21 00:36:55 +00006014static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006015s390_irgen_LLILL(UChar r1, UShort i2)
6016{
6017 put_gpr_dw0(r1, mkU64(i2));
6018
6019 return "llill";
6020}
6021
florian55085f82012-11-21 00:36:55 +00006022static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006023s390_irgen_LLGTR(UChar r1, UChar r2)
6024{
6025 put_gpr_dw0(r1, unop(Iop_32Uto64, binop(Iop_And32, get_gpr_w1(r2),
6026 mkU32(2147483647))));
6027
6028 return "llgtr";
6029}
6030
florian55085f82012-11-21 00:36:55 +00006031static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006032s390_irgen_LLGT(UChar r1, IRTemp op2addr)
6033{
6034 put_gpr_dw0(r1, unop(Iop_32Uto64, binop(Iop_And32, load(Ity_I32,
6035 mkexpr(op2addr)), mkU32(2147483647))));
6036
6037 return "llgt";
6038}
6039
florian55085f82012-11-21 00:36:55 +00006040static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006041s390_irgen_LNR(UChar r1, UChar r2)
6042{
6043 IRTemp op2 = newTemp(Ity_I32);
6044 IRTemp result = newTemp(Ity_I32);
6045
6046 assign(op2, get_gpr_w1(r2));
6047 assign(result, mkite(binop(Iop_CmpLE32S, mkexpr(op2), mkU32(0)), mkexpr(op2),
6048 binop(Iop_Sub32, mkU32(0), mkexpr(op2))));
6049 put_gpr_w1(r1, mkexpr(result));
6050 s390_cc_thunk_putS(S390_CC_OP_BITWISE, result);
6051
6052 return "lnr";
6053}
6054
florian55085f82012-11-21 00:36:55 +00006055static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006056s390_irgen_LNGR(UChar r1, UChar r2)
6057{
6058 IRTemp op2 = newTemp(Ity_I64);
6059 IRTemp result = newTemp(Ity_I64);
6060
6061 assign(op2, get_gpr_dw0(r2));
6062 assign(result, mkite(binop(Iop_CmpLE64S, mkexpr(op2), mkU64(0)), mkexpr(op2),
6063 binop(Iop_Sub64, mkU64(0), mkexpr(op2))));
6064 put_gpr_dw0(r1, mkexpr(result));
6065 s390_cc_thunk_putS(S390_CC_OP_BITWISE, result);
6066
6067 return "lngr";
6068}
6069
florian55085f82012-11-21 00:36:55 +00006070static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006071s390_irgen_LNGFR(UChar r1, UChar r2 __attribute__((unused)))
6072{
6073 IRTemp op2 = newTemp(Ity_I64);
6074 IRTemp result = newTemp(Ity_I64);
6075
6076 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r1)));
6077 assign(result, mkite(binop(Iop_CmpLE64S, mkexpr(op2), mkU64(0)), mkexpr(op2),
6078 binop(Iop_Sub64, mkU64(0), mkexpr(op2))));
6079 put_gpr_dw0(r1, mkexpr(result));
6080 s390_cc_thunk_putS(S390_CC_OP_BITWISE, result);
6081
6082 return "lngfr";
6083}
6084
florian55085f82012-11-21 00:36:55 +00006085static const HChar *
sewardjd7bde722011-04-05 13:19:33 +00006086s390_irgen_LOCR(UChar m3, UChar r1, UChar r2)
6087{
florian6820ba52012-07-26 02:01:50 +00006088 next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0)));
sewardjd7bde722011-04-05 13:19:33 +00006089 put_gpr_w1(r1, get_gpr_w1(r2));
6090
6091 return "locr";
6092}
6093
florian55085f82012-11-21 00:36:55 +00006094static const HChar *
sewardjd7bde722011-04-05 13:19:33 +00006095s390_irgen_LOCGR(UChar m3, UChar r1, UChar r2)
6096{
florian6820ba52012-07-26 02:01:50 +00006097 next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0)));
sewardjd7bde722011-04-05 13:19:33 +00006098 put_gpr_dw0(r1, get_gpr_dw0(r2));
6099
6100 return "locgr";
6101}
6102
florian55085f82012-11-21 00:36:55 +00006103static const HChar *
sewardjd7bde722011-04-05 13:19:33 +00006104s390_irgen_LOC(UChar r1, IRTemp op2addr)
6105{
6106 /* condition is checked in format handler */
6107 put_gpr_w1(r1, load(Ity_I32, mkexpr(op2addr)));
6108
6109 return "loc";
6110}
6111
florian55085f82012-11-21 00:36:55 +00006112static const HChar *
sewardjd7bde722011-04-05 13:19:33 +00006113s390_irgen_LOCG(UChar r1, IRTemp op2addr)
6114{
6115 /* condition is checked in format handler */
6116 put_gpr_dw0(r1, load(Ity_I64, mkexpr(op2addr)));
6117
6118 return "locg";
6119}
6120
florian55085f82012-11-21 00:36:55 +00006121static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006122s390_irgen_LPQ(UChar r1, IRTemp op2addr)
6123{
6124 put_gpr_dw0(r1, load(Ity_I64, mkexpr(op2addr)));
6125 put_gpr_dw0(r1 + 1, load(Ity_I64, binop(Iop_Add64, mkexpr(op2addr), mkU64(8))
6126 ));
6127
6128 return "lpq";
6129}
6130
florian55085f82012-11-21 00:36:55 +00006131static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006132s390_irgen_LPR(UChar r1, UChar r2)
6133{
6134 IRTemp op2 = newTemp(Ity_I32);
6135 IRTemp result = newTemp(Ity_I32);
6136
6137 assign(op2, get_gpr_w1(r2));
6138 assign(result, mkite(binop(Iop_CmpLT32S, mkexpr(op2), mkU32(0)),
6139 binop(Iop_Sub32, mkU32(0), mkexpr(op2)), mkexpr(op2)));
6140 put_gpr_w1(r1, mkexpr(result));
6141 s390_cc_thunk_putS(S390_CC_OP_LOAD_POSITIVE_32, op2);
6142
6143 return "lpr";
6144}
6145
florian55085f82012-11-21 00:36:55 +00006146static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006147s390_irgen_LPGR(UChar r1, UChar r2)
6148{
6149 IRTemp op2 = newTemp(Ity_I64);
6150 IRTemp result = newTemp(Ity_I64);
6151
6152 assign(op2, get_gpr_dw0(r2));
6153 assign(result, mkite(binop(Iop_CmpLT64S, mkexpr(op2), mkU64(0)),
6154 binop(Iop_Sub64, mkU64(0), mkexpr(op2)), mkexpr(op2)));
6155 put_gpr_dw0(r1, mkexpr(result));
6156 s390_cc_thunk_putS(S390_CC_OP_LOAD_POSITIVE_64, op2);
6157
6158 return "lpgr";
6159}
6160
florian55085f82012-11-21 00:36:55 +00006161static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006162s390_irgen_LPGFR(UChar r1, UChar r2)
6163{
6164 IRTemp op2 = newTemp(Ity_I64);
6165 IRTemp result = newTemp(Ity_I64);
6166
6167 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
6168 assign(result, mkite(binop(Iop_CmpLT64S, mkexpr(op2), mkU64(0)),
6169 binop(Iop_Sub64, mkU64(0), mkexpr(op2)), mkexpr(op2)));
6170 put_gpr_dw0(r1, mkexpr(result));
6171 s390_cc_thunk_putS(S390_CC_OP_LOAD_POSITIVE_64, op2);
6172
6173 return "lpgfr";
6174}
6175
florian55085f82012-11-21 00:36:55 +00006176static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006177s390_irgen_LRVR(UChar r1, UChar r2)
6178{
6179 IRTemp b0 = newTemp(Ity_I8);
6180 IRTemp b1 = newTemp(Ity_I8);
6181 IRTemp b2 = newTemp(Ity_I8);
6182 IRTemp b3 = newTemp(Ity_I8);
6183
6184 assign(b3, get_gpr_b7(r2));
6185 assign(b2, get_gpr_b6(r2));
6186 assign(b1, get_gpr_b5(r2));
6187 assign(b0, get_gpr_b4(r2));
6188 put_gpr_b4(r1, mkexpr(b3));
6189 put_gpr_b5(r1, mkexpr(b2));
6190 put_gpr_b6(r1, mkexpr(b1));
6191 put_gpr_b7(r1, mkexpr(b0));
6192
6193 return "lrvr";
6194}
6195
florian55085f82012-11-21 00:36:55 +00006196static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006197s390_irgen_LRVGR(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 IRTemp b4 = newTemp(Ity_I8);
6204 IRTemp b5 = newTemp(Ity_I8);
6205 IRTemp b6 = newTemp(Ity_I8);
6206 IRTemp b7 = newTemp(Ity_I8);
6207
6208 assign(b7, get_gpr_b7(r2));
6209 assign(b6, get_gpr_b6(r2));
6210 assign(b5, get_gpr_b5(r2));
6211 assign(b4, get_gpr_b4(r2));
6212 assign(b3, get_gpr_b3(r2));
6213 assign(b2, get_gpr_b2(r2));
6214 assign(b1, get_gpr_b1(r2));
6215 assign(b0, get_gpr_b0(r2));
6216 put_gpr_b0(r1, mkexpr(b7));
6217 put_gpr_b1(r1, mkexpr(b6));
6218 put_gpr_b2(r1, mkexpr(b5));
6219 put_gpr_b3(r1, mkexpr(b4));
6220 put_gpr_b4(r1, mkexpr(b3));
6221 put_gpr_b5(r1, mkexpr(b2));
6222 put_gpr_b6(r1, mkexpr(b1));
6223 put_gpr_b7(r1, mkexpr(b0));
6224
6225 return "lrvgr";
6226}
6227
florian55085f82012-11-21 00:36:55 +00006228static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006229s390_irgen_LRVH(UChar r1, IRTemp op2addr)
6230{
6231 IRTemp op2 = newTemp(Ity_I16);
6232
6233 assign(op2, load(Ity_I16, mkexpr(op2addr)));
6234 put_gpr_b6(r1, unop(Iop_16to8, mkexpr(op2)));
6235 put_gpr_b7(r1, unop(Iop_16HIto8, mkexpr(op2)));
6236
6237 return "lrvh";
6238}
6239
florian55085f82012-11-21 00:36:55 +00006240static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006241s390_irgen_LRV(UChar r1, IRTemp op2addr)
6242{
6243 IRTemp op2 = newTemp(Ity_I32);
6244
6245 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6246 put_gpr_b4(r1, unop(Iop_32to8, binop(Iop_And32, mkexpr(op2), mkU32(255))));
6247 put_gpr_b5(r1, unop(Iop_32to8, binop(Iop_And32, binop(Iop_Shr32, mkexpr(op2),
6248 mkU8(8)), mkU32(255))));
6249 put_gpr_b6(r1, unop(Iop_32to8, binop(Iop_And32, binop(Iop_Shr32, mkexpr(op2),
6250 mkU8(16)), mkU32(255))));
6251 put_gpr_b7(r1, unop(Iop_32to8, binop(Iop_And32, binop(Iop_Shr32, mkexpr(op2),
6252 mkU8(24)), mkU32(255))));
6253
6254 return "lrv";
6255}
6256
florian55085f82012-11-21 00:36:55 +00006257static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006258s390_irgen_LRVG(UChar r1, IRTemp op2addr)
6259{
6260 IRTemp op2 = newTemp(Ity_I64);
6261
6262 assign(op2, load(Ity_I64, mkexpr(op2addr)));
6263 put_gpr_b0(r1, unop(Iop_64to8, binop(Iop_And64, mkexpr(op2), mkU64(255))));
6264 put_gpr_b1(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6265 mkU8(8)), mkU64(255))));
6266 put_gpr_b2(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6267 mkU8(16)), mkU64(255))));
6268 put_gpr_b3(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6269 mkU8(24)), mkU64(255))));
6270 put_gpr_b4(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6271 mkU8(32)), mkU64(255))));
6272 put_gpr_b5(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6273 mkU8(40)), mkU64(255))));
6274 put_gpr_b6(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6275 mkU8(48)), mkU64(255))));
6276 put_gpr_b7(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6277 mkU8(56)), mkU64(255))));
6278
6279 return "lrvg";
6280}
6281
florian55085f82012-11-21 00:36:55 +00006282static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006283s390_irgen_MVHHI(UShort i2, IRTemp op1addr)
6284{
6285 store(mkexpr(op1addr), mkU16(i2));
6286
6287 return "mvhhi";
6288}
6289
florian55085f82012-11-21 00:36:55 +00006290static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006291s390_irgen_MVHI(UShort i2, IRTemp op1addr)
6292{
6293 store(mkexpr(op1addr), mkU32((UInt)(Int)(Short)i2));
6294
6295 return "mvhi";
6296}
6297
florian55085f82012-11-21 00:36:55 +00006298static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006299s390_irgen_MVGHI(UShort i2, IRTemp op1addr)
6300{
6301 store(mkexpr(op1addr), mkU64((ULong)(Long)(Short)i2));
6302
6303 return "mvghi";
6304}
6305
florian55085f82012-11-21 00:36:55 +00006306static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006307s390_irgen_MVI(UChar i2, IRTemp op1addr)
6308{
6309 store(mkexpr(op1addr), mkU8(i2));
6310
6311 return "mvi";
6312}
6313
florian55085f82012-11-21 00:36:55 +00006314static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006315s390_irgen_MVIY(UChar i2, IRTemp op1addr)
6316{
6317 store(mkexpr(op1addr), mkU8(i2));
6318
6319 return "mviy";
6320}
6321
florian55085f82012-11-21 00:36:55 +00006322static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006323s390_irgen_MR(UChar r1, UChar r2)
6324{
6325 IRTemp op1 = newTemp(Ity_I32);
6326 IRTemp op2 = newTemp(Ity_I32);
6327 IRTemp result = newTemp(Ity_I64);
6328
6329 assign(op1, get_gpr_w1(r1 + 1));
6330 assign(op2, get_gpr_w1(r2));
6331 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6332 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6333 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6334
6335 return "mr";
6336}
6337
florian55085f82012-11-21 00:36:55 +00006338static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006339s390_irgen_M(UChar r1, IRTemp op2addr)
6340{
6341 IRTemp op1 = newTemp(Ity_I32);
6342 IRTemp op2 = newTemp(Ity_I32);
6343 IRTemp result = newTemp(Ity_I64);
6344
6345 assign(op1, get_gpr_w1(r1 + 1));
6346 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6347 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6348 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6349 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6350
6351 return "m";
6352}
6353
florian55085f82012-11-21 00:36:55 +00006354static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006355s390_irgen_MFY(UChar r1, IRTemp op2addr)
6356{
6357 IRTemp op1 = newTemp(Ity_I32);
6358 IRTemp op2 = newTemp(Ity_I32);
6359 IRTemp result = newTemp(Ity_I64);
6360
6361 assign(op1, get_gpr_w1(r1 + 1));
6362 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6363 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6364 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6365 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6366
6367 return "mfy";
6368}
6369
florian55085f82012-11-21 00:36:55 +00006370static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006371s390_irgen_MH(UChar r1, IRTemp op2addr)
6372{
6373 IRTemp op1 = newTemp(Ity_I32);
6374 IRTemp op2 = newTemp(Ity_I16);
6375 IRTemp result = newTemp(Ity_I64);
6376
6377 assign(op1, get_gpr_w1(r1));
6378 assign(op2, load(Ity_I16, mkexpr(op2addr)));
6379 assign(result, binop(Iop_MullS32, mkexpr(op1), unop(Iop_16Sto32, mkexpr(op2))
6380 ));
6381 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6382
6383 return "mh";
6384}
6385
florian55085f82012-11-21 00:36:55 +00006386static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006387s390_irgen_MHY(UChar r1, IRTemp op2addr)
6388{
6389 IRTemp op1 = newTemp(Ity_I32);
6390 IRTemp op2 = newTemp(Ity_I16);
6391 IRTemp result = newTemp(Ity_I64);
6392
6393 assign(op1, get_gpr_w1(r1));
6394 assign(op2, load(Ity_I16, mkexpr(op2addr)));
6395 assign(result, binop(Iop_MullS32, mkexpr(op1), unop(Iop_16Sto32, mkexpr(op2))
6396 ));
6397 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6398
6399 return "mhy";
6400}
6401
florian55085f82012-11-21 00:36:55 +00006402static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006403s390_irgen_MHI(UChar r1, UShort i2)
6404{
6405 IRTemp op1 = newTemp(Ity_I32);
6406 Short op2;
6407 IRTemp result = newTemp(Ity_I64);
6408
6409 assign(op1, get_gpr_w1(r1));
6410 op2 = (Short)i2;
6411 assign(result, binop(Iop_MullS32, mkexpr(op1), unop(Iop_16Sto32,
6412 mkU16((UShort)op2))));
6413 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6414
6415 return "mhi";
6416}
6417
florian55085f82012-11-21 00:36:55 +00006418static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006419s390_irgen_MGHI(UChar r1, UShort i2)
6420{
6421 IRTemp op1 = newTemp(Ity_I64);
6422 Short op2;
6423 IRTemp result = newTemp(Ity_I128);
6424
6425 assign(op1, get_gpr_dw0(r1));
6426 op2 = (Short)i2;
6427 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_16Sto64,
6428 mkU16((UShort)op2))));
6429 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6430
6431 return "mghi";
6432}
6433
florian55085f82012-11-21 00:36:55 +00006434static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006435s390_irgen_MLR(UChar r1, UChar r2)
6436{
6437 IRTemp op1 = newTemp(Ity_I32);
6438 IRTemp op2 = newTemp(Ity_I32);
6439 IRTemp result = newTemp(Ity_I64);
6440
6441 assign(op1, get_gpr_w1(r1 + 1));
6442 assign(op2, get_gpr_w1(r2));
6443 assign(result, binop(Iop_MullU32, mkexpr(op1), mkexpr(op2)));
6444 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6445 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6446
6447 return "mlr";
6448}
6449
florian55085f82012-11-21 00:36:55 +00006450static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006451s390_irgen_MLGR(UChar r1, UChar r2)
6452{
6453 IRTemp op1 = newTemp(Ity_I64);
6454 IRTemp op2 = newTemp(Ity_I64);
6455 IRTemp result = newTemp(Ity_I128);
6456
6457 assign(op1, get_gpr_dw0(r1 + 1));
6458 assign(op2, get_gpr_dw0(r2));
6459 assign(result, binop(Iop_MullU64, mkexpr(op1), mkexpr(op2)));
6460 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result)));
6461 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result)));
6462
6463 return "mlgr";
6464}
6465
florian55085f82012-11-21 00:36:55 +00006466static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006467s390_irgen_ML(UChar r1, IRTemp op2addr)
6468{
6469 IRTemp op1 = newTemp(Ity_I32);
6470 IRTemp op2 = newTemp(Ity_I32);
6471 IRTemp result = newTemp(Ity_I64);
6472
6473 assign(op1, get_gpr_w1(r1 + 1));
6474 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6475 assign(result, binop(Iop_MullU32, mkexpr(op1), mkexpr(op2)));
6476 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6477 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6478
6479 return "ml";
6480}
6481
florian55085f82012-11-21 00:36:55 +00006482static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006483s390_irgen_MLG(UChar r1, IRTemp op2addr)
6484{
6485 IRTemp op1 = newTemp(Ity_I64);
6486 IRTemp op2 = newTemp(Ity_I64);
6487 IRTemp result = newTemp(Ity_I128);
6488
6489 assign(op1, get_gpr_dw0(r1 + 1));
6490 assign(op2, load(Ity_I64, mkexpr(op2addr)));
6491 assign(result, binop(Iop_MullU64, mkexpr(op1), mkexpr(op2)));
6492 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result)));
6493 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result)));
6494
6495 return "mlg";
6496}
6497
florian55085f82012-11-21 00:36:55 +00006498static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006499s390_irgen_MSR(UChar r1, UChar r2)
6500{
6501 IRTemp op1 = newTemp(Ity_I32);
6502 IRTemp op2 = newTemp(Ity_I32);
6503 IRTemp result = newTemp(Ity_I64);
6504
6505 assign(op1, get_gpr_w1(r1));
6506 assign(op2, get_gpr_w1(r2));
6507 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6508 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6509
6510 return "msr";
6511}
6512
florian55085f82012-11-21 00:36:55 +00006513static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006514s390_irgen_MSGR(UChar r1, UChar r2)
6515{
6516 IRTemp op1 = newTemp(Ity_I64);
6517 IRTemp op2 = newTemp(Ity_I64);
6518 IRTemp result = newTemp(Ity_I128);
6519
6520 assign(op1, get_gpr_dw0(r1));
6521 assign(op2, get_gpr_dw0(r2));
6522 assign(result, binop(Iop_MullS64, mkexpr(op1), mkexpr(op2)));
6523 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6524
6525 return "msgr";
6526}
6527
florian55085f82012-11-21 00:36:55 +00006528static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006529s390_irgen_MSGFR(UChar r1, UChar r2)
6530{
6531 IRTemp op1 = newTemp(Ity_I64);
6532 IRTemp op2 = newTemp(Ity_I32);
6533 IRTemp result = newTemp(Ity_I128);
6534
6535 assign(op1, get_gpr_dw0(r1));
6536 assign(op2, get_gpr_w1(r2));
6537 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_32Sto64, mkexpr(op2))
6538 ));
6539 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6540
6541 return "msgfr";
6542}
6543
florian55085f82012-11-21 00:36:55 +00006544static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006545s390_irgen_MS(UChar r1, IRTemp op2addr)
6546{
6547 IRTemp op1 = newTemp(Ity_I32);
6548 IRTemp op2 = newTemp(Ity_I32);
6549 IRTemp result = newTemp(Ity_I64);
6550
6551 assign(op1, get_gpr_w1(r1));
6552 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6553 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6554 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6555
6556 return "ms";
6557}
6558
florian55085f82012-11-21 00:36:55 +00006559static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006560s390_irgen_MSY(UChar r1, IRTemp op2addr)
6561{
6562 IRTemp op1 = newTemp(Ity_I32);
6563 IRTemp op2 = newTemp(Ity_I32);
6564 IRTemp result = newTemp(Ity_I64);
6565
6566 assign(op1, get_gpr_w1(r1));
6567 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6568 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6569 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6570
6571 return "msy";
6572}
6573
florian55085f82012-11-21 00:36:55 +00006574static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006575s390_irgen_MSG(UChar r1, IRTemp op2addr)
6576{
6577 IRTemp op1 = newTemp(Ity_I64);
6578 IRTemp op2 = newTemp(Ity_I64);
6579 IRTemp result = newTemp(Ity_I128);
6580
6581 assign(op1, get_gpr_dw0(r1));
6582 assign(op2, load(Ity_I64, mkexpr(op2addr)));
6583 assign(result, binop(Iop_MullS64, mkexpr(op1), mkexpr(op2)));
6584 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6585
6586 return "msg";
6587}
6588
florian55085f82012-11-21 00:36:55 +00006589static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006590s390_irgen_MSGF(UChar r1, IRTemp op2addr)
6591{
6592 IRTemp op1 = newTemp(Ity_I64);
6593 IRTemp op2 = newTemp(Ity_I32);
6594 IRTemp result = newTemp(Ity_I128);
6595
6596 assign(op1, get_gpr_dw0(r1));
6597 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6598 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_32Sto64, mkexpr(op2))
6599 ));
6600 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6601
6602 return "msgf";
6603}
6604
florian55085f82012-11-21 00:36:55 +00006605static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006606s390_irgen_MSFI(UChar r1, UInt i2)
6607{
6608 IRTemp op1 = newTemp(Ity_I32);
6609 Int op2;
6610 IRTemp result = newTemp(Ity_I64);
6611
6612 assign(op1, get_gpr_w1(r1));
6613 op2 = (Int)i2;
6614 assign(result, binop(Iop_MullS32, mkexpr(op1), mkU32((UInt)op2)));
6615 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6616
6617 return "msfi";
6618}
6619
florian55085f82012-11-21 00:36:55 +00006620static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006621s390_irgen_MSGFI(UChar r1, UInt i2)
6622{
6623 IRTemp op1 = newTemp(Ity_I64);
6624 Int op2;
6625 IRTemp result = newTemp(Ity_I128);
6626
6627 assign(op1, get_gpr_dw0(r1));
6628 op2 = (Int)i2;
6629 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_32Sto64, mkU32((UInt)
6630 op2))));
6631 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6632
6633 return "msgfi";
6634}
6635
florian55085f82012-11-21 00:36:55 +00006636static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006637s390_irgen_OR(UChar r1, UChar r2)
6638{
6639 IRTemp op1 = newTemp(Ity_I32);
6640 IRTemp op2 = newTemp(Ity_I32);
6641 IRTemp result = newTemp(Ity_I32);
6642
6643 assign(op1, get_gpr_w1(r1));
6644 assign(op2, get_gpr_w1(r2));
6645 assign(result, binop(Iop_Or32, mkexpr(op1), mkexpr(op2)));
6646 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6647 put_gpr_w1(r1, mkexpr(result));
6648
6649 return "or";
6650}
6651
florian55085f82012-11-21 00:36:55 +00006652static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006653s390_irgen_OGR(UChar r1, UChar r2)
6654{
6655 IRTemp op1 = newTemp(Ity_I64);
6656 IRTemp op2 = newTemp(Ity_I64);
6657 IRTemp result = newTemp(Ity_I64);
6658
6659 assign(op1, get_gpr_dw0(r1));
6660 assign(op2, get_gpr_dw0(r2));
6661 assign(result, binop(Iop_Or64, mkexpr(op1), mkexpr(op2)));
6662 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6663 put_gpr_dw0(r1, mkexpr(result));
6664
6665 return "ogr";
6666}
6667
florian55085f82012-11-21 00:36:55 +00006668static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006669s390_irgen_ORK(UChar r3, UChar r1, UChar r2)
6670{
6671 IRTemp op2 = newTemp(Ity_I32);
6672 IRTemp op3 = newTemp(Ity_I32);
6673 IRTemp result = newTemp(Ity_I32);
6674
6675 assign(op2, get_gpr_w1(r2));
6676 assign(op3, get_gpr_w1(r3));
6677 assign(result, binop(Iop_Or32, mkexpr(op2), mkexpr(op3)));
6678 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6679 put_gpr_w1(r1, mkexpr(result));
6680
6681 return "ork";
6682}
6683
florian55085f82012-11-21 00:36:55 +00006684static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006685s390_irgen_OGRK(UChar r3, UChar r1, UChar r2)
6686{
6687 IRTemp op2 = newTemp(Ity_I64);
6688 IRTemp op3 = newTemp(Ity_I64);
6689 IRTemp result = newTemp(Ity_I64);
6690
6691 assign(op2, get_gpr_dw0(r2));
6692 assign(op3, get_gpr_dw0(r3));
6693 assign(result, binop(Iop_Or64, mkexpr(op2), mkexpr(op3)));
6694 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6695 put_gpr_dw0(r1, mkexpr(result));
6696
6697 return "ogrk";
6698}
6699
florian55085f82012-11-21 00:36:55 +00006700static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006701s390_irgen_O(UChar r1, IRTemp op2addr)
6702{
6703 IRTemp op1 = newTemp(Ity_I32);
6704 IRTemp op2 = newTemp(Ity_I32);
6705 IRTemp result = newTemp(Ity_I32);
6706
6707 assign(op1, get_gpr_w1(r1));
6708 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6709 assign(result, binop(Iop_Or32, mkexpr(op1), mkexpr(op2)));
6710 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6711 put_gpr_w1(r1, mkexpr(result));
6712
6713 return "o";
6714}
6715
florian55085f82012-11-21 00:36:55 +00006716static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006717s390_irgen_OY(UChar r1, IRTemp op2addr)
6718{
6719 IRTemp op1 = newTemp(Ity_I32);
6720 IRTemp op2 = newTemp(Ity_I32);
6721 IRTemp result = newTemp(Ity_I32);
6722
6723 assign(op1, get_gpr_w1(r1));
6724 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6725 assign(result, binop(Iop_Or32, mkexpr(op1), mkexpr(op2)));
6726 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6727 put_gpr_w1(r1, mkexpr(result));
6728
6729 return "oy";
6730}
6731
florian55085f82012-11-21 00:36:55 +00006732static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006733s390_irgen_OG(UChar r1, IRTemp op2addr)
6734{
6735 IRTemp op1 = newTemp(Ity_I64);
6736 IRTemp op2 = newTemp(Ity_I64);
6737 IRTemp result = newTemp(Ity_I64);
6738
6739 assign(op1, get_gpr_dw0(r1));
6740 assign(op2, load(Ity_I64, mkexpr(op2addr)));
6741 assign(result, binop(Iop_Or64, mkexpr(op1), mkexpr(op2)));
6742 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6743 put_gpr_dw0(r1, mkexpr(result));
6744
6745 return "og";
6746}
6747
florian55085f82012-11-21 00:36:55 +00006748static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006749s390_irgen_OI(UChar i2, IRTemp op1addr)
6750{
6751 IRTemp op1 = newTemp(Ity_I8);
6752 UChar op2;
6753 IRTemp result = newTemp(Ity_I8);
6754
6755 assign(op1, load(Ity_I8, mkexpr(op1addr)));
6756 op2 = i2;
6757 assign(result, binop(Iop_Or8, mkexpr(op1), mkU8(op2)));
6758 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6759 store(mkexpr(op1addr), mkexpr(result));
6760
6761 return "oi";
6762}
6763
florian55085f82012-11-21 00:36:55 +00006764static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006765s390_irgen_OIY(UChar i2, IRTemp op1addr)
6766{
6767 IRTemp op1 = newTemp(Ity_I8);
6768 UChar op2;
6769 IRTemp result = newTemp(Ity_I8);
6770
6771 assign(op1, load(Ity_I8, mkexpr(op1addr)));
6772 op2 = i2;
6773 assign(result, binop(Iop_Or8, mkexpr(op1), mkU8(op2)));
6774 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6775 store(mkexpr(op1addr), mkexpr(result));
6776
6777 return "oiy";
6778}
6779
florian55085f82012-11-21 00:36:55 +00006780static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006781s390_irgen_OIHF(UChar r1, UInt i2)
6782{
6783 IRTemp op1 = newTemp(Ity_I32);
6784 UInt op2;
6785 IRTemp result = newTemp(Ity_I32);
6786
6787 assign(op1, get_gpr_w0(r1));
6788 op2 = i2;
6789 assign(result, binop(Iop_Or32, mkexpr(op1), mkU32(op2)));
6790 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6791 put_gpr_w0(r1, mkexpr(result));
6792
6793 return "oihf";
6794}
6795
florian55085f82012-11-21 00:36:55 +00006796static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006797s390_irgen_OIHH(UChar r1, UShort i2)
6798{
6799 IRTemp op1 = newTemp(Ity_I16);
6800 UShort op2;
6801 IRTemp result = newTemp(Ity_I16);
6802
6803 assign(op1, get_gpr_hw0(r1));
6804 op2 = i2;
6805 assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
6806 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6807 put_gpr_hw0(r1, mkexpr(result));
6808
6809 return "oihh";
6810}
6811
florian55085f82012-11-21 00:36:55 +00006812static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006813s390_irgen_OIHL(UChar r1, UShort i2)
6814{
6815 IRTemp op1 = newTemp(Ity_I16);
6816 UShort op2;
6817 IRTemp result = newTemp(Ity_I16);
6818
6819 assign(op1, get_gpr_hw1(r1));
6820 op2 = i2;
6821 assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
6822 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6823 put_gpr_hw1(r1, mkexpr(result));
6824
6825 return "oihl";
6826}
6827
florian55085f82012-11-21 00:36:55 +00006828static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006829s390_irgen_OILF(UChar r1, UInt i2)
6830{
6831 IRTemp op1 = newTemp(Ity_I32);
6832 UInt op2;
6833 IRTemp result = newTemp(Ity_I32);
6834
6835 assign(op1, get_gpr_w1(r1));
6836 op2 = i2;
6837 assign(result, binop(Iop_Or32, mkexpr(op1), mkU32(op2)));
6838 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6839 put_gpr_w1(r1, mkexpr(result));
6840
6841 return "oilf";
6842}
6843
florian55085f82012-11-21 00:36:55 +00006844static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006845s390_irgen_OILH(UChar r1, UShort i2)
6846{
6847 IRTemp op1 = newTemp(Ity_I16);
6848 UShort op2;
6849 IRTemp result = newTemp(Ity_I16);
6850
6851 assign(op1, get_gpr_hw2(r1));
6852 op2 = i2;
6853 assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
6854 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6855 put_gpr_hw2(r1, mkexpr(result));
6856
6857 return "oilh";
6858}
6859
florian55085f82012-11-21 00:36:55 +00006860static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006861s390_irgen_OILL(UChar r1, UShort i2)
6862{
6863 IRTemp op1 = newTemp(Ity_I16);
6864 UShort op2;
6865 IRTemp result = newTemp(Ity_I16);
6866
6867 assign(op1, get_gpr_hw3(r1));
6868 op2 = i2;
6869 assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
6870 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6871 put_gpr_hw3(r1, mkexpr(result));
6872
6873 return "oill";
6874}
6875
florian55085f82012-11-21 00:36:55 +00006876static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006877s390_irgen_PFD(void)
6878{
6879
6880 return "pfd";
6881}
6882
florian55085f82012-11-21 00:36:55 +00006883static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006884s390_irgen_PFDRL(void)
6885{
6886
6887 return "pfdrl";
6888}
6889
florian55085f82012-11-21 00:36:55 +00006890static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006891s390_irgen_RLL(UChar r1, UChar r3, IRTemp op2addr)
6892{
6893 IRTemp amount = newTemp(Ity_I64);
6894 IRTemp op = newTemp(Ity_I32);
6895
6896 assign(amount, binop(Iop_And64, mkexpr(op2addr), mkU64(31)));
6897 assign(op, get_gpr_w1(r3));
6898 put_gpr_w1(r1, binop(Iop_Or32, binop(Iop_Shl32, mkexpr(op), unop(Iop_64to8,
6899 mkexpr(amount))), binop(Iop_Shr32, mkexpr(op), unop(Iop_64to8,
6900 binop(Iop_Sub64, mkU64(32), mkexpr(amount))))));
6901
6902 return "rll";
6903}
6904
florian55085f82012-11-21 00:36:55 +00006905static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006906s390_irgen_RLLG(UChar r1, UChar r3, IRTemp op2addr)
6907{
6908 IRTemp amount = newTemp(Ity_I64);
6909 IRTemp op = newTemp(Ity_I64);
6910
6911 assign(amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
6912 assign(op, get_gpr_dw0(r3));
6913 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(op), unop(Iop_64to8,
6914 mkexpr(amount))), binop(Iop_Shr64, mkexpr(op), unop(Iop_64to8,
6915 binop(Iop_Sub64, mkU64(64), mkexpr(amount))))));
6916
6917 return "rllg";
6918}
6919
florian55085f82012-11-21 00:36:55 +00006920static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006921s390_irgen_RNSBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
6922{
6923 UChar from;
6924 UChar to;
6925 UChar rot;
6926 UChar t_bit;
6927 ULong mask;
6928 ULong maskc;
6929 IRTemp result = newTemp(Ity_I64);
6930 IRTemp op2 = newTemp(Ity_I64);
6931
6932 from = i3 & 63;
6933 to = i4 & 63;
6934 rot = i5 & 63;
6935 t_bit = i3 & 128;
6936 assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
6937 get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
6938 mkU8(64 - rot))));
6939 if (from <= to) {
6940 mask = ~0ULL;
6941 mask = (mask >> from) & (mask << (63 - to));
6942 maskc = ~mask;
6943 } else {
6944 maskc = ~0ULL;
6945 maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
6946 mask = ~maskc;
6947 }
6948 assign(result, binop(Iop_And64, binop(Iop_And64, get_gpr_dw0(r1), mkexpr(op2)
6949 ), mkU64(mask)));
6950 if (t_bit == 0) {
6951 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
6952 mkU64(maskc)), mkexpr(result)));
6953 }
6954 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6955
6956 return "rnsbg";
6957}
6958
florian55085f82012-11-21 00:36:55 +00006959static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006960s390_irgen_RXSBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
6961{
6962 UChar from;
6963 UChar to;
6964 UChar rot;
6965 UChar t_bit;
6966 ULong mask;
6967 ULong maskc;
6968 IRTemp result = newTemp(Ity_I64);
6969 IRTemp op2 = newTemp(Ity_I64);
6970
6971 from = i3 & 63;
6972 to = i4 & 63;
6973 rot = i5 & 63;
6974 t_bit = i3 & 128;
6975 assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
6976 get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
6977 mkU8(64 - rot))));
6978 if (from <= to) {
6979 mask = ~0ULL;
6980 mask = (mask >> from) & (mask << (63 - to));
6981 maskc = ~mask;
6982 } else {
6983 maskc = ~0ULL;
6984 maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
6985 mask = ~maskc;
6986 }
6987 assign(result, binop(Iop_And64, binop(Iop_Xor64, get_gpr_dw0(r1), mkexpr(op2)
6988 ), mkU64(mask)));
6989 if (t_bit == 0) {
6990 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
6991 mkU64(maskc)), mkexpr(result)));
6992 }
6993 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6994
6995 return "rxsbg";
6996}
6997
florian55085f82012-11-21 00:36:55 +00006998static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006999s390_irgen_ROSBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
7000{
7001 UChar from;
7002 UChar to;
7003 UChar rot;
7004 UChar t_bit;
7005 ULong mask;
7006 ULong maskc;
7007 IRTemp result = newTemp(Ity_I64);
7008 IRTemp op2 = newTemp(Ity_I64);
7009
7010 from = i3 & 63;
7011 to = i4 & 63;
7012 rot = i5 & 63;
7013 t_bit = i3 & 128;
7014 assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
7015 get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
7016 mkU8(64 - rot))));
7017 if (from <= to) {
7018 mask = ~0ULL;
7019 mask = (mask >> from) & (mask << (63 - to));
7020 maskc = ~mask;
7021 } else {
7022 maskc = ~0ULL;
7023 maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
7024 mask = ~maskc;
7025 }
7026 assign(result, binop(Iop_And64, binop(Iop_Or64, get_gpr_dw0(r1), mkexpr(op2)
7027 ), mkU64(mask)));
7028 if (t_bit == 0) {
7029 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
7030 mkU64(maskc)), mkexpr(result)));
7031 }
7032 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7033
7034 return "rosbg";
7035}
7036
florian55085f82012-11-21 00:36:55 +00007037static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007038s390_irgen_RISBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
7039{
7040 UChar from;
7041 UChar to;
7042 UChar rot;
7043 UChar z_bit;
7044 ULong mask;
7045 ULong maskc;
7046 IRTemp op2 = newTemp(Ity_I64);
7047 IRTemp result = newTemp(Ity_I64);
7048
7049 from = i3 & 63;
7050 to = i4 & 63;
7051 rot = i5 & 63;
7052 z_bit = i4 & 128;
7053 assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
7054 get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
7055 mkU8(64 - rot))));
7056 if (from <= to) {
7057 mask = ~0ULL;
7058 mask = (mask >> from) & (mask << (63 - to));
7059 maskc = ~mask;
7060 } else {
7061 maskc = ~0ULL;
7062 maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
7063 mask = ~maskc;
7064 }
7065 if (z_bit == 0) {
7066 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
7067 mkU64(maskc)), binop(Iop_And64, mkexpr(op2), mkU64(mask))));
7068 } else {
7069 put_gpr_dw0(r1, binop(Iop_And64, mkexpr(op2), mkU64(mask)));
7070 }
7071 assign(result, get_gpr_dw0(r1));
7072 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
7073
7074 return "risbg";
7075}
7076
florian55085f82012-11-21 00:36:55 +00007077static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007078s390_irgen_SAR(UChar r1, UChar r2)
7079{
7080 put_ar_w0(r1, get_gpr_w1(r2));
sewardj7ee97522011-05-09 21:45:04 +00007081 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00007082 s390_disasm(ENC3(MNM, AR, GPR), "sar", r1, r2);
7083
7084 return "sar";
7085}
7086
florian55085f82012-11-21 00:36:55 +00007087static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007088s390_irgen_SLDA(UChar r1, IRTemp op2addr)
7089{
7090 IRTemp p1 = newTemp(Ity_I64);
7091 IRTemp p2 = newTemp(Ity_I64);
7092 IRTemp op = newTemp(Ity_I64);
7093 IRTemp result = newTemp(Ity_I64);
florian417b22d2012-07-13 13:41:41 +00007094 ULong sign_mask;
sewardj2019a972011-03-07 16:04:07 +00007095 IRTemp shift_amount = newTemp(Ity_I64);
7096
7097 assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
7098 assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
7099 assign(op, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1), mkU8(32)), mkexpr(p2)
7100 ));
7101 sign_mask = 1ULL << 63;
7102 assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7103 assign(result, binop(Iop_Or64, binop(Iop_And64, binop(Iop_Shl64, mkexpr(op),
florian417b22d2012-07-13 13:41:41 +00007104 unop(Iop_64to8, mkexpr(shift_amount))), mkU64(~sign_mask)),
7105 binop(Iop_And64, mkexpr(op), mkU64(sign_mask))));
sewardj2019a972011-03-07 16:04:07 +00007106 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
7107 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
7108 s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_64, op, shift_amount);
7109
7110 return "slda";
7111}
7112
florian55085f82012-11-21 00:36:55 +00007113static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007114s390_irgen_SLDL(UChar r1, IRTemp op2addr)
7115{
7116 IRTemp p1 = newTemp(Ity_I64);
7117 IRTemp p2 = newTemp(Ity_I64);
7118 IRTemp result = newTemp(Ity_I64);
7119
7120 assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
7121 assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
7122 assign(result, binop(Iop_Shl64, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1),
7123 mkU8(32)), mkexpr(p2)), unop(Iop_64to8, binop(Iop_And64,
7124 mkexpr(op2addr), mkU64(63)))));
7125 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
7126 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
7127
7128 return "sldl";
7129}
7130
florian55085f82012-11-21 00:36:55 +00007131static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007132s390_irgen_SLA(UChar r1, IRTemp op2addr)
7133{
7134 IRTemp uop = newTemp(Ity_I32);
7135 IRTemp result = newTemp(Ity_I32);
7136 UInt sign_mask;
7137 IRTemp shift_amount = newTemp(Ity_I64);
7138 IRTemp op = newTemp(Ity_I32);
7139
7140 assign(op, get_gpr_w1(r1));
7141 assign(uop, get_gpr_w1(r1));
7142 sign_mask = 2147483648U;
7143 assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7144 assign(result, binop(Iop_Or32, binop(Iop_And32, binop(Iop_Shl32, mkexpr(uop),
7145 unop(Iop_64to8, mkexpr(shift_amount))), mkU32(~sign_mask)),
7146 binop(Iop_And32, mkexpr(uop), mkU32(sign_mask))));
7147 put_gpr_w1(r1, mkexpr(result));
7148 s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_32, op, shift_amount);
7149
7150 return "sla";
7151}
7152
florian55085f82012-11-21 00:36:55 +00007153static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007154s390_irgen_SLAK(UChar r1, UChar r3, IRTemp op2addr)
7155{
7156 IRTemp uop = newTemp(Ity_I32);
7157 IRTemp result = newTemp(Ity_I32);
7158 UInt sign_mask;
7159 IRTemp shift_amount = newTemp(Ity_I64);
7160 IRTemp op = newTemp(Ity_I32);
7161
7162 assign(op, get_gpr_w1(r3));
7163 assign(uop, get_gpr_w1(r3));
7164 sign_mask = 2147483648U;
7165 assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7166 assign(result, binop(Iop_Or32, binop(Iop_And32, binop(Iop_Shl32, mkexpr(uop),
7167 unop(Iop_64to8, mkexpr(shift_amount))), mkU32(~sign_mask)),
7168 binop(Iop_And32, mkexpr(uop), mkU32(sign_mask))));
7169 put_gpr_w1(r1, mkexpr(result));
7170 s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_32, op, shift_amount);
7171
7172 return "slak";
7173}
7174
florian55085f82012-11-21 00:36:55 +00007175static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007176s390_irgen_SLAG(UChar r1, UChar r3, IRTemp op2addr)
7177{
7178 IRTemp uop = newTemp(Ity_I64);
7179 IRTemp result = newTemp(Ity_I64);
7180 ULong sign_mask;
7181 IRTemp shift_amount = newTemp(Ity_I64);
7182 IRTemp op = newTemp(Ity_I64);
7183
7184 assign(op, get_gpr_dw0(r3));
7185 assign(uop, get_gpr_dw0(r3));
7186 sign_mask = 9223372036854775808ULL;
7187 assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7188 assign(result, binop(Iop_Or64, binop(Iop_And64, binop(Iop_Shl64, mkexpr(uop),
7189 unop(Iop_64to8, mkexpr(shift_amount))), mkU64(~sign_mask)),
7190 binop(Iop_And64, mkexpr(uop), mkU64(sign_mask))));
7191 put_gpr_dw0(r1, mkexpr(result));
7192 s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_64, op, shift_amount);
7193
7194 return "slag";
7195}
7196
florian55085f82012-11-21 00:36:55 +00007197static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007198s390_irgen_SLL(UChar r1, IRTemp op2addr)
7199{
7200 put_gpr_w1(r1, binop(Iop_Shl32, get_gpr_w1(r1), unop(Iop_64to8,
7201 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
7202
7203 return "sll";
7204}
7205
florian55085f82012-11-21 00:36:55 +00007206static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007207s390_irgen_SLLK(UChar r1, UChar r3, IRTemp op2addr)
7208{
7209 put_gpr_w1(r1, binop(Iop_Shl32, get_gpr_w1(r3), unop(Iop_64to8,
7210 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
7211
7212 return "sllk";
7213}
7214
florian55085f82012-11-21 00:36:55 +00007215static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007216s390_irgen_SLLG(UChar r1, UChar r3, IRTemp op2addr)
7217{
7218 put_gpr_dw0(r1, binop(Iop_Shl64, get_gpr_dw0(r3), unop(Iop_64to8,
7219 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
7220
7221 return "sllg";
7222}
7223
florian55085f82012-11-21 00:36:55 +00007224static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007225s390_irgen_SRDA(UChar r1, IRTemp op2addr)
7226{
7227 IRTemp p1 = newTemp(Ity_I64);
7228 IRTemp p2 = newTemp(Ity_I64);
7229 IRTemp result = newTemp(Ity_I64);
7230
7231 assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
7232 assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
7233 assign(result, binop(Iop_Sar64, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1),
7234 mkU8(32)), mkexpr(p2)), unop(Iop_64to8, binop(Iop_And64,
7235 mkexpr(op2addr), mkU64(63)))));
7236 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
7237 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
7238 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7239
7240 return "srda";
7241}
7242
florian55085f82012-11-21 00:36:55 +00007243static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007244s390_irgen_SRDL(UChar r1, IRTemp op2addr)
7245{
7246 IRTemp p1 = newTemp(Ity_I64);
7247 IRTemp p2 = newTemp(Ity_I64);
7248 IRTemp result = newTemp(Ity_I64);
7249
7250 assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
7251 assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
7252 assign(result, binop(Iop_Shr64, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1),
7253 mkU8(32)), mkexpr(p2)), unop(Iop_64to8, binop(Iop_And64,
7254 mkexpr(op2addr), mkU64(63)))));
7255 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
7256 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
7257
7258 return "srdl";
7259}
7260
florian55085f82012-11-21 00:36:55 +00007261static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007262s390_irgen_SRA(UChar r1, IRTemp op2addr)
7263{
7264 IRTemp result = newTemp(Ity_I32);
7265 IRTemp op = newTemp(Ity_I32);
7266
7267 assign(op, get_gpr_w1(r1));
7268 assign(result, binop(Iop_Sar32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7269 mkexpr(op2addr), mkU64(63)))));
7270 put_gpr_w1(r1, mkexpr(result));
7271 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7272
7273 return "sra";
7274}
7275
florian55085f82012-11-21 00:36:55 +00007276static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007277s390_irgen_SRAK(UChar r1, UChar r3, IRTemp op2addr)
7278{
7279 IRTemp result = newTemp(Ity_I32);
7280 IRTemp op = newTemp(Ity_I32);
7281
7282 assign(op, get_gpr_w1(r3));
7283 assign(result, binop(Iop_Sar32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7284 mkexpr(op2addr), mkU64(63)))));
7285 put_gpr_w1(r1, mkexpr(result));
7286 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7287
7288 return "srak";
7289}
7290
florian55085f82012-11-21 00:36:55 +00007291static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007292s390_irgen_SRAG(UChar r1, UChar r3, IRTemp op2addr)
7293{
7294 IRTemp result = newTemp(Ity_I64);
7295 IRTemp op = newTemp(Ity_I64);
7296
7297 assign(op, get_gpr_dw0(r3));
7298 assign(result, binop(Iop_Sar64, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7299 mkexpr(op2addr), mkU64(63)))));
7300 put_gpr_dw0(r1, mkexpr(result));
7301 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7302
7303 return "srag";
7304}
7305
florian55085f82012-11-21 00:36:55 +00007306static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007307s390_irgen_SRL(UChar r1, IRTemp op2addr)
7308{
7309 IRTemp op = newTemp(Ity_I32);
7310
7311 assign(op, get_gpr_w1(r1));
7312 put_gpr_w1(r1, binop(Iop_Shr32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7313 mkexpr(op2addr), mkU64(63)))));
7314
7315 return "srl";
7316}
7317
florian55085f82012-11-21 00:36:55 +00007318static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007319s390_irgen_SRLK(UChar r1, UChar r3, IRTemp op2addr)
7320{
7321 IRTemp op = newTemp(Ity_I32);
7322
7323 assign(op, get_gpr_w1(r3));
7324 put_gpr_w1(r1, binop(Iop_Shr32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7325 mkexpr(op2addr), mkU64(63)))));
7326
7327 return "srlk";
7328}
7329
florian55085f82012-11-21 00:36:55 +00007330static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007331s390_irgen_SRLG(UChar r1, UChar r3, IRTemp op2addr)
7332{
7333 IRTemp op = newTemp(Ity_I64);
7334
7335 assign(op, get_gpr_dw0(r3));
7336 put_gpr_dw0(r1, binop(Iop_Shr64, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7337 mkexpr(op2addr), mkU64(63)))));
7338
7339 return "srlg";
7340}
7341
florian55085f82012-11-21 00:36:55 +00007342static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007343s390_irgen_ST(UChar r1, IRTemp op2addr)
7344{
7345 store(mkexpr(op2addr), get_gpr_w1(r1));
7346
7347 return "st";
7348}
7349
florian55085f82012-11-21 00:36:55 +00007350static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007351s390_irgen_STY(UChar r1, IRTemp op2addr)
7352{
7353 store(mkexpr(op2addr), get_gpr_w1(r1));
7354
7355 return "sty";
7356}
7357
florian55085f82012-11-21 00:36:55 +00007358static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007359s390_irgen_STG(UChar r1, IRTemp op2addr)
7360{
7361 store(mkexpr(op2addr), get_gpr_dw0(r1));
7362
7363 return "stg";
7364}
7365
florian55085f82012-11-21 00:36:55 +00007366static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007367s390_irgen_STRL(UChar r1, UInt i2)
7368{
7369 store(mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)),
7370 get_gpr_w1(r1));
7371
7372 return "strl";
7373}
7374
florian55085f82012-11-21 00:36:55 +00007375static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007376s390_irgen_STGRL(UChar r1, UInt i2)
7377{
7378 store(mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)),
7379 get_gpr_dw0(r1));
7380
7381 return "stgrl";
7382}
7383
florian55085f82012-11-21 00:36:55 +00007384static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007385s390_irgen_STC(UChar r1, IRTemp op2addr)
7386{
7387 store(mkexpr(op2addr), get_gpr_b7(r1));
7388
7389 return "stc";
7390}
7391
florian55085f82012-11-21 00:36:55 +00007392static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007393s390_irgen_STCY(UChar r1, IRTemp op2addr)
7394{
7395 store(mkexpr(op2addr), get_gpr_b7(r1));
7396
7397 return "stcy";
7398}
7399
florian55085f82012-11-21 00:36:55 +00007400static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007401s390_irgen_STCH(UChar r1, IRTemp op2addr)
7402{
7403 store(mkexpr(op2addr), get_gpr_b3(r1));
7404
7405 return "stch";
7406}
7407
florian55085f82012-11-21 00:36:55 +00007408static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007409s390_irgen_STCM(UChar r1, UChar r3, IRTemp op2addr)
7410{
7411 UChar mask;
7412 UChar n;
7413
7414 mask = (UChar)r3;
7415 n = 0;
7416 if ((mask & 8) != 0) {
7417 store(mkexpr(op2addr), get_gpr_b4(r1));
7418 n = n + 1;
7419 }
7420 if ((mask & 4) != 0) {
7421 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b5(r1));
7422 n = n + 1;
7423 }
7424 if ((mask & 2) != 0) {
7425 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b6(r1));
7426 n = n + 1;
7427 }
7428 if ((mask & 1) != 0) {
7429 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b7(r1));
7430 }
7431
7432 return "stcm";
7433}
7434
florian55085f82012-11-21 00:36:55 +00007435static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007436s390_irgen_STCMY(UChar r1, UChar r3, IRTemp op2addr)
7437{
7438 UChar mask;
7439 UChar n;
7440
7441 mask = (UChar)r3;
7442 n = 0;
7443 if ((mask & 8) != 0) {
7444 store(mkexpr(op2addr), get_gpr_b4(r1));
7445 n = n + 1;
7446 }
7447 if ((mask & 4) != 0) {
7448 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b5(r1));
7449 n = n + 1;
7450 }
7451 if ((mask & 2) != 0) {
7452 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b6(r1));
7453 n = n + 1;
7454 }
7455 if ((mask & 1) != 0) {
7456 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b7(r1));
7457 }
7458
7459 return "stcmy";
7460}
7461
florian55085f82012-11-21 00:36:55 +00007462static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007463s390_irgen_STCMH(UChar r1, UChar r3, IRTemp op2addr)
7464{
7465 UChar mask;
7466 UChar n;
7467
7468 mask = (UChar)r3;
7469 n = 0;
7470 if ((mask & 8) != 0) {
7471 store(mkexpr(op2addr), get_gpr_b0(r1));
7472 n = n + 1;
7473 }
7474 if ((mask & 4) != 0) {
7475 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b1(r1));
7476 n = n + 1;
7477 }
7478 if ((mask & 2) != 0) {
7479 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b2(r1));
7480 n = n + 1;
7481 }
7482 if ((mask & 1) != 0) {
7483 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b3(r1));
7484 }
7485
7486 return "stcmh";
7487}
7488
florian55085f82012-11-21 00:36:55 +00007489static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007490s390_irgen_STH(UChar r1, IRTemp op2addr)
7491{
7492 store(mkexpr(op2addr), get_gpr_hw3(r1));
7493
7494 return "sth";
7495}
7496
florian55085f82012-11-21 00:36:55 +00007497static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007498s390_irgen_STHY(UChar r1, IRTemp op2addr)
7499{
7500 store(mkexpr(op2addr), get_gpr_hw3(r1));
7501
7502 return "sthy";
7503}
7504
florian55085f82012-11-21 00:36:55 +00007505static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007506s390_irgen_STHRL(UChar r1, UInt i2)
7507{
7508 store(mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)),
7509 get_gpr_hw3(r1));
7510
7511 return "sthrl";
7512}
7513
florian55085f82012-11-21 00:36:55 +00007514static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007515s390_irgen_STHH(UChar r1, IRTemp op2addr)
7516{
7517 store(mkexpr(op2addr), get_gpr_hw1(r1));
7518
7519 return "sthh";
7520}
7521
florian55085f82012-11-21 00:36:55 +00007522static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007523s390_irgen_STFH(UChar r1, IRTemp op2addr)
7524{
7525 store(mkexpr(op2addr), get_gpr_w0(r1));
7526
7527 return "stfh";
7528}
7529
florian55085f82012-11-21 00:36:55 +00007530static const HChar *
sewardjd7bde722011-04-05 13:19:33 +00007531s390_irgen_STOC(UChar r1, IRTemp op2addr)
7532{
7533 /* condition is checked in format handler */
7534 store(mkexpr(op2addr), get_gpr_w1(r1));
7535
7536 return "stoc";
7537}
7538
florian55085f82012-11-21 00:36:55 +00007539static const HChar *
sewardjd7bde722011-04-05 13:19:33 +00007540s390_irgen_STOCG(UChar r1, IRTemp op2addr)
7541{
7542 /* condition is checked in format handler */
7543 store(mkexpr(op2addr), get_gpr_dw0(r1));
7544
7545 return "stocg";
7546}
7547
florian55085f82012-11-21 00:36:55 +00007548static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007549s390_irgen_STPQ(UChar r1, IRTemp op2addr)
7550{
7551 store(mkexpr(op2addr), get_gpr_dw0(r1));
7552 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(8)), get_gpr_dw0(r1 + 1));
7553
7554 return "stpq";
7555}
7556
florian55085f82012-11-21 00:36:55 +00007557static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007558s390_irgen_STRVH(UChar r1, IRTemp op2addr)
7559{
7560 store(mkexpr(op2addr), get_gpr_b7(r1));
7561 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(1)), get_gpr_b6(r1));
7562
7563 return "strvh";
7564}
7565
florian55085f82012-11-21 00:36:55 +00007566static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007567s390_irgen_STRV(UChar r1, IRTemp op2addr)
7568{
7569 store(mkexpr(op2addr), get_gpr_b7(r1));
7570 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(1)), get_gpr_b6(r1));
7571 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(2)), get_gpr_b5(r1));
7572 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(3)), get_gpr_b4(r1));
7573
7574 return "strv";
7575}
7576
florian55085f82012-11-21 00:36:55 +00007577static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007578s390_irgen_STRVG(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 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(2)), get_gpr_b5(r1));
7583 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(3)), get_gpr_b4(r1));
7584 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(4)), get_gpr_b3(r1));
7585 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(5)), get_gpr_b2(r1));
7586 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(6)), get_gpr_b1(r1));
7587 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(7)), get_gpr_b0(r1));
7588
7589 return "strvg";
7590}
7591
florian55085f82012-11-21 00:36:55 +00007592static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007593s390_irgen_SR(UChar r1, UChar r2)
7594{
7595 IRTemp op1 = newTemp(Ity_I32);
7596 IRTemp op2 = newTemp(Ity_I32);
7597 IRTemp result = newTemp(Ity_I32);
7598
7599 assign(op1, get_gpr_w1(r1));
7600 assign(op2, get_gpr_w1(r2));
7601 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7602 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
7603 put_gpr_w1(r1, mkexpr(result));
7604
7605 return "sr";
7606}
7607
florian55085f82012-11-21 00:36:55 +00007608static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007609s390_irgen_SGR(UChar r1, UChar r2)
7610{
7611 IRTemp op1 = newTemp(Ity_I64);
7612 IRTemp op2 = newTemp(Ity_I64);
7613 IRTemp result = newTemp(Ity_I64);
7614
7615 assign(op1, get_gpr_dw0(r1));
7616 assign(op2, get_gpr_dw0(r2));
7617 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7618 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
7619 put_gpr_dw0(r1, mkexpr(result));
7620
7621 return "sgr";
7622}
7623
florian55085f82012-11-21 00:36:55 +00007624static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007625s390_irgen_SGFR(UChar r1, UChar r2)
7626{
7627 IRTemp op1 = newTemp(Ity_I64);
7628 IRTemp op2 = newTemp(Ity_I64);
7629 IRTemp result = newTemp(Ity_I64);
7630
7631 assign(op1, get_gpr_dw0(r1));
7632 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
7633 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7634 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
7635 put_gpr_dw0(r1, mkexpr(result));
7636
7637 return "sgfr";
7638}
7639
florian55085f82012-11-21 00:36:55 +00007640static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007641s390_irgen_SRK(UChar r3, UChar r1, UChar r2)
7642{
7643 IRTemp op2 = newTemp(Ity_I32);
7644 IRTemp op3 = newTemp(Ity_I32);
7645 IRTemp result = newTemp(Ity_I32);
7646
7647 assign(op2, get_gpr_w1(r2));
7648 assign(op3, get_gpr_w1(r3));
7649 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
7650 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op2, op3);
7651 put_gpr_w1(r1, mkexpr(result));
7652
7653 return "srk";
7654}
7655
florian55085f82012-11-21 00:36:55 +00007656static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007657s390_irgen_SGRK(UChar r3, UChar r1, UChar r2)
7658{
7659 IRTemp op2 = newTemp(Ity_I64);
7660 IRTemp op3 = newTemp(Ity_I64);
7661 IRTemp result = newTemp(Ity_I64);
7662
7663 assign(op2, get_gpr_dw0(r2));
7664 assign(op3, get_gpr_dw0(r3));
7665 assign(result, binop(Iop_Sub64, mkexpr(op2), mkexpr(op3)));
7666 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op2, op3);
7667 put_gpr_dw0(r1, mkexpr(result));
7668
7669 return "sgrk";
7670}
7671
florian55085f82012-11-21 00:36:55 +00007672static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007673s390_irgen_S(UChar r1, IRTemp op2addr)
7674{
7675 IRTemp op1 = newTemp(Ity_I32);
7676 IRTemp op2 = newTemp(Ity_I32);
7677 IRTemp result = newTemp(Ity_I32);
7678
7679 assign(op1, get_gpr_w1(r1));
7680 assign(op2, load(Ity_I32, mkexpr(op2addr)));
7681 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7682 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
7683 put_gpr_w1(r1, mkexpr(result));
7684
7685 return "s";
7686}
7687
florian55085f82012-11-21 00:36:55 +00007688static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007689s390_irgen_SY(UChar r1, IRTemp op2addr)
7690{
7691 IRTemp op1 = newTemp(Ity_I32);
7692 IRTemp op2 = newTemp(Ity_I32);
7693 IRTemp result = newTemp(Ity_I32);
7694
7695 assign(op1, get_gpr_w1(r1));
7696 assign(op2, load(Ity_I32, mkexpr(op2addr)));
7697 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7698 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
7699 put_gpr_w1(r1, mkexpr(result));
7700
7701 return "sy";
7702}
7703
florian55085f82012-11-21 00:36:55 +00007704static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007705s390_irgen_SG(UChar r1, IRTemp op2addr)
7706{
7707 IRTemp op1 = newTemp(Ity_I64);
7708 IRTemp op2 = newTemp(Ity_I64);
7709 IRTemp result = newTemp(Ity_I64);
7710
7711 assign(op1, get_gpr_dw0(r1));
7712 assign(op2, load(Ity_I64, mkexpr(op2addr)));
7713 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7714 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
7715 put_gpr_dw0(r1, mkexpr(result));
7716
7717 return "sg";
7718}
7719
florian55085f82012-11-21 00:36:55 +00007720static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007721s390_irgen_SGF(UChar r1, IRTemp op2addr)
7722{
7723 IRTemp op1 = newTemp(Ity_I64);
7724 IRTemp op2 = newTemp(Ity_I64);
7725 IRTemp result = newTemp(Ity_I64);
7726
7727 assign(op1, get_gpr_dw0(r1));
7728 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
7729 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7730 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
7731 put_gpr_dw0(r1, mkexpr(result));
7732
7733 return "sgf";
7734}
7735
florian55085f82012-11-21 00:36:55 +00007736static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007737s390_irgen_SH(UChar r1, IRTemp op2addr)
7738{
7739 IRTemp op1 = newTemp(Ity_I32);
7740 IRTemp op2 = newTemp(Ity_I32);
7741 IRTemp result = newTemp(Ity_I32);
7742
7743 assign(op1, get_gpr_w1(r1));
7744 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
7745 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7746 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
7747 put_gpr_w1(r1, mkexpr(result));
7748
7749 return "sh";
7750}
7751
florian55085f82012-11-21 00:36:55 +00007752static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007753s390_irgen_SHY(UChar r1, IRTemp op2addr)
7754{
7755 IRTemp op1 = newTemp(Ity_I32);
7756 IRTemp op2 = newTemp(Ity_I32);
7757 IRTemp result = newTemp(Ity_I32);
7758
7759 assign(op1, get_gpr_w1(r1));
7760 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
7761 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7762 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
7763 put_gpr_w1(r1, mkexpr(result));
7764
7765 return "shy";
7766}
7767
florian55085f82012-11-21 00:36:55 +00007768static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007769s390_irgen_SHHHR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
7770{
7771 IRTemp op2 = newTemp(Ity_I32);
7772 IRTemp op3 = newTemp(Ity_I32);
7773 IRTemp result = newTemp(Ity_I32);
7774
7775 assign(op2, get_gpr_w0(r1));
7776 assign(op3, get_gpr_w0(r2));
7777 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
7778 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op2, op3);
7779 put_gpr_w0(r1, mkexpr(result));
7780
7781 return "shhhr";
7782}
7783
florian55085f82012-11-21 00:36:55 +00007784static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007785s390_irgen_SHHLR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
7786{
7787 IRTemp op2 = newTemp(Ity_I32);
7788 IRTemp op3 = newTemp(Ity_I32);
7789 IRTemp result = newTemp(Ity_I32);
7790
7791 assign(op2, get_gpr_w0(r1));
7792 assign(op3, get_gpr_w1(r2));
7793 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
7794 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op2, op3);
7795 put_gpr_w0(r1, mkexpr(result));
7796
7797 return "shhlr";
7798}
7799
florian55085f82012-11-21 00:36:55 +00007800static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007801s390_irgen_SLR(UChar r1, UChar r2)
7802{
7803 IRTemp op1 = newTemp(Ity_I32);
7804 IRTemp op2 = newTemp(Ity_I32);
7805 IRTemp result = newTemp(Ity_I32);
7806
7807 assign(op1, get_gpr_w1(r1));
7808 assign(op2, get_gpr_w1(r2));
7809 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7810 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, op2);
7811 put_gpr_w1(r1, mkexpr(result));
7812
7813 return "slr";
7814}
7815
florian55085f82012-11-21 00:36:55 +00007816static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007817s390_irgen_SLGR(UChar r1, UChar r2)
7818{
7819 IRTemp op1 = newTemp(Ity_I64);
7820 IRTemp op2 = newTemp(Ity_I64);
7821 IRTemp result = newTemp(Ity_I64);
7822
7823 assign(op1, get_gpr_dw0(r1));
7824 assign(op2, get_gpr_dw0(r2));
7825 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7826 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
7827 put_gpr_dw0(r1, mkexpr(result));
7828
7829 return "slgr";
7830}
7831
florian55085f82012-11-21 00:36:55 +00007832static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007833s390_irgen_SLGFR(UChar r1, UChar r2)
7834{
7835 IRTemp op1 = newTemp(Ity_I64);
7836 IRTemp op2 = newTemp(Ity_I64);
7837 IRTemp result = newTemp(Ity_I64);
7838
7839 assign(op1, get_gpr_dw0(r1));
7840 assign(op2, unop(Iop_32Uto64, get_gpr_w1(r2)));
7841 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7842 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
7843 put_gpr_dw0(r1, mkexpr(result));
7844
7845 return "slgfr";
7846}
7847
florian55085f82012-11-21 00:36:55 +00007848static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007849s390_irgen_SLRK(UChar r3, UChar r1, UChar r2)
7850{
7851 IRTemp op2 = newTemp(Ity_I32);
7852 IRTemp op3 = newTemp(Ity_I32);
7853 IRTemp result = newTemp(Ity_I32);
7854
7855 assign(op2, get_gpr_w1(r2));
7856 assign(op3, get_gpr_w1(r3));
7857 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
7858 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op2, op3);
7859 put_gpr_w1(r1, mkexpr(result));
7860
7861 return "slrk";
7862}
7863
florian55085f82012-11-21 00:36:55 +00007864static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007865s390_irgen_SLGRK(UChar r3, UChar r1, UChar r2)
7866{
7867 IRTemp op2 = newTemp(Ity_I64);
7868 IRTemp op3 = newTemp(Ity_I64);
7869 IRTemp result = newTemp(Ity_I64);
7870
7871 assign(op2, get_gpr_dw0(r2));
7872 assign(op3, get_gpr_dw0(r3));
7873 assign(result, binop(Iop_Sub64, mkexpr(op2), mkexpr(op3)));
7874 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op2, op3);
7875 put_gpr_dw0(r1, mkexpr(result));
7876
7877 return "slgrk";
7878}
7879
florian55085f82012-11-21 00:36:55 +00007880static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007881s390_irgen_SL(UChar r1, IRTemp op2addr)
7882{
7883 IRTemp op1 = newTemp(Ity_I32);
7884 IRTemp op2 = newTemp(Ity_I32);
7885 IRTemp result = newTemp(Ity_I32);
7886
7887 assign(op1, get_gpr_w1(r1));
7888 assign(op2, load(Ity_I32, mkexpr(op2addr)));
7889 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7890 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, op2);
7891 put_gpr_w1(r1, mkexpr(result));
7892
7893 return "sl";
7894}
7895
florian55085f82012-11-21 00:36:55 +00007896static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007897s390_irgen_SLY(UChar r1, IRTemp op2addr)
7898{
7899 IRTemp op1 = newTemp(Ity_I32);
7900 IRTemp op2 = newTemp(Ity_I32);
7901 IRTemp result = newTemp(Ity_I32);
7902
7903 assign(op1, get_gpr_w1(r1));
7904 assign(op2, load(Ity_I32, mkexpr(op2addr)));
7905 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7906 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, op2);
7907 put_gpr_w1(r1, mkexpr(result));
7908
7909 return "sly";
7910}
7911
florian55085f82012-11-21 00:36:55 +00007912static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007913s390_irgen_SLG(UChar r1, IRTemp op2addr)
7914{
7915 IRTemp op1 = newTemp(Ity_I64);
7916 IRTemp op2 = newTemp(Ity_I64);
7917 IRTemp result = newTemp(Ity_I64);
7918
7919 assign(op1, get_gpr_dw0(r1));
7920 assign(op2, load(Ity_I64, mkexpr(op2addr)));
7921 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7922 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
7923 put_gpr_dw0(r1, mkexpr(result));
7924
7925 return "slg";
7926}
7927
florian55085f82012-11-21 00:36:55 +00007928static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007929s390_irgen_SLGF(UChar r1, IRTemp op2addr)
7930{
7931 IRTemp op1 = newTemp(Ity_I64);
7932 IRTemp op2 = newTemp(Ity_I64);
7933 IRTemp result = newTemp(Ity_I64);
7934
7935 assign(op1, get_gpr_dw0(r1));
7936 assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
7937 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7938 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
7939 put_gpr_dw0(r1, mkexpr(result));
7940
7941 return "slgf";
7942}
7943
florian55085f82012-11-21 00:36:55 +00007944static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007945s390_irgen_SLFI(UChar r1, UInt i2)
7946{
7947 IRTemp op1 = newTemp(Ity_I32);
7948 UInt op2;
7949 IRTemp result = newTemp(Ity_I32);
7950
7951 assign(op1, get_gpr_w1(r1));
7952 op2 = i2;
7953 assign(result, binop(Iop_Sub32, mkexpr(op1), mkU32(op2)));
7954 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, mktemp(Ity_I32,
7955 mkU32(op2)));
7956 put_gpr_w1(r1, mkexpr(result));
7957
7958 return "slfi";
7959}
7960
florian55085f82012-11-21 00:36:55 +00007961static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007962s390_irgen_SLGFI(UChar r1, UInt i2)
7963{
7964 IRTemp op1 = newTemp(Ity_I64);
7965 ULong op2;
7966 IRTemp result = newTemp(Ity_I64);
7967
7968 assign(op1, get_gpr_dw0(r1));
7969 op2 = (ULong)i2;
7970 assign(result, binop(Iop_Sub64, mkexpr(op1), mkU64(op2)));
7971 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, mktemp(Ity_I64,
7972 mkU64(op2)));
7973 put_gpr_dw0(r1, mkexpr(result));
7974
7975 return "slgfi";
7976}
7977
florian55085f82012-11-21 00:36:55 +00007978static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007979s390_irgen_SLHHHR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
7980{
7981 IRTemp op2 = newTemp(Ity_I32);
7982 IRTemp op3 = newTemp(Ity_I32);
7983 IRTemp result = newTemp(Ity_I32);
7984
7985 assign(op2, get_gpr_w0(r1));
7986 assign(op3, get_gpr_w0(r2));
7987 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
7988 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op2, op3);
7989 put_gpr_w0(r1, mkexpr(result));
7990
7991 return "slhhhr";
7992}
7993
florian55085f82012-11-21 00:36:55 +00007994static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007995s390_irgen_SLHHLR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
7996{
7997 IRTemp op2 = newTemp(Ity_I32);
7998 IRTemp op3 = newTemp(Ity_I32);
7999 IRTemp result = newTemp(Ity_I32);
8000
8001 assign(op2, get_gpr_w0(r1));
8002 assign(op3, get_gpr_w1(r2));
8003 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
8004 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op2, op3);
8005 put_gpr_w0(r1, mkexpr(result));
8006
8007 return "slhhlr";
8008}
8009
florian55085f82012-11-21 00:36:55 +00008010static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008011s390_irgen_SLBR(UChar r1, UChar r2)
8012{
8013 IRTemp op1 = newTemp(Ity_I32);
8014 IRTemp op2 = newTemp(Ity_I32);
8015 IRTemp result = newTemp(Ity_I32);
8016 IRTemp borrow_in = newTemp(Ity_I32);
8017
8018 assign(op1, get_gpr_w1(r1));
8019 assign(op2, get_gpr_w1(r2));
8020 assign(borrow_in, binop(Iop_Sub32, mkU32(1), binop(Iop_Shr32,
8021 s390_call_calculate_cc(), mkU8(1))));
8022 assign(result, binop(Iop_Sub32, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)),
8023 mkexpr(borrow_in)));
8024 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_32, op1, op2, borrow_in);
8025 put_gpr_w1(r1, mkexpr(result));
8026
8027 return "slbr";
8028}
8029
florian55085f82012-11-21 00:36:55 +00008030static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008031s390_irgen_SLBGR(UChar r1, UChar r2)
8032{
8033 IRTemp op1 = newTemp(Ity_I64);
8034 IRTemp op2 = newTemp(Ity_I64);
8035 IRTemp result = newTemp(Ity_I64);
8036 IRTemp borrow_in = newTemp(Ity_I64);
8037
8038 assign(op1, get_gpr_dw0(r1));
8039 assign(op2, get_gpr_dw0(r2));
8040 assign(borrow_in, unop(Iop_32Uto64, binop(Iop_Sub32, mkU32(1),
8041 binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)))));
8042 assign(result, binop(Iop_Sub64, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)),
8043 mkexpr(borrow_in)));
8044 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_64, op1, op2, borrow_in);
8045 put_gpr_dw0(r1, mkexpr(result));
8046
8047 return "slbgr";
8048}
8049
florian55085f82012-11-21 00:36:55 +00008050static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008051s390_irgen_SLB(UChar r1, IRTemp op2addr)
8052{
8053 IRTemp op1 = newTemp(Ity_I32);
8054 IRTemp op2 = newTemp(Ity_I32);
8055 IRTemp result = newTemp(Ity_I32);
8056 IRTemp borrow_in = newTemp(Ity_I32);
8057
8058 assign(op1, get_gpr_w1(r1));
8059 assign(op2, load(Ity_I32, mkexpr(op2addr)));
8060 assign(borrow_in, binop(Iop_Sub32, mkU32(1), binop(Iop_Shr32,
8061 s390_call_calculate_cc(), mkU8(1))));
8062 assign(result, binop(Iop_Sub32, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)),
8063 mkexpr(borrow_in)));
8064 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_32, op1, op2, borrow_in);
8065 put_gpr_w1(r1, mkexpr(result));
8066
8067 return "slb";
8068}
8069
florian55085f82012-11-21 00:36:55 +00008070static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008071s390_irgen_SLBG(UChar r1, IRTemp op2addr)
8072{
8073 IRTemp op1 = newTemp(Ity_I64);
8074 IRTemp op2 = newTemp(Ity_I64);
8075 IRTemp result = newTemp(Ity_I64);
8076 IRTemp borrow_in = newTemp(Ity_I64);
8077
8078 assign(op1, get_gpr_dw0(r1));
8079 assign(op2, load(Ity_I64, mkexpr(op2addr)));
8080 assign(borrow_in, unop(Iop_32Uto64, binop(Iop_Sub32, mkU32(1),
8081 binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)))));
8082 assign(result, binop(Iop_Sub64, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)),
8083 mkexpr(borrow_in)));
8084 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_64, op1, op2, borrow_in);
8085 put_gpr_dw0(r1, mkexpr(result));
8086
8087 return "slbg";
8088}
8089
florian55085f82012-11-21 00:36:55 +00008090static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008091s390_irgen_SVC(UChar i)
8092{
8093 IRTemp sysno = newTemp(Ity_I64);
8094
8095 if (i != 0) {
8096 assign(sysno, mkU64(i));
8097 } else {
8098 assign(sysno, unop(Iop_32Uto64, get_gpr_w1(1)));
8099 }
8100 system_call(mkexpr(sysno));
8101
8102 return "svc";
8103}
8104
florian55085f82012-11-21 00:36:55 +00008105static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008106s390_irgen_TM(UChar i2, IRTemp op1addr)
8107{
8108 UChar mask;
8109 IRTemp value = newTemp(Ity_I8);
8110
8111 mask = i2;
8112 assign(value, load(Ity_I8, mkexpr(op1addr)));
8113 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_8, value, mktemp(Ity_I8,
8114 mkU8(mask)));
8115
8116 return "tm";
8117}
8118
florian55085f82012-11-21 00:36:55 +00008119static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008120s390_irgen_TMY(UChar i2, IRTemp op1addr)
8121{
8122 UChar mask;
8123 IRTemp value = newTemp(Ity_I8);
8124
8125 mask = i2;
8126 assign(value, load(Ity_I8, mkexpr(op1addr)));
8127 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_8, value, mktemp(Ity_I8,
8128 mkU8(mask)));
8129
8130 return "tmy";
8131}
8132
florian55085f82012-11-21 00:36:55 +00008133static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008134s390_irgen_TMHH(UChar r1, UShort i2)
8135{
8136 UShort mask;
8137 IRTemp value = newTemp(Ity_I16);
8138
8139 mask = i2;
8140 assign(value, get_gpr_hw0(r1));
8141 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
8142 mkU16(mask)));
8143
8144 return "tmhh";
8145}
8146
florian55085f82012-11-21 00:36:55 +00008147static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008148s390_irgen_TMHL(UChar r1, UShort i2)
8149{
8150 UShort mask;
8151 IRTemp value = newTemp(Ity_I16);
8152
8153 mask = i2;
8154 assign(value, get_gpr_hw1(r1));
8155 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
8156 mkU16(mask)));
8157
8158 return "tmhl";
8159}
8160
florian55085f82012-11-21 00:36:55 +00008161static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008162s390_irgen_TMLH(UChar r1, UShort i2)
8163{
8164 UShort mask;
8165 IRTemp value = newTemp(Ity_I16);
8166
8167 mask = i2;
8168 assign(value, get_gpr_hw2(r1));
8169 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
8170 mkU16(mask)));
8171
8172 return "tmlh";
8173}
8174
florian55085f82012-11-21 00:36:55 +00008175static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008176s390_irgen_TMLL(UChar r1, UShort i2)
8177{
8178 UShort mask;
8179 IRTemp value = newTemp(Ity_I16);
8180
8181 mask = i2;
8182 assign(value, get_gpr_hw3(r1));
8183 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
8184 mkU16(mask)));
8185
8186 return "tmll";
8187}
8188
florian55085f82012-11-21 00:36:55 +00008189static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008190s390_irgen_EFPC(UChar r1)
8191{
8192 put_gpr_w1(r1, get_fpc_w0());
8193
8194 return "efpc";
8195}
8196
florian55085f82012-11-21 00:36:55 +00008197static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008198s390_irgen_LER(UChar r1, UChar r2)
8199{
8200 put_fpr_w0(r1, get_fpr_w0(r2));
8201
8202 return "ler";
8203}
8204
florian55085f82012-11-21 00:36:55 +00008205static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008206s390_irgen_LDR(UChar r1, UChar r2)
8207{
8208 put_fpr_dw0(r1, get_fpr_dw0(r2));
8209
8210 return "ldr";
8211}
8212
florian55085f82012-11-21 00:36:55 +00008213static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008214s390_irgen_LXR(UChar r1, UChar r2)
8215{
8216 put_fpr_dw0(r1, get_fpr_dw0(r2));
8217 put_fpr_dw0(r1 + 2, get_fpr_dw0(r2 + 2));
8218
8219 return "lxr";
8220}
8221
florian55085f82012-11-21 00:36:55 +00008222static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008223s390_irgen_LE(UChar r1, IRTemp op2addr)
8224{
8225 put_fpr_w0(r1, load(Ity_F32, mkexpr(op2addr)));
8226
8227 return "le";
8228}
8229
florian55085f82012-11-21 00:36:55 +00008230static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008231s390_irgen_LD(UChar r1, IRTemp op2addr)
8232{
8233 put_fpr_dw0(r1, load(Ity_F64, mkexpr(op2addr)));
8234
8235 return "ld";
8236}
8237
florian55085f82012-11-21 00:36:55 +00008238static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008239s390_irgen_LEY(UChar r1, IRTemp op2addr)
8240{
8241 put_fpr_w0(r1, load(Ity_F32, mkexpr(op2addr)));
8242
8243 return "ley";
8244}
8245
florian55085f82012-11-21 00:36:55 +00008246static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008247s390_irgen_LDY(UChar r1, IRTemp op2addr)
8248{
8249 put_fpr_dw0(r1, load(Ity_F64, mkexpr(op2addr)));
8250
8251 return "ldy";
8252}
8253
florian55085f82012-11-21 00:36:55 +00008254static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008255s390_irgen_LFPC(IRTemp op2addr)
8256{
8257 put_fpc_w0(load(Ity_I32, mkexpr(op2addr)));
8258
8259 return "lfpc";
8260}
8261
florian55085f82012-11-21 00:36:55 +00008262static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008263s390_irgen_LZER(UChar r1)
8264{
8265 put_fpr_w0(r1, mkF32i(0x0));
8266
8267 return "lzer";
8268}
8269
florian55085f82012-11-21 00:36:55 +00008270static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008271s390_irgen_LZDR(UChar r1)
8272{
8273 put_fpr_dw0(r1, mkF64i(0x0));
8274
8275 return "lzdr";
8276}
8277
florian55085f82012-11-21 00:36:55 +00008278static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008279s390_irgen_LZXR(UChar r1)
8280{
8281 put_fpr_dw0(r1, mkF64i(0x0));
8282 put_fpr_dw0(r1 + 2, mkF64i(0x0));
8283
8284 return "lzxr";
8285}
8286
florian55085f82012-11-21 00:36:55 +00008287static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008288s390_irgen_SRNM(IRTemp op2addr)
8289{
florianf0fa1be2012-09-18 20:24:38 +00008290 UInt input_mask, fpc_mask;
sewardj2019a972011-03-07 16:04:07 +00008291
florianf0fa1be2012-09-18 20:24:38 +00008292 input_mask = 3;
8293 fpc_mask = s390_host_has_fpext ? 7 : 3;
sewardj2019a972011-03-07 16:04:07 +00008294
florianf0fa1be2012-09-18 20:24:38 +00008295 put_fpc_w0(binop(Iop_Or32,
8296 binop(Iop_And32, get_fpc_w0(), mkU32(~fpc_mask)),
8297 binop(Iop_And32, unop(Iop_64to32, mkexpr(op2addr)),
8298 mkU32(input_mask))));
sewardj2019a972011-03-07 16:04:07 +00008299 return "srnm";
8300}
8301
florian55085f82012-11-21 00:36:55 +00008302static const HChar *
florianf0fa1be2012-09-18 20:24:38 +00008303s390_irgen_SRNMB(IRTemp op2addr)
8304{
8305 UInt input_mask, fpc_mask;
8306
8307 input_mask = 7;
8308 fpc_mask = 7;
8309
8310 put_fpc_w0(binop(Iop_Or32,
8311 binop(Iop_And32, get_fpc_w0(), mkU32(~fpc_mask)),
8312 binop(Iop_And32, unop(Iop_64to32, mkexpr(op2addr)),
8313 mkU32(input_mask))));
8314 return "srnmb";
8315}
8316
florian81a4bfe2012-09-20 01:25:28 +00008317static void
florianf0fa1be2012-09-18 20:24:38 +00008318s390_irgen_srnmb_wrapper(UChar b2, UShort d2)
8319{
8320 if (b2 == 0) { /* This is the typical case */
8321 if (d2 > 3) {
8322 if (s390_host_has_fpext && d2 == 7) {
8323 /* ok */
8324 } else {
8325 emulation_warning(EmWarn_S390X_invalid_rounding);
florian125e20d2012-10-07 15:42:37 +00008326 d2 = S390_FPC_BFP_ROUND_NEAREST_EVEN;
florianf0fa1be2012-09-18 20:24:38 +00008327 }
8328 }
8329 }
8330
8331 s390_format_S_RD(s390_irgen_SRNMB, b2, d2);
8332}
8333
8334
florian55085f82012-11-21 00:36:55 +00008335static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008336s390_irgen_SFPC(UChar r1)
8337{
8338 put_fpc_w0(get_gpr_w1(r1));
8339
8340 return "sfpc";
8341}
8342
florian55085f82012-11-21 00:36:55 +00008343static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008344s390_irgen_STE(UChar r1, IRTemp op2addr)
8345{
8346 store(mkexpr(op2addr), get_fpr_w0(r1));
8347
8348 return "ste";
8349}
8350
florian55085f82012-11-21 00:36:55 +00008351static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008352s390_irgen_STD(UChar r1, IRTemp op2addr)
8353{
8354 store(mkexpr(op2addr), get_fpr_dw0(r1));
8355
8356 return "std";
8357}
8358
florian55085f82012-11-21 00:36:55 +00008359static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008360s390_irgen_STEY(UChar r1, IRTemp op2addr)
8361{
8362 store(mkexpr(op2addr), get_fpr_w0(r1));
8363
8364 return "stey";
8365}
8366
florian55085f82012-11-21 00:36:55 +00008367static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008368s390_irgen_STDY(UChar r1, IRTemp op2addr)
8369{
8370 store(mkexpr(op2addr), get_fpr_dw0(r1));
8371
8372 return "stdy";
8373}
8374
florian55085f82012-11-21 00:36:55 +00008375static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008376s390_irgen_STFPC(IRTemp op2addr)
8377{
8378 store(mkexpr(op2addr), get_fpc_w0());
8379
8380 return "stfpc";
8381}
8382
florian55085f82012-11-21 00:36:55 +00008383static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008384s390_irgen_AEBR(UChar r1, UChar r2)
8385{
8386 IRTemp op1 = newTemp(Ity_F32);
8387 IRTemp op2 = newTemp(Ity_F32);
8388 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00008389 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008390
8391 assign(op1, get_fpr_w0(r1));
8392 assign(op2, get_fpr_w0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008393 assign(result, triop(Iop_AddF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008394 mkexpr(op2)));
8395 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
8396 put_fpr_w0(r1, mkexpr(result));
8397
8398 return "aebr";
8399}
8400
florian55085f82012-11-21 00:36:55 +00008401static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008402s390_irgen_ADBR(UChar r1, UChar r2)
8403{
8404 IRTemp op1 = newTemp(Ity_F64);
8405 IRTemp op2 = newTemp(Ity_F64);
8406 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00008407 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008408
8409 assign(op1, get_fpr_dw0(r1));
8410 assign(op2, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008411 assign(result, triop(Iop_AddF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008412 mkexpr(op2)));
8413 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
8414 put_fpr_dw0(r1, mkexpr(result));
8415
8416 return "adbr";
8417}
8418
florian55085f82012-11-21 00:36:55 +00008419static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008420s390_irgen_AEB(UChar r1, IRTemp op2addr)
8421{
8422 IRTemp op1 = newTemp(Ity_F32);
8423 IRTemp op2 = newTemp(Ity_F32);
8424 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00008425 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008426
8427 assign(op1, get_fpr_w0(r1));
8428 assign(op2, load(Ity_F32, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00008429 assign(result, triop(Iop_AddF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008430 mkexpr(op2)));
8431 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
8432 put_fpr_w0(r1, mkexpr(result));
8433
8434 return "aeb";
8435}
8436
florian55085f82012-11-21 00:36:55 +00008437static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008438s390_irgen_ADB(UChar r1, IRTemp op2addr)
8439{
8440 IRTemp op1 = newTemp(Ity_F64);
8441 IRTemp op2 = newTemp(Ity_F64);
8442 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00008443 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008444
8445 assign(op1, get_fpr_dw0(r1));
8446 assign(op2, load(Ity_F64, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00008447 assign(result, triop(Iop_AddF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008448 mkexpr(op2)));
8449 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
8450 put_fpr_dw0(r1, mkexpr(result));
8451
8452 return "adb";
8453}
8454
florian55085f82012-11-21 00:36:55 +00008455static const HChar *
florian4b8efad2012-09-02 18:07:08 +00008456s390_irgen_CEFBR(UChar m3, UChar m4 __attribute__((unused)),
8457 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008458{
florian125e20d2012-10-07 15:42:37 +00008459 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian4b8efad2012-09-02 18:07:08 +00008460 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +00008461 m3 = S390_BFP_ROUND_PER_FPC;
florian4b8efad2012-09-02 18:07:08 +00008462 }
sewardj2019a972011-03-07 16:04:07 +00008463 IRTemp op2 = newTemp(Ity_I32);
8464
8465 assign(op2, get_gpr_w1(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008466 put_fpr_w0(r1, binop(Iop_I32StoF32, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +00008467 mkexpr(op2)));
sewardj2019a972011-03-07 16:04:07 +00008468
8469 return "cefbr";
8470}
8471
florian55085f82012-11-21 00:36:55 +00008472static const HChar *
florian4b8efad2012-09-02 18:07:08 +00008473s390_irgen_CDFBR(UChar m3 __attribute__((unused)),
8474 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008475{
8476 IRTemp op2 = newTemp(Ity_I32);
8477
8478 assign(op2, get_gpr_w1(r2));
8479 put_fpr_dw0(r1, unop(Iop_I32StoF64, mkexpr(op2)));
8480
8481 return "cdfbr";
8482}
8483
florian55085f82012-11-21 00:36:55 +00008484static const HChar *
florian4b8efad2012-09-02 18:07:08 +00008485s390_irgen_CEGBR(UChar m3, UChar m4 __attribute__((unused)),
8486 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008487{
florian125e20d2012-10-07 15:42:37 +00008488 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian4b8efad2012-09-02 18:07:08 +00008489 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +00008490 m3 = S390_BFP_ROUND_PER_FPC;
florian4b8efad2012-09-02 18:07:08 +00008491 }
sewardj2019a972011-03-07 16:04:07 +00008492 IRTemp op2 = newTemp(Ity_I64);
8493
8494 assign(op2, get_gpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008495 put_fpr_w0(r1, binop(Iop_I64StoF32, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +00008496 mkexpr(op2)));
sewardj2019a972011-03-07 16:04:07 +00008497
8498 return "cegbr";
8499}
8500
florian55085f82012-11-21 00:36:55 +00008501static const HChar *
florian4b8efad2012-09-02 18:07:08 +00008502s390_irgen_CDGBR(UChar m3, UChar m4 __attribute__((unused)),
8503 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008504{
florian125e20d2012-10-07 15:42:37 +00008505 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian4b8efad2012-09-02 18:07:08 +00008506 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +00008507 m3 = S390_BFP_ROUND_PER_FPC;
florian4b8efad2012-09-02 18:07:08 +00008508 }
sewardj2019a972011-03-07 16:04:07 +00008509 IRTemp op2 = newTemp(Ity_I64);
8510
8511 assign(op2, get_gpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008512 put_fpr_dw0(r1, binop(Iop_I64StoF64, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +00008513 mkexpr(op2)));
sewardj2019a972011-03-07 16:04:07 +00008514
8515 return "cdgbr";
8516}
8517
florian55085f82012-11-21 00:36:55 +00008518static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00008519s390_irgen_CELFBR(UChar m3, UChar m4 __attribute__((unused)),
8520 UChar r1, UChar r2)
8521{
floriane75dafa2012-09-01 17:54:09 +00008522 if (! s390_host_has_fpext) {
8523 emulation_failure(EmFail_S390X_fpext);
8524 } else {
8525 IRTemp op2 = newTemp(Ity_I32);
florian1c8f7ff2012-09-01 00:12:11 +00008526
floriane75dafa2012-09-01 17:54:09 +00008527 assign(op2, get_gpr_w1(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008528 put_fpr_w0(r1, binop(Iop_I32UtoF32, mkexpr(encode_bfp_rounding_mode(m3)),
floriane75dafa2012-09-01 17:54:09 +00008529 mkexpr(op2)));
8530 }
florian1c8f7ff2012-09-01 00:12:11 +00008531 return "celfbr";
8532}
8533
florian55085f82012-11-21 00:36:55 +00008534static const HChar *
floriand2129202012-09-01 20:01:39 +00008535s390_irgen_CDLFBR(UChar m3 __attribute__((unused)),
8536 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
florian1c8f7ff2012-09-01 00:12:11 +00008537{
floriane75dafa2012-09-01 17:54:09 +00008538 if (! s390_host_has_fpext) {
8539 emulation_failure(EmFail_S390X_fpext);
8540 } else {
8541 IRTemp op2 = newTemp(Ity_I32);
florian1c8f7ff2012-09-01 00:12:11 +00008542
floriane75dafa2012-09-01 17:54:09 +00008543 assign(op2, get_gpr_w1(r2));
8544 put_fpr_dw0(r1, unop(Iop_I32UtoF64, mkexpr(op2)));
8545 }
florian1c8f7ff2012-09-01 00:12:11 +00008546 return "cdlfbr";
8547}
8548
florian55085f82012-11-21 00:36:55 +00008549static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00008550s390_irgen_CELGBR(UChar m3, UChar m4 __attribute__((unused)),
8551 UChar r1, UChar r2)
8552{
floriane75dafa2012-09-01 17:54:09 +00008553 if (! s390_host_has_fpext) {
8554 emulation_failure(EmFail_S390X_fpext);
8555 } else {
8556 IRTemp op2 = newTemp(Ity_I64);
florian1c8f7ff2012-09-01 00:12:11 +00008557
floriane75dafa2012-09-01 17:54:09 +00008558 assign(op2, get_gpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008559 put_fpr_w0(r1, binop(Iop_I64UtoF32, mkexpr(encode_bfp_rounding_mode(m3)),
floriane75dafa2012-09-01 17:54:09 +00008560 mkexpr(op2)));
8561 }
florian1c8f7ff2012-09-01 00:12:11 +00008562 return "celgbr";
8563}
8564
florian55085f82012-11-21 00:36:55 +00008565static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00008566s390_irgen_CDLGBR(UChar m3, UChar m4 __attribute__((unused)),
8567 UChar r1, UChar r2)
8568{
floriane75dafa2012-09-01 17:54:09 +00008569 if (! s390_host_has_fpext) {
8570 emulation_failure(EmFail_S390X_fpext);
8571 } else {
8572 IRTemp op2 = newTemp(Ity_I64);
florian1c8f7ff2012-09-01 00:12:11 +00008573
floriane75dafa2012-09-01 17:54:09 +00008574 assign(op2, get_gpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008575 put_fpr_dw0(r1, binop(Iop_I64UtoF64,
8576 mkexpr(encode_bfp_rounding_mode(m3)),
floriane75dafa2012-09-01 17:54:09 +00008577 mkexpr(op2)));
8578 }
florian1c8f7ff2012-09-01 00:12:11 +00008579 return "cdlgbr";
8580}
8581
florian55085f82012-11-21 00:36:55 +00008582static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00008583s390_irgen_CLFEBR(UChar m3, UChar m4 __attribute__((unused)),
8584 UChar r1, UChar r2)
8585{
floriane75dafa2012-09-01 17:54:09 +00008586 if (! s390_host_has_fpext) {
8587 emulation_failure(EmFail_S390X_fpext);
8588 } else {
8589 IRTemp op = newTemp(Ity_F32);
8590 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +00008591 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +00008592
floriane75dafa2012-09-01 17:54:09 +00008593 assign(op, get_fpr_w0(r2));
florian19e00772012-09-06 03:13:22 +00008594 assign(result, binop(Iop_F32toI32U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +00008595 mkexpr(op)));
8596 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008597 s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_UINT_32, op, rounding_mode);
floriane75dafa2012-09-01 17:54:09 +00008598 }
florian1c8f7ff2012-09-01 00:12:11 +00008599 return "clfebr";
8600}
8601
florian55085f82012-11-21 00:36:55 +00008602static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00008603s390_irgen_CLFDBR(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_F64);
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_dw0(r2));
florian19e00772012-09-06 03:13:22 +00008614 assign(result, binop(Iop_F64toI32U, 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_64_TO_UINT_32, op, rounding_mode);
floriane75dafa2012-09-01 17:54:09 +00008618 }
florian1c8f7ff2012-09-01 00:12:11 +00008619 return "clfdbr";
8620}
8621
florian55085f82012-11-21 00:36:55 +00008622static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00008623s390_irgen_CLGEBR(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_F32);
8630 IRTemp result = newTemp(Ity_I64);
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_w0(r2));
florian19e00772012-09-06 03:13:22 +00008634 assign(result, binop(Iop_F32toI64U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +00008635 mkexpr(op)));
8636 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008637 s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_UINT_64, op, rounding_mode);
floriane75dafa2012-09-01 17:54:09 +00008638 }
florian1c8f7ff2012-09-01 00:12:11 +00008639 return "clgebr";
8640}
8641
florian55085f82012-11-21 00:36:55 +00008642static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00008643s390_irgen_CLGDBR(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_F64);
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_dw0(r2));
florian19e00772012-09-06 03:13:22 +00008654 assign(result, binop(Iop_F64toI64U, 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_64_TO_UINT_64, op, rounding_mode);
floriane75dafa2012-09-01 17:54:09 +00008658 }
florian1c8f7ff2012-09-01 00:12:11 +00008659 return "clgdbr";
8660}
8661
florian55085f82012-11-21 00:36:55 +00008662static const HChar *
florian4b8efad2012-09-02 18:07:08 +00008663s390_irgen_CFEBR(UChar m3, UChar m4 __attribute__((unused)),
8664 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008665{
8666 IRTemp op = newTemp(Ity_F32);
8667 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +00008668 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +00008669
8670 assign(op, get_fpr_w0(r2));
florian19e00772012-09-06 03:13:22 +00008671 assign(result, binop(Iop_F32toI32S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +00008672 mkexpr(op)));
8673 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008674 s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_INT_32, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +00008675
8676 return "cfebr";
8677}
8678
florian55085f82012-11-21 00:36:55 +00008679static const HChar *
florian4b8efad2012-09-02 18:07:08 +00008680s390_irgen_CFDBR(UChar m3, UChar m4 __attribute__((unused)),
8681 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008682{
8683 IRTemp op = newTemp(Ity_F64);
8684 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +00008685 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +00008686
8687 assign(op, get_fpr_dw0(r2));
florian19e00772012-09-06 03:13:22 +00008688 assign(result, binop(Iop_F64toI32S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +00008689 mkexpr(op)));
8690 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008691 s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_INT_32, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +00008692
8693 return "cfdbr";
8694}
8695
florian55085f82012-11-21 00:36:55 +00008696static const HChar *
florian4b8efad2012-09-02 18:07:08 +00008697s390_irgen_CGEBR(UChar m3, UChar m4 __attribute__((unused)),
8698 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008699{
8700 IRTemp op = newTemp(Ity_F32);
8701 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +00008702 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +00008703
8704 assign(op, get_fpr_w0(r2));
florian19e00772012-09-06 03:13:22 +00008705 assign(result, binop(Iop_F32toI64S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +00008706 mkexpr(op)));
8707 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008708 s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_INT_64, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +00008709
8710 return "cgebr";
8711}
8712
florian55085f82012-11-21 00:36:55 +00008713static const HChar *
florian4b8efad2012-09-02 18:07:08 +00008714s390_irgen_CGDBR(UChar m3, UChar m4 __attribute__((unused)),
8715 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008716{
8717 IRTemp op = newTemp(Ity_F64);
8718 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +00008719 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +00008720
8721 assign(op, get_fpr_dw0(r2));
florian19e00772012-09-06 03:13:22 +00008722 assign(result, binop(Iop_F64toI64S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +00008723 mkexpr(op)));
8724 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008725 s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_INT_64, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +00008726
8727 return "cgdbr";
8728}
8729
florian55085f82012-11-21 00:36:55 +00008730static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008731s390_irgen_DEBR(UChar r1, UChar r2)
8732{
8733 IRTemp op1 = newTemp(Ity_F32);
8734 IRTemp op2 = newTemp(Ity_F32);
8735 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00008736 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008737
8738 assign(op1, get_fpr_w0(r1));
8739 assign(op2, get_fpr_w0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008740 assign(result, triop(Iop_DivF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008741 mkexpr(op2)));
8742 put_fpr_w0(r1, mkexpr(result));
8743
8744 return "debr";
8745}
8746
florian55085f82012-11-21 00:36:55 +00008747static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008748s390_irgen_DDBR(UChar r1, UChar r2)
8749{
8750 IRTemp op1 = newTemp(Ity_F64);
8751 IRTemp op2 = newTemp(Ity_F64);
8752 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00008753 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008754
8755 assign(op1, get_fpr_dw0(r1));
8756 assign(op2, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008757 assign(result, triop(Iop_DivF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008758 mkexpr(op2)));
8759 put_fpr_dw0(r1, mkexpr(result));
8760
8761 return "ddbr";
8762}
8763
florian55085f82012-11-21 00:36:55 +00008764static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008765s390_irgen_DEB(UChar r1, IRTemp op2addr)
8766{
8767 IRTemp op1 = newTemp(Ity_F32);
8768 IRTemp op2 = newTemp(Ity_F32);
8769 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00008770 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008771
8772 assign(op1, get_fpr_w0(r1));
8773 assign(op2, load(Ity_F32, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00008774 assign(result, triop(Iop_DivF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008775 mkexpr(op2)));
8776 put_fpr_w0(r1, mkexpr(result));
8777
8778 return "deb";
8779}
8780
florian55085f82012-11-21 00:36:55 +00008781static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008782s390_irgen_DDB(UChar r1, IRTemp op2addr)
8783{
8784 IRTemp op1 = newTemp(Ity_F64);
8785 IRTemp op2 = newTemp(Ity_F64);
8786 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00008787 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008788
8789 assign(op1, get_fpr_dw0(r1));
8790 assign(op2, load(Ity_F64, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00008791 assign(result, triop(Iop_DivF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008792 mkexpr(op2)));
8793 put_fpr_dw0(r1, mkexpr(result));
8794
8795 return "ddb";
8796}
8797
florian55085f82012-11-21 00:36:55 +00008798static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008799s390_irgen_LTEBR(UChar r1, UChar r2)
8800{
8801 IRTemp result = newTemp(Ity_F32);
8802
8803 assign(result, get_fpr_w0(r2));
8804 put_fpr_w0(r1, mkexpr(result));
8805 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
8806
8807 return "ltebr";
8808}
8809
florian55085f82012-11-21 00:36:55 +00008810static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008811s390_irgen_LTDBR(UChar r1, UChar r2)
8812{
8813 IRTemp result = newTemp(Ity_F64);
8814
8815 assign(result, get_fpr_dw0(r2));
8816 put_fpr_dw0(r1, mkexpr(result));
8817 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
8818
8819 return "ltdbr";
8820}
8821
florian55085f82012-11-21 00:36:55 +00008822static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008823s390_irgen_LCEBR(UChar r1, UChar r2)
8824{
8825 IRTemp result = newTemp(Ity_F32);
8826
8827 assign(result, unop(Iop_NegF32, get_fpr_w0(r2)));
8828 put_fpr_w0(r1, mkexpr(result));
8829 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
8830
8831 return "lcebr";
8832}
8833
florian55085f82012-11-21 00:36:55 +00008834static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008835s390_irgen_LCDBR(UChar r1, UChar r2)
8836{
8837 IRTemp result = newTemp(Ity_F64);
8838
8839 assign(result, unop(Iop_NegF64, get_fpr_dw0(r2)));
8840 put_fpr_dw0(r1, mkexpr(result));
8841 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
8842
8843 return "lcdbr";
8844}
8845
florian55085f82012-11-21 00:36:55 +00008846static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008847s390_irgen_LDEBR(UChar r1, UChar r2)
8848{
8849 IRTemp op = newTemp(Ity_F32);
8850
8851 assign(op, get_fpr_w0(r2));
8852 put_fpr_dw0(r1, unop(Iop_F32toF64, mkexpr(op)));
8853
8854 return "ldebr";
8855}
8856
florian55085f82012-11-21 00:36:55 +00008857static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008858s390_irgen_LDEB(UChar r1, IRTemp op2addr)
8859{
8860 IRTemp op = newTemp(Ity_F32);
8861
8862 assign(op, load(Ity_F32, mkexpr(op2addr)));
8863 put_fpr_dw0(r1, unop(Iop_F32toF64, mkexpr(op)));
8864
8865 return "ldeb";
8866}
8867
florian55085f82012-11-21 00:36:55 +00008868static const HChar *
florian4b8efad2012-09-02 18:07:08 +00008869s390_irgen_LEDBR(UChar m3, UChar m4 __attribute__((unused)),
8870 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008871{
florian125e20d2012-10-07 15:42:37 +00008872 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian12b0bca2012-09-05 20:05:20 +00008873 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +00008874 m3 = S390_BFP_ROUND_PER_FPC;
florian12b0bca2012-09-05 20:05:20 +00008875 }
sewardj2019a972011-03-07 16:04:07 +00008876 IRTemp op = newTemp(Ity_F64);
8877
8878 assign(op, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008879 put_fpr_w0(r1, binop(Iop_F64toF32, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +00008880 mkexpr(op)));
sewardj2019a972011-03-07 16:04:07 +00008881
8882 return "ledbr";
8883}
8884
florian55085f82012-11-21 00:36:55 +00008885static const HChar *
florian12390202012-11-10 22:34:14 +00008886s390_irgen_LTDTR(UChar r1, UChar r2)
8887{
8888 IRTemp result = newTemp(Ity_D64);
8889
8890 assign(result, get_dpr_dw0(r2));
8891 put_dpr_dw0(r1, mkexpr(result));
8892 s390_cc_thunk_putF(S390_CC_OP_DFP_RESULT_64, result);
8893
8894 return "ltdtr";
8895}
8896
florian55085f82012-11-21 00:36:55 +00008897static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008898s390_irgen_MEEBR(UChar r1, UChar r2)
8899{
8900 IRTemp op1 = newTemp(Ity_F32);
8901 IRTemp op2 = newTemp(Ity_F32);
8902 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00008903 IRRoundingMode rounding_mode =
8904 encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008905
8906 assign(op1, get_fpr_w0(r1));
8907 assign(op2, get_fpr_w0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008908 assign(result, triop(Iop_MulF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008909 mkexpr(op2)));
8910 put_fpr_w0(r1, mkexpr(result));
8911
8912 return "meebr";
8913}
8914
florian55085f82012-11-21 00:36:55 +00008915static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008916s390_irgen_MDBR(UChar r1, UChar r2)
8917{
8918 IRTemp op1 = newTemp(Ity_F64);
8919 IRTemp op2 = newTemp(Ity_F64);
8920 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00008921 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008922
8923 assign(op1, get_fpr_dw0(r1));
8924 assign(op2, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008925 assign(result, triop(Iop_MulF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008926 mkexpr(op2)));
8927 put_fpr_dw0(r1, mkexpr(result));
8928
8929 return "mdbr";
8930}
8931
florian55085f82012-11-21 00:36:55 +00008932static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008933s390_irgen_MEEB(UChar r1, IRTemp op2addr)
8934{
8935 IRTemp op1 = newTemp(Ity_F32);
8936 IRTemp op2 = newTemp(Ity_F32);
8937 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00008938 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008939
8940 assign(op1, get_fpr_w0(r1));
8941 assign(op2, load(Ity_F32, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00008942 assign(result, triop(Iop_MulF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008943 mkexpr(op2)));
8944 put_fpr_w0(r1, mkexpr(result));
8945
8946 return "meeb";
8947}
8948
florian55085f82012-11-21 00:36:55 +00008949static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008950s390_irgen_MDB(UChar r1, IRTemp op2addr)
8951{
8952 IRTemp op1 = newTemp(Ity_F64);
8953 IRTemp op2 = newTemp(Ity_F64);
8954 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00008955 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008956
8957 assign(op1, get_fpr_dw0(r1));
8958 assign(op2, load(Ity_F64, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00008959 assign(result, triop(Iop_MulF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008960 mkexpr(op2)));
8961 put_fpr_dw0(r1, mkexpr(result));
8962
8963 return "mdb";
8964}
8965
florian55085f82012-11-21 00:36:55 +00008966static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008967s390_irgen_SEBR(UChar r1, UChar r2)
8968{
8969 IRTemp op1 = newTemp(Ity_F32);
8970 IRTemp op2 = newTemp(Ity_F32);
8971 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00008972 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008973
8974 assign(op1, get_fpr_w0(r1));
8975 assign(op2, get_fpr_w0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008976 assign(result, triop(Iop_SubF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008977 mkexpr(op2)));
8978 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
8979 put_fpr_w0(r1, mkexpr(result));
8980
8981 return "sebr";
8982}
8983
florian55085f82012-11-21 00:36:55 +00008984static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008985s390_irgen_SDBR(UChar r1, UChar r2)
8986{
8987 IRTemp op1 = newTemp(Ity_F64);
8988 IRTemp op2 = newTemp(Ity_F64);
8989 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00008990 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008991
8992 assign(op1, get_fpr_dw0(r1));
8993 assign(op2, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008994 assign(result, triop(Iop_SubF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008995 mkexpr(op2)));
8996 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
8997 put_fpr_dw0(r1, mkexpr(result));
8998
8999 return "sdbr";
9000}
9001
florian55085f82012-11-21 00:36:55 +00009002static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009003s390_irgen_SEB(UChar r1, IRTemp op2addr)
9004{
9005 IRTemp op1 = newTemp(Ity_F32);
9006 IRTemp op2 = newTemp(Ity_F32);
9007 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00009008 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009009
9010 assign(op1, get_fpr_w0(r1));
9011 assign(op2, load(Ity_F32, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00009012 assign(result, triop(Iop_SubF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009013 mkexpr(op2)));
9014 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
9015 put_fpr_w0(r1, mkexpr(result));
9016
9017 return "seb";
9018}
9019
florian55085f82012-11-21 00:36:55 +00009020static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009021s390_irgen_SDB(UChar r1, IRTemp op2addr)
9022{
9023 IRTemp op1 = newTemp(Ity_F64);
9024 IRTemp op2 = newTemp(Ity_F64);
9025 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00009026 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009027
9028 assign(op1, get_fpr_dw0(r1));
9029 assign(op2, load(Ity_F64, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00009030 assign(result, triop(Iop_SubF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009031 mkexpr(op2)));
9032 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
9033 put_fpr_dw0(r1, mkexpr(result));
9034
9035 return "sdb";
9036}
9037
florian55085f82012-11-21 00:36:55 +00009038static const HChar *
florian12390202012-11-10 22:34:14 +00009039s390_irgen_ADTRA(UChar r3, UChar m4, UChar r1, UChar r2)
9040{
9041 IRTemp op1 = newTemp(Ity_D64);
9042 IRTemp op2 = newTemp(Ity_D64);
9043 IRTemp result = newTemp(Ity_D64);
9044 IRTemp rounding_mode;
9045
9046 vassert(s390_host_has_dfp);
9047 vassert(m4 == 0 || s390_host_has_fpext);
9048 /* when m4 = 0, S390_DFP_ROUND_PER_FPC_0 should be set.
9049 since S390_DFP_ROUND_PER_FPC_0 is also 0, passing m4 is sufficient */
9050 rounding_mode = encode_dfp_rounding_mode(m4);
9051 assign(op1, get_dpr_dw0(r2));
9052 assign(op2, get_dpr_dw0(r3));
9053 assign(result, triop(Iop_AddD64, mkexpr(rounding_mode), mkexpr(op1),
9054 mkexpr(op2)));
9055 s390_cc_thunk_putF(S390_CC_OP_DFP_RESULT_64, result);
9056 put_dpr_dw0(r1, mkexpr(result));
9057
9058 return (m4 == 0) ? "adtr" : "adtra";
9059}
9060
florian55085f82012-11-21 00:36:55 +00009061static const HChar *
florian12390202012-11-10 22:34:14 +00009062s390_irgen_DDTRA(UChar r3, UChar m4, UChar r1, UChar r2)
9063{
9064 IRTemp op1 = newTemp(Ity_D64);
9065 IRTemp op2 = newTemp(Ity_D64);
9066 IRTemp result = newTemp(Ity_D64);
9067 IRTemp rounding_mode;
9068
9069 vassert(s390_host_has_dfp);
9070 vassert(m4 == 0 || s390_host_has_fpext);
9071 /* when m4 = 0, S390_DFP_ROUND_PER_FPC_0 should be set.
9072 since S390_DFP_ROUND_PER_FPC_0 is also 0, passing m4 is sufficient */
9073 rounding_mode = encode_dfp_rounding_mode(m4);
9074 assign(op1, get_dpr_dw0(r2));
9075 assign(op2, get_dpr_dw0(r3));
9076 assign(result, triop(Iop_DivD64, mkexpr(rounding_mode), mkexpr(op1),
9077 mkexpr(op2)));
9078 s390_cc_thunk_putF(S390_CC_OP_DFP_RESULT_64, result);
9079 put_dpr_dw0(r1, mkexpr(result));
9080
9081 return (m4 == 0) ? "ddtr" : "ddtra";
9082}
9083
florian55085f82012-11-21 00:36:55 +00009084static const HChar *
florian12390202012-11-10 22:34:14 +00009085s390_irgen_MDTRA(UChar r3, UChar m4, UChar r1, UChar r2)
9086{
9087 IRTemp op1 = newTemp(Ity_D64);
9088 IRTemp op2 = newTemp(Ity_D64);
9089 IRTemp result = newTemp(Ity_D64);
9090 IRTemp rounding_mode;
9091
9092 vassert(s390_host_has_dfp);
9093 vassert(m4 == 0 || s390_host_has_fpext);
9094 /* when m4 = 0, S390_DFP_ROUND_PER_FPC_0 should be set.
9095 since S390_DFP_ROUND_PER_FPC_0 is also 0, passing m4 is sufficient */
9096 rounding_mode = encode_dfp_rounding_mode(m4);
9097 assign(op1, get_dpr_dw0(r2));
9098 assign(op2, get_dpr_dw0(r3));
9099 assign(result, triop(Iop_MulD64, mkexpr(rounding_mode), mkexpr(op1),
9100 mkexpr(op2)));
9101 s390_cc_thunk_putF(S390_CC_OP_DFP_RESULT_64, result);
9102 put_dpr_dw0(r1, mkexpr(result));
9103
9104 return (m4 == 0) ? "mdtr" : "mdtra";
9105}
9106
florian55085f82012-11-21 00:36:55 +00009107static const HChar *
florian12390202012-11-10 22:34:14 +00009108s390_irgen_SDTRA(UChar r3, UChar m4, UChar r1, UChar r2)
9109{
9110 IRTemp op1 = newTemp(Ity_D64);
9111 IRTemp op2 = newTemp(Ity_D64);
9112 IRTemp result = newTemp(Ity_D64);
9113 IRTemp rounding_mode;
9114
9115 vassert(s390_host_has_dfp);
9116 vassert(m4 == 0 || s390_host_has_fpext);
9117 /* when m4 = 0, S390_DFP_ROUND_PER_FPC_0 should be set.
9118 since S390_DFP_ROUND_PER_FPC_0 is also 0, passing m4 is sufficient */
9119 rounding_mode = encode_dfp_rounding_mode(m4);
9120 assign(op1, get_dpr_dw0(r2));
9121 assign(op2, get_dpr_dw0(r3));
9122 assign(result, triop(Iop_SubD64, mkexpr(rounding_mode), mkexpr(op1),
9123 mkexpr(op2)));
9124 s390_cc_thunk_putF(S390_CC_OP_DFP_RESULT_64, result);
9125 put_dpr_dw0(r1, mkexpr(result));
9126
9127 return (m4 == 0) ? "sdtr" : "sdtra";
9128}
9129
sewardj2019a972011-03-07 16:04:07 +00009130
florian55085f82012-11-21 00:36:55 +00009131static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009132s390_irgen_CLC(UChar length, IRTemp start1, IRTemp start2)
9133{
florian79e839e2012-05-05 02:20:30 +00009134 IRTemp len = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00009135
florian79e839e2012-05-05 02:20:30 +00009136 assign(len, mkU64(length));
9137 s390_irgen_CLC_EX(len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +00009138
9139 return "clc";
9140}
9141
florian55085f82012-11-21 00:36:55 +00009142static const HChar *
florianb0c9a132011-09-08 15:37:39 +00009143s390_irgen_CLCL(UChar r1, UChar r2)
9144{
9145 IRTemp addr1 = newTemp(Ity_I64);
9146 IRTemp addr2 = newTemp(Ity_I64);
9147 IRTemp addr1_load = newTemp(Ity_I64);
9148 IRTemp addr2_load = newTemp(Ity_I64);
9149 IRTemp len1 = newTemp(Ity_I32);
9150 IRTemp len2 = newTemp(Ity_I32);
9151 IRTemp r1p1 = newTemp(Ity_I32); /* contents of r1 + 1 */
9152 IRTemp r2p1 = newTemp(Ity_I32); /* contents of r2 + 1 */
9153 IRTemp single1 = newTemp(Ity_I8);
9154 IRTemp single2 = newTemp(Ity_I8);
9155 IRTemp pad = newTemp(Ity_I8);
9156
9157 assign(addr1, get_gpr_dw0(r1));
9158 assign(r1p1, get_gpr_w1(r1 + 1));
9159 assign(len1, binop(Iop_And32, mkexpr(r1p1), mkU32(0x00ffffff)));
9160 assign(addr2, get_gpr_dw0(r2));
9161 assign(r2p1, get_gpr_w1(r2 + 1));
9162 assign(len2, binop(Iop_And32, mkexpr(r2p1), mkU32(0x00ffffff)));
9163 assign(pad, get_gpr_b4(r2 + 1));
9164
9165 /* len1 == 0 and len2 == 0? Exit */
9166 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +00009167 next_insn_if(binop(Iop_CmpEQ32, binop(Iop_Or32, mkexpr(len1),
9168 mkexpr(len2)), mkU32(0)));
florianb0c9a132011-09-08 15:37:39 +00009169
9170 /* Because mkite evaluates both the then-clause and the else-clause
9171 we cannot load directly from addr1 here. If len1 is 0, then adddr1
9172 may be NULL and loading from there would segfault. So we provide a
9173 valid dummy address in that case. Loading from there does no harm and
9174 the value will be discarded at runtime. */
9175 assign(addr1_load,
9176 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
9177 mkU64(guest_IA_curr_instr), mkexpr(addr1)));
9178 assign(single1,
9179 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
9180 mkexpr(pad), load(Ity_I8, mkexpr(addr1_load))));
9181
9182 assign(addr2_load,
9183 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
9184 mkU64(guest_IA_curr_instr), mkexpr(addr2)));
9185 assign(single2,
9186 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
9187 mkexpr(pad), load(Ity_I8, mkexpr(addr2_load))));
9188
9189 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, single1, single2, False);
9190 /* Fields differ ? */
florian6820ba52012-07-26 02:01:50 +00009191 next_insn_if(binop(Iop_CmpNE8, mkexpr(single1), mkexpr(single2)));
florianb0c9a132011-09-08 15:37:39 +00009192
9193 /* Update len1 and addr1, unless len1 == 0. */
9194 put_gpr_dw0(r1,
9195 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
9196 mkexpr(addr1),
9197 binop(Iop_Add64, mkexpr(addr1), mkU64(1))));
9198
9199 /* When updating len1 we must not modify bits (r1+1)[0:39] */
9200 put_gpr_w1(r1 + 1,
9201 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
9202 binop(Iop_And32, mkexpr(r1p1), mkU32(0xFF000000u)),
9203 binop(Iop_Sub32, mkexpr(r1p1), mkU32(1))));
9204
9205 /* Update len2 and addr2, unless len2 == 0. */
9206 put_gpr_dw0(r2,
9207 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
9208 mkexpr(addr2),
9209 binop(Iop_Add64, mkexpr(addr2), mkU64(1))));
9210
9211 /* When updating len2 we must not modify bits (r2+1)[0:39] */
9212 put_gpr_w1(r2 + 1,
9213 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
9214 binop(Iop_And32, mkexpr(r2p1), mkU32(0xFF000000u)),
9215 binop(Iop_Sub32, mkexpr(r2p1), mkU32(1))));
9216
florian6820ba52012-07-26 02:01:50 +00009217 iterate();
florianb0c9a132011-09-08 15:37:39 +00009218
9219 return "clcl";
9220}
9221
florian55085f82012-11-21 00:36:55 +00009222static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009223s390_irgen_CLCLE(UChar r1, UChar r3, IRTemp pad2)
9224{
9225 IRTemp addr1, addr3, addr1_load, addr3_load, len1, len3, single1, single3;
9226
9227 addr1 = newTemp(Ity_I64);
9228 addr3 = newTemp(Ity_I64);
9229 addr1_load = newTemp(Ity_I64);
9230 addr3_load = newTemp(Ity_I64);
9231 len1 = newTemp(Ity_I64);
9232 len3 = newTemp(Ity_I64);
9233 single1 = newTemp(Ity_I8);
9234 single3 = newTemp(Ity_I8);
9235
9236 assign(addr1, get_gpr_dw0(r1));
9237 assign(len1, get_gpr_dw0(r1 + 1));
9238 assign(addr3, get_gpr_dw0(r3));
9239 assign(len3, get_gpr_dw0(r3 + 1));
9240
9241 /* len1 == 0 and len3 == 0? Exit */
9242 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +00009243 next_insn_if(binop(Iop_CmpEQ64,binop(Iop_Or64, mkexpr(len1),
9244 mkexpr(len3)), mkU64(0)));
sewardj2019a972011-03-07 16:04:07 +00009245
9246 /* A mux requires both ways to be possible. This is a way to prevent clcle
9247 from reading from addr1 if it should read from the pad. Since the pad
9248 has no address, just read from the instruction, we discard that anyway */
9249 assign(addr1_load,
florian6ad49522011-09-09 02:38:55 +00009250 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
9251 mkU64(guest_IA_curr_instr), mkexpr(addr1)));
sewardj2019a972011-03-07 16:04:07 +00009252
9253 /* same for addr3 */
9254 assign(addr3_load,
florian6ad49522011-09-09 02:38:55 +00009255 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
9256 mkU64(guest_IA_curr_instr), mkexpr(addr3)));
sewardj2019a972011-03-07 16:04:07 +00009257
9258 assign(single1,
florian6ad49522011-09-09 02:38:55 +00009259 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
9260 unop(Iop_64to8, mkexpr(pad2)),
9261 load(Ity_I8, mkexpr(addr1_load))));
sewardj2019a972011-03-07 16:04:07 +00009262
9263 assign(single3,
florian6ad49522011-09-09 02:38:55 +00009264 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
9265 unop(Iop_64to8, mkexpr(pad2)),
9266 load(Ity_I8, mkexpr(addr3_load))));
sewardj2019a972011-03-07 16:04:07 +00009267
9268 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, single1, single3, False);
9269 /* Both fields differ ? */
florian6820ba52012-07-26 02:01:50 +00009270 next_insn_if(binop(Iop_CmpNE8, mkexpr(single1), mkexpr(single3)));
sewardj2019a972011-03-07 16:04:07 +00009271
9272 /* If a length in 0 we must not change this length and the address */
9273 put_gpr_dw0(r1,
florian6ad49522011-09-09 02:38:55 +00009274 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
9275 mkexpr(addr1),
9276 binop(Iop_Add64, mkexpr(addr1), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +00009277
9278 put_gpr_dw0(r1 + 1,
florian6ad49522011-09-09 02:38:55 +00009279 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
9280 mkU64(0), binop(Iop_Sub64, mkexpr(len1), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +00009281
9282 put_gpr_dw0(r3,
florian6ad49522011-09-09 02:38:55 +00009283 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
9284 mkexpr(addr3),
9285 binop(Iop_Add64, mkexpr(addr3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +00009286
9287 put_gpr_dw0(r3 + 1,
florian6ad49522011-09-09 02:38:55 +00009288 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
9289 mkU64(0), binop(Iop_Sub64, mkexpr(len3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +00009290
florian6820ba52012-07-26 02:01:50 +00009291 iterate();
sewardj2019a972011-03-07 16:04:07 +00009292
9293 return "clcle";
9294}
floriana64c2432011-07-16 02:11:50 +00009295
florianb0bf6602012-05-05 00:01:16 +00009296
sewardj2019a972011-03-07 16:04:07 +00009297static void
9298s390_irgen_XC_EX(IRTemp length, IRTemp start1, IRTemp start2)
9299{
florianb0bf6602012-05-05 00:01:16 +00009300 s390_irgen_xonc(Iop_Xor8, length, start1, start2);
9301}
sewardj2019a972011-03-07 16:04:07 +00009302
sewardj2019a972011-03-07 16:04:07 +00009303
florianb0bf6602012-05-05 00:01:16 +00009304static void
9305s390_irgen_NC_EX(IRTemp length, IRTemp start1, IRTemp start2)
9306{
9307 s390_irgen_xonc(Iop_And8, length, start1, start2);
9308}
sewardj2019a972011-03-07 16:04:07 +00009309
sewardj2019a972011-03-07 16:04:07 +00009310
florianb0bf6602012-05-05 00:01:16 +00009311static void
9312s390_irgen_OC_EX(IRTemp length, IRTemp start1, IRTemp start2)
9313{
9314 s390_irgen_xonc(Iop_Or8, length, start1, start2);
sewardj2019a972011-03-07 16:04:07 +00009315}
9316
9317
9318static void
9319s390_irgen_CLC_EX(IRTemp length, IRTemp start1, IRTemp start2)
9320{
9321 IRTemp current1 = newTemp(Ity_I8);
9322 IRTemp current2 = newTemp(Ity_I8);
9323 IRTemp counter = newTemp(Ity_I64);
9324
9325 assign(counter, get_counter_dw0());
9326 put_counter_dw0(mkU64(0));
9327
9328 assign(current1, load(Ity_I8, binop(Iop_Add64, mkexpr(start1),
9329 mkexpr(counter))));
9330 assign(current2, load(Ity_I8, binop(Iop_Add64, mkexpr(start2),
9331 mkexpr(counter))));
9332 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, current1, current2,
9333 False);
9334
9335 /* Both fields differ ? */
florian6820ba52012-07-26 02:01:50 +00009336 next_insn_if(binop(Iop_CmpNE8, mkexpr(current1), mkexpr(current2)));
sewardj2019a972011-03-07 16:04:07 +00009337
9338 /* Check for end of field */
9339 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
florian6820ba52012-07-26 02:01:50 +00009340 iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)));
sewardj2019a972011-03-07 16:04:07 +00009341 put_counter_dw0(mkU64(0));
9342}
9343
9344static void
9345s390_irgen_MVC_EX(IRTemp length, IRTemp start1, IRTemp start2)
9346{
9347 IRTemp counter = newTemp(Ity_I64);
9348
9349 assign(counter, get_counter_dw0());
9350
9351 store(binop(Iop_Add64, mkexpr(start1), mkexpr(counter)),
9352 load(Ity_I8, binop(Iop_Add64, mkexpr(start2), mkexpr(counter))));
9353
9354 /* Check for end of field */
9355 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
florian6820ba52012-07-26 02:01:50 +00009356 iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)));
sewardj2019a972011-03-07 16:04:07 +00009357 put_counter_dw0(mkU64(0));
9358}
9359
florianf87d4fb2012-05-05 02:55:24 +00009360static void
9361s390_irgen_TR_EX(IRTemp length, IRTemp start1, IRTemp start2)
9362{
9363 IRTemp op = newTemp(Ity_I8);
9364 IRTemp op1 = newTemp(Ity_I8);
9365 IRTemp result = newTemp(Ity_I64);
9366 IRTemp counter = newTemp(Ity_I64);
9367
9368 assign(counter, get_counter_dw0());
9369
9370 assign(op, load(Ity_I8, binop(Iop_Add64, mkexpr(start1), mkexpr(counter))));
9371
9372 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)), mkexpr(start2)));
9373
9374 assign(op1, load(Ity_I8, mkexpr(result)));
9375 store(binop(Iop_Add64, mkexpr(start1), mkexpr(counter)), mkexpr(op1));
9376
9377 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
florian6820ba52012-07-26 02:01:50 +00009378 iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)));
florianf87d4fb2012-05-05 02:55:24 +00009379 put_counter_dw0(mkU64(0));
9380}
sewardj2019a972011-03-07 16:04:07 +00009381
9382
9383static void
9384s390_irgen_EX_SS(UChar r, IRTemp addr2,
florian6820ba52012-07-26 02:01:50 +00009385 void (*irgen)(IRTemp length, IRTemp start1, IRTemp start2),
9386 int lensize)
sewardj2019a972011-03-07 16:04:07 +00009387{
9388 struct SS {
9389 unsigned int op : 8;
9390 unsigned int l : 8;
9391 unsigned int b1 : 4;
9392 unsigned int d1 : 12;
9393 unsigned int b2 : 4;
9394 unsigned int d2 : 12;
9395 };
9396 union {
9397 struct SS dec;
9398 unsigned long bytes;
9399 } ss;
9400 IRTemp cond;
9401 IRDirty *d;
9402 IRTemp torun;
9403
9404 IRTemp start1 = newTemp(Ity_I64);
9405 IRTemp start2 = newTemp(Ity_I64);
9406 IRTemp len = newTemp(lensize == 64 ? Ity_I64 : Ity_I32);
9407 cond = newTemp(Ity_I1);
9408 torun = newTemp(Ity_I64);
9409
9410 assign(torun, load(Ity_I64, mkexpr(addr2)));
9411 /* Start with a check that the saved code is still correct */
9412 assign(cond, binop(Iop_CmpNE64, mkexpr(torun), mkU64(last_execute_target)));
9413 /* If not, save the new value */
9414 d = unsafeIRDirty_0_N (0, "s390x_dirtyhelper_EX", &s390x_dirtyhelper_EX,
9415 mkIRExprVec_1(mkexpr(torun)));
9416 d->guard = mkexpr(cond);
9417 stmt(IRStmt_Dirty(d));
9418
9419 /* and restart */
florian428dfdd2012-03-27 03:09:49 +00009420 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TISTART),
9421 mkU64(guest_IA_curr_instr)));
9422 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TILEN), mkU64(4)));
florian6820ba52012-07-26 02:01:50 +00009423 restart_if(mkexpr(cond));
sewardj2019a972011-03-07 16:04:07 +00009424
9425 ss.bytes = last_execute_target;
9426 assign(start1, binop(Iop_Add64, mkU64(ss.dec.d1),
9427 ss.dec.b1 != 0 ? get_gpr_dw0(ss.dec.b1) : mkU64(0)));
9428 assign(start2, binop(Iop_Add64, mkU64(ss.dec.d2),
9429 ss.dec.b2 != 0 ? get_gpr_dw0(ss.dec.b2) : mkU64(0)));
9430 assign(len, unop(lensize == 64 ? Iop_8Uto64 : Iop_8Uto32, binop(Iop_Or8,
9431 r != 0 ? get_gpr_b7(r): mkU8(0), mkU8(ss.dec.l))));
9432 irgen(len, start1, start2);
florian8844a632012-04-13 04:04:06 +00009433
sewardj2019a972011-03-07 16:04:07 +00009434 last_execute_target = 0;
9435}
9436
florian55085f82012-11-21 00:36:55 +00009437static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009438s390_irgen_EX(UChar r1, IRTemp addr2)
9439{
9440 switch(last_execute_target & 0xff00000000000000ULL) {
9441 case 0:
9442 {
9443 /* no code information yet */
9444 IRDirty *d;
9445
9446 /* so safe the code... */
9447 d = unsafeIRDirty_0_N (0, "s390x_dirtyhelper_EX", &s390x_dirtyhelper_EX,
9448 mkIRExprVec_1(load(Ity_I64, mkexpr(addr2))));
9449 stmt(IRStmt_Dirty(d));
9450 /* and restart */
florian428dfdd2012-03-27 03:09:49 +00009451 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TISTART),
9452 mkU64(guest_IA_curr_instr)));
9453 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TILEN), mkU64(4)));
florian6820ba52012-07-26 02:01:50 +00009454 restart_if(IRExpr_Const(IRConst_U1(True)));
9455
sewardj2019a972011-03-07 16:04:07 +00009456 /* we know that this will be invalidated */
florianf9e1ed72012-04-17 02:41:56 +00009457 put_IA(mkaddr_expr(guest_IA_next_instr));
sewardj2019a972011-03-07 16:04:07 +00009458 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +00009459 dis_res->jk_StopHere = Ijk_TInval;
sewardj2019a972011-03-07 16:04:07 +00009460 break;
9461 }
9462
9463 case 0xd200000000000000ULL:
9464 /* special case MVC */
9465 s390_irgen_EX_SS(r1, addr2, s390_irgen_MVC_EX, 64);
9466 return "mvc via ex";
9467
9468 case 0xd500000000000000ULL:
9469 /* special case CLC */
9470 s390_irgen_EX_SS(r1, addr2, s390_irgen_CLC_EX, 64);
9471 return "clc via ex";
9472
9473 case 0xd700000000000000ULL:
9474 /* special case XC */
9475 s390_irgen_EX_SS(r1, addr2, s390_irgen_XC_EX, 32);
9476 return "xc via ex";
9477
florianb0bf6602012-05-05 00:01:16 +00009478 case 0xd600000000000000ULL:
9479 /* special case OC */
9480 s390_irgen_EX_SS(r1, addr2, s390_irgen_OC_EX, 32);
9481 return "oc via ex";
9482
9483 case 0xd400000000000000ULL:
9484 /* special case NC */
9485 s390_irgen_EX_SS(r1, addr2, s390_irgen_NC_EX, 32);
9486 return "nc via ex";
sewardj2019a972011-03-07 16:04:07 +00009487
florianf87d4fb2012-05-05 02:55:24 +00009488 case 0xdc00000000000000ULL:
9489 /* special case TR */
9490 s390_irgen_EX_SS(r1, addr2, s390_irgen_TR_EX, 64);
9491 return "tr via ex";
9492
sewardj2019a972011-03-07 16:04:07 +00009493 default:
9494 {
9495 /* everything else will get a self checking prefix that also checks the
9496 register content */
9497 IRDirty *d;
9498 UChar *bytes;
9499 IRTemp cond;
9500 IRTemp orperand;
9501 IRTemp torun;
9502
9503 cond = newTemp(Ity_I1);
9504 orperand = newTemp(Ity_I64);
9505 torun = newTemp(Ity_I64);
9506
9507 if (r1 == 0)
9508 assign(orperand, mkU64(0));
9509 else
9510 assign(orperand, unop(Iop_8Uto64,get_gpr_b7(r1)));
9511 /* This code is going to be translated */
9512 assign(torun, binop(Iop_Or64, load(Ity_I64, mkexpr(addr2)),
9513 binop(Iop_Shl64, mkexpr(orperand), mkU8(48))));
9514
9515 /* Start with a check that saved code is still correct */
9516 assign(cond, binop(Iop_CmpNE64, mkexpr(torun),
9517 mkU64(last_execute_target)));
9518 /* If not, save the new value */
9519 d = unsafeIRDirty_0_N (0, "s390x_dirtyhelper_EX", &s390x_dirtyhelper_EX,
9520 mkIRExprVec_1(mkexpr(torun)));
9521 d->guard = mkexpr(cond);
9522 stmt(IRStmt_Dirty(d));
9523
9524 /* and restart */
florian428dfdd2012-03-27 03:09:49 +00009525 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TISTART), mkU64(guest_IA_curr_instr)));
9526 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TILEN), mkU64(4)));
florian6820ba52012-07-26 02:01:50 +00009527 restart_if(mkexpr(cond));
sewardj2019a972011-03-07 16:04:07 +00009528
9529 /* Now comes the actual translation */
9530 bytes = (UChar *) &last_execute_target;
9531 s390_decode_and_irgen(bytes, ((((bytes[0] >> 6) + 1) >> 1) + 1) << 1,
9532 dis_res);
sewardj7ee97522011-05-09 21:45:04 +00009533 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00009534 vex_printf(" which was executed by\n");
9535 /* dont make useless translations in the next execute */
9536 last_execute_target = 0;
9537 }
9538 }
9539 return "ex";
9540}
9541
florian55085f82012-11-21 00:36:55 +00009542static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009543s390_irgen_EXRL(UChar r1, UInt offset)
9544{
9545 IRTemp addr = newTemp(Ity_I64);
9546 /* we might save one round trip because we know the target */
9547 if (!last_execute_target)
9548 last_execute_target = *(ULong *)(HWord)
9549 (guest_IA_curr_instr + offset * 2UL);
9550 assign(addr, mkU64(guest_IA_curr_instr + offset * 2UL));
9551 s390_irgen_EX(r1, addr);
9552 return "exrl";
9553}
9554
florian55085f82012-11-21 00:36:55 +00009555static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009556s390_irgen_IPM(UChar r1)
9557{
9558 // As long as we dont support SPM, lets just assume 0 as program mask
9559 put_gpr_b4(r1, unop(Iop_32to8, binop(Iop_Or32, mkU32(0 /* program mask */),
9560 binop(Iop_Shl32, s390_call_calculate_cc(), mkU8(4)))));
9561
9562 return "ipm";
9563}
9564
9565
florian55085f82012-11-21 00:36:55 +00009566static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009567s390_irgen_SRST(UChar r1, UChar r2)
9568{
9569 IRTemp address = newTemp(Ity_I64);
9570 IRTemp next = newTemp(Ity_I64);
9571 IRTemp delim = newTemp(Ity_I8);
9572 IRTemp counter = newTemp(Ity_I64);
9573 IRTemp byte = newTemp(Ity_I8);
9574
9575 assign(address, get_gpr_dw0(r2));
9576 assign(next, get_gpr_dw0(r1));
9577
9578 assign(counter, get_counter_dw0());
9579 put_counter_dw0(mkU64(0));
9580
9581 // start = next? CC=2 and out r1 and r2 unchanged
9582 s390_cc_set(2);
9583 put_gpr_dw0(r2, binop(Iop_Sub64, mkexpr(address), mkexpr(counter)));
florian6820ba52012-07-26 02:01:50 +00009584 next_insn_if(binop(Iop_CmpEQ64, mkexpr(address), mkexpr(next)));
sewardj2019a972011-03-07 16:04:07 +00009585
9586 assign(byte, load(Ity_I8, mkexpr(address)));
9587 assign(delim, get_gpr_b7(0));
9588
9589 // byte = delim? CC=1, R1=address
9590 s390_cc_set(1);
9591 put_gpr_dw0(r1, mkexpr(address));
florian6820ba52012-07-26 02:01:50 +00009592 next_insn_if(binop(Iop_CmpEQ8, mkexpr(delim), mkexpr(byte)));
sewardj2019a972011-03-07 16:04:07 +00009593
9594 // else: all equal, no end yet, loop
9595 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
9596 put_gpr_dw0(r1, mkexpr(next));
9597 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(address), mkU64(1)));
floriancf87c942012-07-25 00:52:21 +00009598
florian6820ba52012-07-26 02:01:50 +00009599 iterate();
sewardj2019a972011-03-07 16:04:07 +00009600
9601 return "srst";
9602}
9603
florian55085f82012-11-21 00:36:55 +00009604static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009605s390_irgen_CLST(UChar r1, UChar r2)
9606{
9607 IRTemp address1 = newTemp(Ity_I64);
9608 IRTemp address2 = newTemp(Ity_I64);
9609 IRTemp end = newTemp(Ity_I8);
9610 IRTemp counter = newTemp(Ity_I64);
9611 IRTemp byte1 = newTemp(Ity_I8);
9612 IRTemp byte2 = newTemp(Ity_I8);
9613
9614 assign(address1, get_gpr_dw0(r1));
9615 assign(address2, get_gpr_dw0(r2));
9616 assign(end, get_gpr_b7(0));
9617 assign(counter, get_counter_dw0());
9618 put_counter_dw0(mkU64(0));
9619 assign(byte1, load(Ity_I8, mkexpr(address1)));
9620 assign(byte2, load(Ity_I8, mkexpr(address2)));
9621
9622 // end in both? all equal, reset r1 and r2 to start values
9623 s390_cc_set(0);
9624 put_gpr_dw0(r1, binop(Iop_Sub64, mkexpr(address1), mkexpr(counter)));
9625 put_gpr_dw0(r2, binop(Iop_Sub64, mkexpr(address2), mkexpr(counter)));
florian6820ba52012-07-26 02:01:50 +00009626 next_insn_if(binop(Iop_CmpEQ8, mkU8(0),
9627 binop(Iop_Or8,
9628 binop(Iop_Xor8, mkexpr(byte1), mkexpr(end)),
9629 binop(Iop_Xor8, mkexpr(byte2), mkexpr(end)))));
sewardj2019a972011-03-07 16:04:07 +00009630
9631 put_gpr_dw0(r1, mkexpr(address1));
9632 put_gpr_dw0(r2, mkexpr(address2));
9633
9634 // End found in string1
9635 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +00009636 next_insn_if(binop(Iop_CmpEQ8, mkexpr(end), mkexpr(byte1)));
sewardj2019a972011-03-07 16:04:07 +00009637
9638 // End found in string2
9639 s390_cc_set(2);
florian6820ba52012-07-26 02:01:50 +00009640 next_insn_if(binop(Iop_CmpEQ8, mkexpr(end), mkexpr(byte2)));
sewardj2019a972011-03-07 16:04:07 +00009641
9642 // string1 < string2
9643 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +00009644 next_insn_if(binop(Iop_CmpLT32U, unop(Iop_8Uto32, mkexpr(byte1)),
9645 unop(Iop_8Uto32, mkexpr(byte2))));
sewardj2019a972011-03-07 16:04:07 +00009646
9647 // string2 < string1
9648 s390_cc_set(2);
florian6820ba52012-07-26 02:01:50 +00009649 next_insn_if(binop(Iop_CmpLT32U, unop(Iop_8Uto32, mkexpr(byte2)),
9650 unop(Iop_8Uto32, mkexpr(byte1))));
sewardj2019a972011-03-07 16:04:07 +00009651
9652 // else: all equal, no end yet, loop
9653 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
9654 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), mkU64(1)));
9655 put_gpr_dw0(r2, binop(Iop_Add64, get_gpr_dw0(r2), mkU64(1)));
floriancf87c942012-07-25 00:52:21 +00009656
florian6820ba52012-07-26 02:01:50 +00009657 iterate();
sewardj2019a972011-03-07 16:04:07 +00009658
9659 return "clst";
9660}
9661
9662static void
9663s390_irgen_load_multiple_32bit(UChar r1, UChar r3, IRTemp op2addr)
9664{
9665 UChar reg;
9666 IRTemp addr = newTemp(Ity_I64);
9667
9668 assign(addr, mkexpr(op2addr));
9669 reg = r1;
9670 do {
9671 IRTemp old = addr;
9672
9673 reg %= 16;
9674 put_gpr_w1(reg, load(Ity_I32, mkexpr(addr)));
9675 addr = newTemp(Ity_I64);
9676 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
9677 reg++;
9678 } while (reg != (r3 + 1));
9679}
9680
florian55085f82012-11-21 00:36:55 +00009681static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009682s390_irgen_LM(UChar r1, UChar r3, IRTemp op2addr)
9683{
9684 s390_irgen_load_multiple_32bit(r1, r3, op2addr);
9685
9686 return "lm";
9687}
9688
florian55085f82012-11-21 00:36:55 +00009689static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009690s390_irgen_LMY(UChar r1, UChar r3, IRTemp op2addr)
9691{
9692 s390_irgen_load_multiple_32bit(r1, r3, op2addr);
9693
9694 return "lmy";
9695}
9696
florian55085f82012-11-21 00:36:55 +00009697static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009698s390_irgen_LMH(UChar r1, UChar r3, IRTemp op2addr)
9699{
9700 UChar reg;
9701 IRTemp addr = newTemp(Ity_I64);
9702
9703 assign(addr, mkexpr(op2addr));
9704 reg = r1;
9705 do {
9706 IRTemp old = addr;
9707
9708 reg %= 16;
9709 put_gpr_w0(reg, load(Ity_I32, mkexpr(addr)));
9710 addr = newTemp(Ity_I64);
9711 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
9712 reg++;
9713 } while (reg != (r3 + 1));
9714
9715 return "lmh";
9716}
9717
florian55085f82012-11-21 00:36:55 +00009718static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009719s390_irgen_LMG(UChar r1, UChar r3, IRTemp op2addr)
9720{
9721 UChar reg;
9722 IRTemp addr = newTemp(Ity_I64);
9723
9724 assign(addr, mkexpr(op2addr));
9725 reg = r1;
9726 do {
9727 IRTemp old = addr;
9728
9729 reg %= 16;
9730 put_gpr_dw0(reg, load(Ity_I64, mkexpr(addr)));
9731 addr = newTemp(Ity_I64);
9732 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(8)));
9733 reg++;
9734 } while (reg != (r3 + 1));
9735
9736 return "lmg";
9737}
9738
9739static void
9740s390_irgen_store_multiple_32bit(UChar r1, UChar r3, IRTemp op2addr)
9741{
9742 UChar reg;
9743 IRTemp addr = newTemp(Ity_I64);
9744
9745 assign(addr, mkexpr(op2addr));
9746 reg = r1;
9747 do {
9748 IRTemp old = addr;
9749
9750 reg %= 16;
9751 store(mkexpr(addr), get_gpr_w1(reg));
9752 addr = newTemp(Ity_I64);
9753 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
9754 reg++;
9755 } while( reg != (r3 + 1));
9756}
9757
florian55085f82012-11-21 00:36:55 +00009758static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009759s390_irgen_STM(UChar r1, UChar r3, IRTemp op2addr)
9760{
9761 s390_irgen_store_multiple_32bit(r1, r3, op2addr);
9762
9763 return "stm";
9764}
9765
florian55085f82012-11-21 00:36:55 +00009766static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009767s390_irgen_STMY(UChar r1, UChar r3, IRTemp op2addr)
9768{
9769 s390_irgen_store_multiple_32bit(r1, r3, op2addr);
9770
9771 return "stmy";
9772}
9773
florian55085f82012-11-21 00:36:55 +00009774static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009775s390_irgen_STMH(UChar r1, UChar r3, IRTemp op2addr)
9776{
9777 UChar reg;
9778 IRTemp addr = newTemp(Ity_I64);
9779
9780 assign(addr, mkexpr(op2addr));
9781 reg = r1;
9782 do {
9783 IRTemp old = addr;
9784
9785 reg %= 16;
9786 store(mkexpr(addr), get_gpr_w0(reg));
9787 addr = newTemp(Ity_I64);
9788 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
9789 reg++;
9790 } while( reg != (r3 + 1));
9791
9792 return "stmh";
9793}
9794
florian55085f82012-11-21 00:36:55 +00009795static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009796s390_irgen_STMG(UChar r1, UChar r3, IRTemp op2addr)
9797{
9798 UChar reg;
9799 IRTemp addr = newTemp(Ity_I64);
9800
9801 assign(addr, mkexpr(op2addr));
9802 reg = r1;
9803 do {
9804 IRTemp old = addr;
9805
9806 reg %= 16;
9807 store(mkexpr(addr), get_gpr_dw0(reg));
9808 addr = newTemp(Ity_I64);
9809 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(8)));
9810 reg++;
9811 } while( reg != (r3 + 1));
9812
9813 return "stmg";
9814}
9815
9816static void
florianb0bf6602012-05-05 00:01:16 +00009817s390_irgen_xonc(IROp op, IRTemp length, IRTemp start1, IRTemp start2)
sewardj2019a972011-03-07 16:04:07 +00009818{
9819 IRTemp old1 = newTemp(Ity_I8);
9820 IRTemp old2 = newTemp(Ity_I8);
9821 IRTemp new1 = newTemp(Ity_I8);
9822 IRTemp counter = newTemp(Ity_I32);
9823 IRTemp addr1 = newTemp(Ity_I64);
9824
9825 assign(counter, get_counter_w0());
9826
9827 assign(addr1, binop(Iop_Add64, mkexpr(start1),
9828 unop(Iop_32Uto64, mkexpr(counter))));
9829
9830 assign(old1, load(Ity_I8, mkexpr(addr1)));
9831 assign(old2, load(Ity_I8, binop(Iop_Add64, mkexpr(start2),
9832 unop(Iop_32Uto64,mkexpr(counter)))));
9833 assign(new1, binop(op, mkexpr(old1), mkexpr(old2)));
9834
9835 /* Special case: xc is used to zero memory */
sewardj2019a972011-03-07 16:04:07 +00009836 if (op == Iop_Xor8) {
9837 store(mkexpr(addr1),
florian6ad49522011-09-09 02:38:55 +00009838 mkite(binop(Iop_CmpEQ64, mkexpr(start1), mkexpr(start2)),
9839 mkU8(0), mkexpr(new1)));
sewardj2019a972011-03-07 16:04:07 +00009840 } else
9841 store(mkexpr(addr1), mkexpr(new1));
9842 put_counter_w1(binop(Iop_Or32, unop(Iop_8Uto32, mkexpr(new1)),
9843 get_counter_w1()));
9844
9845 /* Check for end of field */
9846 put_counter_w0(binop(Iop_Add32, mkexpr(counter), mkU32(1)));
florian6820ba52012-07-26 02:01:50 +00009847 iterate_if(binop(Iop_CmpNE32, mkexpr(counter), mkexpr(length)));
sewardj2019a972011-03-07 16:04:07 +00009848 s390_cc_thunk_put1(S390_CC_OP_BITWISE, mktemp(Ity_I32, get_counter_w1()),
9849 False);
9850 put_counter_dw0(mkU64(0));
9851}
9852
florian55085f82012-11-21 00:36:55 +00009853static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009854s390_irgen_XC(UChar length, IRTemp start1, IRTemp start2)
9855{
florianb0bf6602012-05-05 00:01:16 +00009856 IRTemp len = newTemp(Ity_I32);
9857
9858 assign(len, mkU32(length));
9859 s390_irgen_xonc(Iop_Xor8, len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +00009860
9861 return "xc";
9862}
9863
sewardjb63967e2011-03-24 08:50:04 +00009864static void
9865s390_irgen_XC_sameloc(UChar length, UChar b, UShort d)
9866{
9867 IRTemp counter = newTemp(Ity_I32);
9868 IRTemp start = newTemp(Ity_I64);
9869 IRTemp addr = newTemp(Ity_I64);
9870
9871 assign(start,
9872 binop(Iop_Add64, mkU64(d), b != 0 ? get_gpr_dw0(b) : mkU64(0)));
9873
9874 if (length < 8) {
9875 UInt i;
9876
9877 for (i = 0; i <= length; ++i) {
9878 store(binop(Iop_Add64, mkexpr(start), mkU64(i)), mkU8(0));
9879 }
9880 } else {
9881 assign(counter, get_counter_w0());
9882
9883 assign(addr, binop(Iop_Add64, mkexpr(start),
9884 unop(Iop_32Uto64, mkexpr(counter))));
9885
9886 store(mkexpr(addr), mkU8(0));
9887
9888 /* Check for end of field */
9889 put_counter_w0(binop(Iop_Add32, mkexpr(counter), mkU32(1)));
florian6820ba52012-07-26 02:01:50 +00009890 iterate_if(binop(Iop_CmpNE32, mkexpr(counter), mkU32(length)));
sewardjb63967e2011-03-24 08:50:04 +00009891
9892 /* Reset counter */
9893 put_counter_dw0(mkU64(0));
9894 }
9895
9896 s390_cc_thunk_put1(S390_CC_OP_BITWISE, mktemp(Ity_I32, mkU32(0)), False);
9897
sewardj7ee97522011-05-09 21:45:04 +00009898 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardjb63967e2011-03-24 08:50:04 +00009899 s390_disasm(ENC3(MNM, UDLB, UDXB), "xc", d, length, b, d, 0, b);
9900}
9901
florian55085f82012-11-21 00:36:55 +00009902static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009903s390_irgen_NC(UChar length, IRTemp start1, IRTemp start2)
9904{
florianb0bf6602012-05-05 00:01:16 +00009905 IRTemp len = newTemp(Ity_I32);
9906
9907 assign(len, mkU32(length));
9908 s390_irgen_xonc(Iop_And8, len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +00009909
9910 return "nc";
9911}
9912
florian55085f82012-11-21 00:36:55 +00009913static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009914s390_irgen_OC(UChar length, IRTemp start1, IRTemp start2)
9915{
florianb0bf6602012-05-05 00:01:16 +00009916 IRTemp len = newTemp(Ity_I32);
9917
9918 assign(len, mkU32(length));
9919 s390_irgen_xonc(Iop_Or8, len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +00009920
9921 return "oc";
9922}
9923
9924
florian55085f82012-11-21 00:36:55 +00009925static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009926s390_irgen_MVC(UChar length, IRTemp start1, IRTemp start2)
9927{
florian79e839e2012-05-05 02:20:30 +00009928 IRTemp len = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00009929
florian79e839e2012-05-05 02:20:30 +00009930 assign(len, mkU64(length));
9931 s390_irgen_MVC_EX(len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +00009932
9933 return "mvc";
9934}
9935
florian55085f82012-11-21 00:36:55 +00009936static const HChar *
florianb0c9a132011-09-08 15:37:39 +00009937s390_irgen_MVCL(UChar r1, UChar r2)
9938{
9939 IRTemp addr1 = newTemp(Ity_I64);
9940 IRTemp addr2 = newTemp(Ity_I64);
9941 IRTemp addr2_load = newTemp(Ity_I64);
9942 IRTemp r1p1 = newTemp(Ity_I32); /* contents of r1 + 1 */
9943 IRTemp r2p1 = newTemp(Ity_I32); /* contents of r2 + 1 */
9944 IRTemp len1 = newTemp(Ity_I32);
9945 IRTemp len2 = newTemp(Ity_I32);
9946 IRTemp pad = newTemp(Ity_I8);
9947 IRTemp single = newTemp(Ity_I8);
9948
9949 assign(addr1, get_gpr_dw0(r1));
9950 assign(r1p1, get_gpr_w1(r1 + 1));
9951 assign(len1, binop(Iop_And32, mkexpr(r1p1), mkU32(0x00ffffff)));
9952 assign(addr2, get_gpr_dw0(r2));
9953 assign(r2p1, get_gpr_w1(r2 + 1));
9954 assign(len2, binop(Iop_And32, mkexpr(r2p1), mkU32(0x00ffffff)));
9955 assign(pad, get_gpr_b4(r2 + 1));
9956
9957 /* len1 == 0 ? */
9958 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len2, False);
florian6820ba52012-07-26 02:01:50 +00009959 next_insn_if(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)));
florianb0c9a132011-09-08 15:37:39 +00009960
9961 /* Check for destructive overlap:
9962 addr1 > addr2 && addr2 + len1 > addr1 && (addr2 + len2) > addr1 */
9963 s390_cc_set(3);
9964 IRTemp cond1 = newTemp(Ity_I32);
9965 assign(cond1, unop(Iop_1Uto32,
9966 binop(Iop_CmpLT64U, mkexpr(addr2), mkexpr(addr1))));
9967 IRTemp cond2 = newTemp(Ity_I32);
9968 assign(cond2, unop(Iop_1Uto32,
9969 binop(Iop_CmpLT64U, mkexpr(addr1),
9970 binop(Iop_Add64, mkexpr(addr2),
9971 unop(Iop_32Uto64, mkexpr(len1))))));
9972 IRTemp cond3 = newTemp(Ity_I32);
9973 assign(cond3, unop(Iop_1Uto32,
9974 binop(Iop_CmpLT64U,
9975 mkexpr(addr1),
9976 binop(Iop_Add64, mkexpr(addr2),
9977 unop(Iop_32Uto64, mkexpr(len2))))));
9978
florian6820ba52012-07-26 02:01:50 +00009979 next_insn_if(binop(Iop_CmpEQ32,
9980 binop(Iop_And32,
9981 binop(Iop_And32, mkexpr(cond1), mkexpr(cond2)),
9982 mkexpr(cond3)),
9983 mkU32(1)));
florianb0c9a132011-09-08 15:37:39 +00009984
9985 /* See s390_irgen_CLCL for explanation why we cannot load directly
9986 and need two steps. */
9987 assign(addr2_load,
9988 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
9989 mkU64(guest_IA_curr_instr), mkexpr(addr2)));
9990 assign(single,
9991 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
9992 mkexpr(pad), load(Ity_I8, mkexpr(addr2_load))));
9993
9994 store(mkexpr(addr1), mkexpr(single));
9995
9996 /* Update addr1 and len1 */
9997 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkU64(1)));
9998 put_gpr_w1(r1 + 1, binop(Iop_Sub32, mkexpr(r1p1), mkU32(1)));
9999
10000 /* Update addr2 and len2 */
10001 put_gpr_dw0(r2,
10002 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
10003 mkexpr(addr2),
10004 binop(Iop_Add64, mkexpr(addr2), mkU64(1))));
10005
10006 /* When updating len2 we must not modify bits (r2+1)[0:39] */
10007 put_gpr_w1(r2 + 1,
10008 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
10009 binop(Iop_And32, mkexpr(r2p1), mkU32(0xFF000000u)),
10010 binop(Iop_Sub32, mkexpr(r2p1), mkU32(1))));
10011
10012 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len2, False);
florian6820ba52012-07-26 02:01:50 +000010013 iterate_if(binop(Iop_CmpNE32, mkexpr(len1), mkU32(1)));
florianb0c9a132011-09-08 15:37:39 +000010014
10015 return "mvcl";
10016}
10017
10018
florian55085f82012-11-21 00:36:55 +000010019static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010020s390_irgen_MVCLE(UChar r1, UChar r3, IRTemp pad2)
10021{
10022 IRTemp addr1, addr3, addr3_load, len1, len3, single;
10023
10024 addr1 = newTemp(Ity_I64);
10025 addr3 = newTemp(Ity_I64);
10026 addr3_load = newTemp(Ity_I64);
10027 len1 = newTemp(Ity_I64);
10028 len3 = newTemp(Ity_I64);
10029 single = newTemp(Ity_I8);
10030
10031 assign(addr1, get_gpr_dw0(r1));
10032 assign(len1, get_gpr_dw0(r1 + 1));
10033 assign(addr3, get_gpr_dw0(r3));
10034 assign(len3, get_gpr_dw0(r3 + 1));
10035
10036 // len1 == 0 ?
10037 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len3, False);
florian6820ba52012-07-26 02:01:50 +000010038 next_insn_if(binop(Iop_CmpEQ64,mkexpr(len1), mkU64(0)));
sewardj2019a972011-03-07 16:04:07 +000010039
10040 /* This is a hack to prevent mvcle from reading from addr3 if it
10041 should read from the pad. Since the pad has no address, just
10042 read from the instruction, we discard that anyway */
10043 assign(addr3_load,
florian6ad49522011-09-09 02:38:55 +000010044 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
10045 mkU64(guest_IA_curr_instr), mkexpr(addr3)));
sewardj2019a972011-03-07 16:04:07 +000010046
10047 assign(single,
florian6ad49522011-09-09 02:38:55 +000010048 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
10049 unop(Iop_64to8, mkexpr(pad2)),
10050 load(Ity_I8, mkexpr(addr3_load))));
sewardj2019a972011-03-07 16:04:07 +000010051 store(mkexpr(addr1), mkexpr(single));
10052
10053 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkU64(1)));
10054
10055 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkU64(1)));
10056
10057 put_gpr_dw0(r3,
florian6ad49522011-09-09 02:38:55 +000010058 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
10059 mkexpr(addr3),
10060 binop(Iop_Add64, mkexpr(addr3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +000010061
10062 put_gpr_dw0(r3 + 1,
florian6ad49522011-09-09 02:38:55 +000010063 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
10064 mkU64(0), binop(Iop_Sub64, mkexpr(len3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +000010065
sewardj2019a972011-03-07 16:04:07 +000010066 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len3, False);
florian6820ba52012-07-26 02:01:50 +000010067 iterate_if(binop(Iop_CmpNE64, mkexpr(len1), mkU64(1)));
sewardj2019a972011-03-07 16:04:07 +000010068
10069 return "mvcle";
10070}
10071
florian55085f82012-11-21 00:36:55 +000010072static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010073s390_irgen_MVST(UChar r1, UChar r2)
10074{
10075 IRTemp addr1 = newTemp(Ity_I64);
10076 IRTemp addr2 = newTemp(Ity_I64);
10077 IRTemp end = newTemp(Ity_I8);
10078 IRTemp byte = newTemp(Ity_I8);
10079 IRTemp counter = newTemp(Ity_I64);
10080
10081 assign(addr1, get_gpr_dw0(r1));
10082 assign(addr2, get_gpr_dw0(r2));
10083 assign(counter, get_counter_dw0());
10084 assign(end, get_gpr_b7(0));
10085 assign(byte, load(Ity_I8, binop(Iop_Add64, mkexpr(addr2),mkexpr(counter))));
10086 store(binop(Iop_Add64,mkexpr(addr1),mkexpr(counter)), mkexpr(byte));
10087
10088 // We use unlimited as cpu-determined number
10089 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
florian6820ba52012-07-26 02:01:50 +000010090 iterate_if(binop(Iop_CmpNE8, mkexpr(end), mkexpr(byte)));
sewardj2019a972011-03-07 16:04:07 +000010091
10092 // and always set cc=1 at the end + update r1
10093 s390_cc_set(1);
10094 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(counter)));
10095 put_counter_dw0(mkU64(0));
10096
10097 return "mvst";
10098}
10099
10100static void
10101s390_irgen_divide_64to32(IROp op, UChar r1, IRTemp op2)
10102{
10103 IRTemp op1 = newTemp(Ity_I64);
10104 IRTemp result = newTemp(Ity_I64);
10105
10106 assign(op1, binop(Iop_32HLto64,
10107 get_gpr_w1(r1), // high 32 bits
10108 get_gpr_w1(r1 + 1))); // low 32 bits
10109 assign(result, binop(op, mkexpr(op1), mkexpr(op2)));
10110 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result))); // remainder
10111 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result))); // quotient
10112}
10113
10114static void
10115s390_irgen_divide_128to64(IROp op, UChar r1, IRTemp op2)
10116{
10117 IRTemp op1 = newTemp(Ity_I128);
10118 IRTemp result = newTemp(Ity_I128);
10119
10120 assign(op1, binop(Iop_64HLto128,
10121 get_gpr_dw0(r1), // high 64 bits
10122 get_gpr_dw0(r1 + 1))); // low 64 bits
10123 assign(result, binop(op, mkexpr(op1), mkexpr(op2)));
10124 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result))); // remainder
10125 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result))); // quotient
10126}
10127
10128static void
10129s390_irgen_divide_64to64(IROp op, UChar r1, IRTemp op2)
10130{
10131 IRTemp op1 = newTemp(Ity_I64);
10132 IRTemp result = newTemp(Ity_I128);
10133
10134 assign(op1, get_gpr_dw0(r1 + 1));
10135 assign(result, binop(op, mkexpr(op1), mkexpr(op2)));
10136 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result))); // remainder
10137 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result))); // quotient
10138}
10139
florian55085f82012-11-21 00:36:55 +000010140static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010141s390_irgen_DR(UChar r1, UChar r2)
10142{
10143 IRTemp op2 = newTemp(Ity_I32);
10144
10145 assign(op2, get_gpr_w1(r2));
10146
10147 s390_irgen_divide_64to32(Iop_DivModS64to32, r1, op2);
10148
10149 return "dr";
10150}
10151
florian55085f82012-11-21 00:36:55 +000010152static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010153s390_irgen_D(UChar r1, IRTemp op2addr)
10154{
10155 IRTemp op2 = newTemp(Ity_I32);
10156
10157 assign(op2, load(Ity_I32, mkexpr(op2addr)));
10158
10159 s390_irgen_divide_64to32(Iop_DivModS64to32, r1, op2);
10160
10161 return "d";
10162}
10163
florian55085f82012-11-21 00:36:55 +000010164static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010165s390_irgen_DLR(UChar r1, UChar r2)
10166{
10167 IRTemp op2 = newTemp(Ity_I32);
10168
10169 assign(op2, get_gpr_w1(r2));
10170
10171 s390_irgen_divide_64to32(Iop_DivModU64to32, r1, op2);
10172
florian7cd1cde2012-08-16 23:57:43 +000010173 return "dlr";
sewardj2019a972011-03-07 16:04:07 +000010174}
10175
florian55085f82012-11-21 00:36:55 +000010176static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010177s390_irgen_DL(UChar r1, IRTemp op2addr)
10178{
10179 IRTemp op2 = newTemp(Ity_I32);
10180
10181 assign(op2, load(Ity_I32, mkexpr(op2addr)));
10182
10183 s390_irgen_divide_64to32(Iop_DivModU64to32, r1, op2);
10184
10185 return "dl";
10186}
10187
florian55085f82012-11-21 00:36:55 +000010188static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010189s390_irgen_DLG(UChar r1, IRTemp op2addr)
10190{
10191 IRTemp op2 = newTemp(Ity_I64);
10192
10193 assign(op2, load(Ity_I64, mkexpr(op2addr)));
10194
10195 s390_irgen_divide_128to64(Iop_DivModU128to64, r1, op2);
10196
10197 return "dlg";
10198}
10199
florian55085f82012-11-21 00:36:55 +000010200static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010201s390_irgen_DLGR(UChar r1, UChar r2)
10202{
10203 IRTemp op2 = newTemp(Ity_I64);
10204
10205 assign(op2, get_gpr_dw0(r2));
10206
10207 s390_irgen_divide_128to64(Iop_DivModU128to64, r1, op2);
10208
10209 return "dlgr";
10210}
10211
florian55085f82012-11-21 00:36:55 +000010212static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010213s390_irgen_DSGR(UChar r1, UChar r2)
10214{
10215 IRTemp op2 = newTemp(Ity_I64);
10216
10217 assign(op2, get_gpr_dw0(r2));
10218
10219 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
10220
10221 return "dsgr";
10222}
10223
florian55085f82012-11-21 00:36:55 +000010224static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010225s390_irgen_DSG(UChar r1, IRTemp op2addr)
10226{
10227 IRTemp op2 = newTemp(Ity_I64);
10228
10229 assign(op2, load(Ity_I64, mkexpr(op2addr)));
10230
10231 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
10232
10233 return "dsg";
10234}
10235
florian55085f82012-11-21 00:36:55 +000010236static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010237s390_irgen_DSGFR(UChar r1, UChar r2)
10238{
10239 IRTemp op2 = newTemp(Ity_I64);
10240
10241 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
10242
10243 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
10244
10245 return "dsgfr";
10246}
10247
florian55085f82012-11-21 00:36:55 +000010248static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010249s390_irgen_DSGF(UChar r1, IRTemp op2addr)
10250{
10251 IRTemp op2 = newTemp(Ity_I64);
10252
10253 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
10254
10255 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
10256
10257 return "dsgf";
10258}
10259
10260static void
10261s390_irgen_load_ar_multiple(UChar r1, UChar r3, IRTemp op2addr)
10262{
10263 UChar reg;
10264 IRTemp addr = newTemp(Ity_I64);
10265
10266 assign(addr, mkexpr(op2addr));
10267 reg = r1;
10268 do {
10269 IRTemp old = addr;
10270
10271 reg %= 16;
10272 put_ar_w0(reg, load(Ity_I32, mkexpr(addr)));
10273 addr = newTemp(Ity_I64);
10274 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
10275 reg++;
10276 } while (reg != (r3 + 1));
10277}
10278
florian55085f82012-11-21 00:36:55 +000010279static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010280s390_irgen_LAM(UChar r1, UChar r3, IRTemp op2addr)
10281{
10282 s390_irgen_load_ar_multiple(r1, r3, op2addr);
10283
10284 return "lam";
10285}
10286
florian55085f82012-11-21 00:36:55 +000010287static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010288s390_irgen_LAMY(UChar r1, UChar r3, IRTemp op2addr)
10289{
10290 s390_irgen_load_ar_multiple(r1, r3, op2addr);
10291
10292 return "lamy";
10293}
10294
10295static void
10296s390_irgen_store_ar_multiple(UChar r1, UChar r3, IRTemp op2addr)
10297{
10298 UChar reg;
10299 IRTemp addr = newTemp(Ity_I64);
10300
10301 assign(addr, mkexpr(op2addr));
10302 reg = r1;
10303 do {
10304 IRTemp old = addr;
10305
10306 reg %= 16;
10307 store(mkexpr(addr), get_ar_w0(reg));
10308 addr = newTemp(Ity_I64);
10309 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
10310 reg++;
10311 } while (reg != (r3 + 1));
10312}
10313
florian55085f82012-11-21 00:36:55 +000010314static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010315s390_irgen_STAM(UChar r1, UChar r3, IRTemp op2addr)
10316{
10317 s390_irgen_store_ar_multiple(r1, r3, op2addr);
10318
10319 return "stam";
10320}
10321
florian55085f82012-11-21 00:36:55 +000010322static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010323s390_irgen_STAMY(UChar r1, UChar r3, IRTemp op2addr)
10324{
10325 s390_irgen_store_ar_multiple(r1, r3, op2addr);
10326
10327 return "stamy";
10328}
10329
10330
10331/* Implementation for 32-bit compare-and-swap */
10332static void
10333s390_irgen_cas_32(UChar r1, UChar r3, IRTemp op2addr)
10334{
10335 IRCAS *cas;
10336 IRTemp op1 = newTemp(Ity_I32);
10337 IRTemp old_mem = newTemp(Ity_I32);
10338 IRTemp op3 = newTemp(Ity_I32);
10339 IRTemp result = newTemp(Ity_I32);
10340 IRTemp nequal = newTemp(Ity_I1);
10341
10342 assign(op1, get_gpr_w1(r1));
10343 assign(op3, get_gpr_w1(r3));
10344
10345 /* The first and second operands are compared. If they are equal,
10346 the third operand is stored at the second- operand location. */
10347 cas = mkIRCAS(IRTemp_INVALID, old_mem,
10348 Iend_BE, mkexpr(op2addr),
10349 NULL, mkexpr(op1), /* expected value */
10350 NULL, mkexpr(op3) /* new value */);
10351 stmt(IRStmt_CAS(cas));
10352
10353 /* Set CC. Operands compared equal -> 0, else 1. */
10354 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(old_mem)));
10355 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
10356
10357 /* If operands were equal (cc == 0) just store the old value op1 in r1.
10358 Otherwise, store the old_value from memory in r1 and yield. */
10359 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
10360 put_gpr_w1(r1, mkite(mkexpr(nequal), mkexpr(old_mem), mkexpr(op1)));
florian6820ba52012-07-26 02:01:50 +000010361 yield_if(mkexpr(nequal));
sewardj2019a972011-03-07 16:04:07 +000010362}
10363
florian55085f82012-11-21 00:36:55 +000010364static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010365s390_irgen_CS(UChar r1, UChar r3, IRTemp op2addr)
10366{
10367 s390_irgen_cas_32(r1, r3, op2addr);
10368
10369 return "cs";
10370}
10371
florian55085f82012-11-21 00:36:55 +000010372static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010373s390_irgen_CSY(UChar r1, UChar r3, IRTemp op2addr)
10374{
10375 s390_irgen_cas_32(r1, r3, op2addr);
10376
10377 return "csy";
10378}
10379
florian55085f82012-11-21 00:36:55 +000010380static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010381s390_irgen_CSG(UChar r1, UChar r3, IRTemp op2addr)
10382{
10383 IRCAS *cas;
10384 IRTemp op1 = newTemp(Ity_I64);
10385 IRTemp old_mem = newTemp(Ity_I64);
10386 IRTemp op3 = newTemp(Ity_I64);
10387 IRTemp result = newTemp(Ity_I64);
10388 IRTemp nequal = newTemp(Ity_I1);
10389
10390 assign(op1, get_gpr_dw0(r1));
10391 assign(op3, get_gpr_dw0(r3));
10392
10393 /* The first and second operands are compared. If they are equal,
10394 the third operand is stored at the second- operand location. */
10395 cas = mkIRCAS(IRTemp_INVALID, old_mem,
10396 Iend_BE, mkexpr(op2addr),
10397 NULL, mkexpr(op1), /* expected value */
10398 NULL, mkexpr(op3) /* new value */);
10399 stmt(IRStmt_CAS(cas));
10400
10401 /* Set CC. Operands compared equal -> 0, else 1. */
10402 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(old_mem)));
10403 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
10404
10405 /* If operands were equal (cc == 0) just store the old value op1 in r1.
10406 Otherwise, store the old_value from memory in r1 and yield. */
10407 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
10408 put_gpr_dw0(r1, mkite(mkexpr(nequal), mkexpr(old_mem), mkexpr(op1)));
florian6820ba52012-07-26 02:01:50 +000010409 yield_if(mkexpr(nequal));
sewardj2019a972011-03-07 16:04:07 +000010410
10411 return "csg";
10412}
10413
florian448cbba2012-06-06 02:26:01 +000010414/* Implementation for 32-bit compare-double-and-swap */
10415static void
10416s390_irgen_cdas_32(UChar r1, UChar r3, IRTemp op2addr)
10417{
10418 IRCAS *cas;
10419 IRTemp op1_high = newTemp(Ity_I32);
10420 IRTemp op1_low = newTemp(Ity_I32);
10421 IRTemp old_mem_high = newTemp(Ity_I32);
10422 IRTemp old_mem_low = newTemp(Ity_I32);
10423 IRTemp op3_high = newTemp(Ity_I32);
10424 IRTemp op3_low = newTemp(Ity_I32);
10425 IRTemp result = newTemp(Ity_I32);
10426 IRTemp nequal = newTemp(Ity_I1);
10427
10428 assign(op1_high, get_gpr_w1(r1));
10429 assign(op1_low, get_gpr_w1(r1+1));
10430 assign(op3_high, get_gpr_w1(r3));
10431 assign(op3_low, get_gpr_w1(r3+1));
10432
10433 /* The first and second operands are compared. If they are equal,
10434 the third operand is stored at the second-operand location. */
10435 cas = mkIRCAS(old_mem_high, old_mem_low,
10436 Iend_BE, mkexpr(op2addr),
10437 mkexpr(op1_high), mkexpr(op1_low), /* expected value */
10438 mkexpr(op3_high), mkexpr(op3_low) /* new value */);
10439 stmt(IRStmt_CAS(cas));
10440
10441 /* Set CC. Operands compared equal -> 0, else 1. */
10442 assign(result, unop(Iop_1Uto32,
10443 binop(Iop_CmpNE32,
10444 binop(Iop_Or32,
10445 binop(Iop_Xor32, mkexpr(op1_high), mkexpr(old_mem_high)),
10446 binop(Iop_Xor32, mkexpr(op1_low), mkexpr(old_mem_low))),
10447 mkU32(0))));
10448
10449 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
10450
10451 /* If operands were equal (cc == 0) just store the old value op1 in r1.
10452 Otherwise, store the old_value from memory in r1 and yield. */
10453 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
10454 put_gpr_w1(r1, mkite(mkexpr(nequal), mkexpr(old_mem_high), mkexpr(op1_high)));
10455 put_gpr_w1(r1+1, mkite(mkexpr(nequal), mkexpr(old_mem_low), mkexpr(op1_low)));
florian6820ba52012-07-26 02:01:50 +000010456 yield_if(mkexpr(nequal));
florian448cbba2012-06-06 02:26:01 +000010457}
10458
florian55085f82012-11-21 00:36:55 +000010459static const HChar *
florian448cbba2012-06-06 02:26:01 +000010460s390_irgen_CDS(UChar r1, UChar r3, IRTemp op2addr)
10461{
10462 s390_irgen_cdas_32(r1, r3, op2addr);
10463
10464 return "cds";
10465}
10466
florian55085f82012-11-21 00:36:55 +000010467static const HChar *
florian448cbba2012-06-06 02:26:01 +000010468s390_irgen_CDSY(UChar r1, UChar r3, IRTemp op2addr)
10469{
10470 s390_irgen_cdas_32(r1, r3, op2addr);
10471
10472 return "cdsy";
10473}
10474
florian55085f82012-11-21 00:36:55 +000010475static const HChar *
florian448cbba2012-06-06 02:26:01 +000010476s390_irgen_CDSG(UChar r1, UChar r3, IRTemp op2addr)
10477{
10478 IRCAS *cas;
10479 IRTemp op1_high = newTemp(Ity_I64);
10480 IRTemp op1_low = newTemp(Ity_I64);
10481 IRTemp old_mem_high = newTemp(Ity_I64);
10482 IRTemp old_mem_low = newTemp(Ity_I64);
10483 IRTemp op3_high = newTemp(Ity_I64);
10484 IRTemp op3_low = newTemp(Ity_I64);
10485 IRTemp result = newTemp(Ity_I64);
10486 IRTemp nequal = newTemp(Ity_I1);
10487
10488 assign(op1_high, get_gpr_dw0(r1));
10489 assign(op1_low, get_gpr_dw0(r1+1));
10490 assign(op3_high, get_gpr_dw0(r3));
10491 assign(op3_low, get_gpr_dw0(r3+1));
10492
10493 /* The first and second operands are compared. If they are equal,
10494 the third operand is stored at the second-operand location. */
10495 cas = mkIRCAS(old_mem_high, old_mem_low,
10496 Iend_BE, mkexpr(op2addr),
10497 mkexpr(op1_high), mkexpr(op1_low), /* expected value */
10498 mkexpr(op3_high), mkexpr(op3_low) /* new value */);
10499 stmt(IRStmt_CAS(cas));
10500
10501 /* Set CC. Operands compared equal -> 0, else 1. */
10502 assign(result, unop(Iop_1Uto64,
10503 binop(Iop_CmpNE64,
10504 binop(Iop_Or64,
10505 binop(Iop_Xor64, mkexpr(op1_high), mkexpr(old_mem_high)),
10506 binop(Iop_Xor64, mkexpr(op1_low), mkexpr(old_mem_low))),
10507 mkU64(0))));
10508
10509 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
10510
10511 /* If operands were equal (cc == 0) just store the old value op1 in r1.
10512 Otherwise, store the old_value from memory in r1 and yield. */
10513 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
10514 put_gpr_dw0(r1, mkite(mkexpr(nequal), mkexpr(old_mem_high), mkexpr(op1_high)));
10515 put_gpr_dw0(r1+1, mkite(mkexpr(nequal), mkexpr(old_mem_low), mkexpr(op1_low)));
florian6820ba52012-07-26 02:01:50 +000010516 yield_if(mkexpr(nequal));
10517
florian448cbba2012-06-06 02:26:01 +000010518 return "cdsg";
10519}
10520
sewardj2019a972011-03-07 16:04:07 +000010521
10522/* Binary floating point */
10523
florian55085f82012-11-21 00:36:55 +000010524static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010525s390_irgen_AXBR(UChar r1, UChar r2)
10526{
10527 IRTemp op1 = newTemp(Ity_F128);
10528 IRTemp op2 = newTemp(Ity_F128);
10529 IRTemp result = newTemp(Ity_F128);
florian125e20d2012-10-07 15:42:37 +000010530 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000010531
10532 assign(op1, get_fpr_pair(r1));
10533 assign(op2, get_fpr_pair(r2));
floriandb4fcaa2012-09-05 19:54:08 +000010534 assign(result, triop(Iop_AddF128, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +000010535 mkexpr(op2)));
10536 put_fpr_pair(r1, mkexpr(result));
10537
10538 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
10539
10540 return "axbr";
10541}
10542
10543/* The result of a Iop_CmdFxx operation is a condition code. It is
10544 encoded using the values defined in type IRCmpFxxResult.
10545 Before we can store the condition code into the guest state (or do
10546 anything else with it for that matter) we need to convert it to
10547 the encoding that s390 uses. This is what this function does.
10548
10549 s390 VEX b6 b2 b0 cc.1 cc.0
10550 0 0x40 EQ 1 0 0 0 0
10551 1 0x01 LT 0 0 1 0 1
10552 2 0x00 GT 0 0 0 1 0
10553 3 0x45 Unordered 1 1 1 1 1
10554
10555 The following bits from the VEX encoding are interesting:
10556 b0, b2, b6 with b0 being the LSB. We observe:
10557
10558 cc.0 = b0;
10559 cc.1 = b2 | (~b0 & ~b6)
10560
10561 with cc being the s390 condition code.
10562*/
10563static IRExpr *
10564convert_vex_fpcc_to_s390(IRTemp vex_cc)
10565{
10566 IRTemp cc0 = newTemp(Ity_I32);
10567 IRTemp cc1 = newTemp(Ity_I32);
10568 IRTemp b0 = newTemp(Ity_I32);
10569 IRTemp b2 = newTemp(Ity_I32);
10570 IRTemp b6 = newTemp(Ity_I32);
10571
10572 assign(b0, binop(Iop_And32, mkexpr(vex_cc), mkU32(1)));
10573 assign(b2, binop(Iop_And32, binop(Iop_Shr32, mkexpr(vex_cc), mkU8(2)),
10574 mkU32(1)));
10575 assign(b6, binop(Iop_And32, binop(Iop_Shr32, mkexpr(vex_cc), mkU8(6)),
10576 mkU32(1)));
10577
10578 assign(cc0, mkexpr(b0));
10579 assign(cc1, binop(Iop_Or32, mkexpr(b2),
10580 binop(Iop_And32,
10581 binop(Iop_Sub32, mkU32(1), mkexpr(b0)), /* ~b0 */
10582 binop(Iop_Sub32, mkU32(1), mkexpr(b6)) /* ~b6 */
10583 )));
10584
10585 return binop(Iop_Or32, mkexpr(cc0), binop(Iop_Shl32, mkexpr(cc1), mkU8(1)));
10586}
10587
florian55085f82012-11-21 00:36:55 +000010588static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010589s390_irgen_CEBR(UChar r1, UChar r2)
10590{
10591 IRTemp op1 = newTemp(Ity_F32);
10592 IRTemp op2 = newTemp(Ity_F32);
10593 IRTemp cc_vex = newTemp(Ity_I32);
10594 IRTemp cc_s390 = newTemp(Ity_I32);
10595
10596 assign(op1, get_fpr_w0(r1));
10597 assign(op2, get_fpr_w0(r2));
10598 assign(cc_vex, binop(Iop_CmpF32, mkexpr(op1), mkexpr(op2)));
10599
10600 assign(cc_s390, convert_vex_fpcc_to_s390(cc_vex));
10601 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
10602
10603 return "cebr";
10604}
10605
florian55085f82012-11-21 00:36:55 +000010606static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010607s390_irgen_CDBR(UChar r1, UChar r2)
10608{
10609 IRTemp op1 = newTemp(Ity_F64);
10610 IRTemp op2 = newTemp(Ity_F64);
10611 IRTemp cc_vex = newTemp(Ity_I32);
10612 IRTemp cc_s390 = newTemp(Ity_I32);
10613
10614 assign(op1, get_fpr_dw0(r1));
10615 assign(op2, get_fpr_dw0(r2));
10616 assign(cc_vex, binop(Iop_CmpF64, mkexpr(op1), mkexpr(op2)));
10617
10618 assign(cc_s390, convert_vex_fpcc_to_s390(cc_vex));
10619 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
10620
10621 return "cdbr";
10622}
10623
florian55085f82012-11-21 00:36:55 +000010624static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010625s390_irgen_CXBR(UChar r1, UChar r2)
10626{
10627 IRTemp op1 = newTemp(Ity_F128);
10628 IRTemp op2 = newTemp(Ity_F128);
10629 IRTemp cc_vex = newTemp(Ity_I32);
10630 IRTemp cc_s390 = newTemp(Ity_I32);
10631
10632 assign(op1, get_fpr_pair(r1));
10633 assign(op2, get_fpr_pair(r2));
10634 assign(cc_vex, binop(Iop_CmpF128, mkexpr(op1), mkexpr(op2)));
10635
10636 assign(cc_s390, convert_vex_fpcc_to_s390(cc_vex));
10637 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
10638
10639 return "cxbr";
10640}
10641
florian55085f82012-11-21 00:36:55 +000010642static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010643s390_irgen_CEB(UChar r1, IRTemp op2addr)
10644{
10645 IRTemp op1 = newTemp(Ity_F32);
10646 IRTemp op2 = newTemp(Ity_F32);
10647 IRTemp cc_vex = newTemp(Ity_I32);
10648 IRTemp cc_s390 = newTemp(Ity_I32);
10649
10650 assign(op1, get_fpr_w0(r1));
10651 assign(op2, load(Ity_F32, mkexpr(op2addr)));
10652 assign(cc_vex, binop(Iop_CmpF32, mkexpr(op1), mkexpr(op2)));
10653
10654 assign(cc_s390, convert_vex_fpcc_to_s390(cc_vex));
10655 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
10656
10657 return "ceb";
10658}
10659
florian55085f82012-11-21 00:36:55 +000010660static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010661s390_irgen_CDB(UChar r1, IRTemp op2addr)
10662{
10663 IRTemp op1 = newTemp(Ity_F64);
10664 IRTemp op2 = newTemp(Ity_F64);
10665 IRTemp cc_vex = newTemp(Ity_I32);
10666 IRTemp cc_s390 = newTemp(Ity_I32);
10667
10668 assign(op1, get_fpr_dw0(r1));
10669 assign(op2, load(Ity_F64, mkexpr(op2addr)));
10670 assign(cc_vex, binop(Iop_CmpF64, mkexpr(op1), mkexpr(op2)));
10671
10672 assign(cc_s390, convert_vex_fpcc_to_s390(cc_vex));
10673 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
10674
10675 return "cdb";
10676}
10677
florian55085f82012-11-21 00:36:55 +000010678static const HChar *
florian4b8efad2012-09-02 18:07:08 +000010679s390_irgen_CXFBR(UChar m3 __attribute__((unused)),
10680 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000010681{
10682 IRTemp op2 = newTemp(Ity_I32);
10683
10684 assign(op2, get_gpr_w1(r2));
10685 put_fpr_pair(r1, unop(Iop_I32StoF128, mkexpr(op2)));
10686
10687 return "cxfbr";
10688}
10689
florian55085f82012-11-21 00:36:55 +000010690static const HChar *
floriand2129202012-09-01 20:01:39 +000010691s390_irgen_CXLFBR(UChar m3 __attribute__((unused)),
10692 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
florian1c8f7ff2012-09-01 00:12:11 +000010693{
floriane75dafa2012-09-01 17:54:09 +000010694 if (! s390_host_has_fpext) {
10695 emulation_failure(EmFail_S390X_fpext);
10696 } else {
10697 IRTemp op2 = newTemp(Ity_I32);
florian1c8f7ff2012-09-01 00:12:11 +000010698
floriane75dafa2012-09-01 17:54:09 +000010699 assign(op2, get_gpr_w1(r2));
10700 put_fpr_pair(r1, unop(Iop_I32UtoF128, mkexpr(op2)));
10701 }
florian1c8f7ff2012-09-01 00:12:11 +000010702 return "cxlfbr";
10703}
10704
10705
florian55085f82012-11-21 00:36:55 +000010706static const HChar *
florian4b8efad2012-09-02 18:07:08 +000010707s390_irgen_CXGBR(UChar m3 __attribute__((unused)),
10708 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000010709{
10710 IRTemp op2 = newTemp(Ity_I64);
10711
10712 assign(op2, get_gpr_dw0(r2));
10713 put_fpr_pair(r1, unop(Iop_I64StoF128, mkexpr(op2)));
10714
10715 return "cxgbr";
10716}
10717
florian55085f82012-11-21 00:36:55 +000010718static const HChar *
floriand2129202012-09-01 20:01:39 +000010719s390_irgen_CXLGBR(UChar m3 __attribute__((unused)),
10720 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
florian1c8f7ff2012-09-01 00:12:11 +000010721{
floriane75dafa2012-09-01 17:54:09 +000010722 if (! s390_host_has_fpext) {
10723 emulation_failure(EmFail_S390X_fpext);
10724 } else {
10725 IRTemp op2 = newTemp(Ity_I64);
florian1c8f7ff2012-09-01 00:12:11 +000010726
floriane75dafa2012-09-01 17:54:09 +000010727 assign(op2, get_gpr_dw0(r2));
10728 put_fpr_pair(r1, unop(Iop_I64UtoF128, mkexpr(op2)));
10729 }
florian1c8f7ff2012-09-01 00:12:11 +000010730 return "cxlgbr";
10731}
10732
florian55085f82012-11-21 00:36:55 +000010733static const HChar *
florian4b8efad2012-09-02 18:07:08 +000010734s390_irgen_CFXBR(UChar m3, UChar m4 __attribute__((unused)),
10735 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000010736{
10737 IRTemp op = newTemp(Ity_F128);
10738 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +000010739 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +000010740
10741 assign(op, get_fpr_pair(r2));
florian19e00772012-09-06 03:13:22 +000010742 assign(result, binop(Iop_F128toI32S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +000010743 mkexpr(op)));
10744 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +000010745 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_INT_32, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +000010746
10747 return "cfxbr";
10748}
10749
florian55085f82012-11-21 00:36:55 +000010750static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +000010751s390_irgen_CLFXBR(UChar m3, UChar m4 __attribute__((unused)),
10752 UChar r1, UChar r2)
10753{
floriane75dafa2012-09-01 17:54:09 +000010754 if (! s390_host_has_fpext) {
10755 emulation_failure(EmFail_S390X_fpext);
10756 } else {
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);
florian1c8f7ff2012-09-01 00:12:11 +000010760
floriane75dafa2012-09-01 17:54:09 +000010761 assign(op, get_fpr_pair(r2));
florian19e00772012-09-06 03:13:22 +000010762 assign(result, binop(Iop_F128toI32U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +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_UINT_32, op, rounding_mode);
floriane75dafa2012-09-01 17:54:09 +000010766 }
florian1c8f7ff2012-09-01 00:12:11 +000010767 return "clfxbr";
10768}
10769
10770
florian55085f82012-11-21 00:36:55 +000010771static const HChar *
florian4b8efad2012-09-02 18:07:08 +000010772s390_irgen_CGXBR(UChar m3, UChar m4 __attribute__((unused)),
10773 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000010774{
10775 IRTemp op = newTemp(Ity_F128);
10776 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +000010777 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +000010778
10779 assign(op, get_fpr_pair(r2));
florian19e00772012-09-06 03:13:22 +000010780 assign(result, binop(Iop_F128toI64S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +000010781 mkexpr(op)));
10782 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +000010783 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_INT_64, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +000010784
10785 return "cgxbr";
10786}
10787
florian55085f82012-11-21 00:36:55 +000010788static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +000010789s390_irgen_CLGXBR(UChar m3, UChar m4 __attribute__((unused)),
10790 UChar r1, UChar r2)
10791{
floriane75dafa2012-09-01 17:54:09 +000010792 if (! s390_host_has_fpext) {
10793 emulation_failure(EmFail_S390X_fpext);
10794 } else {
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);
florian1c8f7ff2012-09-01 00:12:11 +000010798
floriane75dafa2012-09-01 17:54:09 +000010799 assign(op, get_fpr_pair(r2));
florian19e00772012-09-06 03:13:22 +000010800 assign(result, binop(Iop_F128toI64U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +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_UINT_64, op,
10804 rounding_mode);
floriane75dafa2012-09-01 17:54:09 +000010805 }
florian1c8f7ff2012-09-01 00:12:11 +000010806 return "clgxbr";
10807}
10808
florian55085f82012-11-21 00:36:55 +000010809static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010810s390_irgen_DXBR(UChar r1, UChar r2)
10811{
10812 IRTemp op1 = newTemp(Ity_F128);
10813 IRTemp op2 = newTemp(Ity_F128);
10814 IRTemp result = newTemp(Ity_F128);
florian125e20d2012-10-07 15:42:37 +000010815 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000010816
10817 assign(op1, get_fpr_pair(r1));
10818 assign(op2, get_fpr_pair(r2));
floriandb4fcaa2012-09-05 19:54:08 +000010819 assign(result, triop(Iop_DivF128, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +000010820 mkexpr(op2)));
10821 put_fpr_pair(r1, mkexpr(result));
10822
10823 return "dxbr";
10824}
10825
florian55085f82012-11-21 00:36:55 +000010826static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010827s390_irgen_LTXBR(UChar r1, UChar r2)
10828{
10829 IRTemp result = newTemp(Ity_F128);
10830
10831 assign(result, get_fpr_pair(r2));
10832 put_fpr_pair(r1, mkexpr(result));
10833 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
10834
10835 return "ltxbr";
10836}
10837
florian55085f82012-11-21 00:36:55 +000010838static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010839s390_irgen_LCXBR(UChar r1, UChar r2)
10840{
10841 IRTemp result = newTemp(Ity_F128);
10842
10843 assign(result, unop(Iop_NegF128, get_fpr_pair(r2)));
10844 put_fpr_pair(r1, mkexpr(result));
10845 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
10846
10847 return "lcxbr";
10848}
10849
florian55085f82012-11-21 00:36:55 +000010850static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010851s390_irgen_LXDBR(UChar r1, UChar r2)
10852{
10853 IRTemp op = newTemp(Ity_F64);
10854
10855 assign(op, get_fpr_dw0(r2));
10856 put_fpr_pair(r1, unop(Iop_F64toF128, mkexpr(op)));
10857
10858 return "lxdbr";
10859}
10860
florian55085f82012-11-21 00:36:55 +000010861static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010862s390_irgen_LXEBR(UChar r1, UChar r2)
10863{
10864 IRTemp op = newTemp(Ity_F32);
10865
10866 assign(op, get_fpr_w0(r2));
10867 put_fpr_pair(r1, unop(Iop_F32toF128, mkexpr(op)));
10868
10869 return "lxebr";
10870}
10871
florian55085f82012-11-21 00:36:55 +000010872static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010873s390_irgen_LXDB(UChar r1, IRTemp op2addr)
10874{
10875 IRTemp op = newTemp(Ity_F64);
10876
10877 assign(op, load(Ity_F64, mkexpr(op2addr)));
10878 put_fpr_pair(r1, unop(Iop_F64toF128, mkexpr(op)));
10879
10880 return "lxdb";
10881}
10882
florian55085f82012-11-21 00:36:55 +000010883static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010884s390_irgen_LXEB(UChar r1, IRTemp op2addr)
10885{
10886 IRTemp op = newTemp(Ity_F32);
10887
10888 assign(op, load(Ity_F32, mkexpr(op2addr)));
10889 put_fpr_pair(r1, unop(Iop_F32toF128, mkexpr(op)));
10890
10891 return "lxeb";
10892}
10893
florian55085f82012-11-21 00:36:55 +000010894static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010895s390_irgen_LNEBR(UChar r1, UChar r2)
10896{
10897 IRTemp result = newTemp(Ity_F32);
10898
10899 assign(result, unop(Iop_NegF32, unop(Iop_AbsF32, get_fpr_w0(r2))));
10900 put_fpr_w0(r1, mkexpr(result));
10901 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_32, result);
10902
10903 return "lnebr";
10904}
10905
florian55085f82012-11-21 00:36:55 +000010906static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010907s390_irgen_LNDBR(UChar r1, UChar r2)
10908{
10909 IRTemp result = newTemp(Ity_F64);
10910
10911 assign(result, unop(Iop_NegF64, unop(Iop_AbsF64, get_fpr_dw0(r2))));
10912 put_fpr_dw0(r1, mkexpr(result));
10913 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_64, result);
10914
10915 return "lndbr";
10916}
10917
florian55085f82012-11-21 00:36:55 +000010918static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010919s390_irgen_LNXBR(UChar r1, UChar r2)
10920{
10921 IRTemp result = newTemp(Ity_F128);
10922
10923 assign(result, unop(Iop_NegF128, unop(Iop_AbsF128, get_fpr_pair(r2))));
10924 put_fpr_pair(r1, mkexpr(result));
10925 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
10926
10927 return "lnxbr";
10928}
10929
florian55085f82012-11-21 00:36:55 +000010930static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010931s390_irgen_LPEBR(UChar r1, UChar r2)
10932{
10933 IRTemp result = newTemp(Ity_F32);
10934
10935 assign(result, unop(Iop_AbsF32, get_fpr_w0(r2)));
10936 put_fpr_w0(r1, mkexpr(result));
10937 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_32, result);
10938
10939 return "lpebr";
10940}
10941
florian55085f82012-11-21 00:36:55 +000010942static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010943s390_irgen_LPDBR(UChar r1, UChar r2)
10944{
10945 IRTemp result = newTemp(Ity_F64);
10946
10947 assign(result, unop(Iop_AbsF64, get_fpr_dw0(r2)));
10948 put_fpr_dw0(r1, mkexpr(result));
10949 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_64, result);
10950
10951 return "lpdbr";
10952}
10953
florian55085f82012-11-21 00:36:55 +000010954static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010955s390_irgen_LPXBR(UChar r1, UChar r2)
10956{
10957 IRTemp result = newTemp(Ity_F128);
10958
10959 assign(result, unop(Iop_AbsF128, get_fpr_pair(r2)));
10960 put_fpr_pair(r1, mkexpr(result));
10961 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
10962
10963 return "lpxbr";
10964}
10965
florian55085f82012-11-21 00:36:55 +000010966static const HChar *
florian4b8efad2012-09-02 18:07:08 +000010967s390_irgen_LDXBR(UChar m3, UChar m4 __attribute__((unused)),
10968 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000010969{
florian125e20d2012-10-07 15:42:37 +000010970 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian12b0bca2012-09-05 20:05:20 +000010971 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +000010972 m3 = S390_BFP_ROUND_PER_FPC;
florian12b0bca2012-09-05 20:05:20 +000010973 }
sewardj2019a972011-03-07 16:04:07 +000010974 IRTemp result = newTemp(Ity_F64);
10975
floriandb4fcaa2012-09-05 19:54:08 +000010976 assign(result, binop(Iop_F128toF64, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +000010977 get_fpr_pair(r2)));
sewardj2019a972011-03-07 16:04:07 +000010978 put_fpr_dw0(r1, mkexpr(result));
10979
10980 return "ldxbr";
10981}
10982
florian55085f82012-11-21 00:36:55 +000010983static const HChar *
florian4b8efad2012-09-02 18:07:08 +000010984s390_irgen_LEXBR(UChar m3, UChar m4 __attribute__((unused)),
10985 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000010986{
florian125e20d2012-10-07 15:42:37 +000010987 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian12b0bca2012-09-05 20:05:20 +000010988 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +000010989 m3 = S390_BFP_ROUND_PER_FPC;
florian12b0bca2012-09-05 20:05:20 +000010990 }
sewardj2019a972011-03-07 16:04:07 +000010991 IRTemp result = newTemp(Ity_F32);
10992
floriandb4fcaa2012-09-05 19:54:08 +000010993 assign(result, binop(Iop_F128toF32, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +000010994 get_fpr_pair(r2)));
sewardj2019a972011-03-07 16:04:07 +000010995 put_fpr_w0(r1, mkexpr(result));
10996
10997 return "lexbr";
10998}
10999
florian55085f82012-11-21 00:36:55 +000011000static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011001s390_irgen_MXBR(UChar r1, UChar r2)
11002{
11003 IRTemp op1 = newTemp(Ity_F128);
11004 IRTemp op2 = newTemp(Ity_F128);
11005 IRTemp result = newTemp(Ity_F128);
florian125e20d2012-10-07 15:42:37 +000011006 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011007
11008 assign(op1, get_fpr_pair(r1));
11009 assign(op2, get_fpr_pair(r2));
floriandb4fcaa2012-09-05 19:54:08 +000011010 assign(result, triop(Iop_MulF128, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +000011011 mkexpr(op2)));
11012 put_fpr_pair(r1, mkexpr(result));
11013
11014 return "mxbr";
11015}
11016
florian55085f82012-11-21 00:36:55 +000011017static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011018s390_irgen_MAEBR(UChar r1, UChar r3, UChar r2)
11019{
florian125e20d2012-10-07 15:42:37 +000011020 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
florian847684d2012-09-05 04:19:09 +000011021
floriandb4fcaa2012-09-05 19:54:08 +000011022 put_fpr_w0(r1, qop(Iop_MAddF32, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000011023 get_fpr_w0(r3), get_fpr_w0(r2), get_fpr_w0(r1)));
sewardj2019a972011-03-07 16:04:07 +000011024
11025 return "maebr";
11026}
11027
florian55085f82012-11-21 00:36:55 +000011028static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011029s390_irgen_MADBR(UChar r1, UChar r3, UChar r2)
11030{
florian125e20d2012-10-07 15:42:37 +000011031 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
florian847684d2012-09-05 04:19:09 +000011032
floriandb4fcaa2012-09-05 19:54:08 +000011033 put_fpr_dw0(r1, qop(Iop_MAddF64, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000011034 get_fpr_dw0(r3), get_fpr_dw0(r2), get_fpr_dw0(r1)));
sewardj2019a972011-03-07 16:04:07 +000011035
11036 return "madbr";
11037}
11038
florian55085f82012-11-21 00:36:55 +000011039static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011040s390_irgen_MAEB(UChar r3, IRTemp op2addr, UChar r1)
11041{
11042 IRExpr *op2 = load(Ity_F32, mkexpr(op2addr));
florian125e20d2012-10-07 15:42:37 +000011043 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011044
floriandb4fcaa2012-09-05 19:54:08 +000011045 put_fpr_w0(r1, qop(Iop_MAddF32, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000011046 get_fpr_w0(r3), op2, get_fpr_w0(r1)));
sewardj2019a972011-03-07 16:04:07 +000011047
11048 return "maeb";
11049}
11050
florian55085f82012-11-21 00:36:55 +000011051static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011052s390_irgen_MADB(UChar r3, IRTemp op2addr, UChar r1)
11053{
11054 IRExpr *op2 = load(Ity_F64, mkexpr(op2addr));
florian125e20d2012-10-07 15:42:37 +000011055 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011056
floriandb4fcaa2012-09-05 19:54:08 +000011057 put_fpr_dw0(r1, qop(Iop_MAddF64, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000011058 get_fpr_dw0(r3), op2, get_fpr_dw0(r1)));
sewardj2019a972011-03-07 16:04:07 +000011059
11060 return "madb";
11061}
11062
florian55085f82012-11-21 00:36:55 +000011063static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011064s390_irgen_MSEBR(UChar r1, UChar r3, UChar r2)
11065{
florian125e20d2012-10-07 15:42:37 +000011066 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
florian847684d2012-09-05 04:19:09 +000011067
floriandb4fcaa2012-09-05 19:54:08 +000011068 put_fpr_w0(r1, qop(Iop_MSubF32, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000011069 get_fpr_w0(r3), get_fpr_w0(r2), get_fpr_w0(r1)));
sewardj2019a972011-03-07 16:04:07 +000011070
11071 return "msebr";
11072}
11073
florian55085f82012-11-21 00:36:55 +000011074static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011075s390_irgen_MSDBR(UChar r1, UChar r3, UChar r2)
11076{
florian125e20d2012-10-07 15:42:37 +000011077 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
florian847684d2012-09-05 04:19:09 +000011078
floriandb4fcaa2012-09-05 19:54:08 +000011079 put_fpr_dw0(r1, qop(Iop_MSubF64, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000011080 get_fpr_dw0(r3), get_fpr_dw0(r2), get_fpr_dw0(r1)));
sewardj2019a972011-03-07 16:04:07 +000011081
11082 return "msdbr";
11083}
11084
florian55085f82012-11-21 00:36:55 +000011085static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011086s390_irgen_MSEB(UChar r3, IRTemp op2addr, UChar r1)
11087{
11088 IRExpr *op2 = load(Ity_F32, mkexpr(op2addr));
florian125e20d2012-10-07 15:42:37 +000011089 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011090
floriandb4fcaa2012-09-05 19:54:08 +000011091 put_fpr_w0(r1, qop(Iop_MSubF32, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000011092 get_fpr_w0(r3), op2, get_fpr_w0(r1)));
sewardj2019a972011-03-07 16:04:07 +000011093
11094 return "mseb";
11095}
11096
florian55085f82012-11-21 00:36:55 +000011097static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011098s390_irgen_MSDB(UChar r3, IRTemp op2addr, UChar r1)
11099{
11100 IRExpr *op2 = load(Ity_F64, mkexpr(op2addr));
florian125e20d2012-10-07 15:42:37 +000011101 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011102
floriandb4fcaa2012-09-05 19:54:08 +000011103 put_fpr_dw0(r1, qop(Iop_MSubF64, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000011104 get_fpr_dw0(r3), op2, get_fpr_dw0(r1)));
sewardj2019a972011-03-07 16:04:07 +000011105
11106 return "msdb";
11107}
11108
florian55085f82012-11-21 00:36:55 +000011109static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011110s390_irgen_SQEBR(UChar r1, UChar r2)
11111{
11112 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +000011113 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011114
floriandb4fcaa2012-09-05 19:54:08 +000011115 assign(result, binop(Iop_SqrtF32, mkexpr(rounding_mode), get_fpr_w0(r2)));
sewardj2019a972011-03-07 16:04:07 +000011116 put_fpr_w0(r1, mkexpr(result));
11117
11118 return "sqebr";
11119}
11120
florian55085f82012-11-21 00:36:55 +000011121static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011122s390_irgen_SQDBR(UChar r1, UChar r2)
11123{
11124 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +000011125 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011126
floriandb4fcaa2012-09-05 19:54:08 +000011127 assign(result, binop(Iop_SqrtF64, mkexpr(rounding_mode), get_fpr_dw0(r2)));
sewardj2019a972011-03-07 16:04:07 +000011128 put_fpr_dw0(r1, mkexpr(result));
11129
11130 return "sqdbr";
11131}
11132
florian55085f82012-11-21 00:36:55 +000011133static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011134s390_irgen_SQXBR(UChar r1, UChar r2)
11135{
11136 IRTemp result = newTemp(Ity_F128);
florian125e20d2012-10-07 15:42:37 +000011137 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011138
floriandb4fcaa2012-09-05 19:54:08 +000011139 assign(result, binop(Iop_SqrtF128, mkexpr(rounding_mode),
11140 get_fpr_pair(r2)));
sewardj2019a972011-03-07 16:04:07 +000011141 put_fpr_pair(r1, mkexpr(result));
11142
11143 return "sqxbr";
11144}
11145
florian55085f82012-11-21 00:36:55 +000011146static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011147s390_irgen_SQEB(UChar r1, IRTemp op2addr)
11148{
11149 IRTemp op = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +000011150 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011151
11152 assign(op, load(Ity_F32, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +000011153 put_fpr_w0(r1, binop(Iop_SqrtF32, mkexpr(rounding_mode), mkexpr(op)));
sewardj2019a972011-03-07 16:04:07 +000011154
11155 return "sqeb";
11156}
11157
florian55085f82012-11-21 00:36:55 +000011158static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011159s390_irgen_SQDB(UChar r1, IRTemp op2addr)
11160{
11161 IRTemp op = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +000011162 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011163
11164 assign(op, load(Ity_F64, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +000011165 put_fpr_dw0(r1, binop(Iop_SqrtF64, mkexpr(rounding_mode), mkexpr(op)));
sewardj2019a972011-03-07 16:04:07 +000011166
11167 return "sqdb";
11168}
11169
florian55085f82012-11-21 00:36:55 +000011170static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011171s390_irgen_SXBR(UChar r1, UChar r2)
11172{
11173 IRTemp op1 = newTemp(Ity_F128);
11174 IRTemp op2 = newTemp(Ity_F128);
11175 IRTemp result = newTemp(Ity_F128);
florian125e20d2012-10-07 15:42:37 +000011176 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011177
11178 assign(op1, get_fpr_pair(r1));
11179 assign(op2, get_fpr_pair(r2));
floriandb4fcaa2012-09-05 19:54:08 +000011180 assign(result, triop(Iop_SubF128, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +000011181 mkexpr(op2)));
11182 put_fpr_pair(r1, mkexpr(result));
11183 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
11184
11185 return "sxbr";
11186}
11187
florian55085f82012-11-21 00:36:55 +000011188static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011189s390_irgen_TCEB(UChar r1, IRTemp op2addr)
11190{
11191 IRTemp value = newTemp(Ity_F32);
11192
11193 assign(value, get_fpr_w0(r1));
11194
11195 s390_cc_thunk_putFZ(S390_CC_OP_BFP_TDC_32, value, op2addr);
11196
11197 return "tceb";
11198}
11199
florian55085f82012-11-21 00:36:55 +000011200static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011201s390_irgen_TCDB(UChar r1, IRTemp op2addr)
11202{
11203 IRTemp value = newTemp(Ity_F64);
11204
11205 assign(value, get_fpr_dw0(r1));
11206
11207 s390_cc_thunk_putFZ(S390_CC_OP_BFP_TDC_64, value, op2addr);
11208
11209 return "tcdb";
11210}
11211
florian55085f82012-11-21 00:36:55 +000011212static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011213s390_irgen_TCXB(UChar r1, IRTemp op2addr)
11214{
11215 IRTemp value = newTemp(Ity_F128);
11216
11217 assign(value, get_fpr_pair(r1));
11218
11219 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_TDC_128, value, op2addr);
11220
11221 return "tcxb";
11222}
11223
florian55085f82012-11-21 00:36:55 +000011224static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011225s390_irgen_LCDFR(UChar r1, UChar r2)
11226{
11227 IRTemp result = newTemp(Ity_F64);
11228
11229 assign(result, unop(Iop_NegF64, get_fpr_dw0(r2)));
11230 put_fpr_dw0(r1, mkexpr(result));
11231
11232 return "lcdfr";
11233}
11234
florian55085f82012-11-21 00:36:55 +000011235static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011236s390_irgen_LNDFR(UChar r1, UChar r2)
11237{
11238 IRTemp result = newTemp(Ity_F64);
11239
11240 assign(result, unop(Iop_NegF64, unop(Iop_AbsF64, get_fpr_dw0(r2))));
11241 put_fpr_dw0(r1, mkexpr(result));
11242
11243 return "lndfr";
11244}
11245
florian55085f82012-11-21 00:36:55 +000011246static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011247s390_irgen_LPDFR(UChar r1, UChar r2)
11248{
11249 IRTemp result = newTemp(Ity_F64);
11250
11251 assign(result, unop(Iop_AbsF64, get_fpr_dw0(r2)));
11252 put_fpr_dw0(r1, mkexpr(result));
11253
11254 return "lpdfr";
11255}
11256
florian55085f82012-11-21 00:36:55 +000011257static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011258s390_irgen_LDGR(UChar r1, UChar r2)
11259{
11260 put_fpr_dw0(r1, unop(Iop_ReinterpI64asF64, get_gpr_dw0(r2)));
11261
11262 return "ldgr";
11263}
11264
florian55085f82012-11-21 00:36:55 +000011265static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011266s390_irgen_LGDR(UChar r1, UChar r2)
11267{
11268 put_gpr_dw0(r1, unop(Iop_ReinterpF64asI64, get_fpr_dw0(r2)));
11269
11270 return "lgdr";
11271}
11272
11273
florian55085f82012-11-21 00:36:55 +000011274static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011275s390_irgen_CPSDR(UChar r3, UChar r1, UChar r2)
11276{
11277 IRTemp sign = newTemp(Ity_I64);
11278 IRTemp value = newTemp(Ity_I64);
11279
11280 assign(sign, binop(Iop_And64, unop(Iop_ReinterpF64asI64, get_fpr_dw0(r3)),
11281 mkU64(1ULL << 63)));
11282 assign(value, binop(Iop_And64, unop(Iop_ReinterpF64asI64, get_fpr_dw0(r2)),
11283 mkU64((1ULL << 63) - 1)));
11284 put_fpr_dw0(r1, unop(Iop_ReinterpI64asF64, binop(Iop_Or64, mkexpr(value),
11285 mkexpr(sign))));
11286
11287 return "cpsdr";
11288}
11289
11290
sewardj2019a972011-03-07 16:04:07 +000011291static IRExpr *
11292s390_call_cvb(IRExpr *in)
11293{
11294 IRExpr **args, *call;
11295
11296 args = mkIRExprVec_1(in);
11297 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
11298 "s390_do_cvb", &s390_do_cvb, args);
11299
11300 /* Nothing is excluded from definedness checking. */
11301 call->Iex.CCall.cee->mcx_mask = 0;
11302
11303 return call;
11304}
11305
florian55085f82012-11-21 00:36:55 +000011306static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011307s390_irgen_CVB(UChar r1, IRTemp op2addr)
11308{
11309 put_gpr_w1(r1, s390_call_cvb(load(Ity_I64, mkexpr(op2addr))));
11310
11311 return "cvb";
11312}
11313
florian55085f82012-11-21 00:36:55 +000011314static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011315s390_irgen_CVBY(UChar r1, IRTemp op2addr)
11316{
11317 put_gpr_w1(r1, s390_call_cvb(load(Ity_I64, mkexpr(op2addr))));
11318
11319 return "cvby";
11320}
11321
11322
sewardj2019a972011-03-07 16:04:07 +000011323static IRExpr *
11324s390_call_cvd(IRExpr *in)
11325{
11326 IRExpr **args, *call;
11327
11328 args = mkIRExprVec_1(in);
11329 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
11330 "s390_do_cvd", &s390_do_cvd, args);
11331
11332 /* Nothing is excluded from definedness checking. */
11333 call->Iex.CCall.cee->mcx_mask = 0;
11334
11335 return call;
11336}
11337
florian55085f82012-11-21 00:36:55 +000011338static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011339s390_irgen_CVD(UChar r1, IRTemp op2addr)
11340{
florian11b8ee82012-08-06 13:35:33 +000011341 store(mkexpr(op2addr), s390_call_cvd(unop(Iop_32Uto64, get_gpr_w1(r1))));
sewardj2019a972011-03-07 16:04:07 +000011342
11343 return "cvd";
11344}
11345
florian55085f82012-11-21 00:36:55 +000011346static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011347s390_irgen_CVDY(UChar r1, IRTemp op2addr)
11348{
11349 store(mkexpr(op2addr), s390_call_cvd(get_gpr_w1(r1)));
11350
11351 return "cvdy";
11352}
11353
florian55085f82012-11-21 00:36:55 +000011354static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011355s390_irgen_FLOGR(UChar r1, UChar r2)
11356{
11357 IRTemp input = newTemp(Ity_I64);
11358 IRTemp not_zero = newTemp(Ity_I64);
11359 IRTemp tmpnum = newTemp(Ity_I64);
11360 IRTemp num = newTemp(Ity_I64);
11361 IRTemp shift_amount = newTemp(Ity_I8);
11362
11363 /* We use the "count leading zeroes" operator because the number of
11364 leading zeroes is identical with the bit position of the first '1' bit.
11365 However, that operator does not work when the input value is zero.
11366 Therefore, we set the LSB of the input value to 1 and use Clz64 on
11367 the modified value. If input == 0, then the result is 64. Otherwise,
11368 the result of Clz64 is what we want. */
11369
11370 assign(input, get_gpr_dw0(r2));
11371 assign(not_zero, binop(Iop_Or64, mkexpr(input), mkU64(1)));
11372 assign(tmpnum, unop(Iop_Clz64, mkexpr(not_zero)));
11373
11374 /* num = (input == 0) ? 64 : tmpnum */
11375 assign(num, mkite(binop(Iop_CmpEQ64, mkexpr(input), mkU64(0)),
11376 /* == 0 */ mkU64(64),
11377 /* != 0 */ mkexpr(tmpnum)));
11378
11379 put_gpr_dw0(r1, mkexpr(num));
11380
11381 /* Set the leftmost '1' bit of the input value to zero. The general scheme
11382 is to first shift the input value by NUM + 1 bits to the left which
11383 causes the leftmost '1' bit to disappear. Then we shift logically to
11384 the right by NUM + 1 bits. Because the semantics of Iop_Shl64 and
11385 Iop_Shr64 are undefined if the shift-amount is greater than or equal to
11386 the width of the value-to-be-shifted, we need to special case
11387 NUM + 1 >= 64. This is equivalent to INPUT != 0 && INPUT != 1.
11388 For both such INPUT values the result will be 0. */
11389
11390 assign(shift_amount, unop(Iop_64to8, binop(Iop_Add64, mkexpr(num),
11391 mkU64(1))));
11392
11393 put_gpr_dw0(r1 + 1,
florian6ad49522011-09-09 02:38:55 +000011394 mkite(binop(Iop_CmpLE64U, mkexpr(input), mkU64(1)),
11395 /* == 0 || == 1*/ mkU64(0),
11396 /* otherwise */
11397 binop(Iop_Shr64,
11398 binop(Iop_Shl64, mkexpr(input),
11399 mkexpr(shift_amount)),
11400 mkexpr(shift_amount))));
sewardj2019a972011-03-07 16:04:07 +000011401
11402 /* Compare the original value as an unsigned integer with 0. */
11403 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, input,
11404 mktemp(Ity_I64, mkU64(0)), False);
11405
11406 return "flogr";
11407}
11408
florian55085f82012-11-21 00:36:55 +000011409static const HChar *
sewardj1e5fea62011-05-17 16:18:36 +000011410s390_irgen_STCK(IRTemp op2addr)
11411{
11412 IRDirty *d;
11413 IRTemp cc = newTemp(Ity_I64);
11414
11415 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STCK",
11416 &s390x_dirtyhelper_STCK,
11417 mkIRExprVec_1(mkexpr(op2addr)));
11418 d->mFx = Ifx_Write;
11419 d->mAddr = mkexpr(op2addr);
11420 d->mSize = 8;
11421 stmt(IRStmt_Dirty(d));
11422 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
11423 mkexpr(cc), mkU64(0), mkU64(0));
11424 return "stck";
11425}
11426
florian55085f82012-11-21 00:36:55 +000011427static const HChar *
sewardj1e5fea62011-05-17 16:18:36 +000011428s390_irgen_STCKF(IRTemp op2addr)
11429{
florianc5c669b2012-08-26 14:32:28 +000011430 if (! s390_host_has_stckf) {
floriane75dafa2012-09-01 17:54:09 +000011431 emulation_failure(EmFail_S390X_stckf);
florianc5c669b2012-08-26 14:32:28 +000011432 } else {
11433 IRTemp cc = newTemp(Ity_I64);
sewardj1e5fea62011-05-17 16:18:36 +000011434
florianc5c669b2012-08-26 14:32:28 +000011435 IRDirty *d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STCKF",
11436 &s390x_dirtyhelper_STCKF,
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 }
sewardj1e5fea62011-05-17 16:18:36 +000011445 return "stckf";
11446}
11447
florian55085f82012-11-21 00:36:55 +000011448static const HChar *
sewardj1e5fea62011-05-17 16:18:36 +000011449s390_irgen_STCKE(IRTemp op2addr)
11450{
11451 IRDirty *d;
11452 IRTemp cc = newTemp(Ity_I64);
11453
11454 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STCKE",
11455 &s390x_dirtyhelper_STCKE,
11456 mkIRExprVec_1(mkexpr(op2addr)));
11457 d->mFx = Ifx_Write;
11458 d->mAddr = mkexpr(op2addr);
11459 d->mSize = 16;
11460 stmt(IRStmt_Dirty(d));
11461 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
11462 mkexpr(cc), mkU64(0), mkU64(0));
11463 return "stcke";
11464}
11465
florian55085f82012-11-21 00:36:55 +000011466static const HChar *
florian933065d2011-07-11 01:48:02 +000011467s390_irgen_STFLE(IRTemp op2addr)
11468{
florian4e0083e2012-08-26 03:41:56 +000011469 if (! s390_host_has_stfle) {
floriane75dafa2012-09-01 17:54:09 +000011470 emulation_failure(EmFail_S390X_stfle);
florian4e0083e2012-08-26 03:41:56 +000011471 return "stfle";
11472 }
11473
florian933065d2011-07-11 01:48:02 +000011474 IRDirty *d;
11475 IRTemp cc = newTemp(Ity_I64);
11476
11477 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STFLE",
11478 &s390x_dirtyhelper_STFLE,
11479 mkIRExprVec_1(mkexpr(op2addr)));
11480
11481 d->needsBBP = 1; /* Need to pass pointer to guest state to helper */
11482
sewardjc9069f22012-06-01 16:09:50 +000011483 d->nFxState = 1;
11484 vex_bzero(&d->fxState, sizeof(d->fxState));
11485
florian933065d2011-07-11 01:48:02 +000011486 d->fxState[0].fx = Ifx_Modify; /* read then write */
11487 d->fxState[0].offset = S390X_GUEST_OFFSET(guest_r0);
11488 d->fxState[0].size = sizeof(ULong);
florian933065d2011-07-11 01:48:02 +000011489
11490 d->mAddr = mkexpr(op2addr);
11491 /* Pretend all double words are written */
11492 d->mSize = S390_NUM_FACILITY_DW * sizeof(ULong);
11493 d->mFx = Ifx_Write;
11494
11495 stmt(IRStmt_Dirty(d));
11496
11497 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET), mkexpr(cc), mkU64(0), mkU64(0));
11498
11499 return "stfle";
11500}
11501
florian55085f82012-11-21 00:36:55 +000011502static const HChar *
floriana4384a32011-08-11 16:58:45 +000011503s390_irgen_CKSM(UChar r1,UChar r2)
11504{
11505 IRTemp addr = newTemp(Ity_I64);
11506 IRTemp op = newTemp(Ity_I32);
11507 IRTemp len = newTemp(Ity_I64);
11508 IRTemp oldval = newTemp(Ity_I32);
11509 IRTemp mask = newTemp(Ity_I32);
11510 IRTemp newop = newTemp(Ity_I32);
11511 IRTemp result = newTemp(Ity_I32);
11512 IRTemp result1 = newTemp(Ity_I32);
11513 IRTemp inc = newTemp(Ity_I64);
11514
11515 assign(oldval, get_gpr_w1(r1));
11516 assign(addr, get_gpr_dw0(r2));
11517 assign(len, get_gpr_dw0(r2+1));
11518
11519 /* Condition code is always zero. */
11520 s390_cc_set(0);
11521
11522 /* If length is zero, there is no need to calculate the checksum */
florian6820ba52012-07-26 02:01:50 +000011523 next_insn_if(binop(Iop_CmpEQ64, mkexpr(len), mkU64(0)));
floriana4384a32011-08-11 16:58:45 +000011524
11525 /* Assiging the increment variable to adjust address and length
11526 later on. */
11527 assign(inc, mkite(binop(Iop_CmpLT64U, mkexpr(len), mkU64(4)),
11528 mkexpr(len), mkU64(4)));
11529
11530 /* If length < 4 the final 4-byte 2nd operand value is computed by
11531 appending the remaining bytes to the right with 0. This is done
11532 by AND'ing the 4 bytes loaded from memory with an appropriate
11533 mask. If length >= 4, that mask is simply 0xffffffff. */
11534
11535 assign(mask, mkite(binop(Iop_CmpLT64U, mkexpr(len), mkU64(4)),
11536 /* Mask computation when len < 4:
11537 0xffffffff << (32 - (len % 4)*8) */
11538 binop(Iop_Shl32, mkU32(0xffffffff),
11539 unop(Iop_32to8,
11540 binop(Iop_Sub32, mkU32(32),
11541 binop(Iop_Shl32,
11542 unop(Iop_64to32,
11543 binop(Iop_And64,
11544 mkexpr(len), mkU64(3))),
11545 mkU8(3))))),
11546 mkU32(0xffffffff)));
11547
11548 assign(op, load(Ity_I32, mkexpr(addr)));
11549 assign(newop, binop(Iop_And32, mkexpr(op), mkexpr(mask)));
11550 assign(result, binop(Iop_Add32, mkexpr(newop), mkexpr(oldval)));
11551
11552 /* Checking for carry */
11553 assign(result1, mkite(binop(Iop_CmpLT32U, mkexpr(result), mkexpr(newop)),
11554 binop(Iop_Add32, mkexpr(result), mkU32(1)),
11555 mkexpr(result)));
11556
11557 put_gpr_w1(r1, mkexpr(result1));
11558 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr), mkexpr(inc)));
11559 put_gpr_dw0(r2+1, binop(Iop_Sub64, mkexpr(len), mkexpr(inc)));
11560
florian6820ba52012-07-26 02:01:50 +000011561 iterate_if(binop(Iop_CmpNE64, mkexpr(len), mkU64(0)));
floriana4384a32011-08-11 16:58:45 +000011562
11563 return "cksm";
11564}
11565
florian55085f82012-11-21 00:36:55 +000011566static const HChar *
florian9af37692012-01-15 21:01:16 +000011567s390_irgen_TROO(UChar m3, UChar r1, UChar r2)
11568{
11569 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
11570 src_addr = newTemp(Ity_I64);
11571 des_addr = newTemp(Ity_I64);
11572 tab_addr = newTemp(Ity_I64);
11573 test_byte = newTemp(Ity_I8);
11574 src_len = newTemp(Ity_I64);
11575
11576 assign(src_addr, get_gpr_dw0(r2));
11577 assign(des_addr, get_gpr_dw0(r1));
11578 assign(tab_addr, get_gpr_dw0(1));
florian53518532012-01-18 14:00:31 +000011579 assign(src_len, get_gpr_dw0(r1+1));
florian9af37692012-01-15 21:01:16 +000011580 assign(test_byte, get_gpr_b7(0));
11581
11582 IRTemp op = newTemp(Ity_I8);
11583 IRTemp op1 = newTemp(Ity_I8);
11584 IRTemp result = newTemp(Ity_I64);
11585
11586 /* End of source string? We're done; proceed to next insn */
11587 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000011588 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian9af37692012-01-15 21:01:16 +000011589
11590 /* Load character from source string, index translation table and
11591 store translated character in op1. */
11592 assign(op, load(Ity_I8, mkexpr(src_addr)));
11593
11594 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)),
11595 mkexpr(tab_addr)));
11596 assign(op1, load(Ity_I8, mkexpr(result)));
11597
11598 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
11599 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000011600 next_insn_if(binop(Iop_CmpEQ8, mkexpr(op1), mkexpr(test_byte)));
florian9af37692012-01-15 21:01:16 +000011601 }
11602 store(get_gpr_dw0(r1), mkexpr(op1));
11603
11604 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(1)));
11605 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(1)));
11606 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(1)));
11607
florian6820ba52012-07-26 02:01:50 +000011608 iterate();
florian9af37692012-01-15 21:01:16 +000011609
11610 return "troo";
11611}
11612
florian55085f82012-11-21 00:36:55 +000011613static const HChar *
florian730448f2012-02-04 17:07:07 +000011614s390_irgen_TRTO(UChar m3, UChar r1, UChar r2)
11615{
11616 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
11617 src_addr = newTemp(Ity_I64);
11618 des_addr = newTemp(Ity_I64);
11619 tab_addr = newTemp(Ity_I64);
11620 test_byte = newTemp(Ity_I8);
11621 src_len = newTemp(Ity_I64);
11622
11623 assign(src_addr, get_gpr_dw0(r2));
11624 assign(des_addr, get_gpr_dw0(r1));
11625 assign(tab_addr, get_gpr_dw0(1));
11626 assign(src_len, get_gpr_dw0(r1+1));
11627 assign(test_byte, get_gpr_b7(0));
11628
11629 IRTemp op = newTemp(Ity_I16);
11630 IRTemp op1 = newTemp(Ity_I8);
11631 IRTemp result = newTemp(Ity_I64);
11632
11633 /* End of source string? We're done; proceed to next insn */
11634 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000011635 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian730448f2012-02-04 17:07:07 +000011636
11637 /* Load character from source string, index translation table and
11638 store translated character in op1. */
11639 assign(op, load(Ity_I16, mkexpr(src_addr)));
11640
11641 assign(result, binop(Iop_Add64, unop(Iop_16Uto64, mkexpr(op)),
11642 mkexpr(tab_addr)));
11643
11644 assign(op1, load(Ity_I8, mkexpr(result)));
11645
11646 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
11647 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000011648 next_insn_if(binop(Iop_CmpEQ8, mkexpr(op1), mkexpr(test_byte)));
florian730448f2012-02-04 17:07:07 +000011649 }
11650 store(get_gpr_dw0(r1), mkexpr(op1));
11651
11652 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(2)));
11653 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(1)));
11654 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(2)));
11655
florian6820ba52012-07-26 02:01:50 +000011656 iterate();
florian730448f2012-02-04 17:07:07 +000011657
11658 return "trto";
11659}
11660
florian55085f82012-11-21 00:36:55 +000011661static const HChar *
florian730448f2012-02-04 17:07:07 +000011662s390_irgen_TROT(UChar m3, UChar r1, UChar r2)
11663{
11664 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
11665 src_addr = newTemp(Ity_I64);
11666 des_addr = newTemp(Ity_I64);
11667 tab_addr = newTemp(Ity_I64);
11668 test_byte = newTemp(Ity_I16);
11669 src_len = newTemp(Ity_I64);
11670
11671 assign(src_addr, get_gpr_dw0(r2));
11672 assign(des_addr, get_gpr_dw0(r1));
11673 assign(tab_addr, get_gpr_dw0(1));
11674 assign(src_len, get_gpr_dw0(r1+1));
11675 assign(test_byte, get_gpr_hw3(0));
11676
11677 IRTemp op = newTemp(Ity_I8);
11678 IRTemp op1 = newTemp(Ity_I16);
11679 IRTemp result = newTemp(Ity_I64);
11680
11681 /* End of source string? We're done; proceed to next insn */
11682 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000011683 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian730448f2012-02-04 17:07:07 +000011684
11685 /* Load character from source string, index translation table and
11686 store translated character in op1. */
11687 assign(op, binop(Iop_Shl8, load(Ity_I8, mkexpr(src_addr)), mkU8(1)));
11688
11689 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)),
11690 mkexpr(tab_addr)));
11691 assign(op1, load(Ity_I16, mkexpr(result)));
11692
11693 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
11694 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000011695 next_insn_if(binop(Iop_CmpEQ16, mkexpr(op1), mkexpr(test_byte)));
florian730448f2012-02-04 17:07:07 +000011696 }
11697 store(get_gpr_dw0(r1), mkexpr(op1));
11698
11699 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(1)));
11700 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(2)));
11701 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(1)));
11702
florian6820ba52012-07-26 02:01:50 +000011703 iterate();
florian730448f2012-02-04 17:07:07 +000011704
11705 return "trot";
11706}
11707
florian55085f82012-11-21 00:36:55 +000011708static const HChar *
florian730448f2012-02-04 17:07:07 +000011709s390_irgen_TRTT(UChar m3, UChar r1, UChar r2)
11710{
11711 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
11712 src_addr = newTemp(Ity_I64);
11713 des_addr = newTemp(Ity_I64);
11714 tab_addr = newTemp(Ity_I64);
11715 test_byte = newTemp(Ity_I16);
11716 src_len = newTemp(Ity_I64);
11717
11718 assign(src_addr, get_gpr_dw0(r2));
11719 assign(des_addr, get_gpr_dw0(r1));
11720 assign(tab_addr, get_gpr_dw0(1));
11721 assign(src_len, get_gpr_dw0(r1+1));
11722 assign(test_byte, get_gpr_hw3(0));
11723
11724 IRTemp op = newTemp(Ity_I16);
11725 IRTemp op1 = newTemp(Ity_I16);
11726 IRTemp result = newTemp(Ity_I64);
11727
11728 /* End of source string? We're done; proceed to next insn */
11729 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000011730 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian730448f2012-02-04 17:07:07 +000011731
11732 /* Load character from source string, index translation table and
11733 store translated character in op1. */
11734 assign(op, binop(Iop_Shl16, load(Ity_I16, mkexpr(src_addr)), mkU8(1)));
11735
11736 assign(result, binop(Iop_Add64, unop(Iop_16Uto64, mkexpr(op)),
11737 mkexpr(tab_addr)));
11738 assign(op1, load(Ity_I16, mkexpr(result)));
11739
11740 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
11741 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000011742 next_insn_if(binop(Iop_CmpEQ16, mkexpr(op1), mkexpr(test_byte)));
florian730448f2012-02-04 17:07:07 +000011743 }
11744
11745 store(get_gpr_dw0(r1), mkexpr(op1));
11746
11747 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(2)));
11748 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(2)));
11749 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(2)));
11750
florian6820ba52012-07-26 02:01:50 +000011751 iterate();
florian730448f2012-02-04 17:07:07 +000011752
11753 return "trtt";
11754}
11755
florian55085f82012-11-21 00:36:55 +000011756static const HChar *
florian730448f2012-02-04 17:07:07 +000011757s390_irgen_TR(UChar length, IRTemp start1, IRTemp start2)
11758{
florianf87d4fb2012-05-05 02:55:24 +000011759 IRTemp len = newTemp(Ity_I64);
florian730448f2012-02-04 17:07:07 +000011760
florianf87d4fb2012-05-05 02:55:24 +000011761 assign(len, mkU64(length));
11762 s390_irgen_TR_EX(len, start1, start2);
florian730448f2012-02-04 17:07:07 +000011763
11764 return "tr";
11765}
11766
florian55085f82012-11-21 00:36:55 +000011767static const HChar *
florian730448f2012-02-04 17:07:07 +000011768s390_irgen_TRE(UChar r1,UChar r2)
11769{
11770 IRTemp src_addr, tab_addr, src_len, test_byte;
11771 src_addr = newTemp(Ity_I64);
11772 tab_addr = newTemp(Ity_I64);
11773 src_len = newTemp(Ity_I64);
11774 test_byte = newTemp(Ity_I8);
11775
11776 assign(src_addr, get_gpr_dw0(r1));
11777 assign(src_len, get_gpr_dw0(r1+1));
11778 assign(tab_addr, get_gpr_dw0(r2));
11779 assign(test_byte, get_gpr_b7(0));
11780
11781 IRTemp op = newTemp(Ity_I8);
11782 IRTemp op1 = newTemp(Ity_I8);
11783 IRTemp result = newTemp(Ity_I64);
11784
11785 /* End of source string? We're done; proceed to next insn */
11786 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000011787 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian730448f2012-02-04 17:07:07 +000011788
11789 /* Load character from source string and compare with test byte */
11790 assign(op, load(Ity_I8, mkexpr(src_addr)));
11791
11792 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000011793 next_insn_if(binop(Iop_CmpEQ8, mkexpr(op), mkexpr(test_byte)));
florian730448f2012-02-04 17:07:07 +000011794
11795 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)),
11796 mkexpr(tab_addr)));
11797
11798 assign(op1, load(Ity_I8, mkexpr(result)));
11799
11800 store(get_gpr_dw0(r1), mkexpr(op1));
11801 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(src_addr), mkU64(1)));
11802 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(1)));
11803
florian6820ba52012-07-26 02:01:50 +000011804 iterate();
florian730448f2012-02-04 17:07:07 +000011805
11806 return "tre";
11807}
11808
floriana0100c92012-07-20 00:06:35 +000011809static IRExpr *
11810s390_call_cu21(IRExpr *srcval, IRExpr *low_surrogate)
11811{
11812 IRExpr **args, *call;
11813 args = mkIRExprVec_2(srcval, low_surrogate);
11814 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
11815 "s390_do_cu21", &s390_do_cu21, args);
11816
11817 /* Nothing is excluded from definedness checking. */
11818 call->Iex.CCall.cee->mcx_mask = 0;
11819
11820 return call;
11821}
11822
florian55085f82012-11-21 00:36:55 +000011823static const HChar *
floriana0100c92012-07-20 00:06:35 +000011824s390_irgen_CU21(UChar m3, UChar r1, UChar r2)
11825{
11826 IRTemp addr1 = newTemp(Ity_I64);
11827 IRTemp addr2 = newTemp(Ity_I64);
11828 IRTemp len1 = newTemp(Ity_I64);
11829 IRTemp len2 = newTemp(Ity_I64);
11830
11831 assign(addr1, get_gpr_dw0(r1));
11832 assign(addr2, get_gpr_dw0(r2));
11833 assign(len1, get_gpr_dw0(r1 + 1));
11834 assign(len2, get_gpr_dw0(r2 + 1));
11835
11836 /* We're processing the 2nd operand 2 bytes at a time. Therefore, if
11837 there are less than 2 bytes left, then the 2nd operand is exhausted
11838 and we're done here. cc = 0 */
11839 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000011840 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(2)));
floriana0100c92012-07-20 00:06:35 +000011841
11842 /* There are at least two bytes there. Read them. */
11843 IRTemp srcval = newTemp(Ity_I32);
11844 assign(srcval, unop(Iop_16Uto32, load(Ity_I16, mkexpr(addr2))));
11845
11846 /* Find out whether this is a high surrogate. I.e. SRCVAL lies
11847 inside the interval [0xd800 - 0xdbff] */
11848 IRTemp is_high_surrogate = newTemp(Ity_I32);
11849 IRExpr *flag1 = mkite(binop(Iop_CmpLE32U, mkU32(0xd800), mkexpr(srcval)),
11850 mkU32(1), mkU32(0));
11851 IRExpr *flag2 = mkite(binop(Iop_CmpLE32U, mkexpr(srcval), mkU32(0xdbff)),
11852 mkU32(1), mkU32(0));
11853 assign(is_high_surrogate, binop(Iop_And32, flag1, flag2));
11854
11855 /* If SRCVAL is a high surrogate and there are less than 4 bytes left,
11856 then the 2nd operand is exhausted and we're done here. cc = 0 */
11857 IRExpr *not_enough_bytes =
11858 mkite(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)), mkU32(1), mkU32(0));
11859
florian6820ba52012-07-26 02:01:50 +000011860 next_insn_if(binop(Iop_CmpEQ32,
11861 binop(Iop_And32, mkexpr(is_high_surrogate),
11862 not_enough_bytes), mkU32(1)));
floriana0100c92012-07-20 00:06:35 +000011863
11864 /* The 2nd operand is not exhausted. If the first 2 bytes are a high
11865 surrogate, read the next two bytes (low surrogate). */
11866 IRTemp low_surrogate = newTemp(Ity_I32);
11867 IRExpr *low_surrogate_addr = binop(Iop_Add64, mkexpr(addr2), mkU64(2));
11868
11869 assign(low_surrogate,
11870 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
11871 unop(Iop_16Uto32, load(Ity_I16, low_surrogate_addr)),
11872 mkU32(0))); // any value is fine; it will not be used
11873
11874 /* Call the helper */
11875 IRTemp retval = newTemp(Ity_I64);
florian11b8ee82012-08-06 13:35:33 +000011876 assign(retval, s390_call_cu21(unop(Iop_32Uto64, mkexpr(srcval)),
11877 unop(Iop_32Uto64, mkexpr(low_surrogate))));
floriana0100c92012-07-20 00:06:35 +000011878
11879 /* Before we can test whether the 1st operand is exhausted we need to
11880 test for an invalid low surrogate. Because cc=2 outranks cc=1. */
11881 if (s390_host_has_etf3 && (m3 & 0x1) == 1) {
11882 IRExpr *invalid_low_surrogate =
11883 binop(Iop_And64, mkexpr(retval), mkU64(0xff));
11884
11885 s390_cc_set(2);
florian6820ba52012-07-26 02:01:50 +000011886 next_insn_if(binop(Iop_CmpEQ64, invalid_low_surrogate, mkU64(1)));
floriana0100c92012-07-20 00:06:35 +000011887 }
11888
11889 /* Now test whether the 1st operand is exhausted */
11890 IRTemp num_bytes = newTemp(Ity_I64);
11891 assign(num_bytes, binop(Iop_And64,
11892 binop(Iop_Shr64, mkexpr(retval), mkU8(8)),
11893 mkU64(0xff)));
11894 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000011895 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
floriana0100c92012-07-20 00:06:35 +000011896
11897 /* Extract the bytes to be stored at addr1 */
11898 IRTemp data = newTemp(Ity_I64);
11899 assign(data, binop(Iop_Shr64, mkexpr(retval), mkU8(16)));
11900
11901 /* To store the bytes construct 4 dirty helper calls. The helper calls
11902 are guarded (num_bytes == 1, num_bytes == 2, etc) such that only
11903 one of them will be called at runtime. */
11904 int i;
11905 for (i = 1; i <= 4; ++i) {
11906 IRDirty *d;
11907
11908 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
11909 &s390x_dirtyhelper_CUxy,
11910 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
11911 mkexpr(num_bytes)));
11912 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
11913 d->mFx = Ifx_Write;
11914 d->mAddr = mkexpr(addr1);
11915 d->mSize = i;
11916 stmt(IRStmt_Dirty(d));
11917 }
11918
11919 /* Update source address and length */
11920 IRTemp num_src_bytes = newTemp(Ity_I64);
11921 assign(num_src_bytes,
11922 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
11923 mkU64(4), mkU64(2)));
11924 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkexpr(num_src_bytes)));
11925 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkexpr(num_src_bytes)));
11926
11927 /* Update destination address and length */
11928 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
11929 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
11930
florian6820ba52012-07-26 02:01:50 +000011931 iterate();
floriana0100c92012-07-20 00:06:35 +000011932
11933 return "cu21";
11934}
11935
florian2a415a12012-07-21 17:41:36 +000011936static IRExpr *
11937s390_call_cu24(IRExpr *srcval, IRExpr *low_surrogate)
11938{
11939 IRExpr **args, *call;
11940 args = mkIRExprVec_2(srcval, low_surrogate);
11941 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
11942 "s390_do_cu24", &s390_do_cu24, args);
11943
11944 /* Nothing is excluded from definedness checking. */
11945 call->Iex.CCall.cee->mcx_mask = 0;
11946
11947 return call;
11948}
11949
florian55085f82012-11-21 00:36:55 +000011950static const HChar *
florian2a415a12012-07-21 17:41:36 +000011951s390_irgen_CU24(UChar m3, UChar r1, UChar r2)
11952{
11953 IRTemp addr1 = newTemp(Ity_I64);
11954 IRTemp addr2 = newTemp(Ity_I64);
11955 IRTemp len1 = newTemp(Ity_I64);
11956 IRTemp len2 = newTemp(Ity_I64);
11957
11958 assign(addr1, get_gpr_dw0(r1));
11959 assign(addr2, get_gpr_dw0(r2));
11960 assign(len1, get_gpr_dw0(r1 + 1));
11961 assign(len2, get_gpr_dw0(r2 + 1));
11962
11963 /* We're processing the 2nd operand 2 bytes at a time. Therefore, if
11964 there are less than 2 bytes left, then the 2nd operand is exhausted
11965 and we're done here. cc = 0 */
11966 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000011967 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(2)));
florian2a415a12012-07-21 17:41:36 +000011968
11969 /* There are at least two bytes there. Read them. */
11970 IRTemp srcval = newTemp(Ity_I32);
11971 assign(srcval, unop(Iop_16Uto32, load(Ity_I16, mkexpr(addr2))));
11972
11973 /* Find out whether this is a high surrogate. I.e. SRCVAL lies
11974 inside the interval [0xd800 - 0xdbff] */
11975 IRTemp is_high_surrogate = newTemp(Ity_I32);
11976 IRExpr *flag1 = mkite(binop(Iop_CmpLE32U, mkU32(0xd800), mkexpr(srcval)),
11977 mkU32(1), mkU32(0));
11978 IRExpr *flag2 = mkite(binop(Iop_CmpLE32U, mkexpr(srcval), mkU32(0xdbff)),
11979 mkU32(1), mkU32(0));
11980 assign(is_high_surrogate, binop(Iop_And32, flag1, flag2));
11981
11982 /* If SRCVAL is a high surrogate and there are less than 4 bytes left,
11983 then the 2nd operand is exhausted and we're done here. cc = 0 */
11984 IRExpr *not_enough_bytes =
11985 mkite(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)), mkU32(1), mkU32(0));
11986
florian6820ba52012-07-26 02:01:50 +000011987 next_insn_if(binop(Iop_CmpEQ32,
11988 binop(Iop_And32, mkexpr(is_high_surrogate),
11989 not_enough_bytes),
11990 mkU32(1)));
florian2a415a12012-07-21 17:41:36 +000011991
11992 /* The 2nd operand is not exhausted. If the first 2 bytes are a high
11993 surrogate, read the next two bytes (low surrogate). */
11994 IRTemp low_surrogate = newTemp(Ity_I32);
11995 IRExpr *low_surrogate_addr = binop(Iop_Add64, mkexpr(addr2), mkU64(2));
11996
11997 assign(low_surrogate,
11998 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
11999 unop(Iop_16Uto32, load(Ity_I16, low_surrogate_addr)),
12000 mkU32(0))); // any value is fine; it will not be used
12001
12002 /* Call the helper */
12003 IRTemp retval = newTemp(Ity_I64);
florian11b8ee82012-08-06 13:35:33 +000012004 assign(retval, s390_call_cu24(unop(Iop_32Uto64, mkexpr(srcval)),
12005 unop(Iop_32Uto64, mkexpr(low_surrogate))));
florian2a415a12012-07-21 17:41:36 +000012006
12007 /* Before we can test whether the 1st operand is exhausted we need to
12008 test for an invalid low surrogate. Because cc=2 outranks cc=1. */
12009 if (s390_host_has_etf3 && (m3 & 0x1) == 1) {
12010 IRExpr *invalid_low_surrogate =
12011 binop(Iop_And64, mkexpr(retval), mkU64(0xff));
12012
12013 s390_cc_set(2);
florian6820ba52012-07-26 02:01:50 +000012014 next_insn_if(binop(Iop_CmpEQ64, invalid_low_surrogate, mkU64(1)));
florian2a415a12012-07-21 17:41:36 +000012015 }
12016
12017 /* Now test whether the 1st operand is exhausted */
12018 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000012019 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkU64(4)));
florian2a415a12012-07-21 17:41:36 +000012020
12021 /* Extract the bytes to be stored at addr1 */
12022 IRExpr *data = unop(Iop_64to32, binop(Iop_Shr64, mkexpr(retval), mkU8(8)));
12023
12024 store(mkexpr(addr1), data);
12025
12026 /* Update source address and length */
12027 IRTemp num_src_bytes = newTemp(Ity_I64);
12028 assign(num_src_bytes,
12029 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
12030 mkU64(4), mkU64(2)));
12031 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkexpr(num_src_bytes)));
12032 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkexpr(num_src_bytes)));
12033
12034 /* Update destination address and length */
12035 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkU64(4)));
12036 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkU64(4)));
12037
florian6820ba52012-07-26 02:01:50 +000012038 iterate();
florian2a415a12012-07-21 17:41:36 +000012039
12040 return "cu24";
12041}
floriana4384a32011-08-11 16:58:45 +000012042
florian956194b2012-07-28 22:18:32 +000012043static IRExpr *
12044s390_call_cu42(IRExpr *srcval)
12045{
12046 IRExpr **args, *call;
12047 args = mkIRExprVec_1(srcval);
12048 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
12049 "s390_do_cu42", &s390_do_cu42, args);
12050
12051 /* Nothing is excluded from definedness checking. */
12052 call->Iex.CCall.cee->mcx_mask = 0;
12053
12054 return call;
12055}
12056
florian55085f82012-11-21 00:36:55 +000012057static const HChar *
florian956194b2012-07-28 22:18:32 +000012058s390_irgen_CU42(UChar r1, UChar r2)
12059{
12060 IRTemp addr1 = newTemp(Ity_I64);
12061 IRTemp addr2 = newTemp(Ity_I64);
12062 IRTemp len1 = newTemp(Ity_I64);
12063 IRTemp len2 = newTemp(Ity_I64);
12064
12065 assign(addr1, get_gpr_dw0(r1));
12066 assign(addr2, get_gpr_dw0(r2));
12067 assign(len1, get_gpr_dw0(r1 + 1));
12068 assign(len2, get_gpr_dw0(r2 + 1));
12069
12070 /* We're processing the 2nd operand 4 bytes at a time. Therefore, if
12071 there are less than 4 bytes left, then the 2nd operand is exhausted
12072 and we're done here. cc = 0 */
12073 s390_cc_set(0);
12074 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)));
12075
12076 /* Read the 2nd operand. */
12077 IRTemp srcval = newTemp(Ity_I32);
12078 assign(srcval, load(Ity_I32, mkexpr(addr2)));
12079
12080 /* Call the helper */
12081 IRTemp retval = newTemp(Ity_I64);
florian11b8ee82012-08-06 13:35:33 +000012082 assign(retval, s390_call_cu42(unop(Iop_32Uto64, mkexpr(srcval))));
florian956194b2012-07-28 22:18:32 +000012083
12084 /* If the UTF-32 character was invalid, set cc=2 and we're done.
12085 cc=2 outranks cc=1 (1st operand exhausted) */
12086 IRExpr *invalid_character = binop(Iop_And64, mkexpr(retval), mkU64(0xff));
12087
12088 s390_cc_set(2);
12089 next_insn_if(binop(Iop_CmpEQ64, invalid_character, mkU64(1)));
12090
12091 /* Now test whether the 1st operand is exhausted */
12092 IRTemp num_bytes = newTemp(Ity_I64);
12093 assign(num_bytes, binop(Iop_And64,
12094 binop(Iop_Shr64, mkexpr(retval), mkU8(8)),
12095 mkU64(0xff)));
12096 s390_cc_set(1);
12097 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
12098
12099 /* Extract the bytes to be stored at addr1 */
12100 IRTemp data = newTemp(Ity_I64);
12101 assign(data, binop(Iop_Shr64, mkexpr(retval), mkU8(16)));
12102
12103 /* To store the bytes construct 2 dirty helper calls. The helper calls
12104 are guarded (num_bytes == 2 and num_bytes == 4, respectively) such
12105 that only one of them will be called at runtime. */
12106
12107 Int i;
12108 for (i = 2; i <= 4; ++i) {
12109 IRDirty *d;
12110
12111 if (i == 3) continue; // skip this one
12112
12113 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
12114 &s390x_dirtyhelper_CUxy,
12115 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
12116 mkexpr(num_bytes)));
12117 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
12118 d->mFx = Ifx_Write;
12119 d->mAddr = mkexpr(addr1);
12120 d->mSize = i;
12121 stmt(IRStmt_Dirty(d));
12122 }
12123
12124 /* Update source address and length */
12125 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkU64(4)));
12126 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkU64(4)));
12127
12128 /* Update destination address and length */
12129 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
12130 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
12131
12132 iterate();
12133
12134 return "cu42";
12135}
12136
florian6d9b9b22012-08-03 18:35:39 +000012137static IRExpr *
florianaf2194f2012-08-06 00:07:54 +000012138s390_call_cu41(IRExpr *srcval)
12139{
12140 IRExpr **args, *call;
12141 args = mkIRExprVec_1(srcval);
12142 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
12143 "s390_do_cu41", &s390_do_cu41, args);
12144
12145 /* Nothing is excluded from definedness checking. */
12146 call->Iex.CCall.cee->mcx_mask = 0;
12147
12148 return call;
12149}
12150
florian55085f82012-11-21 00:36:55 +000012151static const HChar *
florianaf2194f2012-08-06 00:07:54 +000012152s390_irgen_CU41(UChar r1, UChar r2)
12153{
12154 IRTemp addr1 = newTemp(Ity_I64);
12155 IRTemp addr2 = newTemp(Ity_I64);
12156 IRTemp len1 = newTemp(Ity_I64);
12157 IRTemp len2 = newTemp(Ity_I64);
12158
12159 assign(addr1, get_gpr_dw0(r1));
12160 assign(addr2, get_gpr_dw0(r2));
12161 assign(len1, get_gpr_dw0(r1 + 1));
12162 assign(len2, get_gpr_dw0(r2 + 1));
12163
12164 /* We're processing the 2nd operand 4 bytes at a time. Therefore, if
12165 there are less than 4 bytes left, then the 2nd operand is exhausted
12166 and we're done here. cc = 0 */
12167 s390_cc_set(0);
12168 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)));
12169
12170 /* Read the 2nd operand. */
12171 IRTemp srcval = newTemp(Ity_I32);
12172 assign(srcval, load(Ity_I32, mkexpr(addr2)));
12173
12174 /* Call the helper */
12175 IRTemp retval = newTemp(Ity_I64);
florian11b8ee82012-08-06 13:35:33 +000012176 assign(retval, s390_call_cu41(unop(Iop_32Uto64, mkexpr(srcval))));
florianaf2194f2012-08-06 00:07:54 +000012177
12178 /* If the UTF-32 character was invalid, set cc=2 and we're done.
12179 cc=2 outranks cc=1 (1st operand exhausted) */
12180 IRExpr *invalid_character = binop(Iop_And64, mkexpr(retval), mkU64(0xff));
12181
12182 s390_cc_set(2);
12183 next_insn_if(binop(Iop_CmpEQ64, invalid_character, mkU64(1)));
12184
12185 /* Now test whether the 1st operand is exhausted */
12186 IRTemp num_bytes = newTemp(Ity_I64);
12187 assign(num_bytes, binop(Iop_And64,
12188 binop(Iop_Shr64, mkexpr(retval), mkU8(8)),
12189 mkU64(0xff)));
12190 s390_cc_set(1);
12191 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
12192
12193 /* Extract the bytes to be stored at addr1 */
12194 IRTemp data = newTemp(Ity_I64);
12195 assign(data, binop(Iop_Shr64, mkexpr(retval), mkU8(16)));
12196
12197 /* To store the bytes construct 4 dirty helper calls. The helper calls
12198 are guarded (num_bytes == 1, num_bytes == 2, etc) such that only
12199 one of them will be called at runtime. */
12200 int i;
12201 for (i = 1; i <= 4; ++i) {
12202 IRDirty *d;
12203
12204 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
12205 &s390x_dirtyhelper_CUxy,
12206 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
12207 mkexpr(num_bytes)));
12208 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
12209 d->mFx = Ifx_Write;
12210 d->mAddr = mkexpr(addr1);
12211 d->mSize = i;
12212 stmt(IRStmt_Dirty(d));
12213 }
12214
12215 /* Update source address and length */
12216 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkU64(4)));
12217 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkU64(4)));
12218
12219 /* Update destination address and length */
12220 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
12221 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
12222
12223 iterate();
12224
12225 return "cu41";
12226}
12227
12228static IRExpr *
florian3f8a96a2012-08-05 02:59:55 +000012229s390_call_cu12_cu14_helper1(IRExpr *byte1, IRExpr *etf3_and_m3_is_1)
florian6d9b9b22012-08-03 18:35:39 +000012230{
12231 IRExpr **args, *call;
12232 args = mkIRExprVec_2(byte1, etf3_and_m3_is_1);
florian3f8a96a2012-08-05 02:59:55 +000012233 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/, "s390_do_cu12_cu14_helper1",
12234 &s390_do_cu12_cu14_helper1, args);
florian6d9b9b22012-08-03 18:35:39 +000012235
12236 /* Nothing is excluded from definedness checking. */
12237 call->Iex.CCall.cee->mcx_mask = 0;
12238
12239 return call;
12240}
12241
12242static IRExpr *
12243s390_call_cu12_helper2(IRExpr *byte1, IRExpr *byte2, IRExpr *byte3,
12244 IRExpr *byte4, IRExpr *stuff)
12245{
12246 IRExpr **args, *call;
12247 args = mkIRExprVec_5(byte1, byte2, byte3, byte4, stuff);
12248 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
12249 "s390_do_cu12_helper2", &s390_do_cu12_helper2, args);
12250
12251 /* Nothing is excluded from definedness checking. */
12252 call->Iex.CCall.cee->mcx_mask = 0;
12253
12254 return call;
12255}
12256
florian3f8a96a2012-08-05 02:59:55 +000012257static IRExpr *
12258s390_call_cu14_helper2(IRExpr *byte1, IRExpr *byte2, IRExpr *byte3,
12259 IRExpr *byte4, IRExpr *stuff)
12260{
12261 IRExpr **args, *call;
12262 args = mkIRExprVec_5(byte1, byte2, byte3, byte4, stuff);
12263 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
12264 "s390_do_cu14_helper2", &s390_do_cu14_helper2, args);
12265
12266 /* Nothing is excluded from definedness checking. */
12267 call->Iex.CCall.cee->mcx_mask = 0;
12268
12269 return call;
12270}
12271
12272static void
12273s390_irgen_cu12_cu14(UChar m3, UChar r1, UChar r2, Bool is_cu12)
florian6d9b9b22012-08-03 18:35:39 +000012274{
12275 IRTemp addr1 = newTemp(Ity_I64);
12276 IRTemp addr2 = newTemp(Ity_I64);
12277 IRTemp len1 = newTemp(Ity_I64);
12278 IRTemp len2 = newTemp(Ity_I64);
12279
12280 assign(addr1, get_gpr_dw0(r1));
12281 assign(addr2, get_gpr_dw0(r2));
12282 assign(len1, get_gpr_dw0(r1 + 1));
12283 assign(len2, get_gpr_dw0(r2 + 1));
12284
12285 UInt extended_checking = s390_host_has_etf3 && (m3 & 0x1) == 1;
12286
12287 /* We're processing the 2nd operand 1 byte at a time. Therefore, if
12288 there is less than 1 byte left, then the 2nd operand is exhausted
12289 and we're done here. cc = 0 */
12290 s390_cc_set(0);
12291 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(1)));
12292
12293 /* There is at least one byte there. Read it. */
florian11b8ee82012-08-06 13:35:33 +000012294 IRTemp byte1 = newTemp(Ity_I64);
12295 assign(byte1, unop(Iop_8Uto64, load(Ity_I8, mkexpr(addr2))));
florian6d9b9b22012-08-03 18:35:39 +000012296
12297 /* Call the helper to get number of bytes and invalid byte indicator */
12298 IRTemp retval1 = newTemp(Ity_I64);
florian3f8a96a2012-08-05 02:59:55 +000012299 assign(retval1, s390_call_cu12_cu14_helper1(mkexpr(byte1),
florian11b8ee82012-08-06 13:35:33 +000012300 mkU64(extended_checking)));
florian6d9b9b22012-08-03 18:35:39 +000012301
12302 /* Check for invalid 1st byte */
12303 IRExpr *is_invalid = unop(Iop_64to1, mkexpr(retval1));
12304 s390_cc_set(2);
12305 next_insn_if(is_invalid);
12306
12307 /* How many bytes do we have to read? */
12308 IRTemp num_src_bytes = newTemp(Ity_I64);
12309 assign(num_src_bytes, binop(Iop_Shr64, mkexpr(retval1), mkU8(8)));
12310
12311 /* Now test whether the 2nd operand is exhausted */
12312 s390_cc_set(0);
12313 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkexpr(num_src_bytes)));
12314
12315 /* Read the remaining bytes */
12316 IRExpr *cond, *addr, *byte2, *byte3, *byte4;
12317
12318 cond = binop(Iop_CmpLE64U, mkU64(2), mkexpr(num_src_bytes));
12319 addr = binop(Iop_Add64, mkexpr(addr2), mkU64(1));
florian11b8ee82012-08-06 13:35:33 +000012320 byte2 = mkite(cond, unop(Iop_8Uto64, load(Ity_I8, addr)), mkU64(0));
florian6d9b9b22012-08-03 18:35:39 +000012321 cond = binop(Iop_CmpLE64U, mkU64(3), mkexpr(num_src_bytes));
12322 addr = binop(Iop_Add64, mkexpr(addr2), mkU64(2));
florian11b8ee82012-08-06 13:35:33 +000012323 byte3 = mkite(cond, unop(Iop_8Uto64, load(Ity_I8, addr)), mkU64(0));
florian6d9b9b22012-08-03 18:35:39 +000012324 cond = binop(Iop_CmpLE64U, mkU64(4), mkexpr(num_src_bytes));
12325 addr = binop(Iop_Add64, mkexpr(addr2), mkU64(3));
florian11b8ee82012-08-06 13:35:33 +000012326 byte4 = mkite(cond, unop(Iop_8Uto64, load(Ity_I8, addr)), mkU64(0));
florian6d9b9b22012-08-03 18:35:39 +000012327
12328 /* Call the helper to get the converted value and invalid byte indicator.
12329 We can pass at most 5 arguments; therefore some encoding is needed
12330 here */
12331 IRExpr *stuff = binop(Iop_Or64,
12332 binop(Iop_Shl64, mkexpr(num_src_bytes), mkU8(1)),
12333 mkU64(extended_checking));
12334 IRTemp retval2 = newTemp(Ity_I64);
florian3f8a96a2012-08-05 02:59:55 +000012335
12336 if (is_cu12) {
12337 assign(retval2, s390_call_cu12_helper2(mkexpr(byte1), byte2, byte3,
12338 byte4, stuff));
12339 } else {
12340 assign(retval2, s390_call_cu14_helper2(mkexpr(byte1), byte2, byte3,
12341 byte4, stuff));
12342 }
florian6d9b9b22012-08-03 18:35:39 +000012343
12344 /* Check for invalid character */
12345 s390_cc_set(2);
12346 is_invalid = unop(Iop_64to1, mkexpr(retval2));
12347 next_insn_if(is_invalid);
12348
12349 /* Now test whether the 1st operand is exhausted */
12350 IRTemp num_bytes = newTemp(Ity_I64);
12351 assign(num_bytes, binop(Iop_And64,
12352 binop(Iop_Shr64, mkexpr(retval2), mkU8(8)),
12353 mkU64(0xff)));
12354 s390_cc_set(1);
12355 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
12356
12357 /* Extract the bytes to be stored at addr1 */
12358 IRTemp data = newTemp(Ity_I64);
12359 assign(data, binop(Iop_Shr64, mkexpr(retval2), mkU8(16)));
12360
florian3f8a96a2012-08-05 02:59:55 +000012361 if (is_cu12) {
12362 /* To store the bytes construct 2 dirty helper calls. The helper calls
12363 are guarded (num_bytes == 2 and num_bytes == 4, respectively) such
12364 that only one of them will be called at runtime. */
florian6d9b9b22012-08-03 18:35:39 +000012365
florian3f8a96a2012-08-05 02:59:55 +000012366 Int i;
12367 for (i = 2; i <= 4; ++i) {
12368 IRDirty *d;
florian6d9b9b22012-08-03 18:35:39 +000012369
florian3f8a96a2012-08-05 02:59:55 +000012370 if (i == 3) continue; // skip this one
florian6d9b9b22012-08-03 18:35:39 +000012371
florian3f8a96a2012-08-05 02:59:55 +000012372 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
12373 &s390x_dirtyhelper_CUxy,
12374 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
12375 mkexpr(num_bytes)));
12376 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
12377 d->mFx = Ifx_Write;
12378 d->mAddr = mkexpr(addr1);
12379 d->mSize = i;
12380 stmt(IRStmt_Dirty(d));
12381 }
12382 } else {
12383 // cu14
12384 store(mkexpr(addr1), unop(Iop_64to32, mkexpr(data)));
florian6d9b9b22012-08-03 18:35:39 +000012385 }
12386
12387 /* Update source address and length */
12388 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkexpr(num_src_bytes)));
12389 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkexpr(num_src_bytes)));
12390
12391 /* Update destination address and length */
12392 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
12393 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
12394
12395 iterate();
florian3f8a96a2012-08-05 02:59:55 +000012396}
12397
florian55085f82012-11-21 00:36:55 +000012398static const HChar *
florian3f8a96a2012-08-05 02:59:55 +000012399s390_irgen_CU12(UChar m3, UChar r1, UChar r2)
12400{
12401 s390_irgen_cu12_cu14(m3, r1, r2, /* is_cu12 = */ 1);
florian6d9b9b22012-08-03 18:35:39 +000012402
12403 return "cu12";
12404}
12405
florian55085f82012-11-21 00:36:55 +000012406static const HChar *
florian3f8a96a2012-08-05 02:59:55 +000012407s390_irgen_CU14(UChar m3, UChar r1, UChar r2)
12408{
12409 s390_irgen_cu12_cu14(m3, r1, r2, /* is_cu12 = */ 0);
12410
12411 return "cu14";
12412}
12413
florian8c88cb62012-08-26 18:58:13 +000012414static IRExpr *
12415s390_call_ecag(IRExpr *op2addr)
12416{
12417 IRExpr **args, *call;
12418
12419 args = mkIRExprVec_1(op2addr);
12420 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
12421 "s390_do_ecag", &s390_do_ecag, args);
12422
12423 /* Nothing is excluded from definedness checking. */
12424 call->Iex.CCall.cee->mcx_mask = 0;
12425
12426 return call;
12427}
12428
florian55085f82012-11-21 00:36:55 +000012429static const HChar *
floriand2129202012-09-01 20:01:39 +000012430s390_irgen_ECAG(UChar r1, UChar r3 __attribute__((unused)), IRTemp op2addr)
florian8c88cb62012-08-26 18:58:13 +000012431{
12432 if (! s390_host_has_gie) {
floriane75dafa2012-09-01 17:54:09 +000012433 emulation_failure(EmFail_S390X_ecag);
florian8c88cb62012-08-26 18:58:13 +000012434 } else {
12435 put_gpr_dw0(r1, s390_call_ecag(mkexpr(op2addr)));
12436 }
12437
12438 return "ecag";
12439}
12440
12441
sewardj2019a972011-03-07 16:04:07 +000012442/*------------------------------------------------------------*/
12443/*--- Build IR for special instructions ---*/
12444/*------------------------------------------------------------*/
12445
florianb4df7682011-07-05 02:09:01 +000012446static void
sewardj2019a972011-03-07 16:04:07 +000012447s390_irgen_client_request(void)
12448{
12449 if (0)
12450 vex_printf("%%R3 = client_request ( %%R2 )\n");
12451
florianf9e1ed72012-04-17 02:41:56 +000012452 Addr64 next = guest_IA_curr_instr + S390_SPECIAL_OP_PREAMBLE_SIZE
12453 + S390_SPECIAL_OP_SIZE;
sewardj2019a972011-03-07 16:04:07 +000012454
florianf9e1ed72012-04-17 02:41:56 +000012455 dis_res->jk_StopHere = Ijk_ClientReq;
sewardj2019a972011-03-07 16:04:07 +000012456 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +000012457
12458 put_IA(mkaddr_expr(next));
sewardj2019a972011-03-07 16:04:07 +000012459}
12460
florianb4df7682011-07-05 02:09:01 +000012461static void
sewardj2019a972011-03-07 16:04:07 +000012462s390_irgen_guest_NRADDR(void)
12463{
12464 if (0)
12465 vex_printf("%%R3 = guest_NRADDR\n");
12466
floriane88b3c92011-07-05 02:48:39 +000012467 put_gpr_dw0(3, IRExpr_Get(S390X_GUEST_OFFSET(guest_NRADDR), Ity_I64));
sewardj2019a972011-03-07 16:04:07 +000012468}
12469
florianb4df7682011-07-05 02:09:01 +000012470static void
sewardj2019a972011-03-07 16:04:07 +000012471s390_irgen_call_noredir(void)
12472{
florianf9e1ed72012-04-17 02:41:56 +000012473 Addr64 next = guest_IA_curr_instr + S390_SPECIAL_OP_PREAMBLE_SIZE
12474 + S390_SPECIAL_OP_SIZE;
12475
sewardj2019a972011-03-07 16:04:07 +000012476 /* Continue after special op */
florianf9e1ed72012-04-17 02:41:56 +000012477 put_gpr_dw0(14, mkaddr_expr(next));
sewardj2019a972011-03-07 16:04:07 +000012478
12479 /* The address is in REG1, all parameters are in the right (guest) places */
florianf9e1ed72012-04-17 02:41:56 +000012480 put_IA(get_gpr_dw0(1));
sewardj2019a972011-03-07 16:04:07 +000012481
12482 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +000012483 dis_res->jk_StopHere = Ijk_NoRedir;
sewardj2019a972011-03-07 16:04:07 +000012484}
12485
12486/* Force proper alignment for the structures below. */
12487#pragma pack(1)
12488
12489
12490static s390_decode_t
12491s390_decode_2byte_and_irgen(UChar *bytes)
12492{
12493 typedef union {
12494 struct {
12495 unsigned int op : 16;
12496 } E;
12497 struct {
12498 unsigned int op : 8;
12499 unsigned int i : 8;
12500 } I;
12501 struct {
12502 unsigned int op : 8;
12503 unsigned int r1 : 4;
12504 unsigned int r2 : 4;
12505 } RR;
12506 } formats;
12507 union {
12508 formats fmt;
12509 UShort value;
12510 } ovl;
12511
12512 vassert(sizeof(formats) == 2);
12513
12514 ((char *)(&ovl.value))[0] = bytes[0];
12515 ((char *)(&ovl.value))[1] = bytes[1];
12516
12517 switch (ovl.value & 0xffff) {
12518 case 0x0101: /* PR */ goto unimplemented;
12519 case 0x0102: /* UPT */ goto unimplemented;
12520 case 0x0104: /* PTFF */ goto unimplemented;
12521 case 0x0107: /* SCKPF */ goto unimplemented;
12522 case 0x010a: /* PFPO */ goto unimplemented;
12523 case 0x010b: /* TAM */ goto unimplemented;
12524 case 0x010c: /* SAM24 */ goto unimplemented;
12525 case 0x010d: /* SAM31 */ goto unimplemented;
12526 case 0x010e: /* SAM64 */ goto unimplemented;
12527 case 0x01ff: /* TRAP2 */ goto unimplemented;
12528 }
12529
12530 switch ((ovl.value & 0xff00) >> 8) {
12531 case 0x04: /* SPM */ goto unimplemented;
12532 case 0x05: /* BALR */ goto unimplemented;
12533 case 0x06: s390_format_RR_RR(s390_irgen_BCTR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12534 goto ok;
12535 case 0x07: s390_format_RR(s390_irgen_BCR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12536 goto ok;
12537 case 0x0a: s390_format_I(s390_irgen_SVC, ovl.fmt.I.i); goto ok;
12538 case 0x0b: /* BSM */ goto unimplemented;
12539 case 0x0c: /* BASSM */ goto unimplemented;
12540 case 0x0d: s390_format_RR_RR(s390_irgen_BASR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12541 goto ok;
florianb0c9a132011-09-08 15:37:39 +000012542 case 0x0e: s390_format_RR(s390_irgen_MVCL, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12543 goto ok;
12544 case 0x0f: s390_format_RR(s390_irgen_CLCL, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12545 goto ok;
sewardj2019a972011-03-07 16:04:07 +000012546 case 0x10: s390_format_RR_RR(s390_irgen_LPR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12547 goto ok;
12548 case 0x11: s390_format_RR_RR(s390_irgen_LNR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12549 goto ok;
12550 case 0x12: s390_format_RR_RR(s390_irgen_LTR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12551 goto ok;
12552 case 0x13: s390_format_RR_RR(s390_irgen_LCR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12553 goto ok;
12554 case 0x14: s390_format_RR_RR(s390_irgen_NR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12555 goto ok;
12556 case 0x15: s390_format_RR_RR(s390_irgen_CLR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12557 goto ok;
12558 case 0x16: s390_format_RR_RR(s390_irgen_OR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12559 goto ok;
12560 case 0x17: s390_format_RR_RR(s390_irgen_XR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12561 goto ok;
12562 case 0x18: s390_format_RR_RR(s390_irgen_LR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12563 goto ok;
12564 case 0x19: s390_format_RR_RR(s390_irgen_CR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12565 goto ok;
12566 case 0x1a: s390_format_RR_RR(s390_irgen_AR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12567 goto ok;
12568 case 0x1b: s390_format_RR_RR(s390_irgen_SR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12569 goto ok;
12570 case 0x1c: s390_format_RR_RR(s390_irgen_MR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12571 goto ok;
12572 case 0x1d: s390_format_RR_RR(s390_irgen_DR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12573 goto ok;
12574 case 0x1e: s390_format_RR_RR(s390_irgen_ALR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12575 goto ok;
12576 case 0x1f: s390_format_RR_RR(s390_irgen_SLR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12577 goto ok;
12578 case 0x20: /* LPDR */ goto unimplemented;
12579 case 0x21: /* LNDR */ goto unimplemented;
12580 case 0x22: /* LTDR */ goto unimplemented;
12581 case 0x23: /* LCDR */ goto unimplemented;
12582 case 0x24: /* HDR */ goto unimplemented;
12583 case 0x25: /* LDXR */ goto unimplemented;
12584 case 0x26: /* MXR */ goto unimplemented;
12585 case 0x27: /* MXDR */ goto unimplemented;
12586 case 0x28: s390_format_RR_FF(s390_irgen_LDR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12587 goto ok;
12588 case 0x29: /* CDR */ goto unimplemented;
12589 case 0x2a: /* ADR */ goto unimplemented;
12590 case 0x2b: /* SDR */ goto unimplemented;
12591 case 0x2c: /* MDR */ goto unimplemented;
12592 case 0x2d: /* DDR */ goto unimplemented;
12593 case 0x2e: /* AWR */ goto unimplemented;
12594 case 0x2f: /* SWR */ goto unimplemented;
12595 case 0x30: /* LPER */ goto unimplemented;
12596 case 0x31: /* LNER */ goto unimplemented;
12597 case 0x32: /* LTER */ goto unimplemented;
12598 case 0x33: /* LCER */ goto unimplemented;
12599 case 0x34: /* HER */ goto unimplemented;
12600 case 0x35: /* LEDR */ goto unimplemented;
12601 case 0x36: /* AXR */ goto unimplemented;
12602 case 0x37: /* SXR */ goto unimplemented;
12603 case 0x38: s390_format_RR_FF(s390_irgen_LER, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12604 goto ok;
12605 case 0x39: /* CER */ goto unimplemented;
12606 case 0x3a: /* AER */ goto unimplemented;
12607 case 0x3b: /* SER */ goto unimplemented;
12608 case 0x3c: /* MDER */ goto unimplemented;
12609 case 0x3d: /* DER */ goto unimplemented;
12610 case 0x3e: /* AUR */ goto unimplemented;
12611 case 0x3f: /* SUR */ goto unimplemented;
12612 }
12613
12614 return S390_DECODE_UNKNOWN_INSN;
12615
12616ok:
12617 return S390_DECODE_OK;
12618
12619unimplemented:
12620 return S390_DECODE_UNIMPLEMENTED_INSN;
12621}
12622
12623static s390_decode_t
12624s390_decode_4byte_and_irgen(UChar *bytes)
12625{
12626 typedef union {
12627 struct {
12628 unsigned int op1 : 8;
12629 unsigned int r1 : 4;
12630 unsigned int op2 : 4;
12631 unsigned int i2 : 16;
12632 } RI;
12633 struct {
12634 unsigned int op : 16;
12635 unsigned int : 8;
12636 unsigned int r1 : 4;
12637 unsigned int r2 : 4;
12638 } RRE;
12639 struct {
12640 unsigned int op : 16;
12641 unsigned int r1 : 4;
12642 unsigned int : 4;
12643 unsigned int r3 : 4;
12644 unsigned int r2 : 4;
12645 } RRF;
12646 struct {
12647 unsigned int op : 16;
florian1c8f7ff2012-09-01 00:12:11 +000012648 unsigned int m3 : 4;
sewardj2019a972011-03-07 16:04:07 +000012649 unsigned int m4 : 4;
12650 unsigned int r1 : 4;
12651 unsigned int r2 : 4;
12652 } RRF2;
12653 struct {
12654 unsigned int op : 16;
12655 unsigned int r3 : 4;
12656 unsigned int : 4;
12657 unsigned int r1 : 4;
12658 unsigned int r2 : 4;
12659 } RRF3;
12660 struct {
12661 unsigned int op : 16;
12662 unsigned int r3 : 4;
12663 unsigned int : 4;
12664 unsigned int r1 : 4;
12665 unsigned int r2 : 4;
12666 } RRR;
12667 struct {
12668 unsigned int op : 16;
12669 unsigned int r3 : 4;
florian12390202012-11-10 22:34:14 +000012670 unsigned int m4 : 4;
sewardj2019a972011-03-07 16:04:07 +000012671 unsigned int r1 : 4;
12672 unsigned int r2 : 4;
12673 } RRF4;
12674 struct {
12675 unsigned int op : 8;
12676 unsigned int r1 : 4;
12677 unsigned int r3 : 4;
12678 unsigned int b2 : 4;
12679 unsigned int d2 : 12;
12680 } RS;
12681 struct {
12682 unsigned int op : 8;
12683 unsigned int r1 : 4;
12684 unsigned int r3 : 4;
12685 unsigned int i2 : 16;
12686 } RSI;
12687 struct {
12688 unsigned int op : 8;
12689 unsigned int r1 : 4;
12690 unsigned int x2 : 4;
12691 unsigned int b2 : 4;
12692 unsigned int d2 : 12;
12693 } RX;
12694 struct {
12695 unsigned int op : 16;
12696 unsigned int b2 : 4;
12697 unsigned int d2 : 12;
12698 } S;
12699 struct {
12700 unsigned int op : 8;
12701 unsigned int i2 : 8;
12702 unsigned int b1 : 4;
12703 unsigned int d1 : 12;
12704 } SI;
12705 } formats;
12706 union {
12707 formats fmt;
12708 UInt value;
12709 } ovl;
12710
12711 vassert(sizeof(formats) == 4);
12712
12713 ((char *)(&ovl.value))[0] = bytes[0];
12714 ((char *)(&ovl.value))[1] = bytes[1];
12715 ((char *)(&ovl.value))[2] = bytes[2];
12716 ((char *)(&ovl.value))[3] = bytes[3];
12717
12718 switch ((ovl.value & 0xff0f0000) >> 16) {
12719 case 0xa500: s390_format_RI_RU(s390_irgen_IIHH, ovl.fmt.RI.r1,
12720 ovl.fmt.RI.i2); goto ok;
12721 case 0xa501: s390_format_RI_RU(s390_irgen_IIHL, ovl.fmt.RI.r1,
12722 ovl.fmt.RI.i2); goto ok;
12723 case 0xa502: s390_format_RI_RU(s390_irgen_IILH, ovl.fmt.RI.r1,
12724 ovl.fmt.RI.i2); goto ok;
12725 case 0xa503: s390_format_RI_RU(s390_irgen_IILL, ovl.fmt.RI.r1,
12726 ovl.fmt.RI.i2); goto ok;
12727 case 0xa504: s390_format_RI_RU(s390_irgen_NIHH, ovl.fmt.RI.r1,
12728 ovl.fmt.RI.i2); goto ok;
12729 case 0xa505: s390_format_RI_RU(s390_irgen_NIHL, ovl.fmt.RI.r1,
12730 ovl.fmt.RI.i2); goto ok;
12731 case 0xa506: s390_format_RI_RU(s390_irgen_NILH, ovl.fmt.RI.r1,
12732 ovl.fmt.RI.i2); goto ok;
12733 case 0xa507: s390_format_RI_RU(s390_irgen_NILL, ovl.fmt.RI.r1,
12734 ovl.fmt.RI.i2); goto ok;
12735 case 0xa508: s390_format_RI_RU(s390_irgen_OIHH, ovl.fmt.RI.r1,
12736 ovl.fmt.RI.i2); goto ok;
12737 case 0xa509: s390_format_RI_RU(s390_irgen_OIHL, ovl.fmt.RI.r1,
12738 ovl.fmt.RI.i2); goto ok;
12739 case 0xa50a: s390_format_RI_RU(s390_irgen_OILH, ovl.fmt.RI.r1,
12740 ovl.fmt.RI.i2); goto ok;
12741 case 0xa50b: s390_format_RI_RU(s390_irgen_OILL, ovl.fmt.RI.r1,
12742 ovl.fmt.RI.i2); goto ok;
12743 case 0xa50c: s390_format_RI_RU(s390_irgen_LLIHH, ovl.fmt.RI.r1,
12744 ovl.fmt.RI.i2); goto ok;
12745 case 0xa50d: s390_format_RI_RU(s390_irgen_LLIHL, ovl.fmt.RI.r1,
12746 ovl.fmt.RI.i2); goto ok;
12747 case 0xa50e: s390_format_RI_RU(s390_irgen_LLILH, ovl.fmt.RI.r1,
12748 ovl.fmt.RI.i2); goto ok;
12749 case 0xa50f: s390_format_RI_RU(s390_irgen_LLILL, ovl.fmt.RI.r1,
12750 ovl.fmt.RI.i2); goto ok;
12751 case 0xa700: s390_format_RI_RU(s390_irgen_TMLH, ovl.fmt.RI.r1,
12752 ovl.fmt.RI.i2); goto ok;
12753 case 0xa701: s390_format_RI_RU(s390_irgen_TMLL, ovl.fmt.RI.r1,
12754 ovl.fmt.RI.i2); goto ok;
12755 case 0xa702: s390_format_RI_RU(s390_irgen_TMHH, ovl.fmt.RI.r1,
12756 ovl.fmt.RI.i2); goto ok;
12757 case 0xa703: s390_format_RI_RU(s390_irgen_TMHL, ovl.fmt.RI.r1,
12758 ovl.fmt.RI.i2); goto ok;
12759 case 0xa704: s390_format_RI(s390_irgen_BRC, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
12760 goto ok;
12761 case 0xa705: s390_format_RI_RP(s390_irgen_BRAS, ovl.fmt.RI.r1,
12762 ovl.fmt.RI.i2); goto ok;
12763 case 0xa706: s390_format_RI_RP(s390_irgen_BRCT, ovl.fmt.RI.r1,
12764 ovl.fmt.RI.i2); goto ok;
12765 case 0xa707: s390_format_RI_RP(s390_irgen_BRCTG, ovl.fmt.RI.r1,
12766 ovl.fmt.RI.i2); goto ok;
12767 case 0xa708: s390_format_RI_RI(s390_irgen_LHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
12768 goto ok;
12769 case 0xa709: s390_format_RI_RI(s390_irgen_LGHI, ovl.fmt.RI.r1,
12770 ovl.fmt.RI.i2); goto ok;
12771 case 0xa70a: s390_format_RI_RI(s390_irgen_AHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
12772 goto ok;
12773 case 0xa70b: s390_format_RI_RI(s390_irgen_AGHI, ovl.fmt.RI.r1,
12774 ovl.fmt.RI.i2); goto ok;
12775 case 0xa70c: s390_format_RI_RI(s390_irgen_MHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
12776 goto ok;
12777 case 0xa70d: s390_format_RI_RI(s390_irgen_MGHI, ovl.fmt.RI.r1,
12778 ovl.fmt.RI.i2); goto ok;
12779 case 0xa70e: s390_format_RI_RI(s390_irgen_CHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
12780 goto ok;
12781 case 0xa70f: s390_format_RI_RI(s390_irgen_CGHI, ovl.fmt.RI.r1,
12782 ovl.fmt.RI.i2); goto ok;
12783 }
12784
12785 switch ((ovl.value & 0xffff0000) >> 16) {
12786 case 0x8000: /* SSM */ goto unimplemented;
12787 case 0x8200: /* LPSW */ goto unimplemented;
florian7700fc92012-01-16 17:25:55 +000012788 case 0x9300: /* TS */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000012789 case 0xb202: /* STIDP */ goto unimplemented;
12790 case 0xb204: /* SCK */ goto unimplemented;
florian7700fc92012-01-16 17:25:55 +000012791 case 0xb205: s390_format_S_RD(s390_irgen_STCK, ovl.fmt.S.b2, ovl.fmt.S.d2);
12792 goto ok;
sewardj2019a972011-03-07 16:04:07 +000012793 case 0xb206: /* SCKC */ goto unimplemented;
12794 case 0xb207: /* STCKC */ goto unimplemented;
12795 case 0xb208: /* SPT */ goto unimplemented;
12796 case 0xb209: /* STPT */ goto unimplemented;
12797 case 0xb20a: /* SPKA */ goto unimplemented;
12798 case 0xb20b: /* IPK */ goto unimplemented;
12799 case 0xb20d: /* PTLB */ goto unimplemented;
12800 case 0xb210: /* SPX */ goto unimplemented;
12801 case 0xb211: /* STPX */ goto unimplemented;
12802 case 0xb212: /* STAP */ goto unimplemented;
12803 case 0xb214: /* SIE */ goto unimplemented;
12804 case 0xb218: /* PC */ goto unimplemented;
12805 case 0xb219: /* SAC */ goto unimplemented;
12806 case 0xb21a: /* CFC */ goto unimplemented;
12807 case 0xb221: /* IPTE */ goto unimplemented;
12808 case 0xb222: s390_format_RRE_R0(s390_irgen_IPM, ovl.fmt.RRE.r1); goto ok;
12809 case 0xb223: /* IVSK */ goto unimplemented;
12810 case 0xb224: /* IAC */ goto unimplemented;
12811 case 0xb225: /* SSAR */ goto unimplemented;
12812 case 0xb226: /* EPAR */ goto unimplemented;
12813 case 0xb227: /* ESAR */ goto unimplemented;
12814 case 0xb228: /* PT */ goto unimplemented;
12815 case 0xb229: /* ISKE */ goto unimplemented;
12816 case 0xb22a: /* RRBE */ goto unimplemented;
12817 case 0xb22b: /* SSKE */ goto unimplemented;
12818 case 0xb22c: /* TB */ goto unimplemented;
12819 case 0xb22d: /* DXR */ goto unimplemented;
12820 case 0xb22e: /* PGIN */ goto unimplemented;
12821 case 0xb22f: /* PGOUT */ goto unimplemented;
12822 case 0xb230: /* CSCH */ goto unimplemented;
12823 case 0xb231: /* HSCH */ goto unimplemented;
12824 case 0xb232: /* MSCH */ goto unimplemented;
12825 case 0xb233: /* SSCH */ goto unimplemented;
12826 case 0xb234: /* STSCH */ goto unimplemented;
12827 case 0xb235: /* TSCH */ goto unimplemented;
12828 case 0xb236: /* TPI */ goto unimplemented;
12829 case 0xb237: /* SAL */ goto unimplemented;
12830 case 0xb238: /* RSCH */ goto unimplemented;
12831 case 0xb239: /* STCRW */ goto unimplemented;
12832 case 0xb23a: /* STCPS */ goto unimplemented;
12833 case 0xb23b: /* RCHP */ goto unimplemented;
12834 case 0xb23c: /* SCHM */ goto unimplemented;
12835 case 0xb240: /* BAKR */ goto unimplemented;
floriana4384a32011-08-11 16:58:45 +000012836 case 0xb241: s390_format_RRE(s390_irgen_CKSM, ovl.fmt.RRE.r1,
12837 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000012838 case 0xb244: /* SQDR */ goto unimplemented;
12839 case 0xb245: /* SQER */ goto unimplemented;
12840 case 0xb246: /* STURA */ goto unimplemented;
12841 case 0xb247: /* MSTA */ goto unimplemented;
12842 case 0xb248: /* PALB */ goto unimplemented;
12843 case 0xb249: /* EREG */ goto unimplemented;
12844 case 0xb24a: /* ESTA */ goto unimplemented;
12845 case 0xb24b: /* LURA */ goto unimplemented;
12846 case 0xb24c: /* TAR */ goto unimplemented;
12847 case 0xb24d: s390_format_RRE(s390_irgen_CPYA, ovl.fmt.RRE.r1,
12848 ovl.fmt.RRE.r2); goto ok;
12849 case 0xb24e: s390_format_RRE(s390_irgen_SAR, ovl.fmt.RRE.r1, ovl.fmt.RRE.r2);
12850 goto ok;
12851 case 0xb24f: s390_format_RRE(s390_irgen_EAR, ovl.fmt.RRE.r1, ovl.fmt.RRE.r2);
12852 goto ok;
12853 case 0xb250: /* CSP */ goto unimplemented;
12854 case 0xb252: s390_format_RRE_RR(s390_irgen_MSR, ovl.fmt.RRE.r1,
12855 ovl.fmt.RRE.r2); goto ok;
12856 case 0xb254: /* MVPG */ goto unimplemented;
12857 case 0xb255: s390_format_RRE_RR(s390_irgen_MVST, ovl.fmt.RRE.r1,
12858 ovl.fmt.RRE.r2); goto ok;
12859 case 0xb257: /* CUSE */ goto unimplemented;
12860 case 0xb258: /* BSG */ goto unimplemented;
12861 case 0xb25a: /* BSA */ goto unimplemented;
12862 case 0xb25d: s390_format_RRE_RR(s390_irgen_CLST, ovl.fmt.RRE.r1,
12863 ovl.fmt.RRE.r2); goto ok;
12864 case 0xb25e: s390_format_RRE_RR(s390_irgen_SRST, ovl.fmt.RRE.r1,
12865 ovl.fmt.RRE.r2); goto ok;
12866 case 0xb263: /* CMPSC */ goto unimplemented;
12867 case 0xb274: /* SIGA */ goto unimplemented;
12868 case 0xb276: /* XSCH */ goto unimplemented;
12869 case 0xb277: /* RP */ goto unimplemented;
sewardj1e5fea62011-05-17 16:18:36 +000012870 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 +000012871 case 0xb279: /* SACF */ goto unimplemented;
sewardj1e5fea62011-05-17 16:18:36 +000012872 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 +000012873 case 0xb27d: /* STSI */ goto unimplemented;
12874 case 0xb299: s390_format_S_RD(s390_irgen_SRNM, ovl.fmt.S.b2, ovl.fmt.S.d2);
12875 goto ok;
12876 case 0xb29c: s390_format_S_RD(s390_irgen_STFPC, ovl.fmt.S.b2, ovl.fmt.S.d2);
12877 goto ok;
12878 case 0xb29d: s390_format_S_RD(s390_irgen_LFPC, ovl.fmt.S.b2, ovl.fmt.S.d2);
12879 goto ok;
florian730448f2012-02-04 17:07:07 +000012880 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 +000012881 case 0xb2a6: s390_format_RRF_M0RERE(s390_irgen_CU21, ovl.fmt.RRF3.r3,
12882 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
12883 goto ok;
florian6d9b9b22012-08-03 18:35:39 +000012884 case 0xb2a7: s390_format_RRF_M0RERE(s390_irgen_CU12, ovl.fmt.RRF3.r3,
12885 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
12886 goto ok;
florian933065d2011-07-11 01:48:02 +000012887 case 0xb2b0: s390_format_S_RD(s390_irgen_STFLE, ovl.fmt.S.b2, ovl.fmt.S.d2);
12888 goto ok;
sewardj2019a972011-03-07 16:04:07 +000012889 case 0xb2b1: /* STFL */ goto unimplemented;
12890 case 0xb2b2: /* LPSWE */ goto unimplemented;
florianf0fa1be2012-09-18 20:24:38 +000012891 case 0xb2b8: s390_irgen_srnmb_wrapper(ovl.fmt.S.b2, ovl.fmt.S.d2);
12892 goto ok;
sewardj2019a972011-03-07 16:04:07 +000012893 case 0xb2b9: /* SRNMT */ goto unimplemented;
12894 case 0xb2bd: /* LFAS */ goto unimplemented;
12895 case 0xb2ff: /* TRAP4 */ goto unimplemented;
12896 case 0xb300: s390_format_RRE_FF(s390_irgen_LPEBR, ovl.fmt.RRE.r1,
12897 ovl.fmt.RRE.r2); goto ok;
12898 case 0xb301: s390_format_RRE_FF(s390_irgen_LNEBR, ovl.fmt.RRE.r1,
12899 ovl.fmt.RRE.r2); goto ok;
12900 case 0xb302: s390_format_RRE_FF(s390_irgen_LTEBR, ovl.fmt.RRE.r1,
12901 ovl.fmt.RRE.r2); goto ok;
12902 case 0xb303: s390_format_RRE_FF(s390_irgen_LCEBR, ovl.fmt.RRE.r1,
12903 ovl.fmt.RRE.r2); goto ok;
12904 case 0xb304: s390_format_RRE_FF(s390_irgen_LDEBR, ovl.fmt.RRE.r1,
12905 ovl.fmt.RRE.r2); goto ok;
12906 case 0xb305: s390_format_RRE_FF(s390_irgen_LXDBR, ovl.fmt.RRE.r1,
12907 ovl.fmt.RRE.r2); goto ok;
12908 case 0xb306: s390_format_RRE_FF(s390_irgen_LXEBR, ovl.fmt.RRE.r1,
12909 ovl.fmt.RRE.r2); goto ok;
12910 case 0xb307: /* MXDBR */ goto unimplemented;
12911 case 0xb308: /* KEBR */ goto unimplemented;
12912 case 0xb309: s390_format_RRE_FF(s390_irgen_CEBR, ovl.fmt.RRE.r1,
12913 ovl.fmt.RRE.r2); goto ok;
12914 case 0xb30a: s390_format_RRE_FF(s390_irgen_AEBR, ovl.fmt.RRE.r1,
12915 ovl.fmt.RRE.r2); goto ok;
12916 case 0xb30b: s390_format_RRE_FF(s390_irgen_SEBR, ovl.fmt.RRE.r1,
12917 ovl.fmt.RRE.r2); goto ok;
12918 case 0xb30c: /* MDEBR */ goto unimplemented;
12919 case 0xb30d: s390_format_RRE_FF(s390_irgen_DEBR, ovl.fmt.RRE.r1,
12920 ovl.fmt.RRE.r2); goto ok;
12921 case 0xb30e: s390_format_RRF_F0FF(s390_irgen_MAEBR, ovl.fmt.RRF.r1,
12922 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
12923 case 0xb30f: s390_format_RRF_F0FF(s390_irgen_MSEBR, ovl.fmt.RRF.r1,
12924 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
12925 case 0xb310: s390_format_RRE_FF(s390_irgen_LPDBR, ovl.fmt.RRE.r1,
12926 ovl.fmt.RRE.r2); goto ok;
12927 case 0xb311: s390_format_RRE_FF(s390_irgen_LNDBR, ovl.fmt.RRE.r1,
12928 ovl.fmt.RRE.r2); goto ok;
12929 case 0xb312: s390_format_RRE_FF(s390_irgen_LTDBR, ovl.fmt.RRE.r1,
12930 ovl.fmt.RRE.r2); goto ok;
12931 case 0xb313: s390_format_RRE_FF(s390_irgen_LCDBR, ovl.fmt.RRE.r1,
12932 ovl.fmt.RRE.r2); goto ok;
12933 case 0xb314: s390_format_RRE_FF(s390_irgen_SQEBR, ovl.fmt.RRE.r1,
12934 ovl.fmt.RRE.r2); goto ok;
12935 case 0xb315: s390_format_RRE_FF(s390_irgen_SQDBR, ovl.fmt.RRE.r1,
12936 ovl.fmt.RRE.r2); goto ok;
12937 case 0xb316: s390_format_RRE_FF(s390_irgen_SQXBR, ovl.fmt.RRE.r1,
12938 ovl.fmt.RRE.r2); goto ok;
12939 case 0xb317: s390_format_RRE_FF(s390_irgen_MEEBR, ovl.fmt.RRE.r1,
12940 ovl.fmt.RRE.r2); goto ok;
12941 case 0xb318: /* KDBR */ goto unimplemented;
12942 case 0xb319: s390_format_RRE_FF(s390_irgen_CDBR, ovl.fmt.RRE.r1,
12943 ovl.fmt.RRE.r2); goto ok;
12944 case 0xb31a: s390_format_RRE_FF(s390_irgen_ADBR, ovl.fmt.RRE.r1,
12945 ovl.fmt.RRE.r2); goto ok;
12946 case 0xb31b: s390_format_RRE_FF(s390_irgen_SDBR, ovl.fmt.RRE.r1,
12947 ovl.fmt.RRE.r2); goto ok;
12948 case 0xb31c: s390_format_RRE_FF(s390_irgen_MDBR, ovl.fmt.RRE.r1,
12949 ovl.fmt.RRE.r2); goto ok;
12950 case 0xb31d: s390_format_RRE_FF(s390_irgen_DDBR, ovl.fmt.RRE.r1,
12951 ovl.fmt.RRE.r2); goto ok;
12952 case 0xb31e: s390_format_RRF_F0FF(s390_irgen_MADBR, ovl.fmt.RRF.r1,
12953 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
12954 case 0xb31f: s390_format_RRF_F0FF(s390_irgen_MSDBR, ovl.fmt.RRF.r1,
12955 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
12956 case 0xb324: /* LDER */ goto unimplemented;
12957 case 0xb325: /* LXDR */ goto unimplemented;
12958 case 0xb326: /* LXER */ goto unimplemented;
12959 case 0xb32e: /* MAER */ goto unimplemented;
12960 case 0xb32f: /* MSER */ goto unimplemented;
12961 case 0xb336: /* SQXR */ goto unimplemented;
12962 case 0xb337: /* MEER */ goto unimplemented;
12963 case 0xb338: /* MAYLR */ goto unimplemented;
12964 case 0xb339: /* MYLR */ goto unimplemented;
12965 case 0xb33a: /* MAYR */ goto unimplemented;
12966 case 0xb33b: /* MYR */ goto unimplemented;
12967 case 0xb33c: /* MAYHR */ goto unimplemented;
12968 case 0xb33d: /* MYHR */ goto unimplemented;
12969 case 0xb33e: /* MADR */ goto unimplemented;
12970 case 0xb33f: /* MSDR */ goto unimplemented;
12971 case 0xb340: s390_format_RRE_FF(s390_irgen_LPXBR, ovl.fmt.RRE.r1,
12972 ovl.fmt.RRE.r2); goto ok;
12973 case 0xb341: s390_format_RRE_FF(s390_irgen_LNXBR, ovl.fmt.RRE.r1,
12974 ovl.fmt.RRE.r2); goto ok;
12975 case 0xb342: s390_format_RRE_FF(s390_irgen_LTXBR, ovl.fmt.RRE.r1,
12976 ovl.fmt.RRE.r2); goto ok;
12977 case 0xb343: s390_format_RRE_FF(s390_irgen_LCXBR, ovl.fmt.RRE.r1,
12978 ovl.fmt.RRE.r2); goto ok;
florian4b8efad2012-09-02 18:07:08 +000012979 case 0xb344: s390_format_RRF_UUFF(s390_irgen_LEDBR, ovl.fmt.RRF2.m3,
12980 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12981 ovl.fmt.RRF2.r2); goto ok;
12982 case 0xb345: s390_format_RRF_UUFF(s390_irgen_LDXBR, ovl.fmt.RRF2.m3,
12983 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12984 ovl.fmt.RRF2.r2); goto ok;
12985 case 0xb346: s390_format_RRF_UUFF(s390_irgen_LEXBR, ovl.fmt.RRF2.m3,
12986 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12987 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000012988 case 0xb347: /* FIXBR */ goto unimplemented;
12989 case 0xb348: /* KXBR */ goto unimplemented;
12990 case 0xb349: s390_format_RRE_FF(s390_irgen_CXBR, ovl.fmt.RRE.r1,
12991 ovl.fmt.RRE.r2); goto ok;
12992 case 0xb34a: s390_format_RRE_FF(s390_irgen_AXBR, ovl.fmt.RRE.r1,
12993 ovl.fmt.RRE.r2); goto ok;
12994 case 0xb34b: s390_format_RRE_FF(s390_irgen_SXBR, ovl.fmt.RRE.r1,
12995 ovl.fmt.RRE.r2); goto ok;
12996 case 0xb34c: s390_format_RRE_FF(s390_irgen_MXBR, ovl.fmt.RRE.r1,
12997 ovl.fmt.RRE.r2); goto ok;
12998 case 0xb34d: s390_format_RRE_FF(s390_irgen_DXBR, ovl.fmt.RRE.r1,
12999 ovl.fmt.RRE.r2); goto ok;
13000 case 0xb350: /* TBEDR */ goto unimplemented;
13001 case 0xb351: /* TBDR */ goto unimplemented;
13002 case 0xb353: /* DIEBR */ goto unimplemented;
13003 case 0xb357: /* FIEBR */ goto unimplemented;
13004 case 0xb358: /* THDER */ goto unimplemented;
13005 case 0xb359: /* THDR */ goto unimplemented;
13006 case 0xb35b: /* DIDBR */ goto unimplemented;
13007 case 0xb35f: /* FIDBR */ goto unimplemented;
13008 case 0xb360: /* LPXR */ goto unimplemented;
13009 case 0xb361: /* LNXR */ goto unimplemented;
13010 case 0xb362: /* LTXR */ goto unimplemented;
13011 case 0xb363: /* LCXR */ goto unimplemented;
13012 case 0xb365: s390_format_RRE_FF(s390_irgen_LXR, ovl.fmt.RRE.r1,
13013 ovl.fmt.RRE.r2); goto ok;
13014 case 0xb366: /* LEXR */ goto unimplemented;
13015 case 0xb367: /* FIXR */ goto unimplemented;
13016 case 0xb369: /* CXR */ goto unimplemented;
13017 case 0xb370: s390_format_RRE_FF(s390_irgen_LPDFR, ovl.fmt.RRE.r1,
13018 ovl.fmt.RRE.r2); goto ok;
13019 case 0xb371: s390_format_RRE_FF(s390_irgen_LNDFR, ovl.fmt.RRE.r1,
13020 ovl.fmt.RRE.r2); goto ok;
13021 case 0xb372: s390_format_RRF_F0FF2(s390_irgen_CPSDR, ovl.fmt.RRF3.r3,
13022 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
13023 goto ok;
13024 case 0xb373: s390_format_RRE_FF(s390_irgen_LCDFR, ovl.fmt.RRE.r1,
13025 ovl.fmt.RRE.r2); goto ok;
13026 case 0xb374: s390_format_RRE_F0(s390_irgen_LZER, ovl.fmt.RRE.r1); goto ok;
13027 case 0xb375: s390_format_RRE_F0(s390_irgen_LZDR, ovl.fmt.RRE.r1); goto ok;
13028 case 0xb376: s390_format_RRE_F0(s390_irgen_LZXR, ovl.fmt.RRE.r1); goto ok;
13029 case 0xb377: /* FIER */ goto unimplemented;
13030 case 0xb37f: /* FIDR */ goto unimplemented;
13031 case 0xb384: s390_format_RRE_R0(s390_irgen_SFPC, ovl.fmt.RRE.r1); goto ok;
13032 case 0xb385: /* SFASR */ goto unimplemented;
13033 case 0xb38c: s390_format_RRE_R0(s390_irgen_EFPC, ovl.fmt.RRE.r1); goto ok;
florian1c8f7ff2012-09-01 00:12:11 +000013034 case 0xb390: s390_format_RRF_UUFR(s390_irgen_CELFBR, ovl.fmt.RRF2.m3,
13035 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13036 ovl.fmt.RRF2.r2); goto ok;
13037 case 0xb391: s390_format_RRF_UUFR(s390_irgen_CDLFBR, ovl.fmt.RRF2.m3,
13038 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13039 ovl.fmt.RRF2.r2); goto ok;
13040 case 0xb392: s390_format_RRF_UUFR(s390_irgen_CXLFBR, ovl.fmt.RRF2.m3,
13041 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13042 ovl.fmt.RRF2.r2); goto ok;
florian4b8efad2012-09-02 18:07:08 +000013043 case 0xb394: s390_format_RRF_UUFR(s390_irgen_CEFBR, ovl.fmt.RRF2.m3,
13044 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13045 ovl.fmt.RRF2.r2); goto ok;
13046 case 0xb395: s390_format_RRF_UUFR(s390_irgen_CDFBR, ovl.fmt.RRF2.m3,
13047 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13048 ovl.fmt.RRF2.r2); goto ok;
13049 case 0xb396: s390_format_RRF_UUFR(s390_irgen_CXFBR, ovl.fmt.RRF2.m3,
13050 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13051 ovl.fmt.RRF2.r2); goto ok;
13052 case 0xb398: s390_format_RRF_UURF(s390_irgen_CFEBR, ovl.fmt.RRF2.m3,
13053 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13054 ovl.fmt.RRF2.r2); goto ok;
13055 case 0xb399: s390_format_RRF_UURF(s390_irgen_CFDBR, ovl.fmt.RRF2.m3,
13056 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13057 ovl.fmt.RRF2.r2); goto ok;
13058 case 0xb39a: s390_format_RRF_UURF(s390_irgen_CFXBR, ovl.fmt.RRF2.m3,
13059 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13060 ovl.fmt.RRF2.r2); goto ok;
florian1c8f7ff2012-09-01 00:12:11 +000013061 case 0xb39c: s390_format_RRF_UURF(s390_irgen_CLFEBR, ovl.fmt.RRF2.m3,
13062 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13063 ovl.fmt.RRF2.r2); goto ok;
13064 case 0xb39d: s390_format_RRF_UURF(s390_irgen_CLFDBR, ovl.fmt.RRF2.m3,
13065 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13066 ovl.fmt.RRF2.r2); goto ok;
13067 case 0xb39e: s390_format_RRF_UURF(s390_irgen_CLFXBR, ovl.fmt.RRF2.m3,
13068 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13069 ovl.fmt.RRF2.r2); goto ok;
13070 case 0xb3a0: s390_format_RRF_UUFR(s390_irgen_CELGBR, ovl.fmt.RRF2.m3,
13071 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13072 ovl.fmt.RRF2.r2); goto ok;
13073 case 0xb3a1: s390_format_RRF_UUFR(s390_irgen_CDLGBR, ovl.fmt.RRF2.m3,
13074 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13075 ovl.fmt.RRF2.r2); goto ok;
13076 case 0xb3a2: s390_format_RRF_UUFR(s390_irgen_CXLGBR, ovl.fmt.RRF2.m3,
13077 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13078 ovl.fmt.RRF2.r2); goto ok;
florian4b8efad2012-09-02 18:07:08 +000013079 case 0xb3a4: s390_format_RRF_UUFR(s390_irgen_CEGBR, ovl.fmt.RRF2.m3,
13080 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13081 ovl.fmt.RRF2.r2); goto ok;
13082 case 0xb3a5: s390_format_RRF_UUFR(s390_irgen_CDGBR, ovl.fmt.RRF2.m3,
13083 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13084 ovl.fmt.RRF2.r2); goto ok;
13085 case 0xb3a6: s390_format_RRF_UUFR(s390_irgen_CXGBR, ovl.fmt.RRF2.m3,
13086 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13087 ovl.fmt.RRF2.r2); goto ok;
13088 case 0xb3a8: s390_format_RRF_UURF(s390_irgen_CGEBR, ovl.fmt.RRF2.m3,
13089 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13090 ovl.fmt.RRF2.r2); goto ok;
13091 case 0xb3a9: s390_format_RRF_UURF(s390_irgen_CGDBR, ovl.fmt.RRF2.m3,
13092 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13093 ovl.fmt.RRF2.r2); goto ok;
13094 case 0xb3aa: s390_format_RRF_UURF(s390_irgen_CGXBR, ovl.fmt.RRF2.m3,
13095 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13096 ovl.fmt.RRF2.r2); goto ok;
florian1c8f7ff2012-09-01 00:12:11 +000013097 case 0xb3ac: s390_format_RRF_UURF(s390_irgen_CLGEBR, ovl.fmt.RRF2.m3,
13098 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13099 ovl.fmt.RRF2.r2); goto ok;
13100 case 0xb3ad: s390_format_RRF_UURF(s390_irgen_CLGDBR, ovl.fmt.RRF2.m3,
13101 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13102 ovl.fmt.RRF2.r2); goto ok;
13103 case 0xb3ae: s390_format_RRF_UURF(s390_irgen_CLGXBR, ovl.fmt.RRF2.m3,
13104 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13105 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013106 case 0xb3b4: /* CEFR */ goto unimplemented;
13107 case 0xb3b5: /* CDFR */ goto unimplemented;
13108 case 0xb3b6: /* CXFR */ goto unimplemented;
13109 case 0xb3b8: /* CFER */ goto unimplemented;
13110 case 0xb3b9: /* CFDR */ goto unimplemented;
13111 case 0xb3ba: /* CFXR */ goto unimplemented;
13112 case 0xb3c1: s390_format_RRE_FR(s390_irgen_LDGR, ovl.fmt.RRE.r1,
13113 ovl.fmt.RRE.r2); goto ok;
13114 case 0xb3c4: /* CEGR */ goto unimplemented;
13115 case 0xb3c5: /* CDGR */ goto unimplemented;
13116 case 0xb3c6: /* CXGR */ goto unimplemented;
13117 case 0xb3c8: /* CGER */ goto unimplemented;
13118 case 0xb3c9: /* CGDR */ goto unimplemented;
13119 case 0xb3ca: /* CGXR */ goto unimplemented;
13120 case 0xb3cd: s390_format_RRE_RF(s390_irgen_LGDR, ovl.fmt.RRE.r1,
13121 ovl.fmt.RRE.r2); goto ok;
florian12390202012-11-10 22:34:14 +000013122 case 0xb3d0: s390_format_RRF_FUFF2(s390_irgen_MDTRA, ovl.fmt.RRF4.r3,
13123 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
13124 ovl.fmt.RRF4.r2); goto ok;
13125 case 0xb3d1: s390_format_RRF_FUFF2(s390_irgen_DDTRA, ovl.fmt.RRF4.r3,
13126 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
13127 ovl.fmt.RRF4.r2); goto ok;
13128 case 0xb3d2: s390_format_RRF_FUFF2(s390_irgen_ADTRA, ovl.fmt.RRF4.r3,
13129 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
13130 ovl.fmt.RRF4.r2); goto ok;
13131 case 0xb3d3: s390_format_RRF_FUFF2(s390_irgen_SDTRA, ovl.fmt.RRF4.r3,
13132 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
13133 ovl.fmt.RRF4.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013134 case 0xb3d4: /* LDETR */ goto unimplemented;
13135 case 0xb3d5: /* LEDTR */ goto unimplemented;
florian12390202012-11-10 22:34:14 +000013136 case 0xb3d6: s390_format_RRE_FF(s390_irgen_LTDTR, ovl.fmt.RRE.r1,
13137 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013138 case 0xb3d7: /* FIDTR */ goto unimplemented;
13139 case 0xb3d8: /* MXTR */ goto unimplemented;
13140 case 0xb3d9: /* DXTR */ goto unimplemented;
13141 case 0xb3da: /* AXTR */ goto unimplemented;
13142 case 0xb3db: /* SXTR */ goto unimplemented;
13143 case 0xb3dc: /* LXDTR */ goto unimplemented;
13144 case 0xb3dd: /* LDXTR */ goto unimplemented;
13145 case 0xb3de: /* LTXTR */ goto unimplemented;
13146 case 0xb3df: /* FIXTR */ goto unimplemented;
13147 case 0xb3e0: /* KDTR */ goto unimplemented;
13148 case 0xb3e1: /* CGDTR */ goto unimplemented;
13149 case 0xb3e2: /* CUDTR */ goto unimplemented;
13150 case 0xb3e3: /* CSDTR */ goto unimplemented;
13151 case 0xb3e4: /* CDTR */ goto unimplemented;
13152 case 0xb3e5: /* EEDTR */ goto unimplemented;
13153 case 0xb3e7: /* ESDTR */ goto unimplemented;
13154 case 0xb3e8: /* KXTR */ goto unimplemented;
13155 case 0xb3e9: /* CGXTR */ goto unimplemented;
13156 case 0xb3ea: /* CUXTR */ goto unimplemented;
13157 case 0xb3eb: /* CSXTR */ goto unimplemented;
13158 case 0xb3ec: /* CXTR */ goto unimplemented;
13159 case 0xb3ed: /* EEXTR */ goto unimplemented;
13160 case 0xb3ef: /* ESXTR */ goto unimplemented;
13161 case 0xb3f1: /* CDGTR */ goto unimplemented;
13162 case 0xb3f2: /* CDUTR */ goto unimplemented;
13163 case 0xb3f3: /* CDSTR */ goto unimplemented;
13164 case 0xb3f4: /* CEDTR */ goto unimplemented;
13165 case 0xb3f5: /* QADTR */ goto unimplemented;
13166 case 0xb3f6: /* IEDTR */ goto unimplemented;
13167 case 0xb3f7: /* RRDTR */ goto unimplemented;
13168 case 0xb3f9: /* CXGTR */ goto unimplemented;
13169 case 0xb3fa: /* CXUTR */ goto unimplemented;
13170 case 0xb3fb: /* CXSTR */ goto unimplemented;
13171 case 0xb3fc: /* CEXTR */ goto unimplemented;
13172 case 0xb3fd: /* QAXTR */ goto unimplemented;
13173 case 0xb3fe: /* IEXTR */ goto unimplemented;
13174 case 0xb3ff: /* RRXTR */ goto unimplemented;
13175 case 0xb900: s390_format_RRE_RR(s390_irgen_LPGR, ovl.fmt.RRE.r1,
13176 ovl.fmt.RRE.r2); goto ok;
13177 case 0xb901: s390_format_RRE_RR(s390_irgen_LNGR, ovl.fmt.RRE.r1,
13178 ovl.fmt.RRE.r2); goto ok;
13179 case 0xb902: s390_format_RRE_RR(s390_irgen_LTGR, ovl.fmt.RRE.r1,
13180 ovl.fmt.RRE.r2); goto ok;
13181 case 0xb903: s390_format_RRE_RR(s390_irgen_LCGR, ovl.fmt.RRE.r1,
13182 ovl.fmt.RRE.r2); goto ok;
13183 case 0xb904: s390_format_RRE_RR(s390_irgen_LGR, ovl.fmt.RRE.r1,
13184 ovl.fmt.RRE.r2); goto ok;
13185 case 0xb905: /* LURAG */ goto unimplemented;
13186 case 0xb906: s390_format_RRE_RR(s390_irgen_LGBR, ovl.fmt.RRE.r1,
13187 ovl.fmt.RRE.r2); goto ok;
13188 case 0xb907: s390_format_RRE_RR(s390_irgen_LGHR, ovl.fmt.RRE.r1,
13189 ovl.fmt.RRE.r2); goto ok;
13190 case 0xb908: s390_format_RRE_RR(s390_irgen_AGR, ovl.fmt.RRE.r1,
13191 ovl.fmt.RRE.r2); goto ok;
13192 case 0xb909: s390_format_RRE_RR(s390_irgen_SGR, ovl.fmt.RRE.r1,
13193 ovl.fmt.RRE.r2); goto ok;
13194 case 0xb90a: s390_format_RRE_RR(s390_irgen_ALGR, ovl.fmt.RRE.r1,
13195 ovl.fmt.RRE.r2); goto ok;
13196 case 0xb90b: s390_format_RRE_RR(s390_irgen_SLGR, ovl.fmt.RRE.r1,
13197 ovl.fmt.RRE.r2); goto ok;
13198 case 0xb90c: s390_format_RRE_RR(s390_irgen_MSGR, ovl.fmt.RRE.r1,
13199 ovl.fmt.RRE.r2); goto ok;
13200 case 0xb90d: s390_format_RRE_RR(s390_irgen_DSGR, ovl.fmt.RRE.r1,
13201 ovl.fmt.RRE.r2); goto ok;
13202 case 0xb90e: /* EREGG */ goto unimplemented;
13203 case 0xb90f: s390_format_RRE_RR(s390_irgen_LRVGR, ovl.fmt.RRE.r1,
13204 ovl.fmt.RRE.r2); goto ok;
13205 case 0xb910: s390_format_RRE_RR(s390_irgen_LPGFR, ovl.fmt.RRE.r1,
13206 ovl.fmt.RRE.r2); goto ok;
13207 case 0xb911: s390_format_RRE_RR(s390_irgen_LNGFR, ovl.fmt.RRE.r1,
13208 ovl.fmt.RRE.r2); goto ok;
13209 case 0xb912: s390_format_RRE_RR(s390_irgen_LTGFR, ovl.fmt.RRE.r1,
13210 ovl.fmt.RRE.r2); goto ok;
13211 case 0xb913: s390_format_RRE_RR(s390_irgen_LCGFR, ovl.fmt.RRE.r1,
13212 ovl.fmt.RRE.r2); goto ok;
13213 case 0xb914: s390_format_RRE_RR(s390_irgen_LGFR, ovl.fmt.RRE.r1,
13214 ovl.fmt.RRE.r2); goto ok;
13215 case 0xb916: s390_format_RRE_RR(s390_irgen_LLGFR, ovl.fmt.RRE.r1,
13216 ovl.fmt.RRE.r2); goto ok;
13217 case 0xb917: s390_format_RRE_RR(s390_irgen_LLGTR, ovl.fmt.RRE.r1,
13218 ovl.fmt.RRE.r2); goto ok;
13219 case 0xb918: s390_format_RRE_RR(s390_irgen_AGFR, ovl.fmt.RRE.r1,
13220 ovl.fmt.RRE.r2); goto ok;
13221 case 0xb919: s390_format_RRE_RR(s390_irgen_SGFR, ovl.fmt.RRE.r1,
13222 ovl.fmt.RRE.r2); goto ok;
13223 case 0xb91a: s390_format_RRE_RR(s390_irgen_ALGFR, ovl.fmt.RRE.r1,
13224 ovl.fmt.RRE.r2); goto ok;
13225 case 0xb91b: s390_format_RRE_RR(s390_irgen_SLGFR, ovl.fmt.RRE.r1,
13226 ovl.fmt.RRE.r2); goto ok;
13227 case 0xb91c: s390_format_RRE_RR(s390_irgen_MSGFR, ovl.fmt.RRE.r1,
13228 ovl.fmt.RRE.r2); goto ok;
13229 case 0xb91d: s390_format_RRE_RR(s390_irgen_DSGFR, ovl.fmt.RRE.r1,
13230 ovl.fmt.RRE.r2); goto ok;
13231 case 0xb91e: /* KMAC */ goto unimplemented;
13232 case 0xb91f: s390_format_RRE_RR(s390_irgen_LRVR, ovl.fmt.RRE.r1,
13233 ovl.fmt.RRE.r2); goto ok;
13234 case 0xb920: s390_format_RRE_RR(s390_irgen_CGR, ovl.fmt.RRE.r1,
13235 ovl.fmt.RRE.r2); goto ok;
13236 case 0xb921: s390_format_RRE_RR(s390_irgen_CLGR, ovl.fmt.RRE.r1,
13237 ovl.fmt.RRE.r2); goto ok;
13238 case 0xb925: /* STURG */ goto unimplemented;
13239 case 0xb926: s390_format_RRE_RR(s390_irgen_LBR, ovl.fmt.RRE.r1,
13240 ovl.fmt.RRE.r2); goto ok;
13241 case 0xb927: s390_format_RRE_RR(s390_irgen_LHR, ovl.fmt.RRE.r1,
13242 ovl.fmt.RRE.r2); goto ok;
13243 case 0xb928: /* PCKMO */ goto unimplemented;
13244 case 0xb92b: /* KMO */ goto unimplemented;
13245 case 0xb92c: /* PCC */ goto unimplemented;
13246 case 0xb92d: /* KMCTR */ goto unimplemented;
13247 case 0xb92e: /* KM */ goto unimplemented;
13248 case 0xb92f: /* KMC */ goto unimplemented;
13249 case 0xb930: s390_format_RRE_RR(s390_irgen_CGFR, ovl.fmt.RRE.r1,
13250 ovl.fmt.RRE.r2); goto ok;
13251 case 0xb931: s390_format_RRE_RR(s390_irgen_CLGFR, ovl.fmt.RRE.r1,
13252 ovl.fmt.RRE.r2); goto ok;
13253 case 0xb93e: /* KIMD */ goto unimplemented;
13254 case 0xb93f: /* KLMD */ goto unimplemented;
13255 case 0xb941: /* CFDTR */ goto unimplemented;
13256 case 0xb942: /* CLGDTR */ goto unimplemented;
13257 case 0xb943: /* CLFDTR */ goto unimplemented;
13258 case 0xb946: s390_format_RRE_RR(s390_irgen_BCTGR, ovl.fmt.RRE.r1,
13259 ovl.fmt.RRE.r2); goto ok;
13260 case 0xb949: /* CFXTR */ goto unimplemented;
13261 case 0xb94a: /* CLGXTR */ goto unimplemented;
13262 case 0xb94b: /* CLFXTR */ goto unimplemented;
13263 case 0xb951: /* CDFTR */ goto unimplemented;
13264 case 0xb952: /* CDLGTR */ goto unimplemented;
13265 case 0xb953: /* CDLFTR */ goto unimplemented;
13266 case 0xb959: /* CXFTR */ goto unimplemented;
13267 case 0xb95a: /* CXLGTR */ goto unimplemented;
13268 case 0xb95b: /* CXLFTR */ goto unimplemented;
13269 case 0xb960: /* CGRT */ goto unimplemented;
13270 case 0xb961: /* CLGRT */ goto unimplemented;
13271 case 0xb972: /* CRT */ goto unimplemented;
13272 case 0xb973: /* CLRT */ goto unimplemented;
13273 case 0xb980: s390_format_RRE_RR(s390_irgen_NGR, ovl.fmt.RRE.r1,
13274 ovl.fmt.RRE.r2); goto ok;
13275 case 0xb981: s390_format_RRE_RR(s390_irgen_OGR, ovl.fmt.RRE.r1,
13276 ovl.fmt.RRE.r2); goto ok;
13277 case 0xb982: s390_format_RRE_RR(s390_irgen_XGR, ovl.fmt.RRE.r1,
13278 ovl.fmt.RRE.r2); goto ok;
13279 case 0xb983: s390_format_RRE_RR(s390_irgen_FLOGR, ovl.fmt.RRE.r1,
13280 ovl.fmt.RRE.r2); goto ok;
13281 case 0xb984: s390_format_RRE_RR(s390_irgen_LLGCR, ovl.fmt.RRE.r1,
13282 ovl.fmt.RRE.r2); goto ok;
13283 case 0xb985: s390_format_RRE_RR(s390_irgen_LLGHR, ovl.fmt.RRE.r1,
13284 ovl.fmt.RRE.r2); goto ok;
13285 case 0xb986: s390_format_RRE_RR(s390_irgen_MLGR, ovl.fmt.RRE.r1,
13286 ovl.fmt.RRE.r2); goto ok;
13287 case 0xb987: s390_format_RRE_RR(s390_irgen_DLGR, ovl.fmt.RRE.r1,
13288 ovl.fmt.RRE.r2); goto ok;
13289 case 0xb988: s390_format_RRE_RR(s390_irgen_ALCGR, ovl.fmt.RRE.r1,
13290 ovl.fmt.RRE.r2); goto ok;
13291 case 0xb989: s390_format_RRE_RR(s390_irgen_SLBGR, ovl.fmt.RRE.r1,
13292 ovl.fmt.RRE.r2); goto ok;
13293 case 0xb98a: /* CSPG */ goto unimplemented;
13294 case 0xb98d: /* EPSW */ goto unimplemented;
13295 case 0xb98e: /* IDTE */ goto unimplemented;
florian730448f2012-02-04 17:07:07 +000013296 case 0xb990: s390_format_RRF_M0RERE(s390_irgen_TRTT, ovl.fmt.RRF3.r3,
13297 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
13298 case 0xb991: s390_format_RRF_M0RERE(s390_irgen_TRTO, ovl.fmt.RRF3.r3,
13299 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
13300 case 0xb992: s390_format_RRF_M0RERE(s390_irgen_TROT, ovl.fmt.RRF3.r3,
13301 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
florian9af37692012-01-15 21:01:16 +000013302 case 0xb993: s390_format_RRF_M0RERE(s390_irgen_TROO, ovl.fmt.RRF3.r3,
13303 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013304 case 0xb994: s390_format_RRE_RR(s390_irgen_LLCR, ovl.fmt.RRE.r1,
13305 ovl.fmt.RRE.r2); goto ok;
13306 case 0xb995: s390_format_RRE_RR(s390_irgen_LLHR, ovl.fmt.RRE.r1,
13307 ovl.fmt.RRE.r2); goto ok;
13308 case 0xb996: s390_format_RRE_RR(s390_irgen_MLR, ovl.fmt.RRE.r1,
13309 ovl.fmt.RRE.r2); goto ok;
13310 case 0xb997: s390_format_RRE_RR(s390_irgen_DLR, ovl.fmt.RRE.r1,
13311 ovl.fmt.RRE.r2); goto ok;
13312 case 0xb998: s390_format_RRE_RR(s390_irgen_ALCR, ovl.fmt.RRE.r1,
13313 ovl.fmt.RRE.r2); goto ok;
13314 case 0xb999: s390_format_RRE_RR(s390_irgen_SLBR, ovl.fmt.RRE.r1,
13315 ovl.fmt.RRE.r2); goto ok;
13316 case 0xb99a: /* EPAIR */ goto unimplemented;
13317 case 0xb99b: /* ESAIR */ goto unimplemented;
13318 case 0xb99d: /* ESEA */ goto unimplemented;
13319 case 0xb99e: /* PTI */ goto unimplemented;
13320 case 0xb99f: /* SSAIR */ goto unimplemented;
13321 case 0xb9a2: /* PTF */ goto unimplemented;
13322 case 0xb9aa: /* LPTEA */ goto unimplemented;
13323 case 0xb9ae: /* RRBM */ goto unimplemented;
13324 case 0xb9af: /* PFMF */ goto unimplemented;
florian3f8a96a2012-08-05 02:59:55 +000013325 case 0xb9b0: s390_format_RRF_M0RERE(s390_irgen_CU14, ovl.fmt.RRF3.r3,
13326 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
13327 goto ok;
florian2a415a12012-07-21 17:41:36 +000013328 case 0xb9b1: s390_format_RRF_M0RERE(s390_irgen_CU24, ovl.fmt.RRF3.r3,
13329 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
13330 goto ok;
florianaf2194f2012-08-06 00:07:54 +000013331 case 0xb9b2: s390_format_RRE_RR(s390_irgen_CU41, ovl.fmt.RRE.r1,
13332 ovl.fmt.RRE.r2); goto ok;
florian956194b2012-07-28 22:18:32 +000013333 case 0xb9b3: s390_format_RRE_RR(s390_irgen_CU42, ovl.fmt.RRE.r1,
13334 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013335 case 0xb9bd: /* TRTRE */ goto unimplemented;
13336 case 0xb9be: /* SRSTU */ goto unimplemented;
13337 case 0xb9bf: /* TRTE */ goto unimplemented;
13338 case 0xb9c8: s390_format_RRF_R0RR2(s390_irgen_AHHHR, ovl.fmt.RRF4.r3,
13339 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13340 goto ok;
13341 case 0xb9c9: s390_format_RRF_R0RR2(s390_irgen_SHHHR, ovl.fmt.RRF4.r3,
13342 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13343 goto ok;
13344 case 0xb9ca: s390_format_RRF_R0RR2(s390_irgen_ALHHHR, ovl.fmt.RRF4.r3,
13345 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13346 goto ok;
13347 case 0xb9cb: s390_format_RRF_R0RR2(s390_irgen_SLHHHR, ovl.fmt.RRF4.r3,
13348 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13349 goto ok;
13350 case 0xb9cd: s390_format_RRE_RR(s390_irgen_CHHR, ovl.fmt.RRE.r1,
13351 ovl.fmt.RRE.r2); goto ok;
13352 case 0xb9cf: s390_format_RRE_RR(s390_irgen_CLHHR, ovl.fmt.RRE.r1,
13353 ovl.fmt.RRE.r2); goto ok;
13354 case 0xb9d8: s390_format_RRF_R0RR2(s390_irgen_AHHLR, ovl.fmt.RRF4.r3,
13355 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13356 goto ok;
13357 case 0xb9d9: s390_format_RRF_R0RR2(s390_irgen_SHHLR, ovl.fmt.RRF4.r3,
13358 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13359 goto ok;
13360 case 0xb9da: s390_format_RRF_R0RR2(s390_irgen_ALHHLR, ovl.fmt.RRF4.r3,
13361 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13362 goto ok;
13363 case 0xb9db: s390_format_RRF_R0RR2(s390_irgen_SLHHLR, ovl.fmt.RRF4.r3,
13364 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13365 goto ok;
13366 case 0xb9dd: s390_format_RRE_RR(s390_irgen_CHLR, ovl.fmt.RRE.r1,
13367 ovl.fmt.RRE.r2); goto ok;
13368 case 0xb9df: s390_format_RRE_RR(s390_irgen_CLHLR, ovl.fmt.RRE.r1,
13369 ovl.fmt.RRE.r2); goto ok;
13370 case 0xb9e1: /* POPCNT */ goto unimplemented;
sewardjd7bde722011-04-05 13:19:33 +000013371 case 0xb9e2: s390_format_RRF_U0RR(s390_irgen_LOCGR, ovl.fmt.RRF3.r3,
13372 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2,
13373 S390_XMNM_LOCGR); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013374 case 0xb9e4: s390_format_RRF_R0RR2(s390_irgen_NGRK, ovl.fmt.RRF4.r3,
13375 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13376 goto ok;
13377 case 0xb9e6: s390_format_RRF_R0RR2(s390_irgen_OGRK, ovl.fmt.RRF4.r3,
13378 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13379 goto ok;
13380 case 0xb9e7: s390_format_RRF_R0RR2(s390_irgen_XGRK, ovl.fmt.RRF4.r3,
13381 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13382 goto ok;
13383 case 0xb9e8: s390_format_RRF_R0RR2(s390_irgen_AGRK, ovl.fmt.RRF4.r3,
13384 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13385 goto ok;
13386 case 0xb9e9: s390_format_RRF_R0RR2(s390_irgen_SGRK, ovl.fmt.RRF4.r3,
13387 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13388 goto ok;
13389 case 0xb9ea: s390_format_RRF_R0RR2(s390_irgen_ALGRK, ovl.fmt.RRF4.r3,
13390 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13391 goto ok;
13392 case 0xb9eb: s390_format_RRF_R0RR2(s390_irgen_SLGRK, ovl.fmt.RRF4.r3,
13393 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13394 goto ok;
sewardjd7bde722011-04-05 13:19:33 +000013395 case 0xb9f2: s390_format_RRF_U0RR(s390_irgen_LOCR, ovl.fmt.RRF3.r3,
13396 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2,
13397 S390_XMNM_LOCR); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013398 case 0xb9f4: s390_format_RRF_R0RR2(s390_irgen_NRK, ovl.fmt.RRF4.r3,
13399 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13400 goto ok;
13401 case 0xb9f6: s390_format_RRF_R0RR2(s390_irgen_ORK, ovl.fmt.RRF4.r3,
13402 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13403 goto ok;
13404 case 0xb9f7: s390_format_RRF_R0RR2(s390_irgen_XRK, ovl.fmt.RRF4.r3,
13405 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13406 goto ok;
13407 case 0xb9f8: s390_format_RRF_R0RR2(s390_irgen_ARK, ovl.fmt.RRF4.r3,
13408 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13409 goto ok;
13410 case 0xb9f9: s390_format_RRF_R0RR2(s390_irgen_SRK, ovl.fmt.RRF4.r3,
13411 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13412 goto ok;
13413 case 0xb9fa: s390_format_RRF_R0RR2(s390_irgen_ALRK, ovl.fmt.RRF4.r3,
13414 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13415 goto ok;
13416 case 0xb9fb: s390_format_RRF_R0RR2(s390_irgen_SLRK, ovl.fmt.RRF4.r3,
13417 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13418 goto ok;
13419 }
13420
13421 switch ((ovl.value & 0xff000000) >> 24) {
13422 case 0x40: s390_format_RX_RRRD(s390_irgen_STH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13423 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13424 case 0x41: s390_format_RX_RRRD(s390_irgen_LA, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13425 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13426 case 0x42: s390_format_RX_RRRD(s390_irgen_STC, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13427 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13428 case 0x43: s390_format_RX_RRRD(s390_irgen_IC, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13429 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13430 case 0x44: s390_format_RX_RRRD(s390_irgen_EX, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13431 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13432 case 0x45: /* BAL */ goto unimplemented;
13433 case 0x46: s390_format_RX_RRRD(s390_irgen_BCT, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13434 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13435 case 0x47: s390_format_RX(s390_irgen_BC, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13436 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13437 case 0x48: s390_format_RX_RRRD(s390_irgen_LH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13438 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13439 case 0x49: s390_format_RX_RRRD(s390_irgen_CH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13440 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13441 case 0x4a: s390_format_RX_RRRD(s390_irgen_AH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13442 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13443 case 0x4b: s390_format_RX_RRRD(s390_irgen_SH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13444 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13445 case 0x4c: s390_format_RX_RRRD(s390_irgen_MH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13446 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13447 case 0x4d: s390_format_RX_RRRD(s390_irgen_BAS, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13448 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13449 case 0x4e: s390_format_RX_RRRD(s390_irgen_CVD, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13450 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13451 case 0x4f: s390_format_RX_RRRD(s390_irgen_CVB, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13452 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13453 case 0x50: s390_format_RX_RRRD(s390_irgen_ST, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13454 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13455 case 0x51: s390_format_RX_RRRD(s390_irgen_LAE, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13456 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13457 case 0x54: s390_format_RX_RRRD(s390_irgen_N, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13458 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13459 case 0x55: s390_format_RX_RRRD(s390_irgen_CL, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13460 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13461 case 0x56: s390_format_RX_RRRD(s390_irgen_O, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13462 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13463 case 0x57: s390_format_RX_RRRD(s390_irgen_X, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13464 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13465 case 0x58: s390_format_RX_RRRD(s390_irgen_L, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13466 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13467 case 0x59: s390_format_RX_RRRD(s390_irgen_C, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13468 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13469 case 0x5a: s390_format_RX_RRRD(s390_irgen_A, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13470 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13471 case 0x5b: s390_format_RX_RRRD(s390_irgen_S, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13472 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13473 case 0x5c: s390_format_RX_RRRD(s390_irgen_M, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13474 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13475 case 0x5d: s390_format_RX_RRRD(s390_irgen_D, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13476 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13477 case 0x5e: s390_format_RX_RRRD(s390_irgen_AL, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13478 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13479 case 0x5f: s390_format_RX_RRRD(s390_irgen_SL, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13480 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13481 case 0x60: s390_format_RX_FRRD(s390_irgen_STD, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13482 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13483 case 0x67: /* MXD */ goto unimplemented;
13484 case 0x68: s390_format_RX_FRRD(s390_irgen_LD, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13485 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13486 case 0x69: /* CD */ goto unimplemented;
13487 case 0x6a: /* AD */ goto unimplemented;
13488 case 0x6b: /* SD */ goto unimplemented;
13489 case 0x6c: /* MD */ goto unimplemented;
13490 case 0x6d: /* DD */ goto unimplemented;
13491 case 0x6e: /* AW */ goto unimplemented;
13492 case 0x6f: /* SW */ goto unimplemented;
13493 case 0x70: s390_format_RX_FRRD(s390_irgen_STE, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13494 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13495 case 0x71: s390_format_RX_RRRD(s390_irgen_MS, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13496 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13497 case 0x78: s390_format_RX_FRRD(s390_irgen_LE, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13498 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13499 case 0x79: /* CE */ goto unimplemented;
13500 case 0x7a: /* AE */ goto unimplemented;
13501 case 0x7b: /* SE */ goto unimplemented;
13502 case 0x7c: /* MDE */ goto unimplemented;
13503 case 0x7d: /* DE */ goto unimplemented;
13504 case 0x7e: /* AU */ goto unimplemented;
13505 case 0x7f: /* SU */ goto unimplemented;
13506 case 0x83: /* DIAG */ goto unimplemented;
13507 case 0x84: s390_format_RSI_RRP(s390_irgen_BRXH, ovl.fmt.RSI.r1,
13508 ovl.fmt.RSI.r3, ovl.fmt.RSI.i2); goto ok;
13509 case 0x85: s390_format_RSI_RRP(s390_irgen_BRXLE, ovl.fmt.RSI.r1,
13510 ovl.fmt.RSI.r3, ovl.fmt.RSI.i2); goto ok;
13511 case 0x86: s390_format_RS_RRRD(s390_irgen_BXH, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13512 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13513 case 0x87: s390_format_RS_RRRD(s390_irgen_BXLE, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13514 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13515 case 0x88: s390_format_RS_R0RD(s390_irgen_SRL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
13516 ovl.fmt.RS.d2); goto ok;
13517 case 0x89: s390_format_RS_R0RD(s390_irgen_SLL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
13518 ovl.fmt.RS.d2); goto ok;
13519 case 0x8a: s390_format_RS_R0RD(s390_irgen_SRA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
13520 ovl.fmt.RS.d2); goto ok;
13521 case 0x8b: s390_format_RS_R0RD(s390_irgen_SLA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
13522 ovl.fmt.RS.d2); goto ok;
13523 case 0x8c: s390_format_RS_R0RD(s390_irgen_SRDL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
13524 ovl.fmt.RS.d2); goto ok;
13525 case 0x8d: s390_format_RS_R0RD(s390_irgen_SLDL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
13526 ovl.fmt.RS.d2); goto ok;
13527 case 0x8e: s390_format_RS_R0RD(s390_irgen_SRDA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
13528 ovl.fmt.RS.d2); goto ok;
13529 case 0x8f: s390_format_RS_R0RD(s390_irgen_SLDA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
13530 ovl.fmt.RS.d2); goto ok;
13531 case 0x90: s390_format_RS_RRRD(s390_irgen_STM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13532 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13533 case 0x91: s390_format_SI_URD(s390_irgen_TM, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
13534 ovl.fmt.SI.d1); goto ok;
13535 case 0x92: s390_format_SI_URD(s390_irgen_MVI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
13536 ovl.fmt.SI.d1); goto ok;
13537 case 0x94: s390_format_SI_URD(s390_irgen_NI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
13538 ovl.fmt.SI.d1); goto ok;
13539 case 0x95: s390_format_SI_URD(s390_irgen_CLI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
13540 ovl.fmt.SI.d1); goto ok;
13541 case 0x96: s390_format_SI_URD(s390_irgen_OI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
13542 ovl.fmt.SI.d1); goto ok;
13543 case 0x97: s390_format_SI_URD(s390_irgen_XI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
13544 ovl.fmt.SI.d1); goto ok;
13545 case 0x98: s390_format_RS_RRRD(s390_irgen_LM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13546 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13547 case 0x99: /* TRACE */ goto unimplemented;
13548 case 0x9a: s390_format_RS_AARD(s390_irgen_LAM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13549 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13550 case 0x9b: s390_format_RS_AARD(s390_irgen_STAM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13551 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13552 case 0xa8: s390_format_RS_RRRD(s390_irgen_MVCLE, ovl.fmt.RS.r1,
13553 ovl.fmt.RS.r3, ovl.fmt.RS.b2, ovl.fmt.RS.d2);
13554 goto ok;
13555 case 0xa9: s390_format_RS_RRRD(s390_irgen_CLCLE, ovl.fmt.RS.r1,
13556 ovl.fmt.RS.r3, ovl.fmt.RS.b2, ovl.fmt.RS.d2);
13557 goto ok;
13558 case 0xac: /* STNSM */ goto unimplemented;
13559 case 0xad: /* STOSM */ goto unimplemented;
13560 case 0xae: /* SIGP */ goto unimplemented;
13561 case 0xaf: /* MC */ goto unimplemented;
13562 case 0xb1: /* LRA */ goto unimplemented;
13563 case 0xb6: /* STCTL */ goto unimplemented;
13564 case 0xb7: /* LCTL */ goto unimplemented;
13565 case 0xba: s390_format_RS_RRRD(s390_irgen_CS, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13566 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
florian448cbba2012-06-06 02:26:01 +000013567 case 0xbb: s390_format_RS_RRRD(s390_irgen_CDS, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13568 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013569 case 0xbd: s390_format_RS_RURD(s390_irgen_CLM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13570 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13571 case 0xbe: s390_format_RS_RURD(s390_irgen_STCM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13572 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13573 case 0xbf: s390_format_RS_RURD(s390_irgen_ICM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13574 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13575 }
13576
13577 return S390_DECODE_UNKNOWN_INSN;
13578
13579ok:
13580 return S390_DECODE_OK;
13581
13582unimplemented:
13583 return S390_DECODE_UNIMPLEMENTED_INSN;
13584}
13585
13586static s390_decode_t
13587s390_decode_6byte_and_irgen(UChar *bytes)
13588{
13589 typedef union {
13590 struct {
13591 unsigned int op1 : 8;
13592 unsigned int r1 : 4;
13593 unsigned int r3 : 4;
13594 unsigned int i2 : 16;
13595 unsigned int : 8;
13596 unsigned int op2 : 8;
13597 } RIE;
13598 struct {
13599 unsigned int op1 : 8;
13600 unsigned int r1 : 4;
13601 unsigned int r2 : 4;
13602 unsigned int i3 : 8;
13603 unsigned int i4 : 8;
13604 unsigned int i5 : 8;
13605 unsigned int op2 : 8;
13606 } RIE_RRUUU;
13607 struct {
13608 unsigned int op1 : 8;
13609 unsigned int r1 : 4;
13610 unsigned int : 4;
13611 unsigned int i2 : 16;
13612 unsigned int m3 : 4;
13613 unsigned int : 4;
13614 unsigned int op2 : 8;
13615 } RIEv1;
13616 struct {
13617 unsigned int op1 : 8;
13618 unsigned int r1 : 4;
13619 unsigned int r2 : 4;
13620 unsigned int i4 : 16;
13621 unsigned int m3 : 4;
13622 unsigned int : 4;
13623 unsigned int op2 : 8;
13624 } RIE_RRPU;
13625 struct {
13626 unsigned int op1 : 8;
13627 unsigned int r1 : 4;
13628 unsigned int m3 : 4;
13629 unsigned int i4 : 16;
13630 unsigned int i2 : 8;
13631 unsigned int op2 : 8;
13632 } RIEv3;
13633 struct {
13634 unsigned int op1 : 8;
13635 unsigned int r1 : 4;
13636 unsigned int op2 : 4;
13637 unsigned int i2 : 32;
13638 } RIL;
13639 struct {
13640 unsigned int op1 : 8;
13641 unsigned int r1 : 4;
13642 unsigned int m3 : 4;
13643 unsigned int b4 : 4;
13644 unsigned int d4 : 12;
13645 unsigned int i2 : 8;
13646 unsigned int op2 : 8;
13647 } RIS;
13648 struct {
13649 unsigned int op1 : 8;
13650 unsigned int r1 : 4;
13651 unsigned int r2 : 4;
13652 unsigned int b4 : 4;
13653 unsigned int d4 : 12;
13654 unsigned int m3 : 4;
13655 unsigned int : 4;
13656 unsigned int op2 : 8;
13657 } RRS;
13658 struct {
13659 unsigned int op1 : 8;
13660 unsigned int l1 : 4;
13661 unsigned int : 4;
13662 unsigned int b1 : 4;
13663 unsigned int d1 : 12;
13664 unsigned int : 8;
13665 unsigned int op2 : 8;
13666 } RSL;
13667 struct {
13668 unsigned int op1 : 8;
13669 unsigned int r1 : 4;
13670 unsigned int r3 : 4;
13671 unsigned int b2 : 4;
13672 unsigned int dl2 : 12;
13673 unsigned int dh2 : 8;
13674 unsigned int op2 : 8;
13675 } RSY;
13676 struct {
13677 unsigned int op1 : 8;
13678 unsigned int r1 : 4;
13679 unsigned int x2 : 4;
13680 unsigned int b2 : 4;
13681 unsigned int d2 : 12;
13682 unsigned int : 8;
13683 unsigned int op2 : 8;
13684 } RXE;
13685 struct {
13686 unsigned int op1 : 8;
13687 unsigned int r3 : 4;
13688 unsigned int x2 : 4;
13689 unsigned int b2 : 4;
13690 unsigned int d2 : 12;
13691 unsigned int r1 : 4;
13692 unsigned int : 4;
13693 unsigned int op2 : 8;
13694 } RXF;
13695 struct {
13696 unsigned int op1 : 8;
13697 unsigned int r1 : 4;
13698 unsigned int x2 : 4;
13699 unsigned int b2 : 4;
13700 unsigned int dl2 : 12;
13701 unsigned int dh2 : 8;
13702 unsigned int op2 : 8;
13703 } RXY;
13704 struct {
13705 unsigned int op1 : 8;
13706 unsigned int i2 : 8;
13707 unsigned int b1 : 4;
13708 unsigned int dl1 : 12;
13709 unsigned int dh1 : 8;
13710 unsigned int op2 : 8;
13711 } SIY;
13712 struct {
13713 unsigned int op : 8;
13714 unsigned int l : 8;
13715 unsigned int b1 : 4;
13716 unsigned int d1 : 12;
13717 unsigned int b2 : 4;
13718 unsigned int d2 : 12;
13719 } SS;
13720 struct {
13721 unsigned int op : 8;
13722 unsigned int l1 : 4;
13723 unsigned int l2 : 4;
13724 unsigned int b1 : 4;
13725 unsigned int d1 : 12;
13726 unsigned int b2 : 4;
13727 unsigned int d2 : 12;
13728 } SS_LLRDRD;
13729 struct {
13730 unsigned int op : 8;
13731 unsigned int r1 : 4;
13732 unsigned int r3 : 4;
13733 unsigned int b2 : 4;
13734 unsigned int d2 : 12;
13735 unsigned int b4 : 4;
13736 unsigned int d4 : 12;
13737 } SS_RRRDRD2;
13738 struct {
13739 unsigned int op : 16;
13740 unsigned int b1 : 4;
13741 unsigned int d1 : 12;
13742 unsigned int b2 : 4;
13743 unsigned int d2 : 12;
13744 } SSE;
13745 struct {
13746 unsigned int op1 : 8;
13747 unsigned int r3 : 4;
13748 unsigned int op2 : 4;
13749 unsigned int b1 : 4;
13750 unsigned int d1 : 12;
13751 unsigned int b2 : 4;
13752 unsigned int d2 : 12;
13753 } SSF;
13754 struct {
13755 unsigned int op : 16;
13756 unsigned int b1 : 4;
13757 unsigned int d1 : 12;
13758 unsigned int i2 : 16;
13759 } SIL;
13760 } formats;
13761 union {
13762 formats fmt;
13763 ULong value;
13764 } ovl;
13765
13766 vassert(sizeof(formats) == 6);
13767
13768 ((char *)(&ovl.value))[0] = bytes[0];
13769 ((char *)(&ovl.value))[1] = bytes[1];
13770 ((char *)(&ovl.value))[2] = bytes[2];
13771 ((char *)(&ovl.value))[3] = bytes[3];
13772 ((char *)(&ovl.value))[4] = bytes[4];
13773 ((char *)(&ovl.value))[5] = bytes[5];
13774 ((char *)(&ovl.value))[6] = 0x0;
13775 ((char *)(&ovl.value))[7] = 0x0;
13776
13777 switch ((ovl.value >> 16) & 0xff00000000ffULL) {
13778 case 0xe30000000002ULL: s390_format_RXY_RRRD(s390_irgen_LTG, ovl.fmt.RXY.r1,
13779 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13780 ovl.fmt.RXY.dl2,
13781 ovl.fmt.RXY.dh2); goto ok;
13782 case 0xe30000000003ULL: /* LRAG */ goto unimplemented;
13783 case 0xe30000000004ULL: s390_format_RXY_RRRD(s390_irgen_LG, ovl.fmt.RXY.r1,
13784 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13785 ovl.fmt.RXY.dl2,
13786 ovl.fmt.RXY.dh2); goto ok;
13787 case 0xe30000000006ULL: s390_format_RXY_RRRD(s390_irgen_CVBY, ovl.fmt.RXY.r1,
13788 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13789 ovl.fmt.RXY.dl2,
13790 ovl.fmt.RXY.dh2); goto ok;
13791 case 0xe30000000008ULL: s390_format_RXY_RRRD(s390_irgen_AG, ovl.fmt.RXY.r1,
13792 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13793 ovl.fmt.RXY.dl2,
13794 ovl.fmt.RXY.dh2); goto ok;
13795 case 0xe30000000009ULL: s390_format_RXY_RRRD(s390_irgen_SG, ovl.fmt.RXY.r1,
13796 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13797 ovl.fmt.RXY.dl2,
13798 ovl.fmt.RXY.dh2); goto ok;
13799 case 0xe3000000000aULL: s390_format_RXY_RRRD(s390_irgen_ALG, ovl.fmt.RXY.r1,
13800 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13801 ovl.fmt.RXY.dl2,
13802 ovl.fmt.RXY.dh2); goto ok;
13803 case 0xe3000000000bULL: s390_format_RXY_RRRD(s390_irgen_SLG, 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 0xe3000000000cULL: s390_format_RXY_RRRD(s390_irgen_MSG, 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 0xe3000000000dULL: s390_format_RXY_RRRD(s390_irgen_DSG, 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 0xe3000000000eULL: /* CVBG */ goto unimplemented;
13816 case 0xe3000000000fULL: s390_format_RXY_RRRD(s390_irgen_LRVG, ovl.fmt.RXY.r1,
13817 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13818 ovl.fmt.RXY.dl2,
13819 ovl.fmt.RXY.dh2); goto ok;
13820 case 0xe30000000012ULL: s390_format_RXY_RRRD(s390_irgen_LT, ovl.fmt.RXY.r1,
13821 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13822 ovl.fmt.RXY.dl2,
13823 ovl.fmt.RXY.dh2); goto ok;
13824 case 0xe30000000013ULL: /* LRAY */ goto unimplemented;
13825 case 0xe30000000014ULL: s390_format_RXY_RRRD(s390_irgen_LGF, ovl.fmt.RXY.r1,
13826 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13827 ovl.fmt.RXY.dl2,
13828 ovl.fmt.RXY.dh2); goto ok;
13829 case 0xe30000000015ULL: s390_format_RXY_RRRD(s390_irgen_LGH, ovl.fmt.RXY.r1,
13830 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13831 ovl.fmt.RXY.dl2,
13832 ovl.fmt.RXY.dh2); goto ok;
13833 case 0xe30000000016ULL: s390_format_RXY_RRRD(s390_irgen_LLGF, ovl.fmt.RXY.r1,
13834 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13835 ovl.fmt.RXY.dl2,
13836 ovl.fmt.RXY.dh2); goto ok;
13837 case 0xe30000000017ULL: s390_format_RXY_RRRD(s390_irgen_LLGT, ovl.fmt.RXY.r1,
13838 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13839 ovl.fmt.RXY.dl2,
13840 ovl.fmt.RXY.dh2); goto ok;
13841 case 0xe30000000018ULL: s390_format_RXY_RRRD(s390_irgen_AGF, ovl.fmt.RXY.r1,
13842 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13843 ovl.fmt.RXY.dl2,
13844 ovl.fmt.RXY.dh2); goto ok;
13845 case 0xe30000000019ULL: s390_format_RXY_RRRD(s390_irgen_SGF, 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 0xe3000000001aULL: s390_format_RXY_RRRD(s390_irgen_ALGF, 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 0xe3000000001bULL: s390_format_RXY_RRRD(s390_irgen_SLGF, 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 0xe3000000001cULL: s390_format_RXY_RRRD(s390_irgen_MSGF, 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 0xe3000000001dULL: s390_format_RXY_RRRD(s390_irgen_DSGF, 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 0xe3000000001eULL: s390_format_RXY_RRRD(s390_irgen_LRV, 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 0xe3000000001fULL: s390_format_RXY_RRRD(s390_irgen_LRVH, 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 0xe30000000020ULL: s390_format_RXY_RRRD(s390_irgen_CG, 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 0xe30000000021ULL: s390_format_RXY_RRRD(s390_irgen_CLG, 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 0xe30000000024ULL: s390_format_RXY_RRRD(s390_irgen_STG, 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 0xe30000000026ULL: s390_format_RXY_RRRD(s390_irgen_CVDY, 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 0xe3000000002eULL: /* CVDG */ goto unimplemented;
13890 case 0xe3000000002fULL: s390_format_RXY_RRRD(s390_irgen_STRVG,
13891 ovl.fmt.RXY.r1, ovl.fmt.RXY.x2,
13892 ovl.fmt.RXY.b2, ovl.fmt.RXY.dl2,
13893 ovl.fmt.RXY.dh2); goto ok;
13894 case 0xe30000000030ULL: s390_format_RXY_RRRD(s390_irgen_CGF, ovl.fmt.RXY.r1,
13895 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13896 ovl.fmt.RXY.dl2,
13897 ovl.fmt.RXY.dh2); goto ok;
13898 case 0xe30000000031ULL: s390_format_RXY_RRRD(s390_irgen_CLGF, ovl.fmt.RXY.r1,
13899 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13900 ovl.fmt.RXY.dl2,
13901 ovl.fmt.RXY.dh2); goto ok;
13902 case 0xe30000000032ULL: s390_format_RXY_RRRD(s390_irgen_LTGF, ovl.fmt.RXY.r1,
13903 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13904 ovl.fmt.RXY.dl2,
13905 ovl.fmt.RXY.dh2); goto ok;
13906 case 0xe30000000034ULL: s390_format_RXY_RRRD(s390_irgen_CGH, ovl.fmt.RXY.r1,
13907 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13908 ovl.fmt.RXY.dl2,
13909 ovl.fmt.RXY.dh2); goto ok;
13910 case 0xe30000000036ULL: s390_format_RXY_URRD(s390_irgen_PFD, ovl.fmt.RXY.r1,
13911 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13912 ovl.fmt.RXY.dl2,
13913 ovl.fmt.RXY.dh2); goto ok;
13914 case 0xe3000000003eULL: s390_format_RXY_RRRD(s390_irgen_STRV, 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 0xe3000000003fULL: s390_format_RXY_RRRD(s390_irgen_STRVH,
13919 ovl.fmt.RXY.r1, ovl.fmt.RXY.x2,
13920 ovl.fmt.RXY.b2, ovl.fmt.RXY.dl2,
13921 ovl.fmt.RXY.dh2); goto ok;
13922 case 0xe30000000046ULL: s390_format_RXY_RRRD(s390_irgen_BCTG, 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 0xe30000000050ULL: s390_format_RXY_RRRD(s390_irgen_STY, 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 0xe30000000051ULL: s390_format_RXY_RRRD(s390_irgen_MSY, 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 0xe30000000054ULL: s390_format_RXY_RRRD(s390_irgen_NY, 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 0xe30000000055ULL: s390_format_RXY_RRRD(s390_irgen_CLY, ovl.fmt.RXY.r1,
13939 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13940 ovl.fmt.RXY.dl2,
13941 ovl.fmt.RXY.dh2); goto ok;
13942 case 0xe30000000056ULL: s390_format_RXY_RRRD(s390_irgen_OY, 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 0xe30000000057ULL: s390_format_RXY_RRRD(s390_irgen_XY, 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 0xe30000000058ULL: s390_format_RXY_RRRD(s390_irgen_LY, 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 0xe30000000059ULL: s390_format_RXY_RRRD(s390_irgen_CY, 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 0xe3000000005aULL: s390_format_RXY_RRRD(s390_irgen_AY, 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 0xe3000000005bULL: s390_format_RXY_RRRD(s390_irgen_SY, 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 0xe3000000005cULL: s390_format_RXY_RRRD(s390_irgen_MFY, 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 0xe3000000005eULL: s390_format_RXY_RRRD(s390_irgen_ALY, 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 0xe3000000005fULL: s390_format_RXY_RRRD(s390_irgen_SLY, 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 0xe30000000070ULL: s390_format_RXY_RRRD(s390_irgen_STHY, 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 0xe30000000071ULL: s390_format_RXY_RRRD(s390_irgen_LAY, 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 0xe30000000072ULL: s390_format_RXY_RRRD(s390_irgen_STCY, 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 0xe30000000073ULL: s390_format_RXY_RRRD(s390_irgen_ICY, 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 0xe30000000075ULL: s390_format_RXY_RRRD(s390_irgen_LAEY, 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 0xe30000000076ULL: s390_format_RXY_RRRD(s390_irgen_LB, 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 0xe30000000077ULL: s390_format_RXY_RRRD(s390_irgen_LGB, 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 0xe30000000078ULL: s390_format_RXY_RRRD(s390_irgen_LHY, 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 0xe30000000079ULL: s390_format_RXY_RRRD(s390_irgen_CHY, 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 0xe3000000007aULL: s390_format_RXY_RRRD(s390_irgen_AHY, 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 0xe3000000007bULL: s390_format_RXY_RRRD(s390_irgen_SHY, 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 0xe3000000007cULL: s390_format_RXY_RRRD(s390_irgen_MHY, 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 0xe30000000080ULL: s390_format_RXY_RRRD(s390_irgen_NG, 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 0xe30000000081ULL: s390_format_RXY_RRRD(s390_irgen_OG, 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 0xe30000000082ULL: s390_format_RXY_RRRD(s390_irgen_XG, 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 0xe30000000086ULL: s390_format_RXY_RRRD(s390_irgen_MLG, 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 0xe30000000087ULL: s390_format_RXY_RRRD(s390_irgen_DLG, 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 0xe30000000088ULL: s390_format_RXY_RRRD(s390_irgen_ALCG, 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 0xe30000000089ULL: s390_format_RXY_RRRD(s390_irgen_SLBG, 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 0xe3000000008eULL: s390_format_RXY_RRRD(s390_irgen_STPQ, 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 0xe3000000008fULL: s390_format_RXY_RRRD(s390_irgen_LPQ, 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 0xe30000000090ULL: s390_format_RXY_RRRD(s390_irgen_LLGC, 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 0xe30000000091ULL: s390_format_RXY_RRRD(s390_irgen_LLGH, 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 0xe30000000094ULL: s390_format_RXY_RRRD(s390_irgen_LLC, 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 0xe30000000095ULL: s390_format_RXY_RRRD(s390_irgen_LLH, 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 0xe30000000096ULL: s390_format_RXY_RRRD(s390_irgen_ML, 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 0xe30000000097ULL: s390_format_RXY_RRRD(s390_irgen_DL, 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 0xe30000000098ULL: s390_format_RXY_RRRD(s390_irgen_ALC, 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 0xe30000000099ULL: s390_format_RXY_RRRD(s390_irgen_SLB, 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 0xe300000000c0ULL: s390_format_RXY_RRRD(s390_irgen_LBH, 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 0xe300000000c2ULL: s390_format_RXY_RRRD(s390_irgen_LLCH, 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 0xe300000000c3ULL: s390_format_RXY_RRRD(s390_irgen_STCH, 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 0xe300000000c4ULL: s390_format_RXY_RRRD(s390_irgen_LHH, 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 0xe300000000c6ULL: s390_format_RXY_RRRD(s390_irgen_LLHH, 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 0xe300000000c7ULL: s390_format_RXY_RRRD(s390_irgen_STHH, 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 0xe300000000caULL: s390_format_RXY_RRRD(s390_irgen_LFH, 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 0xe300000000cbULL: s390_format_RXY_RRRD(s390_irgen_STFH, 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 0xe300000000cdULL: s390_format_RXY_RRRD(s390_irgen_CHF, 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 0xe300000000cfULL: s390_format_RXY_RRRD(s390_irgen_CLHF, 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 0xeb0000000004ULL: s390_format_RSY_RRRD(s390_irgen_LMG, ovl.fmt.RSY.r1,
14135 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14136 ovl.fmt.RSY.dl2,
14137 ovl.fmt.RSY.dh2); goto ok;
14138 case 0xeb000000000aULL: s390_format_RSY_RRRD(s390_irgen_SRAG, ovl.fmt.RSY.r1,
14139 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14140 ovl.fmt.RSY.dl2,
14141 ovl.fmt.RSY.dh2); goto ok;
14142 case 0xeb000000000bULL: s390_format_RSY_RRRD(s390_irgen_SLAG, ovl.fmt.RSY.r1,
14143 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14144 ovl.fmt.RSY.dl2,
14145 ovl.fmt.RSY.dh2); goto ok;
14146 case 0xeb000000000cULL: s390_format_RSY_RRRD(s390_irgen_SRLG, ovl.fmt.RSY.r1,
14147 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14148 ovl.fmt.RSY.dl2,
14149 ovl.fmt.RSY.dh2); goto ok;
14150 case 0xeb000000000dULL: s390_format_RSY_RRRD(s390_irgen_SLLG, ovl.fmt.RSY.r1,
14151 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14152 ovl.fmt.RSY.dl2,
14153 ovl.fmt.RSY.dh2); goto ok;
14154 case 0xeb000000000fULL: /* TRACG */ goto unimplemented;
14155 case 0xeb0000000014ULL: s390_format_RSY_RRRD(s390_irgen_CSY, ovl.fmt.RSY.r1,
14156 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14157 ovl.fmt.RSY.dl2,
14158 ovl.fmt.RSY.dh2); goto ok;
14159 case 0xeb000000001cULL: s390_format_RSY_RRRD(s390_irgen_RLLG, ovl.fmt.RSY.r1,
14160 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14161 ovl.fmt.RSY.dl2,
14162 ovl.fmt.RSY.dh2); goto ok;
14163 case 0xeb000000001dULL: s390_format_RSY_RRRD(s390_irgen_RLL, ovl.fmt.RSY.r1,
14164 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14165 ovl.fmt.RSY.dl2,
14166 ovl.fmt.RSY.dh2); goto ok;
14167 case 0xeb0000000020ULL: s390_format_RSY_RURD(s390_irgen_CLMH, ovl.fmt.RSY.r1,
14168 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14169 ovl.fmt.RSY.dl2,
14170 ovl.fmt.RSY.dh2); goto ok;
14171 case 0xeb0000000021ULL: s390_format_RSY_RURD(s390_irgen_CLMY, ovl.fmt.RSY.r1,
14172 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14173 ovl.fmt.RSY.dl2,
14174 ovl.fmt.RSY.dh2); goto ok;
14175 case 0xeb0000000024ULL: s390_format_RSY_RRRD(s390_irgen_STMG, 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 0xeb0000000025ULL: /* STCTG */ goto unimplemented;
14180 case 0xeb0000000026ULL: s390_format_RSY_RRRD(s390_irgen_STMH, ovl.fmt.RSY.r1,
14181 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14182 ovl.fmt.RSY.dl2,
14183 ovl.fmt.RSY.dh2); goto ok;
14184 case 0xeb000000002cULL: s390_format_RSY_RURD(s390_irgen_STCMH,
14185 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
14186 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
14187 ovl.fmt.RSY.dh2); goto ok;
14188 case 0xeb000000002dULL: s390_format_RSY_RURD(s390_irgen_STCMY,
14189 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
14190 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
14191 ovl.fmt.RSY.dh2); goto ok;
14192 case 0xeb000000002fULL: /* LCTLG */ goto unimplemented;
14193 case 0xeb0000000030ULL: s390_format_RSY_RRRD(s390_irgen_CSG, ovl.fmt.RSY.r1,
14194 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14195 ovl.fmt.RSY.dl2,
14196 ovl.fmt.RSY.dh2); goto ok;
florian448cbba2012-06-06 02:26:01 +000014197 case 0xeb0000000031ULL: s390_format_RSY_RRRD(s390_irgen_CDSY, ovl.fmt.RSY.r1,
14198 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14199 ovl.fmt.RSY.dl2,
14200 ovl.fmt.RSY.dh2); goto ok;
14201 case 0xeb000000003eULL: s390_format_RSY_RRRD(s390_irgen_CDSG, ovl.fmt.RSY.r1,
14202 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14203 ovl.fmt.RSY.dl2,
14204 ovl.fmt.RSY.dh2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014205 case 0xeb0000000044ULL: s390_format_RSY_RRRD(s390_irgen_BXHG, ovl.fmt.RSY.r1,
14206 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14207 ovl.fmt.RSY.dl2,
14208 ovl.fmt.RSY.dh2); goto ok;
14209 case 0xeb0000000045ULL: s390_format_RSY_RRRD(s390_irgen_BXLEG,
14210 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
14211 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
14212 ovl.fmt.RSY.dh2); goto ok;
florian8c88cb62012-08-26 18:58:13 +000014213 case 0xeb000000004cULL: s390_format_RSY_RRRD(s390_irgen_ECAG, 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;
sewardj2019a972011-03-07 16:04:07 +000014217 case 0xeb0000000051ULL: s390_format_SIY_URD(s390_irgen_TMY, ovl.fmt.SIY.i2,
14218 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
14219 ovl.fmt.SIY.dh1); goto ok;
14220 case 0xeb0000000052ULL: s390_format_SIY_URD(s390_irgen_MVIY, ovl.fmt.SIY.i2,
14221 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
14222 ovl.fmt.SIY.dh1); goto ok;
14223 case 0xeb0000000054ULL: s390_format_SIY_URD(s390_irgen_NIY, ovl.fmt.SIY.i2,
14224 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
14225 ovl.fmt.SIY.dh1); goto ok;
14226 case 0xeb0000000055ULL: s390_format_SIY_URD(s390_irgen_CLIY, ovl.fmt.SIY.i2,
14227 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
14228 ovl.fmt.SIY.dh1); goto ok;
14229 case 0xeb0000000056ULL: s390_format_SIY_URD(s390_irgen_OIY, ovl.fmt.SIY.i2,
14230 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
14231 ovl.fmt.SIY.dh1); goto ok;
14232 case 0xeb0000000057ULL: s390_format_SIY_URD(s390_irgen_XIY, ovl.fmt.SIY.i2,
14233 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
14234 ovl.fmt.SIY.dh1); goto ok;
14235 case 0xeb000000006aULL: s390_format_SIY_IRD(s390_irgen_ASI, ovl.fmt.SIY.i2,
14236 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
14237 ovl.fmt.SIY.dh1); goto ok;
14238 case 0xeb000000006eULL: s390_format_SIY_IRD(s390_irgen_ALSI, ovl.fmt.SIY.i2,
14239 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
14240 ovl.fmt.SIY.dh1); goto ok;
14241 case 0xeb000000007aULL: s390_format_SIY_IRD(s390_irgen_AGSI, ovl.fmt.SIY.i2,
14242 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
14243 ovl.fmt.SIY.dh1); goto ok;
14244 case 0xeb000000007eULL: s390_format_SIY_IRD(s390_irgen_ALGSI, ovl.fmt.SIY.i2,
14245 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
14246 ovl.fmt.SIY.dh1); goto ok;
14247 case 0xeb0000000080ULL: s390_format_RSY_RURD(s390_irgen_ICMH, ovl.fmt.RSY.r1,
14248 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14249 ovl.fmt.RSY.dl2,
14250 ovl.fmt.RSY.dh2); goto ok;
14251 case 0xeb0000000081ULL: s390_format_RSY_RURD(s390_irgen_ICMY, ovl.fmt.RSY.r1,
14252 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14253 ovl.fmt.RSY.dl2,
14254 ovl.fmt.RSY.dh2); goto ok;
14255 case 0xeb000000008eULL: /* MVCLU */ goto unimplemented;
14256 case 0xeb000000008fULL: /* CLCLU */ goto unimplemented;
14257 case 0xeb0000000090ULL: s390_format_RSY_RRRD(s390_irgen_STMY, ovl.fmt.RSY.r1,
14258 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14259 ovl.fmt.RSY.dl2,
14260 ovl.fmt.RSY.dh2); goto ok;
14261 case 0xeb0000000096ULL: s390_format_RSY_RRRD(s390_irgen_LMH, ovl.fmt.RSY.r1,
14262 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14263 ovl.fmt.RSY.dl2,
14264 ovl.fmt.RSY.dh2); goto ok;
14265 case 0xeb0000000098ULL: s390_format_RSY_RRRD(s390_irgen_LMY, ovl.fmt.RSY.r1,
14266 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14267 ovl.fmt.RSY.dl2,
14268 ovl.fmt.RSY.dh2); goto ok;
14269 case 0xeb000000009aULL: s390_format_RSY_AARD(s390_irgen_LAMY, ovl.fmt.RSY.r1,
14270 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14271 ovl.fmt.RSY.dl2,
14272 ovl.fmt.RSY.dh2); goto ok;
14273 case 0xeb000000009bULL: s390_format_RSY_AARD(s390_irgen_STAMY,
14274 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
14275 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
14276 ovl.fmt.RSY.dh2); goto ok;
14277 case 0xeb00000000c0ULL: /* TP */ goto unimplemented;
14278 case 0xeb00000000dcULL: s390_format_RSY_RRRD(s390_irgen_SRAK, ovl.fmt.RSY.r1,
14279 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14280 ovl.fmt.RSY.dl2,
14281 ovl.fmt.RSY.dh2); goto ok;
14282 case 0xeb00000000ddULL: s390_format_RSY_RRRD(s390_irgen_SLAK, ovl.fmt.RSY.r1,
14283 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14284 ovl.fmt.RSY.dl2,
14285 ovl.fmt.RSY.dh2); goto ok;
14286 case 0xeb00000000deULL: s390_format_RSY_RRRD(s390_irgen_SRLK, ovl.fmt.RSY.r1,
14287 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14288 ovl.fmt.RSY.dl2,
14289 ovl.fmt.RSY.dh2); goto ok;
14290 case 0xeb00000000dfULL: s390_format_RSY_RRRD(s390_irgen_SLLK, ovl.fmt.RSY.r1,
14291 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14292 ovl.fmt.RSY.dl2,
14293 ovl.fmt.RSY.dh2); goto ok;
sewardjd7bde722011-04-05 13:19:33 +000014294 case 0xeb00000000e2ULL: s390_format_RSY_RDRM(s390_irgen_LOCG, ovl.fmt.RSY.r1,
14295 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14296 ovl.fmt.RSY.dl2,
14297 ovl.fmt.RSY.dh2,
14298 S390_XMNM_LOCG); goto ok;
14299 case 0xeb00000000e3ULL: s390_format_RSY_RDRM(s390_irgen_STOCG,
14300 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
14301 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
14302 ovl.fmt.RSY.dh2,
14303 S390_XMNM_STOCG); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014304 case 0xeb00000000e4ULL: s390_format_RSY_RRRD(s390_irgen_LANG, ovl.fmt.RSY.r1,
14305 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14306 ovl.fmt.RSY.dl2,
14307 ovl.fmt.RSY.dh2); goto ok;
14308 case 0xeb00000000e6ULL: s390_format_RSY_RRRD(s390_irgen_LAOG, ovl.fmt.RSY.r1,
14309 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14310 ovl.fmt.RSY.dl2,
14311 ovl.fmt.RSY.dh2); goto ok;
14312 case 0xeb00000000e7ULL: s390_format_RSY_RRRD(s390_irgen_LAXG, ovl.fmt.RSY.r1,
14313 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14314 ovl.fmt.RSY.dl2,
14315 ovl.fmt.RSY.dh2); goto ok;
14316 case 0xeb00000000e8ULL: s390_format_RSY_RRRD(s390_irgen_LAAG, ovl.fmt.RSY.r1,
14317 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14318 ovl.fmt.RSY.dl2,
14319 ovl.fmt.RSY.dh2); goto ok;
14320 case 0xeb00000000eaULL: s390_format_RSY_RRRD(s390_irgen_LAALG,
14321 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
14322 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
14323 ovl.fmt.RSY.dh2); goto ok;
sewardjd7bde722011-04-05 13:19:33 +000014324 case 0xeb00000000f2ULL: s390_format_RSY_RDRM(s390_irgen_LOC, ovl.fmt.RSY.r1,
14325 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14326 ovl.fmt.RSY.dl2,
14327 ovl.fmt.RSY.dh2, S390_XMNM_LOC);
14328 goto ok;
14329 case 0xeb00000000f3ULL: s390_format_RSY_RDRM(s390_irgen_STOC, ovl.fmt.RSY.r1,
14330 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14331 ovl.fmt.RSY.dl2,
14332 ovl.fmt.RSY.dh2,
14333 S390_XMNM_STOC); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014334 case 0xeb00000000f4ULL: s390_format_RSY_RRRD(s390_irgen_LAN, ovl.fmt.RSY.r1,
14335 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14336 ovl.fmt.RSY.dl2,
14337 ovl.fmt.RSY.dh2); goto ok;
14338 case 0xeb00000000f6ULL: s390_format_RSY_RRRD(s390_irgen_LAO, ovl.fmt.RSY.r1,
14339 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14340 ovl.fmt.RSY.dl2,
14341 ovl.fmt.RSY.dh2); goto ok;
14342 case 0xeb00000000f7ULL: s390_format_RSY_RRRD(s390_irgen_LAX, ovl.fmt.RSY.r1,
14343 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14344 ovl.fmt.RSY.dl2,
14345 ovl.fmt.RSY.dh2); goto ok;
14346 case 0xeb00000000f8ULL: s390_format_RSY_RRRD(s390_irgen_LAA, ovl.fmt.RSY.r1,
14347 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14348 ovl.fmt.RSY.dl2,
14349 ovl.fmt.RSY.dh2); goto ok;
14350 case 0xeb00000000faULL: s390_format_RSY_RRRD(s390_irgen_LAAL, ovl.fmt.RSY.r1,
14351 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14352 ovl.fmt.RSY.dl2,
14353 ovl.fmt.RSY.dh2); goto ok;
14354 case 0xec0000000044ULL: s390_format_RIE_RRP(s390_irgen_BRXHG, ovl.fmt.RIE.r1,
14355 ovl.fmt.RIE.r3, ovl.fmt.RIE.i2);
14356 goto ok;
14357 case 0xec0000000045ULL: s390_format_RIE_RRP(s390_irgen_BRXLG, ovl.fmt.RIE.r1,
14358 ovl.fmt.RIE.r3, ovl.fmt.RIE.i2);
14359 goto ok;
14360 case 0xec0000000051ULL: /* RISBLG */ goto unimplemented;
14361 case 0xec0000000054ULL: s390_format_RIE_RRUUU(s390_irgen_RNSBG,
14362 ovl.fmt.RIE_RRUUU.r1,
14363 ovl.fmt.RIE_RRUUU.r2,
14364 ovl.fmt.RIE_RRUUU.i3,
14365 ovl.fmt.RIE_RRUUU.i4,
14366 ovl.fmt.RIE_RRUUU.i5);
14367 goto ok;
14368 case 0xec0000000055ULL: s390_format_RIE_RRUUU(s390_irgen_RISBG,
14369 ovl.fmt.RIE_RRUUU.r1,
14370 ovl.fmt.RIE_RRUUU.r2,
14371 ovl.fmt.RIE_RRUUU.i3,
14372 ovl.fmt.RIE_RRUUU.i4,
14373 ovl.fmt.RIE_RRUUU.i5);
14374 goto ok;
14375 case 0xec0000000056ULL: s390_format_RIE_RRUUU(s390_irgen_ROSBG,
14376 ovl.fmt.RIE_RRUUU.r1,
14377 ovl.fmt.RIE_RRUUU.r2,
14378 ovl.fmt.RIE_RRUUU.i3,
14379 ovl.fmt.RIE_RRUUU.i4,
14380 ovl.fmt.RIE_RRUUU.i5);
14381 goto ok;
14382 case 0xec0000000057ULL: s390_format_RIE_RRUUU(s390_irgen_RXSBG,
14383 ovl.fmt.RIE_RRUUU.r1,
14384 ovl.fmt.RIE_RRUUU.r2,
14385 ovl.fmt.RIE_RRUUU.i3,
14386 ovl.fmt.RIE_RRUUU.i4,
14387 ovl.fmt.RIE_RRUUU.i5);
14388 goto ok;
14389 case 0xec000000005dULL: /* RISBHG */ goto unimplemented;
14390 case 0xec0000000064ULL: s390_format_RIE_RRPU(s390_irgen_CGRJ,
14391 ovl.fmt.RIE_RRPU.r1,
14392 ovl.fmt.RIE_RRPU.r2,
14393 ovl.fmt.RIE_RRPU.i4,
14394 ovl.fmt.RIE_RRPU.m3); goto ok;
14395 case 0xec0000000065ULL: s390_format_RIE_RRPU(s390_irgen_CLGRJ,
14396 ovl.fmt.RIE_RRPU.r1,
14397 ovl.fmt.RIE_RRPU.r2,
14398 ovl.fmt.RIE_RRPU.i4,
14399 ovl.fmt.RIE_RRPU.m3); goto ok;
14400 case 0xec0000000070ULL: /* CGIT */ goto unimplemented;
14401 case 0xec0000000071ULL: /* CLGIT */ goto unimplemented;
14402 case 0xec0000000072ULL: /* CIT */ goto unimplemented;
14403 case 0xec0000000073ULL: /* CLFIT */ goto unimplemented;
14404 case 0xec0000000076ULL: s390_format_RIE_RRPU(s390_irgen_CRJ,
14405 ovl.fmt.RIE_RRPU.r1,
14406 ovl.fmt.RIE_RRPU.r2,
14407 ovl.fmt.RIE_RRPU.i4,
14408 ovl.fmt.RIE_RRPU.m3); goto ok;
14409 case 0xec0000000077ULL: s390_format_RIE_RRPU(s390_irgen_CLRJ,
14410 ovl.fmt.RIE_RRPU.r1,
14411 ovl.fmt.RIE_RRPU.r2,
14412 ovl.fmt.RIE_RRPU.i4,
14413 ovl.fmt.RIE_RRPU.m3); goto ok;
14414 case 0xec000000007cULL: s390_format_RIE_RUPI(s390_irgen_CGIJ,
14415 ovl.fmt.RIEv3.r1,
14416 ovl.fmt.RIEv3.m3,
14417 ovl.fmt.RIEv3.i4,
14418 ovl.fmt.RIEv3.i2); goto ok;
14419 case 0xec000000007dULL: s390_format_RIE_RUPU(s390_irgen_CLGIJ,
14420 ovl.fmt.RIEv3.r1,
14421 ovl.fmt.RIEv3.m3,
14422 ovl.fmt.RIEv3.i4,
14423 ovl.fmt.RIEv3.i2); goto ok;
14424 case 0xec000000007eULL: s390_format_RIE_RUPI(s390_irgen_CIJ,
14425 ovl.fmt.RIEv3.r1,
14426 ovl.fmt.RIEv3.m3,
14427 ovl.fmt.RIEv3.i4,
14428 ovl.fmt.RIEv3.i2); goto ok;
14429 case 0xec000000007fULL: s390_format_RIE_RUPU(s390_irgen_CLIJ,
14430 ovl.fmt.RIEv3.r1,
14431 ovl.fmt.RIEv3.m3,
14432 ovl.fmt.RIEv3.i4,
14433 ovl.fmt.RIEv3.i2); goto ok;
14434 case 0xec00000000d8ULL: s390_format_RIE_RRI0(s390_irgen_AHIK, ovl.fmt.RIE.r1,
14435 ovl.fmt.RIE.r3, ovl.fmt.RIE.i2);
14436 goto ok;
14437 case 0xec00000000d9ULL: s390_format_RIE_RRI0(s390_irgen_AGHIK,
14438 ovl.fmt.RIE.r1, ovl.fmt.RIE.r3,
14439 ovl.fmt.RIE.i2); goto ok;
14440 case 0xec00000000daULL: s390_format_RIE_RRI0(s390_irgen_ALHSIK,
14441 ovl.fmt.RIE.r1, ovl.fmt.RIE.r3,
14442 ovl.fmt.RIE.i2); goto ok;
14443 case 0xec00000000dbULL: s390_format_RIE_RRI0(s390_irgen_ALGHSIK,
14444 ovl.fmt.RIE.r1, ovl.fmt.RIE.r3,
14445 ovl.fmt.RIE.i2); goto ok;
14446 case 0xec00000000e4ULL: s390_format_RRS(s390_irgen_CGRB, ovl.fmt.RRS.r1,
14447 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
14448 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
14449 goto ok;
14450 case 0xec00000000e5ULL: s390_format_RRS(s390_irgen_CLGRB, ovl.fmt.RRS.r1,
14451 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
14452 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
14453 goto ok;
14454 case 0xec00000000f6ULL: s390_format_RRS(s390_irgen_CRB, ovl.fmt.RRS.r1,
14455 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
14456 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
14457 goto ok;
14458 case 0xec00000000f7ULL: s390_format_RRS(s390_irgen_CLRB, ovl.fmt.RRS.r1,
14459 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
14460 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
14461 goto ok;
14462 case 0xec00000000fcULL: s390_format_RIS_RURDI(s390_irgen_CGIB,
14463 ovl.fmt.RIS.r1, ovl.fmt.RIS.m3,
14464 ovl.fmt.RIS.b4, ovl.fmt.RIS.d4,
14465 ovl.fmt.RIS.i2); goto ok;
14466 case 0xec00000000fdULL: s390_format_RIS_RURDU(s390_irgen_CLGIB,
14467 ovl.fmt.RIS.r1, ovl.fmt.RIS.m3,
14468 ovl.fmt.RIS.b4, ovl.fmt.RIS.d4,
14469 ovl.fmt.RIS.i2); goto ok;
14470 case 0xec00000000feULL: s390_format_RIS_RURDI(s390_irgen_CIB, ovl.fmt.RIS.r1,
14471 ovl.fmt.RIS.m3, ovl.fmt.RIS.b4,
14472 ovl.fmt.RIS.d4,
14473 ovl.fmt.RIS.i2); goto ok;
14474 case 0xec00000000ffULL: s390_format_RIS_RURDU(s390_irgen_CLIB,
14475 ovl.fmt.RIS.r1, ovl.fmt.RIS.m3,
14476 ovl.fmt.RIS.b4, ovl.fmt.RIS.d4,
14477 ovl.fmt.RIS.i2); goto ok;
14478 case 0xed0000000004ULL: s390_format_RXE_FRRD(s390_irgen_LDEB, ovl.fmt.RXE.r1,
14479 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14480 ovl.fmt.RXE.d2); goto ok;
14481 case 0xed0000000005ULL: s390_format_RXE_FRRD(s390_irgen_LXDB, ovl.fmt.RXE.r1,
14482 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14483 ovl.fmt.RXE.d2); goto ok;
14484 case 0xed0000000006ULL: s390_format_RXE_FRRD(s390_irgen_LXEB, ovl.fmt.RXE.r1,
14485 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14486 ovl.fmt.RXE.d2); goto ok;
14487 case 0xed0000000007ULL: /* MXDB */ goto unimplemented;
14488 case 0xed0000000008ULL: /* KEB */ goto unimplemented;
14489 case 0xed0000000009ULL: s390_format_RXE_FRRD(s390_irgen_CEB, ovl.fmt.RXE.r1,
14490 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14491 ovl.fmt.RXE.d2); goto ok;
14492 case 0xed000000000aULL: s390_format_RXE_FRRD(s390_irgen_AEB, ovl.fmt.RXE.r1,
14493 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14494 ovl.fmt.RXE.d2); goto ok;
14495 case 0xed000000000bULL: s390_format_RXE_FRRD(s390_irgen_SEB, ovl.fmt.RXE.r1,
14496 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14497 ovl.fmt.RXE.d2); goto ok;
14498 case 0xed000000000cULL: /* MDEB */ goto unimplemented;
14499 case 0xed000000000dULL: s390_format_RXE_FRRD(s390_irgen_DEB, ovl.fmt.RXE.r1,
14500 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14501 ovl.fmt.RXE.d2); goto ok;
14502 case 0xed000000000eULL: s390_format_RXF_FRRDF(s390_irgen_MAEB,
14503 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
14504 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
14505 ovl.fmt.RXF.r1); goto ok;
14506 case 0xed000000000fULL: s390_format_RXF_FRRDF(s390_irgen_MSEB,
14507 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
14508 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
14509 ovl.fmt.RXF.r1); goto ok;
14510 case 0xed0000000010ULL: s390_format_RXE_FRRD(s390_irgen_TCEB, ovl.fmt.RXE.r1,
14511 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14512 ovl.fmt.RXE.d2); goto ok;
14513 case 0xed0000000011ULL: s390_format_RXE_FRRD(s390_irgen_TCDB, ovl.fmt.RXE.r1,
14514 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14515 ovl.fmt.RXE.d2); goto ok;
14516 case 0xed0000000012ULL: s390_format_RXE_FRRD(s390_irgen_TCXB, ovl.fmt.RXE.r1,
14517 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14518 ovl.fmt.RXE.d2); goto ok;
14519 case 0xed0000000014ULL: s390_format_RXE_FRRD(s390_irgen_SQEB, ovl.fmt.RXE.r1,
14520 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14521 ovl.fmt.RXE.d2); goto ok;
14522 case 0xed0000000015ULL: s390_format_RXE_FRRD(s390_irgen_SQDB, ovl.fmt.RXE.r1,
14523 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14524 ovl.fmt.RXE.d2); goto ok;
14525 case 0xed0000000017ULL: s390_format_RXE_FRRD(s390_irgen_MEEB, ovl.fmt.RXE.r1,
14526 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14527 ovl.fmt.RXE.d2); goto ok;
14528 case 0xed0000000018ULL: /* KDB */ goto unimplemented;
14529 case 0xed0000000019ULL: s390_format_RXE_FRRD(s390_irgen_CDB, ovl.fmt.RXE.r1,
14530 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14531 ovl.fmt.RXE.d2); goto ok;
14532 case 0xed000000001aULL: s390_format_RXE_FRRD(s390_irgen_ADB, ovl.fmt.RXE.r1,
14533 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14534 ovl.fmt.RXE.d2); goto ok;
14535 case 0xed000000001bULL: s390_format_RXE_FRRD(s390_irgen_SDB, ovl.fmt.RXE.r1,
14536 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14537 ovl.fmt.RXE.d2); goto ok;
14538 case 0xed000000001cULL: s390_format_RXE_FRRD(s390_irgen_MDB, ovl.fmt.RXE.r1,
14539 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14540 ovl.fmt.RXE.d2); goto ok;
14541 case 0xed000000001dULL: s390_format_RXE_FRRD(s390_irgen_DDB, ovl.fmt.RXE.r1,
14542 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14543 ovl.fmt.RXE.d2); goto ok;
14544 case 0xed000000001eULL: s390_format_RXF_FRRDF(s390_irgen_MADB,
14545 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
14546 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
14547 ovl.fmt.RXF.r1); goto ok;
14548 case 0xed000000001fULL: s390_format_RXF_FRRDF(s390_irgen_MSDB,
14549 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
14550 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
14551 ovl.fmt.RXF.r1); goto ok;
14552 case 0xed0000000024ULL: /* LDE */ goto unimplemented;
14553 case 0xed0000000025ULL: /* LXD */ goto unimplemented;
14554 case 0xed0000000026ULL: /* LXE */ goto unimplemented;
14555 case 0xed000000002eULL: /* MAE */ goto unimplemented;
14556 case 0xed000000002fULL: /* MSE */ goto unimplemented;
14557 case 0xed0000000034ULL: /* SQE */ goto unimplemented;
14558 case 0xed0000000035ULL: /* SQD */ goto unimplemented;
14559 case 0xed0000000037ULL: /* MEE */ goto unimplemented;
14560 case 0xed0000000038ULL: /* MAYL */ goto unimplemented;
14561 case 0xed0000000039ULL: /* MYL */ goto unimplemented;
14562 case 0xed000000003aULL: /* MAY */ goto unimplemented;
14563 case 0xed000000003bULL: /* MY */ goto unimplemented;
14564 case 0xed000000003cULL: /* MAYH */ goto unimplemented;
14565 case 0xed000000003dULL: /* MYH */ goto unimplemented;
14566 case 0xed000000003eULL: /* MAD */ goto unimplemented;
14567 case 0xed000000003fULL: /* MSD */ goto unimplemented;
14568 case 0xed0000000040ULL: /* SLDT */ goto unimplemented;
14569 case 0xed0000000041ULL: /* SRDT */ goto unimplemented;
14570 case 0xed0000000048ULL: /* SLXT */ goto unimplemented;
14571 case 0xed0000000049ULL: /* SRXT */ goto unimplemented;
14572 case 0xed0000000050ULL: /* TDCET */ goto unimplemented;
14573 case 0xed0000000051ULL: /* TDGET */ goto unimplemented;
14574 case 0xed0000000054ULL: /* TDCDT */ goto unimplemented;
14575 case 0xed0000000055ULL: /* TDGDT */ goto unimplemented;
14576 case 0xed0000000058ULL: /* TDCXT */ goto unimplemented;
14577 case 0xed0000000059ULL: /* TDGXT */ goto unimplemented;
14578 case 0xed0000000064ULL: s390_format_RXY_FRRD(s390_irgen_LEY, ovl.fmt.RXY.r1,
14579 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14580 ovl.fmt.RXY.dl2,
14581 ovl.fmt.RXY.dh2); goto ok;
14582 case 0xed0000000065ULL: s390_format_RXY_FRRD(s390_irgen_LDY, ovl.fmt.RXY.r1,
14583 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14584 ovl.fmt.RXY.dl2,
14585 ovl.fmt.RXY.dh2); goto ok;
14586 case 0xed0000000066ULL: s390_format_RXY_FRRD(s390_irgen_STEY, ovl.fmt.RXY.r1,
14587 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14588 ovl.fmt.RXY.dl2,
14589 ovl.fmt.RXY.dh2); goto ok;
14590 case 0xed0000000067ULL: s390_format_RXY_FRRD(s390_irgen_STDY, ovl.fmt.RXY.r1,
14591 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14592 ovl.fmt.RXY.dl2,
14593 ovl.fmt.RXY.dh2); goto ok;
14594 }
14595
14596 switch (((ovl.value >> 16) & 0xff0f00000000ULL) >> 32) {
14597 case 0xc000ULL: s390_format_RIL_RP(s390_irgen_LARL, ovl.fmt.RIL.r1,
14598 ovl.fmt.RIL.i2); goto ok;
14599 case 0xc001ULL: s390_format_RIL_RI(s390_irgen_LGFI, ovl.fmt.RIL.r1,
14600 ovl.fmt.RIL.i2); goto ok;
14601 case 0xc004ULL: s390_format_RIL(s390_irgen_BRCL, ovl.fmt.RIL.r1,
14602 ovl.fmt.RIL.i2); goto ok;
14603 case 0xc005ULL: s390_format_RIL_RP(s390_irgen_BRASL, ovl.fmt.RIL.r1,
14604 ovl.fmt.RIL.i2); goto ok;
14605 case 0xc006ULL: s390_format_RIL_RU(s390_irgen_XIHF, ovl.fmt.RIL.r1,
14606 ovl.fmt.RIL.i2); goto ok;
14607 case 0xc007ULL: s390_format_RIL_RU(s390_irgen_XILF, ovl.fmt.RIL.r1,
14608 ovl.fmt.RIL.i2); goto ok;
14609 case 0xc008ULL: s390_format_RIL_RU(s390_irgen_IIHF, ovl.fmt.RIL.r1,
14610 ovl.fmt.RIL.i2); goto ok;
14611 case 0xc009ULL: s390_format_RIL_RU(s390_irgen_IILF, ovl.fmt.RIL.r1,
14612 ovl.fmt.RIL.i2); goto ok;
14613 case 0xc00aULL: s390_format_RIL_RU(s390_irgen_NIHF, ovl.fmt.RIL.r1,
14614 ovl.fmt.RIL.i2); goto ok;
14615 case 0xc00bULL: s390_format_RIL_RU(s390_irgen_NILF, ovl.fmt.RIL.r1,
14616 ovl.fmt.RIL.i2); goto ok;
14617 case 0xc00cULL: s390_format_RIL_RU(s390_irgen_OIHF, ovl.fmt.RIL.r1,
14618 ovl.fmt.RIL.i2); goto ok;
14619 case 0xc00dULL: s390_format_RIL_RU(s390_irgen_OILF, ovl.fmt.RIL.r1,
14620 ovl.fmt.RIL.i2); goto ok;
14621 case 0xc00eULL: s390_format_RIL_RU(s390_irgen_LLIHF, ovl.fmt.RIL.r1,
14622 ovl.fmt.RIL.i2); goto ok;
14623 case 0xc00fULL: s390_format_RIL_RU(s390_irgen_LLILF, ovl.fmt.RIL.r1,
14624 ovl.fmt.RIL.i2); goto ok;
14625 case 0xc200ULL: s390_format_RIL_RI(s390_irgen_MSGFI, ovl.fmt.RIL.r1,
14626 ovl.fmt.RIL.i2); goto ok;
14627 case 0xc201ULL: s390_format_RIL_RI(s390_irgen_MSFI, ovl.fmt.RIL.r1,
14628 ovl.fmt.RIL.i2); goto ok;
14629 case 0xc204ULL: s390_format_RIL_RU(s390_irgen_SLGFI, ovl.fmt.RIL.r1,
14630 ovl.fmt.RIL.i2); goto ok;
14631 case 0xc205ULL: s390_format_RIL_RU(s390_irgen_SLFI, ovl.fmt.RIL.r1,
14632 ovl.fmt.RIL.i2); goto ok;
14633 case 0xc208ULL: s390_format_RIL_RI(s390_irgen_AGFI, ovl.fmt.RIL.r1,
14634 ovl.fmt.RIL.i2); goto ok;
14635 case 0xc209ULL: s390_format_RIL_RI(s390_irgen_AFI, ovl.fmt.RIL.r1,
14636 ovl.fmt.RIL.i2); goto ok;
14637 case 0xc20aULL: s390_format_RIL_RU(s390_irgen_ALGFI, ovl.fmt.RIL.r1,
14638 ovl.fmt.RIL.i2); goto ok;
14639 case 0xc20bULL: s390_format_RIL_RU(s390_irgen_ALFI, ovl.fmt.RIL.r1,
14640 ovl.fmt.RIL.i2); goto ok;
14641 case 0xc20cULL: s390_format_RIL_RI(s390_irgen_CGFI, ovl.fmt.RIL.r1,
14642 ovl.fmt.RIL.i2); goto ok;
14643 case 0xc20dULL: s390_format_RIL_RI(s390_irgen_CFI, ovl.fmt.RIL.r1,
14644 ovl.fmt.RIL.i2); goto ok;
14645 case 0xc20eULL: s390_format_RIL_RU(s390_irgen_CLGFI, ovl.fmt.RIL.r1,
14646 ovl.fmt.RIL.i2); goto ok;
14647 case 0xc20fULL: s390_format_RIL_RU(s390_irgen_CLFI, ovl.fmt.RIL.r1,
14648 ovl.fmt.RIL.i2); goto ok;
14649 case 0xc402ULL: s390_format_RIL_RP(s390_irgen_LLHRL, ovl.fmt.RIL.r1,
14650 ovl.fmt.RIL.i2); goto ok;
14651 case 0xc404ULL: s390_format_RIL_RP(s390_irgen_LGHRL, ovl.fmt.RIL.r1,
14652 ovl.fmt.RIL.i2); goto ok;
14653 case 0xc405ULL: s390_format_RIL_RP(s390_irgen_LHRL, ovl.fmt.RIL.r1,
14654 ovl.fmt.RIL.i2); goto ok;
14655 case 0xc406ULL: s390_format_RIL_RP(s390_irgen_LLGHRL, ovl.fmt.RIL.r1,
14656 ovl.fmt.RIL.i2); goto ok;
14657 case 0xc407ULL: s390_format_RIL_RP(s390_irgen_STHRL, ovl.fmt.RIL.r1,
14658 ovl.fmt.RIL.i2); goto ok;
14659 case 0xc408ULL: s390_format_RIL_RP(s390_irgen_LGRL, ovl.fmt.RIL.r1,
14660 ovl.fmt.RIL.i2); goto ok;
14661 case 0xc40bULL: s390_format_RIL_RP(s390_irgen_STGRL, ovl.fmt.RIL.r1,
14662 ovl.fmt.RIL.i2); goto ok;
14663 case 0xc40cULL: s390_format_RIL_RP(s390_irgen_LGFRL, ovl.fmt.RIL.r1,
14664 ovl.fmt.RIL.i2); goto ok;
14665 case 0xc40dULL: s390_format_RIL_RP(s390_irgen_LRL, ovl.fmt.RIL.r1,
14666 ovl.fmt.RIL.i2); goto ok;
14667 case 0xc40eULL: s390_format_RIL_RP(s390_irgen_LLGFRL, ovl.fmt.RIL.r1,
14668 ovl.fmt.RIL.i2); goto ok;
14669 case 0xc40fULL: s390_format_RIL_RP(s390_irgen_STRL, ovl.fmt.RIL.r1,
14670 ovl.fmt.RIL.i2); goto ok;
14671 case 0xc600ULL: s390_format_RIL_RP(s390_irgen_EXRL, ovl.fmt.RIL.r1,
14672 ovl.fmt.RIL.i2); goto ok;
14673 case 0xc602ULL: s390_format_RIL_UP(s390_irgen_PFDRL, ovl.fmt.RIL.r1,
14674 ovl.fmt.RIL.i2); goto ok;
14675 case 0xc604ULL: s390_format_RIL_RP(s390_irgen_CGHRL, ovl.fmt.RIL.r1,
14676 ovl.fmt.RIL.i2); goto ok;
14677 case 0xc605ULL: s390_format_RIL_RP(s390_irgen_CHRL, ovl.fmt.RIL.r1,
14678 ovl.fmt.RIL.i2); goto ok;
14679 case 0xc606ULL: s390_format_RIL_RP(s390_irgen_CLGHRL, ovl.fmt.RIL.r1,
14680 ovl.fmt.RIL.i2); goto ok;
14681 case 0xc607ULL: s390_format_RIL_RP(s390_irgen_CLHRL, ovl.fmt.RIL.r1,
14682 ovl.fmt.RIL.i2); goto ok;
14683 case 0xc608ULL: s390_format_RIL_RP(s390_irgen_CGRL, ovl.fmt.RIL.r1,
14684 ovl.fmt.RIL.i2); goto ok;
14685 case 0xc60aULL: s390_format_RIL_RP(s390_irgen_CLGRL, ovl.fmt.RIL.r1,
14686 ovl.fmt.RIL.i2); goto ok;
14687 case 0xc60cULL: s390_format_RIL_RP(s390_irgen_CGFRL, ovl.fmt.RIL.r1,
14688 ovl.fmt.RIL.i2); goto ok;
14689 case 0xc60dULL: s390_format_RIL_RP(s390_irgen_CRL, ovl.fmt.RIL.r1,
14690 ovl.fmt.RIL.i2); goto ok;
14691 case 0xc60eULL: s390_format_RIL_RP(s390_irgen_CLGFRL, ovl.fmt.RIL.r1,
14692 ovl.fmt.RIL.i2); goto ok;
14693 case 0xc60fULL: s390_format_RIL_RP(s390_irgen_CLRL, ovl.fmt.RIL.r1,
14694 ovl.fmt.RIL.i2); goto ok;
14695 case 0xc800ULL: /* MVCOS */ goto unimplemented;
14696 case 0xc801ULL: /* ECTG */ goto unimplemented;
14697 case 0xc802ULL: /* CSST */ goto unimplemented;
14698 case 0xc804ULL: /* LPD */ goto unimplemented;
14699 case 0xc805ULL: /* LPDG */ goto unimplemented;
14700 case 0xcc06ULL: /* BRCTH */ goto unimplemented;
14701 case 0xcc08ULL: s390_format_RIL_RI(s390_irgen_AIH, ovl.fmt.RIL.r1,
14702 ovl.fmt.RIL.i2); goto ok;
14703 case 0xcc0aULL: s390_format_RIL_RI(s390_irgen_ALSIH, ovl.fmt.RIL.r1,
14704 ovl.fmt.RIL.i2); goto ok;
14705 case 0xcc0bULL: s390_format_RIL_RI(s390_irgen_ALSIHN, ovl.fmt.RIL.r1,
14706 ovl.fmt.RIL.i2); goto ok;
14707 case 0xcc0dULL: s390_format_RIL_RI(s390_irgen_CIH, ovl.fmt.RIL.r1,
14708 ovl.fmt.RIL.i2); goto ok;
14709 case 0xcc0fULL: s390_format_RIL_RU(s390_irgen_CLIH, ovl.fmt.RIL.r1,
14710 ovl.fmt.RIL.i2); goto ok;
14711 }
14712
14713 switch (((ovl.value >> 16) & 0xff0000000000ULL) >> 40) {
14714 case 0xd0ULL: /* TRTR */ goto unimplemented;
14715 case 0xd1ULL: /* MVN */ goto unimplemented;
14716 case 0xd2ULL: s390_format_SS_L0RDRD(s390_irgen_MVC, ovl.fmt.SS.l,
14717 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
14718 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
14719 case 0xd3ULL: /* MVZ */ goto unimplemented;
14720 case 0xd4ULL: s390_format_SS_L0RDRD(s390_irgen_NC, ovl.fmt.SS.l,
14721 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
14722 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
14723 case 0xd5ULL: s390_format_SS_L0RDRD(s390_irgen_CLC, ovl.fmt.SS.l,
14724 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
14725 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
14726 case 0xd6ULL: s390_format_SS_L0RDRD(s390_irgen_OC, ovl.fmt.SS.l,
14727 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
14728 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
sewardjb63967e2011-03-24 08:50:04 +000014729 case 0xd7ULL:
14730 if (ovl.fmt.SS.b1 == ovl.fmt.SS.b2 && ovl.fmt.SS.d1 == ovl.fmt.SS.d2)
14731 s390_irgen_XC_sameloc(ovl.fmt.SS.l, ovl.fmt.SS.b1, ovl.fmt.SS.d1);
14732 else
14733 s390_format_SS_L0RDRD(s390_irgen_XC, ovl.fmt.SS.l,
14734 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
14735 ovl.fmt.SS.b2, ovl.fmt.SS.d2);
14736 goto ok;
sewardj2019a972011-03-07 16:04:07 +000014737 case 0xd9ULL: /* MVCK */ goto unimplemented;
14738 case 0xdaULL: /* MVCP */ goto unimplemented;
14739 case 0xdbULL: /* MVCS */ goto unimplemented;
florian730448f2012-02-04 17:07:07 +000014740 case 0xdcULL: s390_format_SS_L0RDRD(s390_irgen_TR, ovl.fmt.SS.l,
14741 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
14742 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014743 case 0xddULL: /* TRT */ goto unimplemented;
14744 case 0xdeULL: /* ED */ goto unimplemented;
14745 case 0xdfULL: /* EDMK */ goto unimplemented;
14746 case 0xe1ULL: /* PKU */ goto unimplemented;
14747 case 0xe2ULL: /* UNPKU */ goto unimplemented;
14748 case 0xe8ULL: /* MVCIN */ goto unimplemented;
14749 case 0xe9ULL: /* PKA */ goto unimplemented;
14750 case 0xeaULL: /* UNPKA */ goto unimplemented;
14751 case 0xeeULL: /* PLO */ goto unimplemented;
14752 case 0xefULL: /* LMD */ goto unimplemented;
14753 case 0xf0ULL: /* SRP */ goto unimplemented;
14754 case 0xf1ULL: /* MVO */ goto unimplemented;
14755 case 0xf2ULL: /* PACK */ goto unimplemented;
14756 case 0xf3ULL: /* UNPK */ goto unimplemented;
14757 case 0xf8ULL: /* ZAP */ goto unimplemented;
14758 case 0xf9ULL: /* CP */ goto unimplemented;
14759 case 0xfaULL: /* AP */ goto unimplemented;
14760 case 0xfbULL: /* SP */ goto unimplemented;
14761 case 0xfcULL: /* MP */ goto unimplemented;
14762 case 0xfdULL: /* DP */ goto unimplemented;
14763 }
14764
14765 switch (((ovl.value >> 16) & 0xffff00000000ULL) >> 32) {
14766 case 0xe500ULL: /* LASP */ goto unimplemented;
14767 case 0xe501ULL: /* TPROT */ goto unimplemented;
14768 case 0xe502ULL: /* STRAG */ goto unimplemented;
14769 case 0xe50eULL: /* MVCSK */ goto unimplemented;
14770 case 0xe50fULL: /* MVCDK */ goto unimplemented;
14771 case 0xe544ULL: s390_format_SIL_RDI(s390_irgen_MVHHI, ovl.fmt.SIL.b1,
14772 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14773 goto ok;
14774 case 0xe548ULL: s390_format_SIL_RDI(s390_irgen_MVGHI, ovl.fmt.SIL.b1,
14775 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14776 goto ok;
14777 case 0xe54cULL: s390_format_SIL_RDI(s390_irgen_MVHI, ovl.fmt.SIL.b1,
14778 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14779 goto ok;
14780 case 0xe554ULL: s390_format_SIL_RDI(s390_irgen_CHHSI, ovl.fmt.SIL.b1,
14781 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14782 goto ok;
14783 case 0xe555ULL: s390_format_SIL_RDU(s390_irgen_CLHHSI, ovl.fmt.SIL.b1,
14784 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14785 goto ok;
14786 case 0xe558ULL: s390_format_SIL_RDI(s390_irgen_CGHSI, ovl.fmt.SIL.b1,
14787 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14788 goto ok;
14789 case 0xe559ULL: s390_format_SIL_RDU(s390_irgen_CLGHSI, ovl.fmt.SIL.b1,
14790 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14791 goto ok;
14792 case 0xe55cULL: s390_format_SIL_RDI(s390_irgen_CHSI, ovl.fmt.SIL.b1,
14793 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14794 goto ok;
14795 case 0xe55dULL: s390_format_SIL_RDU(s390_irgen_CLFHSI, ovl.fmt.SIL.b1,
14796 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14797 goto ok;
14798 }
14799
14800 return S390_DECODE_UNKNOWN_INSN;
14801
14802ok:
14803 return S390_DECODE_OK;
14804
14805unimplemented:
14806 return S390_DECODE_UNIMPLEMENTED_INSN;
14807}
14808
14809/* Handle "special" instructions. */
14810static s390_decode_t
14811s390_decode_special_and_irgen(UChar *bytes)
14812{
14813 s390_decode_t status = S390_DECODE_OK;
14814
14815 /* Got a "Special" instruction preamble. Which one is it? */
14816 if (bytes[0] == 0x18 && bytes[1] == 0x22 /* lr %r2, %r2 */) {
14817 s390_irgen_client_request();
14818 } else if (bytes[0] == 0x18 && bytes[1] == 0x33 /* lr %r3, %r3 */) {
14819 s390_irgen_guest_NRADDR();
14820 } else if (bytes[0] == 0x18 && bytes[1] == 0x44 /* lr %r4, %r4 */) {
14821 s390_irgen_call_noredir();
florian2245ce92012-08-28 16:49:30 +000014822 } else if (bytes[0] == 0x18 && bytes[1] == 0x55 /* lr %r5, %r5 */) {
14823 vex_inject_ir(irsb, Iend_BE);
14824
14825 /* Invalidate the current insn. The reason is that the IRop we're
14826 injecting here can change. In which case the translation has to
14827 be redone. For ease of handling, we simply invalidate all the
14828 time. */
14829 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TISTART),
14830 mkU64(guest_IA_curr_instr)));
14831 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TILEN),
14832 mkU64(guest_IA_next_instr - guest_IA_curr_instr)));
14833 vassert(guest_IA_next_instr - guest_IA_curr_instr ==
14834 S390_SPECIAL_OP_PREAMBLE_SIZE + S390_SPECIAL_OP_SIZE);
14835
14836 put_IA(mkaddr_expr(guest_IA_next_instr));
14837 dis_res->whatNext = Dis_StopHere;
14838 dis_res->jk_StopHere = Ijk_TInval;
sewardj2019a972011-03-07 16:04:07 +000014839 } else {
14840 /* We don't know what it is. */
14841 return S390_DECODE_UNKNOWN_SPECIAL_INSN;
14842 }
14843
14844 dis_res->len = S390_SPECIAL_OP_PREAMBLE_SIZE + S390_SPECIAL_OP_SIZE;
14845
14846 return status;
14847}
14848
14849
14850/* Function returns # bytes that were decoded or 0 in case of failure */
florianb4df7682011-07-05 02:09:01 +000014851static UInt
sewardj2019a972011-03-07 16:04:07 +000014852s390_decode_and_irgen(UChar *bytes, UInt insn_length, DisResult *dres)
14853{
14854 s390_decode_t status;
14855
14856 dis_res = dres;
14857
14858 /* Spot the 8-byte preamble: 18ff lr r15,r15
14859 1811 lr r1,r1
14860 1822 lr r2,r2
14861 1833 lr r3,r3 */
14862 if (bytes[ 0] == 0x18 && bytes[ 1] == 0xff && bytes[ 2] == 0x18 &&
14863 bytes[ 3] == 0x11 && bytes[ 4] == 0x18 && bytes[ 5] == 0x22 &&
14864 bytes[ 6] == 0x18 && bytes[ 7] == 0x33) {
14865
14866 /* Handle special instruction that follows that preamble. */
14867 if (0) vex_printf("special function handling...\n");
florian2c8ed942011-08-01 22:07:51 +000014868
14869 insn_length = S390_SPECIAL_OP_PREAMBLE_SIZE + S390_SPECIAL_OP_SIZE;
14870 guest_IA_next_instr = guest_IA_curr_instr + insn_length;
14871
14872 status =
14873 s390_decode_special_and_irgen(bytes + S390_SPECIAL_OP_PREAMBLE_SIZE);
sewardj2019a972011-03-07 16:04:07 +000014874 } else {
14875 /* Handle normal instructions. */
14876 switch (insn_length) {
14877 case 2:
14878 status = s390_decode_2byte_and_irgen(bytes);
14879 break;
14880
14881 case 4:
14882 status = s390_decode_4byte_and_irgen(bytes);
14883 break;
14884
14885 case 6:
14886 status = s390_decode_6byte_and_irgen(bytes);
14887 break;
14888
14889 default:
14890 status = S390_DECODE_ERROR;
14891 break;
14892 }
14893 }
florian5fcbba22011-07-27 20:40:22 +000014894 /* If next instruction is execute, stop here */
florianf9e1ed72012-04-17 02:41:56 +000014895 if (dis_res->whatNext == Dis_Continue && bytes[insn_length] == 0x44) {
14896 put_IA(mkaddr_expr(guest_IA_next_instr));
sewardj2019a972011-03-07 16:04:07 +000014897 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +000014898 dis_res->jk_StopHere = Ijk_Boring;
sewardj2019a972011-03-07 16:04:07 +000014899 }
14900
14901 if (status == S390_DECODE_OK) return insn_length; /* OK */
14902
14903 /* Decoding failed somehow */
14904 vex_printf("vex s390->IR: ");
14905 switch (status) {
14906 case S390_DECODE_UNKNOWN_INSN:
14907 vex_printf("unknown insn: ");
14908 break;
14909
14910 case S390_DECODE_UNIMPLEMENTED_INSN:
14911 vex_printf("unimplemented insn: ");
14912 break;
14913
14914 case S390_DECODE_UNKNOWN_SPECIAL_INSN:
14915 vex_printf("unimplemented special insn: ");
14916 break;
14917
14918 default:
14919 case S390_DECODE_ERROR:
14920 vex_printf("decoding error: ");
14921 break;
14922 }
14923
14924 vex_printf("%02x%02x", bytes[0], bytes[1]);
14925 if (insn_length > 2) {
14926 vex_printf(" %02x%02x", bytes[2], bytes[3]);
14927 }
14928 if (insn_length > 4) {
14929 vex_printf(" %02x%02x", bytes[4], bytes[5]);
14930 }
14931 vex_printf("\n");
14932
14933 return 0; /* Failed */
14934}
14935
14936
sewardj2019a972011-03-07 16:04:07 +000014937/* Disassemble a single instruction INSN into IR. */
14938static DisResult
florian420c5012011-07-22 02:12:28 +000014939disInstr_S390_WRK(UChar *insn)
sewardj2019a972011-03-07 16:04:07 +000014940{
14941 UChar byte;
14942 UInt insn_length;
14943 DisResult dres;
14944
14945 /* ---------------------------------------------------- */
14946 /* --- Compute instruction length -- */
14947 /* ---------------------------------------------------- */
14948
14949 /* Get the first byte of the insn. */
14950 byte = insn[0];
14951
14952 /* The leftmost two bits (0:1) encode the length of the insn in bytes.
14953 00 -> 2 bytes, 01 -> 4 bytes, 10 -> 4 bytes, 11 -> 6 bytes. */
14954 insn_length = ((((byte >> 6) + 1) >> 1) + 1) << 1;
14955
14956 guest_IA_next_instr = guest_IA_curr_instr + insn_length;
14957
14958 /* ---------------------------------------------------- */
14959 /* --- Initialise the DisResult data -- */
14960 /* ---------------------------------------------------- */
14961 dres.whatNext = Dis_Continue;
14962 dres.len = insn_length;
14963 dres.continueAt = 0;
florian8844a632012-04-13 04:04:06 +000014964 dres.jk_StopHere = Ijk_INVALID;
sewardj2019a972011-03-07 16:04:07 +000014965
floriana99f20e2011-07-17 14:16:41 +000014966 /* fixs390: consider chasing of conditional jumps */
14967
sewardj2019a972011-03-07 16:04:07 +000014968 /* Normal and special instruction handling starts here. */
14969 if (s390_decode_and_irgen(insn, insn_length, &dres) == 0) {
14970 /* All decode failures end up here. The decoder has already issued an
14971 error message.
14972 Tell the dispatcher that this insn cannot be decoded, and so has
florian342e01a2012-07-26 02:37:49 +000014973 not been executed, and (is currently) the next to be executed.
14974 The insn address in the guest state needs to be set to
14975 guest_IA_curr_instr, otherwise the complaint will report an
14976 incorrect address. */
14977 put_IA(mkaddr_expr(guest_IA_curr_instr));
sewardj2019a972011-03-07 16:04:07 +000014978
florian8844a632012-04-13 04:04:06 +000014979 dres.whatNext = Dis_StopHere;
14980 dres.jk_StopHere = Ijk_NoDecode;
14981 dres.continueAt = 0;
14982 dres.len = 0;
14983 } else {
14984 /* Decode success */
14985 switch (dres.whatNext) {
14986 case Dis_Continue:
florian8559e412012-04-19 14:23:48 +000014987 put_IA(mkaddr_expr(guest_IA_next_instr));
florian8844a632012-04-13 04:04:06 +000014988 break;
14989 case Dis_ResteerU:
14990 case Dis_ResteerC:
14991 put_IA(mkaddr_expr(dres.continueAt));
14992 break;
14993 case Dis_StopHere:
florian4b8efad2012-09-02 18:07:08 +000014994 if (dres.jk_StopHere == Ijk_EmWarn ||
14995 dres.jk_StopHere == Ijk_EmFail) {
14996 /* We assume here, that emulation warnings are not given for
14997 insns that transfer control. There is no good way to
14998 do that. */
14999 put_IA(mkaddr_expr(guest_IA_next_instr));
15000 }
florian8844a632012-04-13 04:04:06 +000015001 break;
15002 default:
15003 vassert(0);
15004 }
sewardj2019a972011-03-07 16:04:07 +000015005 }
15006
15007 return dres;
15008}
15009
15010
15011/*------------------------------------------------------------*/
15012/*--- Top-level fn ---*/
15013/*------------------------------------------------------------*/
15014
15015/* Disassemble a single instruction into IR. The instruction
15016 is located in host memory at &guest_code[delta]. */
15017
15018DisResult
15019disInstr_S390(IRSB *irsb_IN,
sewardj2019a972011-03-07 16:04:07 +000015020 Bool (*resteerOkFn)(void *, Addr64),
15021 Bool resteerCisOk,
15022 void *callback_opaque,
15023 UChar *guest_code,
15024 Long delta,
15025 Addr64 guest_IP,
15026 VexArch guest_arch,
15027 VexArchInfo *archinfo,
15028 VexAbiInfo *abiinfo,
15029 Bool host_bigendian)
15030{
15031 vassert(guest_arch == VexArchS390X);
15032
15033 /* The instruction decoder requires a big-endian machine. */
15034 vassert(host_bigendian == True);
15035
15036 /* Set globals (see top of this file) */
15037 guest_IA_curr_instr = guest_IP;
sewardj2019a972011-03-07 16:04:07 +000015038 irsb = irsb_IN;
florian420c5012011-07-22 02:12:28 +000015039 resteer_fn = resteerOkFn;
15040 resteer_data = callback_opaque;
sewardj2019a972011-03-07 16:04:07 +000015041
florian420c5012011-07-22 02:12:28 +000015042 return disInstr_S390_WRK(guest_code + delta);
sewardj2019a972011-03-07 16:04:07 +000015043}
15044
15045/*---------------------------------------------------------------*/
15046/*--- end guest_s390_toIR.c ---*/
15047/*---------------------------------------------------------------*/