blob: bde121ba50d26465972a3a82c7edbdbd147ce5a7 [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 *);
430
431/* Read a floating point register pair and combine their contents into a
432 128-bit value */
433static IRExpr *
434get_fpr_pair(UInt archreg)
435{
436 IRExpr *high = get_fpr_dw0(archreg);
437 IRExpr *low = get_fpr_dw0(archreg + 2);
438
439 return binop(Iop_F64HLtoF128, high, low);
440}
441
442/* Write a 128-bit floating point value into a register pair. */
443static void
444put_fpr_pair(UInt archreg, IRExpr *expr)
445{
446 IRExpr *high = unop(Iop_F128HItoF64, expr);
447 IRExpr *low = unop(Iop_F128LOtoF64, expr);
448
449 put_fpr_dw0(archreg, high);
450 put_fpr_dw0(archreg + 2, low);
451}
452
floriane75dafa2012-09-01 17:54:09 +0000453/* Terminate the current IRSB with an emulation failure. */
454static void
455emulation_failure(VexEmNote fail_kind)
456{
457 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_EMNOTE), mkU32(fail_kind)));
floriane75dafa2012-09-01 17:54:09 +0000458 dis_res->whatNext = Dis_StopHere;
459 dis_res->jk_StopHere = Ijk_EmFail;
460}
sewardj2019a972011-03-07 16:04:07 +0000461
florian4b8efad2012-09-02 18:07:08 +0000462/* Terminate the current IRSB with an emulation warning. */
463static void
464emulation_warning(VexEmNote warn_kind)
465{
466 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_EMNOTE), mkU32(warn_kind)));
467 dis_res->whatNext = Dis_StopHere;
468 dis_res->jk_StopHere = Ijk_EmWarn;
469}
470
sewardj2019a972011-03-07 16:04:07 +0000471/*------------------------------------------------------------*/
florianf3410f92012-08-03 18:41:58 +0000472/*--- IR Debugging aids. ---*/
473/*------------------------------------------------------------*/
474#if 0
475
476static ULong
477s390_do_print(HChar *text, ULong value)
478{
479 vex_printf("%s %llu\n", text, value);
480 return 0;
481}
482
483static void
484s390_print(HChar *text, IRExpr *value)
485{
486 IRDirty *d;
487
488 d = unsafeIRDirty_0_N(0 /* regparms */, "s390_do_print", &s390_do_print,
489 mkIRExprVec_2(mkU64((ULong)text), value));
490 stmt(IRStmt_Dirty(d));
491}
492#endif
493
494
495/*------------------------------------------------------------*/
sewardj2019a972011-03-07 16:04:07 +0000496/*--- Build the flags thunk. ---*/
497/*------------------------------------------------------------*/
498
499/* Completely fill the flags thunk. We're always filling all fields.
500 Apparently, that is better for redundant PUT elimination. */
501static void
502s390_cc_thunk_fill(IRExpr *op, IRExpr *dep1, IRExpr *dep2, IRExpr *ndep)
503{
504 UInt op_off, dep1_off, dep2_off, ndep_off;
505
florian428dfdd2012-03-27 03:09:49 +0000506 op_off = S390X_GUEST_OFFSET(guest_CC_OP);
507 dep1_off = S390X_GUEST_OFFSET(guest_CC_DEP1);
508 dep2_off = S390X_GUEST_OFFSET(guest_CC_DEP2);
509 ndep_off = S390X_GUEST_OFFSET(guest_CC_NDEP);
sewardj2019a972011-03-07 16:04:07 +0000510
511 stmt(IRStmt_Put(op_off, op));
512 stmt(IRStmt_Put(dep1_off, dep1));
513 stmt(IRStmt_Put(dep2_off, dep2));
514 stmt(IRStmt_Put(ndep_off, ndep));
515}
516
517
518/* Create an expression for V and widen the result to 64 bit. */
519static IRExpr *
520s390_cc_widen(IRTemp v, Bool sign_extend)
521{
522 IRExpr *expr;
523
524 expr = mkexpr(v);
525
526 switch (typeOfIRTemp(irsb->tyenv, v)) {
527 case Ity_I64:
528 break;
529 case Ity_I32:
530 expr = unop(sign_extend ? Iop_32Sto64 : Iop_32Uto64, expr);
531 break;
532 case Ity_I16:
533 expr = unop(sign_extend ? Iop_16Sto64 : Iop_16Uto64, expr);
534 break;
535 case Ity_I8:
536 expr = unop(sign_extend ? Iop_8Sto64 : Iop_8Uto64, expr);
537 break;
538 default:
539 vpanic("s390_cc_widen");
540 }
541
542 return expr;
543}
544
545static void
546s390_cc_thunk_put1(UInt opc, IRTemp d1, Bool sign_extend)
547{
548 IRExpr *op, *dep1, *dep2, *ndep;
549
550 op = mkU64(opc);
551 dep1 = s390_cc_widen(d1, sign_extend);
552 dep2 = mkU64(0);
553 ndep = mkU64(0);
554
555 s390_cc_thunk_fill(op, dep1, dep2, ndep);
556}
557
558
559static void
560s390_cc_thunk_put2(UInt opc, IRTemp d1, IRTemp d2, Bool sign_extend)
561{
562 IRExpr *op, *dep1, *dep2, *ndep;
563
564 op = mkU64(opc);
565 dep1 = s390_cc_widen(d1, sign_extend);
566 dep2 = s390_cc_widen(d2, sign_extend);
567 ndep = mkU64(0);
568
569 s390_cc_thunk_fill(op, dep1, dep2, ndep);
570}
571
572
573/* memcheck believes that the NDEP field in the flags thunk is always
574 defined. But for some flag computations (e.g. add with carry) that is
575 just not true. We therefore need to convey to memcheck that the value
576 of the ndep field does matter and therefore we make the DEP2 field
577 depend on it:
578
579 DEP2 = original_DEP2 ^ NDEP
580
581 In s390_calculate_cc we exploit that (a^b)^b == a
582 I.e. we xor the DEP2 value with the NDEP value to recover the
583 original_DEP2 value. */
584static void
585s390_cc_thunk_put3(UInt opc, IRTemp d1, IRTemp d2, IRTemp nd, Bool sign_extend)
586{
587 IRExpr *op, *dep1, *dep2, *ndep, *dep2x;
588
589 op = mkU64(opc);
590 dep1 = s390_cc_widen(d1, sign_extend);
591 dep2 = s390_cc_widen(d2, sign_extend);
592 ndep = s390_cc_widen(nd, sign_extend);
593
594 dep2x = binop(Iop_Xor64, dep2, ndep);
595
596 s390_cc_thunk_fill(op, dep1, dep2x, ndep);
597}
598
599
600/* Write one floating point value into the flags thunk */
601static void
602s390_cc_thunk_put1f(UInt opc, IRTemp d1)
603{
604 IRExpr *op, *dep1, *dep2, *ndep;
605
606 op = mkU64(opc);
607 dep1 = mkexpr(d1);
608 dep2 = mkU64(0);
609 ndep = mkU64(0);
610
611 s390_cc_thunk_fill(op, dep1, dep2, ndep);
612}
613
614
615/* Write a floating point value and an integer into the flags thunk. The
616 integer value is zero-extended first. */
617static void
618s390_cc_thunk_putFZ(UInt opc, IRTemp d1, IRTemp d2)
619{
620 IRExpr *op, *dep1, *dep2, *ndep;
621
622 op = mkU64(opc);
623 dep1 = mkexpr(d1);
624 dep2 = s390_cc_widen(d2, False);
625 ndep = mkU64(0);
626
627 s390_cc_thunk_fill(op, dep1, dep2, ndep);
628}
629
630
631/* Write a 128-bit floating point value into the flags thunk. This is
632 done by splitting the value into two 64-bits values. */
633static void
634s390_cc_thunk_put1f128(UInt opc, IRTemp d1)
635{
636 IRExpr *op, *hi, *lo, *ndep;
637
638 op = mkU64(opc);
639 hi = unop(Iop_F128HItoF64, mkexpr(d1));
640 lo = unop(Iop_F128LOtoF64, mkexpr(d1));
641 ndep = mkU64(0);
642
643 s390_cc_thunk_fill(op, hi, lo, ndep);
644}
645
646
647/* Write a 128-bit floating point value and an integer into the flags thunk.
648 The integer value is zero-extended first. */
649static void
650s390_cc_thunk_put1f128Z(UInt opc, IRTemp d1, IRTemp nd)
651{
652 IRExpr *op, *hi, *lo, *lox, *ndep;
653
654 op = mkU64(opc);
655 hi = unop(Iop_F128HItoF64, mkexpr(d1));
656 lo = unop(Iop_ReinterpF64asI64, unop(Iop_F128LOtoF64, mkexpr(d1)));
657 ndep = s390_cc_widen(nd, False);
658
659 lox = binop(Iop_Xor64, lo, ndep); /* convey dependency */
660
661 s390_cc_thunk_fill(op, hi, lox, ndep);
662}
663
664
665static void
666s390_cc_set(UInt val)
667{
668 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
669 mkU64(val), mkU64(0), mkU64(0));
670}
671
672/* Build IR to calculate the condition code from flags thunk.
673 Returns an expression of type Ity_I32 */
674static IRExpr *
675s390_call_calculate_cc(void)
676{
677 IRExpr **args, *call, *op, *dep1, *dep2, *ndep;
678
florian428dfdd2012-03-27 03:09:49 +0000679 op = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_OP), Ity_I64);
680 dep1 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP1), Ity_I64);
681 dep2 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP2), Ity_I64);
682 ndep = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_NDEP), Ity_I64);
sewardj2019a972011-03-07 16:04:07 +0000683
684 args = mkIRExprVec_4(op, dep1, dep2, ndep);
685 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
686 "s390_calculate_cc", &s390_calculate_cc, args);
687
688 /* Exclude OP and NDEP from definedness checking. We're only
689 interested in DEP1 and DEP2. */
690 call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<3);
691
692 return call;
693}
694
695/* Build IR to calculate the internal condition code for a "compare and branch"
696 insn. Returns an expression of type Ity_I32 */
697static IRExpr *
florianff9613f2012-05-12 15:26:44 +0000698s390_call_calculate_icc(UInt m, UInt opc, IRTemp op1, IRTemp op2)
sewardj2019a972011-03-07 16:04:07 +0000699{
florianff9613f2012-05-12 15:26:44 +0000700 IRExpr **args, *call, *op, *dep1, *dep2, *mask;
sewardj2019a972011-03-07 16:04:07 +0000701
florianff9613f2012-05-12 15:26:44 +0000702 switch (opc) {
703 case S390_CC_OP_SIGNED_COMPARE:
704 dep1 = s390_cc_widen(op1, True);
705 dep2 = s390_cc_widen(op2, True);
706 break;
707
708 case S390_CC_OP_UNSIGNED_COMPARE:
709 dep1 = s390_cc_widen(op1, False);
710 dep2 = s390_cc_widen(op2, False);
711 break;
712
713 default:
714 vpanic("s390_call_calculate_icc");
715 }
716
717 mask = mkU64(m);
sewardj2019a972011-03-07 16:04:07 +0000718 op = mkU64(opc);
sewardj2019a972011-03-07 16:04:07 +0000719
florianff9613f2012-05-12 15:26:44 +0000720 args = mkIRExprVec_5(mask, op, dep1, dep2, mkU64(0) /* unused */);
sewardj2019a972011-03-07 16:04:07 +0000721 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
florianff9613f2012-05-12 15:26:44 +0000722 "s390_calculate_cond", &s390_calculate_cond, args);
sewardj2019a972011-03-07 16:04:07 +0000723
florianff9613f2012-05-12 15:26:44 +0000724 /* Exclude the requested condition, OP and NDEP from definedness
725 checking. We're only interested in DEP1 and DEP2. */
726 call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<1) | (1<<4);
sewardj2019a972011-03-07 16:04:07 +0000727
728 return call;
729}
730
731/* Build IR to calculate the condition code from flags thunk.
732 Returns an expression of type Ity_I32 */
733static IRExpr *
734s390_call_calculate_cond(UInt m)
735{
736 IRExpr **args, *call, *op, *dep1, *dep2, *ndep, *mask;
737
738 mask = mkU64(m);
florian428dfdd2012-03-27 03:09:49 +0000739 op = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_OP), Ity_I64);
740 dep1 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP1), Ity_I64);
741 dep2 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP2), Ity_I64);
742 ndep = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_NDEP), Ity_I64);
sewardj2019a972011-03-07 16:04:07 +0000743
744 args = mkIRExprVec_5(mask, op, dep1, dep2, ndep);
745 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
746 "s390_calculate_cond", &s390_calculate_cond, args);
747
748 /* Exclude the requested condition, OP and NDEP from definedness
749 checking. We're only interested in DEP1 and DEP2. */
750 call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<1) | (1<<4);
751
752 return call;
753}
754
755#define s390_cc_thunk_putZ(op,dep1) s390_cc_thunk_put1(op,dep1,False)
756#define s390_cc_thunk_putS(op,dep1) s390_cc_thunk_put1(op,dep1,True)
757#define s390_cc_thunk_putF(op,dep1) s390_cc_thunk_put1f(op,dep1)
758#define s390_cc_thunk_putZZ(op,dep1,dep2) s390_cc_thunk_put2(op,dep1,dep2,False)
759#define s390_cc_thunk_putSS(op,dep1,dep2) s390_cc_thunk_put2(op,dep1,dep2,True)
760#define s390_cc_thunk_putFF(op,dep1,dep2) s390_cc_thunk_put2f(op,dep1,dep2)
761#define s390_cc_thunk_putZZZ(op,dep1,dep2,ndep) \
762 s390_cc_thunk_put3(op,dep1,dep2,ndep,False)
763#define s390_cc_thunk_putSSS(op,dep1,dep2,ndep) \
764 s390_cc_thunk_put3(op,dep1,dep2,ndep,True)
sewardj2019a972011-03-07 16:04:07 +0000765
766
sewardj2019a972011-03-07 16:04:07 +0000767
768
769/*------------------------------------------------------------*/
770/*--- Guest register access ---*/
771/*------------------------------------------------------------*/
772
773
774/*------------------------------------------------------------*/
775/*--- ar registers ---*/
776/*------------------------------------------------------------*/
777
778/* Return the guest state offset of a ar register. */
779static UInt
780ar_offset(UInt archreg)
781{
782 static const UInt offset[16] = {
floriane88b3c92011-07-05 02:48:39 +0000783 S390X_GUEST_OFFSET(guest_a0),
784 S390X_GUEST_OFFSET(guest_a1),
785 S390X_GUEST_OFFSET(guest_a2),
786 S390X_GUEST_OFFSET(guest_a3),
787 S390X_GUEST_OFFSET(guest_a4),
788 S390X_GUEST_OFFSET(guest_a5),
789 S390X_GUEST_OFFSET(guest_a6),
790 S390X_GUEST_OFFSET(guest_a7),
791 S390X_GUEST_OFFSET(guest_a8),
792 S390X_GUEST_OFFSET(guest_a9),
793 S390X_GUEST_OFFSET(guest_a10),
794 S390X_GUEST_OFFSET(guest_a11),
795 S390X_GUEST_OFFSET(guest_a12),
796 S390X_GUEST_OFFSET(guest_a13),
797 S390X_GUEST_OFFSET(guest_a14),
798 S390X_GUEST_OFFSET(guest_a15),
sewardj2019a972011-03-07 16:04:07 +0000799 };
800
801 vassert(archreg < 16);
802
803 return offset[archreg];
804}
805
806
807/* Return the guest state offset of word #0 of a ar register. */
808static __inline__ UInt
809ar_w0_offset(UInt archreg)
810{
811 return ar_offset(archreg) + 0;
812}
813
814/* Write word #0 of a ar to the guest state. */
815static __inline__ void
816put_ar_w0(UInt archreg, IRExpr *expr)
817{
818 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
819
820 stmt(IRStmt_Put(ar_w0_offset(archreg), expr));
821}
822
823/* Read word #0 of a ar register. */
824static __inline__ IRExpr *
825get_ar_w0(UInt archreg)
826{
827 return IRExpr_Get(ar_w0_offset(archreg), Ity_I32);
828}
829
830
831/*------------------------------------------------------------*/
832/*--- fpr registers ---*/
833/*------------------------------------------------------------*/
834
835/* Return the guest state offset of a fpr register. */
836static UInt
837fpr_offset(UInt archreg)
838{
839 static const UInt offset[16] = {
floriane88b3c92011-07-05 02:48:39 +0000840 S390X_GUEST_OFFSET(guest_f0),
841 S390X_GUEST_OFFSET(guest_f1),
842 S390X_GUEST_OFFSET(guest_f2),
843 S390X_GUEST_OFFSET(guest_f3),
844 S390X_GUEST_OFFSET(guest_f4),
845 S390X_GUEST_OFFSET(guest_f5),
846 S390X_GUEST_OFFSET(guest_f6),
847 S390X_GUEST_OFFSET(guest_f7),
848 S390X_GUEST_OFFSET(guest_f8),
849 S390X_GUEST_OFFSET(guest_f9),
850 S390X_GUEST_OFFSET(guest_f10),
851 S390X_GUEST_OFFSET(guest_f11),
852 S390X_GUEST_OFFSET(guest_f12),
853 S390X_GUEST_OFFSET(guest_f13),
854 S390X_GUEST_OFFSET(guest_f14),
855 S390X_GUEST_OFFSET(guest_f15),
sewardj2019a972011-03-07 16:04:07 +0000856 };
857
858 vassert(archreg < 16);
859
860 return offset[archreg];
861}
862
863
864/* Return the guest state offset of word #0 of a fpr register. */
865static __inline__ UInt
866fpr_w0_offset(UInt archreg)
867{
868 return fpr_offset(archreg) + 0;
869}
870
871/* Write word #0 of a fpr to the guest state. */
872static __inline__ void
873put_fpr_w0(UInt archreg, IRExpr *expr)
874{
875 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_F32);
876
877 stmt(IRStmt_Put(fpr_w0_offset(archreg), expr));
878}
879
880/* Read word #0 of a fpr register. */
881static __inline__ IRExpr *
882get_fpr_w0(UInt archreg)
883{
884 return IRExpr_Get(fpr_w0_offset(archreg), Ity_F32);
885}
886
887/* Return the guest state offset of double word #0 of a fpr register. */
888static __inline__ UInt
889fpr_dw0_offset(UInt archreg)
890{
891 return fpr_offset(archreg) + 0;
892}
893
894/* Write double word #0 of a fpr to the guest state. */
895static __inline__ void
896put_fpr_dw0(UInt archreg, IRExpr *expr)
897{
898 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_F64);
899
900 stmt(IRStmt_Put(fpr_dw0_offset(archreg), expr));
901}
902
903/* Read double word #0 of a fpr register. */
904static __inline__ IRExpr *
905get_fpr_dw0(UInt archreg)
906{
907 return IRExpr_Get(fpr_dw0_offset(archreg), Ity_F64);
908}
909
910
911/*------------------------------------------------------------*/
912/*--- gpr registers ---*/
913/*------------------------------------------------------------*/
914
915/* Return the guest state offset of a gpr register. */
916static UInt
917gpr_offset(UInt archreg)
918{
919 static const UInt offset[16] = {
floriane88b3c92011-07-05 02:48:39 +0000920 S390X_GUEST_OFFSET(guest_r0),
921 S390X_GUEST_OFFSET(guest_r1),
922 S390X_GUEST_OFFSET(guest_r2),
923 S390X_GUEST_OFFSET(guest_r3),
924 S390X_GUEST_OFFSET(guest_r4),
925 S390X_GUEST_OFFSET(guest_r5),
926 S390X_GUEST_OFFSET(guest_r6),
927 S390X_GUEST_OFFSET(guest_r7),
928 S390X_GUEST_OFFSET(guest_r8),
929 S390X_GUEST_OFFSET(guest_r9),
930 S390X_GUEST_OFFSET(guest_r10),
931 S390X_GUEST_OFFSET(guest_r11),
932 S390X_GUEST_OFFSET(guest_r12),
933 S390X_GUEST_OFFSET(guest_r13),
934 S390X_GUEST_OFFSET(guest_r14),
935 S390X_GUEST_OFFSET(guest_r15),
sewardj2019a972011-03-07 16:04:07 +0000936 };
937
938 vassert(archreg < 16);
939
940 return offset[archreg];
941}
942
943
944/* Return the guest state offset of word #0 of a gpr register. */
945static __inline__ UInt
946gpr_w0_offset(UInt archreg)
947{
948 return gpr_offset(archreg) + 0;
949}
950
951/* Write word #0 of a gpr to the guest state. */
952static __inline__ void
953put_gpr_w0(UInt archreg, IRExpr *expr)
954{
955 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
956
957 stmt(IRStmt_Put(gpr_w0_offset(archreg), expr));
958}
959
960/* Read word #0 of a gpr register. */
961static __inline__ IRExpr *
962get_gpr_w0(UInt archreg)
963{
964 return IRExpr_Get(gpr_w0_offset(archreg), Ity_I32);
965}
966
967/* Return the guest state offset of double word #0 of a gpr register. */
968static __inline__ UInt
969gpr_dw0_offset(UInt archreg)
970{
971 return gpr_offset(archreg) + 0;
972}
973
974/* Write double word #0 of a gpr to the guest state. */
975static __inline__ void
976put_gpr_dw0(UInt archreg, IRExpr *expr)
977{
978 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I64);
979
980 stmt(IRStmt_Put(gpr_dw0_offset(archreg), expr));
981}
982
983/* Read double word #0 of a gpr register. */
984static __inline__ IRExpr *
985get_gpr_dw0(UInt archreg)
986{
987 return IRExpr_Get(gpr_dw0_offset(archreg), Ity_I64);
988}
989
990/* Return the guest state offset of half word #1 of a gpr register. */
991static __inline__ UInt
992gpr_hw1_offset(UInt archreg)
993{
994 return gpr_offset(archreg) + 2;
995}
996
997/* Write half word #1 of a gpr to the guest state. */
998static __inline__ void
999put_gpr_hw1(UInt archreg, IRExpr *expr)
1000{
1001 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1002
1003 stmt(IRStmt_Put(gpr_hw1_offset(archreg), expr));
1004}
1005
1006/* Read half word #1 of a gpr register. */
1007static __inline__ IRExpr *
1008get_gpr_hw1(UInt archreg)
1009{
1010 return IRExpr_Get(gpr_hw1_offset(archreg), Ity_I16);
1011}
1012
1013/* Return the guest state offset of byte #6 of a gpr register. */
1014static __inline__ UInt
1015gpr_b6_offset(UInt archreg)
1016{
1017 return gpr_offset(archreg) + 6;
1018}
1019
1020/* Write byte #6 of a gpr to the guest state. */
1021static __inline__ void
1022put_gpr_b6(UInt archreg, IRExpr *expr)
1023{
1024 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1025
1026 stmt(IRStmt_Put(gpr_b6_offset(archreg), expr));
1027}
1028
1029/* Read byte #6 of a gpr register. */
1030static __inline__ IRExpr *
1031get_gpr_b6(UInt archreg)
1032{
1033 return IRExpr_Get(gpr_b6_offset(archreg), Ity_I8);
1034}
1035
1036/* Return the guest state offset of byte #3 of a gpr register. */
1037static __inline__ UInt
1038gpr_b3_offset(UInt archreg)
1039{
1040 return gpr_offset(archreg) + 3;
1041}
1042
1043/* Write byte #3 of a gpr to the guest state. */
1044static __inline__ void
1045put_gpr_b3(UInt archreg, IRExpr *expr)
1046{
1047 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1048
1049 stmt(IRStmt_Put(gpr_b3_offset(archreg), expr));
1050}
1051
1052/* Read byte #3 of a gpr register. */
1053static __inline__ IRExpr *
1054get_gpr_b3(UInt archreg)
1055{
1056 return IRExpr_Get(gpr_b3_offset(archreg), Ity_I8);
1057}
1058
1059/* Return the guest state offset of byte #0 of a gpr register. */
1060static __inline__ UInt
1061gpr_b0_offset(UInt archreg)
1062{
1063 return gpr_offset(archreg) + 0;
1064}
1065
1066/* Write byte #0 of a gpr to the guest state. */
1067static __inline__ void
1068put_gpr_b0(UInt archreg, IRExpr *expr)
1069{
1070 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1071
1072 stmt(IRStmt_Put(gpr_b0_offset(archreg), expr));
1073}
1074
1075/* Read byte #0 of a gpr register. */
1076static __inline__ IRExpr *
1077get_gpr_b0(UInt archreg)
1078{
1079 return IRExpr_Get(gpr_b0_offset(archreg), Ity_I8);
1080}
1081
1082/* Return the guest state offset of word #1 of a gpr register. */
1083static __inline__ UInt
1084gpr_w1_offset(UInt archreg)
1085{
1086 return gpr_offset(archreg) + 4;
1087}
1088
1089/* Write word #1 of a gpr to the guest state. */
1090static __inline__ void
1091put_gpr_w1(UInt archreg, IRExpr *expr)
1092{
1093 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1094
1095 stmt(IRStmt_Put(gpr_w1_offset(archreg), expr));
1096}
1097
1098/* Read word #1 of a gpr register. */
1099static __inline__ IRExpr *
1100get_gpr_w1(UInt archreg)
1101{
1102 return IRExpr_Get(gpr_w1_offset(archreg), Ity_I32);
1103}
1104
1105/* Return the guest state offset of half word #3 of a gpr register. */
1106static __inline__ UInt
1107gpr_hw3_offset(UInt archreg)
1108{
1109 return gpr_offset(archreg) + 6;
1110}
1111
1112/* Write half word #3 of a gpr to the guest state. */
1113static __inline__ void
1114put_gpr_hw3(UInt archreg, IRExpr *expr)
1115{
1116 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1117
1118 stmt(IRStmt_Put(gpr_hw3_offset(archreg), expr));
1119}
1120
1121/* Read half word #3 of a gpr register. */
1122static __inline__ IRExpr *
1123get_gpr_hw3(UInt archreg)
1124{
1125 return IRExpr_Get(gpr_hw3_offset(archreg), Ity_I16);
1126}
1127
1128/* Return the guest state offset of byte #7 of a gpr register. */
1129static __inline__ UInt
1130gpr_b7_offset(UInt archreg)
1131{
1132 return gpr_offset(archreg) + 7;
1133}
1134
1135/* Write byte #7 of a gpr to the guest state. */
1136static __inline__ void
1137put_gpr_b7(UInt archreg, IRExpr *expr)
1138{
1139 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1140
1141 stmt(IRStmt_Put(gpr_b7_offset(archreg), expr));
1142}
1143
1144/* Read byte #7 of a gpr register. */
1145static __inline__ IRExpr *
1146get_gpr_b7(UInt archreg)
1147{
1148 return IRExpr_Get(gpr_b7_offset(archreg), Ity_I8);
1149}
1150
1151/* Return the guest state offset of half word #0 of a gpr register. */
1152static __inline__ UInt
1153gpr_hw0_offset(UInt archreg)
1154{
1155 return gpr_offset(archreg) + 0;
1156}
1157
1158/* Write half word #0 of a gpr to the guest state. */
1159static __inline__ void
1160put_gpr_hw0(UInt archreg, IRExpr *expr)
1161{
1162 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1163
1164 stmt(IRStmt_Put(gpr_hw0_offset(archreg), expr));
1165}
1166
1167/* Read half word #0 of a gpr register. */
1168static __inline__ IRExpr *
1169get_gpr_hw0(UInt archreg)
1170{
1171 return IRExpr_Get(gpr_hw0_offset(archreg), Ity_I16);
1172}
1173
1174/* Return the guest state offset of byte #4 of a gpr register. */
1175static __inline__ UInt
1176gpr_b4_offset(UInt archreg)
1177{
1178 return gpr_offset(archreg) + 4;
1179}
1180
1181/* Write byte #4 of a gpr to the guest state. */
1182static __inline__ void
1183put_gpr_b4(UInt archreg, IRExpr *expr)
1184{
1185 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1186
1187 stmt(IRStmt_Put(gpr_b4_offset(archreg), expr));
1188}
1189
1190/* Read byte #4 of a gpr register. */
1191static __inline__ IRExpr *
1192get_gpr_b4(UInt archreg)
1193{
1194 return IRExpr_Get(gpr_b4_offset(archreg), Ity_I8);
1195}
1196
1197/* Return the guest state offset of byte #1 of a gpr register. */
1198static __inline__ UInt
1199gpr_b1_offset(UInt archreg)
1200{
1201 return gpr_offset(archreg) + 1;
1202}
1203
1204/* Write byte #1 of a gpr to the guest state. */
1205static __inline__ void
1206put_gpr_b1(UInt archreg, IRExpr *expr)
1207{
1208 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1209
1210 stmt(IRStmt_Put(gpr_b1_offset(archreg), expr));
1211}
1212
1213/* Read byte #1 of a gpr register. */
1214static __inline__ IRExpr *
1215get_gpr_b1(UInt archreg)
1216{
1217 return IRExpr_Get(gpr_b1_offset(archreg), Ity_I8);
1218}
1219
1220/* Return the guest state offset of half word #2 of a gpr register. */
1221static __inline__ UInt
1222gpr_hw2_offset(UInt archreg)
1223{
1224 return gpr_offset(archreg) + 4;
1225}
1226
1227/* Write half word #2 of a gpr to the guest state. */
1228static __inline__ void
1229put_gpr_hw2(UInt archreg, IRExpr *expr)
1230{
1231 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1232
1233 stmt(IRStmt_Put(gpr_hw2_offset(archreg), expr));
1234}
1235
1236/* Read half word #2 of a gpr register. */
1237static __inline__ IRExpr *
1238get_gpr_hw2(UInt archreg)
1239{
1240 return IRExpr_Get(gpr_hw2_offset(archreg), Ity_I16);
1241}
1242
1243/* Return the guest state offset of byte #5 of a gpr register. */
1244static __inline__ UInt
1245gpr_b5_offset(UInt archreg)
1246{
1247 return gpr_offset(archreg) + 5;
1248}
1249
1250/* Write byte #5 of a gpr to the guest state. */
1251static __inline__ void
1252put_gpr_b5(UInt archreg, IRExpr *expr)
1253{
1254 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1255
1256 stmt(IRStmt_Put(gpr_b5_offset(archreg), expr));
1257}
1258
1259/* Read byte #5 of a gpr register. */
1260static __inline__ IRExpr *
1261get_gpr_b5(UInt archreg)
1262{
1263 return IRExpr_Get(gpr_b5_offset(archreg), Ity_I8);
1264}
1265
1266/* Return the guest state offset of byte #2 of a gpr register. */
1267static __inline__ UInt
1268gpr_b2_offset(UInt archreg)
1269{
1270 return gpr_offset(archreg) + 2;
1271}
1272
1273/* Write byte #2 of a gpr to the guest state. */
1274static __inline__ void
1275put_gpr_b2(UInt archreg, IRExpr *expr)
1276{
1277 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1278
1279 stmt(IRStmt_Put(gpr_b2_offset(archreg), expr));
1280}
1281
1282/* Read byte #2 of a gpr register. */
1283static __inline__ IRExpr *
1284get_gpr_b2(UInt archreg)
1285{
1286 return IRExpr_Get(gpr_b2_offset(archreg), Ity_I8);
1287}
1288
1289/* Return the guest state offset of the counter register. */
1290static UInt
1291counter_offset(void)
1292{
floriane88b3c92011-07-05 02:48:39 +00001293 return S390X_GUEST_OFFSET(guest_counter);
sewardj2019a972011-03-07 16:04:07 +00001294}
1295
1296/* Return the guest state offset of double word #0 of the counter register. */
1297static __inline__ UInt
1298counter_dw0_offset(void)
1299{
1300 return counter_offset() + 0;
1301}
1302
1303/* Write double word #0 of the counter to the guest state. */
1304static __inline__ void
1305put_counter_dw0(IRExpr *expr)
1306{
1307 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I64);
1308
1309 stmt(IRStmt_Put(counter_dw0_offset(), expr));
1310}
1311
1312/* Read double word #0 of the counter register. */
1313static __inline__ IRExpr *
1314get_counter_dw0(void)
1315{
1316 return IRExpr_Get(counter_dw0_offset(), Ity_I64);
1317}
1318
1319/* Return the guest state offset of word #0 of the counter register. */
1320static __inline__ UInt
1321counter_w0_offset(void)
1322{
1323 return counter_offset() + 0;
1324}
1325
1326/* Return the guest state offset of word #1 of the counter register. */
1327static __inline__ UInt
1328counter_w1_offset(void)
1329{
1330 return counter_offset() + 4;
1331}
1332
1333/* Write word #0 of the counter to the guest state. */
1334static __inline__ void
1335put_counter_w0(IRExpr *expr)
1336{
1337 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1338
1339 stmt(IRStmt_Put(counter_w0_offset(), expr));
1340}
1341
1342/* Read word #0 of the counter register. */
1343static __inline__ IRExpr *
1344get_counter_w0(void)
1345{
1346 return IRExpr_Get(counter_w0_offset(), Ity_I32);
1347}
1348
1349/* Write word #1 of the counter to the guest state. */
1350static __inline__ void
1351put_counter_w1(IRExpr *expr)
1352{
1353 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1354
1355 stmt(IRStmt_Put(counter_w1_offset(), expr));
1356}
1357
1358/* Read word #1 of the counter register. */
1359static __inline__ IRExpr *
1360get_counter_w1(void)
1361{
1362 return IRExpr_Get(counter_w1_offset(), Ity_I32);
1363}
1364
1365/* Return the guest state offset of the fpc register. */
1366static UInt
1367fpc_offset(void)
1368{
floriane88b3c92011-07-05 02:48:39 +00001369 return S390X_GUEST_OFFSET(guest_fpc);
sewardj2019a972011-03-07 16:04:07 +00001370}
1371
1372/* Return the guest state offset of word #0 of the fpc register. */
1373static __inline__ UInt
1374fpc_w0_offset(void)
1375{
1376 return fpc_offset() + 0;
1377}
1378
1379/* Write word #0 of the fpc to the guest state. */
1380static __inline__ void
1381put_fpc_w0(IRExpr *expr)
1382{
1383 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1384
1385 stmt(IRStmt_Put(fpc_w0_offset(), expr));
1386}
1387
1388/* Read word #0 of the fpc register. */
1389static __inline__ IRExpr *
1390get_fpc_w0(void)
1391{
1392 return IRExpr_Get(fpc_w0_offset(), Ity_I32);
1393}
1394
1395
1396/*------------------------------------------------------------*/
florian2c74d242012-09-12 19:38:42 +00001397/*--- Rounding modes ---*/
1398/*------------------------------------------------------------*/
1399
florian125e20d2012-10-07 15:42:37 +00001400/* Extract the bfp rounding mode from the guest FPC reg and encode it as an
florian2c74d242012-09-12 19:38:42 +00001401 IRRoundingMode:
1402
1403 rounding mode | s390 | IR
1404 -------------------------
1405 to nearest | 00 | 00
1406 to zero | 01 | 11
1407 to +infinity | 10 | 10
1408 to -infinity | 11 | 01
1409
1410 So: IR = (4 - s390) & 3
1411*/
1412static IRExpr *
florian125e20d2012-10-07 15:42:37 +00001413get_bfp_rounding_mode_from_fpc(void)
florian2c74d242012-09-12 19:38:42 +00001414{
1415 IRTemp fpc_bits = newTemp(Ity_I32);
1416
1417 /* For z196 and later the bfp rounding mode is stored in bits [29:31].
1418 Prior to that bits [30:31] contained the bfp rounding mode with
1419 bit 29 being unused and having a value of 0. So we can always
1420 extract the least significant 3 bits. */
1421 assign(fpc_bits, binop(Iop_And32, get_fpc_w0(), mkU32(7)));
1422
1423 /* fixs390:
1424
1425
1426 if (! s390_host_has_fpext && rounding_mode > 3) {
1427 emulation warning @ runtime and
1428 set fpc to round nearest
1429 }
1430 */
1431
1432 /* For now silently adjust an unsupported rounding mode to "nearest" */
1433 IRExpr *rm_s390 = mkite(binop(Iop_CmpLE32S, mkexpr(fpc_bits), mkU32(3)),
1434 mkexpr(fpc_bits),
florian125e20d2012-10-07 15:42:37 +00001435 mkU32(S390_FPC_BFP_ROUND_NEAREST_EVEN));
florian2c74d242012-09-12 19:38:42 +00001436
1437 // rm_IR = (4 - rm_s390) & 3;
1438 return binop(Iop_And32, binop(Iop_Sub32, mkU32(4), rm_s390), mkU32(3));
1439}
1440
1441/* Encode the s390 rounding mode as it appears in the m3 field of certain
1442 instructions to VEX's IRRoundingMode. Rounding modes that cannot be
1443 represented in VEX are converted to Irrm_NEAREST. The rationale is, that
1444 Irrm_NEAREST refers to IEEE 754's roundTiesToEven which the standard
1445 considers the default rounding mode (4.3.3). */
1446static IRTemp
1447encode_bfp_rounding_mode(UChar mode)
1448{
1449 IRExpr *rm;
1450
1451 switch (mode) {
florian125e20d2012-10-07 15:42:37 +00001452 case S390_BFP_ROUND_PER_FPC:
1453 rm = get_bfp_rounding_mode_from_fpc();
1454 break;
1455 case S390_BFP_ROUND_NEAREST_AWAY: /* not supported */
1456 case S390_BFP_ROUND_PREPARE_SHORT: /* not supported */
1457 case S390_BFP_ROUND_NEAREST_EVEN: rm = mkU32(Irrm_NEAREST); break;
1458 case S390_BFP_ROUND_ZERO: rm = mkU32(Irrm_ZERO); break;
1459 case S390_BFP_ROUND_POSINF: rm = mkU32(Irrm_PosINF); break;
1460 case S390_BFP_ROUND_NEGINF: rm = mkU32(Irrm_NegINF); break;
florian2c74d242012-09-12 19:38:42 +00001461 default:
1462 vpanic("encode_bfp_rounding_mode");
1463 }
1464
1465 return mktemp(Ity_I32, rm);
1466}
1467
1468/*------------------------------------------------------------*/
sewardj2019a972011-03-07 16:04:07 +00001469/*--- Build IR for formats ---*/
1470/*------------------------------------------------------------*/
1471static void
1472s390_format_I(HChar *(*irgen)(UChar i),
1473 UChar i)
1474{
1475 HChar *mnm = irgen(i);
1476
sewardj7ee97522011-05-09 21:45:04 +00001477 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001478 s390_disasm(ENC2(MNM, UINT), mnm, i);
1479}
1480
1481static void
1482s390_format_RI(HChar *(*irgen)(UChar r1, UShort i2),
1483 UChar r1, UShort i2)
1484{
1485 irgen(r1, i2);
1486}
1487
1488static void
1489s390_format_RI_RU(HChar *(*irgen)(UChar r1, UShort i2),
1490 UChar r1, UShort i2)
1491{
1492 HChar *mnm = irgen(r1, i2);
1493
sewardj7ee97522011-05-09 21:45:04 +00001494 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001495 s390_disasm(ENC3(MNM, GPR, UINT), mnm, r1, i2);
1496}
1497
1498static void
1499s390_format_RI_RI(HChar *(*irgen)(UChar r1, UShort i2),
1500 UChar r1, UShort i2)
1501{
1502 HChar *mnm = irgen(r1, i2);
1503
sewardj7ee97522011-05-09 21:45:04 +00001504 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001505 s390_disasm(ENC3(MNM, GPR, INT), mnm, r1, (Int)(Short)i2);
1506}
1507
1508static void
1509s390_format_RI_RP(HChar *(*irgen)(UChar r1, UShort i2),
1510 UChar r1, UShort i2)
1511{
1512 HChar *mnm = irgen(r1, i2);
1513
sewardj7ee97522011-05-09 21:45:04 +00001514 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001515 s390_disasm(ENC3(MNM, GPR, PCREL), mnm, r1, (Int)(Short)i2);
1516}
1517
1518static void
1519s390_format_RIE_RRP(HChar *(*irgen)(UChar r1, UChar r3, UShort i2),
1520 UChar r1, UChar r3, UShort i2)
1521{
1522 HChar *mnm = irgen(r1, r3, i2);
1523
sewardj7ee97522011-05-09 21:45:04 +00001524 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001525 s390_disasm(ENC4(MNM, GPR, GPR, PCREL), mnm, r1, r3, (Int)(Short)i2);
1526}
1527
1528static void
1529s390_format_RIE_RRI0(HChar *(*irgen)(UChar r1, UChar r3, UShort i2),
1530 UChar r1, UChar r3, UShort i2)
1531{
1532 HChar *mnm = irgen(r1, r3, i2);
1533
sewardj7ee97522011-05-09 21:45:04 +00001534 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001535 s390_disasm(ENC4(MNM, GPR, GPR, INT), mnm, r1, r3, (Int)(Short)i2);
1536}
1537
1538static void
1539s390_format_RIE_RRUUU(HChar *(*irgen)(UChar r1, UChar r2, UChar i3, UChar i4,
1540 UChar i5),
1541 UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
1542{
1543 HChar *mnm = irgen(r1, r2, i3, i4, i5);
1544
sewardj7ee97522011-05-09 21:45:04 +00001545 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001546 s390_disasm(ENC6(MNM, GPR, GPR, UINT, UINT, UINT), mnm, r1, r2, i3, i4,
1547 i5);
1548}
1549
1550static void
1551s390_format_RIE_RRPU(HChar *(*irgen)(UChar r1, UChar r2, UShort i4, UChar m3),
1552 UChar r1, UChar r2, UShort i4, UChar m3)
1553{
1554 HChar *mnm = irgen(r1, r2, i4, m3);
1555
sewardj7ee97522011-05-09 21:45:04 +00001556 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001557 s390_disasm(ENC5(XMNM, GPR, GPR, CABM, PCREL), S390_XMNM_CAB, mnm, m3, r1,
1558 r2, m3, (Int)(Short)i4);
1559}
1560
1561static void
1562s390_format_RIE_RUPU(HChar *(*irgen)(UChar r1, UChar m3, UShort i4, UChar i2),
1563 UChar r1, UChar m3, UShort i4, UChar i2)
1564{
1565 HChar *mnm = irgen(r1, m3, i4, i2);
1566
sewardj7ee97522011-05-09 21:45:04 +00001567 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001568 s390_disasm(ENC5(XMNM, GPR, UINT, CABM, PCREL), S390_XMNM_CAB, mnm, m3,
1569 r1, i2, m3, (Int)(Short)i4);
1570}
1571
1572static void
1573s390_format_RIE_RUPI(HChar *(*irgen)(UChar r1, UChar m3, UShort i4, UChar i2),
1574 UChar r1, UChar m3, UShort i4, UChar i2)
1575{
1576 HChar *mnm = irgen(r1, m3, i4, i2);
1577
sewardj7ee97522011-05-09 21:45:04 +00001578 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001579 s390_disasm(ENC5(XMNM, GPR, INT, CABM, PCREL), S390_XMNM_CAB, mnm, m3, r1,
1580 (Int)(Char)i2, m3, (Int)(Short)i4);
1581}
1582
1583static void
1584s390_format_RIL(HChar *(*irgen)(UChar r1, UInt i2),
1585 UChar r1, UInt i2)
1586{
1587 irgen(r1, i2);
1588}
1589
1590static void
1591s390_format_RIL_RU(HChar *(*irgen)(UChar r1, UInt i2),
1592 UChar r1, UInt i2)
1593{
1594 HChar *mnm = irgen(r1, i2);
1595
sewardj7ee97522011-05-09 21:45:04 +00001596 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001597 s390_disasm(ENC3(MNM, GPR, UINT), mnm, r1, i2);
1598}
1599
1600static void
1601s390_format_RIL_RI(HChar *(*irgen)(UChar r1, UInt i2),
1602 UChar r1, UInt i2)
1603{
1604 HChar *mnm = irgen(r1, i2);
1605
sewardj7ee97522011-05-09 21:45:04 +00001606 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001607 s390_disasm(ENC3(MNM, GPR, INT), mnm, r1, i2);
1608}
1609
1610static void
1611s390_format_RIL_RP(HChar *(*irgen)(UChar r1, UInt i2),
1612 UChar r1, UInt i2)
1613{
1614 HChar *mnm = irgen(r1, i2);
1615
sewardj7ee97522011-05-09 21:45:04 +00001616 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001617 s390_disasm(ENC3(MNM, GPR, PCREL), mnm, r1, i2);
1618}
1619
1620static void
1621s390_format_RIL_UP(HChar *(*irgen)(void),
1622 UChar r1, UInt i2)
1623{
1624 HChar *mnm = irgen();
1625
sewardj7ee97522011-05-09 21:45:04 +00001626 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001627 s390_disasm(ENC3(MNM, UINT, PCREL), mnm, r1, i2);
1628}
1629
1630static void
1631s390_format_RIS_RURDI(HChar *(*irgen)(UChar r1, UChar m3, UChar i2,
1632 IRTemp op4addr),
1633 UChar r1, UChar m3, UChar b4, UShort d4, UChar i2)
1634{
1635 HChar *mnm;
1636 IRTemp op4addr = newTemp(Ity_I64);
1637
1638 assign(op4addr, binop(Iop_Add64, mkU64(d4), b4 != 0 ? get_gpr_dw0(b4) :
1639 mkU64(0)));
1640
1641 mnm = irgen(r1, m3, i2, op4addr);
1642
sewardj7ee97522011-05-09 21:45:04 +00001643 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001644 s390_disasm(ENC5(XMNM, GPR, INT, CABM, UDXB), S390_XMNM_CAB, mnm, m3, r1,
1645 (Int)(Char)i2, m3, d4, 0, b4);
1646}
1647
1648static void
1649s390_format_RIS_RURDU(HChar *(*irgen)(UChar r1, UChar m3, UChar i2,
1650 IRTemp op4addr),
1651 UChar r1, UChar m3, UChar b4, UShort d4, UChar i2)
1652{
1653 HChar *mnm;
1654 IRTemp op4addr = newTemp(Ity_I64);
1655
1656 assign(op4addr, binop(Iop_Add64, mkU64(d4), b4 != 0 ? get_gpr_dw0(b4) :
1657 mkU64(0)));
1658
1659 mnm = irgen(r1, m3, i2, op4addr);
1660
sewardj7ee97522011-05-09 21:45:04 +00001661 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001662 s390_disasm(ENC5(XMNM, GPR, UINT, CABM, UDXB), S390_XMNM_CAB, mnm, m3, r1,
1663 i2, m3, d4, 0, b4);
1664}
1665
1666static void
1667s390_format_RR(HChar *(*irgen)(UChar r1, UChar r2),
1668 UChar r1, UChar r2)
1669{
1670 irgen(r1, r2);
1671}
1672
1673static void
1674s390_format_RR_RR(HChar *(*irgen)(UChar r1, UChar r2),
1675 UChar r1, UChar r2)
1676{
1677 HChar *mnm = irgen(r1, r2);
1678
sewardj7ee97522011-05-09 21:45:04 +00001679 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001680 s390_disasm(ENC3(MNM, GPR, GPR), mnm, r1, r2);
1681}
1682
1683static void
1684s390_format_RR_FF(HChar *(*irgen)(UChar r1, UChar r2),
1685 UChar r1, UChar r2)
1686{
1687 HChar *mnm = irgen(r1, r2);
1688
sewardj7ee97522011-05-09 21:45:04 +00001689 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001690 s390_disasm(ENC3(MNM, FPR, FPR), mnm, r1, r2);
1691}
1692
1693static void
1694s390_format_RRE(HChar *(*irgen)(UChar r1, UChar r2),
1695 UChar r1, UChar r2)
1696{
1697 irgen(r1, r2);
1698}
1699
1700static void
1701s390_format_RRE_RR(HChar *(*irgen)(UChar r1, UChar r2),
1702 UChar r1, UChar r2)
1703{
1704 HChar *mnm = irgen(r1, r2);
1705
sewardj7ee97522011-05-09 21:45:04 +00001706 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001707 s390_disasm(ENC3(MNM, GPR, GPR), mnm, r1, r2);
1708}
1709
1710static void
1711s390_format_RRE_FF(HChar *(*irgen)(UChar r1, UChar r2),
1712 UChar r1, UChar r2)
1713{
1714 HChar *mnm = irgen(r1, r2);
1715
sewardj7ee97522011-05-09 21:45:04 +00001716 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001717 s390_disasm(ENC3(MNM, FPR, FPR), mnm, r1, r2);
1718}
1719
1720static void
1721s390_format_RRE_RF(HChar *(*irgen)(UChar, UChar),
1722 UChar r1, UChar r2)
1723{
1724 HChar *mnm = irgen(r1, r2);
1725
sewardj7ee97522011-05-09 21:45:04 +00001726 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001727 s390_disasm(ENC3(MNM, GPR, FPR), mnm, r1, r2);
1728}
1729
1730static void
1731s390_format_RRE_FR(HChar *(*irgen)(UChar r1, UChar r2),
1732 UChar r1, UChar r2)
1733{
1734 HChar *mnm = irgen(r1, r2);
1735
sewardj7ee97522011-05-09 21:45:04 +00001736 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001737 s390_disasm(ENC3(MNM, FPR, GPR), mnm, r1, r2);
1738}
1739
1740static void
1741s390_format_RRE_R0(HChar *(*irgen)(UChar r1),
1742 UChar r1)
1743{
1744 HChar *mnm = irgen(r1);
1745
sewardj7ee97522011-05-09 21:45:04 +00001746 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001747 s390_disasm(ENC2(MNM, GPR), mnm, r1);
1748}
1749
1750static void
1751s390_format_RRE_F0(HChar *(*irgen)(UChar r1),
1752 UChar r1)
1753{
1754 HChar *mnm = irgen(r1);
1755
sewardj7ee97522011-05-09 21:45:04 +00001756 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001757 s390_disasm(ENC2(MNM, FPR), mnm, r1);
1758}
1759
1760static void
florian9af37692012-01-15 21:01:16 +00001761s390_format_RRF_M0RERE(HChar *(*irgen)(UChar m3, UChar r1, UChar r2),
1762 UChar m3, UChar r1, UChar r2)
1763{
florianfed3ea32012-07-19 14:54:03 +00001764 HChar *mnm = irgen(m3, r1, r2);
florian9af37692012-01-15 21:01:16 +00001765
1766 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
florianfed3ea32012-07-19 14:54:03 +00001767 s390_disasm(ENC4(MNM, GPR, GPR, UINT), mnm, r1, r2, m3);
florian9af37692012-01-15 21:01:16 +00001768}
1769
1770static void
sewardj2019a972011-03-07 16:04:07 +00001771s390_format_RRF_F0FF(HChar *(*irgen)(UChar, UChar, UChar),
1772 UChar r1, UChar r3, UChar r2)
1773{
1774 HChar *mnm = irgen(r1, r3, r2);
1775
sewardj7ee97522011-05-09 21:45:04 +00001776 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001777 s390_disasm(ENC4(MNM, FPR, FPR, FPR), mnm, r1, r3, r2);
1778}
1779
1780static void
florian4b8efad2012-09-02 18:07:08 +00001781s390_format_RRF_UUFF(HChar *(*irgen)(UChar m3, UChar m4, UChar r1, UChar r2),
1782 UChar m3, UChar m4, UChar r1, UChar r2)
1783{
1784 HChar *mnm = irgen(m3, m4, r1, r2);
1785
1786 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
1787 s390_disasm(ENC5(MNM, FPR, UINT, FPR, UINT), mnm, r1, m3, r2, m4);
1788}
1789
1790static void
florian1c8f7ff2012-09-01 00:12:11 +00001791s390_format_RRF_UUFR(HChar *(*irgen)(UChar m3, UChar m4, UChar r1, UChar r2),
1792 UChar m3, UChar m4, UChar r1, UChar r2)
1793{
1794 HChar *mnm = irgen(m3, m4, r1, r2);
1795
1796 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
1797 s390_disasm(ENC5(MNM, FPR, UINT, GPR, UINT), mnm, r1, m3, r2, m4);
1798}
1799
1800static void
1801s390_format_RRF_UURF(HChar *(*irgen)(UChar m3, UChar m4, UChar r1, UChar r2),
1802 UChar m3, UChar m4, UChar r1, UChar r2)
1803{
1804 HChar *mnm = irgen(m3, m4, r1, r2);
1805
1806 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
1807 s390_disasm(ENC5(MNM, GPR, UINT, FPR, UINT), mnm, r1, m3, r2, m4);
1808}
1809
1810
1811static void
sewardjd7bde722011-04-05 13:19:33 +00001812s390_format_RRF_U0RR(HChar *(*irgen)(UChar m3, UChar r1, UChar r2),
1813 UChar m3, UChar r1, UChar r2, Int xmnm_kind)
1814{
1815 irgen(m3, r1, r2);
1816
sewardj7ee97522011-05-09 21:45:04 +00001817 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardjd7bde722011-04-05 13:19:33 +00001818 s390_disasm(ENC3(XMNM, GPR, GPR), xmnm_kind, m3, r1, r2);
1819}
1820
1821static void
sewardj2019a972011-03-07 16:04:07 +00001822s390_format_RRF_F0FF2(HChar *(*irgen)(UChar, UChar, UChar),
1823 UChar r3, UChar r1, UChar r2)
1824{
1825 HChar *mnm = irgen(r3, r1, r2);
1826
sewardj7ee97522011-05-09 21:45:04 +00001827 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001828 s390_disasm(ENC4(MNM, FPR, FPR, FPR), mnm, r1, r3, r2);
1829}
1830
1831static void
1832s390_format_RRF_R0RR2(HChar *(*irgen)(UChar r3, UChar r1, UChar r2),
1833 UChar r3, UChar r1, UChar r2)
1834{
1835 HChar *mnm = irgen(r3, r1, r2);
1836
sewardj7ee97522011-05-09 21:45:04 +00001837 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001838 s390_disasm(ENC4(MNM, GPR, GPR, GPR), mnm, r1, r2, r3);
1839}
1840
1841static void
1842s390_format_RRS(HChar *(*irgen)(UChar r1, UChar r2, UChar m3, IRTemp op4addr),
1843 UChar r1, UChar r2, UChar b4, UShort d4, UChar m3)
1844{
1845 HChar *mnm;
1846 IRTemp op4addr = newTemp(Ity_I64);
1847
1848 assign(op4addr, binop(Iop_Add64, mkU64(d4), b4 != 0 ? get_gpr_dw0(b4) :
1849 mkU64(0)));
1850
1851 mnm = irgen(r1, r2, m3, op4addr);
1852
sewardj7ee97522011-05-09 21:45:04 +00001853 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001854 s390_disasm(ENC5(XMNM, GPR, GPR, CABM, UDXB), S390_XMNM_CAB, mnm, m3, r1,
1855 r2, m3, d4, 0, b4);
1856}
1857
1858static void
1859s390_format_RS_R0RD(HChar *(*irgen)(UChar r1, IRTemp op2addr),
1860 UChar r1, UChar b2, UShort d2)
1861{
1862 HChar *mnm;
1863 IRTemp op2addr = newTemp(Ity_I64);
1864
1865 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
1866 mkU64(0)));
1867
1868 mnm = irgen(r1, op2addr);
1869
sewardj7ee97522011-05-09 21:45:04 +00001870 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001871 s390_disasm(ENC3(MNM, GPR, UDXB), mnm, r1, d2, 0, b2);
1872}
1873
1874static void
1875s390_format_RS_RRRD(HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
1876 UChar r1, UChar r3, UChar b2, UShort d2)
1877{
1878 HChar *mnm;
1879 IRTemp op2addr = newTemp(Ity_I64);
1880
1881 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
1882 mkU64(0)));
1883
1884 mnm = irgen(r1, r3, op2addr);
1885
sewardj7ee97522011-05-09 21:45:04 +00001886 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001887 s390_disasm(ENC4(MNM, GPR, GPR, UDXB), mnm, r1, r3, d2, 0, b2);
1888}
1889
1890static void
1891s390_format_RS_RURD(HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
1892 UChar r1, UChar r3, UChar b2, UShort d2)
1893{
1894 HChar *mnm;
1895 IRTemp op2addr = newTemp(Ity_I64);
1896
1897 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
1898 mkU64(0)));
1899
1900 mnm = irgen(r1, r3, op2addr);
1901
sewardj7ee97522011-05-09 21:45:04 +00001902 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001903 s390_disasm(ENC4(MNM, GPR, UINT, UDXB), mnm, r1, r3, d2, 0, b2);
1904}
1905
1906static void
1907s390_format_RS_AARD(HChar *(*irgen)(UChar, UChar, IRTemp),
1908 UChar r1, UChar r3, UChar b2, UShort d2)
1909{
1910 HChar *mnm;
1911 IRTemp op2addr = newTemp(Ity_I64);
1912
1913 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
1914 mkU64(0)));
1915
1916 mnm = irgen(r1, r3, op2addr);
1917
sewardj7ee97522011-05-09 21:45:04 +00001918 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001919 s390_disasm(ENC4(MNM, AR, AR, UDXB), mnm, r1, r3, d2, 0, b2);
1920}
1921
1922static void
1923s390_format_RSI_RRP(HChar *(*irgen)(UChar r1, UChar r3, UShort i2),
1924 UChar r1, UChar r3, UShort i2)
1925{
1926 HChar *mnm = irgen(r1, r3, i2);
1927
sewardj7ee97522011-05-09 21:45:04 +00001928 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001929 s390_disasm(ENC4(MNM, GPR, GPR, PCREL), mnm, r1, r3, (Int)(Short)i2);
1930}
1931
1932static void
1933s390_format_RSY_RRRD(HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
1934 UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2)
1935{
1936 HChar *mnm;
1937 IRTemp op2addr = newTemp(Ity_I64);
1938 IRTemp d2 = newTemp(Ity_I64);
1939
1940 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
1941 assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
1942 mkU64(0)));
1943
1944 mnm = irgen(r1, r3, op2addr);
1945
sewardj7ee97522011-05-09 21:45:04 +00001946 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001947 s390_disasm(ENC4(MNM, GPR, GPR, SDXB), mnm, r1, r3, dh2, dl2, 0, b2);
1948}
1949
1950static void
1951s390_format_RSY_AARD(HChar *(*irgen)(UChar, UChar, IRTemp),
1952 UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2)
1953{
1954 HChar *mnm;
1955 IRTemp op2addr = newTemp(Ity_I64);
1956 IRTemp d2 = newTemp(Ity_I64);
1957
1958 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
1959 assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
1960 mkU64(0)));
1961
1962 mnm = irgen(r1, r3, op2addr);
1963
sewardj7ee97522011-05-09 21:45:04 +00001964 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001965 s390_disasm(ENC4(MNM, AR, AR, SDXB), mnm, r1, r3, dh2, dl2, 0, b2);
1966}
1967
1968static void
1969s390_format_RSY_RURD(HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
1970 UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2)
1971{
1972 HChar *mnm;
1973 IRTemp op2addr = newTemp(Ity_I64);
1974 IRTemp d2 = newTemp(Ity_I64);
1975
1976 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
1977 assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
1978 mkU64(0)));
1979
1980 mnm = irgen(r1, r3, op2addr);
1981
sewardj7ee97522011-05-09 21:45:04 +00001982 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001983 s390_disasm(ENC4(MNM, GPR, UINT, SDXB), mnm, r1, r3, dh2, dl2, 0, b2);
1984}
1985
1986static void
sewardjd7bde722011-04-05 13:19:33 +00001987s390_format_RSY_RDRM(HChar *(*irgen)(UChar r1, IRTemp op2addr),
1988 UChar r1, UChar m3, UChar b2, UShort dl2, UChar dh2,
1989 Int xmnm_kind)
1990{
1991 IRTemp op2addr = newTemp(Ity_I64);
1992 IRTemp d2 = newTemp(Ity_I64);
1993
florian6820ba52012-07-26 02:01:50 +00001994 next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0)));
1995
sewardjd7bde722011-04-05 13:19:33 +00001996 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
1997 assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
1998 mkU64(0)));
1999
2000 irgen(r1, op2addr);
florian6820ba52012-07-26 02:01:50 +00002001
2002 vassert(dis_res->whatNext == Dis_Continue);
sewardjd7bde722011-04-05 13:19:33 +00002003
sewardj7ee97522011-05-09 21:45:04 +00002004 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardjd7bde722011-04-05 13:19:33 +00002005 s390_disasm(ENC3(XMNM, GPR, SDXB), xmnm_kind, m3, r1, dh2, dl2, 0, b2);
2006}
2007
2008static void
sewardj2019a972011-03-07 16:04:07 +00002009s390_format_RX(HChar *(*irgen)(UChar r1, UChar x2, UChar b2, UShort d2,
2010 IRTemp op2addr),
2011 UChar r1, UChar x2, UChar b2, UShort d2)
2012{
2013 IRTemp op2addr = newTemp(Ity_I64);
2014
2015 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
2016 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2017 mkU64(0)));
2018
2019 irgen(r1, x2, b2, d2, op2addr);
2020}
2021
2022static void
2023s390_format_RX_RRRD(HChar *(*irgen)(UChar r1, IRTemp op2addr),
2024 UChar r1, UChar x2, UChar b2, UShort d2)
2025{
2026 HChar *mnm;
2027 IRTemp op2addr = newTemp(Ity_I64);
2028
2029 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
2030 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2031 mkU64(0)));
2032
2033 mnm = irgen(r1, op2addr);
2034
sewardj7ee97522011-05-09 21:45:04 +00002035 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002036 s390_disasm(ENC3(MNM, GPR, UDXB), mnm, r1, d2, x2, b2);
2037}
2038
2039static void
2040s390_format_RX_FRRD(HChar *(*irgen)(UChar r1, IRTemp op2addr),
2041 UChar r1, UChar x2, UChar b2, UShort d2)
2042{
2043 HChar *mnm;
2044 IRTemp op2addr = newTemp(Ity_I64);
2045
2046 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
2047 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2048 mkU64(0)));
2049
2050 mnm = irgen(r1, op2addr);
2051
sewardj7ee97522011-05-09 21:45:04 +00002052 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002053 s390_disasm(ENC3(MNM, FPR, UDXB), mnm, r1, d2, x2, b2);
2054}
2055
2056static void
2057s390_format_RXE_FRRD(HChar *(*irgen)(UChar r1, IRTemp op2addr),
2058 UChar r1, UChar x2, UChar b2, UShort d2)
2059{
2060 HChar *mnm;
2061 IRTemp op2addr = newTemp(Ity_I64);
2062
2063 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
2064 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2065 mkU64(0)));
2066
2067 mnm = irgen(r1, op2addr);
2068
sewardj7ee97522011-05-09 21:45:04 +00002069 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002070 s390_disasm(ENC3(MNM, FPR, UDXB), mnm, r1, d2, x2, b2);
2071}
2072
2073static void
2074s390_format_RXF_FRRDF(HChar *(*irgen)(UChar, IRTemp, UChar),
2075 UChar r3, UChar x2, UChar b2, UShort d2, UChar r1)
2076{
2077 HChar *mnm;
2078 IRTemp op2addr = newTemp(Ity_I64);
2079
2080 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
2081 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2082 mkU64(0)));
2083
2084 mnm = irgen(r3, op2addr, r1);
2085
sewardj7ee97522011-05-09 21:45:04 +00002086 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002087 s390_disasm(ENC4(MNM, FPR, FPR, UDXB), mnm, r1, r3, d2, x2, b2);
2088}
2089
2090static void
2091s390_format_RXY_RRRD(HChar *(*irgen)(UChar r1, IRTemp op2addr),
2092 UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
2093{
2094 HChar *mnm;
2095 IRTemp op2addr = newTemp(Ity_I64);
2096 IRTemp d2 = newTemp(Ity_I64);
2097
2098 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2099 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkexpr(d2),
2100 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2101 mkU64(0)));
2102
2103 mnm = irgen(r1, op2addr);
2104
sewardj7ee97522011-05-09 21:45:04 +00002105 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002106 s390_disasm(ENC3(MNM, GPR, SDXB), mnm, r1, dh2, dl2, x2, b2);
2107}
2108
2109static void
2110s390_format_RXY_FRRD(HChar *(*irgen)(UChar r1, IRTemp op2addr),
2111 UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
2112{
2113 HChar *mnm;
2114 IRTemp op2addr = newTemp(Ity_I64);
2115 IRTemp d2 = newTemp(Ity_I64);
2116
2117 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2118 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkexpr(d2),
2119 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2120 mkU64(0)));
2121
2122 mnm = irgen(r1, op2addr);
2123
sewardj7ee97522011-05-09 21:45:04 +00002124 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002125 s390_disasm(ENC3(MNM, FPR, SDXB), mnm, r1, dh2, dl2, x2, b2);
2126}
2127
2128static void
2129s390_format_RXY_URRD(HChar *(*irgen)(void),
2130 UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
2131{
2132 HChar *mnm;
2133 IRTemp op2addr = newTemp(Ity_I64);
2134 IRTemp d2 = newTemp(Ity_I64);
2135
2136 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2137 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkexpr(d2),
2138 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2139 mkU64(0)));
2140
2141 mnm = irgen();
2142
sewardj7ee97522011-05-09 21:45:04 +00002143 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002144 s390_disasm(ENC3(MNM, UINT, SDXB), mnm, r1, dh2, dl2, x2, b2);
2145}
2146
2147static void
2148s390_format_S_RD(HChar *(*irgen)(IRTemp op2addr),
2149 UChar b2, UShort d2)
2150{
2151 HChar *mnm;
2152 IRTemp op2addr = newTemp(Ity_I64);
2153
2154 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2155 mkU64(0)));
2156
2157 mnm = irgen(op2addr);
2158
sewardj7ee97522011-05-09 21:45:04 +00002159 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002160 s390_disasm(ENC2(MNM, UDXB), mnm, d2, 0, b2);
2161}
2162
2163static void
2164s390_format_SI_URD(HChar *(*irgen)(UChar i2, IRTemp op1addr),
2165 UChar i2, UChar b1, UShort d1)
2166{
2167 HChar *mnm;
2168 IRTemp op1addr = newTemp(Ity_I64);
2169
2170 assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
2171 mkU64(0)));
2172
2173 mnm = irgen(i2, op1addr);
2174
sewardj7ee97522011-05-09 21:45:04 +00002175 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002176 s390_disasm(ENC3(MNM, UDXB, UINT), mnm, d1, 0, b1, i2);
2177}
2178
2179static void
2180s390_format_SIY_URD(HChar *(*irgen)(UChar i2, IRTemp op1addr),
2181 UChar i2, UChar b1, UShort dl1, UChar dh1)
2182{
2183 HChar *mnm;
2184 IRTemp op1addr = newTemp(Ity_I64);
2185 IRTemp d1 = newTemp(Ity_I64);
2186
2187 assign(d1, mkU64(((ULong)(Long)(Char)dh1 << 12) | ((ULong)dl1)));
2188 assign(op1addr, binop(Iop_Add64, mkexpr(d1), b1 != 0 ? get_gpr_dw0(b1) :
2189 mkU64(0)));
2190
2191 mnm = irgen(i2, op1addr);
2192
sewardj7ee97522011-05-09 21:45:04 +00002193 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002194 s390_disasm(ENC3(MNM, SDXB, UINT), mnm, dh1, dl1, 0, b1, i2);
2195}
2196
2197static void
2198s390_format_SIY_IRD(HChar *(*irgen)(UChar i2, IRTemp op1addr),
2199 UChar i2, UChar b1, UShort dl1, UChar dh1)
2200{
2201 HChar *mnm;
2202 IRTemp op1addr = newTemp(Ity_I64);
2203 IRTemp d1 = newTemp(Ity_I64);
2204
2205 assign(d1, mkU64(((ULong)(Long)(Char)dh1 << 12) | ((ULong)dl1)));
2206 assign(op1addr, binop(Iop_Add64, mkexpr(d1), b1 != 0 ? get_gpr_dw0(b1) :
2207 mkU64(0)));
2208
2209 mnm = irgen(i2, op1addr);
2210
sewardj7ee97522011-05-09 21:45:04 +00002211 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002212 s390_disasm(ENC3(MNM, SDXB, INT), mnm, dh1, dl1, 0, b1, (Int)(Char)i2);
2213}
2214
2215static void
2216s390_format_SS_L0RDRD(HChar *(*irgen)(UChar, IRTemp, IRTemp),
2217 UChar l, UChar b1, UShort d1, UChar b2, UShort d2)
2218{
2219 HChar *mnm;
2220 IRTemp op1addr = newTemp(Ity_I64);
2221 IRTemp op2addr = newTemp(Ity_I64);
2222
2223 assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
2224 mkU64(0)));
2225 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2226 mkU64(0)));
2227
2228 mnm = irgen(l, op1addr, op2addr);
2229
sewardj7ee97522011-05-09 21:45:04 +00002230 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002231 s390_disasm(ENC3(MNM, UDLB, UDXB), mnm, d1, l, b1, d2, 0, b2);
2232}
2233
2234static void
2235s390_format_SIL_RDI(HChar *(*irgen)(UShort i2, IRTemp op1addr),
2236 UChar b1, UShort d1, UShort i2)
2237{
2238 HChar *mnm;
2239 IRTemp op1addr = newTemp(Ity_I64);
2240
2241 assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
2242 mkU64(0)));
2243
2244 mnm = irgen(i2, op1addr);
2245
sewardj7ee97522011-05-09 21:45:04 +00002246 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002247 s390_disasm(ENC3(MNM, UDXB, INT), mnm, d1, 0, b1, (Int)(Short)i2);
2248}
2249
2250static void
2251s390_format_SIL_RDU(HChar *(*irgen)(UShort i2, IRTemp op1addr),
2252 UChar b1, UShort d1, UShort i2)
2253{
2254 HChar *mnm;
2255 IRTemp op1addr = newTemp(Ity_I64);
2256
2257 assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
2258 mkU64(0)));
2259
2260 mnm = irgen(i2, op1addr);
2261
sewardj7ee97522011-05-09 21:45:04 +00002262 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002263 s390_disasm(ENC3(MNM, UDXB, UINT), mnm, d1, 0, b1, i2);
2264}
2265
2266
2267
2268/*------------------------------------------------------------*/
2269/*--- Build IR for opcodes ---*/
2270/*------------------------------------------------------------*/
2271
2272static HChar *
2273s390_irgen_AR(UChar r1, UChar r2)
2274{
2275 IRTemp op1 = newTemp(Ity_I32);
2276 IRTemp op2 = newTemp(Ity_I32);
2277 IRTemp result = newTemp(Ity_I32);
2278
2279 assign(op1, get_gpr_w1(r1));
2280 assign(op2, get_gpr_w1(r2));
2281 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2282 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2283 put_gpr_w1(r1, mkexpr(result));
2284
2285 return "ar";
2286}
2287
2288static HChar *
2289s390_irgen_AGR(UChar r1, UChar r2)
2290{
2291 IRTemp op1 = newTemp(Ity_I64);
2292 IRTemp op2 = newTemp(Ity_I64);
2293 IRTemp result = newTemp(Ity_I64);
2294
2295 assign(op1, get_gpr_dw0(r1));
2296 assign(op2, get_gpr_dw0(r2));
2297 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2298 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
2299 put_gpr_dw0(r1, mkexpr(result));
2300
2301 return "agr";
2302}
2303
2304static HChar *
2305s390_irgen_AGFR(UChar r1, UChar r2)
2306{
2307 IRTemp op1 = newTemp(Ity_I64);
2308 IRTemp op2 = newTemp(Ity_I64);
2309 IRTemp result = newTemp(Ity_I64);
2310
2311 assign(op1, get_gpr_dw0(r1));
2312 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
2313 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2314 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
2315 put_gpr_dw0(r1, mkexpr(result));
2316
2317 return "agfr";
2318}
2319
2320static HChar *
2321s390_irgen_ARK(UChar r3, UChar r1, UChar r2)
2322{
2323 IRTemp op2 = newTemp(Ity_I32);
2324 IRTemp op3 = newTemp(Ity_I32);
2325 IRTemp result = newTemp(Ity_I32);
2326
2327 assign(op2, get_gpr_w1(r2));
2328 assign(op3, get_gpr_w1(r3));
2329 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2330 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
2331 put_gpr_w1(r1, mkexpr(result));
2332
2333 return "ark";
2334}
2335
2336static HChar *
2337s390_irgen_AGRK(UChar r3, UChar r1, UChar r2)
2338{
2339 IRTemp op2 = newTemp(Ity_I64);
2340 IRTemp op3 = newTemp(Ity_I64);
2341 IRTemp result = newTemp(Ity_I64);
2342
2343 assign(op2, get_gpr_dw0(r2));
2344 assign(op3, get_gpr_dw0(r3));
2345 assign(result, binop(Iop_Add64, mkexpr(op2), mkexpr(op3)));
2346 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op2, op3);
2347 put_gpr_dw0(r1, mkexpr(result));
2348
2349 return "agrk";
2350}
2351
2352static HChar *
2353s390_irgen_A(UChar r1, IRTemp op2addr)
2354{
2355 IRTemp op1 = newTemp(Ity_I32);
2356 IRTemp op2 = newTemp(Ity_I32);
2357 IRTemp result = newTemp(Ity_I32);
2358
2359 assign(op1, get_gpr_w1(r1));
2360 assign(op2, load(Ity_I32, mkexpr(op2addr)));
2361 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2362 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2363 put_gpr_w1(r1, mkexpr(result));
2364
2365 return "a";
2366}
2367
2368static HChar *
2369s390_irgen_AY(UChar r1, IRTemp op2addr)
2370{
2371 IRTemp op1 = newTemp(Ity_I32);
2372 IRTemp op2 = newTemp(Ity_I32);
2373 IRTemp result = newTemp(Ity_I32);
2374
2375 assign(op1, get_gpr_w1(r1));
2376 assign(op2, load(Ity_I32, mkexpr(op2addr)));
2377 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2378 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2379 put_gpr_w1(r1, mkexpr(result));
2380
2381 return "ay";
2382}
2383
2384static HChar *
2385s390_irgen_AG(UChar r1, IRTemp op2addr)
2386{
2387 IRTemp op1 = newTemp(Ity_I64);
2388 IRTemp op2 = newTemp(Ity_I64);
2389 IRTemp result = newTemp(Ity_I64);
2390
2391 assign(op1, get_gpr_dw0(r1));
2392 assign(op2, load(Ity_I64, mkexpr(op2addr)));
2393 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2394 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
2395 put_gpr_dw0(r1, mkexpr(result));
2396
2397 return "ag";
2398}
2399
2400static HChar *
2401s390_irgen_AGF(UChar r1, IRTemp op2addr)
2402{
2403 IRTemp op1 = newTemp(Ity_I64);
2404 IRTemp op2 = newTemp(Ity_I64);
2405 IRTemp result = newTemp(Ity_I64);
2406
2407 assign(op1, get_gpr_dw0(r1));
2408 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
2409 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2410 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
2411 put_gpr_dw0(r1, mkexpr(result));
2412
2413 return "agf";
2414}
2415
2416static HChar *
2417s390_irgen_AFI(UChar r1, UInt i2)
2418{
2419 IRTemp op1 = newTemp(Ity_I32);
2420 Int op2;
2421 IRTemp result = newTemp(Ity_I32);
2422
2423 assign(op1, get_gpr_w1(r1));
2424 op2 = (Int)i2;
2425 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
2426 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
2427 mkU32((UInt)op2)));
2428 put_gpr_w1(r1, mkexpr(result));
2429
2430 return "afi";
2431}
2432
2433static HChar *
2434s390_irgen_AGFI(UChar r1, UInt i2)
2435{
2436 IRTemp op1 = newTemp(Ity_I64);
2437 Long op2;
2438 IRTemp result = newTemp(Ity_I64);
2439
2440 assign(op1, get_gpr_dw0(r1));
2441 op2 = (Long)(Int)i2;
2442 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64((ULong)op2)));
2443 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, mktemp(Ity_I64,
2444 mkU64((ULong)op2)));
2445 put_gpr_dw0(r1, mkexpr(result));
2446
2447 return "agfi";
2448}
2449
2450static HChar *
2451s390_irgen_AHIK(UChar r1, UChar r3, UShort i2)
2452{
2453 Int op2;
2454 IRTemp op3 = newTemp(Ity_I32);
2455 IRTemp result = newTemp(Ity_I32);
2456
2457 op2 = (Int)(Short)i2;
2458 assign(op3, get_gpr_w1(r3));
2459 assign(result, binop(Iop_Add32, mkU32((UInt)op2), mkexpr(op3)));
2460 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, mktemp(Ity_I32, mkU32((UInt)
2461 op2)), op3);
2462 put_gpr_w1(r1, mkexpr(result));
2463
2464 return "ahik";
2465}
2466
2467static HChar *
2468s390_irgen_AGHIK(UChar r1, UChar r3, UShort i2)
2469{
2470 Long op2;
2471 IRTemp op3 = newTemp(Ity_I64);
2472 IRTemp result = newTemp(Ity_I64);
2473
2474 op2 = (Long)(Short)i2;
2475 assign(op3, get_gpr_dw0(r3));
2476 assign(result, binop(Iop_Add64, mkU64((ULong)op2), mkexpr(op3)));
2477 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, mktemp(Ity_I64, mkU64((ULong)
2478 op2)), op3);
2479 put_gpr_dw0(r1, mkexpr(result));
2480
2481 return "aghik";
2482}
2483
2484static HChar *
2485s390_irgen_ASI(UChar i2, IRTemp op1addr)
2486{
2487 IRTemp op1 = newTemp(Ity_I32);
2488 Int op2;
2489 IRTemp result = newTemp(Ity_I32);
2490
2491 assign(op1, load(Ity_I32, mkexpr(op1addr)));
2492 op2 = (Int)(Char)i2;
2493 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
2494 store(mkexpr(op1addr), mkexpr(result));
2495 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
2496 mkU32((UInt)op2)));
2497
2498 return "asi";
2499}
2500
2501static HChar *
2502s390_irgen_AGSI(UChar i2, IRTemp op1addr)
2503{
2504 IRTemp op1 = newTemp(Ity_I64);
2505 Long op2;
2506 IRTemp result = newTemp(Ity_I64);
2507
2508 assign(op1, load(Ity_I64, mkexpr(op1addr)));
2509 op2 = (Long)(Char)i2;
2510 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64((ULong)op2)));
2511 store(mkexpr(op1addr), mkexpr(result));
2512 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, mktemp(Ity_I64,
2513 mkU64((ULong)op2)));
2514
2515 return "agsi";
2516}
2517
2518static HChar *
2519s390_irgen_AH(UChar r1, IRTemp op2addr)
2520{
2521 IRTemp op1 = newTemp(Ity_I32);
2522 IRTemp op2 = newTemp(Ity_I32);
2523 IRTemp result = newTemp(Ity_I32);
2524
2525 assign(op1, get_gpr_w1(r1));
2526 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
2527 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2528 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2529 put_gpr_w1(r1, mkexpr(result));
2530
2531 return "ah";
2532}
2533
2534static HChar *
2535s390_irgen_AHY(UChar r1, IRTemp op2addr)
2536{
2537 IRTemp op1 = newTemp(Ity_I32);
2538 IRTemp op2 = newTemp(Ity_I32);
2539 IRTemp result = newTemp(Ity_I32);
2540
2541 assign(op1, get_gpr_w1(r1));
2542 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
2543 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2544 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2545 put_gpr_w1(r1, mkexpr(result));
2546
2547 return "ahy";
2548}
2549
2550static HChar *
2551s390_irgen_AHI(UChar r1, UShort i2)
2552{
2553 IRTemp op1 = newTemp(Ity_I32);
2554 Int op2;
2555 IRTemp result = newTemp(Ity_I32);
2556
2557 assign(op1, get_gpr_w1(r1));
2558 op2 = (Int)(Short)i2;
2559 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
2560 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
2561 mkU32((UInt)op2)));
2562 put_gpr_w1(r1, mkexpr(result));
2563
2564 return "ahi";
2565}
2566
2567static HChar *
2568s390_irgen_AGHI(UChar r1, UShort i2)
2569{
2570 IRTemp op1 = newTemp(Ity_I64);
2571 Long op2;
2572 IRTemp result = newTemp(Ity_I64);
2573
2574 assign(op1, get_gpr_dw0(r1));
2575 op2 = (Long)(Short)i2;
2576 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64((ULong)op2)));
2577 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, mktemp(Ity_I64,
2578 mkU64((ULong)op2)));
2579 put_gpr_dw0(r1, mkexpr(result));
2580
2581 return "aghi";
2582}
2583
2584static HChar *
2585s390_irgen_AHHHR(UChar r3, UChar r1, UChar r2)
2586{
2587 IRTemp op2 = newTemp(Ity_I32);
2588 IRTemp op3 = newTemp(Ity_I32);
2589 IRTemp result = newTemp(Ity_I32);
2590
2591 assign(op2, get_gpr_w0(r2));
2592 assign(op3, get_gpr_w0(r3));
2593 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2594 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
2595 put_gpr_w0(r1, mkexpr(result));
2596
2597 return "ahhhr";
2598}
2599
2600static HChar *
2601s390_irgen_AHHLR(UChar r3, UChar r1, UChar r2)
2602{
2603 IRTemp op2 = newTemp(Ity_I32);
2604 IRTemp op3 = newTemp(Ity_I32);
2605 IRTemp result = newTemp(Ity_I32);
2606
2607 assign(op2, get_gpr_w0(r2));
2608 assign(op3, get_gpr_w1(r3));
2609 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2610 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
2611 put_gpr_w0(r1, mkexpr(result));
2612
2613 return "ahhlr";
2614}
2615
2616static HChar *
2617s390_irgen_AIH(UChar r1, UInt i2)
2618{
2619 IRTemp op1 = newTemp(Ity_I32);
2620 Int op2;
2621 IRTemp result = newTemp(Ity_I32);
2622
2623 assign(op1, get_gpr_w0(r1));
2624 op2 = (Int)i2;
2625 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
2626 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
2627 mkU32((UInt)op2)));
2628 put_gpr_w0(r1, mkexpr(result));
2629
2630 return "aih";
2631}
2632
2633static HChar *
2634s390_irgen_ALR(UChar r1, UChar r2)
2635{
2636 IRTemp op1 = newTemp(Ity_I32);
2637 IRTemp op2 = newTemp(Ity_I32);
2638 IRTemp result = newTemp(Ity_I32);
2639
2640 assign(op1, get_gpr_w1(r1));
2641 assign(op2, get_gpr_w1(r2));
2642 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2643 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, op2);
2644 put_gpr_w1(r1, mkexpr(result));
2645
2646 return "alr";
2647}
2648
2649static HChar *
2650s390_irgen_ALGR(UChar r1, UChar r2)
2651{
2652 IRTemp op1 = newTemp(Ity_I64);
2653 IRTemp op2 = newTemp(Ity_I64);
2654 IRTemp result = newTemp(Ity_I64);
2655
2656 assign(op1, get_gpr_dw0(r1));
2657 assign(op2, get_gpr_dw0(r2));
2658 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2659 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
2660 put_gpr_dw0(r1, mkexpr(result));
2661
2662 return "algr";
2663}
2664
2665static HChar *
2666s390_irgen_ALGFR(UChar r1, UChar r2)
2667{
2668 IRTemp op1 = newTemp(Ity_I64);
2669 IRTemp op2 = newTemp(Ity_I64);
2670 IRTemp result = newTemp(Ity_I64);
2671
2672 assign(op1, get_gpr_dw0(r1));
2673 assign(op2, unop(Iop_32Uto64, get_gpr_w1(r2)));
2674 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2675 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
2676 put_gpr_dw0(r1, mkexpr(result));
2677
2678 return "algfr";
2679}
2680
2681static HChar *
2682s390_irgen_ALRK(UChar r3, UChar r1, UChar r2)
2683{
2684 IRTemp op2 = newTemp(Ity_I32);
2685 IRTemp op3 = newTemp(Ity_I32);
2686 IRTemp result = newTemp(Ity_I32);
2687
2688 assign(op2, get_gpr_w1(r2));
2689 assign(op3, get_gpr_w1(r3));
2690 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2691 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
2692 put_gpr_w1(r1, mkexpr(result));
2693
2694 return "alrk";
2695}
2696
2697static HChar *
2698s390_irgen_ALGRK(UChar r3, UChar r1, UChar r2)
2699{
2700 IRTemp op2 = newTemp(Ity_I64);
2701 IRTemp op3 = newTemp(Ity_I64);
2702 IRTemp result = newTemp(Ity_I64);
2703
2704 assign(op2, get_gpr_dw0(r2));
2705 assign(op3, get_gpr_dw0(r3));
2706 assign(result, binop(Iop_Add64, mkexpr(op2), mkexpr(op3)));
2707 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op2, op3);
2708 put_gpr_dw0(r1, mkexpr(result));
2709
2710 return "algrk";
2711}
2712
2713static HChar *
2714s390_irgen_AL(UChar r1, IRTemp op2addr)
2715{
2716 IRTemp op1 = newTemp(Ity_I32);
2717 IRTemp op2 = newTemp(Ity_I32);
2718 IRTemp result = newTemp(Ity_I32);
2719
2720 assign(op1, get_gpr_w1(r1));
2721 assign(op2, load(Ity_I32, mkexpr(op2addr)));
2722 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2723 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, op2);
2724 put_gpr_w1(r1, mkexpr(result));
2725
2726 return "al";
2727}
2728
2729static HChar *
2730s390_irgen_ALY(UChar r1, IRTemp op2addr)
2731{
2732 IRTemp op1 = newTemp(Ity_I32);
2733 IRTemp op2 = newTemp(Ity_I32);
2734 IRTemp result = newTemp(Ity_I32);
2735
2736 assign(op1, get_gpr_w1(r1));
2737 assign(op2, load(Ity_I32, mkexpr(op2addr)));
2738 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2739 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, op2);
2740 put_gpr_w1(r1, mkexpr(result));
2741
2742 return "aly";
2743}
2744
2745static HChar *
2746s390_irgen_ALG(UChar r1, IRTemp op2addr)
2747{
2748 IRTemp op1 = newTemp(Ity_I64);
2749 IRTemp op2 = newTemp(Ity_I64);
2750 IRTemp result = newTemp(Ity_I64);
2751
2752 assign(op1, get_gpr_dw0(r1));
2753 assign(op2, load(Ity_I64, mkexpr(op2addr)));
2754 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2755 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
2756 put_gpr_dw0(r1, mkexpr(result));
2757
2758 return "alg";
2759}
2760
2761static HChar *
2762s390_irgen_ALGF(UChar r1, IRTemp op2addr)
2763{
2764 IRTemp op1 = newTemp(Ity_I64);
2765 IRTemp op2 = newTemp(Ity_I64);
2766 IRTemp result = newTemp(Ity_I64);
2767
2768 assign(op1, get_gpr_dw0(r1));
2769 assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
2770 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2771 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
2772 put_gpr_dw0(r1, mkexpr(result));
2773
2774 return "algf";
2775}
2776
2777static HChar *
2778s390_irgen_ALFI(UChar r1, UInt i2)
2779{
2780 IRTemp op1 = newTemp(Ity_I32);
2781 UInt op2;
2782 IRTemp result = newTemp(Ity_I32);
2783
2784 assign(op1, get_gpr_w1(r1));
2785 op2 = i2;
2786 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
2787 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, mktemp(Ity_I32,
2788 mkU32(op2)));
2789 put_gpr_w1(r1, mkexpr(result));
2790
2791 return "alfi";
2792}
2793
2794static HChar *
2795s390_irgen_ALGFI(UChar r1, UInt i2)
2796{
2797 IRTemp op1 = newTemp(Ity_I64);
2798 ULong op2;
2799 IRTemp result = newTemp(Ity_I64);
2800
2801 assign(op1, get_gpr_dw0(r1));
2802 op2 = (ULong)i2;
2803 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64(op2)));
2804 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, mktemp(Ity_I64,
2805 mkU64(op2)));
2806 put_gpr_dw0(r1, mkexpr(result));
2807
2808 return "algfi";
2809}
2810
2811static HChar *
2812s390_irgen_ALHHHR(UChar r3, UChar r1, UChar r2)
2813{
2814 IRTemp op2 = newTemp(Ity_I32);
2815 IRTemp op3 = newTemp(Ity_I32);
2816 IRTemp result = newTemp(Ity_I32);
2817
2818 assign(op2, get_gpr_w0(r2));
2819 assign(op3, get_gpr_w0(r3));
2820 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2821 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
2822 put_gpr_w0(r1, mkexpr(result));
2823
2824 return "alhhhr";
2825}
2826
2827static HChar *
2828s390_irgen_ALHHLR(UChar r3, UChar r1, UChar r2)
2829{
2830 IRTemp op2 = newTemp(Ity_I32);
2831 IRTemp op3 = newTemp(Ity_I32);
2832 IRTemp result = newTemp(Ity_I32);
2833
2834 assign(op2, get_gpr_w0(r2));
2835 assign(op3, get_gpr_w1(r3));
2836 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2837 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
2838 put_gpr_w0(r1, mkexpr(result));
2839
2840 return "alhhlr";
2841}
2842
2843static HChar *
2844s390_irgen_ALCR(UChar r1, UChar r2)
2845{
2846 IRTemp op1 = newTemp(Ity_I32);
2847 IRTemp op2 = newTemp(Ity_I32);
2848 IRTemp result = newTemp(Ity_I32);
2849 IRTemp carry_in = newTemp(Ity_I32);
2850
2851 assign(op1, get_gpr_w1(r1));
2852 assign(op2, get_gpr_w1(r2));
2853 assign(carry_in, binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)));
2854 assign(result, binop(Iop_Add32, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)),
2855 mkexpr(carry_in)));
2856 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_32, op1, op2, carry_in);
2857 put_gpr_w1(r1, mkexpr(result));
2858
2859 return "alcr";
2860}
2861
2862static HChar *
2863s390_irgen_ALCGR(UChar r1, UChar r2)
2864{
2865 IRTemp op1 = newTemp(Ity_I64);
2866 IRTemp op2 = newTemp(Ity_I64);
2867 IRTemp result = newTemp(Ity_I64);
2868 IRTemp carry_in = newTemp(Ity_I64);
2869
2870 assign(op1, get_gpr_dw0(r1));
2871 assign(op2, get_gpr_dw0(r2));
2872 assign(carry_in, unop(Iop_32Uto64, binop(Iop_Shr32, s390_call_calculate_cc(),
2873 mkU8(1))));
2874 assign(result, binop(Iop_Add64, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)),
2875 mkexpr(carry_in)));
2876 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_64, op1, op2, carry_in);
2877 put_gpr_dw0(r1, mkexpr(result));
2878
2879 return "alcgr";
2880}
2881
2882static HChar *
2883s390_irgen_ALC(UChar r1, IRTemp op2addr)
2884{
2885 IRTemp op1 = newTemp(Ity_I32);
2886 IRTemp op2 = newTemp(Ity_I32);
2887 IRTemp result = newTemp(Ity_I32);
2888 IRTemp carry_in = newTemp(Ity_I32);
2889
2890 assign(op1, get_gpr_w1(r1));
2891 assign(op2, load(Ity_I32, mkexpr(op2addr)));
2892 assign(carry_in, binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)));
2893 assign(result, binop(Iop_Add32, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)),
2894 mkexpr(carry_in)));
2895 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_32, op1, op2, carry_in);
2896 put_gpr_w1(r1, mkexpr(result));
2897
2898 return "alc";
2899}
2900
2901static HChar *
2902s390_irgen_ALCG(UChar r1, IRTemp op2addr)
2903{
2904 IRTemp op1 = newTemp(Ity_I64);
2905 IRTemp op2 = newTemp(Ity_I64);
2906 IRTemp result = newTemp(Ity_I64);
2907 IRTemp carry_in = newTemp(Ity_I64);
2908
2909 assign(op1, get_gpr_dw0(r1));
2910 assign(op2, load(Ity_I64, mkexpr(op2addr)));
2911 assign(carry_in, unop(Iop_32Uto64, binop(Iop_Shr32, s390_call_calculate_cc(),
2912 mkU8(1))));
2913 assign(result, binop(Iop_Add64, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)),
2914 mkexpr(carry_in)));
2915 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_64, op1, op2, carry_in);
2916 put_gpr_dw0(r1, mkexpr(result));
2917
2918 return "alcg";
2919}
2920
2921static HChar *
2922s390_irgen_ALSI(UChar i2, IRTemp op1addr)
2923{
2924 IRTemp op1 = newTemp(Ity_I32);
2925 UInt op2;
2926 IRTemp result = newTemp(Ity_I32);
2927
2928 assign(op1, load(Ity_I32, mkexpr(op1addr)));
2929 op2 = (UInt)(Int)(Char)i2;
2930 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
2931 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, mktemp(Ity_I32,
2932 mkU32(op2)));
2933 store(mkexpr(op1addr), mkexpr(result));
2934
2935 return "alsi";
2936}
2937
2938static HChar *
2939s390_irgen_ALGSI(UChar i2, IRTemp op1addr)
2940{
2941 IRTemp op1 = newTemp(Ity_I64);
2942 ULong op2;
2943 IRTemp result = newTemp(Ity_I64);
2944
2945 assign(op1, load(Ity_I64, mkexpr(op1addr)));
2946 op2 = (ULong)(Long)(Char)i2;
2947 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64(op2)));
2948 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, mktemp(Ity_I64,
2949 mkU64(op2)));
2950 store(mkexpr(op1addr), mkexpr(result));
2951
2952 return "algsi";
2953}
2954
2955static HChar *
2956s390_irgen_ALHSIK(UChar r1, UChar r3, UShort i2)
2957{
2958 UInt op2;
2959 IRTemp op3 = newTemp(Ity_I32);
2960 IRTemp result = newTemp(Ity_I32);
2961
2962 op2 = (UInt)(Int)(Short)i2;
2963 assign(op3, get_gpr_w1(r3));
2964 assign(result, binop(Iop_Add32, mkU32(op2), mkexpr(op3)));
2965 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, mktemp(Ity_I32, mkU32(op2)),
2966 op3);
2967 put_gpr_w1(r1, mkexpr(result));
2968
2969 return "alhsik";
2970}
2971
2972static HChar *
2973s390_irgen_ALGHSIK(UChar r1, UChar r3, UShort i2)
2974{
2975 ULong op2;
2976 IRTemp op3 = newTemp(Ity_I64);
2977 IRTemp result = newTemp(Ity_I64);
2978
2979 op2 = (ULong)(Long)(Short)i2;
2980 assign(op3, get_gpr_dw0(r3));
2981 assign(result, binop(Iop_Add64, mkU64(op2), mkexpr(op3)));
2982 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, mktemp(Ity_I64, mkU64(op2)),
2983 op3);
2984 put_gpr_dw0(r1, mkexpr(result));
2985
2986 return "alghsik";
2987}
2988
2989static HChar *
2990s390_irgen_ALSIH(UChar r1, UInt i2)
2991{
2992 IRTemp op1 = newTemp(Ity_I32);
2993 UInt op2;
2994 IRTemp result = newTemp(Ity_I32);
2995
2996 assign(op1, get_gpr_w0(r1));
2997 op2 = i2;
2998 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
2999 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, mktemp(Ity_I32,
3000 mkU32(op2)));
3001 put_gpr_w0(r1, mkexpr(result));
3002
3003 return "alsih";
3004}
3005
3006static HChar *
3007s390_irgen_ALSIHN(UChar r1, UInt i2)
3008{
3009 IRTemp op1 = newTemp(Ity_I32);
3010 UInt op2;
3011 IRTemp result = newTemp(Ity_I32);
3012
3013 assign(op1, get_gpr_w0(r1));
3014 op2 = i2;
3015 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
3016 put_gpr_w0(r1, mkexpr(result));
3017
3018 return "alsihn";
3019}
3020
3021static HChar *
3022s390_irgen_NR(UChar r1, UChar r2)
3023{
3024 IRTemp op1 = newTemp(Ity_I32);
3025 IRTemp op2 = newTemp(Ity_I32);
3026 IRTemp result = newTemp(Ity_I32);
3027
3028 assign(op1, get_gpr_w1(r1));
3029 assign(op2, get_gpr_w1(r2));
3030 assign(result, binop(Iop_And32, mkexpr(op1), mkexpr(op2)));
3031 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3032 put_gpr_w1(r1, mkexpr(result));
3033
3034 return "nr";
3035}
3036
3037static HChar *
3038s390_irgen_NGR(UChar r1, UChar r2)
3039{
3040 IRTemp op1 = newTemp(Ity_I64);
3041 IRTemp op2 = newTemp(Ity_I64);
3042 IRTemp result = newTemp(Ity_I64);
3043
3044 assign(op1, get_gpr_dw0(r1));
3045 assign(op2, get_gpr_dw0(r2));
3046 assign(result, binop(Iop_And64, mkexpr(op1), mkexpr(op2)));
3047 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3048 put_gpr_dw0(r1, mkexpr(result));
3049
3050 return "ngr";
3051}
3052
3053static HChar *
3054s390_irgen_NRK(UChar r3, UChar r1, UChar r2)
3055{
3056 IRTemp op2 = newTemp(Ity_I32);
3057 IRTemp op3 = newTemp(Ity_I32);
3058 IRTemp result = newTemp(Ity_I32);
3059
3060 assign(op2, get_gpr_w1(r2));
3061 assign(op3, get_gpr_w1(r3));
3062 assign(result, binop(Iop_And32, mkexpr(op2), mkexpr(op3)));
3063 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3064 put_gpr_w1(r1, mkexpr(result));
3065
3066 return "nrk";
3067}
3068
3069static HChar *
3070s390_irgen_NGRK(UChar r3, UChar r1, UChar r2)
3071{
3072 IRTemp op2 = newTemp(Ity_I64);
3073 IRTemp op3 = newTemp(Ity_I64);
3074 IRTemp result = newTemp(Ity_I64);
3075
3076 assign(op2, get_gpr_dw0(r2));
3077 assign(op3, get_gpr_dw0(r3));
3078 assign(result, binop(Iop_And64, mkexpr(op2), mkexpr(op3)));
3079 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3080 put_gpr_dw0(r1, mkexpr(result));
3081
3082 return "ngrk";
3083}
3084
3085static HChar *
3086s390_irgen_N(UChar r1, IRTemp op2addr)
3087{
3088 IRTemp op1 = newTemp(Ity_I32);
3089 IRTemp op2 = newTemp(Ity_I32);
3090 IRTemp result = newTemp(Ity_I32);
3091
3092 assign(op1, get_gpr_w1(r1));
3093 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3094 assign(result, binop(Iop_And32, mkexpr(op1), mkexpr(op2)));
3095 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3096 put_gpr_w1(r1, mkexpr(result));
3097
3098 return "n";
3099}
3100
3101static HChar *
3102s390_irgen_NY(UChar r1, IRTemp op2addr)
3103{
3104 IRTemp op1 = newTemp(Ity_I32);
3105 IRTemp op2 = newTemp(Ity_I32);
3106 IRTemp result = newTemp(Ity_I32);
3107
3108 assign(op1, get_gpr_w1(r1));
3109 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3110 assign(result, binop(Iop_And32, mkexpr(op1), mkexpr(op2)));
3111 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3112 put_gpr_w1(r1, mkexpr(result));
3113
3114 return "ny";
3115}
3116
3117static HChar *
3118s390_irgen_NG(UChar r1, IRTemp op2addr)
3119{
3120 IRTemp op1 = newTemp(Ity_I64);
3121 IRTemp op2 = newTemp(Ity_I64);
3122 IRTemp result = newTemp(Ity_I64);
3123
3124 assign(op1, get_gpr_dw0(r1));
3125 assign(op2, load(Ity_I64, mkexpr(op2addr)));
3126 assign(result, binop(Iop_And64, mkexpr(op1), mkexpr(op2)));
3127 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3128 put_gpr_dw0(r1, mkexpr(result));
3129
3130 return "ng";
3131}
3132
3133static HChar *
3134s390_irgen_NI(UChar i2, IRTemp op1addr)
3135{
3136 IRTemp op1 = newTemp(Ity_I8);
3137 UChar op2;
3138 IRTemp result = newTemp(Ity_I8);
3139
3140 assign(op1, load(Ity_I8, mkexpr(op1addr)));
3141 op2 = i2;
3142 assign(result, binop(Iop_And8, mkexpr(op1), mkU8(op2)));
3143 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3144 store(mkexpr(op1addr), mkexpr(result));
3145
3146 return "ni";
3147}
3148
3149static HChar *
3150s390_irgen_NIY(UChar i2, IRTemp op1addr)
3151{
3152 IRTemp op1 = newTemp(Ity_I8);
3153 UChar op2;
3154 IRTemp result = newTemp(Ity_I8);
3155
3156 assign(op1, load(Ity_I8, mkexpr(op1addr)));
3157 op2 = i2;
3158 assign(result, binop(Iop_And8, mkexpr(op1), mkU8(op2)));
3159 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3160 store(mkexpr(op1addr), mkexpr(result));
3161
3162 return "niy";
3163}
3164
3165static HChar *
3166s390_irgen_NIHF(UChar r1, UInt i2)
3167{
3168 IRTemp op1 = newTemp(Ity_I32);
3169 UInt op2;
3170 IRTemp result = newTemp(Ity_I32);
3171
3172 assign(op1, get_gpr_w0(r1));
3173 op2 = i2;
3174 assign(result, binop(Iop_And32, mkexpr(op1), mkU32(op2)));
3175 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3176 put_gpr_w0(r1, mkexpr(result));
3177
3178 return "nihf";
3179}
3180
3181static HChar *
3182s390_irgen_NIHH(UChar r1, UShort i2)
3183{
3184 IRTemp op1 = newTemp(Ity_I16);
3185 UShort op2;
3186 IRTemp result = newTemp(Ity_I16);
3187
3188 assign(op1, get_gpr_hw0(r1));
3189 op2 = i2;
3190 assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
3191 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3192 put_gpr_hw0(r1, mkexpr(result));
3193
3194 return "nihh";
3195}
3196
3197static HChar *
3198s390_irgen_NIHL(UChar r1, UShort i2)
3199{
3200 IRTemp op1 = newTemp(Ity_I16);
3201 UShort op2;
3202 IRTemp result = newTemp(Ity_I16);
3203
3204 assign(op1, get_gpr_hw1(r1));
3205 op2 = i2;
3206 assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
3207 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3208 put_gpr_hw1(r1, mkexpr(result));
3209
3210 return "nihl";
3211}
3212
3213static HChar *
3214s390_irgen_NILF(UChar r1, UInt i2)
3215{
3216 IRTemp op1 = newTemp(Ity_I32);
3217 UInt op2;
3218 IRTemp result = newTemp(Ity_I32);
3219
3220 assign(op1, get_gpr_w1(r1));
3221 op2 = i2;
3222 assign(result, binop(Iop_And32, mkexpr(op1), mkU32(op2)));
3223 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3224 put_gpr_w1(r1, mkexpr(result));
3225
3226 return "nilf";
3227}
3228
3229static HChar *
3230s390_irgen_NILH(UChar r1, UShort i2)
3231{
3232 IRTemp op1 = newTemp(Ity_I16);
3233 UShort op2;
3234 IRTemp result = newTemp(Ity_I16);
3235
3236 assign(op1, get_gpr_hw2(r1));
3237 op2 = i2;
3238 assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
3239 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3240 put_gpr_hw2(r1, mkexpr(result));
3241
3242 return "nilh";
3243}
3244
3245static HChar *
3246s390_irgen_NILL(UChar r1, UShort i2)
3247{
3248 IRTemp op1 = newTemp(Ity_I16);
3249 UShort op2;
3250 IRTemp result = newTemp(Ity_I16);
3251
3252 assign(op1, get_gpr_hw3(r1));
3253 op2 = i2;
3254 assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
3255 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3256 put_gpr_hw3(r1, mkexpr(result));
3257
3258 return "nill";
3259}
3260
3261static HChar *
3262s390_irgen_BASR(UChar r1, UChar r2)
3263{
3264 IRTemp target = newTemp(Ity_I64);
3265
3266 if (r2 == 0) {
3267 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 2ULL));
3268 } else {
3269 if (r1 != r2) {
3270 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 2ULL));
3271 call_function(get_gpr_dw0(r2));
3272 } else {
3273 assign(target, get_gpr_dw0(r2));
3274 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 2ULL));
3275 call_function(mkexpr(target));
3276 }
3277 }
3278
3279 return "basr";
3280}
3281
3282static HChar *
3283s390_irgen_BAS(UChar r1, IRTemp op2addr)
3284{
3285 IRTemp target = newTemp(Ity_I64);
3286
3287 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 4ULL));
3288 assign(target, mkexpr(op2addr));
3289 call_function(mkexpr(target));
3290
3291 return "bas";
3292}
3293
3294static HChar *
3295s390_irgen_BCR(UChar r1, UChar r2)
3296{
3297 IRTemp cond = newTemp(Ity_I32);
3298
sewardja52e37e2011-04-28 18:48:06 +00003299 if (r2 == 0 && (r1 >= 14)) { /* serialization */
3300 stmt(IRStmt_MBE(Imbe_Fence));
3301 }
3302
sewardj2019a972011-03-07 16:04:07 +00003303 if ((r2 == 0) || (r1 == 0)) {
3304 } else {
3305 if (r1 == 15) {
3306 return_from_function(get_gpr_dw0(r2));
3307 } else {
3308 assign(cond, s390_call_calculate_cond(r1));
florianf321da72012-07-21 20:32:57 +00003309 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3310 get_gpr_dw0(r2));
sewardj2019a972011-03-07 16:04:07 +00003311 }
3312 }
sewardj7ee97522011-05-09 21:45:04 +00003313 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00003314 s390_disasm(ENC2(XMNM, GPR), S390_XMNM_BCR, r1, r2);
3315
3316 return "bcr";
3317}
3318
3319static HChar *
3320s390_irgen_BC(UChar r1, UChar x2, UChar b2, UShort d2, IRTemp op2addr)
3321{
3322 IRTemp cond = newTemp(Ity_I32);
3323
3324 if (r1 == 0) {
3325 } else {
3326 if (r1 == 15) {
3327 always_goto(mkexpr(op2addr));
3328 } else {
3329 assign(cond, s390_call_calculate_cond(r1));
florianf321da72012-07-21 20:32:57 +00003330 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3331 mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003332 }
3333 }
sewardj7ee97522011-05-09 21:45:04 +00003334 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00003335 s390_disasm(ENC2(XMNM, UDXB), S390_XMNM_BC, r1, d2, x2, b2);
3336
3337 return "bc";
3338}
3339
3340static HChar *
3341s390_irgen_BCTR(UChar r1, UChar r2)
3342{
3343 put_gpr_w1(r1, binop(Iop_Sub32, get_gpr_w1(r1), mkU32(1)));
3344 if (r2 != 0) {
florianf321da72012-07-21 20:32:57 +00003345 if_condition_goto_computed(binop(Iop_CmpNE32, get_gpr_w1(r1), mkU32(0)),
3346 get_gpr_dw0(r2));
sewardj2019a972011-03-07 16:04:07 +00003347 }
3348
3349 return "bctr";
3350}
3351
3352static HChar *
3353s390_irgen_BCTGR(UChar r1, UChar r2)
3354{
3355 put_gpr_dw0(r1, binop(Iop_Sub64, get_gpr_dw0(r1), mkU64(1)));
3356 if (r2 != 0) {
florianf321da72012-07-21 20:32:57 +00003357 if_condition_goto_computed(binop(Iop_CmpNE64, get_gpr_dw0(r1), mkU64(0)),
3358 get_gpr_dw0(r2));
sewardj2019a972011-03-07 16:04:07 +00003359 }
3360
3361 return "bctgr";
3362}
3363
3364static HChar *
3365s390_irgen_BCT(UChar r1, IRTemp op2addr)
3366{
3367 put_gpr_w1(r1, binop(Iop_Sub32, get_gpr_w1(r1), mkU32(1)));
florianf321da72012-07-21 20:32:57 +00003368 if_condition_goto_computed(binop(Iop_CmpNE32, get_gpr_w1(r1), mkU32(0)),
3369 mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003370
3371 return "bct";
3372}
3373
3374static HChar *
3375s390_irgen_BCTG(UChar r1, IRTemp op2addr)
3376{
3377 put_gpr_dw0(r1, binop(Iop_Sub64, get_gpr_dw0(r1), mkU64(1)));
florianf321da72012-07-21 20:32:57 +00003378 if_condition_goto_computed(binop(Iop_CmpNE64, get_gpr_dw0(r1), mkU64(0)),
3379 mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003380
3381 return "bctg";
3382}
3383
3384static HChar *
3385s390_irgen_BXH(UChar r1, UChar r3, IRTemp op2addr)
3386{
3387 IRTemp value = newTemp(Ity_I32);
3388
3389 assign(value, get_gpr_w1(r3 | 1));
3390 put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
florianf321da72012-07-21 20:32:57 +00003391 if_condition_goto_computed(binop(Iop_CmpLT32S, mkexpr(value),
3392 get_gpr_w1(r1)), mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003393
3394 return "bxh";
3395}
3396
3397static HChar *
3398s390_irgen_BXHG(UChar r1, UChar r3, IRTemp op2addr)
3399{
3400 IRTemp value = newTemp(Ity_I64);
3401
3402 assign(value, get_gpr_dw0(r3 | 1));
3403 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
florianf321da72012-07-21 20:32:57 +00003404 if_condition_goto_computed(binop(Iop_CmpLT64S, mkexpr(value),
3405 get_gpr_dw0(r1)), mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003406
3407 return "bxhg";
3408}
3409
3410static HChar *
3411s390_irgen_BXLE(UChar r1, UChar r3, IRTemp op2addr)
3412{
3413 IRTemp value = newTemp(Ity_I32);
3414
3415 assign(value, get_gpr_w1(r3 | 1));
3416 put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
florianf321da72012-07-21 20:32:57 +00003417 if_condition_goto_computed(binop(Iop_CmpLE32S, get_gpr_w1(r1),
3418 mkexpr(value)), mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003419
3420 return "bxle";
3421}
3422
3423static HChar *
3424s390_irgen_BXLEG(UChar r1, UChar r3, IRTemp op2addr)
3425{
3426 IRTemp value = newTemp(Ity_I64);
3427
3428 assign(value, get_gpr_dw0(r3 | 1));
3429 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
florianf321da72012-07-21 20:32:57 +00003430 if_condition_goto_computed(binop(Iop_CmpLE64S, get_gpr_dw0(r1),
3431 mkexpr(value)), mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003432
3433 return "bxleg";
3434}
3435
3436static HChar *
3437s390_irgen_BRAS(UChar r1, UShort i2)
3438{
3439 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 4ULL));
floriana64c2432011-07-16 02:11:50 +00003440 call_function_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
sewardj2019a972011-03-07 16:04:07 +00003441
3442 return "bras";
3443}
3444
3445static HChar *
3446s390_irgen_BRASL(UChar r1, UInt i2)
3447{
3448 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 6ULL));
floriana64c2432011-07-16 02:11:50 +00003449 call_function_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1));
sewardj2019a972011-03-07 16:04:07 +00003450
3451 return "brasl";
3452}
3453
3454static HChar *
3455s390_irgen_BRC(UChar r1, UShort i2)
3456{
3457 IRTemp cond = newTemp(Ity_I32);
3458
3459 if (r1 == 0) {
3460 } else {
3461 if (r1 == 15) {
floriana64c2432011-07-16 02:11:50 +00003462 always_goto_and_chase(
3463 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
sewardj2019a972011-03-07 16:04:07 +00003464 } else {
3465 assign(cond, s390_call_calculate_cond(r1));
3466 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3467 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3468
3469 }
3470 }
sewardj7ee97522011-05-09 21:45:04 +00003471 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00003472 s390_disasm(ENC2(XMNM, PCREL), S390_XMNM_BRC, r1, (Int)(Short)i2);
3473
3474 return "brc";
3475}
3476
3477static HChar *
3478s390_irgen_BRCL(UChar r1, UInt i2)
3479{
3480 IRTemp cond = newTemp(Ity_I32);
3481
3482 if (r1 == 0) {
3483 } else {
3484 if (r1 == 15) {
floriana64c2432011-07-16 02:11:50 +00003485 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1));
sewardj2019a972011-03-07 16:04:07 +00003486 } else {
3487 assign(cond, s390_call_calculate_cond(r1));
3488 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3489 guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1));
3490 }
3491 }
sewardj7ee97522011-05-09 21:45:04 +00003492 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00003493 s390_disasm(ENC2(XMNM, PCREL), S390_XMNM_BRCL, r1, i2);
3494
3495 return "brcl";
3496}
3497
3498static HChar *
3499s390_irgen_BRCT(UChar r1, UShort i2)
3500{
3501 put_gpr_w1(r1, binop(Iop_Sub32, get_gpr_w1(r1), mkU32(1)));
3502 if_condition_goto(binop(Iop_CmpNE32, get_gpr_w1(r1), mkU32(0)),
3503 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3504
3505 return "brct";
3506}
3507
3508static HChar *
3509s390_irgen_BRCTG(UChar r1, UShort i2)
3510{
3511 put_gpr_dw0(r1, binop(Iop_Sub64, get_gpr_dw0(r1), mkU64(1)));
3512 if_condition_goto(binop(Iop_CmpNE64, get_gpr_dw0(r1), mkU64(0)),
3513 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3514
3515 return "brctg";
3516}
3517
3518static HChar *
3519s390_irgen_BRXH(UChar r1, UChar r3, UShort i2)
3520{
3521 IRTemp value = newTemp(Ity_I32);
3522
3523 assign(value, get_gpr_w1(r3 | 1));
3524 put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
3525 if_condition_goto(binop(Iop_CmpLT32S, mkexpr(value), get_gpr_w1(r1)),
3526 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3527
3528 return "brxh";
3529}
3530
3531static HChar *
3532s390_irgen_BRXHG(UChar r1, UChar r3, UShort i2)
3533{
3534 IRTemp value = newTemp(Ity_I64);
3535
3536 assign(value, get_gpr_dw0(r3 | 1));
3537 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
3538 if_condition_goto(binop(Iop_CmpLT64S, mkexpr(value), get_gpr_dw0(r1)),
3539 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3540
3541 return "brxhg";
3542}
3543
3544static HChar *
3545s390_irgen_BRXLE(UChar r1, UChar r3, UShort i2)
3546{
3547 IRTemp value = newTemp(Ity_I32);
3548
3549 assign(value, get_gpr_w1(r3 | 1));
3550 put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
3551 if_condition_goto(binop(Iop_CmpLE32S, get_gpr_w1(r1), mkexpr(value)),
3552 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3553
3554 return "brxle";
3555}
3556
3557static HChar *
3558s390_irgen_BRXLG(UChar r1, UChar r3, UShort i2)
3559{
3560 IRTemp value = newTemp(Ity_I64);
3561
3562 assign(value, get_gpr_dw0(r3 | 1));
3563 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
3564 if_condition_goto(binop(Iop_CmpLE64S, get_gpr_dw0(r1), mkexpr(value)),
3565 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3566
3567 return "brxlg";
3568}
3569
3570static HChar *
3571s390_irgen_CR(UChar r1, UChar r2)
3572{
3573 IRTemp op1 = newTemp(Ity_I32);
3574 IRTemp op2 = newTemp(Ity_I32);
3575
3576 assign(op1, get_gpr_w1(r1));
3577 assign(op2, get_gpr_w1(r2));
3578 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3579
3580 return "cr";
3581}
3582
3583static HChar *
3584s390_irgen_CGR(UChar r1, UChar r2)
3585{
3586 IRTemp op1 = newTemp(Ity_I64);
3587 IRTemp op2 = newTemp(Ity_I64);
3588
3589 assign(op1, get_gpr_dw0(r1));
3590 assign(op2, get_gpr_dw0(r2));
3591 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3592
3593 return "cgr";
3594}
3595
3596static HChar *
3597s390_irgen_CGFR(UChar r1, UChar r2)
3598{
3599 IRTemp op1 = newTemp(Ity_I64);
3600 IRTemp op2 = newTemp(Ity_I64);
3601
3602 assign(op1, get_gpr_dw0(r1));
3603 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
3604 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3605
3606 return "cgfr";
3607}
3608
3609static HChar *
3610s390_irgen_C(UChar r1, IRTemp op2addr)
3611{
3612 IRTemp op1 = newTemp(Ity_I32);
3613 IRTemp op2 = newTemp(Ity_I32);
3614
3615 assign(op1, get_gpr_w1(r1));
3616 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3617 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3618
3619 return "c";
3620}
3621
3622static HChar *
3623s390_irgen_CY(UChar r1, IRTemp op2addr)
3624{
3625 IRTemp op1 = newTemp(Ity_I32);
3626 IRTemp op2 = newTemp(Ity_I32);
3627
3628 assign(op1, get_gpr_w1(r1));
3629 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3630 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3631
3632 return "cy";
3633}
3634
3635static HChar *
3636s390_irgen_CG(UChar r1, IRTemp op2addr)
3637{
3638 IRTemp op1 = newTemp(Ity_I64);
3639 IRTemp op2 = newTemp(Ity_I64);
3640
3641 assign(op1, get_gpr_dw0(r1));
3642 assign(op2, load(Ity_I64, mkexpr(op2addr)));
3643 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3644
3645 return "cg";
3646}
3647
3648static HChar *
3649s390_irgen_CGF(UChar r1, IRTemp op2addr)
3650{
3651 IRTemp op1 = newTemp(Ity_I64);
3652 IRTemp op2 = newTemp(Ity_I64);
3653
3654 assign(op1, get_gpr_dw0(r1));
3655 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
3656 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3657
3658 return "cgf";
3659}
3660
3661static HChar *
3662s390_irgen_CFI(UChar r1, UInt i2)
3663{
3664 IRTemp op1 = newTemp(Ity_I32);
3665 Int op2;
3666
3667 assign(op1, get_gpr_w1(r1));
3668 op2 = (Int)i2;
3669 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
3670 mkU32((UInt)op2)));
3671
3672 return "cfi";
3673}
3674
3675static HChar *
3676s390_irgen_CGFI(UChar r1, UInt i2)
3677{
3678 IRTemp op1 = newTemp(Ity_I64);
3679 Long op2;
3680
3681 assign(op1, get_gpr_dw0(r1));
3682 op2 = (Long)(Int)i2;
3683 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I64,
3684 mkU64((ULong)op2)));
3685
3686 return "cgfi";
3687}
3688
3689static HChar *
3690s390_irgen_CRL(UChar r1, UInt i2)
3691{
3692 IRTemp op1 = newTemp(Ity_I32);
3693 IRTemp op2 = newTemp(Ity_I32);
3694
3695 assign(op1, get_gpr_w1(r1));
3696 assign(op2, load(Ity_I32, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
3697 i2 << 1))));
3698 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3699
3700 return "crl";
3701}
3702
3703static HChar *
3704s390_irgen_CGRL(UChar r1, UInt i2)
3705{
3706 IRTemp op1 = newTemp(Ity_I64);
3707 IRTemp op2 = newTemp(Ity_I64);
3708
3709 assign(op1, get_gpr_dw0(r1));
3710 assign(op2, load(Ity_I64, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
3711 i2 << 1))));
3712 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3713
3714 return "cgrl";
3715}
3716
3717static HChar *
3718s390_irgen_CGFRL(UChar r1, UInt i2)
3719{
3720 IRTemp op1 = newTemp(Ity_I64);
3721 IRTemp op2 = newTemp(Ity_I64);
3722
3723 assign(op1, get_gpr_dw0(r1));
3724 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
3725 ((ULong)(Long)(Int)i2 << 1)))));
3726 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3727
3728 return "cgfrl";
3729}
3730
3731static HChar *
3732s390_irgen_CRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
3733{
3734 IRTemp op1 = newTemp(Ity_I32);
3735 IRTemp op2 = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00003736 IRTemp cond = newTemp(Ity_I32);
3737
3738 if (m3 == 0) {
3739 } else {
3740 if (m3 == 14) {
3741 always_goto(mkexpr(op4addr));
3742 } else {
3743 assign(op1, get_gpr_w1(r1));
3744 assign(op2, get_gpr_w1(r2));
florianff9613f2012-05-12 15:26:44 +00003745 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
3746 op1, op2));
florianf321da72012-07-21 20:32:57 +00003747 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond),
3748 mkU32(0)), mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00003749 }
3750 }
3751
3752 return "crb";
3753}
3754
3755static HChar *
3756s390_irgen_CGRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
3757{
3758 IRTemp op1 = newTemp(Ity_I64);
3759 IRTemp op2 = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00003760 IRTemp cond = newTemp(Ity_I32);
3761
3762 if (m3 == 0) {
3763 } else {
3764 if (m3 == 14) {
3765 always_goto(mkexpr(op4addr));
3766 } else {
3767 assign(op1, get_gpr_dw0(r1));
3768 assign(op2, get_gpr_dw0(r2));
florianff9613f2012-05-12 15:26:44 +00003769 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
3770 op1, op2));
florianf321da72012-07-21 20:32:57 +00003771 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond),
3772 mkU32(0)), mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00003773 }
3774 }
3775
3776 return "cgrb";
3777}
3778
3779static HChar *
3780s390_irgen_CRJ(UChar r1, UChar r2, UShort i4, UChar m3)
3781{
3782 IRTemp op1 = newTemp(Ity_I32);
3783 IRTemp op2 = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00003784 IRTemp cond = newTemp(Ity_I32);
3785
3786 if (m3 == 0) {
3787 } else {
3788 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00003789 always_goto_and_chase(
3790 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00003791 } else {
3792 assign(op1, get_gpr_w1(r1));
3793 assign(op2, get_gpr_w1(r2));
florianff9613f2012-05-12 15:26:44 +00003794 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
3795 op1, op2));
sewardj2019a972011-03-07 16:04:07 +00003796 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3797 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
3798
3799 }
3800 }
3801
3802 return "crj";
3803}
3804
3805static HChar *
3806s390_irgen_CGRJ(UChar r1, UChar r2, UShort i4, UChar m3)
3807{
3808 IRTemp op1 = newTemp(Ity_I64);
3809 IRTemp op2 = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00003810 IRTemp cond = newTemp(Ity_I32);
3811
3812 if (m3 == 0) {
3813 } else {
3814 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00003815 always_goto_and_chase(
3816 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00003817 } else {
3818 assign(op1, get_gpr_dw0(r1));
3819 assign(op2, get_gpr_dw0(r2));
florianff9613f2012-05-12 15:26:44 +00003820 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
3821 op1, op2));
sewardj2019a972011-03-07 16:04:07 +00003822 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3823 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
3824
3825 }
3826 }
3827
3828 return "cgrj";
3829}
3830
3831static HChar *
3832s390_irgen_CIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
3833{
3834 IRTemp op1 = newTemp(Ity_I32);
3835 Int op2;
sewardj2019a972011-03-07 16:04:07 +00003836 IRTemp cond = newTemp(Ity_I32);
3837
3838 if (m3 == 0) {
3839 } else {
3840 if (m3 == 14) {
3841 always_goto(mkexpr(op4addr));
3842 } else {
3843 assign(op1, get_gpr_w1(r1));
3844 op2 = (Int)(Char)i2;
florianff9613f2012-05-12 15:26:44 +00003845 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
3846 mktemp(Ity_I32, mkU32((UInt)op2))));
florianf321da72012-07-21 20:32:57 +00003847 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3848 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00003849 }
3850 }
3851
3852 return "cib";
3853}
3854
3855static HChar *
3856s390_irgen_CGIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
3857{
3858 IRTemp op1 = newTemp(Ity_I64);
3859 Long op2;
sewardj2019a972011-03-07 16:04:07 +00003860 IRTemp cond = newTemp(Ity_I32);
3861
3862 if (m3 == 0) {
3863 } else {
3864 if (m3 == 14) {
3865 always_goto(mkexpr(op4addr));
3866 } else {
3867 assign(op1, get_gpr_dw0(r1));
3868 op2 = (Long)(Char)i2;
florianff9613f2012-05-12 15:26:44 +00003869 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
3870 mktemp(Ity_I64, mkU64((ULong)op2))));
florianf321da72012-07-21 20:32:57 +00003871 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3872 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00003873 }
3874 }
3875
3876 return "cgib";
3877}
3878
3879static HChar *
3880s390_irgen_CIJ(UChar r1, UChar m3, UShort i4, UChar i2)
3881{
3882 IRTemp op1 = newTemp(Ity_I32);
3883 Int op2;
sewardj2019a972011-03-07 16:04:07 +00003884 IRTemp cond = newTemp(Ity_I32);
3885
3886 if (m3 == 0) {
3887 } else {
3888 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00003889 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00003890 } else {
3891 assign(op1, get_gpr_w1(r1));
3892 op2 = (Int)(Char)i2;
florianff9613f2012-05-12 15:26:44 +00003893 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
3894 mktemp(Ity_I32, mkU32((UInt)op2))));
sewardj2019a972011-03-07 16:04:07 +00003895 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3896 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
3897
3898 }
3899 }
3900
3901 return "cij";
3902}
3903
3904static HChar *
3905s390_irgen_CGIJ(UChar r1, UChar m3, UShort i4, UChar i2)
3906{
3907 IRTemp op1 = newTemp(Ity_I64);
3908 Long op2;
sewardj2019a972011-03-07 16:04:07 +00003909 IRTemp cond = newTemp(Ity_I32);
3910
3911 if (m3 == 0) {
3912 } else {
3913 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00003914 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00003915 } else {
3916 assign(op1, get_gpr_dw0(r1));
3917 op2 = (Long)(Char)i2;
florianff9613f2012-05-12 15:26:44 +00003918 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
3919 mktemp(Ity_I64, mkU64((ULong)op2))));
sewardj2019a972011-03-07 16:04:07 +00003920 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3921 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
3922
3923 }
3924 }
3925
3926 return "cgij";
3927}
3928
3929static HChar *
3930s390_irgen_CH(UChar r1, IRTemp op2addr)
3931{
3932 IRTemp op1 = newTemp(Ity_I32);
3933 IRTemp op2 = newTemp(Ity_I32);
3934
3935 assign(op1, get_gpr_w1(r1));
3936 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
3937 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3938
3939 return "ch";
3940}
3941
3942static HChar *
3943s390_irgen_CHY(UChar r1, IRTemp op2addr)
3944{
3945 IRTemp op1 = newTemp(Ity_I32);
3946 IRTemp op2 = newTemp(Ity_I32);
3947
3948 assign(op1, get_gpr_w1(r1));
3949 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
3950 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3951
3952 return "chy";
3953}
3954
3955static HChar *
3956s390_irgen_CGH(UChar r1, IRTemp op2addr)
3957{
3958 IRTemp op1 = newTemp(Ity_I64);
3959 IRTemp op2 = newTemp(Ity_I64);
3960
3961 assign(op1, get_gpr_dw0(r1));
3962 assign(op2, unop(Iop_16Sto64, load(Ity_I16, mkexpr(op2addr))));
3963 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3964
3965 return "cgh";
3966}
3967
3968static HChar *
3969s390_irgen_CHI(UChar r1, UShort i2)
3970{
3971 IRTemp op1 = newTemp(Ity_I32);
3972 Int op2;
3973
3974 assign(op1, get_gpr_w1(r1));
3975 op2 = (Int)(Short)i2;
3976 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
3977 mkU32((UInt)op2)));
3978
3979 return "chi";
3980}
3981
3982static HChar *
3983s390_irgen_CGHI(UChar r1, UShort i2)
3984{
3985 IRTemp op1 = newTemp(Ity_I64);
3986 Long op2;
3987
3988 assign(op1, get_gpr_dw0(r1));
3989 op2 = (Long)(Short)i2;
3990 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I64,
3991 mkU64((ULong)op2)));
3992
3993 return "cghi";
3994}
3995
3996static HChar *
3997s390_irgen_CHHSI(UShort i2, IRTemp op1addr)
3998{
3999 IRTemp op1 = newTemp(Ity_I16);
4000 Short op2;
4001
4002 assign(op1, load(Ity_I16, mkexpr(op1addr)));
4003 op2 = (Short)i2;
4004 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I16,
4005 mkU16((UShort)op2)));
4006
4007 return "chhsi";
4008}
4009
4010static HChar *
4011s390_irgen_CHSI(UShort i2, IRTemp op1addr)
4012{
4013 IRTemp op1 = newTemp(Ity_I32);
4014 Int op2;
4015
4016 assign(op1, load(Ity_I32, mkexpr(op1addr)));
4017 op2 = (Int)(Short)i2;
4018 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
4019 mkU32((UInt)op2)));
4020
4021 return "chsi";
4022}
4023
4024static HChar *
4025s390_irgen_CGHSI(UShort i2, IRTemp op1addr)
4026{
4027 IRTemp op1 = newTemp(Ity_I64);
4028 Long op2;
4029
4030 assign(op1, load(Ity_I64, mkexpr(op1addr)));
4031 op2 = (Long)(Short)i2;
4032 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I64,
4033 mkU64((ULong)op2)));
4034
4035 return "cghsi";
4036}
4037
4038static HChar *
4039s390_irgen_CHRL(UChar r1, UInt i2)
4040{
4041 IRTemp op1 = newTemp(Ity_I32);
4042 IRTemp op2 = newTemp(Ity_I32);
4043
4044 assign(op1, get_gpr_w1(r1));
4045 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
4046 ((ULong)(Long)(Int)i2 << 1)))));
4047 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4048
4049 return "chrl";
4050}
4051
4052static HChar *
4053s390_irgen_CGHRL(UChar r1, UInt i2)
4054{
4055 IRTemp op1 = newTemp(Ity_I64);
4056 IRTemp op2 = newTemp(Ity_I64);
4057
4058 assign(op1, get_gpr_dw0(r1));
4059 assign(op2, unop(Iop_16Sto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
4060 ((ULong)(Long)(Int)i2 << 1)))));
4061 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4062
4063 return "cghrl";
4064}
4065
4066static HChar *
4067s390_irgen_CHHR(UChar r1, UChar r2)
4068{
4069 IRTemp op1 = newTemp(Ity_I32);
4070 IRTemp op2 = newTemp(Ity_I32);
4071
4072 assign(op1, get_gpr_w0(r1));
4073 assign(op2, get_gpr_w0(r2));
4074 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4075
4076 return "chhr";
4077}
4078
4079static HChar *
4080s390_irgen_CHLR(UChar r1, UChar r2)
4081{
4082 IRTemp op1 = newTemp(Ity_I32);
4083 IRTemp op2 = newTemp(Ity_I32);
4084
4085 assign(op1, get_gpr_w0(r1));
4086 assign(op2, get_gpr_w1(r2));
4087 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4088
4089 return "chlr";
4090}
4091
4092static HChar *
4093s390_irgen_CHF(UChar r1, IRTemp op2addr)
4094{
4095 IRTemp op1 = newTemp(Ity_I32);
4096 IRTemp op2 = newTemp(Ity_I32);
4097
4098 assign(op1, get_gpr_w0(r1));
4099 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4100 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4101
4102 return "chf";
4103}
4104
4105static HChar *
4106s390_irgen_CIH(UChar r1, UInt i2)
4107{
4108 IRTemp op1 = newTemp(Ity_I32);
4109 Int op2;
4110
4111 assign(op1, get_gpr_w0(r1));
4112 op2 = (Int)i2;
4113 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
4114 mkU32((UInt)op2)));
4115
4116 return "cih";
4117}
4118
4119static HChar *
4120s390_irgen_CLR(UChar r1, UChar r2)
4121{
4122 IRTemp op1 = newTemp(Ity_I32);
4123 IRTemp op2 = newTemp(Ity_I32);
4124
4125 assign(op1, get_gpr_w1(r1));
4126 assign(op2, get_gpr_w1(r2));
4127 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4128
4129 return "clr";
4130}
4131
4132static HChar *
4133s390_irgen_CLGR(UChar r1, UChar r2)
4134{
4135 IRTemp op1 = newTemp(Ity_I64);
4136 IRTemp op2 = newTemp(Ity_I64);
4137
4138 assign(op1, get_gpr_dw0(r1));
4139 assign(op2, get_gpr_dw0(r2));
4140 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4141
4142 return "clgr";
4143}
4144
4145static HChar *
4146s390_irgen_CLGFR(UChar r1, UChar r2)
4147{
4148 IRTemp op1 = newTemp(Ity_I64);
4149 IRTemp op2 = newTemp(Ity_I64);
4150
4151 assign(op1, get_gpr_dw0(r1));
4152 assign(op2, unop(Iop_32Uto64, get_gpr_w1(r2)));
4153 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4154
4155 return "clgfr";
4156}
4157
4158static HChar *
4159s390_irgen_CL(UChar r1, IRTemp op2addr)
4160{
4161 IRTemp op1 = newTemp(Ity_I32);
4162 IRTemp op2 = newTemp(Ity_I32);
4163
4164 assign(op1, get_gpr_w1(r1));
4165 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4166 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4167
4168 return "cl";
4169}
4170
4171static HChar *
4172s390_irgen_CLY(UChar r1, IRTemp op2addr)
4173{
4174 IRTemp op1 = newTemp(Ity_I32);
4175 IRTemp op2 = newTemp(Ity_I32);
4176
4177 assign(op1, get_gpr_w1(r1));
4178 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4179 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4180
4181 return "cly";
4182}
4183
4184static HChar *
4185s390_irgen_CLG(UChar r1, IRTemp op2addr)
4186{
4187 IRTemp op1 = newTemp(Ity_I64);
4188 IRTemp op2 = newTemp(Ity_I64);
4189
4190 assign(op1, get_gpr_dw0(r1));
4191 assign(op2, load(Ity_I64, mkexpr(op2addr)));
4192 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4193
4194 return "clg";
4195}
4196
4197static HChar *
4198s390_irgen_CLGF(UChar r1, IRTemp op2addr)
4199{
4200 IRTemp op1 = newTemp(Ity_I64);
4201 IRTemp op2 = newTemp(Ity_I64);
4202
4203 assign(op1, get_gpr_dw0(r1));
4204 assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
4205 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4206
4207 return "clgf";
4208}
4209
4210static HChar *
4211s390_irgen_CLFI(UChar r1, UInt i2)
4212{
4213 IRTemp op1 = newTemp(Ity_I32);
4214 UInt op2;
4215
4216 assign(op1, get_gpr_w1(r1));
4217 op2 = i2;
4218 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I32,
4219 mkU32(op2)));
4220
4221 return "clfi";
4222}
4223
4224static HChar *
4225s390_irgen_CLGFI(UChar r1, UInt i2)
4226{
4227 IRTemp op1 = newTemp(Ity_I64);
4228 ULong op2;
4229
4230 assign(op1, get_gpr_dw0(r1));
4231 op2 = (ULong)i2;
4232 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I64,
4233 mkU64(op2)));
4234
4235 return "clgfi";
4236}
4237
4238static HChar *
4239s390_irgen_CLI(UChar i2, IRTemp op1addr)
4240{
4241 IRTemp op1 = newTemp(Ity_I8);
4242 UChar op2;
4243
4244 assign(op1, load(Ity_I8, mkexpr(op1addr)));
4245 op2 = i2;
4246 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I8,
4247 mkU8(op2)));
4248
4249 return "cli";
4250}
4251
4252static HChar *
4253s390_irgen_CLIY(UChar i2, IRTemp op1addr)
4254{
4255 IRTemp op1 = newTemp(Ity_I8);
4256 UChar op2;
4257
4258 assign(op1, load(Ity_I8, mkexpr(op1addr)));
4259 op2 = i2;
4260 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I8,
4261 mkU8(op2)));
4262
4263 return "cliy";
4264}
4265
4266static HChar *
4267s390_irgen_CLFHSI(UShort i2, IRTemp op1addr)
4268{
4269 IRTemp op1 = newTemp(Ity_I32);
4270 UInt op2;
4271
4272 assign(op1, load(Ity_I32, mkexpr(op1addr)));
4273 op2 = (UInt)i2;
4274 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I32,
4275 mkU32(op2)));
4276
4277 return "clfhsi";
4278}
4279
4280static HChar *
4281s390_irgen_CLGHSI(UShort i2, IRTemp op1addr)
4282{
4283 IRTemp op1 = newTemp(Ity_I64);
4284 ULong op2;
4285
4286 assign(op1, load(Ity_I64, mkexpr(op1addr)));
4287 op2 = (ULong)i2;
4288 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I64,
4289 mkU64(op2)));
4290
4291 return "clghsi";
4292}
4293
4294static HChar *
4295s390_irgen_CLHHSI(UShort i2, IRTemp op1addr)
4296{
4297 IRTemp op1 = newTemp(Ity_I16);
4298 UShort op2;
4299
4300 assign(op1, load(Ity_I16, mkexpr(op1addr)));
4301 op2 = i2;
4302 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I16,
4303 mkU16(op2)));
4304
4305 return "clhhsi";
4306}
4307
4308static HChar *
4309s390_irgen_CLRL(UChar r1, UInt i2)
4310{
4311 IRTemp op1 = newTemp(Ity_I32);
4312 IRTemp op2 = newTemp(Ity_I32);
4313
4314 assign(op1, get_gpr_w1(r1));
4315 assign(op2, load(Ity_I32, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
4316 i2 << 1))));
4317 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4318
4319 return "clrl";
4320}
4321
4322static HChar *
4323s390_irgen_CLGRL(UChar r1, UInt i2)
4324{
4325 IRTemp op1 = newTemp(Ity_I64);
4326 IRTemp op2 = newTemp(Ity_I64);
4327
4328 assign(op1, get_gpr_dw0(r1));
4329 assign(op2, load(Ity_I64, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
4330 i2 << 1))));
4331 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4332
4333 return "clgrl";
4334}
4335
4336static HChar *
4337s390_irgen_CLGFRL(UChar r1, UInt i2)
4338{
4339 IRTemp op1 = newTemp(Ity_I64);
4340 IRTemp op2 = newTemp(Ity_I64);
4341
4342 assign(op1, get_gpr_dw0(r1));
4343 assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
4344 ((ULong)(Long)(Int)i2 << 1)))));
4345 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4346
4347 return "clgfrl";
4348}
4349
4350static HChar *
4351s390_irgen_CLHRL(UChar r1, UInt i2)
4352{
4353 IRTemp op1 = newTemp(Ity_I32);
4354 IRTemp op2 = newTemp(Ity_I32);
4355
4356 assign(op1, get_gpr_w1(r1));
4357 assign(op2, unop(Iop_16Uto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
4358 ((ULong)(Long)(Int)i2 << 1)))));
4359 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4360
4361 return "clhrl";
4362}
4363
4364static HChar *
4365s390_irgen_CLGHRL(UChar r1, UInt i2)
4366{
4367 IRTemp op1 = newTemp(Ity_I64);
4368 IRTemp op2 = newTemp(Ity_I64);
4369
4370 assign(op1, get_gpr_dw0(r1));
4371 assign(op2, unop(Iop_16Uto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
4372 ((ULong)(Long)(Int)i2 << 1)))));
4373 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4374
4375 return "clghrl";
4376}
4377
4378static HChar *
4379s390_irgen_CLRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
4380{
4381 IRTemp op1 = newTemp(Ity_I32);
4382 IRTemp op2 = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00004383 IRTemp cond = newTemp(Ity_I32);
4384
4385 if (m3 == 0) {
4386 } else {
4387 if (m3 == 14) {
4388 always_goto(mkexpr(op4addr));
4389 } else {
4390 assign(op1, get_gpr_w1(r1));
4391 assign(op2, get_gpr_w1(r2));
florianff9613f2012-05-12 15:26:44 +00004392 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4393 op1, op2));
florianf321da72012-07-21 20:32:57 +00004394 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4395 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004396 }
4397 }
4398
4399 return "clrb";
4400}
4401
4402static HChar *
4403s390_irgen_CLGRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
4404{
4405 IRTemp op1 = newTemp(Ity_I64);
4406 IRTemp op2 = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00004407 IRTemp cond = newTemp(Ity_I32);
4408
4409 if (m3 == 0) {
4410 } else {
4411 if (m3 == 14) {
4412 always_goto(mkexpr(op4addr));
4413 } else {
4414 assign(op1, get_gpr_dw0(r1));
4415 assign(op2, get_gpr_dw0(r2));
florianff9613f2012-05-12 15:26:44 +00004416 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4417 op1, op2));
florianf321da72012-07-21 20:32:57 +00004418 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4419 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004420 }
4421 }
4422
4423 return "clgrb";
4424}
4425
4426static HChar *
4427s390_irgen_CLRJ(UChar r1, UChar r2, UShort i4, UChar m3)
4428{
4429 IRTemp op1 = newTemp(Ity_I32);
4430 IRTemp op2 = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00004431 IRTemp cond = newTemp(Ity_I32);
4432
4433 if (m3 == 0) {
4434 } else {
4435 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004436 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004437 } else {
4438 assign(op1, get_gpr_w1(r1));
4439 assign(op2, get_gpr_w1(r2));
florianff9613f2012-05-12 15:26:44 +00004440 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4441 op1, op2));
sewardj2019a972011-03-07 16:04:07 +00004442 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4443 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4444
4445 }
4446 }
4447
4448 return "clrj";
4449}
4450
4451static HChar *
4452s390_irgen_CLGRJ(UChar r1, UChar r2, UShort i4, UChar m3)
4453{
4454 IRTemp op1 = newTemp(Ity_I64);
4455 IRTemp op2 = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00004456 IRTemp cond = newTemp(Ity_I32);
4457
4458 if (m3 == 0) {
4459 } else {
4460 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004461 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004462 } else {
4463 assign(op1, get_gpr_dw0(r1));
4464 assign(op2, get_gpr_dw0(r2));
florianff9613f2012-05-12 15:26:44 +00004465 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4466 op1, op2));
sewardj2019a972011-03-07 16:04:07 +00004467 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4468 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4469
4470 }
4471 }
4472
4473 return "clgrj";
4474}
4475
4476static HChar *
4477s390_irgen_CLIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
4478{
4479 IRTemp op1 = newTemp(Ity_I32);
4480 UInt op2;
sewardj2019a972011-03-07 16:04:07 +00004481 IRTemp cond = newTemp(Ity_I32);
4482
4483 if (m3 == 0) {
4484 } else {
4485 if (m3 == 14) {
4486 always_goto(mkexpr(op4addr));
4487 } else {
4488 assign(op1, get_gpr_w1(r1));
4489 op2 = (UInt)i2;
florianff9613f2012-05-12 15:26:44 +00004490 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4491 mktemp(Ity_I32, mkU32(op2))));
florianf321da72012-07-21 20:32:57 +00004492 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4493 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004494 }
4495 }
4496
4497 return "clib";
4498}
4499
4500static HChar *
4501s390_irgen_CLGIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
4502{
4503 IRTemp op1 = newTemp(Ity_I64);
4504 ULong op2;
sewardj2019a972011-03-07 16:04:07 +00004505 IRTemp cond = newTemp(Ity_I32);
4506
4507 if (m3 == 0) {
4508 } else {
4509 if (m3 == 14) {
4510 always_goto(mkexpr(op4addr));
4511 } else {
4512 assign(op1, get_gpr_dw0(r1));
4513 op2 = (ULong)i2;
florianff9613f2012-05-12 15:26:44 +00004514 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4515 mktemp(Ity_I64, mkU64(op2))));
florianf321da72012-07-21 20:32:57 +00004516 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4517 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004518 }
4519 }
4520
4521 return "clgib";
4522}
4523
4524static HChar *
4525s390_irgen_CLIJ(UChar r1, UChar m3, UShort i4, UChar i2)
4526{
4527 IRTemp op1 = newTemp(Ity_I32);
4528 UInt op2;
sewardj2019a972011-03-07 16:04:07 +00004529 IRTemp cond = newTemp(Ity_I32);
4530
4531 if (m3 == 0) {
4532 } else {
4533 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004534 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004535 } else {
4536 assign(op1, get_gpr_w1(r1));
4537 op2 = (UInt)i2;
florianff9613f2012-05-12 15:26:44 +00004538 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4539 mktemp(Ity_I32, mkU32(op2))));
sewardj2019a972011-03-07 16:04:07 +00004540 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4541 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4542
4543 }
4544 }
4545
4546 return "clij";
4547}
4548
4549static HChar *
4550s390_irgen_CLGIJ(UChar r1, UChar m3, UShort i4, UChar i2)
4551{
4552 IRTemp op1 = newTemp(Ity_I64);
4553 ULong op2;
sewardj2019a972011-03-07 16:04:07 +00004554 IRTemp cond = newTemp(Ity_I32);
4555
4556 if (m3 == 0) {
4557 } else {
4558 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004559 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004560 } else {
4561 assign(op1, get_gpr_dw0(r1));
4562 op2 = (ULong)i2;
florianff9613f2012-05-12 15:26:44 +00004563 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4564 mktemp(Ity_I64, mkU64(op2))));
sewardj2019a972011-03-07 16:04:07 +00004565 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4566 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4567
4568 }
4569 }
4570
4571 return "clgij";
4572}
4573
4574static HChar *
4575s390_irgen_CLM(UChar r1, UChar r3, IRTemp op2addr)
4576{
4577 IRTemp op1 = newTemp(Ity_I32);
4578 IRTemp op2 = newTemp(Ity_I32);
4579 IRTemp b0 = newTemp(Ity_I32);
4580 IRTemp b1 = newTemp(Ity_I32);
4581 IRTemp b2 = newTemp(Ity_I32);
4582 IRTemp b3 = newTemp(Ity_I32);
4583 IRTemp c0 = newTemp(Ity_I32);
4584 IRTemp c1 = newTemp(Ity_I32);
4585 IRTemp c2 = newTemp(Ity_I32);
4586 IRTemp c3 = newTemp(Ity_I32);
4587 UChar n;
4588
4589 n = 0;
4590 if ((r3 & 8) != 0) {
4591 assign(b0, unop(Iop_8Uto32, get_gpr_b4(r1)));
4592 assign(c0, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
4593 n = n + 1;
4594 } else {
4595 assign(b0, mkU32(0));
4596 assign(c0, mkU32(0));
4597 }
4598 if ((r3 & 4) != 0) {
4599 assign(b1, unop(Iop_8Uto32, get_gpr_b5(r1)));
4600 assign(c1, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4601 mkU64(n)))));
4602 n = n + 1;
4603 } else {
4604 assign(b1, mkU32(0));
4605 assign(c1, mkU32(0));
4606 }
4607 if ((r3 & 2) != 0) {
4608 assign(b2, unop(Iop_8Uto32, get_gpr_b6(r1)));
4609 assign(c2, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4610 mkU64(n)))));
4611 n = n + 1;
4612 } else {
4613 assign(b2, mkU32(0));
4614 assign(c2, mkU32(0));
4615 }
4616 if ((r3 & 1) != 0) {
4617 assign(b3, unop(Iop_8Uto32, get_gpr_b7(r1)));
4618 assign(c3, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4619 mkU64(n)))));
4620 n = n + 1;
4621 } else {
4622 assign(b3, mkU32(0));
4623 assign(c3, mkU32(0));
4624 }
4625 assign(op1, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4626 mkexpr(b0), mkU8(24)), binop(Iop_Shl32, mkexpr(b1), mkU8(16))),
4627 binop(Iop_Shl32, mkexpr(b2), mkU8(8))), mkexpr(b3)));
4628 assign(op2, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4629 mkexpr(c0), mkU8(24)), binop(Iop_Shl32, mkexpr(c1), mkU8(16))),
4630 binop(Iop_Shl32, mkexpr(c2), mkU8(8))), mkexpr(c3)));
4631 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4632
4633 return "clm";
4634}
4635
4636static HChar *
4637s390_irgen_CLMY(UChar r1, UChar r3, IRTemp op2addr)
4638{
4639 IRTemp op1 = newTemp(Ity_I32);
4640 IRTemp op2 = newTemp(Ity_I32);
4641 IRTemp b0 = newTemp(Ity_I32);
4642 IRTemp b1 = newTemp(Ity_I32);
4643 IRTemp b2 = newTemp(Ity_I32);
4644 IRTemp b3 = newTemp(Ity_I32);
4645 IRTemp c0 = newTemp(Ity_I32);
4646 IRTemp c1 = newTemp(Ity_I32);
4647 IRTemp c2 = newTemp(Ity_I32);
4648 IRTemp c3 = newTemp(Ity_I32);
4649 UChar n;
4650
4651 n = 0;
4652 if ((r3 & 8) != 0) {
4653 assign(b0, unop(Iop_8Uto32, get_gpr_b4(r1)));
4654 assign(c0, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
4655 n = n + 1;
4656 } else {
4657 assign(b0, mkU32(0));
4658 assign(c0, mkU32(0));
4659 }
4660 if ((r3 & 4) != 0) {
4661 assign(b1, unop(Iop_8Uto32, get_gpr_b5(r1)));
4662 assign(c1, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4663 mkU64(n)))));
4664 n = n + 1;
4665 } else {
4666 assign(b1, mkU32(0));
4667 assign(c1, mkU32(0));
4668 }
4669 if ((r3 & 2) != 0) {
4670 assign(b2, unop(Iop_8Uto32, get_gpr_b6(r1)));
4671 assign(c2, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4672 mkU64(n)))));
4673 n = n + 1;
4674 } else {
4675 assign(b2, mkU32(0));
4676 assign(c2, mkU32(0));
4677 }
4678 if ((r3 & 1) != 0) {
4679 assign(b3, unop(Iop_8Uto32, get_gpr_b7(r1)));
4680 assign(c3, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4681 mkU64(n)))));
4682 n = n + 1;
4683 } else {
4684 assign(b3, mkU32(0));
4685 assign(c3, mkU32(0));
4686 }
4687 assign(op1, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4688 mkexpr(b0), mkU8(24)), binop(Iop_Shl32, mkexpr(b1), mkU8(16))),
4689 binop(Iop_Shl32, mkexpr(b2), mkU8(8))), mkexpr(b3)));
4690 assign(op2, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4691 mkexpr(c0), mkU8(24)), binop(Iop_Shl32, mkexpr(c1), mkU8(16))),
4692 binop(Iop_Shl32, mkexpr(c2), mkU8(8))), mkexpr(c3)));
4693 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4694
4695 return "clmy";
4696}
4697
4698static HChar *
4699s390_irgen_CLMH(UChar r1, UChar r3, IRTemp op2addr)
4700{
4701 IRTemp op1 = newTemp(Ity_I32);
4702 IRTemp op2 = newTemp(Ity_I32);
4703 IRTemp b0 = newTemp(Ity_I32);
4704 IRTemp b1 = newTemp(Ity_I32);
4705 IRTemp b2 = newTemp(Ity_I32);
4706 IRTemp b3 = newTemp(Ity_I32);
4707 IRTemp c0 = newTemp(Ity_I32);
4708 IRTemp c1 = newTemp(Ity_I32);
4709 IRTemp c2 = newTemp(Ity_I32);
4710 IRTemp c3 = newTemp(Ity_I32);
4711 UChar n;
4712
4713 n = 0;
4714 if ((r3 & 8) != 0) {
4715 assign(b0, unop(Iop_8Uto32, get_gpr_b0(r1)));
4716 assign(c0, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
4717 n = n + 1;
4718 } else {
4719 assign(b0, mkU32(0));
4720 assign(c0, mkU32(0));
4721 }
4722 if ((r3 & 4) != 0) {
4723 assign(b1, unop(Iop_8Uto32, get_gpr_b1(r1)));
4724 assign(c1, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4725 mkU64(n)))));
4726 n = n + 1;
4727 } else {
4728 assign(b1, mkU32(0));
4729 assign(c1, mkU32(0));
4730 }
4731 if ((r3 & 2) != 0) {
4732 assign(b2, unop(Iop_8Uto32, get_gpr_b2(r1)));
4733 assign(c2, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4734 mkU64(n)))));
4735 n = n + 1;
4736 } else {
4737 assign(b2, mkU32(0));
4738 assign(c2, mkU32(0));
4739 }
4740 if ((r3 & 1) != 0) {
4741 assign(b3, unop(Iop_8Uto32, get_gpr_b3(r1)));
4742 assign(c3, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4743 mkU64(n)))));
4744 n = n + 1;
4745 } else {
4746 assign(b3, mkU32(0));
4747 assign(c3, mkU32(0));
4748 }
4749 assign(op1, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4750 mkexpr(b0), mkU8(24)), binop(Iop_Shl32, mkexpr(b1), mkU8(16))),
4751 binop(Iop_Shl32, mkexpr(b2), mkU8(8))), mkexpr(b3)));
4752 assign(op2, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4753 mkexpr(c0), mkU8(24)), binop(Iop_Shl32, mkexpr(c1), mkU8(16))),
4754 binop(Iop_Shl32, mkexpr(c2), mkU8(8))), mkexpr(c3)));
4755 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4756
4757 return "clmh";
4758}
4759
4760static HChar *
4761s390_irgen_CLHHR(UChar r1, UChar r2)
4762{
4763 IRTemp op1 = newTemp(Ity_I32);
4764 IRTemp op2 = newTemp(Ity_I32);
4765
4766 assign(op1, get_gpr_w0(r1));
4767 assign(op2, get_gpr_w0(r2));
4768 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4769
4770 return "clhhr";
4771}
4772
4773static HChar *
4774s390_irgen_CLHLR(UChar r1, UChar r2)
4775{
4776 IRTemp op1 = newTemp(Ity_I32);
4777 IRTemp op2 = newTemp(Ity_I32);
4778
4779 assign(op1, get_gpr_w0(r1));
4780 assign(op2, get_gpr_w1(r2));
4781 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4782
4783 return "clhlr";
4784}
4785
4786static HChar *
4787s390_irgen_CLHF(UChar r1, IRTemp op2addr)
4788{
4789 IRTemp op1 = newTemp(Ity_I32);
4790 IRTemp op2 = newTemp(Ity_I32);
4791
4792 assign(op1, get_gpr_w0(r1));
4793 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4794 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4795
4796 return "clhf";
4797}
4798
4799static HChar *
4800s390_irgen_CLIH(UChar r1, UInt i2)
4801{
4802 IRTemp op1 = newTemp(Ity_I32);
4803 UInt op2;
4804
4805 assign(op1, get_gpr_w0(r1));
4806 op2 = i2;
4807 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I32,
4808 mkU32(op2)));
4809
4810 return "clih";
4811}
4812
4813static HChar *
4814s390_irgen_CPYA(UChar r1, UChar r2)
4815{
4816 put_ar_w0(r1, get_ar_w0(r2));
sewardj7ee97522011-05-09 21:45:04 +00004817 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00004818 s390_disasm(ENC3(MNM, AR, AR), "cpya", r1, r2);
4819
4820 return "cpya";
4821}
4822
4823static HChar *
4824s390_irgen_XR(UChar r1, UChar r2)
4825{
4826 IRTemp op1 = newTemp(Ity_I32);
4827 IRTemp op2 = newTemp(Ity_I32);
4828 IRTemp result = newTemp(Ity_I32);
4829
4830 if (r1 == r2) {
4831 assign(result, mkU32(0));
4832 } else {
4833 assign(op1, get_gpr_w1(r1));
4834 assign(op2, get_gpr_w1(r2));
4835 assign(result, binop(Iop_Xor32, mkexpr(op1), mkexpr(op2)));
4836 }
4837 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4838 put_gpr_w1(r1, mkexpr(result));
4839
4840 return "xr";
4841}
4842
4843static HChar *
4844s390_irgen_XGR(UChar r1, UChar r2)
4845{
4846 IRTemp op1 = newTemp(Ity_I64);
4847 IRTemp op2 = newTemp(Ity_I64);
4848 IRTemp result = newTemp(Ity_I64);
4849
4850 if (r1 == r2) {
4851 assign(result, mkU64(0));
4852 } else {
4853 assign(op1, get_gpr_dw0(r1));
4854 assign(op2, get_gpr_dw0(r2));
4855 assign(result, binop(Iop_Xor64, mkexpr(op1), mkexpr(op2)));
4856 }
4857 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4858 put_gpr_dw0(r1, mkexpr(result));
4859
4860 return "xgr";
4861}
4862
4863static HChar *
4864s390_irgen_XRK(UChar r3, UChar r1, UChar r2)
4865{
4866 IRTemp op2 = newTemp(Ity_I32);
4867 IRTemp op3 = newTemp(Ity_I32);
4868 IRTemp result = newTemp(Ity_I32);
4869
4870 assign(op2, get_gpr_w1(r2));
4871 assign(op3, get_gpr_w1(r3));
4872 assign(result, binop(Iop_Xor32, mkexpr(op2), mkexpr(op3)));
4873 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4874 put_gpr_w1(r1, mkexpr(result));
4875
4876 return "xrk";
4877}
4878
4879static HChar *
4880s390_irgen_XGRK(UChar r3, UChar r1, UChar r2)
4881{
4882 IRTemp op2 = newTemp(Ity_I64);
4883 IRTemp op3 = newTemp(Ity_I64);
4884 IRTemp result = newTemp(Ity_I64);
4885
4886 assign(op2, get_gpr_dw0(r2));
4887 assign(op3, get_gpr_dw0(r3));
4888 assign(result, binop(Iop_Xor64, mkexpr(op2), mkexpr(op3)));
4889 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4890 put_gpr_dw0(r1, mkexpr(result));
4891
4892 return "xgrk";
4893}
4894
4895static HChar *
4896s390_irgen_X(UChar r1, IRTemp op2addr)
4897{
4898 IRTemp op1 = newTemp(Ity_I32);
4899 IRTemp op2 = newTemp(Ity_I32);
4900 IRTemp result = newTemp(Ity_I32);
4901
4902 assign(op1, get_gpr_w1(r1));
4903 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4904 assign(result, binop(Iop_Xor32, mkexpr(op1), mkexpr(op2)));
4905 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4906 put_gpr_w1(r1, mkexpr(result));
4907
4908 return "x";
4909}
4910
4911static HChar *
4912s390_irgen_XY(UChar r1, IRTemp op2addr)
4913{
4914 IRTemp op1 = newTemp(Ity_I32);
4915 IRTemp op2 = newTemp(Ity_I32);
4916 IRTemp result = newTemp(Ity_I32);
4917
4918 assign(op1, get_gpr_w1(r1));
4919 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4920 assign(result, binop(Iop_Xor32, mkexpr(op1), mkexpr(op2)));
4921 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4922 put_gpr_w1(r1, mkexpr(result));
4923
4924 return "xy";
4925}
4926
4927static HChar *
4928s390_irgen_XG(UChar r1, IRTemp op2addr)
4929{
4930 IRTemp op1 = newTemp(Ity_I64);
4931 IRTemp op2 = newTemp(Ity_I64);
4932 IRTemp result = newTemp(Ity_I64);
4933
4934 assign(op1, get_gpr_dw0(r1));
4935 assign(op2, load(Ity_I64, mkexpr(op2addr)));
4936 assign(result, binop(Iop_Xor64, mkexpr(op1), mkexpr(op2)));
4937 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4938 put_gpr_dw0(r1, mkexpr(result));
4939
4940 return "xg";
4941}
4942
4943static HChar *
4944s390_irgen_XI(UChar i2, IRTemp op1addr)
4945{
4946 IRTemp op1 = newTemp(Ity_I8);
4947 UChar op2;
4948 IRTemp result = newTemp(Ity_I8);
4949
4950 assign(op1, load(Ity_I8, mkexpr(op1addr)));
4951 op2 = i2;
4952 assign(result, binop(Iop_Xor8, mkexpr(op1), mkU8(op2)));
4953 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4954 store(mkexpr(op1addr), mkexpr(result));
4955
4956 return "xi";
4957}
4958
4959static HChar *
4960s390_irgen_XIY(UChar i2, IRTemp op1addr)
4961{
4962 IRTemp op1 = newTemp(Ity_I8);
4963 UChar op2;
4964 IRTemp result = newTemp(Ity_I8);
4965
4966 assign(op1, load(Ity_I8, mkexpr(op1addr)));
4967 op2 = i2;
4968 assign(result, binop(Iop_Xor8, mkexpr(op1), mkU8(op2)));
4969 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4970 store(mkexpr(op1addr), mkexpr(result));
4971
4972 return "xiy";
4973}
4974
4975static HChar *
4976s390_irgen_XIHF(UChar r1, UInt i2)
4977{
4978 IRTemp op1 = newTemp(Ity_I32);
4979 UInt op2;
4980 IRTemp result = newTemp(Ity_I32);
4981
4982 assign(op1, get_gpr_w0(r1));
4983 op2 = i2;
4984 assign(result, binop(Iop_Xor32, mkexpr(op1), mkU32(op2)));
4985 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4986 put_gpr_w0(r1, mkexpr(result));
4987
4988 return "xihf";
4989}
4990
4991static HChar *
4992s390_irgen_XILF(UChar r1, UInt i2)
4993{
4994 IRTemp op1 = newTemp(Ity_I32);
4995 UInt op2;
4996 IRTemp result = newTemp(Ity_I32);
4997
4998 assign(op1, get_gpr_w1(r1));
4999 op2 = i2;
5000 assign(result, binop(Iop_Xor32, mkexpr(op1), mkU32(op2)));
5001 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5002 put_gpr_w1(r1, mkexpr(result));
5003
5004 return "xilf";
5005}
5006
5007static HChar *
5008s390_irgen_EAR(UChar r1, UChar r2)
5009{
5010 put_gpr_w1(r1, get_ar_w0(r2));
sewardj7ee97522011-05-09 21:45:04 +00005011 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00005012 s390_disasm(ENC3(MNM, GPR, AR), "ear", r1, r2);
5013
5014 return "ear";
5015}
5016
5017static HChar *
5018s390_irgen_IC(UChar r1, IRTemp op2addr)
5019{
5020 put_gpr_b7(r1, load(Ity_I8, mkexpr(op2addr)));
5021
5022 return "ic";
5023}
5024
5025static HChar *
5026s390_irgen_ICY(UChar r1, IRTemp op2addr)
5027{
5028 put_gpr_b7(r1, load(Ity_I8, mkexpr(op2addr)));
5029
5030 return "icy";
5031}
5032
5033static HChar *
5034s390_irgen_ICM(UChar r1, UChar r3, IRTemp op2addr)
5035{
5036 UChar n;
5037 IRTemp result = newTemp(Ity_I32);
5038 UInt mask;
5039
5040 n = 0;
5041 mask = (UInt)r3;
5042 if ((mask & 8) != 0) {
5043 put_gpr_b4(r1, load(Ity_I8, mkexpr(op2addr)));
5044 n = n + 1;
5045 }
5046 if ((mask & 4) != 0) {
5047 put_gpr_b5(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5048
5049 n = n + 1;
5050 }
5051 if ((mask & 2) != 0) {
5052 put_gpr_b6(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5053
5054 n = n + 1;
5055 }
5056 if ((mask & 1) != 0) {
5057 put_gpr_b7(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5058
5059 n = n + 1;
5060 }
5061 assign(result, get_gpr_w1(r1));
5062 s390_cc_thunk_putZZ(S390_CC_OP_INSERT_CHAR_MASK_32, result, mktemp(Ity_I32,
5063 mkU32(mask)));
5064
5065 return "icm";
5066}
5067
5068static HChar *
5069s390_irgen_ICMY(UChar r1, UChar r3, IRTemp op2addr)
5070{
5071 UChar n;
5072 IRTemp result = newTemp(Ity_I32);
5073 UInt mask;
5074
5075 n = 0;
5076 mask = (UInt)r3;
5077 if ((mask & 8) != 0) {
5078 put_gpr_b4(r1, load(Ity_I8, mkexpr(op2addr)));
5079 n = n + 1;
5080 }
5081 if ((mask & 4) != 0) {
5082 put_gpr_b5(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5083
5084 n = n + 1;
5085 }
5086 if ((mask & 2) != 0) {
5087 put_gpr_b6(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5088
5089 n = n + 1;
5090 }
5091 if ((mask & 1) != 0) {
5092 put_gpr_b7(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5093
5094 n = n + 1;
5095 }
5096 assign(result, get_gpr_w1(r1));
5097 s390_cc_thunk_putZZ(S390_CC_OP_INSERT_CHAR_MASK_32, result, mktemp(Ity_I32,
5098 mkU32(mask)));
5099
5100 return "icmy";
5101}
5102
5103static HChar *
5104s390_irgen_ICMH(UChar r1, UChar r3, IRTemp op2addr)
5105{
5106 UChar n;
5107 IRTemp result = newTemp(Ity_I32);
5108 UInt mask;
5109
5110 n = 0;
5111 mask = (UInt)r3;
5112 if ((mask & 8) != 0) {
5113 put_gpr_b0(r1, load(Ity_I8, mkexpr(op2addr)));
5114 n = n + 1;
5115 }
5116 if ((mask & 4) != 0) {
5117 put_gpr_b1(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5118
5119 n = n + 1;
5120 }
5121 if ((mask & 2) != 0) {
5122 put_gpr_b2(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5123
5124 n = n + 1;
5125 }
5126 if ((mask & 1) != 0) {
5127 put_gpr_b3(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5128
5129 n = n + 1;
5130 }
5131 assign(result, get_gpr_w0(r1));
5132 s390_cc_thunk_putZZ(S390_CC_OP_INSERT_CHAR_MASK_32, result, mktemp(Ity_I32,
5133 mkU32(mask)));
5134
5135 return "icmh";
5136}
5137
5138static HChar *
5139s390_irgen_IIHF(UChar r1, UInt i2)
5140{
5141 put_gpr_w0(r1, mkU32(i2));
5142
5143 return "iihf";
5144}
5145
5146static HChar *
5147s390_irgen_IIHH(UChar r1, UShort i2)
5148{
5149 put_gpr_hw0(r1, mkU16(i2));
5150
5151 return "iihh";
5152}
5153
5154static HChar *
5155s390_irgen_IIHL(UChar r1, UShort i2)
5156{
5157 put_gpr_hw1(r1, mkU16(i2));
5158
5159 return "iihl";
5160}
5161
5162static HChar *
5163s390_irgen_IILF(UChar r1, UInt i2)
5164{
5165 put_gpr_w1(r1, mkU32(i2));
5166
5167 return "iilf";
5168}
5169
5170static HChar *
5171s390_irgen_IILH(UChar r1, UShort i2)
5172{
5173 put_gpr_hw2(r1, mkU16(i2));
5174
5175 return "iilh";
5176}
5177
5178static HChar *
5179s390_irgen_IILL(UChar r1, UShort i2)
5180{
5181 put_gpr_hw3(r1, mkU16(i2));
5182
5183 return "iill";
5184}
5185
5186static HChar *
5187s390_irgen_LR(UChar r1, UChar r2)
5188{
5189 put_gpr_w1(r1, get_gpr_w1(r2));
5190
5191 return "lr";
5192}
5193
5194static HChar *
5195s390_irgen_LGR(UChar r1, UChar r2)
5196{
5197 put_gpr_dw0(r1, get_gpr_dw0(r2));
5198
5199 return "lgr";
5200}
5201
5202static HChar *
5203s390_irgen_LGFR(UChar r1, UChar r2)
5204{
5205 put_gpr_dw0(r1, unop(Iop_32Sto64, get_gpr_w1(r2)));
5206
5207 return "lgfr";
5208}
5209
5210static HChar *
5211s390_irgen_L(UChar r1, IRTemp op2addr)
5212{
5213 put_gpr_w1(r1, load(Ity_I32, mkexpr(op2addr)));
5214
5215 return "l";
5216}
5217
5218static HChar *
5219s390_irgen_LY(UChar r1, IRTemp op2addr)
5220{
5221 put_gpr_w1(r1, load(Ity_I32, mkexpr(op2addr)));
5222
5223 return "ly";
5224}
5225
5226static HChar *
5227s390_irgen_LG(UChar r1, IRTemp op2addr)
5228{
5229 put_gpr_dw0(r1, load(Ity_I64, mkexpr(op2addr)));
5230
5231 return "lg";
5232}
5233
5234static HChar *
5235s390_irgen_LGF(UChar r1, IRTemp op2addr)
5236{
5237 put_gpr_dw0(r1, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
5238
5239 return "lgf";
5240}
5241
5242static HChar *
5243s390_irgen_LGFI(UChar r1, UInt i2)
5244{
5245 put_gpr_dw0(r1, mkU64((ULong)(Long)(Int)i2));
5246
5247 return "lgfi";
5248}
5249
5250static HChar *
5251s390_irgen_LRL(UChar r1, UInt i2)
5252{
5253 put_gpr_w1(r1, load(Ity_I32, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
5254 i2 << 1))));
5255
5256 return "lrl";
5257}
5258
5259static HChar *
5260s390_irgen_LGRL(UChar r1, UInt i2)
5261{
5262 put_gpr_dw0(r1, load(Ity_I64, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
5263 i2 << 1))));
5264
5265 return "lgrl";
5266}
5267
5268static HChar *
5269s390_irgen_LGFRL(UChar r1, UInt i2)
5270{
5271 put_gpr_dw0(r1, unop(Iop_32Sto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
5272 ((ULong)(Long)(Int)i2 << 1)))));
5273
5274 return "lgfrl";
5275}
5276
5277static HChar *
5278s390_irgen_LA(UChar r1, IRTemp op2addr)
5279{
5280 put_gpr_dw0(r1, mkexpr(op2addr));
5281
5282 return "la";
5283}
5284
5285static HChar *
5286s390_irgen_LAY(UChar r1, IRTemp op2addr)
5287{
5288 put_gpr_dw0(r1, mkexpr(op2addr));
5289
5290 return "lay";
5291}
5292
5293static HChar *
5294s390_irgen_LAE(UChar r1, IRTemp op2addr)
5295{
5296 put_gpr_dw0(r1, mkexpr(op2addr));
5297
5298 return "lae";
5299}
5300
5301static HChar *
5302s390_irgen_LAEY(UChar r1, IRTemp op2addr)
5303{
5304 put_gpr_dw0(r1, mkexpr(op2addr));
5305
5306 return "laey";
5307}
5308
5309static HChar *
5310s390_irgen_LARL(UChar r1, UInt i2)
5311{
5312 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)));
5313
5314 return "larl";
5315}
5316
5317static HChar *
5318s390_irgen_LAA(UChar r1, UChar r3, IRTemp op2addr)
5319{
5320 IRTemp op2 = newTemp(Ity_I32);
5321 IRTemp op3 = newTemp(Ity_I32);
5322 IRTemp result = newTemp(Ity_I32);
5323
5324 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5325 assign(op3, get_gpr_w1(r3));
5326 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
5327 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
5328 store(mkexpr(op2addr), mkexpr(result));
5329 put_gpr_w1(r1, mkexpr(op2));
5330
5331 return "laa";
5332}
5333
5334static HChar *
5335s390_irgen_LAAG(UChar r1, UChar r3, IRTemp op2addr)
5336{
5337 IRTemp op2 = newTemp(Ity_I64);
5338 IRTemp op3 = newTemp(Ity_I64);
5339 IRTemp result = newTemp(Ity_I64);
5340
5341 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5342 assign(op3, get_gpr_dw0(r3));
5343 assign(result, binop(Iop_Add64, mkexpr(op2), mkexpr(op3)));
5344 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op2, op3);
5345 store(mkexpr(op2addr), mkexpr(result));
5346 put_gpr_dw0(r1, mkexpr(op2));
5347
5348 return "laag";
5349}
5350
5351static HChar *
5352s390_irgen_LAAL(UChar r1, UChar r3, IRTemp op2addr)
5353{
5354 IRTemp op2 = newTemp(Ity_I32);
5355 IRTemp op3 = newTemp(Ity_I32);
5356 IRTemp result = newTemp(Ity_I32);
5357
5358 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5359 assign(op3, get_gpr_w1(r3));
5360 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
5361 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
5362 store(mkexpr(op2addr), mkexpr(result));
5363 put_gpr_w1(r1, mkexpr(op2));
5364
5365 return "laal";
5366}
5367
5368static HChar *
5369s390_irgen_LAALG(UChar r1, UChar r3, IRTemp op2addr)
5370{
5371 IRTemp op2 = newTemp(Ity_I64);
5372 IRTemp op3 = newTemp(Ity_I64);
5373 IRTemp result = newTemp(Ity_I64);
5374
5375 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5376 assign(op3, get_gpr_dw0(r3));
5377 assign(result, binop(Iop_Add64, mkexpr(op2), mkexpr(op3)));
5378 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op2, op3);
5379 store(mkexpr(op2addr), mkexpr(result));
5380 put_gpr_dw0(r1, mkexpr(op2));
5381
5382 return "laalg";
5383}
5384
5385static HChar *
5386s390_irgen_LAN(UChar r1, UChar r3, IRTemp op2addr)
5387{
5388 IRTemp op2 = newTemp(Ity_I32);
5389 IRTemp op3 = newTemp(Ity_I32);
5390 IRTemp result = newTemp(Ity_I32);
5391
5392 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5393 assign(op3, get_gpr_w1(r3));
5394 assign(result, binop(Iop_And32, mkexpr(op2), mkexpr(op3)));
5395 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5396 store(mkexpr(op2addr), mkexpr(result));
5397 put_gpr_w1(r1, mkexpr(op2));
5398
5399 return "lan";
5400}
5401
5402static HChar *
5403s390_irgen_LANG(UChar r1, UChar r3, IRTemp op2addr)
5404{
5405 IRTemp op2 = newTemp(Ity_I64);
5406 IRTemp op3 = newTemp(Ity_I64);
5407 IRTemp result = newTemp(Ity_I64);
5408
5409 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5410 assign(op3, get_gpr_dw0(r3));
5411 assign(result, binop(Iop_And64, mkexpr(op2), mkexpr(op3)));
5412 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5413 store(mkexpr(op2addr), mkexpr(result));
5414 put_gpr_dw0(r1, mkexpr(op2));
5415
5416 return "lang";
5417}
5418
5419static HChar *
5420s390_irgen_LAX(UChar r1, UChar r3, IRTemp op2addr)
5421{
5422 IRTemp op2 = newTemp(Ity_I32);
5423 IRTemp op3 = newTemp(Ity_I32);
5424 IRTemp result = newTemp(Ity_I32);
5425
5426 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5427 assign(op3, get_gpr_w1(r3));
5428 assign(result, binop(Iop_Xor32, mkexpr(op2), mkexpr(op3)));
5429 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5430 store(mkexpr(op2addr), mkexpr(result));
5431 put_gpr_w1(r1, mkexpr(op2));
5432
5433 return "lax";
5434}
5435
5436static HChar *
5437s390_irgen_LAXG(UChar r1, UChar r3, IRTemp op2addr)
5438{
5439 IRTemp op2 = newTemp(Ity_I64);
5440 IRTemp op3 = newTemp(Ity_I64);
5441 IRTemp result = newTemp(Ity_I64);
5442
5443 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5444 assign(op3, get_gpr_dw0(r3));
5445 assign(result, binop(Iop_Xor64, mkexpr(op2), mkexpr(op3)));
5446 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5447 store(mkexpr(op2addr), mkexpr(result));
5448 put_gpr_dw0(r1, mkexpr(op2));
5449
5450 return "laxg";
5451}
5452
5453static HChar *
5454s390_irgen_LAO(UChar r1, UChar r3, IRTemp op2addr)
5455{
5456 IRTemp op2 = newTemp(Ity_I32);
5457 IRTemp op3 = newTemp(Ity_I32);
5458 IRTemp result = newTemp(Ity_I32);
5459
5460 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5461 assign(op3, get_gpr_w1(r3));
5462 assign(result, binop(Iop_Or32, mkexpr(op2), mkexpr(op3)));
5463 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5464 store(mkexpr(op2addr), mkexpr(result));
5465 put_gpr_w1(r1, mkexpr(op2));
5466
5467 return "lao";
5468}
5469
5470static HChar *
5471s390_irgen_LAOG(UChar r1, UChar r3, IRTemp op2addr)
5472{
5473 IRTemp op2 = newTemp(Ity_I64);
5474 IRTemp op3 = newTemp(Ity_I64);
5475 IRTemp result = newTemp(Ity_I64);
5476
5477 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5478 assign(op3, get_gpr_dw0(r3));
5479 assign(result, binop(Iop_Or64, mkexpr(op2), mkexpr(op3)));
5480 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5481 store(mkexpr(op2addr), mkexpr(result));
5482 put_gpr_dw0(r1, mkexpr(op2));
5483
5484 return "laog";
5485}
5486
5487static HChar *
5488s390_irgen_LTR(UChar r1, UChar r2)
5489{
5490 IRTemp op2 = newTemp(Ity_I32);
5491
5492 assign(op2, get_gpr_w1(r2));
5493 put_gpr_w1(r1, mkexpr(op2));
5494 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5495
5496 return "ltr";
5497}
5498
5499static HChar *
5500s390_irgen_LTGR(UChar r1, UChar r2)
5501{
5502 IRTemp op2 = newTemp(Ity_I64);
5503
5504 assign(op2, get_gpr_dw0(r2));
5505 put_gpr_dw0(r1, mkexpr(op2));
5506 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5507
5508 return "ltgr";
5509}
5510
5511static HChar *
5512s390_irgen_LTGFR(UChar r1, UChar r2)
5513{
5514 IRTemp op2 = newTemp(Ity_I64);
5515
5516 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
5517 put_gpr_dw0(r1, mkexpr(op2));
5518 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5519
5520 return "ltgfr";
5521}
5522
5523static HChar *
5524s390_irgen_LT(UChar r1, IRTemp op2addr)
5525{
5526 IRTemp op2 = newTemp(Ity_I32);
5527
5528 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5529 put_gpr_w1(r1, mkexpr(op2));
5530 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5531
5532 return "lt";
5533}
5534
5535static HChar *
5536s390_irgen_LTG(UChar r1, IRTemp op2addr)
5537{
5538 IRTemp op2 = newTemp(Ity_I64);
5539
5540 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5541 put_gpr_dw0(r1, mkexpr(op2));
5542 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5543
5544 return "ltg";
5545}
5546
5547static HChar *
5548s390_irgen_LTGF(UChar r1, IRTemp op2addr)
5549{
5550 IRTemp op2 = newTemp(Ity_I64);
5551
5552 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
5553 put_gpr_dw0(r1, mkexpr(op2));
5554 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5555
5556 return "ltgf";
5557}
5558
5559static HChar *
5560s390_irgen_LBR(UChar r1, UChar r2)
5561{
5562 put_gpr_w1(r1, unop(Iop_8Sto32, get_gpr_b7(r2)));
5563
5564 return "lbr";
5565}
5566
5567static HChar *
5568s390_irgen_LGBR(UChar r1, UChar r2)
5569{
5570 put_gpr_dw0(r1, unop(Iop_8Sto64, get_gpr_b7(r2)));
5571
5572 return "lgbr";
5573}
5574
5575static HChar *
5576s390_irgen_LB(UChar r1, IRTemp op2addr)
5577{
5578 put_gpr_w1(r1, unop(Iop_8Sto32, load(Ity_I8, mkexpr(op2addr))));
5579
5580 return "lb";
5581}
5582
5583static HChar *
5584s390_irgen_LGB(UChar r1, IRTemp op2addr)
5585{
5586 put_gpr_dw0(r1, unop(Iop_8Sto64, load(Ity_I8, mkexpr(op2addr))));
5587
5588 return "lgb";
5589}
5590
5591static HChar *
5592s390_irgen_LBH(UChar r1, IRTemp op2addr)
5593{
5594 put_gpr_w0(r1, unop(Iop_8Sto32, load(Ity_I8, mkexpr(op2addr))));
5595
5596 return "lbh";
5597}
5598
5599static HChar *
5600s390_irgen_LCR(UChar r1, UChar r2)
5601{
5602 Int op1;
5603 IRTemp op2 = newTemp(Ity_I32);
5604 IRTemp result = newTemp(Ity_I32);
5605
5606 op1 = 0;
5607 assign(op2, get_gpr_w1(r2));
5608 assign(result, binop(Iop_Sub32, mkU32((UInt)op1), mkexpr(op2)));
5609 put_gpr_w1(r1, mkexpr(result));
5610 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, mktemp(Ity_I32, mkU32((UInt)
5611 op1)), op2);
5612
5613 return "lcr";
5614}
5615
5616static HChar *
5617s390_irgen_LCGR(UChar r1, UChar r2)
5618{
5619 Long op1;
5620 IRTemp op2 = newTemp(Ity_I64);
5621 IRTemp result = newTemp(Ity_I64);
5622
5623 op1 = 0ULL;
5624 assign(op2, get_gpr_dw0(r2));
5625 assign(result, binop(Iop_Sub64, mkU64((ULong)op1), mkexpr(op2)));
5626 put_gpr_dw0(r1, mkexpr(result));
5627 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, mktemp(Ity_I64, mkU64((ULong)
5628 op1)), op2);
5629
5630 return "lcgr";
5631}
5632
5633static HChar *
5634s390_irgen_LCGFR(UChar r1, UChar r2)
5635{
5636 Long op1;
5637 IRTemp op2 = newTemp(Ity_I64);
5638 IRTemp result = newTemp(Ity_I64);
5639
5640 op1 = 0ULL;
5641 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
5642 assign(result, binop(Iop_Sub64, mkU64((ULong)op1), mkexpr(op2)));
5643 put_gpr_dw0(r1, mkexpr(result));
5644 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, mktemp(Ity_I64, mkU64((ULong)
5645 op1)), op2);
5646
5647 return "lcgfr";
5648}
5649
5650static HChar *
5651s390_irgen_LHR(UChar r1, UChar r2)
5652{
5653 put_gpr_w1(r1, unop(Iop_16Sto32, get_gpr_hw3(r2)));
5654
5655 return "lhr";
5656}
5657
5658static HChar *
5659s390_irgen_LGHR(UChar r1, UChar r2)
5660{
5661 put_gpr_dw0(r1, unop(Iop_16Sto64, get_gpr_hw3(r2)));
5662
5663 return "lghr";
5664}
5665
5666static HChar *
5667s390_irgen_LH(UChar r1, IRTemp op2addr)
5668{
5669 put_gpr_w1(r1, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
5670
5671 return "lh";
5672}
5673
5674static HChar *
5675s390_irgen_LHY(UChar r1, IRTemp op2addr)
5676{
5677 put_gpr_w1(r1, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
5678
5679 return "lhy";
5680}
5681
5682static HChar *
5683s390_irgen_LGH(UChar r1, IRTemp op2addr)
5684{
5685 put_gpr_dw0(r1, unop(Iop_16Sto64, load(Ity_I16, mkexpr(op2addr))));
5686
5687 return "lgh";
5688}
5689
5690static HChar *
5691s390_irgen_LHI(UChar r1, UShort i2)
5692{
5693 put_gpr_w1(r1, mkU32((UInt)(Int)(Short)i2));
5694
5695 return "lhi";
5696}
5697
5698static HChar *
5699s390_irgen_LGHI(UChar r1, UShort i2)
5700{
5701 put_gpr_dw0(r1, mkU64((ULong)(Long)(Short)i2));
5702
5703 return "lghi";
5704}
5705
5706static HChar *
5707s390_irgen_LHRL(UChar r1, UInt i2)
5708{
5709 put_gpr_w1(r1, unop(Iop_16Sto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
5710 ((ULong)(Long)(Int)i2 << 1)))));
5711
5712 return "lhrl";
5713}
5714
5715static HChar *
5716s390_irgen_LGHRL(UChar r1, UInt i2)
5717{
5718 put_gpr_dw0(r1, unop(Iop_16Sto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
5719 ((ULong)(Long)(Int)i2 << 1)))));
5720
5721 return "lghrl";
5722}
5723
5724static HChar *
5725s390_irgen_LHH(UChar r1, IRTemp op2addr)
5726{
5727 put_gpr_w0(r1, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
5728
5729 return "lhh";
5730}
5731
5732static HChar *
5733s390_irgen_LFH(UChar r1, IRTemp op2addr)
5734{
5735 put_gpr_w0(r1, load(Ity_I32, mkexpr(op2addr)));
5736
5737 return "lfh";
5738}
5739
5740static HChar *
5741s390_irgen_LLGFR(UChar r1, UChar r2)
5742{
5743 put_gpr_dw0(r1, unop(Iop_32Uto64, get_gpr_w1(r2)));
5744
5745 return "llgfr";
5746}
5747
5748static HChar *
5749s390_irgen_LLGF(UChar r1, IRTemp op2addr)
5750{
5751 put_gpr_dw0(r1, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
5752
5753 return "llgf";
5754}
5755
5756static HChar *
5757s390_irgen_LLGFRL(UChar r1, UInt i2)
5758{
5759 put_gpr_dw0(r1, unop(Iop_32Uto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
5760 ((ULong)(Long)(Int)i2 << 1)))));
5761
5762 return "llgfrl";
5763}
5764
5765static HChar *
5766s390_irgen_LLCR(UChar r1, UChar r2)
5767{
5768 put_gpr_w1(r1, unop(Iop_8Uto32, get_gpr_b7(r2)));
5769
5770 return "llcr";
5771}
5772
5773static HChar *
5774s390_irgen_LLGCR(UChar r1, UChar r2)
5775{
5776 put_gpr_dw0(r1, unop(Iop_8Uto64, get_gpr_b7(r2)));
5777
5778 return "llgcr";
5779}
5780
5781static HChar *
5782s390_irgen_LLC(UChar r1, IRTemp op2addr)
5783{
5784 put_gpr_w1(r1, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
5785
5786 return "llc";
5787}
5788
5789static HChar *
5790s390_irgen_LLGC(UChar r1, IRTemp op2addr)
5791{
5792 put_gpr_dw0(r1, unop(Iop_8Uto64, load(Ity_I8, mkexpr(op2addr))));
5793
5794 return "llgc";
5795}
5796
5797static HChar *
5798s390_irgen_LLCH(UChar r1, IRTemp op2addr)
5799{
5800 put_gpr_w0(r1, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
5801
5802 return "llch";
5803}
5804
5805static HChar *
5806s390_irgen_LLHR(UChar r1, UChar r2)
5807{
5808 put_gpr_w1(r1, unop(Iop_16Uto32, get_gpr_hw3(r2)));
5809
5810 return "llhr";
5811}
5812
5813static HChar *
5814s390_irgen_LLGHR(UChar r1, UChar r2)
5815{
5816 put_gpr_dw0(r1, unop(Iop_16Uto64, get_gpr_hw3(r2)));
5817
5818 return "llghr";
5819}
5820
5821static HChar *
5822s390_irgen_LLH(UChar r1, IRTemp op2addr)
5823{
5824 put_gpr_w1(r1, unop(Iop_16Uto32, load(Ity_I16, mkexpr(op2addr))));
5825
5826 return "llh";
5827}
5828
5829static HChar *
5830s390_irgen_LLGH(UChar r1, IRTemp op2addr)
5831{
5832 put_gpr_dw0(r1, unop(Iop_16Uto64, load(Ity_I16, mkexpr(op2addr))));
5833
5834 return "llgh";
5835}
5836
5837static HChar *
5838s390_irgen_LLHRL(UChar r1, UInt i2)
5839{
5840 put_gpr_w1(r1, unop(Iop_16Uto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
5841 ((ULong)(Long)(Int)i2 << 1)))));
5842
5843 return "llhrl";
5844}
5845
5846static HChar *
5847s390_irgen_LLGHRL(UChar r1, UInt i2)
5848{
5849 put_gpr_dw0(r1, unop(Iop_16Uto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
5850 ((ULong)(Long)(Int)i2 << 1)))));
5851
5852 return "llghrl";
5853}
5854
5855static HChar *
5856s390_irgen_LLHH(UChar r1, IRTemp op2addr)
5857{
5858 put_gpr_w0(r1, unop(Iop_16Uto32, load(Ity_I16, mkexpr(op2addr))));
5859
5860 return "llhh";
5861}
5862
5863static HChar *
5864s390_irgen_LLIHF(UChar r1, UInt i2)
5865{
5866 put_gpr_dw0(r1, mkU64(((ULong)i2) << 32));
5867
5868 return "llihf";
5869}
5870
5871static HChar *
5872s390_irgen_LLIHH(UChar r1, UShort i2)
5873{
5874 put_gpr_dw0(r1, mkU64(((ULong)i2) << 48));
5875
5876 return "llihh";
5877}
5878
5879static HChar *
5880s390_irgen_LLIHL(UChar r1, UShort i2)
5881{
5882 put_gpr_dw0(r1, mkU64(((ULong)i2) << 32));
5883
5884 return "llihl";
5885}
5886
5887static HChar *
5888s390_irgen_LLILF(UChar r1, UInt i2)
5889{
5890 put_gpr_dw0(r1, mkU64(i2));
5891
5892 return "llilf";
5893}
5894
5895static HChar *
5896s390_irgen_LLILH(UChar r1, UShort i2)
5897{
5898 put_gpr_dw0(r1, mkU64(((ULong)i2) << 16));
5899
5900 return "llilh";
5901}
5902
5903static HChar *
5904s390_irgen_LLILL(UChar r1, UShort i2)
5905{
5906 put_gpr_dw0(r1, mkU64(i2));
5907
5908 return "llill";
5909}
5910
5911static HChar *
5912s390_irgen_LLGTR(UChar r1, UChar r2)
5913{
5914 put_gpr_dw0(r1, unop(Iop_32Uto64, binop(Iop_And32, get_gpr_w1(r2),
5915 mkU32(2147483647))));
5916
5917 return "llgtr";
5918}
5919
5920static HChar *
5921s390_irgen_LLGT(UChar r1, IRTemp op2addr)
5922{
5923 put_gpr_dw0(r1, unop(Iop_32Uto64, binop(Iop_And32, load(Ity_I32,
5924 mkexpr(op2addr)), mkU32(2147483647))));
5925
5926 return "llgt";
5927}
5928
5929static HChar *
5930s390_irgen_LNR(UChar r1, UChar r2)
5931{
5932 IRTemp op2 = newTemp(Ity_I32);
5933 IRTemp result = newTemp(Ity_I32);
5934
5935 assign(op2, get_gpr_w1(r2));
5936 assign(result, mkite(binop(Iop_CmpLE32S, mkexpr(op2), mkU32(0)), mkexpr(op2),
5937 binop(Iop_Sub32, mkU32(0), mkexpr(op2))));
5938 put_gpr_w1(r1, mkexpr(result));
5939 s390_cc_thunk_putS(S390_CC_OP_BITWISE, result);
5940
5941 return "lnr";
5942}
5943
5944static HChar *
5945s390_irgen_LNGR(UChar r1, UChar r2)
5946{
5947 IRTemp op2 = newTemp(Ity_I64);
5948 IRTemp result = newTemp(Ity_I64);
5949
5950 assign(op2, get_gpr_dw0(r2));
5951 assign(result, mkite(binop(Iop_CmpLE64S, mkexpr(op2), mkU64(0)), mkexpr(op2),
5952 binop(Iop_Sub64, mkU64(0), mkexpr(op2))));
5953 put_gpr_dw0(r1, mkexpr(result));
5954 s390_cc_thunk_putS(S390_CC_OP_BITWISE, result);
5955
5956 return "lngr";
5957}
5958
5959static HChar *
5960s390_irgen_LNGFR(UChar r1, UChar r2 __attribute__((unused)))
5961{
5962 IRTemp op2 = newTemp(Ity_I64);
5963 IRTemp result = newTemp(Ity_I64);
5964
5965 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r1)));
5966 assign(result, mkite(binop(Iop_CmpLE64S, mkexpr(op2), mkU64(0)), mkexpr(op2),
5967 binop(Iop_Sub64, mkU64(0), mkexpr(op2))));
5968 put_gpr_dw0(r1, mkexpr(result));
5969 s390_cc_thunk_putS(S390_CC_OP_BITWISE, result);
5970
5971 return "lngfr";
5972}
5973
5974static HChar *
sewardjd7bde722011-04-05 13:19:33 +00005975s390_irgen_LOCR(UChar m3, UChar r1, UChar r2)
5976{
florian6820ba52012-07-26 02:01:50 +00005977 next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0)));
sewardjd7bde722011-04-05 13:19:33 +00005978 put_gpr_w1(r1, get_gpr_w1(r2));
5979
5980 return "locr";
5981}
5982
5983static HChar *
5984s390_irgen_LOCGR(UChar m3, UChar r1, UChar r2)
5985{
florian6820ba52012-07-26 02:01:50 +00005986 next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0)));
sewardjd7bde722011-04-05 13:19:33 +00005987 put_gpr_dw0(r1, get_gpr_dw0(r2));
5988
5989 return "locgr";
5990}
5991
5992static HChar *
5993s390_irgen_LOC(UChar r1, IRTemp op2addr)
5994{
5995 /* condition is checked in format handler */
5996 put_gpr_w1(r1, load(Ity_I32, mkexpr(op2addr)));
5997
5998 return "loc";
5999}
6000
6001static HChar *
6002s390_irgen_LOCG(UChar r1, IRTemp op2addr)
6003{
6004 /* condition is checked in format handler */
6005 put_gpr_dw0(r1, load(Ity_I64, mkexpr(op2addr)));
6006
6007 return "locg";
6008}
6009
6010static HChar *
sewardj2019a972011-03-07 16:04:07 +00006011s390_irgen_LPQ(UChar r1, IRTemp op2addr)
6012{
6013 put_gpr_dw0(r1, load(Ity_I64, mkexpr(op2addr)));
6014 put_gpr_dw0(r1 + 1, load(Ity_I64, binop(Iop_Add64, mkexpr(op2addr), mkU64(8))
6015 ));
6016
6017 return "lpq";
6018}
6019
6020static HChar *
6021s390_irgen_LPR(UChar r1, UChar r2)
6022{
6023 IRTemp op2 = newTemp(Ity_I32);
6024 IRTemp result = newTemp(Ity_I32);
6025
6026 assign(op2, get_gpr_w1(r2));
6027 assign(result, mkite(binop(Iop_CmpLT32S, mkexpr(op2), mkU32(0)),
6028 binop(Iop_Sub32, mkU32(0), mkexpr(op2)), mkexpr(op2)));
6029 put_gpr_w1(r1, mkexpr(result));
6030 s390_cc_thunk_putS(S390_CC_OP_LOAD_POSITIVE_32, op2);
6031
6032 return "lpr";
6033}
6034
6035static HChar *
6036s390_irgen_LPGR(UChar r1, UChar r2)
6037{
6038 IRTemp op2 = newTemp(Ity_I64);
6039 IRTemp result = newTemp(Ity_I64);
6040
6041 assign(op2, get_gpr_dw0(r2));
6042 assign(result, mkite(binop(Iop_CmpLT64S, mkexpr(op2), mkU64(0)),
6043 binop(Iop_Sub64, mkU64(0), mkexpr(op2)), mkexpr(op2)));
6044 put_gpr_dw0(r1, mkexpr(result));
6045 s390_cc_thunk_putS(S390_CC_OP_LOAD_POSITIVE_64, op2);
6046
6047 return "lpgr";
6048}
6049
6050static HChar *
6051s390_irgen_LPGFR(UChar r1, UChar r2)
6052{
6053 IRTemp op2 = newTemp(Ity_I64);
6054 IRTemp result = newTemp(Ity_I64);
6055
6056 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
6057 assign(result, mkite(binop(Iop_CmpLT64S, mkexpr(op2), mkU64(0)),
6058 binop(Iop_Sub64, mkU64(0), mkexpr(op2)), mkexpr(op2)));
6059 put_gpr_dw0(r1, mkexpr(result));
6060 s390_cc_thunk_putS(S390_CC_OP_LOAD_POSITIVE_64, op2);
6061
6062 return "lpgfr";
6063}
6064
6065static HChar *
6066s390_irgen_LRVR(UChar r1, UChar r2)
6067{
6068 IRTemp b0 = newTemp(Ity_I8);
6069 IRTemp b1 = newTemp(Ity_I8);
6070 IRTemp b2 = newTemp(Ity_I8);
6071 IRTemp b3 = newTemp(Ity_I8);
6072
6073 assign(b3, get_gpr_b7(r2));
6074 assign(b2, get_gpr_b6(r2));
6075 assign(b1, get_gpr_b5(r2));
6076 assign(b0, get_gpr_b4(r2));
6077 put_gpr_b4(r1, mkexpr(b3));
6078 put_gpr_b5(r1, mkexpr(b2));
6079 put_gpr_b6(r1, mkexpr(b1));
6080 put_gpr_b7(r1, mkexpr(b0));
6081
6082 return "lrvr";
6083}
6084
6085static HChar *
6086s390_irgen_LRVGR(UChar r1, UChar r2)
6087{
6088 IRTemp b0 = newTemp(Ity_I8);
6089 IRTemp b1 = newTemp(Ity_I8);
6090 IRTemp b2 = newTemp(Ity_I8);
6091 IRTemp b3 = newTemp(Ity_I8);
6092 IRTemp b4 = newTemp(Ity_I8);
6093 IRTemp b5 = newTemp(Ity_I8);
6094 IRTemp b6 = newTemp(Ity_I8);
6095 IRTemp b7 = newTemp(Ity_I8);
6096
6097 assign(b7, get_gpr_b7(r2));
6098 assign(b6, get_gpr_b6(r2));
6099 assign(b5, get_gpr_b5(r2));
6100 assign(b4, get_gpr_b4(r2));
6101 assign(b3, get_gpr_b3(r2));
6102 assign(b2, get_gpr_b2(r2));
6103 assign(b1, get_gpr_b1(r2));
6104 assign(b0, get_gpr_b0(r2));
6105 put_gpr_b0(r1, mkexpr(b7));
6106 put_gpr_b1(r1, mkexpr(b6));
6107 put_gpr_b2(r1, mkexpr(b5));
6108 put_gpr_b3(r1, mkexpr(b4));
6109 put_gpr_b4(r1, mkexpr(b3));
6110 put_gpr_b5(r1, mkexpr(b2));
6111 put_gpr_b6(r1, mkexpr(b1));
6112 put_gpr_b7(r1, mkexpr(b0));
6113
6114 return "lrvgr";
6115}
6116
6117static HChar *
6118s390_irgen_LRVH(UChar r1, IRTemp op2addr)
6119{
6120 IRTemp op2 = newTemp(Ity_I16);
6121
6122 assign(op2, load(Ity_I16, mkexpr(op2addr)));
6123 put_gpr_b6(r1, unop(Iop_16to8, mkexpr(op2)));
6124 put_gpr_b7(r1, unop(Iop_16HIto8, mkexpr(op2)));
6125
6126 return "lrvh";
6127}
6128
6129static HChar *
6130s390_irgen_LRV(UChar r1, IRTemp op2addr)
6131{
6132 IRTemp op2 = newTemp(Ity_I32);
6133
6134 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6135 put_gpr_b4(r1, unop(Iop_32to8, binop(Iop_And32, mkexpr(op2), mkU32(255))));
6136 put_gpr_b5(r1, unop(Iop_32to8, binop(Iop_And32, binop(Iop_Shr32, mkexpr(op2),
6137 mkU8(8)), mkU32(255))));
6138 put_gpr_b6(r1, unop(Iop_32to8, binop(Iop_And32, binop(Iop_Shr32, mkexpr(op2),
6139 mkU8(16)), mkU32(255))));
6140 put_gpr_b7(r1, unop(Iop_32to8, binop(Iop_And32, binop(Iop_Shr32, mkexpr(op2),
6141 mkU8(24)), mkU32(255))));
6142
6143 return "lrv";
6144}
6145
6146static HChar *
6147s390_irgen_LRVG(UChar r1, IRTemp op2addr)
6148{
6149 IRTemp op2 = newTemp(Ity_I64);
6150
6151 assign(op2, load(Ity_I64, mkexpr(op2addr)));
6152 put_gpr_b0(r1, unop(Iop_64to8, binop(Iop_And64, mkexpr(op2), mkU64(255))));
6153 put_gpr_b1(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6154 mkU8(8)), mkU64(255))));
6155 put_gpr_b2(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6156 mkU8(16)), mkU64(255))));
6157 put_gpr_b3(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6158 mkU8(24)), mkU64(255))));
6159 put_gpr_b4(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6160 mkU8(32)), mkU64(255))));
6161 put_gpr_b5(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6162 mkU8(40)), mkU64(255))));
6163 put_gpr_b6(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6164 mkU8(48)), mkU64(255))));
6165 put_gpr_b7(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6166 mkU8(56)), mkU64(255))));
6167
6168 return "lrvg";
6169}
6170
6171static HChar *
6172s390_irgen_MVHHI(UShort i2, IRTemp op1addr)
6173{
6174 store(mkexpr(op1addr), mkU16(i2));
6175
6176 return "mvhhi";
6177}
6178
6179static HChar *
6180s390_irgen_MVHI(UShort i2, IRTemp op1addr)
6181{
6182 store(mkexpr(op1addr), mkU32((UInt)(Int)(Short)i2));
6183
6184 return "mvhi";
6185}
6186
6187static HChar *
6188s390_irgen_MVGHI(UShort i2, IRTemp op1addr)
6189{
6190 store(mkexpr(op1addr), mkU64((ULong)(Long)(Short)i2));
6191
6192 return "mvghi";
6193}
6194
6195static HChar *
6196s390_irgen_MVI(UChar i2, IRTemp op1addr)
6197{
6198 store(mkexpr(op1addr), mkU8(i2));
6199
6200 return "mvi";
6201}
6202
6203static HChar *
6204s390_irgen_MVIY(UChar i2, IRTemp op1addr)
6205{
6206 store(mkexpr(op1addr), mkU8(i2));
6207
6208 return "mviy";
6209}
6210
6211static HChar *
6212s390_irgen_MR(UChar r1, UChar r2)
6213{
6214 IRTemp op1 = newTemp(Ity_I32);
6215 IRTemp op2 = newTemp(Ity_I32);
6216 IRTemp result = newTemp(Ity_I64);
6217
6218 assign(op1, get_gpr_w1(r1 + 1));
6219 assign(op2, get_gpr_w1(r2));
6220 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6221 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6222 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6223
6224 return "mr";
6225}
6226
6227static HChar *
6228s390_irgen_M(UChar r1, IRTemp op2addr)
6229{
6230 IRTemp op1 = newTemp(Ity_I32);
6231 IRTemp op2 = newTemp(Ity_I32);
6232 IRTemp result = newTemp(Ity_I64);
6233
6234 assign(op1, get_gpr_w1(r1 + 1));
6235 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6236 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6237 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6238 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6239
6240 return "m";
6241}
6242
6243static HChar *
6244s390_irgen_MFY(UChar r1, IRTemp op2addr)
6245{
6246 IRTemp op1 = newTemp(Ity_I32);
6247 IRTemp op2 = newTemp(Ity_I32);
6248 IRTemp result = newTemp(Ity_I64);
6249
6250 assign(op1, get_gpr_w1(r1 + 1));
6251 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6252 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6253 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6254 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6255
6256 return "mfy";
6257}
6258
6259static HChar *
6260s390_irgen_MH(UChar r1, IRTemp op2addr)
6261{
6262 IRTemp op1 = newTemp(Ity_I32);
6263 IRTemp op2 = newTemp(Ity_I16);
6264 IRTemp result = newTemp(Ity_I64);
6265
6266 assign(op1, get_gpr_w1(r1));
6267 assign(op2, load(Ity_I16, mkexpr(op2addr)));
6268 assign(result, binop(Iop_MullS32, mkexpr(op1), unop(Iop_16Sto32, mkexpr(op2))
6269 ));
6270 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6271
6272 return "mh";
6273}
6274
6275static HChar *
6276s390_irgen_MHY(UChar r1, IRTemp op2addr)
6277{
6278 IRTemp op1 = newTemp(Ity_I32);
6279 IRTemp op2 = newTemp(Ity_I16);
6280 IRTemp result = newTemp(Ity_I64);
6281
6282 assign(op1, get_gpr_w1(r1));
6283 assign(op2, load(Ity_I16, mkexpr(op2addr)));
6284 assign(result, binop(Iop_MullS32, mkexpr(op1), unop(Iop_16Sto32, mkexpr(op2))
6285 ));
6286 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6287
6288 return "mhy";
6289}
6290
6291static HChar *
6292s390_irgen_MHI(UChar r1, UShort i2)
6293{
6294 IRTemp op1 = newTemp(Ity_I32);
6295 Short op2;
6296 IRTemp result = newTemp(Ity_I64);
6297
6298 assign(op1, get_gpr_w1(r1));
6299 op2 = (Short)i2;
6300 assign(result, binop(Iop_MullS32, mkexpr(op1), unop(Iop_16Sto32,
6301 mkU16((UShort)op2))));
6302 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6303
6304 return "mhi";
6305}
6306
6307static HChar *
6308s390_irgen_MGHI(UChar r1, UShort i2)
6309{
6310 IRTemp op1 = newTemp(Ity_I64);
6311 Short op2;
6312 IRTemp result = newTemp(Ity_I128);
6313
6314 assign(op1, get_gpr_dw0(r1));
6315 op2 = (Short)i2;
6316 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_16Sto64,
6317 mkU16((UShort)op2))));
6318 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6319
6320 return "mghi";
6321}
6322
6323static HChar *
6324s390_irgen_MLR(UChar r1, UChar r2)
6325{
6326 IRTemp op1 = newTemp(Ity_I32);
6327 IRTemp op2 = newTemp(Ity_I32);
6328 IRTemp result = newTemp(Ity_I64);
6329
6330 assign(op1, get_gpr_w1(r1 + 1));
6331 assign(op2, get_gpr_w1(r2));
6332 assign(result, binop(Iop_MullU32, mkexpr(op1), mkexpr(op2)));
6333 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6334 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6335
6336 return "mlr";
6337}
6338
6339static HChar *
6340s390_irgen_MLGR(UChar r1, UChar r2)
6341{
6342 IRTemp op1 = newTemp(Ity_I64);
6343 IRTemp op2 = newTemp(Ity_I64);
6344 IRTemp result = newTemp(Ity_I128);
6345
6346 assign(op1, get_gpr_dw0(r1 + 1));
6347 assign(op2, get_gpr_dw0(r2));
6348 assign(result, binop(Iop_MullU64, mkexpr(op1), mkexpr(op2)));
6349 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result)));
6350 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result)));
6351
6352 return "mlgr";
6353}
6354
6355static HChar *
6356s390_irgen_ML(UChar r1, IRTemp op2addr)
6357{
6358 IRTemp op1 = newTemp(Ity_I32);
6359 IRTemp op2 = newTemp(Ity_I32);
6360 IRTemp result = newTemp(Ity_I64);
6361
6362 assign(op1, get_gpr_w1(r1 + 1));
6363 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6364 assign(result, binop(Iop_MullU32, mkexpr(op1), mkexpr(op2)));
6365 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6366 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6367
6368 return "ml";
6369}
6370
6371static HChar *
6372s390_irgen_MLG(UChar r1, IRTemp op2addr)
6373{
6374 IRTemp op1 = newTemp(Ity_I64);
6375 IRTemp op2 = newTemp(Ity_I64);
6376 IRTemp result = newTemp(Ity_I128);
6377
6378 assign(op1, get_gpr_dw0(r1 + 1));
6379 assign(op2, load(Ity_I64, mkexpr(op2addr)));
6380 assign(result, binop(Iop_MullU64, mkexpr(op1), mkexpr(op2)));
6381 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result)));
6382 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result)));
6383
6384 return "mlg";
6385}
6386
6387static HChar *
6388s390_irgen_MSR(UChar r1, UChar r2)
6389{
6390 IRTemp op1 = newTemp(Ity_I32);
6391 IRTemp op2 = newTemp(Ity_I32);
6392 IRTemp result = newTemp(Ity_I64);
6393
6394 assign(op1, get_gpr_w1(r1));
6395 assign(op2, get_gpr_w1(r2));
6396 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6397 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6398
6399 return "msr";
6400}
6401
6402static HChar *
6403s390_irgen_MSGR(UChar r1, UChar r2)
6404{
6405 IRTemp op1 = newTemp(Ity_I64);
6406 IRTemp op2 = newTemp(Ity_I64);
6407 IRTemp result = newTemp(Ity_I128);
6408
6409 assign(op1, get_gpr_dw0(r1));
6410 assign(op2, get_gpr_dw0(r2));
6411 assign(result, binop(Iop_MullS64, mkexpr(op1), mkexpr(op2)));
6412 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6413
6414 return "msgr";
6415}
6416
6417static HChar *
6418s390_irgen_MSGFR(UChar r1, UChar r2)
6419{
6420 IRTemp op1 = newTemp(Ity_I64);
6421 IRTemp op2 = newTemp(Ity_I32);
6422 IRTemp result = newTemp(Ity_I128);
6423
6424 assign(op1, get_gpr_dw0(r1));
6425 assign(op2, get_gpr_w1(r2));
6426 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_32Sto64, mkexpr(op2))
6427 ));
6428 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6429
6430 return "msgfr";
6431}
6432
6433static HChar *
6434s390_irgen_MS(UChar r1, IRTemp op2addr)
6435{
6436 IRTemp op1 = newTemp(Ity_I32);
6437 IRTemp op2 = newTemp(Ity_I32);
6438 IRTemp result = newTemp(Ity_I64);
6439
6440 assign(op1, get_gpr_w1(r1));
6441 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6442 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6443 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6444
6445 return "ms";
6446}
6447
6448static HChar *
6449s390_irgen_MSY(UChar r1, IRTemp op2addr)
6450{
6451 IRTemp op1 = newTemp(Ity_I32);
6452 IRTemp op2 = newTemp(Ity_I32);
6453 IRTemp result = newTemp(Ity_I64);
6454
6455 assign(op1, get_gpr_w1(r1));
6456 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6457 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6458 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6459
6460 return "msy";
6461}
6462
6463static HChar *
6464s390_irgen_MSG(UChar r1, IRTemp op2addr)
6465{
6466 IRTemp op1 = newTemp(Ity_I64);
6467 IRTemp op2 = newTemp(Ity_I64);
6468 IRTemp result = newTemp(Ity_I128);
6469
6470 assign(op1, get_gpr_dw0(r1));
6471 assign(op2, load(Ity_I64, mkexpr(op2addr)));
6472 assign(result, binop(Iop_MullS64, mkexpr(op1), mkexpr(op2)));
6473 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6474
6475 return "msg";
6476}
6477
6478static HChar *
6479s390_irgen_MSGF(UChar r1, IRTemp op2addr)
6480{
6481 IRTemp op1 = newTemp(Ity_I64);
6482 IRTemp op2 = newTemp(Ity_I32);
6483 IRTemp result = newTemp(Ity_I128);
6484
6485 assign(op1, get_gpr_dw0(r1));
6486 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6487 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_32Sto64, mkexpr(op2))
6488 ));
6489 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6490
6491 return "msgf";
6492}
6493
6494static HChar *
6495s390_irgen_MSFI(UChar r1, UInt i2)
6496{
6497 IRTemp op1 = newTemp(Ity_I32);
6498 Int op2;
6499 IRTemp result = newTemp(Ity_I64);
6500
6501 assign(op1, get_gpr_w1(r1));
6502 op2 = (Int)i2;
6503 assign(result, binop(Iop_MullS32, mkexpr(op1), mkU32((UInt)op2)));
6504 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6505
6506 return "msfi";
6507}
6508
6509static HChar *
6510s390_irgen_MSGFI(UChar r1, UInt i2)
6511{
6512 IRTemp op1 = newTemp(Ity_I64);
6513 Int op2;
6514 IRTemp result = newTemp(Ity_I128);
6515
6516 assign(op1, get_gpr_dw0(r1));
6517 op2 = (Int)i2;
6518 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_32Sto64, mkU32((UInt)
6519 op2))));
6520 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6521
6522 return "msgfi";
6523}
6524
6525static HChar *
6526s390_irgen_OR(UChar r1, UChar r2)
6527{
6528 IRTemp op1 = newTemp(Ity_I32);
6529 IRTemp op2 = newTemp(Ity_I32);
6530 IRTemp result = newTemp(Ity_I32);
6531
6532 assign(op1, get_gpr_w1(r1));
6533 assign(op2, get_gpr_w1(r2));
6534 assign(result, binop(Iop_Or32, mkexpr(op1), mkexpr(op2)));
6535 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6536 put_gpr_w1(r1, mkexpr(result));
6537
6538 return "or";
6539}
6540
6541static HChar *
6542s390_irgen_OGR(UChar r1, UChar r2)
6543{
6544 IRTemp op1 = newTemp(Ity_I64);
6545 IRTemp op2 = newTemp(Ity_I64);
6546 IRTemp result = newTemp(Ity_I64);
6547
6548 assign(op1, get_gpr_dw0(r1));
6549 assign(op2, get_gpr_dw0(r2));
6550 assign(result, binop(Iop_Or64, mkexpr(op1), mkexpr(op2)));
6551 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6552 put_gpr_dw0(r1, mkexpr(result));
6553
6554 return "ogr";
6555}
6556
6557static HChar *
6558s390_irgen_ORK(UChar r3, UChar r1, UChar r2)
6559{
6560 IRTemp op2 = newTemp(Ity_I32);
6561 IRTemp op3 = newTemp(Ity_I32);
6562 IRTemp result = newTemp(Ity_I32);
6563
6564 assign(op2, get_gpr_w1(r2));
6565 assign(op3, get_gpr_w1(r3));
6566 assign(result, binop(Iop_Or32, mkexpr(op2), mkexpr(op3)));
6567 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6568 put_gpr_w1(r1, mkexpr(result));
6569
6570 return "ork";
6571}
6572
6573static HChar *
6574s390_irgen_OGRK(UChar r3, UChar r1, UChar r2)
6575{
6576 IRTemp op2 = newTemp(Ity_I64);
6577 IRTemp op3 = newTemp(Ity_I64);
6578 IRTemp result = newTemp(Ity_I64);
6579
6580 assign(op2, get_gpr_dw0(r2));
6581 assign(op3, get_gpr_dw0(r3));
6582 assign(result, binop(Iop_Or64, mkexpr(op2), mkexpr(op3)));
6583 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6584 put_gpr_dw0(r1, mkexpr(result));
6585
6586 return "ogrk";
6587}
6588
6589static HChar *
6590s390_irgen_O(UChar r1, IRTemp op2addr)
6591{
6592 IRTemp op1 = newTemp(Ity_I32);
6593 IRTemp op2 = newTemp(Ity_I32);
6594 IRTemp result = newTemp(Ity_I32);
6595
6596 assign(op1, get_gpr_w1(r1));
6597 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6598 assign(result, binop(Iop_Or32, mkexpr(op1), mkexpr(op2)));
6599 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6600 put_gpr_w1(r1, mkexpr(result));
6601
6602 return "o";
6603}
6604
6605static HChar *
6606s390_irgen_OY(UChar r1, IRTemp op2addr)
6607{
6608 IRTemp op1 = newTemp(Ity_I32);
6609 IRTemp op2 = newTemp(Ity_I32);
6610 IRTemp result = newTemp(Ity_I32);
6611
6612 assign(op1, get_gpr_w1(r1));
6613 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6614 assign(result, binop(Iop_Or32, mkexpr(op1), mkexpr(op2)));
6615 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6616 put_gpr_w1(r1, mkexpr(result));
6617
6618 return "oy";
6619}
6620
6621static HChar *
6622s390_irgen_OG(UChar r1, IRTemp op2addr)
6623{
6624 IRTemp op1 = newTemp(Ity_I64);
6625 IRTemp op2 = newTemp(Ity_I64);
6626 IRTemp result = newTemp(Ity_I64);
6627
6628 assign(op1, get_gpr_dw0(r1));
6629 assign(op2, load(Ity_I64, mkexpr(op2addr)));
6630 assign(result, binop(Iop_Or64, mkexpr(op1), mkexpr(op2)));
6631 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6632 put_gpr_dw0(r1, mkexpr(result));
6633
6634 return "og";
6635}
6636
6637static HChar *
6638s390_irgen_OI(UChar i2, IRTemp op1addr)
6639{
6640 IRTemp op1 = newTemp(Ity_I8);
6641 UChar op2;
6642 IRTemp result = newTemp(Ity_I8);
6643
6644 assign(op1, load(Ity_I8, mkexpr(op1addr)));
6645 op2 = i2;
6646 assign(result, binop(Iop_Or8, mkexpr(op1), mkU8(op2)));
6647 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6648 store(mkexpr(op1addr), mkexpr(result));
6649
6650 return "oi";
6651}
6652
6653static HChar *
6654s390_irgen_OIY(UChar i2, IRTemp op1addr)
6655{
6656 IRTemp op1 = newTemp(Ity_I8);
6657 UChar op2;
6658 IRTemp result = newTemp(Ity_I8);
6659
6660 assign(op1, load(Ity_I8, mkexpr(op1addr)));
6661 op2 = i2;
6662 assign(result, binop(Iop_Or8, mkexpr(op1), mkU8(op2)));
6663 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6664 store(mkexpr(op1addr), mkexpr(result));
6665
6666 return "oiy";
6667}
6668
6669static HChar *
6670s390_irgen_OIHF(UChar r1, UInt i2)
6671{
6672 IRTemp op1 = newTemp(Ity_I32);
6673 UInt op2;
6674 IRTemp result = newTemp(Ity_I32);
6675
6676 assign(op1, get_gpr_w0(r1));
6677 op2 = i2;
6678 assign(result, binop(Iop_Or32, mkexpr(op1), mkU32(op2)));
6679 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6680 put_gpr_w0(r1, mkexpr(result));
6681
6682 return "oihf";
6683}
6684
6685static HChar *
6686s390_irgen_OIHH(UChar r1, UShort i2)
6687{
6688 IRTemp op1 = newTemp(Ity_I16);
6689 UShort op2;
6690 IRTemp result = newTemp(Ity_I16);
6691
6692 assign(op1, get_gpr_hw0(r1));
6693 op2 = i2;
6694 assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
6695 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6696 put_gpr_hw0(r1, mkexpr(result));
6697
6698 return "oihh";
6699}
6700
6701static HChar *
6702s390_irgen_OIHL(UChar r1, UShort i2)
6703{
6704 IRTemp op1 = newTemp(Ity_I16);
6705 UShort op2;
6706 IRTemp result = newTemp(Ity_I16);
6707
6708 assign(op1, get_gpr_hw1(r1));
6709 op2 = i2;
6710 assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
6711 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6712 put_gpr_hw1(r1, mkexpr(result));
6713
6714 return "oihl";
6715}
6716
6717static HChar *
6718s390_irgen_OILF(UChar r1, UInt i2)
6719{
6720 IRTemp op1 = newTemp(Ity_I32);
6721 UInt op2;
6722 IRTemp result = newTemp(Ity_I32);
6723
6724 assign(op1, get_gpr_w1(r1));
6725 op2 = i2;
6726 assign(result, binop(Iop_Or32, mkexpr(op1), mkU32(op2)));
6727 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6728 put_gpr_w1(r1, mkexpr(result));
6729
6730 return "oilf";
6731}
6732
6733static HChar *
6734s390_irgen_OILH(UChar r1, UShort i2)
6735{
6736 IRTemp op1 = newTemp(Ity_I16);
6737 UShort op2;
6738 IRTemp result = newTemp(Ity_I16);
6739
6740 assign(op1, get_gpr_hw2(r1));
6741 op2 = i2;
6742 assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
6743 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6744 put_gpr_hw2(r1, mkexpr(result));
6745
6746 return "oilh";
6747}
6748
6749static HChar *
6750s390_irgen_OILL(UChar r1, UShort i2)
6751{
6752 IRTemp op1 = newTemp(Ity_I16);
6753 UShort op2;
6754 IRTemp result = newTemp(Ity_I16);
6755
6756 assign(op1, get_gpr_hw3(r1));
6757 op2 = i2;
6758 assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
6759 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6760 put_gpr_hw3(r1, mkexpr(result));
6761
6762 return "oill";
6763}
6764
6765static HChar *
6766s390_irgen_PFD(void)
6767{
6768
6769 return "pfd";
6770}
6771
6772static HChar *
6773s390_irgen_PFDRL(void)
6774{
6775
6776 return "pfdrl";
6777}
6778
6779static HChar *
6780s390_irgen_RLL(UChar r1, UChar r3, IRTemp op2addr)
6781{
6782 IRTemp amount = newTemp(Ity_I64);
6783 IRTemp op = newTemp(Ity_I32);
6784
6785 assign(amount, binop(Iop_And64, mkexpr(op2addr), mkU64(31)));
6786 assign(op, get_gpr_w1(r3));
6787 put_gpr_w1(r1, binop(Iop_Or32, binop(Iop_Shl32, mkexpr(op), unop(Iop_64to8,
6788 mkexpr(amount))), binop(Iop_Shr32, mkexpr(op), unop(Iop_64to8,
6789 binop(Iop_Sub64, mkU64(32), mkexpr(amount))))));
6790
6791 return "rll";
6792}
6793
6794static HChar *
6795s390_irgen_RLLG(UChar r1, UChar r3, IRTemp op2addr)
6796{
6797 IRTemp amount = newTemp(Ity_I64);
6798 IRTemp op = newTemp(Ity_I64);
6799
6800 assign(amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
6801 assign(op, get_gpr_dw0(r3));
6802 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(op), unop(Iop_64to8,
6803 mkexpr(amount))), binop(Iop_Shr64, mkexpr(op), unop(Iop_64to8,
6804 binop(Iop_Sub64, mkU64(64), mkexpr(amount))))));
6805
6806 return "rllg";
6807}
6808
6809static HChar *
6810s390_irgen_RNSBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
6811{
6812 UChar from;
6813 UChar to;
6814 UChar rot;
6815 UChar t_bit;
6816 ULong mask;
6817 ULong maskc;
6818 IRTemp result = newTemp(Ity_I64);
6819 IRTemp op2 = newTemp(Ity_I64);
6820
6821 from = i3 & 63;
6822 to = i4 & 63;
6823 rot = i5 & 63;
6824 t_bit = i3 & 128;
6825 assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
6826 get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
6827 mkU8(64 - rot))));
6828 if (from <= to) {
6829 mask = ~0ULL;
6830 mask = (mask >> from) & (mask << (63 - to));
6831 maskc = ~mask;
6832 } else {
6833 maskc = ~0ULL;
6834 maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
6835 mask = ~maskc;
6836 }
6837 assign(result, binop(Iop_And64, binop(Iop_And64, get_gpr_dw0(r1), mkexpr(op2)
6838 ), mkU64(mask)));
6839 if (t_bit == 0) {
6840 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
6841 mkU64(maskc)), mkexpr(result)));
6842 }
6843 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6844
6845 return "rnsbg";
6846}
6847
6848static HChar *
6849s390_irgen_RXSBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
6850{
6851 UChar from;
6852 UChar to;
6853 UChar rot;
6854 UChar t_bit;
6855 ULong mask;
6856 ULong maskc;
6857 IRTemp result = newTemp(Ity_I64);
6858 IRTemp op2 = newTemp(Ity_I64);
6859
6860 from = i3 & 63;
6861 to = i4 & 63;
6862 rot = i5 & 63;
6863 t_bit = i3 & 128;
6864 assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
6865 get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
6866 mkU8(64 - rot))));
6867 if (from <= to) {
6868 mask = ~0ULL;
6869 mask = (mask >> from) & (mask << (63 - to));
6870 maskc = ~mask;
6871 } else {
6872 maskc = ~0ULL;
6873 maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
6874 mask = ~maskc;
6875 }
6876 assign(result, binop(Iop_And64, binop(Iop_Xor64, get_gpr_dw0(r1), mkexpr(op2)
6877 ), mkU64(mask)));
6878 if (t_bit == 0) {
6879 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
6880 mkU64(maskc)), mkexpr(result)));
6881 }
6882 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6883
6884 return "rxsbg";
6885}
6886
6887static HChar *
6888s390_irgen_ROSBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
6889{
6890 UChar from;
6891 UChar to;
6892 UChar rot;
6893 UChar t_bit;
6894 ULong mask;
6895 ULong maskc;
6896 IRTemp result = newTemp(Ity_I64);
6897 IRTemp op2 = newTemp(Ity_I64);
6898
6899 from = i3 & 63;
6900 to = i4 & 63;
6901 rot = i5 & 63;
6902 t_bit = i3 & 128;
6903 assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
6904 get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
6905 mkU8(64 - rot))));
6906 if (from <= to) {
6907 mask = ~0ULL;
6908 mask = (mask >> from) & (mask << (63 - to));
6909 maskc = ~mask;
6910 } else {
6911 maskc = ~0ULL;
6912 maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
6913 mask = ~maskc;
6914 }
6915 assign(result, binop(Iop_And64, binop(Iop_Or64, get_gpr_dw0(r1), mkexpr(op2)
6916 ), mkU64(mask)));
6917 if (t_bit == 0) {
6918 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
6919 mkU64(maskc)), mkexpr(result)));
6920 }
6921 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6922
6923 return "rosbg";
6924}
6925
6926static HChar *
6927s390_irgen_RISBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
6928{
6929 UChar from;
6930 UChar to;
6931 UChar rot;
6932 UChar z_bit;
6933 ULong mask;
6934 ULong maskc;
6935 IRTemp op2 = newTemp(Ity_I64);
6936 IRTemp result = newTemp(Ity_I64);
6937
6938 from = i3 & 63;
6939 to = i4 & 63;
6940 rot = i5 & 63;
6941 z_bit = i4 & 128;
6942 assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
6943 get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
6944 mkU8(64 - rot))));
6945 if (from <= to) {
6946 mask = ~0ULL;
6947 mask = (mask >> from) & (mask << (63 - to));
6948 maskc = ~mask;
6949 } else {
6950 maskc = ~0ULL;
6951 maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
6952 mask = ~maskc;
6953 }
6954 if (z_bit == 0) {
6955 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
6956 mkU64(maskc)), binop(Iop_And64, mkexpr(op2), mkU64(mask))));
6957 } else {
6958 put_gpr_dw0(r1, binop(Iop_And64, mkexpr(op2), mkU64(mask)));
6959 }
6960 assign(result, get_gpr_dw0(r1));
6961 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
6962
6963 return "risbg";
6964}
6965
6966static HChar *
6967s390_irgen_SAR(UChar r1, UChar r2)
6968{
6969 put_ar_w0(r1, get_gpr_w1(r2));
sewardj7ee97522011-05-09 21:45:04 +00006970 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00006971 s390_disasm(ENC3(MNM, AR, GPR), "sar", r1, r2);
6972
6973 return "sar";
6974}
6975
6976static HChar *
6977s390_irgen_SLDA(UChar r1, IRTemp op2addr)
6978{
6979 IRTemp p1 = newTemp(Ity_I64);
6980 IRTemp p2 = newTemp(Ity_I64);
6981 IRTemp op = newTemp(Ity_I64);
6982 IRTemp result = newTemp(Ity_I64);
florian417b22d2012-07-13 13:41:41 +00006983 ULong sign_mask;
sewardj2019a972011-03-07 16:04:07 +00006984 IRTemp shift_amount = newTemp(Ity_I64);
6985
6986 assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
6987 assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
6988 assign(op, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1), mkU8(32)), mkexpr(p2)
6989 ));
6990 sign_mask = 1ULL << 63;
6991 assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
6992 assign(result, binop(Iop_Or64, binop(Iop_And64, binop(Iop_Shl64, mkexpr(op),
florian417b22d2012-07-13 13:41:41 +00006993 unop(Iop_64to8, mkexpr(shift_amount))), mkU64(~sign_mask)),
6994 binop(Iop_And64, mkexpr(op), mkU64(sign_mask))));
sewardj2019a972011-03-07 16:04:07 +00006995 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6996 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6997 s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_64, op, shift_amount);
6998
6999 return "slda";
7000}
7001
7002static HChar *
7003s390_irgen_SLDL(UChar r1, IRTemp op2addr)
7004{
7005 IRTemp p1 = newTemp(Ity_I64);
7006 IRTemp p2 = newTemp(Ity_I64);
7007 IRTemp result = newTemp(Ity_I64);
7008
7009 assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
7010 assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
7011 assign(result, binop(Iop_Shl64, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1),
7012 mkU8(32)), mkexpr(p2)), unop(Iop_64to8, binop(Iop_And64,
7013 mkexpr(op2addr), mkU64(63)))));
7014 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
7015 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
7016
7017 return "sldl";
7018}
7019
7020static HChar *
7021s390_irgen_SLA(UChar r1, IRTemp op2addr)
7022{
7023 IRTemp uop = newTemp(Ity_I32);
7024 IRTemp result = newTemp(Ity_I32);
7025 UInt sign_mask;
7026 IRTemp shift_amount = newTemp(Ity_I64);
7027 IRTemp op = newTemp(Ity_I32);
7028
7029 assign(op, get_gpr_w1(r1));
7030 assign(uop, get_gpr_w1(r1));
7031 sign_mask = 2147483648U;
7032 assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7033 assign(result, binop(Iop_Or32, binop(Iop_And32, binop(Iop_Shl32, mkexpr(uop),
7034 unop(Iop_64to8, mkexpr(shift_amount))), mkU32(~sign_mask)),
7035 binop(Iop_And32, mkexpr(uop), mkU32(sign_mask))));
7036 put_gpr_w1(r1, mkexpr(result));
7037 s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_32, op, shift_amount);
7038
7039 return "sla";
7040}
7041
7042static HChar *
7043s390_irgen_SLAK(UChar r1, UChar r3, IRTemp op2addr)
7044{
7045 IRTemp uop = newTemp(Ity_I32);
7046 IRTemp result = newTemp(Ity_I32);
7047 UInt sign_mask;
7048 IRTemp shift_amount = newTemp(Ity_I64);
7049 IRTemp op = newTemp(Ity_I32);
7050
7051 assign(op, get_gpr_w1(r3));
7052 assign(uop, get_gpr_w1(r3));
7053 sign_mask = 2147483648U;
7054 assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7055 assign(result, binop(Iop_Or32, binop(Iop_And32, binop(Iop_Shl32, mkexpr(uop),
7056 unop(Iop_64to8, mkexpr(shift_amount))), mkU32(~sign_mask)),
7057 binop(Iop_And32, mkexpr(uop), mkU32(sign_mask))));
7058 put_gpr_w1(r1, mkexpr(result));
7059 s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_32, op, shift_amount);
7060
7061 return "slak";
7062}
7063
7064static HChar *
7065s390_irgen_SLAG(UChar r1, UChar r3, IRTemp op2addr)
7066{
7067 IRTemp uop = newTemp(Ity_I64);
7068 IRTemp result = newTemp(Ity_I64);
7069 ULong sign_mask;
7070 IRTemp shift_amount = newTemp(Ity_I64);
7071 IRTemp op = newTemp(Ity_I64);
7072
7073 assign(op, get_gpr_dw0(r3));
7074 assign(uop, get_gpr_dw0(r3));
7075 sign_mask = 9223372036854775808ULL;
7076 assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7077 assign(result, binop(Iop_Or64, binop(Iop_And64, binop(Iop_Shl64, mkexpr(uop),
7078 unop(Iop_64to8, mkexpr(shift_amount))), mkU64(~sign_mask)),
7079 binop(Iop_And64, mkexpr(uop), mkU64(sign_mask))));
7080 put_gpr_dw0(r1, mkexpr(result));
7081 s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_64, op, shift_amount);
7082
7083 return "slag";
7084}
7085
7086static HChar *
7087s390_irgen_SLL(UChar r1, IRTemp op2addr)
7088{
7089 put_gpr_w1(r1, binop(Iop_Shl32, get_gpr_w1(r1), unop(Iop_64to8,
7090 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
7091
7092 return "sll";
7093}
7094
7095static HChar *
7096s390_irgen_SLLK(UChar r1, UChar r3, IRTemp op2addr)
7097{
7098 put_gpr_w1(r1, binop(Iop_Shl32, get_gpr_w1(r3), unop(Iop_64to8,
7099 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
7100
7101 return "sllk";
7102}
7103
7104static HChar *
7105s390_irgen_SLLG(UChar r1, UChar r3, IRTemp op2addr)
7106{
7107 put_gpr_dw0(r1, binop(Iop_Shl64, get_gpr_dw0(r3), unop(Iop_64to8,
7108 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
7109
7110 return "sllg";
7111}
7112
7113static HChar *
7114s390_irgen_SRDA(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_Sar64, 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 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7128
7129 return "srda";
7130}
7131
7132static HChar *
7133s390_irgen_SRDL(UChar r1, IRTemp op2addr)
7134{
7135 IRTemp p1 = newTemp(Ity_I64);
7136 IRTemp p2 = newTemp(Ity_I64);
7137 IRTemp result = newTemp(Ity_I64);
7138
7139 assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
7140 assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
7141 assign(result, binop(Iop_Shr64, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1),
7142 mkU8(32)), mkexpr(p2)), unop(Iop_64to8, binop(Iop_And64,
7143 mkexpr(op2addr), mkU64(63)))));
7144 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
7145 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
7146
7147 return "srdl";
7148}
7149
7150static HChar *
7151s390_irgen_SRA(UChar r1, IRTemp op2addr)
7152{
7153 IRTemp result = newTemp(Ity_I32);
7154 IRTemp op = newTemp(Ity_I32);
7155
7156 assign(op, get_gpr_w1(r1));
7157 assign(result, binop(Iop_Sar32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7158 mkexpr(op2addr), mkU64(63)))));
7159 put_gpr_w1(r1, mkexpr(result));
7160 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7161
7162 return "sra";
7163}
7164
7165static HChar *
7166s390_irgen_SRAK(UChar r1, UChar r3, IRTemp op2addr)
7167{
7168 IRTemp result = newTemp(Ity_I32);
7169 IRTemp op = newTemp(Ity_I32);
7170
7171 assign(op, get_gpr_w1(r3));
7172 assign(result, binop(Iop_Sar32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7173 mkexpr(op2addr), mkU64(63)))));
7174 put_gpr_w1(r1, mkexpr(result));
7175 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7176
7177 return "srak";
7178}
7179
7180static HChar *
7181s390_irgen_SRAG(UChar r1, UChar r3, IRTemp op2addr)
7182{
7183 IRTemp result = newTemp(Ity_I64);
7184 IRTemp op = newTemp(Ity_I64);
7185
7186 assign(op, get_gpr_dw0(r3));
7187 assign(result, binop(Iop_Sar64, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7188 mkexpr(op2addr), mkU64(63)))));
7189 put_gpr_dw0(r1, mkexpr(result));
7190 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7191
7192 return "srag";
7193}
7194
7195static HChar *
7196s390_irgen_SRL(UChar r1, IRTemp op2addr)
7197{
7198 IRTemp op = newTemp(Ity_I32);
7199
7200 assign(op, get_gpr_w1(r1));
7201 put_gpr_w1(r1, binop(Iop_Shr32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7202 mkexpr(op2addr), mkU64(63)))));
7203
7204 return "srl";
7205}
7206
7207static HChar *
7208s390_irgen_SRLK(UChar r1, UChar r3, IRTemp op2addr)
7209{
7210 IRTemp op = newTemp(Ity_I32);
7211
7212 assign(op, get_gpr_w1(r3));
7213 put_gpr_w1(r1, binop(Iop_Shr32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7214 mkexpr(op2addr), mkU64(63)))));
7215
7216 return "srlk";
7217}
7218
7219static HChar *
7220s390_irgen_SRLG(UChar r1, UChar r3, IRTemp op2addr)
7221{
7222 IRTemp op = newTemp(Ity_I64);
7223
7224 assign(op, get_gpr_dw0(r3));
7225 put_gpr_dw0(r1, binop(Iop_Shr64, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7226 mkexpr(op2addr), mkU64(63)))));
7227
7228 return "srlg";
7229}
7230
7231static HChar *
7232s390_irgen_ST(UChar r1, IRTemp op2addr)
7233{
7234 store(mkexpr(op2addr), get_gpr_w1(r1));
7235
7236 return "st";
7237}
7238
7239static HChar *
7240s390_irgen_STY(UChar r1, IRTemp op2addr)
7241{
7242 store(mkexpr(op2addr), get_gpr_w1(r1));
7243
7244 return "sty";
7245}
7246
7247static HChar *
7248s390_irgen_STG(UChar r1, IRTemp op2addr)
7249{
7250 store(mkexpr(op2addr), get_gpr_dw0(r1));
7251
7252 return "stg";
7253}
7254
7255static HChar *
7256s390_irgen_STRL(UChar r1, UInt i2)
7257{
7258 store(mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)),
7259 get_gpr_w1(r1));
7260
7261 return "strl";
7262}
7263
7264static HChar *
7265s390_irgen_STGRL(UChar r1, UInt i2)
7266{
7267 store(mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)),
7268 get_gpr_dw0(r1));
7269
7270 return "stgrl";
7271}
7272
7273static HChar *
7274s390_irgen_STC(UChar r1, IRTemp op2addr)
7275{
7276 store(mkexpr(op2addr), get_gpr_b7(r1));
7277
7278 return "stc";
7279}
7280
7281static HChar *
7282s390_irgen_STCY(UChar r1, IRTemp op2addr)
7283{
7284 store(mkexpr(op2addr), get_gpr_b7(r1));
7285
7286 return "stcy";
7287}
7288
7289static HChar *
7290s390_irgen_STCH(UChar r1, IRTemp op2addr)
7291{
7292 store(mkexpr(op2addr), get_gpr_b3(r1));
7293
7294 return "stch";
7295}
7296
7297static HChar *
7298s390_irgen_STCM(UChar r1, UChar r3, IRTemp op2addr)
7299{
7300 UChar mask;
7301 UChar n;
7302
7303 mask = (UChar)r3;
7304 n = 0;
7305 if ((mask & 8) != 0) {
7306 store(mkexpr(op2addr), get_gpr_b4(r1));
7307 n = n + 1;
7308 }
7309 if ((mask & 4) != 0) {
7310 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b5(r1));
7311 n = n + 1;
7312 }
7313 if ((mask & 2) != 0) {
7314 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b6(r1));
7315 n = n + 1;
7316 }
7317 if ((mask & 1) != 0) {
7318 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b7(r1));
7319 }
7320
7321 return "stcm";
7322}
7323
7324static HChar *
7325s390_irgen_STCMY(UChar r1, UChar r3, IRTemp op2addr)
7326{
7327 UChar mask;
7328 UChar n;
7329
7330 mask = (UChar)r3;
7331 n = 0;
7332 if ((mask & 8) != 0) {
7333 store(mkexpr(op2addr), get_gpr_b4(r1));
7334 n = n + 1;
7335 }
7336 if ((mask & 4) != 0) {
7337 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b5(r1));
7338 n = n + 1;
7339 }
7340 if ((mask & 2) != 0) {
7341 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b6(r1));
7342 n = n + 1;
7343 }
7344 if ((mask & 1) != 0) {
7345 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b7(r1));
7346 }
7347
7348 return "stcmy";
7349}
7350
7351static HChar *
7352s390_irgen_STCMH(UChar r1, UChar r3, IRTemp op2addr)
7353{
7354 UChar mask;
7355 UChar n;
7356
7357 mask = (UChar)r3;
7358 n = 0;
7359 if ((mask & 8) != 0) {
7360 store(mkexpr(op2addr), get_gpr_b0(r1));
7361 n = n + 1;
7362 }
7363 if ((mask & 4) != 0) {
7364 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b1(r1));
7365 n = n + 1;
7366 }
7367 if ((mask & 2) != 0) {
7368 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b2(r1));
7369 n = n + 1;
7370 }
7371 if ((mask & 1) != 0) {
7372 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b3(r1));
7373 }
7374
7375 return "stcmh";
7376}
7377
7378static HChar *
7379s390_irgen_STH(UChar r1, IRTemp op2addr)
7380{
7381 store(mkexpr(op2addr), get_gpr_hw3(r1));
7382
7383 return "sth";
7384}
7385
7386static HChar *
7387s390_irgen_STHY(UChar r1, IRTemp op2addr)
7388{
7389 store(mkexpr(op2addr), get_gpr_hw3(r1));
7390
7391 return "sthy";
7392}
7393
7394static HChar *
7395s390_irgen_STHRL(UChar r1, UInt i2)
7396{
7397 store(mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)),
7398 get_gpr_hw3(r1));
7399
7400 return "sthrl";
7401}
7402
7403static HChar *
7404s390_irgen_STHH(UChar r1, IRTemp op2addr)
7405{
7406 store(mkexpr(op2addr), get_gpr_hw1(r1));
7407
7408 return "sthh";
7409}
7410
7411static HChar *
7412s390_irgen_STFH(UChar r1, IRTemp op2addr)
7413{
7414 store(mkexpr(op2addr), get_gpr_w0(r1));
7415
7416 return "stfh";
7417}
7418
7419static HChar *
sewardjd7bde722011-04-05 13:19:33 +00007420s390_irgen_STOC(UChar r1, IRTemp op2addr)
7421{
7422 /* condition is checked in format handler */
7423 store(mkexpr(op2addr), get_gpr_w1(r1));
7424
7425 return "stoc";
7426}
7427
7428static HChar *
7429s390_irgen_STOCG(UChar r1, IRTemp op2addr)
7430{
7431 /* condition is checked in format handler */
7432 store(mkexpr(op2addr), get_gpr_dw0(r1));
7433
7434 return "stocg";
7435}
7436
7437static HChar *
sewardj2019a972011-03-07 16:04:07 +00007438s390_irgen_STPQ(UChar r1, IRTemp op2addr)
7439{
7440 store(mkexpr(op2addr), get_gpr_dw0(r1));
7441 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(8)), get_gpr_dw0(r1 + 1));
7442
7443 return "stpq";
7444}
7445
7446static HChar *
7447s390_irgen_STRVH(UChar r1, IRTemp op2addr)
7448{
7449 store(mkexpr(op2addr), get_gpr_b7(r1));
7450 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(1)), get_gpr_b6(r1));
7451
7452 return "strvh";
7453}
7454
7455static HChar *
7456s390_irgen_STRV(UChar r1, IRTemp op2addr)
7457{
7458 store(mkexpr(op2addr), get_gpr_b7(r1));
7459 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(1)), get_gpr_b6(r1));
7460 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(2)), get_gpr_b5(r1));
7461 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(3)), get_gpr_b4(r1));
7462
7463 return "strv";
7464}
7465
7466static HChar *
7467s390_irgen_STRVG(UChar r1, IRTemp op2addr)
7468{
7469 store(mkexpr(op2addr), get_gpr_b7(r1));
7470 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(1)), get_gpr_b6(r1));
7471 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(2)), get_gpr_b5(r1));
7472 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(3)), get_gpr_b4(r1));
7473 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(4)), get_gpr_b3(r1));
7474 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(5)), get_gpr_b2(r1));
7475 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(6)), get_gpr_b1(r1));
7476 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(7)), get_gpr_b0(r1));
7477
7478 return "strvg";
7479}
7480
7481static HChar *
7482s390_irgen_SR(UChar r1, UChar r2)
7483{
7484 IRTemp op1 = newTemp(Ity_I32);
7485 IRTemp op2 = newTemp(Ity_I32);
7486 IRTemp result = newTemp(Ity_I32);
7487
7488 assign(op1, get_gpr_w1(r1));
7489 assign(op2, get_gpr_w1(r2));
7490 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7491 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
7492 put_gpr_w1(r1, mkexpr(result));
7493
7494 return "sr";
7495}
7496
7497static HChar *
7498s390_irgen_SGR(UChar r1, UChar r2)
7499{
7500 IRTemp op1 = newTemp(Ity_I64);
7501 IRTemp op2 = newTemp(Ity_I64);
7502 IRTemp result = newTemp(Ity_I64);
7503
7504 assign(op1, get_gpr_dw0(r1));
7505 assign(op2, get_gpr_dw0(r2));
7506 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7507 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
7508 put_gpr_dw0(r1, mkexpr(result));
7509
7510 return "sgr";
7511}
7512
7513static HChar *
7514s390_irgen_SGFR(UChar r1, UChar r2)
7515{
7516 IRTemp op1 = newTemp(Ity_I64);
7517 IRTemp op2 = newTemp(Ity_I64);
7518 IRTemp result = newTemp(Ity_I64);
7519
7520 assign(op1, get_gpr_dw0(r1));
7521 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
7522 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7523 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
7524 put_gpr_dw0(r1, mkexpr(result));
7525
7526 return "sgfr";
7527}
7528
7529static HChar *
7530s390_irgen_SRK(UChar r3, UChar r1, UChar r2)
7531{
7532 IRTemp op2 = newTemp(Ity_I32);
7533 IRTemp op3 = newTemp(Ity_I32);
7534 IRTemp result = newTemp(Ity_I32);
7535
7536 assign(op2, get_gpr_w1(r2));
7537 assign(op3, get_gpr_w1(r3));
7538 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
7539 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op2, op3);
7540 put_gpr_w1(r1, mkexpr(result));
7541
7542 return "srk";
7543}
7544
7545static HChar *
7546s390_irgen_SGRK(UChar r3, UChar r1, UChar r2)
7547{
7548 IRTemp op2 = newTemp(Ity_I64);
7549 IRTemp op3 = newTemp(Ity_I64);
7550 IRTemp result = newTemp(Ity_I64);
7551
7552 assign(op2, get_gpr_dw0(r2));
7553 assign(op3, get_gpr_dw0(r3));
7554 assign(result, binop(Iop_Sub64, mkexpr(op2), mkexpr(op3)));
7555 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op2, op3);
7556 put_gpr_dw0(r1, mkexpr(result));
7557
7558 return "sgrk";
7559}
7560
7561static HChar *
7562s390_irgen_S(UChar r1, IRTemp op2addr)
7563{
7564 IRTemp op1 = newTemp(Ity_I32);
7565 IRTemp op2 = newTemp(Ity_I32);
7566 IRTemp result = newTemp(Ity_I32);
7567
7568 assign(op1, get_gpr_w1(r1));
7569 assign(op2, load(Ity_I32, mkexpr(op2addr)));
7570 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7571 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
7572 put_gpr_w1(r1, mkexpr(result));
7573
7574 return "s";
7575}
7576
7577static HChar *
7578s390_irgen_SY(UChar r1, IRTemp op2addr)
7579{
7580 IRTemp op1 = newTemp(Ity_I32);
7581 IRTemp op2 = newTemp(Ity_I32);
7582 IRTemp result = newTemp(Ity_I32);
7583
7584 assign(op1, get_gpr_w1(r1));
7585 assign(op2, load(Ity_I32, mkexpr(op2addr)));
7586 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7587 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
7588 put_gpr_w1(r1, mkexpr(result));
7589
7590 return "sy";
7591}
7592
7593static HChar *
7594s390_irgen_SG(UChar r1, IRTemp op2addr)
7595{
7596 IRTemp op1 = newTemp(Ity_I64);
7597 IRTemp op2 = newTemp(Ity_I64);
7598 IRTemp result = newTemp(Ity_I64);
7599
7600 assign(op1, get_gpr_dw0(r1));
7601 assign(op2, load(Ity_I64, mkexpr(op2addr)));
7602 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7603 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
7604 put_gpr_dw0(r1, mkexpr(result));
7605
7606 return "sg";
7607}
7608
7609static HChar *
7610s390_irgen_SGF(UChar r1, IRTemp op2addr)
7611{
7612 IRTemp op1 = newTemp(Ity_I64);
7613 IRTemp op2 = newTemp(Ity_I64);
7614 IRTemp result = newTemp(Ity_I64);
7615
7616 assign(op1, get_gpr_dw0(r1));
7617 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
7618 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7619 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
7620 put_gpr_dw0(r1, mkexpr(result));
7621
7622 return "sgf";
7623}
7624
7625static HChar *
7626s390_irgen_SH(UChar r1, IRTemp op2addr)
7627{
7628 IRTemp op1 = newTemp(Ity_I32);
7629 IRTemp op2 = newTemp(Ity_I32);
7630 IRTemp result = newTemp(Ity_I32);
7631
7632 assign(op1, get_gpr_w1(r1));
7633 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
7634 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7635 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
7636 put_gpr_w1(r1, mkexpr(result));
7637
7638 return "sh";
7639}
7640
7641static HChar *
7642s390_irgen_SHY(UChar r1, IRTemp op2addr)
7643{
7644 IRTemp op1 = newTemp(Ity_I32);
7645 IRTemp op2 = newTemp(Ity_I32);
7646 IRTemp result = newTemp(Ity_I32);
7647
7648 assign(op1, get_gpr_w1(r1));
7649 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
7650 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7651 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
7652 put_gpr_w1(r1, mkexpr(result));
7653
7654 return "shy";
7655}
7656
7657static HChar *
7658s390_irgen_SHHHR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
7659{
7660 IRTemp op2 = newTemp(Ity_I32);
7661 IRTemp op3 = newTemp(Ity_I32);
7662 IRTemp result = newTemp(Ity_I32);
7663
7664 assign(op2, get_gpr_w0(r1));
7665 assign(op3, get_gpr_w0(r2));
7666 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
7667 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op2, op3);
7668 put_gpr_w0(r1, mkexpr(result));
7669
7670 return "shhhr";
7671}
7672
7673static HChar *
7674s390_irgen_SHHLR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
7675{
7676 IRTemp op2 = newTemp(Ity_I32);
7677 IRTemp op3 = newTemp(Ity_I32);
7678 IRTemp result = newTemp(Ity_I32);
7679
7680 assign(op2, get_gpr_w0(r1));
7681 assign(op3, get_gpr_w1(r2));
7682 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
7683 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op2, op3);
7684 put_gpr_w0(r1, mkexpr(result));
7685
7686 return "shhlr";
7687}
7688
7689static HChar *
7690s390_irgen_SLR(UChar r1, UChar r2)
7691{
7692 IRTemp op1 = newTemp(Ity_I32);
7693 IRTemp op2 = newTemp(Ity_I32);
7694 IRTemp result = newTemp(Ity_I32);
7695
7696 assign(op1, get_gpr_w1(r1));
7697 assign(op2, get_gpr_w1(r2));
7698 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7699 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, op2);
7700 put_gpr_w1(r1, mkexpr(result));
7701
7702 return "slr";
7703}
7704
7705static HChar *
7706s390_irgen_SLGR(UChar r1, UChar r2)
7707{
7708 IRTemp op1 = newTemp(Ity_I64);
7709 IRTemp op2 = newTemp(Ity_I64);
7710 IRTemp result = newTemp(Ity_I64);
7711
7712 assign(op1, get_gpr_dw0(r1));
7713 assign(op2, get_gpr_dw0(r2));
7714 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7715 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
7716 put_gpr_dw0(r1, mkexpr(result));
7717
7718 return "slgr";
7719}
7720
7721static HChar *
7722s390_irgen_SLGFR(UChar r1, UChar r2)
7723{
7724 IRTemp op1 = newTemp(Ity_I64);
7725 IRTemp op2 = newTemp(Ity_I64);
7726 IRTemp result = newTemp(Ity_I64);
7727
7728 assign(op1, get_gpr_dw0(r1));
7729 assign(op2, unop(Iop_32Uto64, get_gpr_w1(r2)));
7730 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7731 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
7732 put_gpr_dw0(r1, mkexpr(result));
7733
7734 return "slgfr";
7735}
7736
7737static HChar *
7738s390_irgen_SLRK(UChar r3, UChar r1, UChar r2)
7739{
7740 IRTemp op2 = newTemp(Ity_I32);
7741 IRTemp op3 = newTemp(Ity_I32);
7742 IRTemp result = newTemp(Ity_I32);
7743
7744 assign(op2, get_gpr_w1(r2));
7745 assign(op3, get_gpr_w1(r3));
7746 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
7747 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op2, op3);
7748 put_gpr_w1(r1, mkexpr(result));
7749
7750 return "slrk";
7751}
7752
7753static HChar *
7754s390_irgen_SLGRK(UChar r3, UChar r1, UChar r2)
7755{
7756 IRTemp op2 = newTemp(Ity_I64);
7757 IRTemp op3 = newTemp(Ity_I64);
7758 IRTemp result = newTemp(Ity_I64);
7759
7760 assign(op2, get_gpr_dw0(r2));
7761 assign(op3, get_gpr_dw0(r3));
7762 assign(result, binop(Iop_Sub64, mkexpr(op2), mkexpr(op3)));
7763 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op2, op3);
7764 put_gpr_dw0(r1, mkexpr(result));
7765
7766 return "slgrk";
7767}
7768
7769static HChar *
7770s390_irgen_SL(UChar r1, IRTemp op2addr)
7771{
7772 IRTemp op1 = newTemp(Ity_I32);
7773 IRTemp op2 = newTemp(Ity_I32);
7774 IRTemp result = newTemp(Ity_I32);
7775
7776 assign(op1, get_gpr_w1(r1));
7777 assign(op2, load(Ity_I32, mkexpr(op2addr)));
7778 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7779 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, op2);
7780 put_gpr_w1(r1, mkexpr(result));
7781
7782 return "sl";
7783}
7784
7785static HChar *
7786s390_irgen_SLY(UChar r1, IRTemp op2addr)
7787{
7788 IRTemp op1 = newTemp(Ity_I32);
7789 IRTemp op2 = newTemp(Ity_I32);
7790 IRTemp result = newTemp(Ity_I32);
7791
7792 assign(op1, get_gpr_w1(r1));
7793 assign(op2, load(Ity_I32, mkexpr(op2addr)));
7794 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7795 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, op2);
7796 put_gpr_w1(r1, mkexpr(result));
7797
7798 return "sly";
7799}
7800
7801static HChar *
7802s390_irgen_SLG(UChar r1, IRTemp op2addr)
7803{
7804 IRTemp op1 = newTemp(Ity_I64);
7805 IRTemp op2 = newTemp(Ity_I64);
7806 IRTemp result = newTemp(Ity_I64);
7807
7808 assign(op1, get_gpr_dw0(r1));
7809 assign(op2, load(Ity_I64, mkexpr(op2addr)));
7810 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7811 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
7812 put_gpr_dw0(r1, mkexpr(result));
7813
7814 return "slg";
7815}
7816
7817static HChar *
7818s390_irgen_SLGF(UChar r1, IRTemp op2addr)
7819{
7820 IRTemp op1 = newTemp(Ity_I64);
7821 IRTemp op2 = newTemp(Ity_I64);
7822 IRTemp result = newTemp(Ity_I64);
7823
7824 assign(op1, get_gpr_dw0(r1));
7825 assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
7826 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7827 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
7828 put_gpr_dw0(r1, mkexpr(result));
7829
7830 return "slgf";
7831}
7832
7833static HChar *
7834s390_irgen_SLFI(UChar r1, UInt i2)
7835{
7836 IRTemp op1 = newTemp(Ity_I32);
7837 UInt op2;
7838 IRTemp result = newTemp(Ity_I32);
7839
7840 assign(op1, get_gpr_w1(r1));
7841 op2 = i2;
7842 assign(result, binop(Iop_Sub32, mkexpr(op1), mkU32(op2)));
7843 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, mktemp(Ity_I32,
7844 mkU32(op2)));
7845 put_gpr_w1(r1, mkexpr(result));
7846
7847 return "slfi";
7848}
7849
7850static HChar *
7851s390_irgen_SLGFI(UChar r1, UInt i2)
7852{
7853 IRTemp op1 = newTemp(Ity_I64);
7854 ULong op2;
7855 IRTemp result = newTemp(Ity_I64);
7856
7857 assign(op1, get_gpr_dw0(r1));
7858 op2 = (ULong)i2;
7859 assign(result, binop(Iop_Sub64, mkexpr(op1), mkU64(op2)));
7860 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, mktemp(Ity_I64,
7861 mkU64(op2)));
7862 put_gpr_dw0(r1, mkexpr(result));
7863
7864 return "slgfi";
7865}
7866
7867static HChar *
7868s390_irgen_SLHHHR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
7869{
7870 IRTemp op2 = newTemp(Ity_I32);
7871 IRTemp op3 = newTemp(Ity_I32);
7872 IRTemp result = newTemp(Ity_I32);
7873
7874 assign(op2, get_gpr_w0(r1));
7875 assign(op3, get_gpr_w0(r2));
7876 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
7877 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op2, op3);
7878 put_gpr_w0(r1, mkexpr(result));
7879
7880 return "slhhhr";
7881}
7882
7883static HChar *
7884s390_irgen_SLHHLR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
7885{
7886 IRTemp op2 = newTemp(Ity_I32);
7887 IRTemp op3 = newTemp(Ity_I32);
7888 IRTemp result = newTemp(Ity_I32);
7889
7890 assign(op2, get_gpr_w0(r1));
7891 assign(op3, get_gpr_w1(r2));
7892 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
7893 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op2, op3);
7894 put_gpr_w0(r1, mkexpr(result));
7895
7896 return "slhhlr";
7897}
7898
7899static HChar *
7900s390_irgen_SLBR(UChar r1, UChar r2)
7901{
7902 IRTemp op1 = newTemp(Ity_I32);
7903 IRTemp op2 = newTemp(Ity_I32);
7904 IRTemp result = newTemp(Ity_I32);
7905 IRTemp borrow_in = newTemp(Ity_I32);
7906
7907 assign(op1, get_gpr_w1(r1));
7908 assign(op2, get_gpr_w1(r2));
7909 assign(borrow_in, binop(Iop_Sub32, mkU32(1), binop(Iop_Shr32,
7910 s390_call_calculate_cc(), mkU8(1))));
7911 assign(result, binop(Iop_Sub32, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)),
7912 mkexpr(borrow_in)));
7913 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_32, op1, op2, borrow_in);
7914 put_gpr_w1(r1, mkexpr(result));
7915
7916 return "slbr";
7917}
7918
7919static HChar *
7920s390_irgen_SLBGR(UChar r1, UChar r2)
7921{
7922 IRTemp op1 = newTemp(Ity_I64);
7923 IRTemp op2 = newTemp(Ity_I64);
7924 IRTemp result = newTemp(Ity_I64);
7925 IRTemp borrow_in = newTemp(Ity_I64);
7926
7927 assign(op1, get_gpr_dw0(r1));
7928 assign(op2, get_gpr_dw0(r2));
7929 assign(borrow_in, unop(Iop_32Uto64, binop(Iop_Sub32, mkU32(1),
7930 binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)))));
7931 assign(result, binop(Iop_Sub64, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)),
7932 mkexpr(borrow_in)));
7933 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_64, op1, op2, borrow_in);
7934 put_gpr_dw0(r1, mkexpr(result));
7935
7936 return "slbgr";
7937}
7938
7939static HChar *
7940s390_irgen_SLB(UChar r1, IRTemp op2addr)
7941{
7942 IRTemp op1 = newTemp(Ity_I32);
7943 IRTemp op2 = newTemp(Ity_I32);
7944 IRTemp result = newTemp(Ity_I32);
7945 IRTemp borrow_in = newTemp(Ity_I32);
7946
7947 assign(op1, get_gpr_w1(r1));
7948 assign(op2, load(Ity_I32, mkexpr(op2addr)));
7949 assign(borrow_in, binop(Iop_Sub32, mkU32(1), binop(Iop_Shr32,
7950 s390_call_calculate_cc(), mkU8(1))));
7951 assign(result, binop(Iop_Sub32, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)),
7952 mkexpr(borrow_in)));
7953 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_32, op1, op2, borrow_in);
7954 put_gpr_w1(r1, mkexpr(result));
7955
7956 return "slb";
7957}
7958
7959static HChar *
7960s390_irgen_SLBG(UChar r1, IRTemp op2addr)
7961{
7962 IRTemp op1 = newTemp(Ity_I64);
7963 IRTemp op2 = newTemp(Ity_I64);
7964 IRTemp result = newTemp(Ity_I64);
7965 IRTemp borrow_in = newTemp(Ity_I64);
7966
7967 assign(op1, get_gpr_dw0(r1));
7968 assign(op2, load(Ity_I64, mkexpr(op2addr)));
7969 assign(borrow_in, unop(Iop_32Uto64, binop(Iop_Sub32, mkU32(1),
7970 binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)))));
7971 assign(result, binop(Iop_Sub64, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)),
7972 mkexpr(borrow_in)));
7973 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_64, op1, op2, borrow_in);
7974 put_gpr_dw0(r1, mkexpr(result));
7975
7976 return "slbg";
7977}
7978
7979static HChar *
7980s390_irgen_SVC(UChar i)
7981{
7982 IRTemp sysno = newTemp(Ity_I64);
7983
7984 if (i != 0) {
7985 assign(sysno, mkU64(i));
7986 } else {
7987 assign(sysno, unop(Iop_32Uto64, get_gpr_w1(1)));
7988 }
7989 system_call(mkexpr(sysno));
7990
7991 return "svc";
7992}
7993
7994static HChar *
sewardj2019a972011-03-07 16:04:07 +00007995s390_irgen_TM(UChar i2, IRTemp op1addr)
7996{
7997 UChar mask;
7998 IRTemp value = newTemp(Ity_I8);
7999
8000 mask = i2;
8001 assign(value, load(Ity_I8, mkexpr(op1addr)));
8002 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_8, value, mktemp(Ity_I8,
8003 mkU8(mask)));
8004
8005 return "tm";
8006}
8007
8008static HChar *
8009s390_irgen_TMY(UChar i2, IRTemp op1addr)
8010{
8011 UChar mask;
8012 IRTemp value = newTemp(Ity_I8);
8013
8014 mask = i2;
8015 assign(value, load(Ity_I8, mkexpr(op1addr)));
8016 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_8, value, mktemp(Ity_I8,
8017 mkU8(mask)));
8018
8019 return "tmy";
8020}
8021
8022static HChar *
8023s390_irgen_TMHH(UChar r1, UShort i2)
8024{
8025 UShort mask;
8026 IRTemp value = newTemp(Ity_I16);
8027
8028 mask = i2;
8029 assign(value, get_gpr_hw0(r1));
8030 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
8031 mkU16(mask)));
8032
8033 return "tmhh";
8034}
8035
8036static HChar *
8037s390_irgen_TMHL(UChar r1, UShort i2)
8038{
8039 UShort mask;
8040 IRTemp value = newTemp(Ity_I16);
8041
8042 mask = i2;
8043 assign(value, get_gpr_hw1(r1));
8044 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
8045 mkU16(mask)));
8046
8047 return "tmhl";
8048}
8049
8050static HChar *
8051s390_irgen_TMLH(UChar r1, UShort i2)
8052{
8053 UShort mask;
8054 IRTemp value = newTemp(Ity_I16);
8055
8056 mask = i2;
8057 assign(value, get_gpr_hw2(r1));
8058 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
8059 mkU16(mask)));
8060
8061 return "tmlh";
8062}
8063
8064static HChar *
8065s390_irgen_TMLL(UChar r1, UShort i2)
8066{
8067 UShort mask;
8068 IRTemp value = newTemp(Ity_I16);
8069
8070 mask = i2;
8071 assign(value, get_gpr_hw3(r1));
8072 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
8073 mkU16(mask)));
8074
8075 return "tmll";
8076}
8077
8078static HChar *
8079s390_irgen_EFPC(UChar r1)
8080{
8081 put_gpr_w1(r1, get_fpc_w0());
8082
8083 return "efpc";
8084}
8085
8086static HChar *
8087s390_irgen_LER(UChar r1, UChar r2)
8088{
8089 put_fpr_w0(r1, get_fpr_w0(r2));
8090
8091 return "ler";
8092}
8093
8094static HChar *
8095s390_irgen_LDR(UChar r1, UChar r2)
8096{
8097 put_fpr_dw0(r1, get_fpr_dw0(r2));
8098
8099 return "ldr";
8100}
8101
8102static HChar *
8103s390_irgen_LXR(UChar r1, UChar r2)
8104{
8105 put_fpr_dw0(r1, get_fpr_dw0(r2));
8106 put_fpr_dw0(r1 + 2, get_fpr_dw0(r2 + 2));
8107
8108 return "lxr";
8109}
8110
8111static HChar *
8112s390_irgen_LE(UChar r1, IRTemp op2addr)
8113{
8114 put_fpr_w0(r1, load(Ity_F32, mkexpr(op2addr)));
8115
8116 return "le";
8117}
8118
8119static HChar *
8120s390_irgen_LD(UChar r1, IRTemp op2addr)
8121{
8122 put_fpr_dw0(r1, load(Ity_F64, mkexpr(op2addr)));
8123
8124 return "ld";
8125}
8126
8127static HChar *
8128s390_irgen_LEY(UChar r1, IRTemp op2addr)
8129{
8130 put_fpr_w0(r1, load(Ity_F32, mkexpr(op2addr)));
8131
8132 return "ley";
8133}
8134
8135static HChar *
8136s390_irgen_LDY(UChar r1, IRTemp op2addr)
8137{
8138 put_fpr_dw0(r1, load(Ity_F64, mkexpr(op2addr)));
8139
8140 return "ldy";
8141}
8142
8143static HChar *
8144s390_irgen_LFPC(IRTemp op2addr)
8145{
8146 put_fpc_w0(load(Ity_I32, mkexpr(op2addr)));
8147
8148 return "lfpc";
8149}
8150
8151static HChar *
8152s390_irgen_LZER(UChar r1)
8153{
8154 put_fpr_w0(r1, mkF32i(0x0));
8155
8156 return "lzer";
8157}
8158
8159static HChar *
8160s390_irgen_LZDR(UChar r1)
8161{
8162 put_fpr_dw0(r1, mkF64i(0x0));
8163
8164 return "lzdr";
8165}
8166
8167static HChar *
8168s390_irgen_LZXR(UChar r1)
8169{
8170 put_fpr_dw0(r1, mkF64i(0x0));
8171 put_fpr_dw0(r1 + 2, mkF64i(0x0));
8172
8173 return "lzxr";
8174}
8175
8176static HChar *
8177s390_irgen_SRNM(IRTemp op2addr)
8178{
florianf0fa1be2012-09-18 20:24:38 +00008179 UInt input_mask, fpc_mask;
sewardj2019a972011-03-07 16:04:07 +00008180
florianf0fa1be2012-09-18 20:24:38 +00008181 input_mask = 3;
8182 fpc_mask = s390_host_has_fpext ? 7 : 3;
sewardj2019a972011-03-07 16:04:07 +00008183
florianf0fa1be2012-09-18 20:24:38 +00008184 put_fpc_w0(binop(Iop_Or32,
8185 binop(Iop_And32, get_fpc_w0(), mkU32(~fpc_mask)),
8186 binop(Iop_And32, unop(Iop_64to32, mkexpr(op2addr)),
8187 mkU32(input_mask))));
sewardj2019a972011-03-07 16:04:07 +00008188 return "srnm";
8189}
8190
8191static HChar *
florianf0fa1be2012-09-18 20:24:38 +00008192s390_irgen_SRNMB(IRTemp op2addr)
8193{
8194 UInt input_mask, fpc_mask;
8195
8196 input_mask = 7;
8197 fpc_mask = 7;
8198
8199 put_fpc_w0(binop(Iop_Or32,
8200 binop(Iop_And32, get_fpc_w0(), mkU32(~fpc_mask)),
8201 binop(Iop_And32, unop(Iop_64to32, mkexpr(op2addr)),
8202 mkU32(input_mask))));
8203 return "srnmb";
8204}
8205
florian81a4bfe2012-09-20 01:25:28 +00008206static void
florianf0fa1be2012-09-18 20:24:38 +00008207s390_irgen_srnmb_wrapper(UChar b2, UShort d2)
8208{
8209 if (b2 == 0) { /* This is the typical case */
8210 if (d2 > 3) {
8211 if (s390_host_has_fpext && d2 == 7) {
8212 /* ok */
8213 } else {
8214 emulation_warning(EmWarn_S390X_invalid_rounding);
florian125e20d2012-10-07 15:42:37 +00008215 d2 = S390_FPC_BFP_ROUND_NEAREST_EVEN;
florianf0fa1be2012-09-18 20:24:38 +00008216 }
8217 }
8218 }
8219
8220 s390_format_S_RD(s390_irgen_SRNMB, b2, d2);
8221}
8222
8223
8224static HChar *
sewardj2019a972011-03-07 16:04:07 +00008225s390_irgen_SFPC(UChar r1)
8226{
8227 put_fpc_w0(get_gpr_w1(r1));
8228
8229 return "sfpc";
8230}
8231
8232static HChar *
8233s390_irgen_STE(UChar r1, IRTemp op2addr)
8234{
8235 store(mkexpr(op2addr), get_fpr_w0(r1));
8236
8237 return "ste";
8238}
8239
8240static HChar *
8241s390_irgen_STD(UChar r1, IRTemp op2addr)
8242{
8243 store(mkexpr(op2addr), get_fpr_dw0(r1));
8244
8245 return "std";
8246}
8247
8248static HChar *
8249s390_irgen_STEY(UChar r1, IRTemp op2addr)
8250{
8251 store(mkexpr(op2addr), get_fpr_w0(r1));
8252
8253 return "stey";
8254}
8255
8256static HChar *
8257s390_irgen_STDY(UChar r1, IRTemp op2addr)
8258{
8259 store(mkexpr(op2addr), get_fpr_dw0(r1));
8260
8261 return "stdy";
8262}
8263
8264static HChar *
8265s390_irgen_STFPC(IRTemp op2addr)
8266{
8267 store(mkexpr(op2addr), get_fpc_w0());
8268
8269 return "stfpc";
8270}
8271
8272static HChar *
8273s390_irgen_AEBR(UChar r1, UChar r2)
8274{
8275 IRTemp op1 = newTemp(Ity_F32);
8276 IRTemp op2 = newTemp(Ity_F32);
8277 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00008278 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008279
8280 assign(op1, get_fpr_w0(r1));
8281 assign(op2, get_fpr_w0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008282 assign(result, triop(Iop_AddF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008283 mkexpr(op2)));
8284 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
8285 put_fpr_w0(r1, mkexpr(result));
8286
8287 return "aebr";
8288}
8289
8290static HChar *
8291s390_irgen_ADBR(UChar r1, UChar r2)
8292{
8293 IRTemp op1 = newTemp(Ity_F64);
8294 IRTemp op2 = newTemp(Ity_F64);
8295 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00008296 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008297
8298 assign(op1, get_fpr_dw0(r1));
8299 assign(op2, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008300 assign(result, triop(Iop_AddF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008301 mkexpr(op2)));
8302 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
8303 put_fpr_dw0(r1, mkexpr(result));
8304
8305 return "adbr";
8306}
8307
8308static HChar *
8309s390_irgen_AEB(UChar r1, IRTemp op2addr)
8310{
8311 IRTemp op1 = newTemp(Ity_F32);
8312 IRTemp op2 = newTemp(Ity_F32);
8313 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00008314 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008315
8316 assign(op1, get_fpr_w0(r1));
8317 assign(op2, load(Ity_F32, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00008318 assign(result, triop(Iop_AddF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008319 mkexpr(op2)));
8320 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
8321 put_fpr_w0(r1, mkexpr(result));
8322
8323 return "aeb";
8324}
8325
8326static HChar *
8327s390_irgen_ADB(UChar r1, IRTemp op2addr)
8328{
8329 IRTemp op1 = newTemp(Ity_F64);
8330 IRTemp op2 = newTemp(Ity_F64);
8331 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00008332 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008333
8334 assign(op1, get_fpr_dw0(r1));
8335 assign(op2, load(Ity_F64, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00008336 assign(result, triop(Iop_AddF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008337 mkexpr(op2)));
8338 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
8339 put_fpr_dw0(r1, mkexpr(result));
8340
8341 return "adb";
8342}
8343
8344static HChar *
florian4b8efad2012-09-02 18:07:08 +00008345s390_irgen_CEFBR(UChar m3, UChar m4 __attribute__((unused)),
8346 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008347{
florian125e20d2012-10-07 15:42:37 +00008348 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian4b8efad2012-09-02 18:07:08 +00008349 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +00008350 m3 = S390_BFP_ROUND_PER_FPC;
florian4b8efad2012-09-02 18:07:08 +00008351 }
sewardj2019a972011-03-07 16:04:07 +00008352 IRTemp op2 = newTemp(Ity_I32);
8353
8354 assign(op2, get_gpr_w1(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008355 put_fpr_w0(r1, binop(Iop_I32StoF32, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +00008356 mkexpr(op2)));
sewardj2019a972011-03-07 16:04:07 +00008357
8358 return "cefbr";
8359}
8360
8361static HChar *
florian4b8efad2012-09-02 18:07:08 +00008362s390_irgen_CDFBR(UChar m3 __attribute__((unused)),
8363 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008364{
8365 IRTemp op2 = newTemp(Ity_I32);
8366
8367 assign(op2, get_gpr_w1(r2));
8368 put_fpr_dw0(r1, unop(Iop_I32StoF64, mkexpr(op2)));
8369
8370 return "cdfbr";
8371}
8372
8373static HChar *
florian4b8efad2012-09-02 18:07:08 +00008374s390_irgen_CEGBR(UChar m3, UChar m4 __attribute__((unused)),
8375 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008376{
florian125e20d2012-10-07 15:42:37 +00008377 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian4b8efad2012-09-02 18:07:08 +00008378 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +00008379 m3 = S390_BFP_ROUND_PER_FPC;
florian4b8efad2012-09-02 18:07:08 +00008380 }
sewardj2019a972011-03-07 16:04:07 +00008381 IRTemp op2 = newTemp(Ity_I64);
8382
8383 assign(op2, get_gpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008384 put_fpr_w0(r1, binop(Iop_I64StoF32, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +00008385 mkexpr(op2)));
sewardj2019a972011-03-07 16:04:07 +00008386
8387 return "cegbr";
8388}
8389
8390static HChar *
florian4b8efad2012-09-02 18:07:08 +00008391s390_irgen_CDGBR(UChar m3, UChar m4 __attribute__((unused)),
8392 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008393{
florian125e20d2012-10-07 15:42:37 +00008394 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian4b8efad2012-09-02 18:07:08 +00008395 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +00008396 m3 = S390_BFP_ROUND_PER_FPC;
florian4b8efad2012-09-02 18:07:08 +00008397 }
sewardj2019a972011-03-07 16:04:07 +00008398 IRTemp op2 = newTemp(Ity_I64);
8399
8400 assign(op2, get_gpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008401 put_fpr_dw0(r1, binop(Iop_I64StoF64, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +00008402 mkexpr(op2)));
sewardj2019a972011-03-07 16:04:07 +00008403
8404 return "cdgbr";
8405}
8406
8407static HChar *
florian1c8f7ff2012-09-01 00:12:11 +00008408s390_irgen_CELFBR(UChar m3, UChar m4 __attribute__((unused)),
8409 UChar r1, UChar r2)
8410{
floriane75dafa2012-09-01 17:54:09 +00008411 if (! s390_host_has_fpext) {
8412 emulation_failure(EmFail_S390X_fpext);
8413 } else {
8414 IRTemp op2 = newTemp(Ity_I32);
florian1c8f7ff2012-09-01 00:12:11 +00008415
floriane75dafa2012-09-01 17:54:09 +00008416 assign(op2, get_gpr_w1(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008417 put_fpr_w0(r1, binop(Iop_I32UtoF32, mkexpr(encode_bfp_rounding_mode(m3)),
floriane75dafa2012-09-01 17:54:09 +00008418 mkexpr(op2)));
8419 }
florian1c8f7ff2012-09-01 00:12:11 +00008420 return "celfbr";
8421}
8422
8423static HChar *
floriand2129202012-09-01 20:01:39 +00008424s390_irgen_CDLFBR(UChar m3 __attribute__((unused)),
8425 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
florian1c8f7ff2012-09-01 00:12:11 +00008426{
floriane75dafa2012-09-01 17:54:09 +00008427 if (! s390_host_has_fpext) {
8428 emulation_failure(EmFail_S390X_fpext);
8429 } else {
8430 IRTemp op2 = newTemp(Ity_I32);
florian1c8f7ff2012-09-01 00:12:11 +00008431
floriane75dafa2012-09-01 17:54:09 +00008432 assign(op2, get_gpr_w1(r2));
8433 put_fpr_dw0(r1, unop(Iop_I32UtoF64, mkexpr(op2)));
8434 }
florian1c8f7ff2012-09-01 00:12:11 +00008435 return "cdlfbr";
8436}
8437
8438static HChar *
8439s390_irgen_CELGBR(UChar m3, UChar m4 __attribute__((unused)),
8440 UChar r1, UChar r2)
8441{
floriane75dafa2012-09-01 17:54:09 +00008442 if (! s390_host_has_fpext) {
8443 emulation_failure(EmFail_S390X_fpext);
8444 } else {
8445 IRTemp op2 = newTemp(Ity_I64);
florian1c8f7ff2012-09-01 00:12:11 +00008446
floriane75dafa2012-09-01 17:54:09 +00008447 assign(op2, get_gpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008448 put_fpr_w0(r1, binop(Iop_I64UtoF32, mkexpr(encode_bfp_rounding_mode(m3)),
floriane75dafa2012-09-01 17:54:09 +00008449 mkexpr(op2)));
8450 }
florian1c8f7ff2012-09-01 00:12:11 +00008451 return "celgbr";
8452}
8453
8454static HChar *
8455s390_irgen_CDLGBR(UChar m3, UChar m4 __attribute__((unused)),
8456 UChar r1, UChar r2)
8457{
floriane75dafa2012-09-01 17:54:09 +00008458 if (! s390_host_has_fpext) {
8459 emulation_failure(EmFail_S390X_fpext);
8460 } else {
8461 IRTemp op2 = newTemp(Ity_I64);
florian1c8f7ff2012-09-01 00:12:11 +00008462
floriane75dafa2012-09-01 17:54:09 +00008463 assign(op2, get_gpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008464 put_fpr_dw0(r1, binop(Iop_I64UtoF64,
8465 mkexpr(encode_bfp_rounding_mode(m3)),
floriane75dafa2012-09-01 17:54:09 +00008466 mkexpr(op2)));
8467 }
florian1c8f7ff2012-09-01 00:12:11 +00008468 return "cdlgbr";
8469}
8470
8471static HChar *
8472s390_irgen_CLFEBR(UChar m3, UChar m4 __attribute__((unused)),
8473 UChar r1, UChar r2)
8474{
floriane75dafa2012-09-01 17:54:09 +00008475 if (! s390_host_has_fpext) {
8476 emulation_failure(EmFail_S390X_fpext);
8477 } else {
8478 IRTemp op = newTemp(Ity_F32);
8479 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +00008480 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +00008481
floriane75dafa2012-09-01 17:54:09 +00008482 assign(op, get_fpr_w0(r2));
florian19e00772012-09-06 03:13:22 +00008483 assign(result, binop(Iop_F32toI32U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +00008484 mkexpr(op)));
8485 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008486 s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_UINT_32, op, rounding_mode);
floriane75dafa2012-09-01 17:54:09 +00008487 }
florian1c8f7ff2012-09-01 00:12:11 +00008488 return "clfebr";
8489}
8490
8491static HChar *
8492s390_irgen_CLFDBR(UChar m3, UChar m4 __attribute__((unused)),
8493 UChar r1, UChar r2)
8494{
floriane75dafa2012-09-01 17:54:09 +00008495 if (! s390_host_has_fpext) {
8496 emulation_failure(EmFail_S390X_fpext);
8497 } else {
8498 IRTemp op = newTemp(Ity_F64);
8499 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +00008500 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +00008501
floriane75dafa2012-09-01 17:54:09 +00008502 assign(op, get_fpr_dw0(r2));
florian19e00772012-09-06 03:13:22 +00008503 assign(result, binop(Iop_F64toI32U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +00008504 mkexpr(op)));
8505 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008506 s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_UINT_32, op, rounding_mode);
floriane75dafa2012-09-01 17:54:09 +00008507 }
florian1c8f7ff2012-09-01 00:12:11 +00008508 return "clfdbr";
8509}
8510
8511static HChar *
8512s390_irgen_CLGEBR(UChar m3, UChar m4 __attribute__((unused)),
8513 UChar r1, UChar r2)
8514{
floriane75dafa2012-09-01 17:54:09 +00008515 if (! s390_host_has_fpext) {
8516 emulation_failure(EmFail_S390X_fpext);
8517 } else {
8518 IRTemp op = newTemp(Ity_F32);
8519 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +00008520 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +00008521
floriane75dafa2012-09-01 17:54:09 +00008522 assign(op, get_fpr_w0(r2));
florian19e00772012-09-06 03:13:22 +00008523 assign(result, binop(Iop_F32toI64U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +00008524 mkexpr(op)));
8525 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008526 s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_UINT_64, op, rounding_mode);
floriane75dafa2012-09-01 17:54:09 +00008527 }
florian1c8f7ff2012-09-01 00:12:11 +00008528 return "clgebr";
8529}
8530
8531static HChar *
8532s390_irgen_CLGDBR(UChar m3, UChar m4 __attribute__((unused)),
8533 UChar r1, UChar r2)
8534{
floriane75dafa2012-09-01 17:54:09 +00008535 if (! s390_host_has_fpext) {
8536 emulation_failure(EmFail_S390X_fpext);
8537 } else {
8538 IRTemp op = newTemp(Ity_F64);
8539 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +00008540 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +00008541
floriane75dafa2012-09-01 17:54:09 +00008542 assign(op, get_fpr_dw0(r2));
florian19e00772012-09-06 03:13:22 +00008543 assign(result, binop(Iop_F64toI64U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +00008544 mkexpr(op)));
8545 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008546 s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_UINT_64, op, rounding_mode);
floriane75dafa2012-09-01 17:54:09 +00008547 }
florian1c8f7ff2012-09-01 00:12:11 +00008548 return "clgdbr";
8549}
8550
8551static HChar *
florian4b8efad2012-09-02 18:07:08 +00008552s390_irgen_CFEBR(UChar m3, UChar m4 __attribute__((unused)),
8553 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008554{
8555 IRTemp op = newTemp(Ity_F32);
8556 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +00008557 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +00008558
8559 assign(op, get_fpr_w0(r2));
florian19e00772012-09-06 03:13:22 +00008560 assign(result, binop(Iop_F32toI32S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +00008561 mkexpr(op)));
8562 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008563 s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_INT_32, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +00008564
8565 return "cfebr";
8566}
8567
8568static HChar *
florian4b8efad2012-09-02 18:07:08 +00008569s390_irgen_CFDBR(UChar m3, UChar m4 __attribute__((unused)),
8570 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008571{
8572 IRTemp op = newTemp(Ity_F64);
8573 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +00008574 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +00008575
8576 assign(op, get_fpr_dw0(r2));
florian19e00772012-09-06 03:13:22 +00008577 assign(result, binop(Iop_F64toI32S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +00008578 mkexpr(op)));
8579 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008580 s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_INT_32, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +00008581
8582 return "cfdbr";
8583}
8584
8585static HChar *
florian4b8efad2012-09-02 18:07:08 +00008586s390_irgen_CGEBR(UChar m3, UChar m4 __attribute__((unused)),
8587 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008588{
8589 IRTemp op = newTemp(Ity_F32);
8590 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +00008591 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +00008592
8593 assign(op, get_fpr_w0(r2));
florian19e00772012-09-06 03:13:22 +00008594 assign(result, binop(Iop_F32toI64S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +00008595 mkexpr(op)));
8596 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008597 s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_INT_64, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +00008598
8599 return "cgebr";
8600}
8601
8602static HChar *
florian4b8efad2012-09-02 18:07:08 +00008603s390_irgen_CGDBR(UChar m3, UChar m4 __attribute__((unused)),
8604 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008605{
8606 IRTemp op = newTemp(Ity_F64);
8607 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +00008608 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +00008609
8610 assign(op, get_fpr_dw0(r2));
florian19e00772012-09-06 03:13:22 +00008611 assign(result, binop(Iop_F64toI64S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +00008612 mkexpr(op)));
8613 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008614 s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_INT_64, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +00008615
8616 return "cgdbr";
8617}
8618
8619static HChar *
8620s390_irgen_DEBR(UChar r1, UChar r2)
8621{
8622 IRTemp op1 = newTemp(Ity_F32);
8623 IRTemp op2 = newTemp(Ity_F32);
8624 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00008625 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008626
8627 assign(op1, get_fpr_w0(r1));
8628 assign(op2, get_fpr_w0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008629 assign(result, triop(Iop_DivF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008630 mkexpr(op2)));
8631 put_fpr_w0(r1, mkexpr(result));
8632
8633 return "debr";
8634}
8635
8636static HChar *
8637s390_irgen_DDBR(UChar r1, UChar r2)
8638{
8639 IRTemp op1 = newTemp(Ity_F64);
8640 IRTemp op2 = newTemp(Ity_F64);
8641 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00008642 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008643
8644 assign(op1, get_fpr_dw0(r1));
8645 assign(op2, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008646 assign(result, triop(Iop_DivF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008647 mkexpr(op2)));
8648 put_fpr_dw0(r1, mkexpr(result));
8649
8650 return "ddbr";
8651}
8652
8653static HChar *
8654s390_irgen_DEB(UChar r1, IRTemp op2addr)
8655{
8656 IRTemp op1 = newTemp(Ity_F32);
8657 IRTemp op2 = newTemp(Ity_F32);
8658 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00008659 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008660
8661 assign(op1, get_fpr_w0(r1));
8662 assign(op2, load(Ity_F32, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00008663 assign(result, triop(Iop_DivF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008664 mkexpr(op2)));
8665 put_fpr_w0(r1, mkexpr(result));
8666
8667 return "deb";
8668}
8669
8670static HChar *
8671s390_irgen_DDB(UChar r1, IRTemp op2addr)
8672{
8673 IRTemp op1 = newTemp(Ity_F64);
8674 IRTemp op2 = newTemp(Ity_F64);
8675 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00008676 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008677
8678 assign(op1, get_fpr_dw0(r1));
8679 assign(op2, load(Ity_F64, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00008680 assign(result, triop(Iop_DivF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008681 mkexpr(op2)));
8682 put_fpr_dw0(r1, mkexpr(result));
8683
8684 return "ddb";
8685}
8686
8687static HChar *
8688s390_irgen_LTEBR(UChar r1, UChar r2)
8689{
8690 IRTemp result = newTemp(Ity_F32);
8691
8692 assign(result, get_fpr_w0(r2));
8693 put_fpr_w0(r1, mkexpr(result));
8694 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
8695
8696 return "ltebr";
8697}
8698
8699static HChar *
8700s390_irgen_LTDBR(UChar r1, UChar r2)
8701{
8702 IRTemp result = newTemp(Ity_F64);
8703
8704 assign(result, get_fpr_dw0(r2));
8705 put_fpr_dw0(r1, mkexpr(result));
8706 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
8707
8708 return "ltdbr";
8709}
8710
8711static HChar *
8712s390_irgen_LCEBR(UChar r1, UChar r2)
8713{
8714 IRTemp result = newTemp(Ity_F32);
8715
8716 assign(result, unop(Iop_NegF32, get_fpr_w0(r2)));
8717 put_fpr_w0(r1, mkexpr(result));
8718 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
8719
8720 return "lcebr";
8721}
8722
8723static HChar *
8724s390_irgen_LCDBR(UChar r1, UChar r2)
8725{
8726 IRTemp result = newTemp(Ity_F64);
8727
8728 assign(result, unop(Iop_NegF64, get_fpr_dw0(r2)));
8729 put_fpr_dw0(r1, mkexpr(result));
8730 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
8731
8732 return "lcdbr";
8733}
8734
8735static HChar *
8736s390_irgen_LDEBR(UChar r1, UChar r2)
8737{
8738 IRTemp op = newTemp(Ity_F32);
8739
8740 assign(op, get_fpr_w0(r2));
8741 put_fpr_dw0(r1, unop(Iop_F32toF64, mkexpr(op)));
8742
8743 return "ldebr";
8744}
8745
8746static HChar *
8747s390_irgen_LDEB(UChar r1, IRTemp op2addr)
8748{
8749 IRTemp op = newTemp(Ity_F32);
8750
8751 assign(op, load(Ity_F32, mkexpr(op2addr)));
8752 put_fpr_dw0(r1, unop(Iop_F32toF64, mkexpr(op)));
8753
8754 return "ldeb";
8755}
8756
8757static HChar *
florian4b8efad2012-09-02 18:07:08 +00008758s390_irgen_LEDBR(UChar m3, UChar m4 __attribute__((unused)),
8759 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008760{
florian125e20d2012-10-07 15:42:37 +00008761 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian12b0bca2012-09-05 20:05:20 +00008762 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +00008763 m3 = S390_BFP_ROUND_PER_FPC;
florian12b0bca2012-09-05 20:05:20 +00008764 }
sewardj2019a972011-03-07 16:04:07 +00008765 IRTemp op = newTemp(Ity_F64);
8766
8767 assign(op, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008768 put_fpr_w0(r1, binop(Iop_F64toF32, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +00008769 mkexpr(op)));
sewardj2019a972011-03-07 16:04:07 +00008770
8771 return "ledbr";
8772}
8773
8774static HChar *
8775s390_irgen_MEEBR(UChar r1, UChar r2)
8776{
8777 IRTemp op1 = newTemp(Ity_F32);
8778 IRTemp op2 = newTemp(Ity_F32);
8779 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00008780 IRRoundingMode rounding_mode =
8781 encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008782
8783 assign(op1, get_fpr_w0(r1));
8784 assign(op2, get_fpr_w0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008785 assign(result, triop(Iop_MulF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008786 mkexpr(op2)));
8787 put_fpr_w0(r1, mkexpr(result));
8788
8789 return "meebr";
8790}
8791
8792static HChar *
8793s390_irgen_MDBR(UChar r1, UChar r2)
8794{
8795 IRTemp op1 = newTemp(Ity_F64);
8796 IRTemp op2 = newTemp(Ity_F64);
8797 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00008798 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008799
8800 assign(op1, get_fpr_dw0(r1));
8801 assign(op2, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008802 assign(result, triop(Iop_MulF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008803 mkexpr(op2)));
8804 put_fpr_dw0(r1, mkexpr(result));
8805
8806 return "mdbr";
8807}
8808
8809static HChar *
8810s390_irgen_MEEB(UChar r1, IRTemp op2addr)
8811{
8812 IRTemp op1 = newTemp(Ity_F32);
8813 IRTemp op2 = newTemp(Ity_F32);
8814 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00008815 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008816
8817 assign(op1, get_fpr_w0(r1));
8818 assign(op2, load(Ity_F32, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00008819 assign(result, triop(Iop_MulF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008820 mkexpr(op2)));
8821 put_fpr_w0(r1, mkexpr(result));
8822
8823 return "meeb";
8824}
8825
8826static HChar *
8827s390_irgen_MDB(UChar r1, IRTemp op2addr)
8828{
8829 IRTemp op1 = newTemp(Ity_F64);
8830 IRTemp op2 = newTemp(Ity_F64);
8831 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00008832 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008833
8834 assign(op1, get_fpr_dw0(r1));
8835 assign(op2, load(Ity_F64, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00008836 assign(result, triop(Iop_MulF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008837 mkexpr(op2)));
8838 put_fpr_dw0(r1, mkexpr(result));
8839
8840 return "mdb";
8841}
8842
8843static HChar *
8844s390_irgen_SEBR(UChar r1, UChar r2)
8845{
8846 IRTemp op1 = newTemp(Ity_F32);
8847 IRTemp op2 = newTemp(Ity_F32);
8848 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00008849 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008850
8851 assign(op1, get_fpr_w0(r1));
8852 assign(op2, get_fpr_w0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008853 assign(result, triop(Iop_SubF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008854 mkexpr(op2)));
8855 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
8856 put_fpr_w0(r1, mkexpr(result));
8857
8858 return "sebr";
8859}
8860
8861static HChar *
8862s390_irgen_SDBR(UChar r1, UChar r2)
8863{
8864 IRTemp op1 = newTemp(Ity_F64);
8865 IRTemp op2 = newTemp(Ity_F64);
8866 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00008867 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008868
8869 assign(op1, get_fpr_dw0(r1));
8870 assign(op2, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008871 assign(result, triop(Iop_SubF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008872 mkexpr(op2)));
8873 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
8874 put_fpr_dw0(r1, mkexpr(result));
8875
8876 return "sdbr";
8877}
8878
8879static HChar *
8880s390_irgen_SEB(UChar r1, IRTemp op2addr)
8881{
8882 IRTemp op1 = newTemp(Ity_F32);
8883 IRTemp op2 = newTemp(Ity_F32);
8884 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00008885 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008886
8887 assign(op1, get_fpr_w0(r1));
8888 assign(op2, load(Ity_F32, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00008889 assign(result, triop(Iop_SubF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008890 mkexpr(op2)));
8891 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
8892 put_fpr_w0(r1, mkexpr(result));
8893
8894 return "seb";
8895}
8896
8897static HChar *
8898s390_irgen_SDB(UChar r1, IRTemp op2addr)
8899{
8900 IRTemp op1 = newTemp(Ity_F64);
8901 IRTemp op2 = newTemp(Ity_F64);
8902 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00008903 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008904
8905 assign(op1, get_fpr_dw0(r1));
8906 assign(op2, load(Ity_F64, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00008907 assign(result, triop(Iop_SubF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008908 mkexpr(op2)));
8909 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
8910 put_fpr_dw0(r1, mkexpr(result));
8911
8912 return "sdb";
8913}
8914
8915
8916static HChar *
8917s390_irgen_CLC(UChar length, IRTemp start1, IRTemp start2)
8918{
florian79e839e2012-05-05 02:20:30 +00008919 IRTemp len = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00008920
florian79e839e2012-05-05 02:20:30 +00008921 assign(len, mkU64(length));
8922 s390_irgen_CLC_EX(len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +00008923
8924 return "clc";
8925}
8926
8927static HChar *
florianb0c9a132011-09-08 15:37:39 +00008928s390_irgen_CLCL(UChar r1, UChar r2)
8929{
8930 IRTemp addr1 = newTemp(Ity_I64);
8931 IRTemp addr2 = newTemp(Ity_I64);
8932 IRTemp addr1_load = newTemp(Ity_I64);
8933 IRTemp addr2_load = newTemp(Ity_I64);
8934 IRTemp len1 = newTemp(Ity_I32);
8935 IRTemp len2 = newTemp(Ity_I32);
8936 IRTemp r1p1 = newTemp(Ity_I32); /* contents of r1 + 1 */
8937 IRTemp r2p1 = newTemp(Ity_I32); /* contents of r2 + 1 */
8938 IRTemp single1 = newTemp(Ity_I8);
8939 IRTemp single2 = newTemp(Ity_I8);
8940 IRTemp pad = newTemp(Ity_I8);
8941
8942 assign(addr1, get_gpr_dw0(r1));
8943 assign(r1p1, get_gpr_w1(r1 + 1));
8944 assign(len1, binop(Iop_And32, mkexpr(r1p1), mkU32(0x00ffffff)));
8945 assign(addr2, get_gpr_dw0(r2));
8946 assign(r2p1, get_gpr_w1(r2 + 1));
8947 assign(len2, binop(Iop_And32, mkexpr(r2p1), mkU32(0x00ffffff)));
8948 assign(pad, get_gpr_b4(r2 + 1));
8949
8950 /* len1 == 0 and len2 == 0? Exit */
8951 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +00008952 next_insn_if(binop(Iop_CmpEQ32, binop(Iop_Or32, mkexpr(len1),
8953 mkexpr(len2)), mkU32(0)));
florianb0c9a132011-09-08 15:37:39 +00008954
8955 /* Because mkite evaluates both the then-clause and the else-clause
8956 we cannot load directly from addr1 here. If len1 is 0, then adddr1
8957 may be NULL and loading from there would segfault. So we provide a
8958 valid dummy address in that case. Loading from there does no harm and
8959 the value will be discarded at runtime. */
8960 assign(addr1_load,
8961 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
8962 mkU64(guest_IA_curr_instr), mkexpr(addr1)));
8963 assign(single1,
8964 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
8965 mkexpr(pad), load(Ity_I8, mkexpr(addr1_load))));
8966
8967 assign(addr2_load,
8968 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
8969 mkU64(guest_IA_curr_instr), mkexpr(addr2)));
8970 assign(single2,
8971 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
8972 mkexpr(pad), load(Ity_I8, mkexpr(addr2_load))));
8973
8974 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, single1, single2, False);
8975 /* Fields differ ? */
florian6820ba52012-07-26 02:01:50 +00008976 next_insn_if(binop(Iop_CmpNE8, mkexpr(single1), mkexpr(single2)));
florianb0c9a132011-09-08 15:37:39 +00008977
8978 /* Update len1 and addr1, unless len1 == 0. */
8979 put_gpr_dw0(r1,
8980 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
8981 mkexpr(addr1),
8982 binop(Iop_Add64, mkexpr(addr1), mkU64(1))));
8983
8984 /* When updating len1 we must not modify bits (r1+1)[0:39] */
8985 put_gpr_w1(r1 + 1,
8986 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
8987 binop(Iop_And32, mkexpr(r1p1), mkU32(0xFF000000u)),
8988 binop(Iop_Sub32, mkexpr(r1p1), mkU32(1))));
8989
8990 /* Update len2 and addr2, unless len2 == 0. */
8991 put_gpr_dw0(r2,
8992 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
8993 mkexpr(addr2),
8994 binop(Iop_Add64, mkexpr(addr2), mkU64(1))));
8995
8996 /* When updating len2 we must not modify bits (r2+1)[0:39] */
8997 put_gpr_w1(r2 + 1,
8998 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
8999 binop(Iop_And32, mkexpr(r2p1), mkU32(0xFF000000u)),
9000 binop(Iop_Sub32, mkexpr(r2p1), mkU32(1))));
9001
florian6820ba52012-07-26 02:01:50 +00009002 iterate();
florianb0c9a132011-09-08 15:37:39 +00009003
9004 return "clcl";
9005}
9006
9007static HChar *
sewardj2019a972011-03-07 16:04:07 +00009008s390_irgen_CLCLE(UChar r1, UChar r3, IRTemp pad2)
9009{
9010 IRTemp addr1, addr3, addr1_load, addr3_load, len1, len3, single1, single3;
9011
9012 addr1 = newTemp(Ity_I64);
9013 addr3 = newTemp(Ity_I64);
9014 addr1_load = newTemp(Ity_I64);
9015 addr3_load = newTemp(Ity_I64);
9016 len1 = newTemp(Ity_I64);
9017 len3 = newTemp(Ity_I64);
9018 single1 = newTemp(Ity_I8);
9019 single3 = newTemp(Ity_I8);
9020
9021 assign(addr1, get_gpr_dw0(r1));
9022 assign(len1, get_gpr_dw0(r1 + 1));
9023 assign(addr3, get_gpr_dw0(r3));
9024 assign(len3, get_gpr_dw0(r3 + 1));
9025
9026 /* len1 == 0 and len3 == 0? Exit */
9027 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +00009028 next_insn_if(binop(Iop_CmpEQ64,binop(Iop_Or64, mkexpr(len1),
9029 mkexpr(len3)), mkU64(0)));
sewardj2019a972011-03-07 16:04:07 +00009030
9031 /* A mux requires both ways to be possible. This is a way to prevent clcle
9032 from reading from addr1 if it should read from the pad. Since the pad
9033 has no address, just read from the instruction, we discard that anyway */
9034 assign(addr1_load,
florian6ad49522011-09-09 02:38:55 +00009035 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
9036 mkU64(guest_IA_curr_instr), mkexpr(addr1)));
sewardj2019a972011-03-07 16:04:07 +00009037
9038 /* same for addr3 */
9039 assign(addr3_load,
florian6ad49522011-09-09 02:38:55 +00009040 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
9041 mkU64(guest_IA_curr_instr), mkexpr(addr3)));
sewardj2019a972011-03-07 16:04:07 +00009042
9043 assign(single1,
florian6ad49522011-09-09 02:38:55 +00009044 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
9045 unop(Iop_64to8, mkexpr(pad2)),
9046 load(Ity_I8, mkexpr(addr1_load))));
sewardj2019a972011-03-07 16:04:07 +00009047
9048 assign(single3,
florian6ad49522011-09-09 02:38:55 +00009049 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
9050 unop(Iop_64to8, mkexpr(pad2)),
9051 load(Ity_I8, mkexpr(addr3_load))));
sewardj2019a972011-03-07 16:04:07 +00009052
9053 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, single1, single3, False);
9054 /* Both fields differ ? */
florian6820ba52012-07-26 02:01:50 +00009055 next_insn_if(binop(Iop_CmpNE8, mkexpr(single1), mkexpr(single3)));
sewardj2019a972011-03-07 16:04:07 +00009056
9057 /* If a length in 0 we must not change this length and the address */
9058 put_gpr_dw0(r1,
florian6ad49522011-09-09 02:38:55 +00009059 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
9060 mkexpr(addr1),
9061 binop(Iop_Add64, mkexpr(addr1), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +00009062
9063 put_gpr_dw0(r1 + 1,
florian6ad49522011-09-09 02:38:55 +00009064 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
9065 mkU64(0), binop(Iop_Sub64, mkexpr(len1), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +00009066
9067 put_gpr_dw0(r3,
florian6ad49522011-09-09 02:38:55 +00009068 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
9069 mkexpr(addr3),
9070 binop(Iop_Add64, mkexpr(addr3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +00009071
9072 put_gpr_dw0(r3 + 1,
florian6ad49522011-09-09 02:38:55 +00009073 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
9074 mkU64(0), binop(Iop_Sub64, mkexpr(len3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +00009075
florian6820ba52012-07-26 02:01:50 +00009076 iterate();
sewardj2019a972011-03-07 16:04:07 +00009077
9078 return "clcle";
9079}
floriana64c2432011-07-16 02:11:50 +00009080
florianb0bf6602012-05-05 00:01:16 +00009081
sewardj2019a972011-03-07 16:04:07 +00009082static void
9083s390_irgen_XC_EX(IRTemp length, IRTemp start1, IRTemp start2)
9084{
florianb0bf6602012-05-05 00:01:16 +00009085 s390_irgen_xonc(Iop_Xor8, length, start1, start2);
9086}
sewardj2019a972011-03-07 16:04:07 +00009087
sewardj2019a972011-03-07 16:04:07 +00009088
florianb0bf6602012-05-05 00:01:16 +00009089static void
9090s390_irgen_NC_EX(IRTemp length, IRTemp start1, IRTemp start2)
9091{
9092 s390_irgen_xonc(Iop_And8, length, start1, start2);
9093}
sewardj2019a972011-03-07 16:04:07 +00009094
sewardj2019a972011-03-07 16:04:07 +00009095
florianb0bf6602012-05-05 00:01:16 +00009096static void
9097s390_irgen_OC_EX(IRTemp length, IRTemp start1, IRTemp start2)
9098{
9099 s390_irgen_xonc(Iop_Or8, length, start1, start2);
sewardj2019a972011-03-07 16:04:07 +00009100}
9101
9102
9103static void
9104s390_irgen_CLC_EX(IRTemp length, IRTemp start1, IRTemp start2)
9105{
9106 IRTemp current1 = newTemp(Ity_I8);
9107 IRTemp current2 = newTemp(Ity_I8);
9108 IRTemp counter = newTemp(Ity_I64);
9109
9110 assign(counter, get_counter_dw0());
9111 put_counter_dw0(mkU64(0));
9112
9113 assign(current1, load(Ity_I8, binop(Iop_Add64, mkexpr(start1),
9114 mkexpr(counter))));
9115 assign(current2, load(Ity_I8, binop(Iop_Add64, mkexpr(start2),
9116 mkexpr(counter))));
9117 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, current1, current2,
9118 False);
9119
9120 /* Both fields differ ? */
florian6820ba52012-07-26 02:01:50 +00009121 next_insn_if(binop(Iop_CmpNE8, mkexpr(current1), mkexpr(current2)));
sewardj2019a972011-03-07 16:04:07 +00009122
9123 /* Check for end of field */
9124 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
florian6820ba52012-07-26 02:01:50 +00009125 iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)));
sewardj2019a972011-03-07 16:04:07 +00009126 put_counter_dw0(mkU64(0));
9127}
9128
9129static void
9130s390_irgen_MVC_EX(IRTemp length, IRTemp start1, IRTemp start2)
9131{
9132 IRTemp counter = newTemp(Ity_I64);
9133
9134 assign(counter, get_counter_dw0());
9135
9136 store(binop(Iop_Add64, mkexpr(start1), mkexpr(counter)),
9137 load(Ity_I8, binop(Iop_Add64, mkexpr(start2), mkexpr(counter))));
9138
9139 /* Check for end of field */
9140 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
florian6820ba52012-07-26 02:01:50 +00009141 iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)));
sewardj2019a972011-03-07 16:04:07 +00009142 put_counter_dw0(mkU64(0));
9143}
9144
florianf87d4fb2012-05-05 02:55:24 +00009145static void
9146s390_irgen_TR_EX(IRTemp length, IRTemp start1, IRTemp start2)
9147{
9148 IRTemp op = newTemp(Ity_I8);
9149 IRTemp op1 = newTemp(Ity_I8);
9150 IRTemp result = newTemp(Ity_I64);
9151 IRTemp counter = newTemp(Ity_I64);
9152
9153 assign(counter, get_counter_dw0());
9154
9155 assign(op, load(Ity_I8, binop(Iop_Add64, mkexpr(start1), mkexpr(counter))));
9156
9157 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)), mkexpr(start2)));
9158
9159 assign(op1, load(Ity_I8, mkexpr(result)));
9160 store(binop(Iop_Add64, mkexpr(start1), mkexpr(counter)), mkexpr(op1));
9161
9162 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
florian6820ba52012-07-26 02:01:50 +00009163 iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)));
florianf87d4fb2012-05-05 02:55:24 +00009164 put_counter_dw0(mkU64(0));
9165}
sewardj2019a972011-03-07 16:04:07 +00009166
9167
9168static void
9169s390_irgen_EX_SS(UChar r, IRTemp addr2,
florian6820ba52012-07-26 02:01:50 +00009170 void (*irgen)(IRTemp length, IRTemp start1, IRTemp start2),
9171 int lensize)
sewardj2019a972011-03-07 16:04:07 +00009172{
9173 struct SS {
9174 unsigned int op : 8;
9175 unsigned int l : 8;
9176 unsigned int b1 : 4;
9177 unsigned int d1 : 12;
9178 unsigned int b2 : 4;
9179 unsigned int d2 : 12;
9180 };
9181 union {
9182 struct SS dec;
9183 unsigned long bytes;
9184 } ss;
9185 IRTemp cond;
9186 IRDirty *d;
9187 IRTemp torun;
9188
9189 IRTemp start1 = newTemp(Ity_I64);
9190 IRTemp start2 = newTemp(Ity_I64);
9191 IRTemp len = newTemp(lensize == 64 ? Ity_I64 : Ity_I32);
9192 cond = newTemp(Ity_I1);
9193 torun = newTemp(Ity_I64);
9194
9195 assign(torun, load(Ity_I64, mkexpr(addr2)));
9196 /* Start with a check that the saved code is still correct */
9197 assign(cond, binop(Iop_CmpNE64, mkexpr(torun), mkU64(last_execute_target)));
9198 /* If not, save the new value */
9199 d = unsafeIRDirty_0_N (0, "s390x_dirtyhelper_EX", &s390x_dirtyhelper_EX,
9200 mkIRExprVec_1(mkexpr(torun)));
9201 d->guard = mkexpr(cond);
9202 stmt(IRStmt_Dirty(d));
9203
9204 /* and restart */
florian428dfdd2012-03-27 03:09:49 +00009205 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TISTART),
9206 mkU64(guest_IA_curr_instr)));
9207 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TILEN), mkU64(4)));
florian6820ba52012-07-26 02:01:50 +00009208 restart_if(mkexpr(cond));
sewardj2019a972011-03-07 16:04:07 +00009209
9210 ss.bytes = last_execute_target;
9211 assign(start1, binop(Iop_Add64, mkU64(ss.dec.d1),
9212 ss.dec.b1 != 0 ? get_gpr_dw0(ss.dec.b1) : mkU64(0)));
9213 assign(start2, binop(Iop_Add64, mkU64(ss.dec.d2),
9214 ss.dec.b2 != 0 ? get_gpr_dw0(ss.dec.b2) : mkU64(0)));
9215 assign(len, unop(lensize == 64 ? Iop_8Uto64 : Iop_8Uto32, binop(Iop_Or8,
9216 r != 0 ? get_gpr_b7(r): mkU8(0), mkU8(ss.dec.l))));
9217 irgen(len, start1, start2);
florian8844a632012-04-13 04:04:06 +00009218
sewardj2019a972011-03-07 16:04:07 +00009219 last_execute_target = 0;
9220}
9221
9222static HChar *
9223s390_irgen_EX(UChar r1, IRTemp addr2)
9224{
9225 switch(last_execute_target & 0xff00000000000000ULL) {
9226 case 0:
9227 {
9228 /* no code information yet */
9229 IRDirty *d;
9230
9231 /* so safe the code... */
9232 d = unsafeIRDirty_0_N (0, "s390x_dirtyhelper_EX", &s390x_dirtyhelper_EX,
9233 mkIRExprVec_1(load(Ity_I64, mkexpr(addr2))));
9234 stmt(IRStmt_Dirty(d));
9235 /* and restart */
florian428dfdd2012-03-27 03:09:49 +00009236 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TISTART),
9237 mkU64(guest_IA_curr_instr)));
9238 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TILEN), mkU64(4)));
florian6820ba52012-07-26 02:01:50 +00009239 restart_if(IRExpr_Const(IRConst_U1(True)));
9240
sewardj2019a972011-03-07 16:04:07 +00009241 /* we know that this will be invalidated */
florianf9e1ed72012-04-17 02:41:56 +00009242 put_IA(mkaddr_expr(guest_IA_next_instr));
sewardj2019a972011-03-07 16:04:07 +00009243 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +00009244 dis_res->jk_StopHere = Ijk_TInval;
sewardj2019a972011-03-07 16:04:07 +00009245 break;
9246 }
9247
9248 case 0xd200000000000000ULL:
9249 /* special case MVC */
9250 s390_irgen_EX_SS(r1, addr2, s390_irgen_MVC_EX, 64);
9251 return "mvc via ex";
9252
9253 case 0xd500000000000000ULL:
9254 /* special case CLC */
9255 s390_irgen_EX_SS(r1, addr2, s390_irgen_CLC_EX, 64);
9256 return "clc via ex";
9257
9258 case 0xd700000000000000ULL:
9259 /* special case XC */
9260 s390_irgen_EX_SS(r1, addr2, s390_irgen_XC_EX, 32);
9261 return "xc via ex";
9262
florianb0bf6602012-05-05 00:01:16 +00009263 case 0xd600000000000000ULL:
9264 /* special case OC */
9265 s390_irgen_EX_SS(r1, addr2, s390_irgen_OC_EX, 32);
9266 return "oc via ex";
9267
9268 case 0xd400000000000000ULL:
9269 /* special case NC */
9270 s390_irgen_EX_SS(r1, addr2, s390_irgen_NC_EX, 32);
9271 return "nc via ex";
sewardj2019a972011-03-07 16:04:07 +00009272
florianf87d4fb2012-05-05 02:55:24 +00009273 case 0xdc00000000000000ULL:
9274 /* special case TR */
9275 s390_irgen_EX_SS(r1, addr2, s390_irgen_TR_EX, 64);
9276 return "tr via ex";
9277
sewardj2019a972011-03-07 16:04:07 +00009278 default:
9279 {
9280 /* everything else will get a self checking prefix that also checks the
9281 register content */
9282 IRDirty *d;
9283 UChar *bytes;
9284 IRTemp cond;
9285 IRTemp orperand;
9286 IRTemp torun;
9287
9288 cond = newTemp(Ity_I1);
9289 orperand = newTemp(Ity_I64);
9290 torun = newTemp(Ity_I64);
9291
9292 if (r1 == 0)
9293 assign(orperand, mkU64(0));
9294 else
9295 assign(orperand, unop(Iop_8Uto64,get_gpr_b7(r1)));
9296 /* This code is going to be translated */
9297 assign(torun, binop(Iop_Or64, load(Ity_I64, mkexpr(addr2)),
9298 binop(Iop_Shl64, mkexpr(orperand), mkU8(48))));
9299
9300 /* Start with a check that saved code is still correct */
9301 assign(cond, binop(Iop_CmpNE64, mkexpr(torun),
9302 mkU64(last_execute_target)));
9303 /* If not, save the new value */
9304 d = unsafeIRDirty_0_N (0, "s390x_dirtyhelper_EX", &s390x_dirtyhelper_EX,
9305 mkIRExprVec_1(mkexpr(torun)));
9306 d->guard = mkexpr(cond);
9307 stmt(IRStmt_Dirty(d));
9308
9309 /* and restart */
florian428dfdd2012-03-27 03:09:49 +00009310 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TISTART), mkU64(guest_IA_curr_instr)));
9311 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TILEN), mkU64(4)));
florian6820ba52012-07-26 02:01:50 +00009312 restart_if(mkexpr(cond));
sewardj2019a972011-03-07 16:04:07 +00009313
9314 /* Now comes the actual translation */
9315 bytes = (UChar *) &last_execute_target;
9316 s390_decode_and_irgen(bytes, ((((bytes[0] >> 6) + 1) >> 1) + 1) << 1,
9317 dis_res);
sewardj7ee97522011-05-09 21:45:04 +00009318 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00009319 vex_printf(" which was executed by\n");
9320 /* dont make useless translations in the next execute */
9321 last_execute_target = 0;
9322 }
9323 }
9324 return "ex";
9325}
9326
9327static HChar *
9328s390_irgen_EXRL(UChar r1, UInt offset)
9329{
9330 IRTemp addr = newTemp(Ity_I64);
9331 /* we might save one round trip because we know the target */
9332 if (!last_execute_target)
9333 last_execute_target = *(ULong *)(HWord)
9334 (guest_IA_curr_instr + offset * 2UL);
9335 assign(addr, mkU64(guest_IA_curr_instr + offset * 2UL));
9336 s390_irgen_EX(r1, addr);
9337 return "exrl";
9338}
9339
9340static HChar *
9341s390_irgen_IPM(UChar r1)
9342{
9343 // As long as we dont support SPM, lets just assume 0 as program mask
9344 put_gpr_b4(r1, unop(Iop_32to8, binop(Iop_Or32, mkU32(0 /* program mask */),
9345 binop(Iop_Shl32, s390_call_calculate_cc(), mkU8(4)))));
9346
9347 return "ipm";
9348}
9349
9350
9351static HChar *
9352s390_irgen_SRST(UChar r1, UChar r2)
9353{
9354 IRTemp address = newTemp(Ity_I64);
9355 IRTemp next = newTemp(Ity_I64);
9356 IRTemp delim = newTemp(Ity_I8);
9357 IRTemp counter = newTemp(Ity_I64);
9358 IRTemp byte = newTemp(Ity_I8);
9359
9360 assign(address, get_gpr_dw0(r2));
9361 assign(next, get_gpr_dw0(r1));
9362
9363 assign(counter, get_counter_dw0());
9364 put_counter_dw0(mkU64(0));
9365
9366 // start = next? CC=2 and out r1 and r2 unchanged
9367 s390_cc_set(2);
9368 put_gpr_dw0(r2, binop(Iop_Sub64, mkexpr(address), mkexpr(counter)));
florian6820ba52012-07-26 02:01:50 +00009369 next_insn_if(binop(Iop_CmpEQ64, mkexpr(address), mkexpr(next)));
sewardj2019a972011-03-07 16:04:07 +00009370
9371 assign(byte, load(Ity_I8, mkexpr(address)));
9372 assign(delim, get_gpr_b7(0));
9373
9374 // byte = delim? CC=1, R1=address
9375 s390_cc_set(1);
9376 put_gpr_dw0(r1, mkexpr(address));
florian6820ba52012-07-26 02:01:50 +00009377 next_insn_if(binop(Iop_CmpEQ8, mkexpr(delim), mkexpr(byte)));
sewardj2019a972011-03-07 16:04:07 +00009378
9379 // else: all equal, no end yet, loop
9380 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
9381 put_gpr_dw0(r1, mkexpr(next));
9382 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(address), mkU64(1)));
floriancf87c942012-07-25 00:52:21 +00009383
florian6820ba52012-07-26 02:01:50 +00009384 iterate();
sewardj2019a972011-03-07 16:04:07 +00009385
9386 return "srst";
9387}
9388
9389static HChar *
9390s390_irgen_CLST(UChar r1, UChar r2)
9391{
9392 IRTemp address1 = newTemp(Ity_I64);
9393 IRTemp address2 = newTemp(Ity_I64);
9394 IRTemp end = newTemp(Ity_I8);
9395 IRTemp counter = newTemp(Ity_I64);
9396 IRTemp byte1 = newTemp(Ity_I8);
9397 IRTemp byte2 = newTemp(Ity_I8);
9398
9399 assign(address1, get_gpr_dw0(r1));
9400 assign(address2, get_gpr_dw0(r2));
9401 assign(end, get_gpr_b7(0));
9402 assign(counter, get_counter_dw0());
9403 put_counter_dw0(mkU64(0));
9404 assign(byte1, load(Ity_I8, mkexpr(address1)));
9405 assign(byte2, load(Ity_I8, mkexpr(address2)));
9406
9407 // end in both? all equal, reset r1 and r2 to start values
9408 s390_cc_set(0);
9409 put_gpr_dw0(r1, binop(Iop_Sub64, mkexpr(address1), mkexpr(counter)));
9410 put_gpr_dw0(r2, binop(Iop_Sub64, mkexpr(address2), mkexpr(counter)));
florian6820ba52012-07-26 02:01:50 +00009411 next_insn_if(binop(Iop_CmpEQ8, mkU8(0),
9412 binop(Iop_Or8,
9413 binop(Iop_Xor8, mkexpr(byte1), mkexpr(end)),
9414 binop(Iop_Xor8, mkexpr(byte2), mkexpr(end)))));
sewardj2019a972011-03-07 16:04:07 +00009415
9416 put_gpr_dw0(r1, mkexpr(address1));
9417 put_gpr_dw0(r2, mkexpr(address2));
9418
9419 // End found in string1
9420 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +00009421 next_insn_if(binop(Iop_CmpEQ8, mkexpr(end), mkexpr(byte1)));
sewardj2019a972011-03-07 16:04:07 +00009422
9423 // End found in string2
9424 s390_cc_set(2);
florian6820ba52012-07-26 02:01:50 +00009425 next_insn_if(binop(Iop_CmpEQ8, mkexpr(end), mkexpr(byte2)));
sewardj2019a972011-03-07 16:04:07 +00009426
9427 // string1 < string2
9428 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +00009429 next_insn_if(binop(Iop_CmpLT32U, unop(Iop_8Uto32, mkexpr(byte1)),
9430 unop(Iop_8Uto32, mkexpr(byte2))));
sewardj2019a972011-03-07 16:04:07 +00009431
9432 // string2 < string1
9433 s390_cc_set(2);
florian6820ba52012-07-26 02:01:50 +00009434 next_insn_if(binop(Iop_CmpLT32U, unop(Iop_8Uto32, mkexpr(byte2)),
9435 unop(Iop_8Uto32, mkexpr(byte1))));
sewardj2019a972011-03-07 16:04:07 +00009436
9437 // else: all equal, no end yet, loop
9438 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
9439 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), mkU64(1)));
9440 put_gpr_dw0(r2, binop(Iop_Add64, get_gpr_dw0(r2), mkU64(1)));
floriancf87c942012-07-25 00:52:21 +00009441
florian6820ba52012-07-26 02:01:50 +00009442 iterate();
sewardj2019a972011-03-07 16:04:07 +00009443
9444 return "clst";
9445}
9446
9447static void
9448s390_irgen_load_multiple_32bit(UChar r1, UChar r3, IRTemp op2addr)
9449{
9450 UChar reg;
9451 IRTemp addr = newTemp(Ity_I64);
9452
9453 assign(addr, mkexpr(op2addr));
9454 reg = r1;
9455 do {
9456 IRTemp old = addr;
9457
9458 reg %= 16;
9459 put_gpr_w1(reg, load(Ity_I32, mkexpr(addr)));
9460 addr = newTemp(Ity_I64);
9461 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
9462 reg++;
9463 } while (reg != (r3 + 1));
9464}
9465
9466static HChar *
9467s390_irgen_LM(UChar r1, UChar r3, IRTemp op2addr)
9468{
9469 s390_irgen_load_multiple_32bit(r1, r3, op2addr);
9470
9471 return "lm";
9472}
9473
9474static HChar *
9475s390_irgen_LMY(UChar r1, UChar r3, IRTemp op2addr)
9476{
9477 s390_irgen_load_multiple_32bit(r1, r3, op2addr);
9478
9479 return "lmy";
9480}
9481
9482static HChar *
9483s390_irgen_LMH(UChar r1, UChar r3, IRTemp op2addr)
9484{
9485 UChar reg;
9486 IRTemp addr = newTemp(Ity_I64);
9487
9488 assign(addr, mkexpr(op2addr));
9489 reg = r1;
9490 do {
9491 IRTemp old = addr;
9492
9493 reg %= 16;
9494 put_gpr_w0(reg, load(Ity_I32, mkexpr(addr)));
9495 addr = newTemp(Ity_I64);
9496 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
9497 reg++;
9498 } while (reg != (r3 + 1));
9499
9500 return "lmh";
9501}
9502
9503static HChar *
9504s390_irgen_LMG(UChar r1, UChar r3, IRTemp op2addr)
9505{
9506 UChar reg;
9507 IRTemp addr = newTemp(Ity_I64);
9508
9509 assign(addr, mkexpr(op2addr));
9510 reg = r1;
9511 do {
9512 IRTemp old = addr;
9513
9514 reg %= 16;
9515 put_gpr_dw0(reg, load(Ity_I64, mkexpr(addr)));
9516 addr = newTemp(Ity_I64);
9517 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(8)));
9518 reg++;
9519 } while (reg != (r3 + 1));
9520
9521 return "lmg";
9522}
9523
9524static void
9525s390_irgen_store_multiple_32bit(UChar r1, UChar r3, IRTemp op2addr)
9526{
9527 UChar reg;
9528 IRTemp addr = newTemp(Ity_I64);
9529
9530 assign(addr, mkexpr(op2addr));
9531 reg = r1;
9532 do {
9533 IRTemp old = addr;
9534
9535 reg %= 16;
9536 store(mkexpr(addr), get_gpr_w1(reg));
9537 addr = newTemp(Ity_I64);
9538 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
9539 reg++;
9540 } while( reg != (r3 + 1));
9541}
9542
9543static HChar *
9544s390_irgen_STM(UChar r1, UChar r3, IRTemp op2addr)
9545{
9546 s390_irgen_store_multiple_32bit(r1, r3, op2addr);
9547
9548 return "stm";
9549}
9550
9551static HChar *
9552s390_irgen_STMY(UChar r1, UChar r3, IRTemp op2addr)
9553{
9554 s390_irgen_store_multiple_32bit(r1, r3, op2addr);
9555
9556 return "stmy";
9557}
9558
9559static HChar *
9560s390_irgen_STMH(UChar r1, UChar r3, IRTemp op2addr)
9561{
9562 UChar reg;
9563 IRTemp addr = newTemp(Ity_I64);
9564
9565 assign(addr, mkexpr(op2addr));
9566 reg = r1;
9567 do {
9568 IRTemp old = addr;
9569
9570 reg %= 16;
9571 store(mkexpr(addr), get_gpr_w0(reg));
9572 addr = newTemp(Ity_I64);
9573 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
9574 reg++;
9575 } while( reg != (r3 + 1));
9576
9577 return "stmh";
9578}
9579
9580static HChar *
9581s390_irgen_STMG(UChar r1, UChar r3, IRTemp op2addr)
9582{
9583 UChar reg;
9584 IRTemp addr = newTemp(Ity_I64);
9585
9586 assign(addr, mkexpr(op2addr));
9587 reg = r1;
9588 do {
9589 IRTemp old = addr;
9590
9591 reg %= 16;
9592 store(mkexpr(addr), get_gpr_dw0(reg));
9593 addr = newTemp(Ity_I64);
9594 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(8)));
9595 reg++;
9596 } while( reg != (r3 + 1));
9597
9598 return "stmg";
9599}
9600
9601static void
florianb0bf6602012-05-05 00:01:16 +00009602s390_irgen_xonc(IROp op, IRTemp length, IRTemp start1, IRTemp start2)
sewardj2019a972011-03-07 16:04:07 +00009603{
9604 IRTemp old1 = newTemp(Ity_I8);
9605 IRTemp old2 = newTemp(Ity_I8);
9606 IRTemp new1 = newTemp(Ity_I8);
9607 IRTemp counter = newTemp(Ity_I32);
9608 IRTemp addr1 = newTemp(Ity_I64);
9609
9610 assign(counter, get_counter_w0());
9611
9612 assign(addr1, binop(Iop_Add64, mkexpr(start1),
9613 unop(Iop_32Uto64, mkexpr(counter))));
9614
9615 assign(old1, load(Ity_I8, mkexpr(addr1)));
9616 assign(old2, load(Ity_I8, binop(Iop_Add64, mkexpr(start2),
9617 unop(Iop_32Uto64,mkexpr(counter)))));
9618 assign(new1, binop(op, mkexpr(old1), mkexpr(old2)));
9619
9620 /* Special case: xc is used to zero memory */
sewardj2019a972011-03-07 16:04:07 +00009621 if (op == Iop_Xor8) {
9622 store(mkexpr(addr1),
florian6ad49522011-09-09 02:38:55 +00009623 mkite(binop(Iop_CmpEQ64, mkexpr(start1), mkexpr(start2)),
9624 mkU8(0), mkexpr(new1)));
sewardj2019a972011-03-07 16:04:07 +00009625 } else
9626 store(mkexpr(addr1), mkexpr(new1));
9627 put_counter_w1(binop(Iop_Or32, unop(Iop_8Uto32, mkexpr(new1)),
9628 get_counter_w1()));
9629
9630 /* Check for end of field */
9631 put_counter_w0(binop(Iop_Add32, mkexpr(counter), mkU32(1)));
florian6820ba52012-07-26 02:01:50 +00009632 iterate_if(binop(Iop_CmpNE32, mkexpr(counter), mkexpr(length)));
sewardj2019a972011-03-07 16:04:07 +00009633 s390_cc_thunk_put1(S390_CC_OP_BITWISE, mktemp(Ity_I32, get_counter_w1()),
9634 False);
9635 put_counter_dw0(mkU64(0));
9636}
9637
9638static HChar *
9639s390_irgen_XC(UChar length, IRTemp start1, IRTemp start2)
9640{
florianb0bf6602012-05-05 00:01:16 +00009641 IRTemp len = newTemp(Ity_I32);
9642
9643 assign(len, mkU32(length));
9644 s390_irgen_xonc(Iop_Xor8, len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +00009645
9646 return "xc";
9647}
9648
sewardjb63967e2011-03-24 08:50:04 +00009649static void
9650s390_irgen_XC_sameloc(UChar length, UChar b, UShort d)
9651{
9652 IRTemp counter = newTemp(Ity_I32);
9653 IRTemp start = newTemp(Ity_I64);
9654 IRTemp addr = newTemp(Ity_I64);
9655
9656 assign(start,
9657 binop(Iop_Add64, mkU64(d), b != 0 ? get_gpr_dw0(b) : mkU64(0)));
9658
9659 if (length < 8) {
9660 UInt i;
9661
9662 for (i = 0; i <= length; ++i) {
9663 store(binop(Iop_Add64, mkexpr(start), mkU64(i)), mkU8(0));
9664 }
9665 } else {
9666 assign(counter, get_counter_w0());
9667
9668 assign(addr, binop(Iop_Add64, mkexpr(start),
9669 unop(Iop_32Uto64, mkexpr(counter))));
9670
9671 store(mkexpr(addr), mkU8(0));
9672
9673 /* Check for end of field */
9674 put_counter_w0(binop(Iop_Add32, mkexpr(counter), mkU32(1)));
florian6820ba52012-07-26 02:01:50 +00009675 iterate_if(binop(Iop_CmpNE32, mkexpr(counter), mkU32(length)));
sewardjb63967e2011-03-24 08:50:04 +00009676
9677 /* Reset counter */
9678 put_counter_dw0(mkU64(0));
9679 }
9680
9681 s390_cc_thunk_put1(S390_CC_OP_BITWISE, mktemp(Ity_I32, mkU32(0)), False);
9682
sewardj7ee97522011-05-09 21:45:04 +00009683 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardjb63967e2011-03-24 08:50:04 +00009684 s390_disasm(ENC3(MNM, UDLB, UDXB), "xc", d, length, b, d, 0, b);
9685}
9686
sewardj2019a972011-03-07 16:04:07 +00009687static HChar *
9688s390_irgen_NC(UChar length, IRTemp start1, IRTemp start2)
9689{
florianb0bf6602012-05-05 00:01:16 +00009690 IRTemp len = newTemp(Ity_I32);
9691
9692 assign(len, mkU32(length));
9693 s390_irgen_xonc(Iop_And8, len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +00009694
9695 return "nc";
9696}
9697
9698static HChar *
9699s390_irgen_OC(UChar length, IRTemp start1, IRTemp start2)
9700{
florianb0bf6602012-05-05 00:01:16 +00009701 IRTemp len = newTemp(Ity_I32);
9702
9703 assign(len, mkU32(length));
9704 s390_irgen_xonc(Iop_Or8, len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +00009705
9706 return "oc";
9707}
9708
9709
9710static HChar *
9711s390_irgen_MVC(UChar length, IRTemp start1, IRTemp start2)
9712{
florian79e839e2012-05-05 02:20:30 +00009713 IRTemp len = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00009714
florian79e839e2012-05-05 02:20:30 +00009715 assign(len, mkU64(length));
9716 s390_irgen_MVC_EX(len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +00009717
9718 return "mvc";
9719}
9720
9721static HChar *
florianb0c9a132011-09-08 15:37:39 +00009722s390_irgen_MVCL(UChar r1, UChar r2)
9723{
9724 IRTemp addr1 = newTemp(Ity_I64);
9725 IRTemp addr2 = newTemp(Ity_I64);
9726 IRTemp addr2_load = newTemp(Ity_I64);
9727 IRTemp r1p1 = newTemp(Ity_I32); /* contents of r1 + 1 */
9728 IRTemp r2p1 = newTemp(Ity_I32); /* contents of r2 + 1 */
9729 IRTemp len1 = newTemp(Ity_I32);
9730 IRTemp len2 = newTemp(Ity_I32);
9731 IRTemp pad = newTemp(Ity_I8);
9732 IRTemp single = newTemp(Ity_I8);
9733
9734 assign(addr1, get_gpr_dw0(r1));
9735 assign(r1p1, get_gpr_w1(r1 + 1));
9736 assign(len1, binop(Iop_And32, mkexpr(r1p1), mkU32(0x00ffffff)));
9737 assign(addr2, get_gpr_dw0(r2));
9738 assign(r2p1, get_gpr_w1(r2 + 1));
9739 assign(len2, binop(Iop_And32, mkexpr(r2p1), mkU32(0x00ffffff)));
9740 assign(pad, get_gpr_b4(r2 + 1));
9741
9742 /* len1 == 0 ? */
9743 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len2, False);
florian6820ba52012-07-26 02:01:50 +00009744 next_insn_if(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)));
florianb0c9a132011-09-08 15:37:39 +00009745
9746 /* Check for destructive overlap:
9747 addr1 > addr2 && addr2 + len1 > addr1 && (addr2 + len2) > addr1 */
9748 s390_cc_set(3);
9749 IRTemp cond1 = newTemp(Ity_I32);
9750 assign(cond1, unop(Iop_1Uto32,
9751 binop(Iop_CmpLT64U, mkexpr(addr2), mkexpr(addr1))));
9752 IRTemp cond2 = newTemp(Ity_I32);
9753 assign(cond2, unop(Iop_1Uto32,
9754 binop(Iop_CmpLT64U, mkexpr(addr1),
9755 binop(Iop_Add64, mkexpr(addr2),
9756 unop(Iop_32Uto64, mkexpr(len1))))));
9757 IRTemp cond3 = newTemp(Ity_I32);
9758 assign(cond3, unop(Iop_1Uto32,
9759 binop(Iop_CmpLT64U,
9760 mkexpr(addr1),
9761 binop(Iop_Add64, mkexpr(addr2),
9762 unop(Iop_32Uto64, mkexpr(len2))))));
9763
florian6820ba52012-07-26 02:01:50 +00009764 next_insn_if(binop(Iop_CmpEQ32,
9765 binop(Iop_And32,
9766 binop(Iop_And32, mkexpr(cond1), mkexpr(cond2)),
9767 mkexpr(cond3)),
9768 mkU32(1)));
florianb0c9a132011-09-08 15:37:39 +00009769
9770 /* See s390_irgen_CLCL for explanation why we cannot load directly
9771 and need two steps. */
9772 assign(addr2_load,
9773 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
9774 mkU64(guest_IA_curr_instr), mkexpr(addr2)));
9775 assign(single,
9776 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
9777 mkexpr(pad), load(Ity_I8, mkexpr(addr2_load))));
9778
9779 store(mkexpr(addr1), mkexpr(single));
9780
9781 /* Update addr1 and len1 */
9782 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkU64(1)));
9783 put_gpr_w1(r1 + 1, binop(Iop_Sub32, mkexpr(r1p1), mkU32(1)));
9784
9785 /* Update addr2 and len2 */
9786 put_gpr_dw0(r2,
9787 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
9788 mkexpr(addr2),
9789 binop(Iop_Add64, mkexpr(addr2), mkU64(1))));
9790
9791 /* When updating len2 we must not modify bits (r2+1)[0:39] */
9792 put_gpr_w1(r2 + 1,
9793 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
9794 binop(Iop_And32, mkexpr(r2p1), mkU32(0xFF000000u)),
9795 binop(Iop_Sub32, mkexpr(r2p1), mkU32(1))));
9796
9797 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len2, False);
florian6820ba52012-07-26 02:01:50 +00009798 iterate_if(binop(Iop_CmpNE32, mkexpr(len1), mkU32(1)));
florianb0c9a132011-09-08 15:37:39 +00009799
9800 return "mvcl";
9801}
9802
9803
9804static HChar *
sewardj2019a972011-03-07 16:04:07 +00009805s390_irgen_MVCLE(UChar r1, UChar r3, IRTemp pad2)
9806{
9807 IRTemp addr1, addr3, addr3_load, len1, len3, single;
9808
9809 addr1 = newTemp(Ity_I64);
9810 addr3 = newTemp(Ity_I64);
9811 addr3_load = newTemp(Ity_I64);
9812 len1 = newTemp(Ity_I64);
9813 len3 = newTemp(Ity_I64);
9814 single = newTemp(Ity_I8);
9815
9816 assign(addr1, get_gpr_dw0(r1));
9817 assign(len1, get_gpr_dw0(r1 + 1));
9818 assign(addr3, get_gpr_dw0(r3));
9819 assign(len3, get_gpr_dw0(r3 + 1));
9820
9821 // len1 == 0 ?
9822 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len3, False);
florian6820ba52012-07-26 02:01:50 +00009823 next_insn_if(binop(Iop_CmpEQ64,mkexpr(len1), mkU64(0)));
sewardj2019a972011-03-07 16:04:07 +00009824
9825 /* This is a hack to prevent mvcle from reading from addr3 if it
9826 should read from the pad. Since the pad has no address, just
9827 read from the instruction, we discard that anyway */
9828 assign(addr3_load,
florian6ad49522011-09-09 02:38:55 +00009829 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
9830 mkU64(guest_IA_curr_instr), mkexpr(addr3)));
sewardj2019a972011-03-07 16:04:07 +00009831
9832 assign(single,
florian6ad49522011-09-09 02:38:55 +00009833 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
9834 unop(Iop_64to8, mkexpr(pad2)),
9835 load(Ity_I8, mkexpr(addr3_load))));
sewardj2019a972011-03-07 16:04:07 +00009836 store(mkexpr(addr1), mkexpr(single));
9837
9838 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkU64(1)));
9839
9840 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkU64(1)));
9841
9842 put_gpr_dw0(r3,
florian6ad49522011-09-09 02:38:55 +00009843 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
9844 mkexpr(addr3),
9845 binop(Iop_Add64, mkexpr(addr3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +00009846
9847 put_gpr_dw0(r3 + 1,
florian6ad49522011-09-09 02:38:55 +00009848 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
9849 mkU64(0), binop(Iop_Sub64, mkexpr(len3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +00009850
sewardj2019a972011-03-07 16:04:07 +00009851 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len3, False);
florian6820ba52012-07-26 02:01:50 +00009852 iterate_if(binop(Iop_CmpNE64, mkexpr(len1), mkU64(1)));
sewardj2019a972011-03-07 16:04:07 +00009853
9854 return "mvcle";
9855}
9856
9857static HChar *
9858s390_irgen_MVST(UChar r1, UChar r2)
9859{
9860 IRTemp addr1 = newTemp(Ity_I64);
9861 IRTemp addr2 = newTemp(Ity_I64);
9862 IRTemp end = newTemp(Ity_I8);
9863 IRTemp byte = newTemp(Ity_I8);
9864 IRTemp counter = newTemp(Ity_I64);
9865
9866 assign(addr1, get_gpr_dw0(r1));
9867 assign(addr2, get_gpr_dw0(r2));
9868 assign(counter, get_counter_dw0());
9869 assign(end, get_gpr_b7(0));
9870 assign(byte, load(Ity_I8, binop(Iop_Add64, mkexpr(addr2),mkexpr(counter))));
9871 store(binop(Iop_Add64,mkexpr(addr1),mkexpr(counter)), mkexpr(byte));
9872
9873 // We use unlimited as cpu-determined number
9874 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
florian6820ba52012-07-26 02:01:50 +00009875 iterate_if(binop(Iop_CmpNE8, mkexpr(end), mkexpr(byte)));
sewardj2019a972011-03-07 16:04:07 +00009876
9877 // and always set cc=1 at the end + update r1
9878 s390_cc_set(1);
9879 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(counter)));
9880 put_counter_dw0(mkU64(0));
9881
9882 return "mvst";
9883}
9884
9885static void
9886s390_irgen_divide_64to32(IROp op, UChar r1, IRTemp op2)
9887{
9888 IRTemp op1 = newTemp(Ity_I64);
9889 IRTemp result = newTemp(Ity_I64);
9890
9891 assign(op1, binop(Iop_32HLto64,
9892 get_gpr_w1(r1), // high 32 bits
9893 get_gpr_w1(r1 + 1))); // low 32 bits
9894 assign(result, binop(op, mkexpr(op1), mkexpr(op2)));
9895 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result))); // remainder
9896 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result))); // quotient
9897}
9898
9899static void
9900s390_irgen_divide_128to64(IROp op, UChar r1, IRTemp op2)
9901{
9902 IRTemp op1 = newTemp(Ity_I128);
9903 IRTemp result = newTemp(Ity_I128);
9904
9905 assign(op1, binop(Iop_64HLto128,
9906 get_gpr_dw0(r1), // high 64 bits
9907 get_gpr_dw0(r1 + 1))); // low 64 bits
9908 assign(result, binop(op, mkexpr(op1), mkexpr(op2)));
9909 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result))); // remainder
9910 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result))); // quotient
9911}
9912
9913static void
9914s390_irgen_divide_64to64(IROp op, UChar r1, IRTemp op2)
9915{
9916 IRTemp op1 = newTemp(Ity_I64);
9917 IRTemp result = newTemp(Ity_I128);
9918
9919 assign(op1, get_gpr_dw0(r1 + 1));
9920 assign(result, binop(op, mkexpr(op1), mkexpr(op2)));
9921 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result))); // remainder
9922 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result))); // quotient
9923}
9924
9925static HChar *
9926s390_irgen_DR(UChar r1, UChar r2)
9927{
9928 IRTemp op2 = newTemp(Ity_I32);
9929
9930 assign(op2, get_gpr_w1(r2));
9931
9932 s390_irgen_divide_64to32(Iop_DivModS64to32, r1, op2);
9933
9934 return "dr";
9935}
9936
9937static HChar *
9938s390_irgen_D(UChar r1, IRTemp op2addr)
9939{
9940 IRTemp op2 = newTemp(Ity_I32);
9941
9942 assign(op2, load(Ity_I32, mkexpr(op2addr)));
9943
9944 s390_irgen_divide_64to32(Iop_DivModS64to32, r1, op2);
9945
9946 return "d";
9947}
9948
9949static HChar *
9950s390_irgen_DLR(UChar r1, UChar r2)
9951{
9952 IRTemp op2 = newTemp(Ity_I32);
9953
9954 assign(op2, get_gpr_w1(r2));
9955
9956 s390_irgen_divide_64to32(Iop_DivModU64to32, r1, op2);
9957
florian7cd1cde2012-08-16 23:57:43 +00009958 return "dlr";
sewardj2019a972011-03-07 16:04:07 +00009959}
9960
9961static HChar *
9962s390_irgen_DL(UChar r1, IRTemp op2addr)
9963{
9964 IRTemp op2 = newTemp(Ity_I32);
9965
9966 assign(op2, load(Ity_I32, mkexpr(op2addr)));
9967
9968 s390_irgen_divide_64to32(Iop_DivModU64to32, r1, op2);
9969
9970 return "dl";
9971}
9972
9973static HChar *
9974s390_irgen_DLG(UChar r1, IRTemp op2addr)
9975{
9976 IRTemp op2 = newTemp(Ity_I64);
9977
9978 assign(op2, load(Ity_I64, mkexpr(op2addr)));
9979
9980 s390_irgen_divide_128to64(Iop_DivModU128to64, r1, op2);
9981
9982 return "dlg";
9983}
9984
9985static HChar *
9986s390_irgen_DLGR(UChar r1, UChar r2)
9987{
9988 IRTemp op2 = newTemp(Ity_I64);
9989
9990 assign(op2, get_gpr_dw0(r2));
9991
9992 s390_irgen_divide_128to64(Iop_DivModU128to64, r1, op2);
9993
9994 return "dlgr";
9995}
9996
9997static HChar *
9998s390_irgen_DSGR(UChar r1, UChar r2)
9999{
10000 IRTemp op2 = newTemp(Ity_I64);
10001
10002 assign(op2, get_gpr_dw0(r2));
10003
10004 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
10005
10006 return "dsgr";
10007}
10008
10009static HChar *
10010s390_irgen_DSG(UChar r1, IRTemp op2addr)
10011{
10012 IRTemp op2 = newTemp(Ity_I64);
10013
10014 assign(op2, load(Ity_I64, mkexpr(op2addr)));
10015
10016 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
10017
10018 return "dsg";
10019}
10020
10021static HChar *
10022s390_irgen_DSGFR(UChar r1, UChar r2)
10023{
10024 IRTemp op2 = newTemp(Ity_I64);
10025
10026 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
10027
10028 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
10029
10030 return "dsgfr";
10031}
10032
10033static HChar *
10034s390_irgen_DSGF(UChar r1, IRTemp op2addr)
10035{
10036 IRTemp op2 = newTemp(Ity_I64);
10037
10038 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
10039
10040 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
10041
10042 return "dsgf";
10043}
10044
10045static void
10046s390_irgen_load_ar_multiple(UChar r1, UChar r3, IRTemp op2addr)
10047{
10048 UChar reg;
10049 IRTemp addr = newTemp(Ity_I64);
10050
10051 assign(addr, mkexpr(op2addr));
10052 reg = r1;
10053 do {
10054 IRTemp old = addr;
10055
10056 reg %= 16;
10057 put_ar_w0(reg, load(Ity_I32, mkexpr(addr)));
10058 addr = newTemp(Ity_I64);
10059 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
10060 reg++;
10061 } while (reg != (r3 + 1));
10062}
10063
10064static HChar *
10065s390_irgen_LAM(UChar r1, UChar r3, IRTemp op2addr)
10066{
10067 s390_irgen_load_ar_multiple(r1, r3, op2addr);
10068
10069 return "lam";
10070}
10071
10072static HChar *
10073s390_irgen_LAMY(UChar r1, UChar r3, IRTemp op2addr)
10074{
10075 s390_irgen_load_ar_multiple(r1, r3, op2addr);
10076
10077 return "lamy";
10078}
10079
10080static void
10081s390_irgen_store_ar_multiple(UChar r1, UChar r3, IRTemp op2addr)
10082{
10083 UChar reg;
10084 IRTemp addr = newTemp(Ity_I64);
10085
10086 assign(addr, mkexpr(op2addr));
10087 reg = r1;
10088 do {
10089 IRTemp old = addr;
10090
10091 reg %= 16;
10092 store(mkexpr(addr), get_ar_w0(reg));
10093 addr = newTemp(Ity_I64);
10094 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
10095 reg++;
10096 } while (reg != (r3 + 1));
10097}
10098
10099static HChar *
10100s390_irgen_STAM(UChar r1, UChar r3, IRTemp op2addr)
10101{
10102 s390_irgen_store_ar_multiple(r1, r3, op2addr);
10103
10104 return "stam";
10105}
10106
10107static HChar *
10108s390_irgen_STAMY(UChar r1, UChar r3, IRTemp op2addr)
10109{
10110 s390_irgen_store_ar_multiple(r1, r3, op2addr);
10111
10112 return "stamy";
10113}
10114
10115
10116/* Implementation for 32-bit compare-and-swap */
10117static void
10118s390_irgen_cas_32(UChar r1, UChar r3, IRTemp op2addr)
10119{
10120 IRCAS *cas;
10121 IRTemp op1 = newTemp(Ity_I32);
10122 IRTemp old_mem = newTemp(Ity_I32);
10123 IRTemp op3 = newTemp(Ity_I32);
10124 IRTemp result = newTemp(Ity_I32);
10125 IRTemp nequal = newTemp(Ity_I1);
10126
10127 assign(op1, get_gpr_w1(r1));
10128 assign(op3, get_gpr_w1(r3));
10129
10130 /* The first and second operands are compared. If they are equal,
10131 the third operand is stored at the second- operand location. */
10132 cas = mkIRCAS(IRTemp_INVALID, old_mem,
10133 Iend_BE, mkexpr(op2addr),
10134 NULL, mkexpr(op1), /* expected value */
10135 NULL, mkexpr(op3) /* new value */);
10136 stmt(IRStmt_CAS(cas));
10137
10138 /* Set CC. Operands compared equal -> 0, else 1. */
10139 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(old_mem)));
10140 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
10141
10142 /* If operands were equal (cc == 0) just store the old value op1 in r1.
10143 Otherwise, store the old_value from memory in r1 and yield. */
10144 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
10145 put_gpr_w1(r1, mkite(mkexpr(nequal), mkexpr(old_mem), mkexpr(op1)));
florian6820ba52012-07-26 02:01:50 +000010146 yield_if(mkexpr(nequal));
sewardj2019a972011-03-07 16:04:07 +000010147}
10148
10149static HChar *
10150s390_irgen_CS(UChar r1, UChar r3, IRTemp op2addr)
10151{
10152 s390_irgen_cas_32(r1, r3, op2addr);
10153
10154 return "cs";
10155}
10156
10157static HChar *
10158s390_irgen_CSY(UChar r1, UChar r3, IRTemp op2addr)
10159{
10160 s390_irgen_cas_32(r1, r3, op2addr);
10161
10162 return "csy";
10163}
10164
10165static HChar *
10166s390_irgen_CSG(UChar r1, UChar r3, IRTemp op2addr)
10167{
10168 IRCAS *cas;
10169 IRTemp op1 = newTemp(Ity_I64);
10170 IRTemp old_mem = newTemp(Ity_I64);
10171 IRTemp op3 = newTemp(Ity_I64);
10172 IRTemp result = newTemp(Ity_I64);
10173 IRTemp nequal = newTemp(Ity_I1);
10174
10175 assign(op1, get_gpr_dw0(r1));
10176 assign(op3, get_gpr_dw0(r3));
10177
10178 /* The first and second operands are compared. If they are equal,
10179 the third operand is stored at the second- operand location. */
10180 cas = mkIRCAS(IRTemp_INVALID, old_mem,
10181 Iend_BE, mkexpr(op2addr),
10182 NULL, mkexpr(op1), /* expected value */
10183 NULL, mkexpr(op3) /* new value */);
10184 stmt(IRStmt_CAS(cas));
10185
10186 /* Set CC. Operands compared equal -> 0, else 1. */
10187 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(old_mem)));
10188 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
10189
10190 /* If operands were equal (cc == 0) just store the old value op1 in r1.
10191 Otherwise, store the old_value from memory in r1 and yield. */
10192 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
10193 put_gpr_dw0(r1, mkite(mkexpr(nequal), mkexpr(old_mem), mkexpr(op1)));
florian6820ba52012-07-26 02:01:50 +000010194 yield_if(mkexpr(nequal));
sewardj2019a972011-03-07 16:04:07 +000010195
10196 return "csg";
10197}
10198
florian448cbba2012-06-06 02:26:01 +000010199/* Implementation for 32-bit compare-double-and-swap */
10200static void
10201s390_irgen_cdas_32(UChar r1, UChar r3, IRTemp op2addr)
10202{
10203 IRCAS *cas;
10204 IRTemp op1_high = newTemp(Ity_I32);
10205 IRTemp op1_low = newTemp(Ity_I32);
10206 IRTemp old_mem_high = newTemp(Ity_I32);
10207 IRTemp old_mem_low = newTemp(Ity_I32);
10208 IRTemp op3_high = newTemp(Ity_I32);
10209 IRTemp op3_low = newTemp(Ity_I32);
10210 IRTemp result = newTemp(Ity_I32);
10211 IRTemp nequal = newTemp(Ity_I1);
10212
10213 assign(op1_high, get_gpr_w1(r1));
10214 assign(op1_low, get_gpr_w1(r1+1));
10215 assign(op3_high, get_gpr_w1(r3));
10216 assign(op3_low, get_gpr_w1(r3+1));
10217
10218 /* The first and second operands are compared. If they are equal,
10219 the third operand is stored at the second-operand location. */
10220 cas = mkIRCAS(old_mem_high, old_mem_low,
10221 Iend_BE, mkexpr(op2addr),
10222 mkexpr(op1_high), mkexpr(op1_low), /* expected value */
10223 mkexpr(op3_high), mkexpr(op3_low) /* new value */);
10224 stmt(IRStmt_CAS(cas));
10225
10226 /* Set CC. Operands compared equal -> 0, else 1. */
10227 assign(result, unop(Iop_1Uto32,
10228 binop(Iop_CmpNE32,
10229 binop(Iop_Or32,
10230 binop(Iop_Xor32, mkexpr(op1_high), mkexpr(old_mem_high)),
10231 binop(Iop_Xor32, mkexpr(op1_low), mkexpr(old_mem_low))),
10232 mkU32(0))));
10233
10234 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
10235
10236 /* If operands were equal (cc == 0) just store the old value op1 in r1.
10237 Otherwise, store the old_value from memory in r1 and yield. */
10238 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
10239 put_gpr_w1(r1, mkite(mkexpr(nequal), mkexpr(old_mem_high), mkexpr(op1_high)));
10240 put_gpr_w1(r1+1, mkite(mkexpr(nequal), mkexpr(old_mem_low), mkexpr(op1_low)));
florian6820ba52012-07-26 02:01:50 +000010241 yield_if(mkexpr(nequal));
florian448cbba2012-06-06 02:26:01 +000010242}
10243
10244static HChar *
10245s390_irgen_CDS(UChar r1, UChar r3, IRTemp op2addr)
10246{
10247 s390_irgen_cdas_32(r1, r3, op2addr);
10248
10249 return "cds";
10250}
10251
10252static HChar *
10253s390_irgen_CDSY(UChar r1, UChar r3, IRTemp op2addr)
10254{
10255 s390_irgen_cdas_32(r1, r3, op2addr);
10256
10257 return "cdsy";
10258}
10259
10260static HChar *
10261s390_irgen_CDSG(UChar r1, UChar r3, IRTemp op2addr)
10262{
10263 IRCAS *cas;
10264 IRTemp op1_high = newTemp(Ity_I64);
10265 IRTemp op1_low = newTemp(Ity_I64);
10266 IRTemp old_mem_high = newTemp(Ity_I64);
10267 IRTemp old_mem_low = newTemp(Ity_I64);
10268 IRTemp op3_high = newTemp(Ity_I64);
10269 IRTemp op3_low = newTemp(Ity_I64);
10270 IRTemp result = newTemp(Ity_I64);
10271 IRTemp nequal = newTemp(Ity_I1);
10272
10273 assign(op1_high, get_gpr_dw0(r1));
10274 assign(op1_low, get_gpr_dw0(r1+1));
10275 assign(op3_high, get_gpr_dw0(r3));
10276 assign(op3_low, get_gpr_dw0(r3+1));
10277
10278 /* The first and second operands are compared. If they are equal,
10279 the third operand is stored at the second-operand location. */
10280 cas = mkIRCAS(old_mem_high, old_mem_low,
10281 Iend_BE, mkexpr(op2addr),
10282 mkexpr(op1_high), mkexpr(op1_low), /* expected value */
10283 mkexpr(op3_high), mkexpr(op3_low) /* new value */);
10284 stmt(IRStmt_CAS(cas));
10285
10286 /* Set CC. Operands compared equal -> 0, else 1. */
10287 assign(result, unop(Iop_1Uto64,
10288 binop(Iop_CmpNE64,
10289 binop(Iop_Or64,
10290 binop(Iop_Xor64, mkexpr(op1_high), mkexpr(old_mem_high)),
10291 binop(Iop_Xor64, mkexpr(op1_low), mkexpr(old_mem_low))),
10292 mkU64(0))));
10293
10294 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
10295
10296 /* If operands were equal (cc == 0) just store the old value op1 in r1.
10297 Otherwise, store the old_value from memory in r1 and yield. */
10298 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
10299 put_gpr_dw0(r1, mkite(mkexpr(nequal), mkexpr(old_mem_high), mkexpr(op1_high)));
10300 put_gpr_dw0(r1+1, mkite(mkexpr(nequal), mkexpr(old_mem_low), mkexpr(op1_low)));
florian6820ba52012-07-26 02:01:50 +000010301 yield_if(mkexpr(nequal));
10302
florian448cbba2012-06-06 02:26:01 +000010303 return "cdsg";
10304}
10305
sewardj2019a972011-03-07 16:04:07 +000010306
10307/* Binary floating point */
10308
10309static HChar *
10310s390_irgen_AXBR(UChar r1, UChar r2)
10311{
10312 IRTemp op1 = newTemp(Ity_F128);
10313 IRTemp op2 = newTemp(Ity_F128);
10314 IRTemp result = newTemp(Ity_F128);
florian125e20d2012-10-07 15:42:37 +000010315 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000010316
10317 assign(op1, get_fpr_pair(r1));
10318 assign(op2, get_fpr_pair(r2));
floriandb4fcaa2012-09-05 19:54:08 +000010319 assign(result, triop(Iop_AddF128, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +000010320 mkexpr(op2)));
10321 put_fpr_pair(r1, mkexpr(result));
10322
10323 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
10324
10325 return "axbr";
10326}
10327
10328/* The result of a Iop_CmdFxx operation is a condition code. It is
10329 encoded using the values defined in type IRCmpFxxResult.
10330 Before we can store the condition code into the guest state (or do
10331 anything else with it for that matter) we need to convert it to
10332 the encoding that s390 uses. This is what this function does.
10333
10334 s390 VEX b6 b2 b0 cc.1 cc.0
10335 0 0x40 EQ 1 0 0 0 0
10336 1 0x01 LT 0 0 1 0 1
10337 2 0x00 GT 0 0 0 1 0
10338 3 0x45 Unordered 1 1 1 1 1
10339
10340 The following bits from the VEX encoding are interesting:
10341 b0, b2, b6 with b0 being the LSB. We observe:
10342
10343 cc.0 = b0;
10344 cc.1 = b2 | (~b0 & ~b6)
10345
10346 with cc being the s390 condition code.
10347*/
10348static IRExpr *
10349convert_vex_fpcc_to_s390(IRTemp vex_cc)
10350{
10351 IRTemp cc0 = newTemp(Ity_I32);
10352 IRTemp cc1 = newTemp(Ity_I32);
10353 IRTemp b0 = newTemp(Ity_I32);
10354 IRTemp b2 = newTemp(Ity_I32);
10355 IRTemp b6 = newTemp(Ity_I32);
10356
10357 assign(b0, binop(Iop_And32, mkexpr(vex_cc), mkU32(1)));
10358 assign(b2, binop(Iop_And32, binop(Iop_Shr32, mkexpr(vex_cc), mkU8(2)),
10359 mkU32(1)));
10360 assign(b6, binop(Iop_And32, binop(Iop_Shr32, mkexpr(vex_cc), mkU8(6)),
10361 mkU32(1)));
10362
10363 assign(cc0, mkexpr(b0));
10364 assign(cc1, binop(Iop_Or32, mkexpr(b2),
10365 binop(Iop_And32,
10366 binop(Iop_Sub32, mkU32(1), mkexpr(b0)), /* ~b0 */
10367 binop(Iop_Sub32, mkU32(1), mkexpr(b6)) /* ~b6 */
10368 )));
10369
10370 return binop(Iop_Or32, mkexpr(cc0), binop(Iop_Shl32, mkexpr(cc1), mkU8(1)));
10371}
10372
10373static HChar *
10374s390_irgen_CEBR(UChar r1, UChar r2)
10375{
10376 IRTemp op1 = newTemp(Ity_F32);
10377 IRTemp op2 = newTemp(Ity_F32);
10378 IRTemp cc_vex = newTemp(Ity_I32);
10379 IRTemp cc_s390 = newTemp(Ity_I32);
10380
10381 assign(op1, get_fpr_w0(r1));
10382 assign(op2, get_fpr_w0(r2));
10383 assign(cc_vex, binop(Iop_CmpF32, mkexpr(op1), mkexpr(op2)));
10384
10385 assign(cc_s390, convert_vex_fpcc_to_s390(cc_vex));
10386 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
10387
10388 return "cebr";
10389}
10390
10391static HChar *
10392s390_irgen_CDBR(UChar r1, UChar r2)
10393{
10394 IRTemp op1 = newTemp(Ity_F64);
10395 IRTemp op2 = newTemp(Ity_F64);
10396 IRTemp cc_vex = newTemp(Ity_I32);
10397 IRTemp cc_s390 = newTemp(Ity_I32);
10398
10399 assign(op1, get_fpr_dw0(r1));
10400 assign(op2, get_fpr_dw0(r2));
10401 assign(cc_vex, binop(Iop_CmpF64, mkexpr(op1), mkexpr(op2)));
10402
10403 assign(cc_s390, convert_vex_fpcc_to_s390(cc_vex));
10404 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
10405
10406 return "cdbr";
10407}
10408
10409static HChar *
10410s390_irgen_CXBR(UChar r1, UChar r2)
10411{
10412 IRTemp op1 = newTemp(Ity_F128);
10413 IRTemp op2 = newTemp(Ity_F128);
10414 IRTemp cc_vex = newTemp(Ity_I32);
10415 IRTemp cc_s390 = newTemp(Ity_I32);
10416
10417 assign(op1, get_fpr_pair(r1));
10418 assign(op2, get_fpr_pair(r2));
10419 assign(cc_vex, binop(Iop_CmpF128, mkexpr(op1), mkexpr(op2)));
10420
10421 assign(cc_s390, convert_vex_fpcc_to_s390(cc_vex));
10422 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
10423
10424 return "cxbr";
10425}
10426
10427static HChar *
10428s390_irgen_CEB(UChar r1, IRTemp op2addr)
10429{
10430 IRTemp op1 = newTemp(Ity_F32);
10431 IRTemp op2 = newTemp(Ity_F32);
10432 IRTemp cc_vex = newTemp(Ity_I32);
10433 IRTemp cc_s390 = newTemp(Ity_I32);
10434
10435 assign(op1, get_fpr_w0(r1));
10436 assign(op2, load(Ity_F32, mkexpr(op2addr)));
10437 assign(cc_vex, binop(Iop_CmpF32, mkexpr(op1), mkexpr(op2)));
10438
10439 assign(cc_s390, convert_vex_fpcc_to_s390(cc_vex));
10440 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
10441
10442 return "ceb";
10443}
10444
10445static HChar *
10446s390_irgen_CDB(UChar r1, IRTemp op2addr)
10447{
10448 IRTemp op1 = newTemp(Ity_F64);
10449 IRTemp op2 = newTemp(Ity_F64);
10450 IRTemp cc_vex = newTemp(Ity_I32);
10451 IRTemp cc_s390 = newTemp(Ity_I32);
10452
10453 assign(op1, get_fpr_dw0(r1));
10454 assign(op2, load(Ity_F64, mkexpr(op2addr)));
10455 assign(cc_vex, binop(Iop_CmpF64, mkexpr(op1), mkexpr(op2)));
10456
10457 assign(cc_s390, convert_vex_fpcc_to_s390(cc_vex));
10458 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
10459
10460 return "cdb";
10461}
10462
10463static HChar *
florian4b8efad2012-09-02 18:07:08 +000010464s390_irgen_CXFBR(UChar m3 __attribute__((unused)),
10465 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000010466{
10467 IRTemp op2 = newTemp(Ity_I32);
10468
10469 assign(op2, get_gpr_w1(r2));
10470 put_fpr_pair(r1, unop(Iop_I32StoF128, mkexpr(op2)));
10471
10472 return "cxfbr";
10473}
10474
10475static HChar *
floriand2129202012-09-01 20:01:39 +000010476s390_irgen_CXLFBR(UChar m3 __attribute__((unused)),
10477 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
florian1c8f7ff2012-09-01 00:12:11 +000010478{
floriane75dafa2012-09-01 17:54:09 +000010479 if (! s390_host_has_fpext) {
10480 emulation_failure(EmFail_S390X_fpext);
10481 } else {
10482 IRTemp op2 = newTemp(Ity_I32);
florian1c8f7ff2012-09-01 00:12:11 +000010483
floriane75dafa2012-09-01 17:54:09 +000010484 assign(op2, get_gpr_w1(r2));
10485 put_fpr_pair(r1, unop(Iop_I32UtoF128, mkexpr(op2)));
10486 }
florian1c8f7ff2012-09-01 00:12:11 +000010487 return "cxlfbr";
10488}
10489
10490
10491static HChar *
florian4b8efad2012-09-02 18:07:08 +000010492s390_irgen_CXGBR(UChar m3 __attribute__((unused)),
10493 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000010494{
10495 IRTemp op2 = newTemp(Ity_I64);
10496
10497 assign(op2, get_gpr_dw0(r2));
10498 put_fpr_pair(r1, unop(Iop_I64StoF128, mkexpr(op2)));
10499
10500 return "cxgbr";
10501}
10502
10503static HChar *
floriand2129202012-09-01 20:01:39 +000010504s390_irgen_CXLGBR(UChar m3 __attribute__((unused)),
10505 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
florian1c8f7ff2012-09-01 00:12:11 +000010506{
floriane75dafa2012-09-01 17:54:09 +000010507 if (! s390_host_has_fpext) {
10508 emulation_failure(EmFail_S390X_fpext);
10509 } else {
10510 IRTemp op2 = newTemp(Ity_I64);
florian1c8f7ff2012-09-01 00:12:11 +000010511
floriane75dafa2012-09-01 17:54:09 +000010512 assign(op2, get_gpr_dw0(r2));
10513 put_fpr_pair(r1, unop(Iop_I64UtoF128, mkexpr(op2)));
10514 }
florian1c8f7ff2012-09-01 00:12:11 +000010515 return "cxlgbr";
10516}
10517
10518static HChar *
florian4b8efad2012-09-02 18:07:08 +000010519s390_irgen_CFXBR(UChar m3, UChar m4 __attribute__((unused)),
10520 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000010521{
10522 IRTemp op = newTemp(Ity_F128);
10523 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +000010524 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +000010525
10526 assign(op, get_fpr_pair(r2));
florian19e00772012-09-06 03:13:22 +000010527 assign(result, binop(Iop_F128toI32S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +000010528 mkexpr(op)));
10529 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +000010530 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_INT_32, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +000010531
10532 return "cfxbr";
10533}
10534
10535static HChar *
florian1c8f7ff2012-09-01 00:12:11 +000010536s390_irgen_CLFXBR(UChar m3, UChar m4 __attribute__((unused)),
10537 UChar r1, UChar r2)
10538{
floriane75dafa2012-09-01 17:54:09 +000010539 if (! s390_host_has_fpext) {
10540 emulation_failure(EmFail_S390X_fpext);
10541 } else {
10542 IRTemp op = newTemp(Ity_F128);
10543 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +000010544 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +000010545
floriane75dafa2012-09-01 17:54:09 +000010546 assign(op, get_fpr_pair(r2));
florian19e00772012-09-06 03:13:22 +000010547 assign(result, binop(Iop_F128toI32U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +000010548 mkexpr(op)));
10549 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +000010550 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_UINT_32, op, rounding_mode);
floriane75dafa2012-09-01 17:54:09 +000010551 }
florian1c8f7ff2012-09-01 00:12:11 +000010552 return "clfxbr";
10553}
10554
10555
10556static HChar *
florian4b8efad2012-09-02 18:07:08 +000010557s390_irgen_CGXBR(UChar m3, UChar m4 __attribute__((unused)),
10558 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000010559{
10560 IRTemp op = newTemp(Ity_F128);
10561 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +000010562 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +000010563
10564 assign(op, get_fpr_pair(r2));
florian19e00772012-09-06 03:13:22 +000010565 assign(result, binop(Iop_F128toI64S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +000010566 mkexpr(op)));
10567 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +000010568 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_INT_64, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +000010569
10570 return "cgxbr";
10571}
10572
10573static HChar *
florian1c8f7ff2012-09-01 00:12:11 +000010574s390_irgen_CLGXBR(UChar m3, UChar m4 __attribute__((unused)),
10575 UChar r1, UChar r2)
10576{
floriane75dafa2012-09-01 17:54:09 +000010577 if (! s390_host_has_fpext) {
10578 emulation_failure(EmFail_S390X_fpext);
10579 } else {
10580 IRTemp op = newTemp(Ity_F128);
10581 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +000010582 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +000010583
floriane75dafa2012-09-01 17:54:09 +000010584 assign(op, get_fpr_pair(r2));
florian19e00772012-09-06 03:13:22 +000010585 assign(result, binop(Iop_F128toI64U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +000010586 mkexpr(op)));
10587 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +000010588 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_UINT_64, op,
10589 rounding_mode);
floriane75dafa2012-09-01 17:54:09 +000010590 }
florian1c8f7ff2012-09-01 00:12:11 +000010591 return "clgxbr";
10592}
10593
10594static HChar *
sewardj2019a972011-03-07 16:04:07 +000010595s390_irgen_DXBR(UChar r1, UChar r2)
10596{
10597 IRTemp op1 = newTemp(Ity_F128);
10598 IRTemp op2 = newTemp(Ity_F128);
10599 IRTemp result = newTemp(Ity_F128);
florian125e20d2012-10-07 15:42:37 +000010600 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000010601
10602 assign(op1, get_fpr_pair(r1));
10603 assign(op2, get_fpr_pair(r2));
floriandb4fcaa2012-09-05 19:54:08 +000010604 assign(result, triop(Iop_DivF128, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +000010605 mkexpr(op2)));
10606 put_fpr_pair(r1, mkexpr(result));
10607
10608 return "dxbr";
10609}
10610
10611static HChar *
10612s390_irgen_LTXBR(UChar r1, UChar r2)
10613{
10614 IRTemp result = newTemp(Ity_F128);
10615
10616 assign(result, get_fpr_pair(r2));
10617 put_fpr_pair(r1, mkexpr(result));
10618 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
10619
10620 return "ltxbr";
10621}
10622
10623static HChar *
10624s390_irgen_LCXBR(UChar r1, UChar r2)
10625{
10626 IRTemp result = newTemp(Ity_F128);
10627
10628 assign(result, unop(Iop_NegF128, get_fpr_pair(r2)));
10629 put_fpr_pair(r1, mkexpr(result));
10630 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
10631
10632 return "lcxbr";
10633}
10634
10635static HChar *
10636s390_irgen_LXDBR(UChar r1, UChar r2)
10637{
10638 IRTemp op = newTemp(Ity_F64);
10639
10640 assign(op, get_fpr_dw0(r2));
10641 put_fpr_pair(r1, unop(Iop_F64toF128, mkexpr(op)));
10642
10643 return "lxdbr";
10644}
10645
10646static HChar *
10647s390_irgen_LXEBR(UChar r1, UChar r2)
10648{
10649 IRTemp op = newTemp(Ity_F32);
10650
10651 assign(op, get_fpr_w0(r2));
10652 put_fpr_pair(r1, unop(Iop_F32toF128, mkexpr(op)));
10653
10654 return "lxebr";
10655}
10656
10657static HChar *
10658s390_irgen_LXDB(UChar r1, IRTemp op2addr)
10659{
10660 IRTemp op = newTemp(Ity_F64);
10661
10662 assign(op, load(Ity_F64, mkexpr(op2addr)));
10663 put_fpr_pair(r1, unop(Iop_F64toF128, mkexpr(op)));
10664
10665 return "lxdb";
10666}
10667
10668static HChar *
10669s390_irgen_LXEB(UChar r1, IRTemp op2addr)
10670{
10671 IRTemp op = newTemp(Ity_F32);
10672
10673 assign(op, load(Ity_F32, mkexpr(op2addr)));
10674 put_fpr_pair(r1, unop(Iop_F32toF128, mkexpr(op)));
10675
10676 return "lxeb";
10677}
10678
10679static HChar *
10680s390_irgen_LNEBR(UChar r1, UChar r2)
10681{
10682 IRTemp result = newTemp(Ity_F32);
10683
10684 assign(result, unop(Iop_NegF32, unop(Iop_AbsF32, get_fpr_w0(r2))));
10685 put_fpr_w0(r1, mkexpr(result));
10686 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_32, result);
10687
10688 return "lnebr";
10689}
10690
10691static HChar *
10692s390_irgen_LNDBR(UChar r1, UChar r2)
10693{
10694 IRTemp result = newTemp(Ity_F64);
10695
10696 assign(result, unop(Iop_NegF64, unop(Iop_AbsF64, get_fpr_dw0(r2))));
10697 put_fpr_dw0(r1, mkexpr(result));
10698 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_64, result);
10699
10700 return "lndbr";
10701}
10702
10703static HChar *
10704s390_irgen_LNXBR(UChar r1, UChar r2)
10705{
10706 IRTemp result = newTemp(Ity_F128);
10707
10708 assign(result, unop(Iop_NegF128, unop(Iop_AbsF128, get_fpr_pair(r2))));
10709 put_fpr_pair(r1, mkexpr(result));
10710 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
10711
10712 return "lnxbr";
10713}
10714
10715static HChar *
10716s390_irgen_LPEBR(UChar r1, UChar r2)
10717{
10718 IRTemp result = newTemp(Ity_F32);
10719
10720 assign(result, unop(Iop_AbsF32, get_fpr_w0(r2)));
10721 put_fpr_w0(r1, mkexpr(result));
10722 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_32, result);
10723
10724 return "lpebr";
10725}
10726
10727static HChar *
10728s390_irgen_LPDBR(UChar r1, UChar r2)
10729{
10730 IRTemp result = newTemp(Ity_F64);
10731
10732 assign(result, unop(Iop_AbsF64, get_fpr_dw0(r2)));
10733 put_fpr_dw0(r1, mkexpr(result));
10734 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_64, result);
10735
10736 return "lpdbr";
10737}
10738
10739static HChar *
10740s390_irgen_LPXBR(UChar r1, UChar r2)
10741{
10742 IRTemp result = newTemp(Ity_F128);
10743
10744 assign(result, unop(Iop_AbsF128, get_fpr_pair(r2)));
10745 put_fpr_pair(r1, mkexpr(result));
10746 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
10747
10748 return "lpxbr";
10749}
10750
10751static HChar *
florian4b8efad2012-09-02 18:07:08 +000010752s390_irgen_LDXBR(UChar m3, UChar m4 __attribute__((unused)),
10753 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000010754{
florian125e20d2012-10-07 15:42:37 +000010755 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian12b0bca2012-09-05 20:05:20 +000010756 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +000010757 m3 = S390_BFP_ROUND_PER_FPC;
florian12b0bca2012-09-05 20:05:20 +000010758 }
sewardj2019a972011-03-07 16:04:07 +000010759 IRTemp result = newTemp(Ity_F64);
10760
floriandb4fcaa2012-09-05 19:54:08 +000010761 assign(result, binop(Iop_F128toF64, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +000010762 get_fpr_pair(r2)));
sewardj2019a972011-03-07 16:04:07 +000010763 put_fpr_dw0(r1, mkexpr(result));
10764
10765 return "ldxbr";
10766}
10767
10768static HChar *
florian4b8efad2012-09-02 18:07:08 +000010769s390_irgen_LEXBR(UChar m3, UChar m4 __attribute__((unused)),
10770 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000010771{
florian125e20d2012-10-07 15:42:37 +000010772 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian12b0bca2012-09-05 20:05:20 +000010773 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +000010774 m3 = S390_BFP_ROUND_PER_FPC;
florian12b0bca2012-09-05 20:05:20 +000010775 }
sewardj2019a972011-03-07 16:04:07 +000010776 IRTemp result = newTemp(Ity_F32);
10777
floriandb4fcaa2012-09-05 19:54:08 +000010778 assign(result, binop(Iop_F128toF32, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +000010779 get_fpr_pair(r2)));
sewardj2019a972011-03-07 16:04:07 +000010780 put_fpr_w0(r1, mkexpr(result));
10781
10782 return "lexbr";
10783}
10784
10785static HChar *
10786s390_irgen_MXBR(UChar r1, UChar r2)
10787{
10788 IRTemp op1 = newTemp(Ity_F128);
10789 IRTemp op2 = newTemp(Ity_F128);
10790 IRTemp result = newTemp(Ity_F128);
florian125e20d2012-10-07 15:42:37 +000010791 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000010792
10793 assign(op1, get_fpr_pair(r1));
10794 assign(op2, get_fpr_pair(r2));
floriandb4fcaa2012-09-05 19:54:08 +000010795 assign(result, triop(Iop_MulF128, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +000010796 mkexpr(op2)));
10797 put_fpr_pair(r1, mkexpr(result));
10798
10799 return "mxbr";
10800}
10801
10802static HChar *
10803s390_irgen_MAEBR(UChar r1, UChar r3, UChar r2)
10804{
florian125e20d2012-10-07 15:42:37 +000010805 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
florian847684d2012-09-05 04:19:09 +000010806
floriandb4fcaa2012-09-05 19:54:08 +000010807 put_fpr_w0(r1, qop(Iop_MAddF32, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000010808 get_fpr_w0(r3), get_fpr_w0(r2), get_fpr_w0(r1)));
sewardj2019a972011-03-07 16:04:07 +000010809
10810 return "maebr";
10811}
10812
10813static HChar *
10814s390_irgen_MADBR(UChar r1, UChar r3, UChar r2)
10815{
florian125e20d2012-10-07 15:42:37 +000010816 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
florian847684d2012-09-05 04:19:09 +000010817
floriandb4fcaa2012-09-05 19:54:08 +000010818 put_fpr_dw0(r1, qop(Iop_MAddF64, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000010819 get_fpr_dw0(r3), get_fpr_dw0(r2), get_fpr_dw0(r1)));
sewardj2019a972011-03-07 16:04:07 +000010820
10821 return "madbr";
10822}
10823
10824static HChar *
10825s390_irgen_MAEB(UChar r3, IRTemp op2addr, UChar r1)
10826{
10827 IRExpr *op2 = load(Ity_F32, mkexpr(op2addr));
florian125e20d2012-10-07 15:42:37 +000010828 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000010829
floriandb4fcaa2012-09-05 19:54:08 +000010830 put_fpr_w0(r1, qop(Iop_MAddF32, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000010831 get_fpr_w0(r3), op2, get_fpr_w0(r1)));
sewardj2019a972011-03-07 16:04:07 +000010832
10833 return "maeb";
10834}
10835
10836static HChar *
10837s390_irgen_MADB(UChar r3, IRTemp op2addr, UChar r1)
10838{
10839 IRExpr *op2 = load(Ity_F64, mkexpr(op2addr));
florian125e20d2012-10-07 15:42:37 +000010840 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000010841
floriandb4fcaa2012-09-05 19:54:08 +000010842 put_fpr_dw0(r1, qop(Iop_MAddF64, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000010843 get_fpr_dw0(r3), op2, get_fpr_dw0(r1)));
sewardj2019a972011-03-07 16:04:07 +000010844
10845 return "madb";
10846}
10847
10848static HChar *
10849s390_irgen_MSEBR(UChar r1, UChar r3, UChar r2)
10850{
florian125e20d2012-10-07 15:42:37 +000010851 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
florian847684d2012-09-05 04:19:09 +000010852
floriandb4fcaa2012-09-05 19:54:08 +000010853 put_fpr_w0(r1, qop(Iop_MSubF32, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000010854 get_fpr_w0(r3), get_fpr_w0(r2), get_fpr_w0(r1)));
sewardj2019a972011-03-07 16:04:07 +000010855
10856 return "msebr";
10857}
10858
10859static HChar *
10860s390_irgen_MSDBR(UChar r1, UChar r3, UChar r2)
10861{
florian125e20d2012-10-07 15:42:37 +000010862 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
florian847684d2012-09-05 04:19:09 +000010863
floriandb4fcaa2012-09-05 19:54:08 +000010864 put_fpr_dw0(r1, qop(Iop_MSubF64, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000010865 get_fpr_dw0(r3), get_fpr_dw0(r2), get_fpr_dw0(r1)));
sewardj2019a972011-03-07 16:04:07 +000010866
10867 return "msdbr";
10868}
10869
10870static HChar *
10871s390_irgen_MSEB(UChar r3, IRTemp op2addr, UChar r1)
10872{
10873 IRExpr *op2 = load(Ity_F32, mkexpr(op2addr));
florian125e20d2012-10-07 15:42:37 +000010874 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000010875
floriandb4fcaa2012-09-05 19:54:08 +000010876 put_fpr_w0(r1, qop(Iop_MSubF32, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000010877 get_fpr_w0(r3), op2, get_fpr_w0(r1)));
sewardj2019a972011-03-07 16:04:07 +000010878
10879 return "mseb";
10880}
10881
10882static HChar *
10883s390_irgen_MSDB(UChar r3, IRTemp op2addr, UChar r1)
10884{
10885 IRExpr *op2 = load(Ity_F64, mkexpr(op2addr));
florian125e20d2012-10-07 15:42:37 +000010886 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000010887
floriandb4fcaa2012-09-05 19:54:08 +000010888 put_fpr_dw0(r1, qop(Iop_MSubF64, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000010889 get_fpr_dw0(r3), op2, get_fpr_dw0(r1)));
sewardj2019a972011-03-07 16:04:07 +000010890
10891 return "msdb";
10892}
10893
10894static HChar *
10895s390_irgen_SQEBR(UChar r1, UChar r2)
10896{
10897 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +000010898 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000010899
floriandb4fcaa2012-09-05 19:54:08 +000010900 assign(result, binop(Iop_SqrtF32, mkexpr(rounding_mode), get_fpr_w0(r2)));
sewardj2019a972011-03-07 16:04:07 +000010901 put_fpr_w0(r1, mkexpr(result));
10902
10903 return "sqebr";
10904}
10905
10906static HChar *
10907s390_irgen_SQDBR(UChar r1, UChar r2)
10908{
10909 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +000010910 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000010911
floriandb4fcaa2012-09-05 19:54:08 +000010912 assign(result, binop(Iop_SqrtF64, mkexpr(rounding_mode), get_fpr_dw0(r2)));
sewardj2019a972011-03-07 16:04:07 +000010913 put_fpr_dw0(r1, mkexpr(result));
10914
10915 return "sqdbr";
10916}
10917
10918static HChar *
10919s390_irgen_SQXBR(UChar r1, UChar r2)
10920{
10921 IRTemp result = newTemp(Ity_F128);
florian125e20d2012-10-07 15:42:37 +000010922 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000010923
floriandb4fcaa2012-09-05 19:54:08 +000010924 assign(result, binop(Iop_SqrtF128, mkexpr(rounding_mode),
10925 get_fpr_pair(r2)));
sewardj2019a972011-03-07 16:04:07 +000010926 put_fpr_pair(r1, mkexpr(result));
10927
10928 return "sqxbr";
10929}
10930
10931static HChar *
10932s390_irgen_SQEB(UChar r1, IRTemp op2addr)
10933{
10934 IRTemp op = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +000010935 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000010936
10937 assign(op, load(Ity_F32, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +000010938 put_fpr_w0(r1, binop(Iop_SqrtF32, mkexpr(rounding_mode), mkexpr(op)));
sewardj2019a972011-03-07 16:04:07 +000010939
10940 return "sqeb";
10941}
10942
10943static HChar *
10944s390_irgen_SQDB(UChar r1, IRTemp op2addr)
10945{
10946 IRTemp op = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +000010947 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000010948
10949 assign(op, load(Ity_F64, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +000010950 put_fpr_dw0(r1, binop(Iop_SqrtF64, mkexpr(rounding_mode), mkexpr(op)));
sewardj2019a972011-03-07 16:04:07 +000010951
10952 return "sqdb";
10953}
10954
10955static HChar *
10956s390_irgen_SXBR(UChar r1, UChar r2)
10957{
10958 IRTemp op1 = newTemp(Ity_F128);
10959 IRTemp op2 = newTemp(Ity_F128);
10960 IRTemp result = newTemp(Ity_F128);
florian125e20d2012-10-07 15:42:37 +000010961 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000010962
10963 assign(op1, get_fpr_pair(r1));
10964 assign(op2, get_fpr_pair(r2));
floriandb4fcaa2012-09-05 19:54:08 +000010965 assign(result, triop(Iop_SubF128, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +000010966 mkexpr(op2)));
10967 put_fpr_pair(r1, mkexpr(result));
10968 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
10969
10970 return "sxbr";
10971}
10972
10973static HChar *
10974s390_irgen_TCEB(UChar r1, IRTemp op2addr)
10975{
10976 IRTemp value = newTemp(Ity_F32);
10977
10978 assign(value, get_fpr_w0(r1));
10979
10980 s390_cc_thunk_putFZ(S390_CC_OP_BFP_TDC_32, value, op2addr);
10981
10982 return "tceb";
10983}
10984
10985static HChar *
10986s390_irgen_TCDB(UChar r1, IRTemp op2addr)
10987{
10988 IRTemp value = newTemp(Ity_F64);
10989
10990 assign(value, get_fpr_dw0(r1));
10991
10992 s390_cc_thunk_putFZ(S390_CC_OP_BFP_TDC_64, value, op2addr);
10993
10994 return "tcdb";
10995}
10996
10997static HChar *
10998s390_irgen_TCXB(UChar r1, IRTemp op2addr)
10999{
11000 IRTemp value = newTemp(Ity_F128);
11001
11002 assign(value, get_fpr_pair(r1));
11003
11004 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_TDC_128, value, op2addr);
11005
11006 return "tcxb";
11007}
11008
11009static HChar *
11010s390_irgen_LCDFR(UChar r1, UChar r2)
11011{
11012 IRTemp result = newTemp(Ity_F64);
11013
11014 assign(result, unop(Iop_NegF64, get_fpr_dw0(r2)));
11015 put_fpr_dw0(r1, mkexpr(result));
11016
11017 return "lcdfr";
11018}
11019
11020static HChar *
11021s390_irgen_LNDFR(UChar r1, UChar r2)
11022{
11023 IRTemp result = newTemp(Ity_F64);
11024
11025 assign(result, unop(Iop_NegF64, unop(Iop_AbsF64, get_fpr_dw0(r2))));
11026 put_fpr_dw0(r1, mkexpr(result));
11027
11028 return "lndfr";
11029}
11030
11031static HChar *
11032s390_irgen_LPDFR(UChar r1, UChar r2)
11033{
11034 IRTemp result = newTemp(Ity_F64);
11035
11036 assign(result, unop(Iop_AbsF64, get_fpr_dw0(r2)));
11037 put_fpr_dw0(r1, mkexpr(result));
11038
11039 return "lpdfr";
11040}
11041
11042static HChar *
11043s390_irgen_LDGR(UChar r1, UChar r2)
11044{
11045 put_fpr_dw0(r1, unop(Iop_ReinterpI64asF64, get_gpr_dw0(r2)));
11046
11047 return "ldgr";
11048}
11049
11050static HChar *
11051s390_irgen_LGDR(UChar r1, UChar r2)
11052{
11053 put_gpr_dw0(r1, unop(Iop_ReinterpF64asI64, get_fpr_dw0(r2)));
11054
11055 return "lgdr";
11056}
11057
11058
11059static HChar *
11060s390_irgen_CPSDR(UChar r3, UChar r1, UChar r2)
11061{
11062 IRTemp sign = newTemp(Ity_I64);
11063 IRTemp value = newTemp(Ity_I64);
11064
11065 assign(sign, binop(Iop_And64, unop(Iop_ReinterpF64asI64, get_fpr_dw0(r3)),
11066 mkU64(1ULL << 63)));
11067 assign(value, binop(Iop_And64, unop(Iop_ReinterpF64asI64, get_fpr_dw0(r2)),
11068 mkU64((1ULL << 63) - 1)));
11069 put_fpr_dw0(r1, unop(Iop_ReinterpI64asF64, binop(Iop_Or64, mkexpr(value),
11070 mkexpr(sign))));
11071
11072 return "cpsdr";
11073}
11074
11075
sewardj2019a972011-03-07 16:04:07 +000011076static IRExpr *
11077s390_call_cvb(IRExpr *in)
11078{
11079 IRExpr **args, *call;
11080
11081 args = mkIRExprVec_1(in);
11082 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
11083 "s390_do_cvb", &s390_do_cvb, args);
11084
11085 /* Nothing is excluded from definedness checking. */
11086 call->Iex.CCall.cee->mcx_mask = 0;
11087
11088 return call;
11089}
11090
11091static HChar *
11092s390_irgen_CVB(UChar r1, IRTemp op2addr)
11093{
11094 put_gpr_w1(r1, s390_call_cvb(load(Ity_I64, mkexpr(op2addr))));
11095
11096 return "cvb";
11097}
11098
11099static HChar *
11100s390_irgen_CVBY(UChar r1, IRTemp op2addr)
11101{
11102 put_gpr_w1(r1, s390_call_cvb(load(Ity_I64, mkexpr(op2addr))));
11103
11104 return "cvby";
11105}
11106
11107
sewardj2019a972011-03-07 16:04:07 +000011108static IRExpr *
11109s390_call_cvd(IRExpr *in)
11110{
11111 IRExpr **args, *call;
11112
11113 args = mkIRExprVec_1(in);
11114 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
11115 "s390_do_cvd", &s390_do_cvd, args);
11116
11117 /* Nothing is excluded from definedness checking. */
11118 call->Iex.CCall.cee->mcx_mask = 0;
11119
11120 return call;
11121}
11122
11123static HChar *
11124s390_irgen_CVD(UChar r1, IRTemp op2addr)
11125{
florian11b8ee82012-08-06 13:35:33 +000011126 store(mkexpr(op2addr), s390_call_cvd(unop(Iop_32Uto64, get_gpr_w1(r1))));
sewardj2019a972011-03-07 16:04:07 +000011127
11128 return "cvd";
11129}
11130
11131static HChar *
11132s390_irgen_CVDY(UChar r1, IRTemp op2addr)
11133{
11134 store(mkexpr(op2addr), s390_call_cvd(get_gpr_w1(r1)));
11135
11136 return "cvdy";
11137}
11138
11139static HChar *
11140s390_irgen_FLOGR(UChar r1, UChar r2)
11141{
11142 IRTemp input = newTemp(Ity_I64);
11143 IRTemp not_zero = newTemp(Ity_I64);
11144 IRTemp tmpnum = newTemp(Ity_I64);
11145 IRTemp num = newTemp(Ity_I64);
11146 IRTemp shift_amount = newTemp(Ity_I8);
11147
11148 /* We use the "count leading zeroes" operator because the number of
11149 leading zeroes is identical with the bit position of the first '1' bit.
11150 However, that operator does not work when the input value is zero.
11151 Therefore, we set the LSB of the input value to 1 and use Clz64 on
11152 the modified value. If input == 0, then the result is 64. Otherwise,
11153 the result of Clz64 is what we want. */
11154
11155 assign(input, get_gpr_dw0(r2));
11156 assign(not_zero, binop(Iop_Or64, mkexpr(input), mkU64(1)));
11157 assign(tmpnum, unop(Iop_Clz64, mkexpr(not_zero)));
11158
11159 /* num = (input == 0) ? 64 : tmpnum */
11160 assign(num, mkite(binop(Iop_CmpEQ64, mkexpr(input), mkU64(0)),
11161 /* == 0 */ mkU64(64),
11162 /* != 0 */ mkexpr(tmpnum)));
11163
11164 put_gpr_dw0(r1, mkexpr(num));
11165
11166 /* Set the leftmost '1' bit of the input value to zero. The general scheme
11167 is to first shift the input value by NUM + 1 bits to the left which
11168 causes the leftmost '1' bit to disappear. Then we shift logically to
11169 the right by NUM + 1 bits. Because the semantics of Iop_Shl64 and
11170 Iop_Shr64 are undefined if the shift-amount is greater than or equal to
11171 the width of the value-to-be-shifted, we need to special case
11172 NUM + 1 >= 64. This is equivalent to INPUT != 0 && INPUT != 1.
11173 For both such INPUT values the result will be 0. */
11174
11175 assign(shift_amount, unop(Iop_64to8, binop(Iop_Add64, mkexpr(num),
11176 mkU64(1))));
11177
11178 put_gpr_dw0(r1 + 1,
florian6ad49522011-09-09 02:38:55 +000011179 mkite(binop(Iop_CmpLE64U, mkexpr(input), mkU64(1)),
11180 /* == 0 || == 1*/ mkU64(0),
11181 /* otherwise */
11182 binop(Iop_Shr64,
11183 binop(Iop_Shl64, mkexpr(input),
11184 mkexpr(shift_amount)),
11185 mkexpr(shift_amount))));
sewardj2019a972011-03-07 16:04:07 +000011186
11187 /* Compare the original value as an unsigned integer with 0. */
11188 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, input,
11189 mktemp(Ity_I64, mkU64(0)), False);
11190
11191 return "flogr";
11192}
11193
sewardj1e5fea62011-05-17 16:18:36 +000011194static HChar *
11195s390_irgen_STCK(IRTemp op2addr)
11196{
11197 IRDirty *d;
11198 IRTemp cc = newTemp(Ity_I64);
11199
11200 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STCK",
11201 &s390x_dirtyhelper_STCK,
11202 mkIRExprVec_1(mkexpr(op2addr)));
11203 d->mFx = Ifx_Write;
11204 d->mAddr = mkexpr(op2addr);
11205 d->mSize = 8;
11206 stmt(IRStmt_Dirty(d));
11207 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
11208 mkexpr(cc), mkU64(0), mkU64(0));
11209 return "stck";
11210}
11211
11212static HChar *
11213s390_irgen_STCKF(IRTemp op2addr)
11214{
florianc5c669b2012-08-26 14:32:28 +000011215 if (! s390_host_has_stckf) {
floriane75dafa2012-09-01 17:54:09 +000011216 emulation_failure(EmFail_S390X_stckf);
florianc5c669b2012-08-26 14:32:28 +000011217 } else {
11218 IRTemp cc = newTemp(Ity_I64);
sewardj1e5fea62011-05-17 16:18:36 +000011219
florianc5c669b2012-08-26 14:32:28 +000011220 IRDirty *d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STCKF",
11221 &s390x_dirtyhelper_STCKF,
11222 mkIRExprVec_1(mkexpr(op2addr)));
11223 d->mFx = Ifx_Write;
11224 d->mAddr = mkexpr(op2addr);
11225 d->mSize = 8;
11226 stmt(IRStmt_Dirty(d));
11227 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
11228 mkexpr(cc), mkU64(0), mkU64(0));
11229 }
sewardj1e5fea62011-05-17 16:18:36 +000011230 return "stckf";
11231}
11232
11233static HChar *
11234s390_irgen_STCKE(IRTemp op2addr)
11235{
11236 IRDirty *d;
11237 IRTemp cc = newTemp(Ity_I64);
11238
11239 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STCKE",
11240 &s390x_dirtyhelper_STCKE,
11241 mkIRExprVec_1(mkexpr(op2addr)));
11242 d->mFx = Ifx_Write;
11243 d->mAddr = mkexpr(op2addr);
11244 d->mSize = 16;
11245 stmt(IRStmt_Dirty(d));
11246 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
11247 mkexpr(cc), mkU64(0), mkU64(0));
11248 return "stcke";
11249}
11250
florian933065d2011-07-11 01:48:02 +000011251static HChar *
11252s390_irgen_STFLE(IRTemp op2addr)
11253{
florian4e0083e2012-08-26 03:41:56 +000011254 if (! s390_host_has_stfle) {
floriane75dafa2012-09-01 17:54:09 +000011255 emulation_failure(EmFail_S390X_stfle);
florian4e0083e2012-08-26 03:41:56 +000011256 return "stfle";
11257 }
11258
florian933065d2011-07-11 01:48:02 +000011259 IRDirty *d;
11260 IRTemp cc = newTemp(Ity_I64);
11261
11262 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STFLE",
11263 &s390x_dirtyhelper_STFLE,
11264 mkIRExprVec_1(mkexpr(op2addr)));
11265
11266 d->needsBBP = 1; /* Need to pass pointer to guest state to helper */
11267
sewardjc9069f22012-06-01 16:09:50 +000011268 d->nFxState = 1;
11269 vex_bzero(&d->fxState, sizeof(d->fxState));
11270
florian933065d2011-07-11 01:48:02 +000011271 d->fxState[0].fx = Ifx_Modify; /* read then write */
11272 d->fxState[0].offset = S390X_GUEST_OFFSET(guest_r0);
11273 d->fxState[0].size = sizeof(ULong);
florian933065d2011-07-11 01:48:02 +000011274
11275 d->mAddr = mkexpr(op2addr);
11276 /* Pretend all double words are written */
11277 d->mSize = S390_NUM_FACILITY_DW * sizeof(ULong);
11278 d->mFx = Ifx_Write;
11279
11280 stmt(IRStmt_Dirty(d));
11281
11282 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET), mkexpr(cc), mkU64(0), mkU64(0));
11283
11284 return "stfle";
11285}
11286
floriana4384a32011-08-11 16:58:45 +000011287static HChar *
11288s390_irgen_CKSM(UChar r1,UChar r2)
11289{
11290 IRTemp addr = newTemp(Ity_I64);
11291 IRTemp op = newTemp(Ity_I32);
11292 IRTemp len = newTemp(Ity_I64);
11293 IRTemp oldval = newTemp(Ity_I32);
11294 IRTemp mask = newTemp(Ity_I32);
11295 IRTemp newop = newTemp(Ity_I32);
11296 IRTemp result = newTemp(Ity_I32);
11297 IRTemp result1 = newTemp(Ity_I32);
11298 IRTemp inc = newTemp(Ity_I64);
11299
11300 assign(oldval, get_gpr_w1(r1));
11301 assign(addr, get_gpr_dw0(r2));
11302 assign(len, get_gpr_dw0(r2+1));
11303
11304 /* Condition code is always zero. */
11305 s390_cc_set(0);
11306
11307 /* If length is zero, there is no need to calculate the checksum */
florian6820ba52012-07-26 02:01:50 +000011308 next_insn_if(binop(Iop_CmpEQ64, mkexpr(len), mkU64(0)));
floriana4384a32011-08-11 16:58:45 +000011309
11310 /* Assiging the increment variable to adjust address and length
11311 later on. */
11312 assign(inc, mkite(binop(Iop_CmpLT64U, mkexpr(len), mkU64(4)),
11313 mkexpr(len), mkU64(4)));
11314
11315 /* If length < 4 the final 4-byte 2nd operand value is computed by
11316 appending the remaining bytes to the right with 0. This is done
11317 by AND'ing the 4 bytes loaded from memory with an appropriate
11318 mask. If length >= 4, that mask is simply 0xffffffff. */
11319
11320 assign(mask, mkite(binop(Iop_CmpLT64U, mkexpr(len), mkU64(4)),
11321 /* Mask computation when len < 4:
11322 0xffffffff << (32 - (len % 4)*8) */
11323 binop(Iop_Shl32, mkU32(0xffffffff),
11324 unop(Iop_32to8,
11325 binop(Iop_Sub32, mkU32(32),
11326 binop(Iop_Shl32,
11327 unop(Iop_64to32,
11328 binop(Iop_And64,
11329 mkexpr(len), mkU64(3))),
11330 mkU8(3))))),
11331 mkU32(0xffffffff)));
11332
11333 assign(op, load(Ity_I32, mkexpr(addr)));
11334 assign(newop, binop(Iop_And32, mkexpr(op), mkexpr(mask)));
11335 assign(result, binop(Iop_Add32, mkexpr(newop), mkexpr(oldval)));
11336
11337 /* Checking for carry */
11338 assign(result1, mkite(binop(Iop_CmpLT32U, mkexpr(result), mkexpr(newop)),
11339 binop(Iop_Add32, mkexpr(result), mkU32(1)),
11340 mkexpr(result)));
11341
11342 put_gpr_w1(r1, mkexpr(result1));
11343 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr), mkexpr(inc)));
11344 put_gpr_dw0(r2+1, binop(Iop_Sub64, mkexpr(len), mkexpr(inc)));
11345
florian6820ba52012-07-26 02:01:50 +000011346 iterate_if(binop(Iop_CmpNE64, mkexpr(len), mkU64(0)));
floriana4384a32011-08-11 16:58:45 +000011347
11348 return "cksm";
11349}
11350
florian9af37692012-01-15 21:01:16 +000011351static HChar *
11352s390_irgen_TROO(UChar m3, UChar r1, UChar r2)
11353{
11354 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
11355 src_addr = newTemp(Ity_I64);
11356 des_addr = newTemp(Ity_I64);
11357 tab_addr = newTemp(Ity_I64);
11358 test_byte = newTemp(Ity_I8);
11359 src_len = newTemp(Ity_I64);
11360
11361 assign(src_addr, get_gpr_dw0(r2));
11362 assign(des_addr, get_gpr_dw0(r1));
11363 assign(tab_addr, get_gpr_dw0(1));
florian53518532012-01-18 14:00:31 +000011364 assign(src_len, get_gpr_dw0(r1+1));
florian9af37692012-01-15 21:01:16 +000011365 assign(test_byte, get_gpr_b7(0));
11366
11367 IRTemp op = newTemp(Ity_I8);
11368 IRTemp op1 = newTemp(Ity_I8);
11369 IRTemp result = newTemp(Ity_I64);
11370
11371 /* End of source string? We're done; proceed to next insn */
11372 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000011373 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian9af37692012-01-15 21:01:16 +000011374
11375 /* Load character from source string, index translation table and
11376 store translated character in op1. */
11377 assign(op, load(Ity_I8, mkexpr(src_addr)));
11378
11379 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)),
11380 mkexpr(tab_addr)));
11381 assign(op1, load(Ity_I8, mkexpr(result)));
11382
11383 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
11384 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000011385 next_insn_if(binop(Iop_CmpEQ8, mkexpr(op1), mkexpr(test_byte)));
florian9af37692012-01-15 21:01:16 +000011386 }
11387 store(get_gpr_dw0(r1), mkexpr(op1));
11388
11389 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(1)));
11390 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(1)));
11391 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(1)));
11392
florian6820ba52012-07-26 02:01:50 +000011393 iterate();
florian9af37692012-01-15 21:01:16 +000011394
11395 return "troo";
11396}
11397
florian730448f2012-02-04 17:07:07 +000011398static HChar *
11399s390_irgen_TRTO(UChar m3, UChar r1, UChar r2)
11400{
11401 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
11402 src_addr = newTemp(Ity_I64);
11403 des_addr = newTemp(Ity_I64);
11404 tab_addr = newTemp(Ity_I64);
11405 test_byte = newTemp(Ity_I8);
11406 src_len = newTemp(Ity_I64);
11407
11408 assign(src_addr, get_gpr_dw0(r2));
11409 assign(des_addr, get_gpr_dw0(r1));
11410 assign(tab_addr, get_gpr_dw0(1));
11411 assign(src_len, get_gpr_dw0(r1+1));
11412 assign(test_byte, get_gpr_b7(0));
11413
11414 IRTemp op = newTemp(Ity_I16);
11415 IRTemp op1 = newTemp(Ity_I8);
11416 IRTemp result = newTemp(Ity_I64);
11417
11418 /* End of source string? We're done; proceed to next insn */
11419 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000011420 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian730448f2012-02-04 17:07:07 +000011421
11422 /* Load character from source string, index translation table and
11423 store translated character in op1. */
11424 assign(op, load(Ity_I16, mkexpr(src_addr)));
11425
11426 assign(result, binop(Iop_Add64, unop(Iop_16Uto64, mkexpr(op)),
11427 mkexpr(tab_addr)));
11428
11429 assign(op1, load(Ity_I8, mkexpr(result)));
11430
11431 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
11432 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000011433 next_insn_if(binop(Iop_CmpEQ8, mkexpr(op1), mkexpr(test_byte)));
florian730448f2012-02-04 17:07:07 +000011434 }
11435 store(get_gpr_dw0(r1), mkexpr(op1));
11436
11437 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(2)));
11438 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(1)));
11439 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(2)));
11440
florian6820ba52012-07-26 02:01:50 +000011441 iterate();
florian730448f2012-02-04 17:07:07 +000011442
11443 return "trto";
11444}
11445
11446static HChar *
11447s390_irgen_TROT(UChar m3, UChar r1, UChar r2)
11448{
11449 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
11450 src_addr = newTemp(Ity_I64);
11451 des_addr = newTemp(Ity_I64);
11452 tab_addr = newTemp(Ity_I64);
11453 test_byte = newTemp(Ity_I16);
11454 src_len = newTemp(Ity_I64);
11455
11456 assign(src_addr, get_gpr_dw0(r2));
11457 assign(des_addr, get_gpr_dw0(r1));
11458 assign(tab_addr, get_gpr_dw0(1));
11459 assign(src_len, get_gpr_dw0(r1+1));
11460 assign(test_byte, get_gpr_hw3(0));
11461
11462 IRTemp op = newTemp(Ity_I8);
11463 IRTemp op1 = newTemp(Ity_I16);
11464 IRTemp result = newTemp(Ity_I64);
11465
11466 /* End of source string? We're done; proceed to next insn */
11467 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000011468 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian730448f2012-02-04 17:07:07 +000011469
11470 /* Load character from source string, index translation table and
11471 store translated character in op1. */
11472 assign(op, binop(Iop_Shl8, load(Ity_I8, mkexpr(src_addr)), mkU8(1)));
11473
11474 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)),
11475 mkexpr(tab_addr)));
11476 assign(op1, load(Ity_I16, mkexpr(result)));
11477
11478 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
11479 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000011480 next_insn_if(binop(Iop_CmpEQ16, mkexpr(op1), mkexpr(test_byte)));
florian730448f2012-02-04 17:07:07 +000011481 }
11482 store(get_gpr_dw0(r1), mkexpr(op1));
11483
11484 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(1)));
11485 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(2)));
11486 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(1)));
11487
florian6820ba52012-07-26 02:01:50 +000011488 iterate();
florian730448f2012-02-04 17:07:07 +000011489
11490 return "trot";
11491}
11492
11493static HChar *
11494s390_irgen_TRTT(UChar m3, UChar r1, UChar r2)
11495{
11496 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
11497 src_addr = newTemp(Ity_I64);
11498 des_addr = newTemp(Ity_I64);
11499 tab_addr = newTemp(Ity_I64);
11500 test_byte = newTemp(Ity_I16);
11501 src_len = newTemp(Ity_I64);
11502
11503 assign(src_addr, get_gpr_dw0(r2));
11504 assign(des_addr, get_gpr_dw0(r1));
11505 assign(tab_addr, get_gpr_dw0(1));
11506 assign(src_len, get_gpr_dw0(r1+1));
11507 assign(test_byte, get_gpr_hw3(0));
11508
11509 IRTemp op = newTemp(Ity_I16);
11510 IRTemp op1 = newTemp(Ity_I16);
11511 IRTemp result = newTemp(Ity_I64);
11512
11513 /* End of source string? We're done; proceed to next insn */
11514 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000011515 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian730448f2012-02-04 17:07:07 +000011516
11517 /* Load character from source string, index translation table and
11518 store translated character in op1. */
11519 assign(op, binop(Iop_Shl16, load(Ity_I16, mkexpr(src_addr)), mkU8(1)));
11520
11521 assign(result, binop(Iop_Add64, unop(Iop_16Uto64, mkexpr(op)),
11522 mkexpr(tab_addr)));
11523 assign(op1, load(Ity_I16, mkexpr(result)));
11524
11525 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
11526 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000011527 next_insn_if(binop(Iop_CmpEQ16, mkexpr(op1), mkexpr(test_byte)));
florian730448f2012-02-04 17:07:07 +000011528 }
11529
11530 store(get_gpr_dw0(r1), mkexpr(op1));
11531
11532 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(2)));
11533 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(2)));
11534 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(2)));
11535
florian6820ba52012-07-26 02:01:50 +000011536 iterate();
florian730448f2012-02-04 17:07:07 +000011537
11538 return "trtt";
11539}
11540
11541static HChar *
11542s390_irgen_TR(UChar length, IRTemp start1, IRTemp start2)
11543{
florianf87d4fb2012-05-05 02:55:24 +000011544 IRTemp len = newTemp(Ity_I64);
florian730448f2012-02-04 17:07:07 +000011545
florianf87d4fb2012-05-05 02:55:24 +000011546 assign(len, mkU64(length));
11547 s390_irgen_TR_EX(len, start1, start2);
florian730448f2012-02-04 17:07:07 +000011548
11549 return "tr";
11550}
11551
11552static HChar *
11553s390_irgen_TRE(UChar r1,UChar r2)
11554{
11555 IRTemp src_addr, tab_addr, src_len, test_byte;
11556 src_addr = newTemp(Ity_I64);
11557 tab_addr = newTemp(Ity_I64);
11558 src_len = newTemp(Ity_I64);
11559 test_byte = newTemp(Ity_I8);
11560
11561 assign(src_addr, get_gpr_dw0(r1));
11562 assign(src_len, get_gpr_dw0(r1+1));
11563 assign(tab_addr, get_gpr_dw0(r2));
11564 assign(test_byte, get_gpr_b7(0));
11565
11566 IRTemp op = newTemp(Ity_I8);
11567 IRTemp op1 = newTemp(Ity_I8);
11568 IRTemp result = newTemp(Ity_I64);
11569
11570 /* End of source string? We're done; proceed to next insn */
11571 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000011572 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian730448f2012-02-04 17:07:07 +000011573
11574 /* Load character from source string and compare with test byte */
11575 assign(op, load(Ity_I8, mkexpr(src_addr)));
11576
11577 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000011578 next_insn_if(binop(Iop_CmpEQ8, mkexpr(op), mkexpr(test_byte)));
florian730448f2012-02-04 17:07:07 +000011579
11580 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)),
11581 mkexpr(tab_addr)));
11582
11583 assign(op1, load(Ity_I8, mkexpr(result)));
11584
11585 store(get_gpr_dw0(r1), mkexpr(op1));
11586 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(src_addr), mkU64(1)));
11587 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(1)));
11588
florian6820ba52012-07-26 02:01:50 +000011589 iterate();
florian730448f2012-02-04 17:07:07 +000011590
11591 return "tre";
11592}
11593
floriana0100c92012-07-20 00:06:35 +000011594static IRExpr *
11595s390_call_cu21(IRExpr *srcval, IRExpr *low_surrogate)
11596{
11597 IRExpr **args, *call;
11598 args = mkIRExprVec_2(srcval, low_surrogate);
11599 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
11600 "s390_do_cu21", &s390_do_cu21, args);
11601
11602 /* Nothing is excluded from definedness checking. */
11603 call->Iex.CCall.cee->mcx_mask = 0;
11604
11605 return call;
11606}
11607
11608static HChar *
11609s390_irgen_CU21(UChar m3, UChar r1, UChar r2)
11610{
11611 IRTemp addr1 = newTemp(Ity_I64);
11612 IRTemp addr2 = newTemp(Ity_I64);
11613 IRTemp len1 = newTemp(Ity_I64);
11614 IRTemp len2 = newTemp(Ity_I64);
11615
11616 assign(addr1, get_gpr_dw0(r1));
11617 assign(addr2, get_gpr_dw0(r2));
11618 assign(len1, get_gpr_dw0(r1 + 1));
11619 assign(len2, get_gpr_dw0(r2 + 1));
11620
11621 /* We're processing the 2nd operand 2 bytes at a time. Therefore, if
11622 there are less than 2 bytes left, then the 2nd operand is exhausted
11623 and we're done here. cc = 0 */
11624 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000011625 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(2)));
floriana0100c92012-07-20 00:06:35 +000011626
11627 /* There are at least two bytes there. Read them. */
11628 IRTemp srcval = newTemp(Ity_I32);
11629 assign(srcval, unop(Iop_16Uto32, load(Ity_I16, mkexpr(addr2))));
11630
11631 /* Find out whether this is a high surrogate. I.e. SRCVAL lies
11632 inside the interval [0xd800 - 0xdbff] */
11633 IRTemp is_high_surrogate = newTemp(Ity_I32);
11634 IRExpr *flag1 = mkite(binop(Iop_CmpLE32U, mkU32(0xd800), mkexpr(srcval)),
11635 mkU32(1), mkU32(0));
11636 IRExpr *flag2 = mkite(binop(Iop_CmpLE32U, mkexpr(srcval), mkU32(0xdbff)),
11637 mkU32(1), mkU32(0));
11638 assign(is_high_surrogate, binop(Iop_And32, flag1, flag2));
11639
11640 /* If SRCVAL is a high surrogate and there are less than 4 bytes left,
11641 then the 2nd operand is exhausted and we're done here. cc = 0 */
11642 IRExpr *not_enough_bytes =
11643 mkite(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)), mkU32(1), mkU32(0));
11644
florian6820ba52012-07-26 02:01:50 +000011645 next_insn_if(binop(Iop_CmpEQ32,
11646 binop(Iop_And32, mkexpr(is_high_surrogate),
11647 not_enough_bytes), mkU32(1)));
floriana0100c92012-07-20 00:06:35 +000011648
11649 /* The 2nd operand is not exhausted. If the first 2 bytes are a high
11650 surrogate, read the next two bytes (low surrogate). */
11651 IRTemp low_surrogate = newTemp(Ity_I32);
11652 IRExpr *low_surrogate_addr = binop(Iop_Add64, mkexpr(addr2), mkU64(2));
11653
11654 assign(low_surrogate,
11655 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
11656 unop(Iop_16Uto32, load(Ity_I16, low_surrogate_addr)),
11657 mkU32(0))); // any value is fine; it will not be used
11658
11659 /* Call the helper */
11660 IRTemp retval = newTemp(Ity_I64);
florian11b8ee82012-08-06 13:35:33 +000011661 assign(retval, s390_call_cu21(unop(Iop_32Uto64, mkexpr(srcval)),
11662 unop(Iop_32Uto64, mkexpr(low_surrogate))));
floriana0100c92012-07-20 00:06:35 +000011663
11664 /* Before we can test whether the 1st operand is exhausted we need to
11665 test for an invalid low surrogate. Because cc=2 outranks cc=1. */
11666 if (s390_host_has_etf3 && (m3 & 0x1) == 1) {
11667 IRExpr *invalid_low_surrogate =
11668 binop(Iop_And64, mkexpr(retval), mkU64(0xff));
11669
11670 s390_cc_set(2);
florian6820ba52012-07-26 02:01:50 +000011671 next_insn_if(binop(Iop_CmpEQ64, invalid_low_surrogate, mkU64(1)));
floriana0100c92012-07-20 00:06:35 +000011672 }
11673
11674 /* Now test whether the 1st operand is exhausted */
11675 IRTemp num_bytes = newTemp(Ity_I64);
11676 assign(num_bytes, binop(Iop_And64,
11677 binop(Iop_Shr64, mkexpr(retval), mkU8(8)),
11678 mkU64(0xff)));
11679 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000011680 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
floriana0100c92012-07-20 00:06:35 +000011681
11682 /* Extract the bytes to be stored at addr1 */
11683 IRTemp data = newTemp(Ity_I64);
11684 assign(data, binop(Iop_Shr64, mkexpr(retval), mkU8(16)));
11685
11686 /* To store the bytes construct 4 dirty helper calls. The helper calls
11687 are guarded (num_bytes == 1, num_bytes == 2, etc) such that only
11688 one of them will be called at runtime. */
11689 int i;
11690 for (i = 1; i <= 4; ++i) {
11691 IRDirty *d;
11692
11693 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
11694 &s390x_dirtyhelper_CUxy,
11695 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
11696 mkexpr(num_bytes)));
11697 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
11698 d->mFx = Ifx_Write;
11699 d->mAddr = mkexpr(addr1);
11700 d->mSize = i;
11701 stmt(IRStmt_Dirty(d));
11702 }
11703
11704 /* Update source address and length */
11705 IRTemp num_src_bytes = newTemp(Ity_I64);
11706 assign(num_src_bytes,
11707 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
11708 mkU64(4), mkU64(2)));
11709 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkexpr(num_src_bytes)));
11710 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkexpr(num_src_bytes)));
11711
11712 /* Update destination address and length */
11713 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
11714 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
11715
florian6820ba52012-07-26 02:01:50 +000011716 iterate();
floriana0100c92012-07-20 00:06:35 +000011717
11718 return "cu21";
11719}
11720
florian2a415a12012-07-21 17:41:36 +000011721static IRExpr *
11722s390_call_cu24(IRExpr *srcval, IRExpr *low_surrogate)
11723{
11724 IRExpr **args, *call;
11725 args = mkIRExprVec_2(srcval, low_surrogate);
11726 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
11727 "s390_do_cu24", &s390_do_cu24, args);
11728
11729 /* Nothing is excluded from definedness checking. */
11730 call->Iex.CCall.cee->mcx_mask = 0;
11731
11732 return call;
11733}
11734
11735static HChar *
11736s390_irgen_CU24(UChar m3, UChar r1, UChar r2)
11737{
11738 IRTemp addr1 = newTemp(Ity_I64);
11739 IRTemp addr2 = newTemp(Ity_I64);
11740 IRTemp len1 = newTemp(Ity_I64);
11741 IRTemp len2 = newTemp(Ity_I64);
11742
11743 assign(addr1, get_gpr_dw0(r1));
11744 assign(addr2, get_gpr_dw0(r2));
11745 assign(len1, get_gpr_dw0(r1 + 1));
11746 assign(len2, get_gpr_dw0(r2 + 1));
11747
11748 /* We're processing the 2nd operand 2 bytes at a time. Therefore, if
11749 there are less than 2 bytes left, then the 2nd operand is exhausted
11750 and we're done here. cc = 0 */
11751 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000011752 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(2)));
florian2a415a12012-07-21 17:41:36 +000011753
11754 /* There are at least two bytes there. Read them. */
11755 IRTemp srcval = newTemp(Ity_I32);
11756 assign(srcval, unop(Iop_16Uto32, load(Ity_I16, mkexpr(addr2))));
11757
11758 /* Find out whether this is a high surrogate. I.e. SRCVAL lies
11759 inside the interval [0xd800 - 0xdbff] */
11760 IRTemp is_high_surrogate = newTemp(Ity_I32);
11761 IRExpr *flag1 = mkite(binop(Iop_CmpLE32U, mkU32(0xd800), mkexpr(srcval)),
11762 mkU32(1), mkU32(0));
11763 IRExpr *flag2 = mkite(binop(Iop_CmpLE32U, mkexpr(srcval), mkU32(0xdbff)),
11764 mkU32(1), mkU32(0));
11765 assign(is_high_surrogate, binop(Iop_And32, flag1, flag2));
11766
11767 /* If SRCVAL is a high surrogate and there are less than 4 bytes left,
11768 then the 2nd operand is exhausted and we're done here. cc = 0 */
11769 IRExpr *not_enough_bytes =
11770 mkite(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)), mkU32(1), mkU32(0));
11771
florian6820ba52012-07-26 02:01:50 +000011772 next_insn_if(binop(Iop_CmpEQ32,
11773 binop(Iop_And32, mkexpr(is_high_surrogate),
11774 not_enough_bytes),
11775 mkU32(1)));
florian2a415a12012-07-21 17:41:36 +000011776
11777 /* The 2nd operand is not exhausted. If the first 2 bytes are a high
11778 surrogate, read the next two bytes (low surrogate). */
11779 IRTemp low_surrogate = newTemp(Ity_I32);
11780 IRExpr *low_surrogate_addr = binop(Iop_Add64, mkexpr(addr2), mkU64(2));
11781
11782 assign(low_surrogate,
11783 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
11784 unop(Iop_16Uto32, load(Ity_I16, low_surrogate_addr)),
11785 mkU32(0))); // any value is fine; it will not be used
11786
11787 /* Call the helper */
11788 IRTemp retval = newTemp(Ity_I64);
florian11b8ee82012-08-06 13:35:33 +000011789 assign(retval, s390_call_cu24(unop(Iop_32Uto64, mkexpr(srcval)),
11790 unop(Iop_32Uto64, mkexpr(low_surrogate))));
florian2a415a12012-07-21 17:41:36 +000011791
11792 /* Before we can test whether the 1st operand is exhausted we need to
11793 test for an invalid low surrogate. Because cc=2 outranks cc=1. */
11794 if (s390_host_has_etf3 && (m3 & 0x1) == 1) {
11795 IRExpr *invalid_low_surrogate =
11796 binop(Iop_And64, mkexpr(retval), mkU64(0xff));
11797
11798 s390_cc_set(2);
florian6820ba52012-07-26 02:01:50 +000011799 next_insn_if(binop(Iop_CmpEQ64, invalid_low_surrogate, mkU64(1)));
florian2a415a12012-07-21 17:41:36 +000011800 }
11801
11802 /* Now test whether the 1st operand is exhausted */
11803 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000011804 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkU64(4)));
florian2a415a12012-07-21 17:41:36 +000011805
11806 /* Extract the bytes to be stored at addr1 */
11807 IRExpr *data = unop(Iop_64to32, binop(Iop_Shr64, mkexpr(retval), mkU8(8)));
11808
11809 store(mkexpr(addr1), data);
11810
11811 /* Update source address and length */
11812 IRTemp num_src_bytes = newTemp(Ity_I64);
11813 assign(num_src_bytes,
11814 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
11815 mkU64(4), mkU64(2)));
11816 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkexpr(num_src_bytes)));
11817 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkexpr(num_src_bytes)));
11818
11819 /* Update destination address and length */
11820 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkU64(4)));
11821 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkU64(4)));
11822
florian6820ba52012-07-26 02:01:50 +000011823 iterate();
florian2a415a12012-07-21 17:41:36 +000011824
11825 return "cu24";
11826}
floriana4384a32011-08-11 16:58:45 +000011827
florian956194b2012-07-28 22:18:32 +000011828static IRExpr *
11829s390_call_cu42(IRExpr *srcval)
11830{
11831 IRExpr **args, *call;
11832 args = mkIRExprVec_1(srcval);
11833 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
11834 "s390_do_cu42", &s390_do_cu42, args);
11835
11836 /* Nothing is excluded from definedness checking. */
11837 call->Iex.CCall.cee->mcx_mask = 0;
11838
11839 return call;
11840}
11841
11842static HChar *
11843s390_irgen_CU42(UChar r1, UChar r2)
11844{
11845 IRTemp addr1 = newTemp(Ity_I64);
11846 IRTemp addr2 = newTemp(Ity_I64);
11847 IRTemp len1 = newTemp(Ity_I64);
11848 IRTemp len2 = newTemp(Ity_I64);
11849
11850 assign(addr1, get_gpr_dw0(r1));
11851 assign(addr2, get_gpr_dw0(r2));
11852 assign(len1, get_gpr_dw0(r1 + 1));
11853 assign(len2, get_gpr_dw0(r2 + 1));
11854
11855 /* We're processing the 2nd operand 4 bytes at a time. Therefore, if
11856 there are less than 4 bytes left, then the 2nd operand is exhausted
11857 and we're done here. cc = 0 */
11858 s390_cc_set(0);
11859 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)));
11860
11861 /* Read the 2nd operand. */
11862 IRTemp srcval = newTemp(Ity_I32);
11863 assign(srcval, load(Ity_I32, mkexpr(addr2)));
11864
11865 /* Call the helper */
11866 IRTemp retval = newTemp(Ity_I64);
florian11b8ee82012-08-06 13:35:33 +000011867 assign(retval, s390_call_cu42(unop(Iop_32Uto64, mkexpr(srcval))));
florian956194b2012-07-28 22:18:32 +000011868
11869 /* If the UTF-32 character was invalid, set cc=2 and we're done.
11870 cc=2 outranks cc=1 (1st operand exhausted) */
11871 IRExpr *invalid_character = binop(Iop_And64, mkexpr(retval), mkU64(0xff));
11872
11873 s390_cc_set(2);
11874 next_insn_if(binop(Iop_CmpEQ64, invalid_character, mkU64(1)));
11875
11876 /* Now test whether the 1st operand is exhausted */
11877 IRTemp num_bytes = newTemp(Ity_I64);
11878 assign(num_bytes, binop(Iop_And64,
11879 binop(Iop_Shr64, mkexpr(retval), mkU8(8)),
11880 mkU64(0xff)));
11881 s390_cc_set(1);
11882 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
11883
11884 /* Extract the bytes to be stored at addr1 */
11885 IRTemp data = newTemp(Ity_I64);
11886 assign(data, binop(Iop_Shr64, mkexpr(retval), mkU8(16)));
11887
11888 /* To store the bytes construct 2 dirty helper calls. The helper calls
11889 are guarded (num_bytes == 2 and num_bytes == 4, respectively) such
11890 that only one of them will be called at runtime. */
11891
11892 Int i;
11893 for (i = 2; i <= 4; ++i) {
11894 IRDirty *d;
11895
11896 if (i == 3) continue; // skip this one
11897
11898 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
11899 &s390x_dirtyhelper_CUxy,
11900 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
11901 mkexpr(num_bytes)));
11902 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
11903 d->mFx = Ifx_Write;
11904 d->mAddr = mkexpr(addr1);
11905 d->mSize = i;
11906 stmt(IRStmt_Dirty(d));
11907 }
11908
11909 /* Update source address and length */
11910 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkU64(4)));
11911 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkU64(4)));
11912
11913 /* Update destination address and length */
11914 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
11915 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
11916
11917 iterate();
11918
11919 return "cu42";
11920}
11921
florian6d9b9b22012-08-03 18:35:39 +000011922static IRExpr *
florianaf2194f2012-08-06 00:07:54 +000011923s390_call_cu41(IRExpr *srcval)
11924{
11925 IRExpr **args, *call;
11926 args = mkIRExprVec_1(srcval);
11927 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
11928 "s390_do_cu41", &s390_do_cu41, args);
11929
11930 /* Nothing is excluded from definedness checking. */
11931 call->Iex.CCall.cee->mcx_mask = 0;
11932
11933 return call;
11934}
11935
11936static HChar *
11937s390_irgen_CU41(UChar r1, UChar r2)
11938{
11939 IRTemp addr1 = newTemp(Ity_I64);
11940 IRTemp addr2 = newTemp(Ity_I64);
11941 IRTemp len1 = newTemp(Ity_I64);
11942 IRTemp len2 = newTemp(Ity_I64);
11943
11944 assign(addr1, get_gpr_dw0(r1));
11945 assign(addr2, get_gpr_dw0(r2));
11946 assign(len1, get_gpr_dw0(r1 + 1));
11947 assign(len2, get_gpr_dw0(r2 + 1));
11948
11949 /* We're processing the 2nd operand 4 bytes at a time. Therefore, if
11950 there are less than 4 bytes left, then the 2nd operand is exhausted
11951 and we're done here. cc = 0 */
11952 s390_cc_set(0);
11953 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)));
11954
11955 /* Read the 2nd operand. */
11956 IRTemp srcval = newTemp(Ity_I32);
11957 assign(srcval, load(Ity_I32, mkexpr(addr2)));
11958
11959 /* Call the helper */
11960 IRTemp retval = newTemp(Ity_I64);
florian11b8ee82012-08-06 13:35:33 +000011961 assign(retval, s390_call_cu41(unop(Iop_32Uto64, mkexpr(srcval))));
florianaf2194f2012-08-06 00:07:54 +000011962
11963 /* If the UTF-32 character was invalid, set cc=2 and we're done.
11964 cc=2 outranks cc=1 (1st operand exhausted) */
11965 IRExpr *invalid_character = binop(Iop_And64, mkexpr(retval), mkU64(0xff));
11966
11967 s390_cc_set(2);
11968 next_insn_if(binop(Iop_CmpEQ64, invalid_character, mkU64(1)));
11969
11970 /* Now test whether the 1st operand is exhausted */
11971 IRTemp num_bytes = newTemp(Ity_I64);
11972 assign(num_bytes, binop(Iop_And64,
11973 binop(Iop_Shr64, mkexpr(retval), mkU8(8)),
11974 mkU64(0xff)));
11975 s390_cc_set(1);
11976 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
11977
11978 /* Extract the bytes to be stored at addr1 */
11979 IRTemp data = newTemp(Ity_I64);
11980 assign(data, binop(Iop_Shr64, mkexpr(retval), mkU8(16)));
11981
11982 /* To store the bytes construct 4 dirty helper calls. The helper calls
11983 are guarded (num_bytes == 1, num_bytes == 2, etc) such that only
11984 one of them will be called at runtime. */
11985 int i;
11986 for (i = 1; i <= 4; ++i) {
11987 IRDirty *d;
11988
11989 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
11990 &s390x_dirtyhelper_CUxy,
11991 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
11992 mkexpr(num_bytes)));
11993 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
11994 d->mFx = Ifx_Write;
11995 d->mAddr = mkexpr(addr1);
11996 d->mSize = i;
11997 stmt(IRStmt_Dirty(d));
11998 }
11999
12000 /* Update source address and length */
12001 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkU64(4)));
12002 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkU64(4)));
12003
12004 /* Update destination address and length */
12005 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
12006 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
12007
12008 iterate();
12009
12010 return "cu41";
12011}
12012
12013static IRExpr *
florian3f8a96a2012-08-05 02:59:55 +000012014s390_call_cu12_cu14_helper1(IRExpr *byte1, IRExpr *etf3_and_m3_is_1)
florian6d9b9b22012-08-03 18:35:39 +000012015{
12016 IRExpr **args, *call;
12017 args = mkIRExprVec_2(byte1, etf3_and_m3_is_1);
florian3f8a96a2012-08-05 02:59:55 +000012018 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/, "s390_do_cu12_cu14_helper1",
12019 &s390_do_cu12_cu14_helper1, args);
florian6d9b9b22012-08-03 18:35:39 +000012020
12021 /* Nothing is excluded from definedness checking. */
12022 call->Iex.CCall.cee->mcx_mask = 0;
12023
12024 return call;
12025}
12026
12027static IRExpr *
12028s390_call_cu12_helper2(IRExpr *byte1, IRExpr *byte2, IRExpr *byte3,
12029 IRExpr *byte4, IRExpr *stuff)
12030{
12031 IRExpr **args, *call;
12032 args = mkIRExprVec_5(byte1, byte2, byte3, byte4, stuff);
12033 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
12034 "s390_do_cu12_helper2", &s390_do_cu12_helper2, args);
12035
12036 /* Nothing is excluded from definedness checking. */
12037 call->Iex.CCall.cee->mcx_mask = 0;
12038
12039 return call;
12040}
12041
florian3f8a96a2012-08-05 02:59:55 +000012042static IRExpr *
12043s390_call_cu14_helper2(IRExpr *byte1, IRExpr *byte2, IRExpr *byte3,
12044 IRExpr *byte4, IRExpr *stuff)
12045{
12046 IRExpr **args, *call;
12047 args = mkIRExprVec_5(byte1, byte2, byte3, byte4, stuff);
12048 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
12049 "s390_do_cu14_helper2", &s390_do_cu14_helper2, args);
12050
12051 /* Nothing is excluded from definedness checking. */
12052 call->Iex.CCall.cee->mcx_mask = 0;
12053
12054 return call;
12055}
12056
12057static void
12058s390_irgen_cu12_cu14(UChar m3, UChar r1, UChar r2, Bool is_cu12)
florian6d9b9b22012-08-03 18:35:39 +000012059{
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 UInt extended_checking = s390_host_has_etf3 && (m3 & 0x1) == 1;
12071
12072 /* We're processing the 2nd operand 1 byte at a time. Therefore, if
12073 there is less than 1 byte left, then the 2nd operand is exhausted
12074 and we're done here. cc = 0 */
12075 s390_cc_set(0);
12076 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(1)));
12077
12078 /* There is at least one byte there. Read it. */
florian11b8ee82012-08-06 13:35:33 +000012079 IRTemp byte1 = newTemp(Ity_I64);
12080 assign(byte1, unop(Iop_8Uto64, load(Ity_I8, mkexpr(addr2))));
florian6d9b9b22012-08-03 18:35:39 +000012081
12082 /* Call the helper to get number of bytes and invalid byte indicator */
12083 IRTemp retval1 = newTemp(Ity_I64);
florian3f8a96a2012-08-05 02:59:55 +000012084 assign(retval1, s390_call_cu12_cu14_helper1(mkexpr(byte1),
florian11b8ee82012-08-06 13:35:33 +000012085 mkU64(extended_checking)));
florian6d9b9b22012-08-03 18:35:39 +000012086
12087 /* Check for invalid 1st byte */
12088 IRExpr *is_invalid = unop(Iop_64to1, mkexpr(retval1));
12089 s390_cc_set(2);
12090 next_insn_if(is_invalid);
12091
12092 /* How many bytes do we have to read? */
12093 IRTemp num_src_bytes = newTemp(Ity_I64);
12094 assign(num_src_bytes, binop(Iop_Shr64, mkexpr(retval1), mkU8(8)));
12095
12096 /* Now test whether the 2nd operand is exhausted */
12097 s390_cc_set(0);
12098 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkexpr(num_src_bytes)));
12099
12100 /* Read the remaining bytes */
12101 IRExpr *cond, *addr, *byte2, *byte3, *byte4;
12102
12103 cond = binop(Iop_CmpLE64U, mkU64(2), mkexpr(num_src_bytes));
12104 addr = binop(Iop_Add64, mkexpr(addr2), mkU64(1));
florian11b8ee82012-08-06 13:35:33 +000012105 byte2 = mkite(cond, unop(Iop_8Uto64, load(Ity_I8, addr)), mkU64(0));
florian6d9b9b22012-08-03 18:35:39 +000012106 cond = binop(Iop_CmpLE64U, mkU64(3), mkexpr(num_src_bytes));
12107 addr = binop(Iop_Add64, mkexpr(addr2), mkU64(2));
florian11b8ee82012-08-06 13:35:33 +000012108 byte3 = mkite(cond, unop(Iop_8Uto64, load(Ity_I8, addr)), mkU64(0));
florian6d9b9b22012-08-03 18:35:39 +000012109 cond = binop(Iop_CmpLE64U, mkU64(4), mkexpr(num_src_bytes));
12110 addr = binop(Iop_Add64, mkexpr(addr2), mkU64(3));
florian11b8ee82012-08-06 13:35:33 +000012111 byte4 = mkite(cond, unop(Iop_8Uto64, load(Ity_I8, addr)), mkU64(0));
florian6d9b9b22012-08-03 18:35:39 +000012112
12113 /* Call the helper to get the converted value and invalid byte indicator.
12114 We can pass at most 5 arguments; therefore some encoding is needed
12115 here */
12116 IRExpr *stuff = binop(Iop_Or64,
12117 binop(Iop_Shl64, mkexpr(num_src_bytes), mkU8(1)),
12118 mkU64(extended_checking));
12119 IRTemp retval2 = newTemp(Ity_I64);
florian3f8a96a2012-08-05 02:59:55 +000012120
12121 if (is_cu12) {
12122 assign(retval2, s390_call_cu12_helper2(mkexpr(byte1), byte2, byte3,
12123 byte4, stuff));
12124 } else {
12125 assign(retval2, s390_call_cu14_helper2(mkexpr(byte1), byte2, byte3,
12126 byte4, stuff));
12127 }
florian6d9b9b22012-08-03 18:35:39 +000012128
12129 /* Check for invalid character */
12130 s390_cc_set(2);
12131 is_invalid = unop(Iop_64to1, mkexpr(retval2));
12132 next_insn_if(is_invalid);
12133
12134 /* Now test whether the 1st operand is exhausted */
12135 IRTemp num_bytes = newTemp(Ity_I64);
12136 assign(num_bytes, binop(Iop_And64,
12137 binop(Iop_Shr64, mkexpr(retval2), mkU8(8)),
12138 mkU64(0xff)));
12139 s390_cc_set(1);
12140 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
12141
12142 /* Extract the bytes to be stored at addr1 */
12143 IRTemp data = newTemp(Ity_I64);
12144 assign(data, binop(Iop_Shr64, mkexpr(retval2), mkU8(16)));
12145
florian3f8a96a2012-08-05 02:59:55 +000012146 if (is_cu12) {
12147 /* To store the bytes construct 2 dirty helper calls. The helper calls
12148 are guarded (num_bytes == 2 and num_bytes == 4, respectively) such
12149 that only one of them will be called at runtime. */
florian6d9b9b22012-08-03 18:35:39 +000012150
florian3f8a96a2012-08-05 02:59:55 +000012151 Int i;
12152 for (i = 2; i <= 4; ++i) {
12153 IRDirty *d;
florian6d9b9b22012-08-03 18:35:39 +000012154
florian3f8a96a2012-08-05 02:59:55 +000012155 if (i == 3) continue; // skip this one
florian6d9b9b22012-08-03 18:35:39 +000012156
florian3f8a96a2012-08-05 02:59:55 +000012157 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
12158 &s390x_dirtyhelper_CUxy,
12159 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
12160 mkexpr(num_bytes)));
12161 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
12162 d->mFx = Ifx_Write;
12163 d->mAddr = mkexpr(addr1);
12164 d->mSize = i;
12165 stmt(IRStmt_Dirty(d));
12166 }
12167 } else {
12168 // cu14
12169 store(mkexpr(addr1), unop(Iop_64to32, mkexpr(data)));
florian6d9b9b22012-08-03 18:35:39 +000012170 }
12171
12172 /* Update source address and length */
12173 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkexpr(num_src_bytes)));
12174 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkexpr(num_src_bytes)));
12175
12176 /* Update destination address and length */
12177 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
12178 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
12179
12180 iterate();
florian3f8a96a2012-08-05 02:59:55 +000012181}
12182
12183static HChar *
12184s390_irgen_CU12(UChar m3, UChar r1, UChar r2)
12185{
12186 s390_irgen_cu12_cu14(m3, r1, r2, /* is_cu12 = */ 1);
florian6d9b9b22012-08-03 18:35:39 +000012187
12188 return "cu12";
12189}
12190
florian3f8a96a2012-08-05 02:59:55 +000012191static HChar *
12192s390_irgen_CU14(UChar m3, UChar r1, UChar r2)
12193{
12194 s390_irgen_cu12_cu14(m3, r1, r2, /* is_cu12 = */ 0);
12195
12196 return "cu14";
12197}
12198
florian8c88cb62012-08-26 18:58:13 +000012199static IRExpr *
12200s390_call_ecag(IRExpr *op2addr)
12201{
12202 IRExpr **args, *call;
12203
12204 args = mkIRExprVec_1(op2addr);
12205 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
12206 "s390_do_ecag", &s390_do_ecag, args);
12207
12208 /* Nothing is excluded from definedness checking. */
12209 call->Iex.CCall.cee->mcx_mask = 0;
12210
12211 return call;
12212}
12213
12214static HChar *
floriand2129202012-09-01 20:01:39 +000012215s390_irgen_ECAG(UChar r1, UChar r3 __attribute__((unused)), IRTemp op2addr)
florian8c88cb62012-08-26 18:58:13 +000012216{
12217 if (! s390_host_has_gie) {
floriane75dafa2012-09-01 17:54:09 +000012218 emulation_failure(EmFail_S390X_ecag);
florian8c88cb62012-08-26 18:58:13 +000012219 } else {
12220 put_gpr_dw0(r1, s390_call_ecag(mkexpr(op2addr)));
12221 }
12222
12223 return "ecag";
12224}
12225
12226
sewardj2019a972011-03-07 16:04:07 +000012227/*------------------------------------------------------------*/
12228/*--- Build IR for special instructions ---*/
12229/*------------------------------------------------------------*/
12230
florianb4df7682011-07-05 02:09:01 +000012231static void
sewardj2019a972011-03-07 16:04:07 +000012232s390_irgen_client_request(void)
12233{
12234 if (0)
12235 vex_printf("%%R3 = client_request ( %%R2 )\n");
12236
florianf9e1ed72012-04-17 02:41:56 +000012237 Addr64 next = guest_IA_curr_instr + S390_SPECIAL_OP_PREAMBLE_SIZE
12238 + S390_SPECIAL_OP_SIZE;
sewardj2019a972011-03-07 16:04:07 +000012239
florianf9e1ed72012-04-17 02:41:56 +000012240 dis_res->jk_StopHere = Ijk_ClientReq;
sewardj2019a972011-03-07 16:04:07 +000012241 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +000012242
12243 put_IA(mkaddr_expr(next));
sewardj2019a972011-03-07 16:04:07 +000012244}
12245
florianb4df7682011-07-05 02:09:01 +000012246static void
sewardj2019a972011-03-07 16:04:07 +000012247s390_irgen_guest_NRADDR(void)
12248{
12249 if (0)
12250 vex_printf("%%R3 = guest_NRADDR\n");
12251
floriane88b3c92011-07-05 02:48:39 +000012252 put_gpr_dw0(3, IRExpr_Get(S390X_GUEST_OFFSET(guest_NRADDR), Ity_I64));
sewardj2019a972011-03-07 16:04:07 +000012253}
12254
florianb4df7682011-07-05 02:09:01 +000012255static void
sewardj2019a972011-03-07 16:04:07 +000012256s390_irgen_call_noredir(void)
12257{
florianf9e1ed72012-04-17 02:41:56 +000012258 Addr64 next = guest_IA_curr_instr + S390_SPECIAL_OP_PREAMBLE_SIZE
12259 + S390_SPECIAL_OP_SIZE;
12260
sewardj2019a972011-03-07 16:04:07 +000012261 /* Continue after special op */
florianf9e1ed72012-04-17 02:41:56 +000012262 put_gpr_dw0(14, mkaddr_expr(next));
sewardj2019a972011-03-07 16:04:07 +000012263
12264 /* The address is in REG1, all parameters are in the right (guest) places */
florianf9e1ed72012-04-17 02:41:56 +000012265 put_IA(get_gpr_dw0(1));
sewardj2019a972011-03-07 16:04:07 +000012266
12267 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +000012268 dis_res->jk_StopHere = Ijk_NoRedir;
sewardj2019a972011-03-07 16:04:07 +000012269}
12270
12271/* Force proper alignment for the structures below. */
12272#pragma pack(1)
12273
12274
12275static s390_decode_t
12276s390_decode_2byte_and_irgen(UChar *bytes)
12277{
12278 typedef union {
12279 struct {
12280 unsigned int op : 16;
12281 } E;
12282 struct {
12283 unsigned int op : 8;
12284 unsigned int i : 8;
12285 } I;
12286 struct {
12287 unsigned int op : 8;
12288 unsigned int r1 : 4;
12289 unsigned int r2 : 4;
12290 } RR;
12291 } formats;
12292 union {
12293 formats fmt;
12294 UShort value;
12295 } ovl;
12296
12297 vassert(sizeof(formats) == 2);
12298
12299 ((char *)(&ovl.value))[0] = bytes[0];
12300 ((char *)(&ovl.value))[1] = bytes[1];
12301
12302 switch (ovl.value & 0xffff) {
12303 case 0x0101: /* PR */ goto unimplemented;
12304 case 0x0102: /* UPT */ goto unimplemented;
12305 case 0x0104: /* PTFF */ goto unimplemented;
12306 case 0x0107: /* SCKPF */ goto unimplemented;
12307 case 0x010a: /* PFPO */ goto unimplemented;
12308 case 0x010b: /* TAM */ goto unimplemented;
12309 case 0x010c: /* SAM24 */ goto unimplemented;
12310 case 0x010d: /* SAM31 */ goto unimplemented;
12311 case 0x010e: /* SAM64 */ goto unimplemented;
12312 case 0x01ff: /* TRAP2 */ goto unimplemented;
12313 }
12314
12315 switch ((ovl.value & 0xff00) >> 8) {
12316 case 0x04: /* SPM */ goto unimplemented;
12317 case 0x05: /* BALR */ goto unimplemented;
12318 case 0x06: s390_format_RR_RR(s390_irgen_BCTR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12319 goto ok;
12320 case 0x07: s390_format_RR(s390_irgen_BCR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12321 goto ok;
12322 case 0x0a: s390_format_I(s390_irgen_SVC, ovl.fmt.I.i); goto ok;
12323 case 0x0b: /* BSM */ goto unimplemented;
12324 case 0x0c: /* BASSM */ goto unimplemented;
12325 case 0x0d: s390_format_RR_RR(s390_irgen_BASR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12326 goto ok;
florianb0c9a132011-09-08 15:37:39 +000012327 case 0x0e: s390_format_RR(s390_irgen_MVCL, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12328 goto ok;
12329 case 0x0f: s390_format_RR(s390_irgen_CLCL, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12330 goto ok;
sewardj2019a972011-03-07 16:04:07 +000012331 case 0x10: s390_format_RR_RR(s390_irgen_LPR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12332 goto ok;
12333 case 0x11: s390_format_RR_RR(s390_irgen_LNR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12334 goto ok;
12335 case 0x12: s390_format_RR_RR(s390_irgen_LTR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12336 goto ok;
12337 case 0x13: s390_format_RR_RR(s390_irgen_LCR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12338 goto ok;
12339 case 0x14: s390_format_RR_RR(s390_irgen_NR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12340 goto ok;
12341 case 0x15: s390_format_RR_RR(s390_irgen_CLR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12342 goto ok;
12343 case 0x16: s390_format_RR_RR(s390_irgen_OR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12344 goto ok;
12345 case 0x17: s390_format_RR_RR(s390_irgen_XR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12346 goto ok;
12347 case 0x18: s390_format_RR_RR(s390_irgen_LR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12348 goto ok;
12349 case 0x19: s390_format_RR_RR(s390_irgen_CR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12350 goto ok;
12351 case 0x1a: s390_format_RR_RR(s390_irgen_AR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12352 goto ok;
12353 case 0x1b: s390_format_RR_RR(s390_irgen_SR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12354 goto ok;
12355 case 0x1c: s390_format_RR_RR(s390_irgen_MR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12356 goto ok;
12357 case 0x1d: s390_format_RR_RR(s390_irgen_DR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12358 goto ok;
12359 case 0x1e: s390_format_RR_RR(s390_irgen_ALR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12360 goto ok;
12361 case 0x1f: s390_format_RR_RR(s390_irgen_SLR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12362 goto ok;
12363 case 0x20: /* LPDR */ goto unimplemented;
12364 case 0x21: /* LNDR */ goto unimplemented;
12365 case 0x22: /* LTDR */ goto unimplemented;
12366 case 0x23: /* LCDR */ goto unimplemented;
12367 case 0x24: /* HDR */ goto unimplemented;
12368 case 0x25: /* LDXR */ goto unimplemented;
12369 case 0x26: /* MXR */ goto unimplemented;
12370 case 0x27: /* MXDR */ goto unimplemented;
12371 case 0x28: s390_format_RR_FF(s390_irgen_LDR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12372 goto ok;
12373 case 0x29: /* CDR */ goto unimplemented;
12374 case 0x2a: /* ADR */ goto unimplemented;
12375 case 0x2b: /* SDR */ goto unimplemented;
12376 case 0x2c: /* MDR */ goto unimplemented;
12377 case 0x2d: /* DDR */ goto unimplemented;
12378 case 0x2e: /* AWR */ goto unimplemented;
12379 case 0x2f: /* SWR */ goto unimplemented;
12380 case 0x30: /* LPER */ goto unimplemented;
12381 case 0x31: /* LNER */ goto unimplemented;
12382 case 0x32: /* LTER */ goto unimplemented;
12383 case 0x33: /* LCER */ goto unimplemented;
12384 case 0x34: /* HER */ goto unimplemented;
12385 case 0x35: /* LEDR */ goto unimplemented;
12386 case 0x36: /* AXR */ goto unimplemented;
12387 case 0x37: /* SXR */ goto unimplemented;
12388 case 0x38: s390_format_RR_FF(s390_irgen_LER, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12389 goto ok;
12390 case 0x39: /* CER */ goto unimplemented;
12391 case 0x3a: /* AER */ goto unimplemented;
12392 case 0x3b: /* SER */ goto unimplemented;
12393 case 0x3c: /* MDER */ goto unimplemented;
12394 case 0x3d: /* DER */ goto unimplemented;
12395 case 0x3e: /* AUR */ goto unimplemented;
12396 case 0x3f: /* SUR */ goto unimplemented;
12397 }
12398
12399 return S390_DECODE_UNKNOWN_INSN;
12400
12401ok:
12402 return S390_DECODE_OK;
12403
12404unimplemented:
12405 return S390_DECODE_UNIMPLEMENTED_INSN;
12406}
12407
12408static s390_decode_t
12409s390_decode_4byte_and_irgen(UChar *bytes)
12410{
12411 typedef union {
12412 struct {
12413 unsigned int op1 : 8;
12414 unsigned int r1 : 4;
12415 unsigned int op2 : 4;
12416 unsigned int i2 : 16;
12417 } RI;
12418 struct {
12419 unsigned int op : 16;
12420 unsigned int : 8;
12421 unsigned int r1 : 4;
12422 unsigned int r2 : 4;
12423 } RRE;
12424 struct {
12425 unsigned int op : 16;
12426 unsigned int r1 : 4;
12427 unsigned int : 4;
12428 unsigned int r3 : 4;
12429 unsigned int r2 : 4;
12430 } RRF;
12431 struct {
12432 unsigned int op : 16;
florian1c8f7ff2012-09-01 00:12:11 +000012433 unsigned int m3 : 4;
sewardj2019a972011-03-07 16:04:07 +000012434 unsigned int m4 : 4;
12435 unsigned int r1 : 4;
12436 unsigned int r2 : 4;
12437 } RRF2;
12438 struct {
12439 unsigned int op : 16;
12440 unsigned int r3 : 4;
12441 unsigned int : 4;
12442 unsigned int r1 : 4;
12443 unsigned int r2 : 4;
12444 } RRF3;
12445 struct {
12446 unsigned int op : 16;
12447 unsigned int r3 : 4;
12448 unsigned int : 4;
12449 unsigned int r1 : 4;
12450 unsigned int r2 : 4;
12451 } RRR;
12452 struct {
12453 unsigned int op : 16;
12454 unsigned int r3 : 4;
12455 unsigned int : 4;
12456 unsigned int r1 : 4;
12457 unsigned int r2 : 4;
12458 } RRF4;
12459 struct {
12460 unsigned int op : 8;
12461 unsigned int r1 : 4;
12462 unsigned int r3 : 4;
12463 unsigned int b2 : 4;
12464 unsigned int d2 : 12;
12465 } RS;
12466 struct {
12467 unsigned int op : 8;
12468 unsigned int r1 : 4;
12469 unsigned int r3 : 4;
12470 unsigned int i2 : 16;
12471 } RSI;
12472 struct {
12473 unsigned int op : 8;
12474 unsigned int r1 : 4;
12475 unsigned int x2 : 4;
12476 unsigned int b2 : 4;
12477 unsigned int d2 : 12;
12478 } RX;
12479 struct {
12480 unsigned int op : 16;
12481 unsigned int b2 : 4;
12482 unsigned int d2 : 12;
12483 } S;
12484 struct {
12485 unsigned int op : 8;
12486 unsigned int i2 : 8;
12487 unsigned int b1 : 4;
12488 unsigned int d1 : 12;
12489 } SI;
12490 } formats;
12491 union {
12492 formats fmt;
12493 UInt value;
12494 } ovl;
12495
12496 vassert(sizeof(formats) == 4);
12497
12498 ((char *)(&ovl.value))[0] = bytes[0];
12499 ((char *)(&ovl.value))[1] = bytes[1];
12500 ((char *)(&ovl.value))[2] = bytes[2];
12501 ((char *)(&ovl.value))[3] = bytes[3];
12502
12503 switch ((ovl.value & 0xff0f0000) >> 16) {
12504 case 0xa500: s390_format_RI_RU(s390_irgen_IIHH, ovl.fmt.RI.r1,
12505 ovl.fmt.RI.i2); goto ok;
12506 case 0xa501: s390_format_RI_RU(s390_irgen_IIHL, ovl.fmt.RI.r1,
12507 ovl.fmt.RI.i2); goto ok;
12508 case 0xa502: s390_format_RI_RU(s390_irgen_IILH, ovl.fmt.RI.r1,
12509 ovl.fmt.RI.i2); goto ok;
12510 case 0xa503: s390_format_RI_RU(s390_irgen_IILL, ovl.fmt.RI.r1,
12511 ovl.fmt.RI.i2); goto ok;
12512 case 0xa504: s390_format_RI_RU(s390_irgen_NIHH, ovl.fmt.RI.r1,
12513 ovl.fmt.RI.i2); goto ok;
12514 case 0xa505: s390_format_RI_RU(s390_irgen_NIHL, ovl.fmt.RI.r1,
12515 ovl.fmt.RI.i2); goto ok;
12516 case 0xa506: s390_format_RI_RU(s390_irgen_NILH, ovl.fmt.RI.r1,
12517 ovl.fmt.RI.i2); goto ok;
12518 case 0xa507: s390_format_RI_RU(s390_irgen_NILL, ovl.fmt.RI.r1,
12519 ovl.fmt.RI.i2); goto ok;
12520 case 0xa508: s390_format_RI_RU(s390_irgen_OIHH, ovl.fmt.RI.r1,
12521 ovl.fmt.RI.i2); goto ok;
12522 case 0xa509: s390_format_RI_RU(s390_irgen_OIHL, ovl.fmt.RI.r1,
12523 ovl.fmt.RI.i2); goto ok;
12524 case 0xa50a: s390_format_RI_RU(s390_irgen_OILH, ovl.fmt.RI.r1,
12525 ovl.fmt.RI.i2); goto ok;
12526 case 0xa50b: s390_format_RI_RU(s390_irgen_OILL, ovl.fmt.RI.r1,
12527 ovl.fmt.RI.i2); goto ok;
12528 case 0xa50c: s390_format_RI_RU(s390_irgen_LLIHH, ovl.fmt.RI.r1,
12529 ovl.fmt.RI.i2); goto ok;
12530 case 0xa50d: s390_format_RI_RU(s390_irgen_LLIHL, ovl.fmt.RI.r1,
12531 ovl.fmt.RI.i2); goto ok;
12532 case 0xa50e: s390_format_RI_RU(s390_irgen_LLILH, ovl.fmt.RI.r1,
12533 ovl.fmt.RI.i2); goto ok;
12534 case 0xa50f: s390_format_RI_RU(s390_irgen_LLILL, ovl.fmt.RI.r1,
12535 ovl.fmt.RI.i2); goto ok;
12536 case 0xa700: s390_format_RI_RU(s390_irgen_TMLH, ovl.fmt.RI.r1,
12537 ovl.fmt.RI.i2); goto ok;
12538 case 0xa701: s390_format_RI_RU(s390_irgen_TMLL, ovl.fmt.RI.r1,
12539 ovl.fmt.RI.i2); goto ok;
12540 case 0xa702: s390_format_RI_RU(s390_irgen_TMHH, ovl.fmt.RI.r1,
12541 ovl.fmt.RI.i2); goto ok;
12542 case 0xa703: s390_format_RI_RU(s390_irgen_TMHL, ovl.fmt.RI.r1,
12543 ovl.fmt.RI.i2); goto ok;
12544 case 0xa704: s390_format_RI(s390_irgen_BRC, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
12545 goto ok;
12546 case 0xa705: s390_format_RI_RP(s390_irgen_BRAS, ovl.fmt.RI.r1,
12547 ovl.fmt.RI.i2); goto ok;
12548 case 0xa706: s390_format_RI_RP(s390_irgen_BRCT, ovl.fmt.RI.r1,
12549 ovl.fmt.RI.i2); goto ok;
12550 case 0xa707: s390_format_RI_RP(s390_irgen_BRCTG, ovl.fmt.RI.r1,
12551 ovl.fmt.RI.i2); goto ok;
12552 case 0xa708: s390_format_RI_RI(s390_irgen_LHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
12553 goto ok;
12554 case 0xa709: s390_format_RI_RI(s390_irgen_LGHI, ovl.fmt.RI.r1,
12555 ovl.fmt.RI.i2); goto ok;
12556 case 0xa70a: s390_format_RI_RI(s390_irgen_AHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
12557 goto ok;
12558 case 0xa70b: s390_format_RI_RI(s390_irgen_AGHI, ovl.fmt.RI.r1,
12559 ovl.fmt.RI.i2); goto ok;
12560 case 0xa70c: s390_format_RI_RI(s390_irgen_MHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
12561 goto ok;
12562 case 0xa70d: s390_format_RI_RI(s390_irgen_MGHI, ovl.fmt.RI.r1,
12563 ovl.fmt.RI.i2); goto ok;
12564 case 0xa70e: s390_format_RI_RI(s390_irgen_CHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
12565 goto ok;
12566 case 0xa70f: s390_format_RI_RI(s390_irgen_CGHI, ovl.fmt.RI.r1,
12567 ovl.fmt.RI.i2); goto ok;
12568 }
12569
12570 switch ((ovl.value & 0xffff0000) >> 16) {
12571 case 0x8000: /* SSM */ goto unimplemented;
12572 case 0x8200: /* LPSW */ goto unimplemented;
florian7700fc92012-01-16 17:25:55 +000012573 case 0x9300: /* TS */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000012574 case 0xb202: /* STIDP */ goto unimplemented;
12575 case 0xb204: /* SCK */ goto unimplemented;
florian7700fc92012-01-16 17:25:55 +000012576 case 0xb205: s390_format_S_RD(s390_irgen_STCK, ovl.fmt.S.b2, ovl.fmt.S.d2);
12577 goto ok;
sewardj2019a972011-03-07 16:04:07 +000012578 case 0xb206: /* SCKC */ goto unimplemented;
12579 case 0xb207: /* STCKC */ goto unimplemented;
12580 case 0xb208: /* SPT */ goto unimplemented;
12581 case 0xb209: /* STPT */ goto unimplemented;
12582 case 0xb20a: /* SPKA */ goto unimplemented;
12583 case 0xb20b: /* IPK */ goto unimplemented;
12584 case 0xb20d: /* PTLB */ goto unimplemented;
12585 case 0xb210: /* SPX */ goto unimplemented;
12586 case 0xb211: /* STPX */ goto unimplemented;
12587 case 0xb212: /* STAP */ goto unimplemented;
12588 case 0xb214: /* SIE */ goto unimplemented;
12589 case 0xb218: /* PC */ goto unimplemented;
12590 case 0xb219: /* SAC */ goto unimplemented;
12591 case 0xb21a: /* CFC */ goto unimplemented;
12592 case 0xb221: /* IPTE */ goto unimplemented;
12593 case 0xb222: s390_format_RRE_R0(s390_irgen_IPM, ovl.fmt.RRE.r1); goto ok;
12594 case 0xb223: /* IVSK */ goto unimplemented;
12595 case 0xb224: /* IAC */ goto unimplemented;
12596 case 0xb225: /* SSAR */ goto unimplemented;
12597 case 0xb226: /* EPAR */ goto unimplemented;
12598 case 0xb227: /* ESAR */ goto unimplemented;
12599 case 0xb228: /* PT */ goto unimplemented;
12600 case 0xb229: /* ISKE */ goto unimplemented;
12601 case 0xb22a: /* RRBE */ goto unimplemented;
12602 case 0xb22b: /* SSKE */ goto unimplemented;
12603 case 0xb22c: /* TB */ goto unimplemented;
12604 case 0xb22d: /* DXR */ goto unimplemented;
12605 case 0xb22e: /* PGIN */ goto unimplemented;
12606 case 0xb22f: /* PGOUT */ goto unimplemented;
12607 case 0xb230: /* CSCH */ goto unimplemented;
12608 case 0xb231: /* HSCH */ goto unimplemented;
12609 case 0xb232: /* MSCH */ goto unimplemented;
12610 case 0xb233: /* SSCH */ goto unimplemented;
12611 case 0xb234: /* STSCH */ goto unimplemented;
12612 case 0xb235: /* TSCH */ goto unimplemented;
12613 case 0xb236: /* TPI */ goto unimplemented;
12614 case 0xb237: /* SAL */ goto unimplemented;
12615 case 0xb238: /* RSCH */ goto unimplemented;
12616 case 0xb239: /* STCRW */ goto unimplemented;
12617 case 0xb23a: /* STCPS */ goto unimplemented;
12618 case 0xb23b: /* RCHP */ goto unimplemented;
12619 case 0xb23c: /* SCHM */ goto unimplemented;
12620 case 0xb240: /* BAKR */ goto unimplemented;
floriana4384a32011-08-11 16:58:45 +000012621 case 0xb241: s390_format_RRE(s390_irgen_CKSM, ovl.fmt.RRE.r1,
12622 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000012623 case 0xb244: /* SQDR */ goto unimplemented;
12624 case 0xb245: /* SQER */ goto unimplemented;
12625 case 0xb246: /* STURA */ goto unimplemented;
12626 case 0xb247: /* MSTA */ goto unimplemented;
12627 case 0xb248: /* PALB */ goto unimplemented;
12628 case 0xb249: /* EREG */ goto unimplemented;
12629 case 0xb24a: /* ESTA */ goto unimplemented;
12630 case 0xb24b: /* LURA */ goto unimplemented;
12631 case 0xb24c: /* TAR */ goto unimplemented;
12632 case 0xb24d: s390_format_RRE(s390_irgen_CPYA, ovl.fmt.RRE.r1,
12633 ovl.fmt.RRE.r2); goto ok;
12634 case 0xb24e: s390_format_RRE(s390_irgen_SAR, ovl.fmt.RRE.r1, ovl.fmt.RRE.r2);
12635 goto ok;
12636 case 0xb24f: s390_format_RRE(s390_irgen_EAR, ovl.fmt.RRE.r1, ovl.fmt.RRE.r2);
12637 goto ok;
12638 case 0xb250: /* CSP */ goto unimplemented;
12639 case 0xb252: s390_format_RRE_RR(s390_irgen_MSR, ovl.fmt.RRE.r1,
12640 ovl.fmt.RRE.r2); goto ok;
12641 case 0xb254: /* MVPG */ goto unimplemented;
12642 case 0xb255: s390_format_RRE_RR(s390_irgen_MVST, ovl.fmt.RRE.r1,
12643 ovl.fmt.RRE.r2); goto ok;
12644 case 0xb257: /* CUSE */ goto unimplemented;
12645 case 0xb258: /* BSG */ goto unimplemented;
12646 case 0xb25a: /* BSA */ goto unimplemented;
12647 case 0xb25d: s390_format_RRE_RR(s390_irgen_CLST, ovl.fmt.RRE.r1,
12648 ovl.fmt.RRE.r2); goto ok;
12649 case 0xb25e: s390_format_RRE_RR(s390_irgen_SRST, ovl.fmt.RRE.r1,
12650 ovl.fmt.RRE.r2); goto ok;
12651 case 0xb263: /* CMPSC */ goto unimplemented;
12652 case 0xb274: /* SIGA */ goto unimplemented;
12653 case 0xb276: /* XSCH */ goto unimplemented;
12654 case 0xb277: /* RP */ goto unimplemented;
sewardj1e5fea62011-05-17 16:18:36 +000012655 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 +000012656 case 0xb279: /* SACF */ goto unimplemented;
sewardj1e5fea62011-05-17 16:18:36 +000012657 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 +000012658 case 0xb27d: /* STSI */ goto unimplemented;
12659 case 0xb299: s390_format_S_RD(s390_irgen_SRNM, ovl.fmt.S.b2, ovl.fmt.S.d2);
12660 goto ok;
12661 case 0xb29c: s390_format_S_RD(s390_irgen_STFPC, ovl.fmt.S.b2, ovl.fmt.S.d2);
12662 goto ok;
12663 case 0xb29d: s390_format_S_RD(s390_irgen_LFPC, ovl.fmt.S.b2, ovl.fmt.S.d2);
12664 goto ok;
florian730448f2012-02-04 17:07:07 +000012665 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 +000012666 case 0xb2a6: s390_format_RRF_M0RERE(s390_irgen_CU21, ovl.fmt.RRF3.r3,
12667 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
12668 goto ok;
florian6d9b9b22012-08-03 18:35:39 +000012669 case 0xb2a7: s390_format_RRF_M0RERE(s390_irgen_CU12, ovl.fmt.RRF3.r3,
12670 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
12671 goto ok;
florian933065d2011-07-11 01:48:02 +000012672 case 0xb2b0: s390_format_S_RD(s390_irgen_STFLE, ovl.fmt.S.b2, ovl.fmt.S.d2);
12673 goto ok;
sewardj2019a972011-03-07 16:04:07 +000012674 case 0xb2b1: /* STFL */ goto unimplemented;
12675 case 0xb2b2: /* LPSWE */ goto unimplemented;
florianf0fa1be2012-09-18 20:24:38 +000012676 case 0xb2b8: s390_irgen_srnmb_wrapper(ovl.fmt.S.b2, ovl.fmt.S.d2);
12677 goto ok;
sewardj2019a972011-03-07 16:04:07 +000012678 case 0xb2b9: /* SRNMT */ goto unimplemented;
12679 case 0xb2bd: /* LFAS */ goto unimplemented;
12680 case 0xb2ff: /* TRAP4 */ goto unimplemented;
12681 case 0xb300: s390_format_RRE_FF(s390_irgen_LPEBR, ovl.fmt.RRE.r1,
12682 ovl.fmt.RRE.r2); goto ok;
12683 case 0xb301: s390_format_RRE_FF(s390_irgen_LNEBR, ovl.fmt.RRE.r1,
12684 ovl.fmt.RRE.r2); goto ok;
12685 case 0xb302: s390_format_RRE_FF(s390_irgen_LTEBR, ovl.fmt.RRE.r1,
12686 ovl.fmt.RRE.r2); goto ok;
12687 case 0xb303: s390_format_RRE_FF(s390_irgen_LCEBR, ovl.fmt.RRE.r1,
12688 ovl.fmt.RRE.r2); goto ok;
12689 case 0xb304: s390_format_RRE_FF(s390_irgen_LDEBR, ovl.fmt.RRE.r1,
12690 ovl.fmt.RRE.r2); goto ok;
12691 case 0xb305: s390_format_RRE_FF(s390_irgen_LXDBR, ovl.fmt.RRE.r1,
12692 ovl.fmt.RRE.r2); goto ok;
12693 case 0xb306: s390_format_RRE_FF(s390_irgen_LXEBR, ovl.fmt.RRE.r1,
12694 ovl.fmt.RRE.r2); goto ok;
12695 case 0xb307: /* MXDBR */ goto unimplemented;
12696 case 0xb308: /* KEBR */ goto unimplemented;
12697 case 0xb309: s390_format_RRE_FF(s390_irgen_CEBR, ovl.fmt.RRE.r1,
12698 ovl.fmt.RRE.r2); goto ok;
12699 case 0xb30a: s390_format_RRE_FF(s390_irgen_AEBR, ovl.fmt.RRE.r1,
12700 ovl.fmt.RRE.r2); goto ok;
12701 case 0xb30b: s390_format_RRE_FF(s390_irgen_SEBR, ovl.fmt.RRE.r1,
12702 ovl.fmt.RRE.r2); goto ok;
12703 case 0xb30c: /* MDEBR */ goto unimplemented;
12704 case 0xb30d: s390_format_RRE_FF(s390_irgen_DEBR, ovl.fmt.RRE.r1,
12705 ovl.fmt.RRE.r2); goto ok;
12706 case 0xb30e: s390_format_RRF_F0FF(s390_irgen_MAEBR, ovl.fmt.RRF.r1,
12707 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
12708 case 0xb30f: s390_format_RRF_F0FF(s390_irgen_MSEBR, ovl.fmt.RRF.r1,
12709 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
12710 case 0xb310: s390_format_RRE_FF(s390_irgen_LPDBR, ovl.fmt.RRE.r1,
12711 ovl.fmt.RRE.r2); goto ok;
12712 case 0xb311: s390_format_RRE_FF(s390_irgen_LNDBR, ovl.fmt.RRE.r1,
12713 ovl.fmt.RRE.r2); goto ok;
12714 case 0xb312: s390_format_RRE_FF(s390_irgen_LTDBR, ovl.fmt.RRE.r1,
12715 ovl.fmt.RRE.r2); goto ok;
12716 case 0xb313: s390_format_RRE_FF(s390_irgen_LCDBR, ovl.fmt.RRE.r1,
12717 ovl.fmt.RRE.r2); goto ok;
12718 case 0xb314: s390_format_RRE_FF(s390_irgen_SQEBR, ovl.fmt.RRE.r1,
12719 ovl.fmt.RRE.r2); goto ok;
12720 case 0xb315: s390_format_RRE_FF(s390_irgen_SQDBR, ovl.fmt.RRE.r1,
12721 ovl.fmt.RRE.r2); goto ok;
12722 case 0xb316: s390_format_RRE_FF(s390_irgen_SQXBR, ovl.fmt.RRE.r1,
12723 ovl.fmt.RRE.r2); goto ok;
12724 case 0xb317: s390_format_RRE_FF(s390_irgen_MEEBR, ovl.fmt.RRE.r1,
12725 ovl.fmt.RRE.r2); goto ok;
12726 case 0xb318: /* KDBR */ goto unimplemented;
12727 case 0xb319: s390_format_RRE_FF(s390_irgen_CDBR, ovl.fmt.RRE.r1,
12728 ovl.fmt.RRE.r2); goto ok;
12729 case 0xb31a: s390_format_RRE_FF(s390_irgen_ADBR, ovl.fmt.RRE.r1,
12730 ovl.fmt.RRE.r2); goto ok;
12731 case 0xb31b: s390_format_RRE_FF(s390_irgen_SDBR, ovl.fmt.RRE.r1,
12732 ovl.fmt.RRE.r2); goto ok;
12733 case 0xb31c: s390_format_RRE_FF(s390_irgen_MDBR, ovl.fmt.RRE.r1,
12734 ovl.fmt.RRE.r2); goto ok;
12735 case 0xb31d: s390_format_RRE_FF(s390_irgen_DDBR, ovl.fmt.RRE.r1,
12736 ovl.fmt.RRE.r2); goto ok;
12737 case 0xb31e: s390_format_RRF_F0FF(s390_irgen_MADBR, ovl.fmt.RRF.r1,
12738 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
12739 case 0xb31f: s390_format_RRF_F0FF(s390_irgen_MSDBR, ovl.fmt.RRF.r1,
12740 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
12741 case 0xb324: /* LDER */ goto unimplemented;
12742 case 0xb325: /* LXDR */ goto unimplemented;
12743 case 0xb326: /* LXER */ goto unimplemented;
12744 case 0xb32e: /* MAER */ goto unimplemented;
12745 case 0xb32f: /* MSER */ goto unimplemented;
12746 case 0xb336: /* SQXR */ goto unimplemented;
12747 case 0xb337: /* MEER */ goto unimplemented;
12748 case 0xb338: /* MAYLR */ goto unimplemented;
12749 case 0xb339: /* MYLR */ goto unimplemented;
12750 case 0xb33a: /* MAYR */ goto unimplemented;
12751 case 0xb33b: /* MYR */ goto unimplemented;
12752 case 0xb33c: /* MAYHR */ goto unimplemented;
12753 case 0xb33d: /* MYHR */ goto unimplemented;
12754 case 0xb33e: /* MADR */ goto unimplemented;
12755 case 0xb33f: /* MSDR */ goto unimplemented;
12756 case 0xb340: s390_format_RRE_FF(s390_irgen_LPXBR, ovl.fmt.RRE.r1,
12757 ovl.fmt.RRE.r2); goto ok;
12758 case 0xb341: s390_format_RRE_FF(s390_irgen_LNXBR, ovl.fmt.RRE.r1,
12759 ovl.fmt.RRE.r2); goto ok;
12760 case 0xb342: s390_format_RRE_FF(s390_irgen_LTXBR, ovl.fmt.RRE.r1,
12761 ovl.fmt.RRE.r2); goto ok;
12762 case 0xb343: s390_format_RRE_FF(s390_irgen_LCXBR, ovl.fmt.RRE.r1,
12763 ovl.fmt.RRE.r2); goto ok;
florian4b8efad2012-09-02 18:07:08 +000012764 case 0xb344: s390_format_RRF_UUFF(s390_irgen_LEDBR, ovl.fmt.RRF2.m3,
12765 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12766 ovl.fmt.RRF2.r2); goto ok;
12767 case 0xb345: s390_format_RRF_UUFF(s390_irgen_LDXBR, ovl.fmt.RRF2.m3,
12768 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12769 ovl.fmt.RRF2.r2); goto ok;
12770 case 0xb346: s390_format_RRF_UUFF(s390_irgen_LEXBR, ovl.fmt.RRF2.m3,
12771 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12772 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000012773 case 0xb347: /* FIXBR */ goto unimplemented;
12774 case 0xb348: /* KXBR */ goto unimplemented;
12775 case 0xb349: s390_format_RRE_FF(s390_irgen_CXBR, ovl.fmt.RRE.r1,
12776 ovl.fmt.RRE.r2); goto ok;
12777 case 0xb34a: s390_format_RRE_FF(s390_irgen_AXBR, ovl.fmt.RRE.r1,
12778 ovl.fmt.RRE.r2); goto ok;
12779 case 0xb34b: s390_format_RRE_FF(s390_irgen_SXBR, ovl.fmt.RRE.r1,
12780 ovl.fmt.RRE.r2); goto ok;
12781 case 0xb34c: s390_format_RRE_FF(s390_irgen_MXBR, ovl.fmt.RRE.r1,
12782 ovl.fmt.RRE.r2); goto ok;
12783 case 0xb34d: s390_format_RRE_FF(s390_irgen_DXBR, ovl.fmt.RRE.r1,
12784 ovl.fmt.RRE.r2); goto ok;
12785 case 0xb350: /* TBEDR */ goto unimplemented;
12786 case 0xb351: /* TBDR */ goto unimplemented;
12787 case 0xb353: /* DIEBR */ goto unimplemented;
12788 case 0xb357: /* FIEBR */ goto unimplemented;
12789 case 0xb358: /* THDER */ goto unimplemented;
12790 case 0xb359: /* THDR */ goto unimplemented;
12791 case 0xb35b: /* DIDBR */ goto unimplemented;
12792 case 0xb35f: /* FIDBR */ goto unimplemented;
12793 case 0xb360: /* LPXR */ goto unimplemented;
12794 case 0xb361: /* LNXR */ goto unimplemented;
12795 case 0xb362: /* LTXR */ goto unimplemented;
12796 case 0xb363: /* LCXR */ goto unimplemented;
12797 case 0xb365: s390_format_RRE_FF(s390_irgen_LXR, ovl.fmt.RRE.r1,
12798 ovl.fmt.RRE.r2); goto ok;
12799 case 0xb366: /* LEXR */ goto unimplemented;
12800 case 0xb367: /* FIXR */ goto unimplemented;
12801 case 0xb369: /* CXR */ goto unimplemented;
12802 case 0xb370: s390_format_RRE_FF(s390_irgen_LPDFR, ovl.fmt.RRE.r1,
12803 ovl.fmt.RRE.r2); goto ok;
12804 case 0xb371: s390_format_RRE_FF(s390_irgen_LNDFR, ovl.fmt.RRE.r1,
12805 ovl.fmt.RRE.r2); goto ok;
12806 case 0xb372: s390_format_RRF_F0FF2(s390_irgen_CPSDR, ovl.fmt.RRF3.r3,
12807 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
12808 goto ok;
12809 case 0xb373: s390_format_RRE_FF(s390_irgen_LCDFR, ovl.fmt.RRE.r1,
12810 ovl.fmt.RRE.r2); goto ok;
12811 case 0xb374: s390_format_RRE_F0(s390_irgen_LZER, ovl.fmt.RRE.r1); goto ok;
12812 case 0xb375: s390_format_RRE_F0(s390_irgen_LZDR, ovl.fmt.RRE.r1); goto ok;
12813 case 0xb376: s390_format_RRE_F0(s390_irgen_LZXR, ovl.fmt.RRE.r1); goto ok;
12814 case 0xb377: /* FIER */ goto unimplemented;
12815 case 0xb37f: /* FIDR */ goto unimplemented;
12816 case 0xb384: s390_format_RRE_R0(s390_irgen_SFPC, ovl.fmt.RRE.r1); goto ok;
12817 case 0xb385: /* SFASR */ goto unimplemented;
12818 case 0xb38c: s390_format_RRE_R0(s390_irgen_EFPC, ovl.fmt.RRE.r1); goto ok;
florian1c8f7ff2012-09-01 00:12:11 +000012819 case 0xb390: s390_format_RRF_UUFR(s390_irgen_CELFBR, ovl.fmt.RRF2.m3,
12820 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12821 ovl.fmt.RRF2.r2); goto ok;
12822 case 0xb391: s390_format_RRF_UUFR(s390_irgen_CDLFBR, ovl.fmt.RRF2.m3,
12823 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12824 ovl.fmt.RRF2.r2); goto ok;
12825 case 0xb392: s390_format_RRF_UUFR(s390_irgen_CXLFBR, ovl.fmt.RRF2.m3,
12826 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12827 ovl.fmt.RRF2.r2); goto ok;
florian4b8efad2012-09-02 18:07:08 +000012828 case 0xb394: s390_format_RRF_UUFR(s390_irgen_CEFBR, ovl.fmt.RRF2.m3,
12829 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12830 ovl.fmt.RRF2.r2); goto ok;
12831 case 0xb395: s390_format_RRF_UUFR(s390_irgen_CDFBR, ovl.fmt.RRF2.m3,
12832 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12833 ovl.fmt.RRF2.r2); goto ok;
12834 case 0xb396: s390_format_RRF_UUFR(s390_irgen_CXFBR, ovl.fmt.RRF2.m3,
12835 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12836 ovl.fmt.RRF2.r2); goto ok;
12837 case 0xb398: s390_format_RRF_UURF(s390_irgen_CFEBR, ovl.fmt.RRF2.m3,
12838 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12839 ovl.fmt.RRF2.r2); goto ok;
12840 case 0xb399: s390_format_RRF_UURF(s390_irgen_CFDBR, ovl.fmt.RRF2.m3,
12841 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12842 ovl.fmt.RRF2.r2); goto ok;
12843 case 0xb39a: s390_format_RRF_UURF(s390_irgen_CFXBR, ovl.fmt.RRF2.m3,
12844 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12845 ovl.fmt.RRF2.r2); goto ok;
florian1c8f7ff2012-09-01 00:12:11 +000012846 case 0xb39c: s390_format_RRF_UURF(s390_irgen_CLFEBR, ovl.fmt.RRF2.m3,
12847 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12848 ovl.fmt.RRF2.r2); goto ok;
12849 case 0xb39d: s390_format_RRF_UURF(s390_irgen_CLFDBR, ovl.fmt.RRF2.m3,
12850 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12851 ovl.fmt.RRF2.r2); goto ok;
12852 case 0xb39e: s390_format_RRF_UURF(s390_irgen_CLFXBR, ovl.fmt.RRF2.m3,
12853 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12854 ovl.fmt.RRF2.r2); goto ok;
12855 case 0xb3a0: s390_format_RRF_UUFR(s390_irgen_CELGBR, ovl.fmt.RRF2.m3,
12856 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12857 ovl.fmt.RRF2.r2); goto ok;
12858 case 0xb3a1: s390_format_RRF_UUFR(s390_irgen_CDLGBR, ovl.fmt.RRF2.m3,
12859 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12860 ovl.fmt.RRF2.r2); goto ok;
12861 case 0xb3a2: s390_format_RRF_UUFR(s390_irgen_CXLGBR, ovl.fmt.RRF2.m3,
12862 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12863 ovl.fmt.RRF2.r2); goto ok;
florian4b8efad2012-09-02 18:07:08 +000012864 case 0xb3a4: s390_format_RRF_UUFR(s390_irgen_CEGBR, ovl.fmt.RRF2.m3,
12865 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12866 ovl.fmt.RRF2.r2); goto ok;
12867 case 0xb3a5: s390_format_RRF_UUFR(s390_irgen_CDGBR, ovl.fmt.RRF2.m3,
12868 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12869 ovl.fmt.RRF2.r2); goto ok;
12870 case 0xb3a6: s390_format_RRF_UUFR(s390_irgen_CXGBR, ovl.fmt.RRF2.m3,
12871 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12872 ovl.fmt.RRF2.r2); goto ok;
12873 case 0xb3a8: s390_format_RRF_UURF(s390_irgen_CGEBR, ovl.fmt.RRF2.m3,
12874 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12875 ovl.fmt.RRF2.r2); goto ok;
12876 case 0xb3a9: s390_format_RRF_UURF(s390_irgen_CGDBR, ovl.fmt.RRF2.m3,
12877 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12878 ovl.fmt.RRF2.r2); goto ok;
12879 case 0xb3aa: s390_format_RRF_UURF(s390_irgen_CGXBR, ovl.fmt.RRF2.m3,
12880 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12881 ovl.fmt.RRF2.r2); goto ok;
florian1c8f7ff2012-09-01 00:12:11 +000012882 case 0xb3ac: s390_format_RRF_UURF(s390_irgen_CLGEBR, ovl.fmt.RRF2.m3,
12883 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12884 ovl.fmt.RRF2.r2); goto ok;
12885 case 0xb3ad: s390_format_RRF_UURF(s390_irgen_CLGDBR, ovl.fmt.RRF2.m3,
12886 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12887 ovl.fmt.RRF2.r2); goto ok;
12888 case 0xb3ae: s390_format_RRF_UURF(s390_irgen_CLGXBR, ovl.fmt.RRF2.m3,
12889 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12890 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000012891 case 0xb3b4: /* CEFR */ goto unimplemented;
12892 case 0xb3b5: /* CDFR */ goto unimplemented;
12893 case 0xb3b6: /* CXFR */ goto unimplemented;
12894 case 0xb3b8: /* CFER */ goto unimplemented;
12895 case 0xb3b9: /* CFDR */ goto unimplemented;
12896 case 0xb3ba: /* CFXR */ goto unimplemented;
12897 case 0xb3c1: s390_format_RRE_FR(s390_irgen_LDGR, ovl.fmt.RRE.r1,
12898 ovl.fmt.RRE.r2); goto ok;
12899 case 0xb3c4: /* CEGR */ goto unimplemented;
12900 case 0xb3c5: /* CDGR */ goto unimplemented;
12901 case 0xb3c6: /* CXGR */ goto unimplemented;
12902 case 0xb3c8: /* CGER */ goto unimplemented;
12903 case 0xb3c9: /* CGDR */ goto unimplemented;
12904 case 0xb3ca: /* CGXR */ goto unimplemented;
12905 case 0xb3cd: s390_format_RRE_RF(s390_irgen_LGDR, ovl.fmt.RRE.r1,
12906 ovl.fmt.RRE.r2); goto ok;
12907 case 0xb3d0: /* MDTR */ goto unimplemented;
12908 case 0xb3d1: /* DDTR */ goto unimplemented;
12909 case 0xb3d2: /* ADTR */ goto unimplemented;
12910 case 0xb3d3: /* SDTR */ goto unimplemented;
12911 case 0xb3d4: /* LDETR */ goto unimplemented;
12912 case 0xb3d5: /* LEDTR */ goto unimplemented;
12913 case 0xb3d6: /* LTDTR */ goto unimplemented;
12914 case 0xb3d7: /* FIDTR */ goto unimplemented;
12915 case 0xb3d8: /* MXTR */ goto unimplemented;
12916 case 0xb3d9: /* DXTR */ goto unimplemented;
12917 case 0xb3da: /* AXTR */ goto unimplemented;
12918 case 0xb3db: /* SXTR */ goto unimplemented;
12919 case 0xb3dc: /* LXDTR */ goto unimplemented;
12920 case 0xb3dd: /* LDXTR */ goto unimplemented;
12921 case 0xb3de: /* LTXTR */ goto unimplemented;
12922 case 0xb3df: /* FIXTR */ goto unimplemented;
12923 case 0xb3e0: /* KDTR */ goto unimplemented;
12924 case 0xb3e1: /* CGDTR */ goto unimplemented;
12925 case 0xb3e2: /* CUDTR */ goto unimplemented;
12926 case 0xb3e3: /* CSDTR */ goto unimplemented;
12927 case 0xb3e4: /* CDTR */ goto unimplemented;
12928 case 0xb3e5: /* EEDTR */ goto unimplemented;
12929 case 0xb3e7: /* ESDTR */ goto unimplemented;
12930 case 0xb3e8: /* KXTR */ goto unimplemented;
12931 case 0xb3e9: /* CGXTR */ goto unimplemented;
12932 case 0xb3ea: /* CUXTR */ goto unimplemented;
12933 case 0xb3eb: /* CSXTR */ goto unimplemented;
12934 case 0xb3ec: /* CXTR */ goto unimplemented;
12935 case 0xb3ed: /* EEXTR */ goto unimplemented;
12936 case 0xb3ef: /* ESXTR */ goto unimplemented;
12937 case 0xb3f1: /* CDGTR */ goto unimplemented;
12938 case 0xb3f2: /* CDUTR */ goto unimplemented;
12939 case 0xb3f3: /* CDSTR */ goto unimplemented;
12940 case 0xb3f4: /* CEDTR */ goto unimplemented;
12941 case 0xb3f5: /* QADTR */ goto unimplemented;
12942 case 0xb3f6: /* IEDTR */ goto unimplemented;
12943 case 0xb3f7: /* RRDTR */ goto unimplemented;
12944 case 0xb3f9: /* CXGTR */ goto unimplemented;
12945 case 0xb3fa: /* CXUTR */ goto unimplemented;
12946 case 0xb3fb: /* CXSTR */ goto unimplemented;
12947 case 0xb3fc: /* CEXTR */ goto unimplemented;
12948 case 0xb3fd: /* QAXTR */ goto unimplemented;
12949 case 0xb3fe: /* IEXTR */ goto unimplemented;
12950 case 0xb3ff: /* RRXTR */ goto unimplemented;
12951 case 0xb900: s390_format_RRE_RR(s390_irgen_LPGR, ovl.fmt.RRE.r1,
12952 ovl.fmt.RRE.r2); goto ok;
12953 case 0xb901: s390_format_RRE_RR(s390_irgen_LNGR, ovl.fmt.RRE.r1,
12954 ovl.fmt.RRE.r2); goto ok;
12955 case 0xb902: s390_format_RRE_RR(s390_irgen_LTGR, ovl.fmt.RRE.r1,
12956 ovl.fmt.RRE.r2); goto ok;
12957 case 0xb903: s390_format_RRE_RR(s390_irgen_LCGR, ovl.fmt.RRE.r1,
12958 ovl.fmt.RRE.r2); goto ok;
12959 case 0xb904: s390_format_RRE_RR(s390_irgen_LGR, ovl.fmt.RRE.r1,
12960 ovl.fmt.RRE.r2); goto ok;
12961 case 0xb905: /* LURAG */ goto unimplemented;
12962 case 0xb906: s390_format_RRE_RR(s390_irgen_LGBR, ovl.fmt.RRE.r1,
12963 ovl.fmt.RRE.r2); goto ok;
12964 case 0xb907: s390_format_RRE_RR(s390_irgen_LGHR, ovl.fmt.RRE.r1,
12965 ovl.fmt.RRE.r2); goto ok;
12966 case 0xb908: s390_format_RRE_RR(s390_irgen_AGR, ovl.fmt.RRE.r1,
12967 ovl.fmt.RRE.r2); goto ok;
12968 case 0xb909: s390_format_RRE_RR(s390_irgen_SGR, ovl.fmt.RRE.r1,
12969 ovl.fmt.RRE.r2); goto ok;
12970 case 0xb90a: s390_format_RRE_RR(s390_irgen_ALGR, ovl.fmt.RRE.r1,
12971 ovl.fmt.RRE.r2); goto ok;
12972 case 0xb90b: s390_format_RRE_RR(s390_irgen_SLGR, ovl.fmt.RRE.r1,
12973 ovl.fmt.RRE.r2); goto ok;
12974 case 0xb90c: s390_format_RRE_RR(s390_irgen_MSGR, ovl.fmt.RRE.r1,
12975 ovl.fmt.RRE.r2); goto ok;
12976 case 0xb90d: s390_format_RRE_RR(s390_irgen_DSGR, ovl.fmt.RRE.r1,
12977 ovl.fmt.RRE.r2); goto ok;
12978 case 0xb90e: /* EREGG */ goto unimplemented;
12979 case 0xb90f: s390_format_RRE_RR(s390_irgen_LRVGR, ovl.fmt.RRE.r1,
12980 ovl.fmt.RRE.r2); goto ok;
12981 case 0xb910: s390_format_RRE_RR(s390_irgen_LPGFR, ovl.fmt.RRE.r1,
12982 ovl.fmt.RRE.r2); goto ok;
12983 case 0xb911: s390_format_RRE_RR(s390_irgen_LNGFR, ovl.fmt.RRE.r1,
12984 ovl.fmt.RRE.r2); goto ok;
12985 case 0xb912: s390_format_RRE_RR(s390_irgen_LTGFR, ovl.fmt.RRE.r1,
12986 ovl.fmt.RRE.r2); goto ok;
12987 case 0xb913: s390_format_RRE_RR(s390_irgen_LCGFR, ovl.fmt.RRE.r1,
12988 ovl.fmt.RRE.r2); goto ok;
12989 case 0xb914: s390_format_RRE_RR(s390_irgen_LGFR, ovl.fmt.RRE.r1,
12990 ovl.fmt.RRE.r2); goto ok;
12991 case 0xb916: s390_format_RRE_RR(s390_irgen_LLGFR, ovl.fmt.RRE.r1,
12992 ovl.fmt.RRE.r2); goto ok;
12993 case 0xb917: s390_format_RRE_RR(s390_irgen_LLGTR, ovl.fmt.RRE.r1,
12994 ovl.fmt.RRE.r2); goto ok;
12995 case 0xb918: s390_format_RRE_RR(s390_irgen_AGFR, ovl.fmt.RRE.r1,
12996 ovl.fmt.RRE.r2); goto ok;
12997 case 0xb919: s390_format_RRE_RR(s390_irgen_SGFR, ovl.fmt.RRE.r1,
12998 ovl.fmt.RRE.r2); goto ok;
12999 case 0xb91a: s390_format_RRE_RR(s390_irgen_ALGFR, ovl.fmt.RRE.r1,
13000 ovl.fmt.RRE.r2); goto ok;
13001 case 0xb91b: s390_format_RRE_RR(s390_irgen_SLGFR, ovl.fmt.RRE.r1,
13002 ovl.fmt.RRE.r2); goto ok;
13003 case 0xb91c: s390_format_RRE_RR(s390_irgen_MSGFR, ovl.fmt.RRE.r1,
13004 ovl.fmt.RRE.r2); goto ok;
13005 case 0xb91d: s390_format_RRE_RR(s390_irgen_DSGFR, ovl.fmt.RRE.r1,
13006 ovl.fmt.RRE.r2); goto ok;
13007 case 0xb91e: /* KMAC */ goto unimplemented;
13008 case 0xb91f: s390_format_RRE_RR(s390_irgen_LRVR, ovl.fmt.RRE.r1,
13009 ovl.fmt.RRE.r2); goto ok;
13010 case 0xb920: s390_format_RRE_RR(s390_irgen_CGR, ovl.fmt.RRE.r1,
13011 ovl.fmt.RRE.r2); goto ok;
13012 case 0xb921: s390_format_RRE_RR(s390_irgen_CLGR, ovl.fmt.RRE.r1,
13013 ovl.fmt.RRE.r2); goto ok;
13014 case 0xb925: /* STURG */ goto unimplemented;
13015 case 0xb926: s390_format_RRE_RR(s390_irgen_LBR, ovl.fmt.RRE.r1,
13016 ovl.fmt.RRE.r2); goto ok;
13017 case 0xb927: s390_format_RRE_RR(s390_irgen_LHR, ovl.fmt.RRE.r1,
13018 ovl.fmt.RRE.r2); goto ok;
13019 case 0xb928: /* PCKMO */ goto unimplemented;
13020 case 0xb92b: /* KMO */ goto unimplemented;
13021 case 0xb92c: /* PCC */ goto unimplemented;
13022 case 0xb92d: /* KMCTR */ goto unimplemented;
13023 case 0xb92e: /* KM */ goto unimplemented;
13024 case 0xb92f: /* KMC */ goto unimplemented;
13025 case 0xb930: s390_format_RRE_RR(s390_irgen_CGFR, ovl.fmt.RRE.r1,
13026 ovl.fmt.RRE.r2); goto ok;
13027 case 0xb931: s390_format_RRE_RR(s390_irgen_CLGFR, ovl.fmt.RRE.r1,
13028 ovl.fmt.RRE.r2); goto ok;
13029 case 0xb93e: /* KIMD */ goto unimplemented;
13030 case 0xb93f: /* KLMD */ goto unimplemented;
13031 case 0xb941: /* CFDTR */ goto unimplemented;
13032 case 0xb942: /* CLGDTR */ goto unimplemented;
13033 case 0xb943: /* CLFDTR */ goto unimplemented;
13034 case 0xb946: s390_format_RRE_RR(s390_irgen_BCTGR, ovl.fmt.RRE.r1,
13035 ovl.fmt.RRE.r2); goto ok;
13036 case 0xb949: /* CFXTR */ goto unimplemented;
13037 case 0xb94a: /* CLGXTR */ goto unimplemented;
13038 case 0xb94b: /* CLFXTR */ goto unimplemented;
13039 case 0xb951: /* CDFTR */ goto unimplemented;
13040 case 0xb952: /* CDLGTR */ goto unimplemented;
13041 case 0xb953: /* CDLFTR */ goto unimplemented;
13042 case 0xb959: /* CXFTR */ goto unimplemented;
13043 case 0xb95a: /* CXLGTR */ goto unimplemented;
13044 case 0xb95b: /* CXLFTR */ goto unimplemented;
13045 case 0xb960: /* CGRT */ goto unimplemented;
13046 case 0xb961: /* CLGRT */ goto unimplemented;
13047 case 0xb972: /* CRT */ goto unimplemented;
13048 case 0xb973: /* CLRT */ goto unimplemented;
13049 case 0xb980: s390_format_RRE_RR(s390_irgen_NGR, ovl.fmt.RRE.r1,
13050 ovl.fmt.RRE.r2); goto ok;
13051 case 0xb981: s390_format_RRE_RR(s390_irgen_OGR, ovl.fmt.RRE.r1,
13052 ovl.fmt.RRE.r2); goto ok;
13053 case 0xb982: s390_format_RRE_RR(s390_irgen_XGR, ovl.fmt.RRE.r1,
13054 ovl.fmt.RRE.r2); goto ok;
13055 case 0xb983: s390_format_RRE_RR(s390_irgen_FLOGR, ovl.fmt.RRE.r1,
13056 ovl.fmt.RRE.r2); goto ok;
13057 case 0xb984: s390_format_RRE_RR(s390_irgen_LLGCR, ovl.fmt.RRE.r1,
13058 ovl.fmt.RRE.r2); goto ok;
13059 case 0xb985: s390_format_RRE_RR(s390_irgen_LLGHR, ovl.fmt.RRE.r1,
13060 ovl.fmt.RRE.r2); goto ok;
13061 case 0xb986: s390_format_RRE_RR(s390_irgen_MLGR, ovl.fmt.RRE.r1,
13062 ovl.fmt.RRE.r2); goto ok;
13063 case 0xb987: s390_format_RRE_RR(s390_irgen_DLGR, ovl.fmt.RRE.r1,
13064 ovl.fmt.RRE.r2); goto ok;
13065 case 0xb988: s390_format_RRE_RR(s390_irgen_ALCGR, ovl.fmt.RRE.r1,
13066 ovl.fmt.RRE.r2); goto ok;
13067 case 0xb989: s390_format_RRE_RR(s390_irgen_SLBGR, ovl.fmt.RRE.r1,
13068 ovl.fmt.RRE.r2); goto ok;
13069 case 0xb98a: /* CSPG */ goto unimplemented;
13070 case 0xb98d: /* EPSW */ goto unimplemented;
13071 case 0xb98e: /* IDTE */ goto unimplemented;
florian730448f2012-02-04 17:07:07 +000013072 case 0xb990: s390_format_RRF_M0RERE(s390_irgen_TRTT, ovl.fmt.RRF3.r3,
13073 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
13074 case 0xb991: s390_format_RRF_M0RERE(s390_irgen_TRTO, ovl.fmt.RRF3.r3,
13075 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
13076 case 0xb992: s390_format_RRF_M0RERE(s390_irgen_TROT, ovl.fmt.RRF3.r3,
13077 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
florian9af37692012-01-15 21:01:16 +000013078 case 0xb993: s390_format_RRF_M0RERE(s390_irgen_TROO, ovl.fmt.RRF3.r3,
13079 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013080 case 0xb994: s390_format_RRE_RR(s390_irgen_LLCR, ovl.fmt.RRE.r1,
13081 ovl.fmt.RRE.r2); goto ok;
13082 case 0xb995: s390_format_RRE_RR(s390_irgen_LLHR, ovl.fmt.RRE.r1,
13083 ovl.fmt.RRE.r2); goto ok;
13084 case 0xb996: s390_format_RRE_RR(s390_irgen_MLR, ovl.fmt.RRE.r1,
13085 ovl.fmt.RRE.r2); goto ok;
13086 case 0xb997: s390_format_RRE_RR(s390_irgen_DLR, ovl.fmt.RRE.r1,
13087 ovl.fmt.RRE.r2); goto ok;
13088 case 0xb998: s390_format_RRE_RR(s390_irgen_ALCR, ovl.fmt.RRE.r1,
13089 ovl.fmt.RRE.r2); goto ok;
13090 case 0xb999: s390_format_RRE_RR(s390_irgen_SLBR, ovl.fmt.RRE.r1,
13091 ovl.fmt.RRE.r2); goto ok;
13092 case 0xb99a: /* EPAIR */ goto unimplemented;
13093 case 0xb99b: /* ESAIR */ goto unimplemented;
13094 case 0xb99d: /* ESEA */ goto unimplemented;
13095 case 0xb99e: /* PTI */ goto unimplemented;
13096 case 0xb99f: /* SSAIR */ goto unimplemented;
13097 case 0xb9a2: /* PTF */ goto unimplemented;
13098 case 0xb9aa: /* LPTEA */ goto unimplemented;
13099 case 0xb9ae: /* RRBM */ goto unimplemented;
13100 case 0xb9af: /* PFMF */ goto unimplemented;
florian3f8a96a2012-08-05 02:59:55 +000013101 case 0xb9b0: s390_format_RRF_M0RERE(s390_irgen_CU14, ovl.fmt.RRF3.r3,
13102 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
13103 goto ok;
florian2a415a12012-07-21 17:41:36 +000013104 case 0xb9b1: s390_format_RRF_M0RERE(s390_irgen_CU24, ovl.fmt.RRF3.r3,
13105 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
13106 goto ok;
florianaf2194f2012-08-06 00:07:54 +000013107 case 0xb9b2: s390_format_RRE_RR(s390_irgen_CU41, ovl.fmt.RRE.r1,
13108 ovl.fmt.RRE.r2); goto ok;
florian956194b2012-07-28 22:18:32 +000013109 case 0xb9b3: s390_format_RRE_RR(s390_irgen_CU42, ovl.fmt.RRE.r1,
13110 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013111 case 0xb9bd: /* TRTRE */ goto unimplemented;
13112 case 0xb9be: /* SRSTU */ goto unimplemented;
13113 case 0xb9bf: /* TRTE */ goto unimplemented;
13114 case 0xb9c8: s390_format_RRF_R0RR2(s390_irgen_AHHHR, ovl.fmt.RRF4.r3,
13115 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13116 goto ok;
13117 case 0xb9c9: s390_format_RRF_R0RR2(s390_irgen_SHHHR, ovl.fmt.RRF4.r3,
13118 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13119 goto ok;
13120 case 0xb9ca: s390_format_RRF_R0RR2(s390_irgen_ALHHHR, ovl.fmt.RRF4.r3,
13121 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13122 goto ok;
13123 case 0xb9cb: s390_format_RRF_R0RR2(s390_irgen_SLHHHR, ovl.fmt.RRF4.r3,
13124 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13125 goto ok;
13126 case 0xb9cd: s390_format_RRE_RR(s390_irgen_CHHR, ovl.fmt.RRE.r1,
13127 ovl.fmt.RRE.r2); goto ok;
13128 case 0xb9cf: s390_format_RRE_RR(s390_irgen_CLHHR, ovl.fmt.RRE.r1,
13129 ovl.fmt.RRE.r2); goto ok;
13130 case 0xb9d8: s390_format_RRF_R0RR2(s390_irgen_AHHLR, ovl.fmt.RRF4.r3,
13131 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13132 goto ok;
13133 case 0xb9d9: s390_format_RRF_R0RR2(s390_irgen_SHHLR, ovl.fmt.RRF4.r3,
13134 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13135 goto ok;
13136 case 0xb9da: s390_format_RRF_R0RR2(s390_irgen_ALHHLR, ovl.fmt.RRF4.r3,
13137 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13138 goto ok;
13139 case 0xb9db: s390_format_RRF_R0RR2(s390_irgen_SLHHLR, ovl.fmt.RRF4.r3,
13140 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13141 goto ok;
13142 case 0xb9dd: s390_format_RRE_RR(s390_irgen_CHLR, ovl.fmt.RRE.r1,
13143 ovl.fmt.RRE.r2); goto ok;
13144 case 0xb9df: s390_format_RRE_RR(s390_irgen_CLHLR, ovl.fmt.RRE.r1,
13145 ovl.fmt.RRE.r2); goto ok;
13146 case 0xb9e1: /* POPCNT */ goto unimplemented;
sewardjd7bde722011-04-05 13:19:33 +000013147 case 0xb9e2: s390_format_RRF_U0RR(s390_irgen_LOCGR, ovl.fmt.RRF3.r3,
13148 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2,
13149 S390_XMNM_LOCGR); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013150 case 0xb9e4: s390_format_RRF_R0RR2(s390_irgen_NGRK, ovl.fmt.RRF4.r3,
13151 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13152 goto ok;
13153 case 0xb9e6: s390_format_RRF_R0RR2(s390_irgen_OGRK, ovl.fmt.RRF4.r3,
13154 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13155 goto ok;
13156 case 0xb9e7: s390_format_RRF_R0RR2(s390_irgen_XGRK, ovl.fmt.RRF4.r3,
13157 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13158 goto ok;
13159 case 0xb9e8: s390_format_RRF_R0RR2(s390_irgen_AGRK, ovl.fmt.RRF4.r3,
13160 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13161 goto ok;
13162 case 0xb9e9: s390_format_RRF_R0RR2(s390_irgen_SGRK, ovl.fmt.RRF4.r3,
13163 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13164 goto ok;
13165 case 0xb9ea: s390_format_RRF_R0RR2(s390_irgen_ALGRK, ovl.fmt.RRF4.r3,
13166 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13167 goto ok;
13168 case 0xb9eb: s390_format_RRF_R0RR2(s390_irgen_SLGRK, ovl.fmt.RRF4.r3,
13169 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13170 goto ok;
sewardjd7bde722011-04-05 13:19:33 +000013171 case 0xb9f2: s390_format_RRF_U0RR(s390_irgen_LOCR, ovl.fmt.RRF3.r3,
13172 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2,
13173 S390_XMNM_LOCR); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013174 case 0xb9f4: s390_format_RRF_R0RR2(s390_irgen_NRK, ovl.fmt.RRF4.r3,
13175 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13176 goto ok;
13177 case 0xb9f6: s390_format_RRF_R0RR2(s390_irgen_ORK, ovl.fmt.RRF4.r3,
13178 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13179 goto ok;
13180 case 0xb9f7: s390_format_RRF_R0RR2(s390_irgen_XRK, ovl.fmt.RRF4.r3,
13181 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13182 goto ok;
13183 case 0xb9f8: s390_format_RRF_R0RR2(s390_irgen_ARK, ovl.fmt.RRF4.r3,
13184 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13185 goto ok;
13186 case 0xb9f9: s390_format_RRF_R0RR2(s390_irgen_SRK, ovl.fmt.RRF4.r3,
13187 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13188 goto ok;
13189 case 0xb9fa: s390_format_RRF_R0RR2(s390_irgen_ALRK, ovl.fmt.RRF4.r3,
13190 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13191 goto ok;
13192 case 0xb9fb: s390_format_RRF_R0RR2(s390_irgen_SLRK, ovl.fmt.RRF4.r3,
13193 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13194 goto ok;
13195 }
13196
13197 switch ((ovl.value & 0xff000000) >> 24) {
13198 case 0x40: s390_format_RX_RRRD(s390_irgen_STH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13199 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13200 case 0x41: s390_format_RX_RRRD(s390_irgen_LA, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13201 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13202 case 0x42: s390_format_RX_RRRD(s390_irgen_STC, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13203 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13204 case 0x43: s390_format_RX_RRRD(s390_irgen_IC, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13205 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13206 case 0x44: s390_format_RX_RRRD(s390_irgen_EX, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13207 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13208 case 0x45: /* BAL */ goto unimplemented;
13209 case 0x46: s390_format_RX_RRRD(s390_irgen_BCT, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13210 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13211 case 0x47: s390_format_RX(s390_irgen_BC, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13212 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13213 case 0x48: s390_format_RX_RRRD(s390_irgen_LH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13214 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13215 case 0x49: s390_format_RX_RRRD(s390_irgen_CH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13216 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13217 case 0x4a: s390_format_RX_RRRD(s390_irgen_AH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13218 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13219 case 0x4b: s390_format_RX_RRRD(s390_irgen_SH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13220 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13221 case 0x4c: s390_format_RX_RRRD(s390_irgen_MH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13222 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13223 case 0x4d: s390_format_RX_RRRD(s390_irgen_BAS, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13224 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13225 case 0x4e: s390_format_RX_RRRD(s390_irgen_CVD, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13226 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13227 case 0x4f: s390_format_RX_RRRD(s390_irgen_CVB, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13228 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13229 case 0x50: s390_format_RX_RRRD(s390_irgen_ST, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13230 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13231 case 0x51: s390_format_RX_RRRD(s390_irgen_LAE, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13232 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13233 case 0x54: s390_format_RX_RRRD(s390_irgen_N, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13234 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13235 case 0x55: s390_format_RX_RRRD(s390_irgen_CL, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13236 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13237 case 0x56: s390_format_RX_RRRD(s390_irgen_O, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13238 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13239 case 0x57: s390_format_RX_RRRD(s390_irgen_X, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13240 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13241 case 0x58: s390_format_RX_RRRD(s390_irgen_L, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13242 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13243 case 0x59: s390_format_RX_RRRD(s390_irgen_C, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13244 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13245 case 0x5a: s390_format_RX_RRRD(s390_irgen_A, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13246 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13247 case 0x5b: s390_format_RX_RRRD(s390_irgen_S, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13248 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13249 case 0x5c: s390_format_RX_RRRD(s390_irgen_M, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13250 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13251 case 0x5d: s390_format_RX_RRRD(s390_irgen_D, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13252 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13253 case 0x5e: s390_format_RX_RRRD(s390_irgen_AL, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13254 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13255 case 0x5f: s390_format_RX_RRRD(s390_irgen_SL, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13256 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13257 case 0x60: s390_format_RX_FRRD(s390_irgen_STD, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13258 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13259 case 0x67: /* MXD */ goto unimplemented;
13260 case 0x68: s390_format_RX_FRRD(s390_irgen_LD, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13261 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13262 case 0x69: /* CD */ goto unimplemented;
13263 case 0x6a: /* AD */ goto unimplemented;
13264 case 0x6b: /* SD */ goto unimplemented;
13265 case 0x6c: /* MD */ goto unimplemented;
13266 case 0x6d: /* DD */ goto unimplemented;
13267 case 0x6e: /* AW */ goto unimplemented;
13268 case 0x6f: /* SW */ goto unimplemented;
13269 case 0x70: s390_format_RX_FRRD(s390_irgen_STE, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13270 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13271 case 0x71: s390_format_RX_RRRD(s390_irgen_MS, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13272 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13273 case 0x78: s390_format_RX_FRRD(s390_irgen_LE, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13274 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13275 case 0x79: /* CE */ goto unimplemented;
13276 case 0x7a: /* AE */ goto unimplemented;
13277 case 0x7b: /* SE */ goto unimplemented;
13278 case 0x7c: /* MDE */ goto unimplemented;
13279 case 0x7d: /* DE */ goto unimplemented;
13280 case 0x7e: /* AU */ goto unimplemented;
13281 case 0x7f: /* SU */ goto unimplemented;
13282 case 0x83: /* DIAG */ goto unimplemented;
13283 case 0x84: s390_format_RSI_RRP(s390_irgen_BRXH, ovl.fmt.RSI.r1,
13284 ovl.fmt.RSI.r3, ovl.fmt.RSI.i2); goto ok;
13285 case 0x85: s390_format_RSI_RRP(s390_irgen_BRXLE, ovl.fmt.RSI.r1,
13286 ovl.fmt.RSI.r3, ovl.fmt.RSI.i2); goto ok;
13287 case 0x86: s390_format_RS_RRRD(s390_irgen_BXH, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13288 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13289 case 0x87: s390_format_RS_RRRD(s390_irgen_BXLE, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13290 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13291 case 0x88: s390_format_RS_R0RD(s390_irgen_SRL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
13292 ovl.fmt.RS.d2); goto ok;
13293 case 0x89: s390_format_RS_R0RD(s390_irgen_SLL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
13294 ovl.fmt.RS.d2); goto ok;
13295 case 0x8a: s390_format_RS_R0RD(s390_irgen_SRA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
13296 ovl.fmt.RS.d2); goto ok;
13297 case 0x8b: s390_format_RS_R0RD(s390_irgen_SLA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
13298 ovl.fmt.RS.d2); goto ok;
13299 case 0x8c: s390_format_RS_R0RD(s390_irgen_SRDL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
13300 ovl.fmt.RS.d2); goto ok;
13301 case 0x8d: s390_format_RS_R0RD(s390_irgen_SLDL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
13302 ovl.fmt.RS.d2); goto ok;
13303 case 0x8e: s390_format_RS_R0RD(s390_irgen_SRDA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
13304 ovl.fmt.RS.d2); goto ok;
13305 case 0x8f: s390_format_RS_R0RD(s390_irgen_SLDA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
13306 ovl.fmt.RS.d2); goto ok;
13307 case 0x90: s390_format_RS_RRRD(s390_irgen_STM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13308 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13309 case 0x91: s390_format_SI_URD(s390_irgen_TM, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
13310 ovl.fmt.SI.d1); goto ok;
13311 case 0x92: s390_format_SI_URD(s390_irgen_MVI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
13312 ovl.fmt.SI.d1); goto ok;
13313 case 0x94: s390_format_SI_URD(s390_irgen_NI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
13314 ovl.fmt.SI.d1); goto ok;
13315 case 0x95: s390_format_SI_URD(s390_irgen_CLI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
13316 ovl.fmt.SI.d1); goto ok;
13317 case 0x96: s390_format_SI_URD(s390_irgen_OI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
13318 ovl.fmt.SI.d1); goto ok;
13319 case 0x97: s390_format_SI_URD(s390_irgen_XI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
13320 ovl.fmt.SI.d1); goto ok;
13321 case 0x98: s390_format_RS_RRRD(s390_irgen_LM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13322 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13323 case 0x99: /* TRACE */ goto unimplemented;
13324 case 0x9a: s390_format_RS_AARD(s390_irgen_LAM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13325 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13326 case 0x9b: s390_format_RS_AARD(s390_irgen_STAM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13327 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13328 case 0xa8: s390_format_RS_RRRD(s390_irgen_MVCLE, ovl.fmt.RS.r1,
13329 ovl.fmt.RS.r3, ovl.fmt.RS.b2, ovl.fmt.RS.d2);
13330 goto ok;
13331 case 0xa9: s390_format_RS_RRRD(s390_irgen_CLCLE, ovl.fmt.RS.r1,
13332 ovl.fmt.RS.r3, ovl.fmt.RS.b2, ovl.fmt.RS.d2);
13333 goto ok;
13334 case 0xac: /* STNSM */ goto unimplemented;
13335 case 0xad: /* STOSM */ goto unimplemented;
13336 case 0xae: /* SIGP */ goto unimplemented;
13337 case 0xaf: /* MC */ goto unimplemented;
13338 case 0xb1: /* LRA */ goto unimplemented;
13339 case 0xb6: /* STCTL */ goto unimplemented;
13340 case 0xb7: /* LCTL */ goto unimplemented;
13341 case 0xba: s390_format_RS_RRRD(s390_irgen_CS, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13342 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
florian448cbba2012-06-06 02:26:01 +000013343 case 0xbb: s390_format_RS_RRRD(s390_irgen_CDS, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13344 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013345 case 0xbd: s390_format_RS_RURD(s390_irgen_CLM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13346 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13347 case 0xbe: s390_format_RS_RURD(s390_irgen_STCM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13348 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13349 case 0xbf: s390_format_RS_RURD(s390_irgen_ICM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13350 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13351 }
13352
13353 return S390_DECODE_UNKNOWN_INSN;
13354
13355ok:
13356 return S390_DECODE_OK;
13357
13358unimplemented:
13359 return S390_DECODE_UNIMPLEMENTED_INSN;
13360}
13361
13362static s390_decode_t
13363s390_decode_6byte_and_irgen(UChar *bytes)
13364{
13365 typedef union {
13366 struct {
13367 unsigned int op1 : 8;
13368 unsigned int r1 : 4;
13369 unsigned int r3 : 4;
13370 unsigned int i2 : 16;
13371 unsigned int : 8;
13372 unsigned int op2 : 8;
13373 } RIE;
13374 struct {
13375 unsigned int op1 : 8;
13376 unsigned int r1 : 4;
13377 unsigned int r2 : 4;
13378 unsigned int i3 : 8;
13379 unsigned int i4 : 8;
13380 unsigned int i5 : 8;
13381 unsigned int op2 : 8;
13382 } RIE_RRUUU;
13383 struct {
13384 unsigned int op1 : 8;
13385 unsigned int r1 : 4;
13386 unsigned int : 4;
13387 unsigned int i2 : 16;
13388 unsigned int m3 : 4;
13389 unsigned int : 4;
13390 unsigned int op2 : 8;
13391 } RIEv1;
13392 struct {
13393 unsigned int op1 : 8;
13394 unsigned int r1 : 4;
13395 unsigned int r2 : 4;
13396 unsigned int i4 : 16;
13397 unsigned int m3 : 4;
13398 unsigned int : 4;
13399 unsigned int op2 : 8;
13400 } RIE_RRPU;
13401 struct {
13402 unsigned int op1 : 8;
13403 unsigned int r1 : 4;
13404 unsigned int m3 : 4;
13405 unsigned int i4 : 16;
13406 unsigned int i2 : 8;
13407 unsigned int op2 : 8;
13408 } RIEv3;
13409 struct {
13410 unsigned int op1 : 8;
13411 unsigned int r1 : 4;
13412 unsigned int op2 : 4;
13413 unsigned int i2 : 32;
13414 } RIL;
13415 struct {
13416 unsigned int op1 : 8;
13417 unsigned int r1 : 4;
13418 unsigned int m3 : 4;
13419 unsigned int b4 : 4;
13420 unsigned int d4 : 12;
13421 unsigned int i2 : 8;
13422 unsigned int op2 : 8;
13423 } RIS;
13424 struct {
13425 unsigned int op1 : 8;
13426 unsigned int r1 : 4;
13427 unsigned int r2 : 4;
13428 unsigned int b4 : 4;
13429 unsigned int d4 : 12;
13430 unsigned int m3 : 4;
13431 unsigned int : 4;
13432 unsigned int op2 : 8;
13433 } RRS;
13434 struct {
13435 unsigned int op1 : 8;
13436 unsigned int l1 : 4;
13437 unsigned int : 4;
13438 unsigned int b1 : 4;
13439 unsigned int d1 : 12;
13440 unsigned int : 8;
13441 unsigned int op2 : 8;
13442 } RSL;
13443 struct {
13444 unsigned int op1 : 8;
13445 unsigned int r1 : 4;
13446 unsigned int r3 : 4;
13447 unsigned int b2 : 4;
13448 unsigned int dl2 : 12;
13449 unsigned int dh2 : 8;
13450 unsigned int op2 : 8;
13451 } RSY;
13452 struct {
13453 unsigned int op1 : 8;
13454 unsigned int r1 : 4;
13455 unsigned int x2 : 4;
13456 unsigned int b2 : 4;
13457 unsigned int d2 : 12;
13458 unsigned int : 8;
13459 unsigned int op2 : 8;
13460 } RXE;
13461 struct {
13462 unsigned int op1 : 8;
13463 unsigned int r3 : 4;
13464 unsigned int x2 : 4;
13465 unsigned int b2 : 4;
13466 unsigned int d2 : 12;
13467 unsigned int r1 : 4;
13468 unsigned int : 4;
13469 unsigned int op2 : 8;
13470 } RXF;
13471 struct {
13472 unsigned int op1 : 8;
13473 unsigned int r1 : 4;
13474 unsigned int x2 : 4;
13475 unsigned int b2 : 4;
13476 unsigned int dl2 : 12;
13477 unsigned int dh2 : 8;
13478 unsigned int op2 : 8;
13479 } RXY;
13480 struct {
13481 unsigned int op1 : 8;
13482 unsigned int i2 : 8;
13483 unsigned int b1 : 4;
13484 unsigned int dl1 : 12;
13485 unsigned int dh1 : 8;
13486 unsigned int op2 : 8;
13487 } SIY;
13488 struct {
13489 unsigned int op : 8;
13490 unsigned int l : 8;
13491 unsigned int b1 : 4;
13492 unsigned int d1 : 12;
13493 unsigned int b2 : 4;
13494 unsigned int d2 : 12;
13495 } SS;
13496 struct {
13497 unsigned int op : 8;
13498 unsigned int l1 : 4;
13499 unsigned int l2 : 4;
13500 unsigned int b1 : 4;
13501 unsigned int d1 : 12;
13502 unsigned int b2 : 4;
13503 unsigned int d2 : 12;
13504 } SS_LLRDRD;
13505 struct {
13506 unsigned int op : 8;
13507 unsigned int r1 : 4;
13508 unsigned int r3 : 4;
13509 unsigned int b2 : 4;
13510 unsigned int d2 : 12;
13511 unsigned int b4 : 4;
13512 unsigned int d4 : 12;
13513 } SS_RRRDRD2;
13514 struct {
13515 unsigned int op : 16;
13516 unsigned int b1 : 4;
13517 unsigned int d1 : 12;
13518 unsigned int b2 : 4;
13519 unsigned int d2 : 12;
13520 } SSE;
13521 struct {
13522 unsigned int op1 : 8;
13523 unsigned int r3 : 4;
13524 unsigned int op2 : 4;
13525 unsigned int b1 : 4;
13526 unsigned int d1 : 12;
13527 unsigned int b2 : 4;
13528 unsigned int d2 : 12;
13529 } SSF;
13530 struct {
13531 unsigned int op : 16;
13532 unsigned int b1 : 4;
13533 unsigned int d1 : 12;
13534 unsigned int i2 : 16;
13535 } SIL;
13536 } formats;
13537 union {
13538 formats fmt;
13539 ULong value;
13540 } ovl;
13541
13542 vassert(sizeof(formats) == 6);
13543
13544 ((char *)(&ovl.value))[0] = bytes[0];
13545 ((char *)(&ovl.value))[1] = bytes[1];
13546 ((char *)(&ovl.value))[2] = bytes[2];
13547 ((char *)(&ovl.value))[3] = bytes[3];
13548 ((char *)(&ovl.value))[4] = bytes[4];
13549 ((char *)(&ovl.value))[5] = bytes[5];
13550 ((char *)(&ovl.value))[6] = 0x0;
13551 ((char *)(&ovl.value))[7] = 0x0;
13552
13553 switch ((ovl.value >> 16) & 0xff00000000ffULL) {
13554 case 0xe30000000002ULL: s390_format_RXY_RRRD(s390_irgen_LTG, ovl.fmt.RXY.r1,
13555 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13556 ovl.fmt.RXY.dl2,
13557 ovl.fmt.RXY.dh2); goto ok;
13558 case 0xe30000000003ULL: /* LRAG */ goto unimplemented;
13559 case 0xe30000000004ULL: s390_format_RXY_RRRD(s390_irgen_LG, ovl.fmt.RXY.r1,
13560 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13561 ovl.fmt.RXY.dl2,
13562 ovl.fmt.RXY.dh2); goto ok;
13563 case 0xe30000000006ULL: s390_format_RXY_RRRD(s390_irgen_CVBY, ovl.fmt.RXY.r1,
13564 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13565 ovl.fmt.RXY.dl2,
13566 ovl.fmt.RXY.dh2); goto ok;
13567 case 0xe30000000008ULL: s390_format_RXY_RRRD(s390_irgen_AG, ovl.fmt.RXY.r1,
13568 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13569 ovl.fmt.RXY.dl2,
13570 ovl.fmt.RXY.dh2); goto ok;
13571 case 0xe30000000009ULL: s390_format_RXY_RRRD(s390_irgen_SG, ovl.fmt.RXY.r1,
13572 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13573 ovl.fmt.RXY.dl2,
13574 ovl.fmt.RXY.dh2); goto ok;
13575 case 0xe3000000000aULL: s390_format_RXY_RRRD(s390_irgen_ALG, ovl.fmt.RXY.r1,
13576 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13577 ovl.fmt.RXY.dl2,
13578 ovl.fmt.RXY.dh2); goto ok;
13579 case 0xe3000000000bULL: s390_format_RXY_RRRD(s390_irgen_SLG, ovl.fmt.RXY.r1,
13580 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13581 ovl.fmt.RXY.dl2,
13582 ovl.fmt.RXY.dh2); goto ok;
13583 case 0xe3000000000cULL: s390_format_RXY_RRRD(s390_irgen_MSG, ovl.fmt.RXY.r1,
13584 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13585 ovl.fmt.RXY.dl2,
13586 ovl.fmt.RXY.dh2); goto ok;
13587 case 0xe3000000000dULL: s390_format_RXY_RRRD(s390_irgen_DSG, ovl.fmt.RXY.r1,
13588 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13589 ovl.fmt.RXY.dl2,
13590 ovl.fmt.RXY.dh2); goto ok;
13591 case 0xe3000000000eULL: /* CVBG */ goto unimplemented;
13592 case 0xe3000000000fULL: s390_format_RXY_RRRD(s390_irgen_LRVG, ovl.fmt.RXY.r1,
13593 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13594 ovl.fmt.RXY.dl2,
13595 ovl.fmt.RXY.dh2); goto ok;
13596 case 0xe30000000012ULL: s390_format_RXY_RRRD(s390_irgen_LT, ovl.fmt.RXY.r1,
13597 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13598 ovl.fmt.RXY.dl2,
13599 ovl.fmt.RXY.dh2); goto ok;
13600 case 0xe30000000013ULL: /* LRAY */ goto unimplemented;
13601 case 0xe30000000014ULL: s390_format_RXY_RRRD(s390_irgen_LGF, ovl.fmt.RXY.r1,
13602 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13603 ovl.fmt.RXY.dl2,
13604 ovl.fmt.RXY.dh2); goto ok;
13605 case 0xe30000000015ULL: s390_format_RXY_RRRD(s390_irgen_LGH, ovl.fmt.RXY.r1,
13606 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13607 ovl.fmt.RXY.dl2,
13608 ovl.fmt.RXY.dh2); goto ok;
13609 case 0xe30000000016ULL: s390_format_RXY_RRRD(s390_irgen_LLGF, ovl.fmt.RXY.r1,
13610 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13611 ovl.fmt.RXY.dl2,
13612 ovl.fmt.RXY.dh2); goto ok;
13613 case 0xe30000000017ULL: s390_format_RXY_RRRD(s390_irgen_LLGT, ovl.fmt.RXY.r1,
13614 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13615 ovl.fmt.RXY.dl2,
13616 ovl.fmt.RXY.dh2); goto ok;
13617 case 0xe30000000018ULL: s390_format_RXY_RRRD(s390_irgen_AGF, ovl.fmt.RXY.r1,
13618 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13619 ovl.fmt.RXY.dl2,
13620 ovl.fmt.RXY.dh2); goto ok;
13621 case 0xe30000000019ULL: s390_format_RXY_RRRD(s390_irgen_SGF, ovl.fmt.RXY.r1,
13622 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13623 ovl.fmt.RXY.dl2,
13624 ovl.fmt.RXY.dh2); goto ok;
13625 case 0xe3000000001aULL: s390_format_RXY_RRRD(s390_irgen_ALGF, ovl.fmt.RXY.r1,
13626 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13627 ovl.fmt.RXY.dl2,
13628 ovl.fmt.RXY.dh2); goto ok;
13629 case 0xe3000000001bULL: s390_format_RXY_RRRD(s390_irgen_SLGF, ovl.fmt.RXY.r1,
13630 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13631 ovl.fmt.RXY.dl2,
13632 ovl.fmt.RXY.dh2); goto ok;
13633 case 0xe3000000001cULL: s390_format_RXY_RRRD(s390_irgen_MSGF, ovl.fmt.RXY.r1,
13634 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13635 ovl.fmt.RXY.dl2,
13636 ovl.fmt.RXY.dh2); goto ok;
13637 case 0xe3000000001dULL: s390_format_RXY_RRRD(s390_irgen_DSGF, ovl.fmt.RXY.r1,
13638 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13639 ovl.fmt.RXY.dl2,
13640 ovl.fmt.RXY.dh2); goto ok;
13641 case 0xe3000000001eULL: s390_format_RXY_RRRD(s390_irgen_LRV, ovl.fmt.RXY.r1,
13642 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13643 ovl.fmt.RXY.dl2,
13644 ovl.fmt.RXY.dh2); goto ok;
13645 case 0xe3000000001fULL: s390_format_RXY_RRRD(s390_irgen_LRVH, ovl.fmt.RXY.r1,
13646 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13647 ovl.fmt.RXY.dl2,
13648 ovl.fmt.RXY.dh2); goto ok;
13649 case 0xe30000000020ULL: s390_format_RXY_RRRD(s390_irgen_CG, ovl.fmt.RXY.r1,
13650 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13651 ovl.fmt.RXY.dl2,
13652 ovl.fmt.RXY.dh2); goto ok;
13653 case 0xe30000000021ULL: s390_format_RXY_RRRD(s390_irgen_CLG, ovl.fmt.RXY.r1,
13654 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13655 ovl.fmt.RXY.dl2,
13656 ovl.fmt.RXY.dh2); goto ok;
13657 case 0xe30000000024ULL: s390_format_RXY_RRRD(s390_irgen_STG, ovl.fmt.RXY.r1,
13658 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13659 ovl.fmt.RXY.dl2,
13660 ovl.fmt.RXY.dh2); goto ok;
13661 case 0xe30000000026ULL: s390_format_RXY_RRRD(s390_irgen_CVDY, ovl.fmt.RXY.r1,
13662 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13663 ovl.fmt.RXY.dl2,
13664 ovl.fmt.RXY.dh2); goto ok;
13665 case 0xe3000000002eULL: /* CVDG */ goto unimplemented;
13666 case 0xe3000000002fULL: s390_format_RXY_RRRD(s390_irgen_STRVG,
13667 ovl.fmt.RXY.r1, ovl.fmt.RXY.x2,
13668 ovl.fmt.RXY.b2, ovl.fmt.RXY.dl2,
13669 ovl.fmt.RXY.dh2); goto ok;
13670 case 0xe30000000030ULL: s390_format_RXY_RRRD(s390_irgen_CGF, ovl.fmt.RXY.r1,
13671 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13672 ovl.fmt.RXY.dl2,
13673 ovl.fmt.RXY.dh2); goto ok;
13674 case 0xe30000000031ULL: s390_format_RXY_RRRD(s390_irgen_CLGF, ovl.fmt.RXY.r1,
13675 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13676 ovl.fmt.RXY.dl2,
13677 ovl.fmt.RXY.dh2); goto ok;
13678 case 0xe30000000032ULL: s390_format_RXY_RRRD(s390_irgen_LTGF, ovl.fmt.RXY.r1,
13679 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13680 ovl.fmt.RXY.dl2,
13681 ovl.fmt.RXY.dh2); goto ok;
13682 case 0xe30000000034ULL: s390_format_RXY_RRRD(s390_irgen_CGH, ovl.fmt.RXY.r1,
13683 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13684 ovl.fmt.RXY.dl2,
13685 ovl.fmt.RXY.dh2); goto ok;
13686 case 0xe30000000036ULL: s390_format_RXY_URRD(s390_irgen_PFD, ovl.fmt.RXY.r1,
13687 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13688 ovl.fmt.RXY.dl2,
13689 ovl.fmt.RXY.dh2); goto ok;
13690 case 0xe3000000003eULL: s390_format_RXY_RRRD(s390_irgen_STRV, ovl.fmt.RXY.r1,
13691 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13692 ovl.fmt.RXY.dl2,
13693 ovl.fmt.RXY.dh2); goto ok;
13694 case 0xe3000000003fULL: s390_format_RXY_RRRD(s390_irgen_STRVH,
13695 ovl.fmt.RXY.r1, ovl.fmt.RXY.x2,
13696 ovl.fmt.RXY.b2, ovl.fmt.RXY.dl2,
13697 ovl.fmt.RXY.dh2); goto ok;
13698 case 0xe30000000046ULL: s390_format_RXY_RRRD(s390_irgen_BCTG, ovl.fmt.RXY.r1,
13699 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13700 ovl.fmt.RXY.dl2,
13701 ovl.fmt.RXY.dh2); goto ok;
13702 case 0xe30000000050ULL: s390_format_RXY_RRRD(s390_irgen_STY, ovl.fmt.RXY.r1,
13703 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13704 ovl.fmt.RXY.dl2,
13705 ovl.fmt.RXY.dh2); goto ok;
13706 case 0xe30000000051ULL: s390_format_RXY_RRRD(s390_irgen_MSY, ovl.fmt.RXY.r1,
13707 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13708 ovl.fmt.RXY.dl2,
13709 ovl.fmt.RXY.dh2); goto ok;
13710 case 0xe30000000054ULL: s390_format_RXY_RRRD(s390_irgen_NY, ovl.fmt.RXY.r1,
13711 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13712 ovl.fmt.RXY.dl2,
13713 ovl.fmt.RXY.dh2); goto ok;
13714 case 0xe30000000055ULL: s390_format_RXY_RRRD(s390_irgen_CLY, ovl.fmt.RXY.r1,
13715 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13716 ovl.fmt.RXY.dl2,
13717 ovl.fmt.RXY.dh2); goto ok;
13718 case 0xe30000000056ULL: s390_format_RXY_RRRD(s390_irgen_OY, ovl.fmt.RXY.r1,
13719 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13720 ovl.fmt.RXY.dl2,
13721 ovl.fmt.RXY.dh2); goto ok;
13722 case 0xe30000000057ULL: s390_format_RXY_RRRD(s390_irgen_XY, ovl.fmt.RXY.r1,
13723 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13724 ovl.fmt.RXY.dl2,
13725 ovl.fmt.RXY.dh2); goto ok;
13726 case 0xe30000000058ULL: s390_format_RXY_RRRD(s390_irgen_LY, ovl.fmt.RXY.r1,
13727 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13728 ovl.fmt.RXY.dl2,
13729 ovl.fmt.RXY.dh2); goto ok;
13730 case 0xe30000000059ULL: s390_format_RXY_RRRD(s390_irgen_CY, ovl.fmt.RXY.r1,
13731 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13732 ovl.fmt.RXY.dl2,
13733 ovl.fmt.RXY.dh2); goto ok;
13734 case 0xe3000000005aULL: s390_format_RXY_RRRD(s390_irgen_AY, ovl.fmt.RXY.r1,
13735 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13736 ovl.fmt.RXY.dl2,
13737 ovl.fmt.RXY.dh2); goto ok;
13738 case 0xe3000000005bULL: s390_format_RXY_RRRD(s390_irgen_SY, ovl.fmt.RXY.r1,
13739 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13740 ovl.fmt.RXY.dl2,
13741 ovl.fmt.RXY.dh2); goto ok;
13742 case 0xe3000000005cULL: s390_format_RXY_RRRD(s390_irgen_MFY, ovl.fmt.RXY.r1,
13743 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13744 ovl.fmt.RXY.dl2,
13745 ovl.fmt.RXY.dh2); goto ok;
13746 case 0xe3000000005eULL: s390_format_RXY_RRRD(s390_irgen_ALY, ovl.fmt.RXY.r1,
13747 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13748 ovl.fmt.RXY.dl2,
13749 ovl.fmt.RXY.dh2); goto ok;
13750 case 0xe3000000005fULL: s390_format_RXY_RRRD(s390_irgen_SLY, ovl.fmt.RXY.r1,
13751 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13752 ovl.fmt.RXY.dl2,
13753 ovl.fmt.RXY.dh2); goto ok;
13754 case 0xe30000000070ULL: s390_format_RXY_RRRD(s390_irgen_STHY, ovl.fmt.RXY.r1,
13755 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13756 ovl.fmt.RXY.dl2,
13757 ovl.fmt.RXY.dh2); goto ok;
13758 case 0xe30000000071ULL: s390_format_RXY_RRRD(s390_irgen_LAY, ovl.fmt.RXY.r1,
13759 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13760 ovl.fmt.RXY.dl2,
13761 ovl.fmt.RXY.dh2); goto ok;
13762 case 0xe30000000072ULL: s390_format_RXY_RRRD(s390_irgen_STCY, ovl.fmt.RXY.r1,
13763 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13764 ovl.fmt.RXY.dl2,
13765 ovl.fmt.RXY.dh2); goto ok;
13766 case 0xe30000000073ULL: s390_format_RXY_RRRD(s390_irgen_ICY, ovl.fmt.RXY.r1,
13767 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13768 ovl.fmt.RXY.dl2,
13769 ovl.fmt.RXY.dh2); goto ok;
13770 case 0xe30000000075ULL: s390_format_RXY_RRRD(s390_irgen_LAEY, ovl.fmt.RXY.r1,
13771 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13772 ovl.fmt.RXY.dl2,
13773 ovl.fmt.RXY.dh2); goto ok;
13774 case 0xe30000000076ULL: s390_format_RXY_RRRD(s390_irgen_LB, ovl.fmt.RXY.r1,
13775 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13776 ovl.fmt.RXY.dl2,
13777 ovl.fmt.RXY.dh2); goto ok;
13778 case 0xe30000000077ULL: s390_format_RXY_RRRD(s390_irgen_LGB, 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 0xe30000000078ULL: s390_format_RXY_RRRD(s390_irgen_LHY, ovl.fmt.RXY.r1,
13783 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13784 ovl.fmt.RXY.dl2,
13785 ovl.fmt.RXY.dh2); goto ok;
13786 case 0xe30000000079ULL: s390_format_RXY_RRRD(s390_irgen_CHY, ovl.fmt.RXY.r1,
13787 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13788 ovl.fmt.RXY.dl2,
13789 ovl.fmt.RXY.dh2); goto ok;
13790 case 0xe3000000007aULL: s390_format_RXY_RRRD(s390_irgen_AHY, ovl.fmt.RXY.r1,
13791 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13792 ovl.fmt.RXY.dl2,
13793 ovl.fmt.RXY.dh2); goto ok;
13794 case 0xe3000000007bULL: s390_format_RXY_RRRD(s390_irgen_SHY, ovl.fmt.RXY.r1,
13795 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13796 ovl.fmt.RXY.dl2,
13797 ovl.fmt.RXY.dh2); goto ok;
13798 case 0xe3000000007cULL: s390_format_RXY_RRRD(s390_irgen_MHY, ovl.fmt.RXY.r1,
13799 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13800 ovl.fmt.RXY.dl2,
13801 ovl.fmt.RXY.dh2); goto ok;
13802 case 0xe30000000080ULL: s390_format_RXY_RRRD(s390_irgen_NG, ovl.fmt.RXY.r1,
13803 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13804 ovl.fmt.RXY.dl2,
13805 ovl.fmt.RXY.dh2); goto ok;
13806 case 0xe30000000081ULL: s390_format_RXY_RRRD(s390_irgen_OG, ovl.fmt.RXY.r1,
13807 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13808 ovl.fmt.RXY.dl2,
13809 ovl.fmt.RXY.dh2); goto ok;
13810 case 0xe30000000082ULL: s390_format_RXY_RRRD(s390_irgen_XG, ovl.fmt.RXY.r1,
13811 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13812 ovl.fmt.RXY.dl2,
13813 ovl.fmt.RXY.dh2); goto ok;
13814 case 0xe30000000086ULL: s390_format_RXY_RRRD(s390_irgen_MLG, ovl.fmt.RXY.r1,
13815 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13816 ovl.fmt.RXY.dl2,
13817 ovl.fmt.RXY.dh2); goto ok;
13818 case 0xe30000000087ULL: s390_format_RXY_RRRD(s390_irgen_DLG, ovl.fmt.RXY.r1,
13819 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13820 ovl.fmt.RXY.dl2,
13821 ovl.fmt.RXY.dh2); goto ok;
13822 case 0xe30000000088ULL: s390_format_RXY_RRRD(s390_irgen_ALCG, ovl.fmt.RXY.r1,
13823 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13824 ovl.fmt.RXY.dl2,
13825 ovl.fmt.RXY.dh2); goto ok;
13826 case 0xe30000000089ULL: s390_format_RXY_RRRD(s390_irgen_SLBG, ovl.fmt.RXY.r1,
13827 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13828 ovl.fmt.RXY.dl2,
13829 ovl.fmt.RXY.dh2); goto ok;
13830 case 0xe3000000008eULL: s390_format_RXY_RRRD(s390_irgen_STPQ, ovl.fmt.RXY.r1,
13831 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13832 ovl.fmt.RXY.dl2,
13833 ovl.fmt.RXY.dh2); goto ok;
13834 case 0xe3000000008fULL: s390_format_RXY_RRRD(s390_irgen_LPQ, ovl.fmt.RXY.r1,
13835 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13836 ovl.fmt.RXY.dl2,
13837 ovl.fmt.RXY.dh2); goto ok;
13838 case 0xe30000000090ULL: s390_format_RXY_RRRD(s390_irgen_LLGC, ovl.fmt.RXY.r1,
13839 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13840 ovl.fmt.RXY.dl2,
13841 ovl.fmt.RXY.dh2); goto ok;
13842 case 0xe30000000091ULL: s390_format_RXY_RRRD(s390_irgen_LLGH, ovl.fmt.RXY.r1,
13843 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13844 ovl.fmt.RXY.dl2,
13845 ovl.fmt.RXY.dh2); goto ok;
13846 case 0xe30000000094ULL: s390_format_RXY_RRRD(s390_irgen_LLC, ovl.fmt.RXY.r1,
13847 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13848 ovl.fmt.RXY.dl2,
13849 ovl.fmt.RXY.dh2); goto ok;
13850 case 0xe30000000095ULL: s390_format_RXY_RRRD(s390_irgen_LLH, ovl.fmt.RXY.r1,
13851 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13852 ovl.fmt.RXY.dl2,
13853 ovl.fmt.RXY.dh2); goto ok;
13854 case 0xe30000000096ULL: s390_format_RXY_RRRD(s390_irgen_ML, ovl.fmt.RXY.r1,
13855 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13856 ovl.fmt.RXY.dl2,
13857 ovl.fmt.RXY.dh2); goto ok;
13858 case 0xe30000000097ULL: s390_format_RXY_RRRD(s390_irgen_DL, ovl.fmt.RXY.r1,
13859 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13860 ovl.fmt.RXY.dl2,
13861 ovl.fmt.RXY.dh2); goto ok;
13862 case 0xe30000000098ULL: s390_format_RXY_RRRD(s390_irgen_ALC, ovl.fmt.RXY.r1,
13863 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13864 ovl.fmt.RXY.dl2,
13865 ovl.fmt.RXY.dh2); goto ok;
13866 case 0xe30000000099ULL: s390_format_RXY_RRRD(s390_irgen_SLB, ovl.fmt.RXY.r1,
13867 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13868 ovl.fmt.RXY.dl2,
13869 ovl.fmt.RXY.dh2); goto ok;
13870 case 0xe300000000c0ULL: s390_format_RXY_RRRD(s390_irgen_LBH, ovl.fmt.RXY.r1,
13871 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13872 ovl.fmt.RXY.dl2,
13873 ovl.fmt.RXY.dh2); goto ok;
13874 case 0xe300000000c2ULL: s390_format_RXY_RRRD(s390_irgen_LLCH, ovl.fmt.RXY.r1,
13875 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13876 ovl.fmt.RXY.dl2,
13877 ovl.fmt.RXY.dh2); goto ok;
13878 case 0xe300000000c3ULL: s390_format_RXY_RRRD(s390_irgen_STCH, ovl.fmt.RXY.r1,
13879 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13880 ovl.fmt.RXY.dl2,
13881 ovl.fmt.RXY.dh2); goto ok;
13882 case 0xe300000000c4ULL: s390_format_RXY_RRRD(s390_irgen_LHH, ovl.fmt.RXY.r1,
13883 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13884 ovl.fmt.RXY.dl2,
13885 ovl.fmt.RXY.dh2); goto ok;
13886 case 0xe300000000c6ULL: s390_format_RXY_RRRD(s390_irgen_LLHH, ovl.fmt.RXY.r1,
13887 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13888 ovl.fmt.RXY.dl2,
13889 ovl.fmt.RXY.dh2); goto ok;
13890 case 0xe300000000c7ULL: s390_format_RXY_RRRD(s390_irgen_STHH, ovl.fmt.RXY.r1,
13891 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13892 ovl.fmt.RXY.dl2,
13893 ovl.fmt.RXY.dh2); goto ok;
13894 case 0xe300000000caULL: s390_format_RXY_RRRD(s390_irgen_LFH, 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 0xe300000000cbULL: s390_format_RXY_RRRD(s390_irgen_STFH, 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 0xe300000000cdULL: s390_format_RXY_RRRD(s390_irgen_CHF, 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 0xe300000000cfULL: s390_format_RXY_RRRD(s390_irgen_CLHF, 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 0xeb0000000004ULL: s390_format_RSY_RRRD(s390_irgen_LMG, ovl.fmt.RSY.r1,
13911 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13912 ovl.fmt.RSY.dl2,
13913 ovl.fmt.RSY.dh2); goto ok;
13914 case 0xeb000000000aULL: s390_format_RSY_RRRD(s390_irgen_SRAG, ovl.fmt.RSY.r1,
13915 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13916 ovl.fmt.RSY.dl2,
13917 ovl.fmt.RSY.dh2); goto ok;
13918 case 0xeb000000000bULL: s390_format_RSY_RRRD(s390_irgen_SLAG, ovl.fmt.RSY.r1,
13919 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13920 ovl.fmt.RSY.dl2,
13921 ovl.fmt.RSY.dh2); goto ok;
13922 case 0xeb000000000cULL: s390_format_RSY_RRRD(s390_irgen_SRLG, ovl.fmt.RSY.r1,
13923 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13924 ovl.fmt.RSY.dl2,
13925 ovl.fmt.RSY.dh2); goto ok;
13926 case 0xeb000000000dULL: s390_format_RSY_RRRD(s390_irgen_SLLG, ovl.fmt.RSY.r1,
13927 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13928 ovl.fmt.RSY.dl2,
13929 ovl.fmt.RSY.dh2); goto ok;
13930 case 0xeb000000000fULL: /* TRACG */ goto unimplemented;
13931 case 0xeb0000000014ULL: s390_format_RSY_RRRD(s390_irgen_CSY, ovl.fmt.RSY.r1,
13932 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13933 ovl.fmt.RSY.dl2,
13934 ovl.fmt.RSY.dh2); goto ok;
13935 case 0xeb000000001cULL: s390_format_RSY_RRRD(s390_irgen_RLLG, ovl.fmt.RSY.r1,
13936 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13937 ovl.fmt.RSY.dl2,
13938 ovl.fmt.RSY.dh2); goto ok;
13939 case 0xeb000000001dULL: s390_format_RSY_RRRD(s390_irgen_RLL, ovl.fmt.RSY.r1,
13940 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13941 ovl.fmt.RSY.dl2,
13942 ovl.fmt.RSY.dh2); goto ok;
13943 case 0xeb0000000020ULL: s390_format_RSY_RURD(s390_irgen_CLMH, ovl.fmt.RSY.r1,
13944 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13945 ovl.fmt.RSY.dl2,
13946 ovl.fmt.RSY.dh2); goto ok;
13947 case 0xeb0000000021ULL: s390_format_RSY_RURD(s390_irgen_CLMY, ovl.fmt.RSY.r1,
13948 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13949 ovl.fmt.RSY.dl2,
13950 ovl.fmt.RSY.dh2); goto ok;
13951 case 0xeb0000000024ULL: s390_format_RSY_RRRD(s390_irgen_STMG, ovl.fmt.RSY.r1,
13952 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13953 ovl.fmt.RSY.dl2,
13954 ovl.fmt.RSY.dh2); goto ok;
13955 case 0xeb0000000025ULL: /* STCTG */ goto unimplemented;
13956 case 0xeb0000000026ULL: s390_format_RSY_RRRD(s390_irgen_STMH, ovl.fmt.RSY.r1,
13957 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13958 ovl.fmt.RSY.dl2,
13959 ovl.fmt.RSY.dh2); goto ok;
13960 case 0xeb000000002cULL: s390_format_RSY_RURD(s390_irgen_STCMH,
13961 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
13962 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
13963 ovl.fmt.RSY.dh2); goto ok;
13964 case 0xeb000000002dULL: s390_format_RSY_RURD(s390_irgen_STCMY,
13965 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
13966 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
13967 ovl.fmt.RSY.dh2); goto ok;
13968 case 0xeb000000002fULL: /* LCTLG */ goto unimplemented;
13969 case 0xeb0000000030ULL: s390_format_RSY_RRRD(s390_irgen_CSG, ovl.fmt.RSY.r1,
13970 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13971 ovl.fmt.RSY.dl2,
13972 ovl.fmt.RSY.dh2); goto ok;
florian448cbba2012-06-06 02:26:01 +000013973 case 0xeb0000000031ULL: s390_format_RSY_RRRD(s390_irgen_CDSY, ovl.fmt.RSY.r1,
13974 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13975 ovl.fmt.RSY.dl2,
13976 ovl.fmt.RSY.dh2); goto ok;
13977 case 0xeb000000003eULL: s390_format_RSY_RRRD(s390_irgen_CDSG, ovl.fmt.RSY.r1,
13978 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13979 ovl.fmt.RSY.dl2,
13980 ovl.fmt.RSY.dh2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013981 case 0xeb0000000044ULL: s390_format_RSY_RRRD(s390_irgen_BXHG, ovl.fmt.RSY.r1,
13982 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13983 ovl.fmt.RSY.dl2,
13984 ovl.fmt.RSY.dh2); goto ok;
13985 case 0xeb0000000045ULL: s390_format_RSY_RRRD(s390_irgen_BXLEG,
13986 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
13987 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
13988 ovl.fmt.RSY.dh2); goto ok;
florian8c88cb62012-08-26 18:58:13 +000013989 case 0xeb000000004cULL: s390_format_RSY_RRRD(s390_irgen_ECAG, ovl.fmt.RSY.r1,
13990 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13991 ovl.fmt.RSY.dl2,
13992 ovl.fmt.RSY.dh2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013993 case 0xeb0000000051ULL: s390_format_SIY_URD(s390_irgen_TMY, ovl.fmt.SIY.i2,
13994 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
13995 ovl.fmt.SIY.dh1); goto ok;
13996 case 0xeb0000000052ULL: s390_format_SIY_URD(s390_irgen_MVIY, ovl.fmt.SIY.i2,
13997 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
13998 ovl.fmt.SIY.dh1); goto ok;
13999 case 0xeb0000000054ULL: s390_format_SIY_URD(s390_irgen_NIY, ovl.fmt.SIY.i2,
14000 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
14001 ovl.fmt.SIY.dh1); goto ok;
14002 case 0xeb0000000055ULL: s390_format_SIY_URD(s390_irgen_CLIY, ovl.fmt.SIY.i2,
14003 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
14004 ovl.fmt.SIY.dh1); goto ok;
14005 case 0xeb0000000056ULL: s390_format_SIY_URD(s390_irgen_OIY, ovl.fmt.SIY.i2,
14006 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
14007 ovl.fmt.SIY.dh1); goto ok;
14008 case 0xeb0000000057ULL: s390_format_SIY_URD(s390_irgen_XIY, ovl.fmt.SIY.i2,
14009 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
14010 ovl.fmt.SIY.dh1); goto ok;
14011 case 0xeb000000006aULL: s390_format_SIY_IRD(s390_irgen_ASI, ovl.fmt.SIY.i2,
14012 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
14013 ovl.fmt.SIY.dh1); goto ok;
14014 case 0xeb000000006eULL: s390_format_SIY_IRD(s390_irgen_ALSI, ovl.fmt.SIY.i2,
14015 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
14016 ovl.fmt.SIY.dh1); goto ok;
14017 case 0xeb000000007aULL: s390_format_SIY_IRD(s390_irgen_AGSI, ovl.fmt.SIY.i2,
14018 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
14019 ovl.fmt.SIY.dh1); goto ok;
14020 case 0xeb000000007eULL: s390_format_SIY_IRD(s390_irgen_ALGSI, ovl.fmt.SIY.i2,
14021 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
14022 ovl.fmt.SIY.dh1); goto ok;
14023 case 0xeb0000000080ULL: s390_format_RSY_RURD(s390_irgen_ICMH, ovl.fmt.RSY.r1,
14024 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14025 ovl.fmt.RSY.dl2,
14026 ovl.fmt.RSY.dh2); goto ok;
14027 case 0xeb0000000081ULL: s390_format_RSY_RURD(s390_irgen_ICMY, ovl.fmt.RSY.r1,
14028 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14029 ovl.fmt.RSY.dl2,
14030 ovl.fmt.RSY.dh2); goto ok;
14031 case 0xeb000000008eULL: /* MVCLU */ goto unimplemented;
14032 case 0xeb000000008fULL: /* CLCLU */ goto unimplemented;
14033 case 0xeb0000000090ULL: s390_format_RSY_RRRD(s390_irgen_STMY, ovl.fmt.RSY.r1,
14034 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14035 ovl.fmt.RSY.dl2,
14036 ovl.fmt.RSY.dh2); goto ok;
14037 case 0xeb0000000096ULL: s390_format_RSY_RRRD(s390_irgen_LMH, ovl.fmt.RSY.r1,
14038 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14039 ovl.fmt.RSY.dl2,
14040 ovl.fmt.RSY.dh2); goto ok;
14041 case 0xeb0000000098ULL: s390_format_RSY_RRRD(s390_irgen_LMY, ovl.fmt.RSY.r1,
14042 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14043 ovl.fmt.RSY.dl2,
14044 ovl.fmt.RSY.dh2); goto ok;
14045 case 0xeb000000009aULL: s390_format_RSY_AARD(s390_irgen_LAMY, ovl.fmt.RSY.r1,
14046 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14047 ovl.fmt.RSY.dl2,
14048 ovl.fmt.RSY.dh2); goto ok;
14049 case 0xeb000000009bULL: s390_format_RSY_AARD(s390_irgen_STAMY,
14050 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
14051 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
14052 ovl.fmt.RSY.dh2); goto ok;
14053 case 0xeb00000000c0ULL: /* TP */ goto unimplemented;
14054 case 0xeb00000000dcULL: s390_format_RSY_RRRD(s390_irgen_SRAK, ovl.fmt.RSY.r1,
14055 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14056 ovl.fmt.RSY.dl2,
14057 ovl.fmt.RSY.dh2); goto ok;
14058 case 0xeb00000000ddULL: s390_format_RSY_RRRD(s390_irgen_SLAK, ovl.fmt.RSY.r1,
14059 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14060 ovl.fmt.RSY.dl2,
14061 ovl.fmt.RSY.dh2); goto ok;
14062 case 0xeb00000000deULL: s390_format_RSY_RRRD(s390_irgen_SRLK, ovl.fmt.RSY.r1,
14063 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14064 ovl.fmt.RSY.dl2,
14065 ovl.fmt.RSY.dh2); goto ok;
14066 case 0xeb00000000dfULL: s390_format_RSY_RRRD(s390_irgen_SLLK, ovl.fmt.RSY.r1,
14067 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14068 ovl.fmt.RSY.dl2,
14069 ovl.fmt.RSY.dh2); goto ok;
sewardjd7bde722011-04-05 13:19:33 +000014070 case 0xeb00000000e2ULL: s390_format_RSY_RDRM(s390_irgen_LOCG, ovl.fmt.RSY.r1,
14071 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14072 ovl.fmt.RSY.dl2,
14073 ovl.fmt.RSY.dh2,
14074 S390_XMNM_LOCG); goto ok;
14075 case 0xeb00000000e3ULL: s390_format_RSY_RDRM(s390_irgen_STOCG,
14076 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
14077 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
14078 ovl.fmt.RSY.dh2,
14079 S390_XMNM_STOCG); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014080 case 0xeb00000000e4ULL: s390_format_RSY_RRRD(s390_irgen_LANG, ovl.fmt.RSY.r1,
14081 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14082 ovl.fmt.RSY.dl2,
14083 ovl.fmt.RSY.dh2); goto ok;
14084 case 0xeb00000000e6ULL: s390_format_RSY_RRRD(s390_irgen_LAOG, ovl.fmt.RSY.r1,
14085 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14086 ovl.fmt.RSY.dl2,
14087 ovl.fmt.RSY.dh2); goto ok;
14088 case 0xeb00000000e7ULL: s390_format_RSY_RRRD(s390_irgen_LAXG, ovl.fmt.RSY.r1,
14089 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14090 ovl.fmt.RSY.dl2,
14091 ovl.fmt.RSY.dh2); goto ok;
14092 case 0xeb00000000e8ULL: s390_format_RSY_RRRD(s390_irgen_LAAG, ovl.fmt.RSY.r1,
14093 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14094 ovl.fmt.RSY.dl2,
14095 ovl.fmt.RSY.dh2); goto ok;
14096 case 0xeb00000000eaULL: s390_format_RSY_RRRD(s390_irgen_LAALG,
14097 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
14098 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
14099 ovl.fmt.RSY.dh2); goto ok;
sewardjd7bde722011-04-05 13:19:33 +000014100 case 0xeb00000000f2ULL: s390_format_RSY_RDRM(s390_irgen_LOC, ovl.fmt.RSY.r1,
14101 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14102 ovl.fmt.RSY.dl2,
14103 ovl.fmt.RSY.dh2, S390_XMNM_LOC);
14104 goto ok;
14105 case 0xeb00000000f3ULL: s390_format_RSY_RDRM(s390_irgen_STOC, ovl.fmt.RSY.r1,
14106 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14107 ovl.fmt.RSY.dl2,
14108 ovl.fmt.RSY.dh2,
14109 S390_XMNM_STOC); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014110 case 0xeb00000000f4ULL: s390_format_RSY_RRRD(s390_irgen_LAN, ovl.fmt.RSY.r1,
14111 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14112 ovl.fmt.RSY.dl2,
14113 ovl.fmt.RSY.dh2); goto ok;
14114 case 0xeb00000000f6ULL: s390_format_RSY_RRRD(s390_irgen_LAO, ovl.fmt.RSY.r1,
14115 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14116 ovl.fmt.RSY.dl2,
14117 ovl.fmt.RSY.dh2); goto ok;
14118 case 0xeb00000000f7ULL: s390_format_RSY_RRRD(s390_irgen_LAX, ovl.fmt.RSY.r1,
14119 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14120 ovl.fmt.RSY.dl2,
14121 ovl.fmt.RSY.dh2); goto ok;
14122 case 0xeb00000000f8ULL: s390_format_RSY_RRRD(s390_irgen_LAA, ovl.fmt.RSY.r1,
14123 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14124 ovl.fmt.RSY.dl2,
14125 ovl.fmt.RSY.dh2); goto ok;
14126 case 0xeb00000000faULL: s390_format_RSY_RRRD(s390_irgen_LAAL, ovl.fmt.RSY.r1,
14127 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14128 ovl.fmt.RSY.dl2,
14129 ovl.fmt.RSY.dh2); goto ok;
14130 case 0xec0000000044ULL: s390_format_RIE_RRP(s390_irgen_BRXHG, ovl.fmt.RIE.r1,
14131 ovl.fmt.RIE.r3, ovl.fmt.RIE.i2);
14132 goto ok;
14133 case 0xec0000000045ULL: s390_format_RIE_RRP(s390_irgen_BRXLG, ovl.fmt.RIE.r1,
14134 ovl.fmt.RIE.r3, ovl.fmt.RIE.i2);
14135 goto ok;
14136 case 0xec0000000051ULL: /* RISBLG */ goto unimplemented;
14137 case 0xec0000000054ULL: s390_format_RIE_RRUUU(s390_irgen_RNSBG,
14138 ovl.fmt.RIE_RRUUU.r1,
14139 ovl.fmt.RIE_RRUUU.r2,
14140 ovl.fmt.RIE_RRUUU.i3,
14141 ovl.fmt.RIE_RRUUU.i4,
14142 ovl.fmt.RIE_RRUUU.i5);
14143 goto ok;
14144 case 0xec0000000055ULL: s390_format_RIE_RRUUU(s390_irgen_RISBG,
14145 ovl.fmt.RIE_RRUUU.r1,
14146 ovl.fmt.RIE_RRUUU.r2,
14147 ovl.fmt.RIE_RRUUU.i3,
14148 ovl.fmt.RIE_RRUUU.i4,
14149 ovl.fmt.RIE_RRUUU.i5);
14150 goto ok;
14151 case 0xec0000000056ULL: s390_format_RIE_RRUUU(s390_irgen_ROSBG,
14152 ovl.fmt.RIE_RRUUU.r1,
14153 ovl.fmt.RIE_RRUUU.r2,
14154 ovl.fmt.RIE_RRUUU.i3,
14155 ovl.fmt.RIE_RRUUU.i4,
14156 ovl.fmt.RIE_RRUUU.i5);
14157 goto ok;
14158 case 0xec0000000057ULL: s390_format_RIE_RRUUU(s390_irgen_RXSBG,
14159 ovl.fmt.RIE_RRUUU.r1,
14160 ovl.fmt.RIE_RRUUU.r2,
14161 ovl.fmt.RIE_RRUUU.i3,
14162 ovl.fmt.RIE_RRUUU.i4,
14163 ovl.fmt.RIE_RRUUU.i5);
14164 goto ok;
14165 case 0xec000000005dULL: /* RISBHG */ goto unimplemented;
14166 case 0xec0000000064ULL: s390_format_RIE_RRPU(s390_irgen_CGRJ,
14167 ovl.fmt.RIE_RRPU.r1,
14168 ovl.fmt.RIE_RRPU.r2,
14169 ovl.fmt.RIE_RRPU.i4,
14170 ovl.fmt.RIE_RRPU.m3); goto ok;
14171 case 0xec0000000065ULL: s390_format_RIE_RRPU(s390_irgen_CLGRJ,
14172 ovl.fmt.RIE_RRPU.r1,
14173 ovl.fmt.RIE_RRPU.r2,
14174 ovl.fmt.RIE_RRPU.i4,
14175 ovl.fmt.RIE_RRPU.m3); goto ok;
14176 case 0xec0000000070ULL: /* CGIT */ goto unimplemented;
14177 case 0xec0000000071ULL: /* CLGIT */ goto unimplemented;
14178 case 0xec0000000072ULL: /* CIT */ goto unimplemented;
14179 case 0xec0000000073ULL: /* CLFIT */ goto unimplemented;
14180 case 0xec0000000076ULL: s390_format_RIE_RRPU(s390_irgen_CRJ,
14181 ovl.fmt.RIE_RRPU.r1,
14182 ovl.fmt.RIE_RRPU.r2,
14183 ovl.fmt.RIE_RRPU.i4,
14184 ovl.fmt.RIE_RRPU.m3); goto ok;
14185 case 0xec0000000077ULL: s390_format_RIE_RRPU(s390_irgen_CLRJ,
14186 ovl.fmt.RIE_RRPU.r1,
14187 ovl.fmt.RIE_RRPU.r2,
14188 ovl.fmt.RIE_RRPU.i4,
14189 ovl.fmt.RIE_RRPU.m3); goto ok;
14190 case 0xec000000007cULL: s390_format_RIE_RUPI(s390_irgen_CGIJ,
14191 ovl.fmt.RIEv3.r1,
14192 ovl.fmt.RIEv3.m3,
14193 ovl.fmt.RIEv3.i4,
14194 ovl.fmt.RIEv3.i2); goto ok;
14195 case 0xec000000007dULL: s390_format_RIE_RUPU(s390_irgen_CLGIJ,
14196 ovl.fmt.RIEv3.r1,
14197 ovl.fmt.RIEv3.m3,
14198 ovl.fmt.RIEv3.i4,
14199 ovl.fmt.RIEv3.i2); goto ok;
14200 case 0xec000000007eULL: s390_format_RIE_RUPI(s390_irgen_CIJ,
14201 ovl.fmt.RIEv3.r1,
14202 ovl.fmt.RIEv3.m3,
14203 ovl.fmt.RIEv3.i4,
14204 ovl.fmt.RIEv3.i2); goto ok;
14205 case 0xec000000007fULL: s390_format_RIE_RUPU(s390_irgen_CLIJ,
14206 ovl.fmt.RIEv3.r1,
14207 ovl.fmt.RIEv3.m3,
14208 ovl.fmt.RIEv3.i4,
14209 ovl.fmt.RIEv3.i2); goto ok;
14210 case 0xec00000000d8ULL: s390_format_RIE_RRI0(s390_irgen_AHIK, ovl.fmt.RIE.r1,
14211 ovl.fmt.RIE.r3, ovl.fmt.RIE.i2);
14212 goto ok;
14213 case 0xec00000000d9ULL: s390_format_RIE_RRI0(s390_irgen_AGHIK,
14214 ovl.fmt.RIE.r1, ovl.fmt.RIE.r3,
14215 ovl.fmt.RIE.i2); goto ok;
14216 case 0xec00000000daULL: s390_format_RIE_RRI0(s390_irgen_ALHSIK,
14217 ovl.fmt.RIE.r1, ovl.fmt.RIE.r3,
14218 ovl.fmt.RIE.i2); goto ok;
14219 case 0xec00000000dbULL: s390_format_RIE_RRI0(s390_irgen_ALGHSIK,
14220 ovl.fmt.RIE.r1, ovl.fmt.RIE.r3,
14221 ovl.fmt.RIE.i2); goto ok;
14222 case 0xec00000000e4ULL: s390_format_RRS(s390_irgen_CGRB, ovl.fmt.RRS.r1,
14223 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
14224 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
14225 goto ok;
14226 case 0xec00000000e5ULL: s390_format_RRS(s390_irgen_CLGRB, ovl.fmt.RRS.r1,
14227 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
14228 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
14229 goto ok;
14230 case 0xec00000000f6ULL: s390_format_RRS(s390_irgen_CRB, ovl.fmt.RRS.r1,
14231 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
14232 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
14233 goto ok;
14234 case 0xec00000000f7ULL: s390_format_RRS(s390_irgen_CLRB, ovl.fmt.RRS.r1,
14235 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
14236 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
14237 goto ok;
14238 case 0xec00000000fcULL: s390_format_RIS_RURDI(s390_irgen_CGIB,
14239 ovl.fmt.RIS.r1, ovl.fmt.RIS.m3,
14240 ovl.fmt.RIS.b4, ovl.fmt.RIS.d4,
14241 ovl.fmt.RIS.i2); goto ok;
14242 case 0xec00000000fdULL: s390_format_RIS_RURDU(s390_irgen_CLGIB,
14243 ovl.fmt.RIS.r1, ovl.fmt.RIS.m3,
14244 ovl.fmt.RIS.b4, ovl.fmt.RIS.d4,
14245 ovl.fmt.RIS.i2); goto ok;
14246 case 0xec00000000feULL: s390_format_RIS_RURDI(s390_irgen_CIB, ovl.fmt.RIS.r1,
14247 ovl.fmt.RIS.m3, ovl.fmt.RIS.b4,
14248 ovl.fmt.RIS.d4,
14249 ovl.fmt.RIS.i2); goto ok;
14250 case 0xec00000000ffULL: s390_format_RIS_RURDU(s390_irgen_CLIB,
14251 ovl.fmt.RIS.r1, ovl.fmt.RIS.m3,
14252 ovl.fmt.RIS.b4, ovl.fmt.RIS.d4,
14253 ovl.fmt.RIS.i2); goto ok;
14254 case 0xed0000000004ULL: s390_format_RXE_FRRD(s390_irgen_LDEB, ovl.fmt.RXE.r1,
14255 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14256 ovl.fmt.RXE.d2); goto ok;
14257 case 0xed0000000005ULL: s390_format_RXE_FRRD(s390_irgen_LXDB, ovl.fmt.RXE.r1,
14258 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14259 ovl.fmt.RXE.d2); goto ok;
14260 case 0xed0000000006ULL: s390_format_RXE_FRRD(s390_irgen_LXEB, ovl.fmt.RXE.r1,
14261 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14262 ovl.fmt.RXE.d2); goto ok;
14263 case 0xed0000000007ULL: /* MXDB */ goto unimplemented;
14264 case 0xed0000000008ULL: /* KEB */ goto unimplemented;
14265 case 0xed0000000009ULL: s390_format_RXE_FRRD(s390_irgen_CEB, ovl.fmt.RXE.r1,
14266 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14267 ovl.fmt.RXE.d2); goto ok;
14268 case 0xed000000000aULL: s390_format_RXE_FRRD(s390_irgen_AEB, ovl.fmt.RXE.r1,
14269 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14270 ovl.fmt.RXE.d2); goto ok;
14271 case 0xed000000000bULL: s390_format_RXE_FRRD(s390_irgen_SEB, ovl.fmt.RXE.r1,
14272 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14273 ovl.fmt.RXE.d2); goto ok;
14274 case 0xed000000000cULL: /* MDEB */ goto unimplemented;
14275 case 0xed000000000dULL: s390_format_RXE_FRRD(s390_irgen_DEB, ovl.fmt.RXE.r1,
14276 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14277 ovl.fmt.RXE.d2); goto ok;
14278 case 0xed000000000eULL: s390_format_RXF_FRRDF(s390_irgen_MAEB,
14279 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
14280 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
14281 ovl.fmt.RXF.r1); goto ok;
14282 case 0xed000000000fULL: s390_format_RXF_FRRDF(s390_irgen_MSEB,
14283 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
14284 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
14285 ovl.fmt.RXF.r1); goto ok;
14286 case 0xed0000000010ULL: s390_format_RXE_FRRD(s390_irgen_TCEB, ovl.fmt.RXE.r1,
14287 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14288 ovl.fmt.RXE.d2); goto ok;
14289 case 0xed0000000011ULL: s390_format_RXE_FRRD(s390_irgen_TCDB, ovl.fmt.RXE.r1,
14290 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14291 ovl.fmt.RXE.d2); goto ok;
14292 case 0xed0000000012ULL: s390_format_RXE_FRRD(s390_irgen_TCXB, ovl.fmt.RXE.r1,
14293 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14294 ovl.fmt.RXE.d2); goto ok;
14295 case 0xed0000000014ULL: s390_format_RXE_FRRD(s390_irgen_SQEB, ovl.fmt.RXE.r1,
14296 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14297 ovl.fmt.RXE.d2); goto ok;
14298 case 0xed0000000015ULL: s390_format_RXE_FRRD(s390_irgen_SQDB, ovl.fmt.RXE.r1,
14299 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14300 ovl.fmt.RXE.d2); goto ok;
14301 case 0xed0000000017ULL: s390_format_RXE_FRRD(s390_irgen_MEEB, ovl.fmt.RXE.r1,
14302 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14303 ovl.fmt.RXE.d2); goto ok;
14304 case 0xed0000000018ULL: /* KDB */ goto unimplemented;
14305 case 0xed0000000019ULL: s390_format_RXE_FRRD(s390_irgen_CDB, ovl.fmt.RXE.r1,
14306 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14307 ovl.fmt.RXE.d2); goto ok;
14308 case 0xed000000001aULL: s390_format_RXE_FRRD(s390_irgen_ADB, ovl.fmt.RXE.r1,
14309 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14310 ovl.fmt.RXE.d2); goto ok;
14311 case 0xed000000001bULL: s390_format_RXE_FRRD(s390_irgen_SDB, ovl.fmt.RXE.r1,
14312 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14313 ovl.fmt.RXE.d2); goto ok;
14314 case 0xed000000001cULL: s390_format_RXE_FRRD(s390_irgen_MDB, ovl.fmt.RXE.r1,
14315 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14316 ovl.fmt.RXE.d2); goto ok;
14317 case 0xed000000001dULL: s390_format_RXE_FRRD(s390_irgen_DDB, ovl.fmt.RXE.r1,
14318 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14319 ovl.fmt.RXE.d2); goto ok;
14320 case 0xed000000001eULL: s390_format_RXF_FRRDF(s390_irgen_MADB,
14321 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
14322 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
14323 ovl.fmt.RXF.r1); goto ok;
14324 case 0xed000000001fULL: s390_format_RXF_FRRDF(s390_irgen_MSDB,
14325 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
14326 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
14327 ovl.fmt.RXF.r1); goto ok;
14328 case 0xed0000000024ULL: /* LDE */ goto unimplemented;
14329 case 0xed0000000025ULL: /* LXD */ goto unimplemented;
14330 case 0xed0000000026ULL: /* LXE */ goto unimplemented;
14331 case 0xed000000002eULL: /* MAE */ goto unimplemented;
14332 case 0xed000000002fULL: /* MSE */ goto unimplemented;
14333 case 0xed0000000034ULL: /* SQE */ goto unimplemented;
14334 case 0xed0000000035ULL: /* SQD */ goto unimplemented;
14335 case 0xed0000000037ULL: /* MEE */ goto unimplemented;
14336 case 0xed0000000038ULL: /* MAYL */ goto unimplemented;
14337 case 0xed0000000039ULL: /* MYL */ goto unimplemented;
14338 case 0xed000000003aULL: /* MAY */ goto unimplemented;
14339 case 0xed000000003bULL: /* MY */ goto unimplemented;
14340 case 0xed000000003cULL: /* MAYH */ goto unimplemented;
14341 case 0xed000000003dULL: /* MYH */ goto unimplemented;
14342 case 0xed000000003eULL: /* MAD */ goto unimplemented;
14343 case 0xed000000003fULL: /* MSD */ goto unimplemented;
14344 case 0xed0000000040ULL: /* SLDT */ goto unimplemented;
14345 case 0xed0000000041ULL: /* SRDT */ goto unimplemented;
14346 case 0xed0000000048ULL: /* SLXT */ goto unimplemented;
14347 case 0xed0000000049ULL: /* SRXT */ goto unimplemented;
14348 case 0xed0000000050ULL: /* TDCET */ goto unimplemented;
14349 case 0xed0000000051ULL: /* TDGET */ goto unimplemented;
14350 case 0xed0000000054ULL: /* TDCDT */ goto unimplemented;
14351 case 0xed0000000055ULL: /* TDGDT */ goto unimplemented;
14352 case 0xed0000000058ULL: /* TDCXT */ goto unimplemented;
14353 case 0xed0000000059ULL: /* TDGXT */ goto unimplemented;
14354 case 0xed0000000064ULL: s390_format_RXY_FRRD(s390_irgen_LEY, ovl.fmt.RXY.r1,
14355 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14356 ovl.fmt.RXY.dl2,
14357 ovl.fmt.RXY.dh2); goto ok;
14358 case 0xed0000000065ULL: s390_format_RXY_FRRD(s390_irgen_LDY, ovl.fmt.RXY.r1,
14359 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14360 ovl.fmt.RXY.dl2,
14361 ovl.fmt.RXY.dh2); goto ok;
14362 case 0xed0000000066ULL: s390_format_RXY_FRRD(s390_irgen_STEY, ovl.fmt.RXY.r1,
14363 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14364 ovl.fmt.RXY.dl2,
14365 ovl.fmt.RXY.dh2); goto ok;
14366 case 0xed0000000067ULL: s390_format_RXY_FRRD(s390_irgen_STDY, ovl.fmt.RXY.r1,
14367 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14368 ovl.fmt.RXY.dl2,
14369 ovl.fmt.RXY.dh2); goto ok;
14370 }
14371
14372 switch (((ovl.value >> 16) & 0xff0f00000000ULL) >> 32) {
14373 case 0xc000ULL: s390_format_RIL_RP(s390_irgen_LARL, ovl.fmt.RIL.r1,
14374 ovl.fmt.RIL.i2); goto ok;
14375 case 0xc001ULL: s390_format_RIL_RI(s390_irgen_LGFI, ovl.fmt.RIL.r1,
14376 ovl.fmt.RIL.i2); goto ok;
14377 case 0xc004ULL: s390_format_RIL(s390_irgen_BRCL, ovl.fmt.RIL.r1,
14378 ovl.fmt.RIL.i2); goto ok;
14379 case 0xc005ULL: s390_format_RIL_RP(s390_irgen_BRASL, ovl.fmt.RIL.r1,
14380 ovl.fmt.RIL.i2); goto ok;
14381 case 0xc006ULL: s390_format_RIL_RU(s390_irgen_XIHF, ovl.fmt.RIL.r1,
14382 ovl.fmt.RIL.i2); goto ok;
14383 case 0xc007ULL: s390_format_RIL_RU(s390_irgen_XILF, ovl.fmt.RIL.r1,
14384 ovl.fmt.RIL.i2); goto ok;
14385 case 0xc008ULL: s390_format_RIL_RU(s390_irgen_IIHF, ovl.fmt.RIL.r1,
14386 ovl.fmt.RIL.i2); goto ok;
14387 case 0xc009ULL: s390_format_RIL_RU(s390_irgen_IILF, ovl.fmt.RIL.r1,
14388 ovl.fmt.RIL.i2); goto ok;
14389 case 0xc00aULL: s390_format_RIL_RU(s390_irgen_NIHF, ovl.fmt.RIL.r1,
14390 ovl.fmt.RIL.i2); goto ok;
14391 case 0xc00bULL: s390_format_RIL_RU(s390_irgen_NILF, ovl.fmt.RIL.r1,
14392 ovl.fmt.RIL.i2); goto ok;
14393 case 0xc00cULL: s390_format_RIL_RU(s390_irgen_OIHF, ovl.fmt.RIL.r1,
14394 ovl.fmt.RIL.i2); goto ok;
14395 case 0xc00dULL: s390_format_RIL_RU(s390_irgen_OILF, ovl.fmt.RIL.r1,
14396 ovl.fmt.RIL.i2); goto ok;
14397 case 0xc00eULL: s390_format_RIL_RU(s390_irgen_LLIHF, ovl.fmt.RIL.r1,
14398 ovl.fmt.RIL.i2); goto ok;
14399 case 0xc00fULL: s390_format_RIL_RU(s390_irgen_LLILF, ovl.fmt.RIL.r1,
14400 ovl.fmt.RIL.i2); goto ok;
14401 case 0xc200ULL: s390_format_RIL_RI(s390_irgen_MSGFI, ovl.fmt.RIL.r1,
14402 ovl.fmt.RIL.i2); goto ok;
14403 case 0xc201ULL: s390_format_RIL_RI(s390_irgen_MSFI, ovl.fmt.RIL.r1,
14404 ovl.fmt.RIL.i2); goto ok;
14405 case 0xc204ULL: s390_format_RIL_RU(s390_irgen_SLGFI, ovl.fmt.RIL.r1,
14406 ovl.fmt.RIL.i2); goto ok;
14407 case 0xc205ULL: s390_format_RIL_RU(s390_irgen_SLFI, ovl.fmt.RIL.r1,
14408 ovl.fmt.RIL.i2); goto ok;
14409 case 0xc208ULL: s390_format_RIL_RI(s390_irgen_AGFI, ovl.fmt.RIL.r1,
14410 ovl.fmt.RIL.i2); goto ok;
14411 case 0xc209ULL: s390_format_RIL_RI(s390_irgen_AFI, ovl.fmt.RIL.r1,
14412 ovl.fmt.RIL.i2); goto ok;
14413 case 0xc20aULL: s390_format_RIL_RU(s390_irgen_ALGFI, ovl.fmt.RIL.r1,
14414 ovl.fmt.RIL.i2); goto ok;
14415 case 0xc20bULL: s390_format_RIL_RU(s390_irgen_ALFI, ovl.fmt.RIL.r1,
14416 ovl.fmt.RIL.i2); goto ok;
14417 case 0xc20cULL: s390_format_RIL_RI(s390_irgen_CGFI, ovl.fmt.RIL.r1,
14418 ovl.fmt.RIL.i2); goto ok;
14419 case 0xc20dULL: s390_format_RIL_RI(s390_irgen_CFI, ovl.fmt.RIL.r1,
14420 ovl.fmt.RIL.i2); goto ok;
14421 case 0xc20eULL: s390_format_RIL_RU(s390_irgen_CLGFI, ovl.fmt.RIL.r1,
14422 ovl.fmt.RIL.i2); goto ok;
14423 case 0xc20fULL: s390_format_RIL_RU(s390_irgen_CLFI, ovl.fmt.RIL.r1,
14424 ovl.fmt.RIL.i2); goto ok;
14425 case 0xc402ULL: s390_format_RIL_RP(s390_irgen_LLHRL, ovl.fmt.RIL.r1,
14426 ovl.fmt.RIL.i2); goto ok;
14427 case 0xc404ULL: s390_format_RIL_RP(s390_irgen_LGHRL, ovl.fmt.RIL.r1,
14428 ovl.fmt.RIL.i2); goto ok;
14429 case 0xc405ULL: s390_format_RIL_RP(s390_irgen_LHRL, ovl.fmt.RIL.r1,
14430 ovl.fmt.RIL.i2); goto ok;
14431 case 0xc406ULL: s390_format_RIL_RP(s390_irgen_LLGHRL, ovl.fmt.RIL.r1,
14432 ovl.fmt.RIL.i2); goto ok;
14433 case 0xc407ULL: s390_format_RIL_RP(s390_irgen_STHRL, ovl.fmt.RIL.r1,
14434 ovl.fmt.RIL.i2); goto ok;
14435 case 0xc408ULL: s390_format_RIL_RP(s390_irgen_LGRL, ovl.fmt.RIL.r1,
14436 ovl.fmt.RIL.i2); goto ok;
14437 case 0xc40bULL: s390_format_RIL_RP(s390_irgen_STGRL, ovl.fmt.RIL.r1,
14438 ovl.fmt.RIL.i2); goto ok;
14439 case 0xc40cULL: s390_format_RIL_RP(s390_irgen_LGFRL, ovl.fmt.RIL.r1,
14440 ovl.fmt.RIL.i2); goto ok;
14441 case 0xc40dULL: s390_format_RIL_RP(s390_irgen_LRL, ovl.fmt.RIL.r1,
14442 ovl.fmt.RIL.i2); goto ok;
14443 case 0xc40eULL: s390_format_RIL_RP(s390_irgen_LLGFRL, ovl.fmt.RIL.r1,
14444 ovl.fmt.RIL.i2); goto ok;
14445 case 0xc40fULL: s390_format_RIL_RP(s390_irgen_STRL, ovl.fmt.RIL.r1,
14446 ovl.fmt.RIL.i2); goto ok;
14447 case 0xc600ULL: s390_format_RIL_RP(s390_irgen_EXRL, ovl.fmt.RIL.r1,
14448 ovl.fmt.RIL.i2); goto ok;
14449 case 0xc602ULL: s390_format_RIL_UP(s390_irgen_PFDRL, ovl.fmt.RIL.r1,
14450 ovl.fmt.RIL.i2); goto ok;
14451 case 0xc604ULL: s390_format_RIL_RP(s390_irgen_CGHRL, ovl.fmt.RIL.r1,
14452 ovl.fmt.RIL.i2); goto ok;
14453 case 0xc605ULL: s390_format_RIL_RP(s390_irgen_CHRL, ovl.fmt.RIL.r1,
14454 ovl.fmt.RIL.i2); goto ok;
14455 case 0xc606ULL: s390_format_RIL_RP(s390_irgen_CLGHRL, ovl.fmt.RIL.r1,
14456 ovl.fmt.RIL.i2); goto ok;
14457 case 0xc607ULL: s390_format_RIL_RP(s390_irgen_CLHRL, ovl.fmt.RIL.r1,
14458 ovl.fmt.RIL.i2); goto ok;
14459 case 0xc608ULL: s390_format_RIL_RP(s390_irgen_CGRL, ovl.fmt.RIL.r1,
14460 ovl.fmt.RIL.i2); goto ok;
14461 case 0xc60aULL: s390_format_RIL_RP(s390_irgen_CLGRL, ovl.fmt.RIL.r1,
14462 ovl.fmt.RIL.i2); goto ok;
14463 case 0xc60cULL: s390_format_RIL_RP(s390_irgen_CGFRL, ovl.fmt.RIL.r1,
14464 ovl.fmt.RIL.i2); goto ok;
14465 case 0xc60dULL: s390_format_RIL_RP(s390_irgen_CRL, ovl.fmt.RIL.r1,
14466 ovl.fmt.RIL.i2); goto ok;
14467 case 0xc60eULL: s390_format_RIL_RP(s390_irgen_CLGFRL, ovl.fmt.RIL.r1,
14468 ovl.fmt.RIL.i2); goto ok;
14469 case 0xc60fULL: s390_format_RIL_RP(s390_irgen_CLRL, ovl.fmt.RIL.r1,
14470 ovl.fmt.RIL.i2); goto ok;
14471 case 0xc800ULL: /* MVCOS */ goto unimplemented;
14472 case 0xc801ULL: /* ECTG */ goto unimplemented;
14473 case 0xc802ULL: /* CSST */ goto unimplemented;
14474 case 0xc804ULL: /* LPD */ goto unimplemented;
14475 case 0xc805ULL: /* LPDG */ goto unimplemented;
14476 case 0xcc06ULL: /* BRCTH */ goto unimplemented;
14477 case 0xcc08ULL: s390_format_RIL_RI(s390_irgen_AIH, ovl.fmt.RIL.r1,
14478 ovl.fmt.RIL.i2); goto ok;
14479 case 0xcc0aULL: s390_format_RIL_RI(s390_irgen_ALSIH, ovl.fmt.RIL.r1,
14480 ovl.fmt.RIL.i2); goto ok;
14481 case 0xcc0bULL: s390_format_RIL_RI(s390_irgen_ALSIHN, ovl.fmt.RIL.r1,
14482 ovl.fmt.RIL.i2); goto ok;
14483 case 0xcc0dULL: s390_format_RIL_RI(s390_irgen_CIH, ovl.fmt.RIL.r1,
14484 ovl.fmt.RIL.i2); goto ok;
14485 case 0xcc0fULL: s390_format_RIL_RU(s390_irgen_CLIH, ovl.fmt.RIL.r1,
14486 ovl.fmt.RIL.i2); goto ok;
14487 }
14488
14489 switch (((ovl.value >> 16) & 0xff0000000000ULL) >> 40) {
14490 case 0xd0ULL: /* TRTR */ goto unimplemented;
14491 case 0xd1ULL: /* MVN */ goto unimplemented;
14492 case 0xd2ULL: s390_format_SS_L0RDRD(s390_irgen_MVC, ovl.fmt.SS.l,
14493 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
14494 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
14495 case 0xd3ULL: /* MVZ */ goto unimplemented;
14496 case 0xd4ULL: s390_format_SS_L0RDRD(s390_irgen_NC, ovl.fmt.SS.l,
14497 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
14498 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
14499 case 0xd5ULL: s390_format_SS_L0RDRD(s390_irgen_CLC, ovl.fmt.SS.l,
14500 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
14501 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
14502 case 0xd6ULL: s390_format_SS_L0RDRD(s390_irgen_OC, ovl.fmt.SS.l,
14503 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
14504 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
sewardjb63967e2011-03-24 08:50:04 +000014505 case 0xd7ULL:
14506 if (ovl.fmt.SS.b1 == ovl.fmt.SS.b2 && ovl.fmt.SS.d1 == ovl.fmt.SS.d2)
14507 s390_irgen_XC_sameloc(ovl.fmt.SS.l, ovl.fmt.SS.b1, ovl.fmt.SS.d1);
14508 else
14509 s390_format_SS_L0RDRD(s390_irgen_XC, ovl.fmt.SS.l,
14510 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
14511 ovl.fmt.SS.b2, ovl.fmt.SS.d2);
14512 goto ok;
sewardj2019a972011-03-07 16:04:07 +000014513 case 0xd9ULL: /* MVCK */ goto unimplemented;
14514 case 0xdaULL: /* MVCP */ goto unimplemented;
14515 case 0xdbULL: /* MVCS */ goto unimplemented;
florian730448f2012-02-04 17:07:07 +000014516 case 0xdcULL: s390_format_SS_L0RDRD(s390_irgen_TR, ovl.fmt.SS.l,
14517 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
14518 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014519 case 0xddULL: /* TRT */ goto unimplemented;
14520 case 0xdeULL: /* ED */ goto unimplemented;
14521 case 0xdfULL: /* EDMK */ goto unimplemented;
14522 case 0xe1ULL: /* PKU */ goto unimplemented;
14523 case 0xe2ULL: /* UNPKU */ goto unimplemented;
14524 case 0xe8ULL: /* MVCIN */ goto unimplemented;
14525 case 0xe9ULL: /* PKA */ goto unimplemented;
14526 case 0xeaULL: /* UNPKA */ goto unimplemented;
14527 case 0xeeULL: /* PLO */ goto unimplemented;
14528 case 0xefULL: /* LMD */ goto unimplemented;
14529 case 0xf0ULL: /* SRP */ goto unimplemented;
14530 case 0xf1ULL: /* MVO */ goto unimplemented;
14531 case 0xf2ULL: /* PACK */ goto unimplemented;
14532 case 0xf3ULL: /* UNPK */ goto unimplemented;
14533 case 0xf8ULL: /* ZAP */ goto unimplemented;
14534 case 0xf9ULL: /* CP */ goto unimplemented;
14535 case 0xfaULL: /* AP */ goto unimplemented;
14536 case 0xfbULL: /* SP */ goto unimplemented;
14537 case 0xfcULL: /* MP */ goto unimplemented;
14538 case 0xfdULL: /* DP */ goto unimplemented;
14539 }
14540
14541 switch (((ovl.value >> 16) & 0xffff00000000ULL) >> 32) {
14542 case 0xe500ULL: /* LASP */ goto unimplemented;
14543 case 0xe501ULL: /* TPROT */ goto unimplemented;
14544 case 0xe502ULL: /* STRAG */ goto unimplemented;
14545 case 0xe50eULL: /* MVCSK */ goto unimplemented;
14546 case 0xe50fULL: /* MVCDK */ goto unimplemented;
14547 case 0xe544ULL: s390_format_SIL_RDI(s390_irgen_MVHHI, ovl.fmt.SIL.b1,
14548 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14549 goto ok;
14550 case 0xe548ULL: s390_format_SIL_RDI(s390_irgen_MVGHI, ovl.fmt.SIL.b1,
14551 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14552 goto ok;
14553 case 0xe54cULL: s390_format_SIL_RDI(s390_irgen_MVHI, ovl.fmt.SIL.b1,
14554 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14555 goto ok;
14556 case 0xe554ULL: s390_format_SIL_RDI(s390_irgen_CHHSI, ovl.fmt.SIL.b1,
14557 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14558 goto ok;
14559 case 0xe555ULL: s390_format_SIL_RDU(s390_irgen_CLHHSI, ovl.fmt.SIL.b1,
14560 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14561 goto ok;
14562 case 0xe558ULL: s390_format_SIL_RDI(s390_irgen_CGHSI, ovl.fmt.SIL.b1,
14563 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14564 goto ok;
14565 case 0xe559ULL: s390_format_SIL_RDU(s390_irgen_CLGHSI, ovl.fmt.SIL.b1,
14566 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14567 goto ok;
14568 case 0xe55cULL: s390_format_SIL_RDI(s390_irgen_CHSI, ovl.fmt.SIL.b1,
14569 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14570 goto ok;
14571 case 0xe55dULL: s390_format_SIL_RDU(s390_irgen_CLFHSI, ovl.fmt.SIL.b1,
14572 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14573 goto ok;
14574 }
14575
14576 return S390_DECODE_UNKNOWN_INSN;
14577
14578ok:
14579 return S390_DECODE_OK;
14580
14581unimplemented:
14582 return S390_DECODE_UNIMPLEMENTED_INSN;
14583}
14584
14585/* Handle "special" instructions. */
14586static s390_decode_t
14587s390_decode_special_and_irgen(UChar *bytes)
14588{
14589 s390_decode_t status = S390_DECODE_OK;
14590
14591 /* Got a "Special" instruction preamble. Which one is it? */
14592 if (bytes[0] == 0x18 && bytes[1] == 0x22 /* lr %r2, %r2 */) {
14593 s390_irgen_client_request();
14594 } else if (bytes[0] == 0x18 && bytes[1] == 0x33 /* lr %r3, %r3 */) {
14595 s390_irgen_guest_NRADDR();
14596 } else if (bytes[0] == 0x18 && bytes[1] == 0x44 /* lr %r4, %r4 */) {
14597 s390_irgen_call_noredir();
florian2245ce92012-08-28 16:49:30 +000014598 } else if (bytes[0] == 0x18 && bytes[1] == 0x55 /* lr %r5, %r5 */) {
14599 vex_inject_ir(irsb, Iend_BE);
14600
14601 /* Invalidate the current insn. The reason is that the IRop we're
14602 injecting here can change. In which case the translation has to
14603 be redone. For ease of handling, we simply invalidate all the
14604 time. */
14605 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TISTART),
14606 mkU64(guest_IA_curr_instr)));
14607 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TILEN),
14608 mkU64(guest_IA_next_instr - guest_IA_curr_instr)));
14609 vassert(guest_IA_next_instr - guest_IA_curr_instr ==
14610 S390_SPECIAL_OP_PREAMBLE_SIZE + S390_SPECIAL_OP_SIZE);
14611
14612 put_IA(mkaddr_expr(guest_IA_next_instr));
14613 dis_res->whatNext = Dis_StopHere;
14614 dis_res->jk_StopHere = Ijk_TInval;
sewardj2019a972011-03-07 16:04:07 +000014615 } else {
14616 /* We don't know what it is. */
14617 return S390_DECODE_UNKNOWN_SPECIAL_INSN;
14618 }
14619
14620 dis_res->len = S390_SPECIAL_OP_PREAMBLE_SIZE + S390_SPECIAL_OP_SIZE;
14621
14622 return status;
14623}
14624
14625
14626/* Function returns # bytes that were decoded or 0 in case of failure */
florianb4df7682011-07-05 02:09:01 +000014627static UInt
sewardj2019a972011-03-07 16:04:07 +000014628s390_decode_and_irgen(UChar *bytes, UInt insn_length, DisResult *dres)
14629{
14630 s390_decode_t status;
14631
14632 dis_res = dres;
14633
14634 /* Spot the 8-byte preamble: 18ff lr r15,r15
14635 1811 lr r1,r1
14636 1822 lr r2,r2
14637 1833 lr r3,r3 */
14638 if (bytes[ 0] == 0x18 && bytes[ 1] == 0xff && bytes[ 2] == 0x18 &&
14639 bytes[ 3] == 0x11 && bytes[ 4] == 0x18 && bytes[ 5] == 0x22 &&
14640 bytes[ 6] == 0x18 && bytes[ 7] == 0x33) {
14641
14642 /* Handle special instruction that follows that preamble. */
14643 if (0) vex_printf("special function handling...\n");
florian2c8ed942011-08-01 22:07:51 +000014644
14645 insn_length = S390_SPECIAL_OP_PREAMBLE_SIZE + S390_SPECIAL_OP_SIZE;
14646 guest_IA_next_instr = guest_IA_curr_instr + insn_length;
14647
14648 status =
14649 s390_decode_special_and_irgen(bytes + S390_SPECIAL_OP_PREAMBLE_SIZE);
sewardj2019a972011-03-07 16:04:07 +000014650 } else {
14651 /* Handle normal instructions. */
14652 switch (insn_length) {
14653 case 2:
14654 status = s390_decode_2byte_and_irgen(bytes);
14655 break;
14656
14657 case 4:
14658 status = s390_decode_4byte_and_irgen(bytes);
14659 break;
14660
14661 case 6:
14662 status = s390_decode_6byte_and_irgen(bytes);
14663 break;
14664
14665 default:
14666 status = S390_DECODE_ERROR;
14667 break;
14668 }
14669 }
florian5fcbba22011-07-27 20:40:22 +000014670 /* If next instruction is execute, stop here */
florianf9e1ed72012-04-17 02:41:56 +000014671 if (dis_res->whatNext == Dis_Continue && bytes[insn_length] == 0x44) {
14672 put_IA(mkaddr_expr(guest_IA_next_instr));
sewardj2019a972011-03-07 16:04:07 +000014673 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +000014674 dis_res->jk_StopHere = Ijk_Boring;
sewardj2019a972011-03-07 16:04:07 +000014675 }
14676
14677 if (status == S390_DECODE_OK) return insn_length; /* OK */
14678
14679 /* Decoding failed somehow */
14680 vex_printf("vex s390->IR: ");
14681 switch (status) {
14682 case S390_DECODE_UNKNOWN_INSN:
14683 vex_printf("unknown insn: ");
14684 break;
14685
14686 case S390_DECODE_UNIMPLEMENTED_INSN:
14687 vex_printf("unimplemented insn: ");
14688 break;
14689
14690 case S390_DECODE_UNKNOWN_SPECIAL_INSN:
14691 vex_printf("unimplemented special insn: ");
14692 break;
14693
14694 default:
14695 case S390_DECODE_ERROR:
14696 vex_printf("decoding error: ");
14697 break;
14698 }
14699
14700 vex_printf("%02x%02x", bytes[0], bytes[1]);
14701 if (insn_length > 2) {
14702 vex_printf(" %02x%02x", bytes[2], bytes[3]);
14703 }
14704 if (insn_length > 4) {
14705 vex_printf(" %02x%02x", bytes[4], bytes[5]);
14706 }
14707 vex_printf("\n");
14708
14709 return 0; /* Failed */
14710}
14711
14712
sewardj2019a972011-03-07 16:04:07 +000014713/* Disassemble a single instruction INSN into IR. */
14714static DisResult
florian420c5012011-07-22 02:12:28 +000014715disInstr_S390_WRK(UChar *insn)
sewardj2019a972011-03-07 16:04:07 +000014716{
14717 UChar byte;
14718 UInt insn_length;
14719 DisResult dres;
14720
14721 /* ---------------------------------------------------- */
14722 /* --- Compute instruction length -- */
14723 /* ---------------------------------------------------- */
14724
14725 /* Get the first byte of the insn. */
14726 byte = insn[0];
14727
14728 /* The leftmost two bits (0:1) encode the length of the insn in bytes.
14729 00 -> 2 bytes, 01 -> 4 bytes, 10 -> 4 bytes, 11 -> 6 bytes. */
14730 insn_length = ((((byte >> 6) + 1) >> 1) + 1) << 1;
14731
14732 guest_IA_next_instr = guest_IA_curr_instr + insn_length;
14733
14734 /* ---------------------------------------------------- */
14735 /* --- Initialise the DisResult data -- */
14736 /* ---------------------------------------------------- */
14737 dres.whatNext = Dis_Continue;
14738 dres.len = insn_length;
14739 dres.continueAt = 0;
florian8844a632012-04-13 04:04:06 +000014740 dres.jk_StopHere = Ijk_INVALID;
sewardj2019a972011-03-07 16:04:07 +000014741
floriana99f20e2011-07-17 14:16:41 +000014742 /* fixs390: consider chasing of conditional jumps */
14743
sewardj2019a972011-03-07 16:04:07 +000014744 /* Normal and special instruction handling starts here. */
14745 if (s390_decode_and_irgen(insn, insn_length, &dres) == 0) {
14746 /* All decode failures end up here. The decoder has already issued an
14747 error message.
14748 Tell the dispatcher that this insn cannot be decoded, and so has
florian342e01a2012-07-26 02:37:49 +000014749 not been executed, and (is currently) the next to be executed.
14750 The insn address in the guest state needs to be set to
14751 guest_IA_curr_instr, otherwise the complaint will report an
14752 incorrect address. */
14753 put_IA(mkaddr_expr(guest_IA_curr_instr));
sewardj2019a972011-03-07 16:04:07 +000014754
florian8844a632012-04-13 04:04:06 +000014755 dres.whatNext = Dis_StopHere;
14756 dres.jk_StopHere = Ijk_NoDecode;
14757 dres.continueAt = 0;
14758 dres.len = 0;
14759 } else {
14760 /* Decode success */
14761 switch (dres.whatNext) {
14762 case Dis_Continue:
florian8559e412012-04-19 14:23:48 +000014763 put_IA(mkaddr_expr(guest_IA_next_instr));
florian8844a632012-04-13 04:04:06 +000014764 break;
14765 case Dis_ResteerU:
14766 case Dis_ResteerC:
14767 put_IA(mkaddr_expr(dres.continueAt));
14768 break;
14769 case Dis_StopHere:
florian4b8efad2012-09-02 18:07:08 +000014770 if (dres.jk_StopHere == Ijk_EmWarn ||
14771 dres.jk_StopHere == Ijk_EmFail) {
14772 /* We assume here, that emulation warnings are not given for
14773 insns that transfer control. There is no good way to
14774 do that. */
14775 put_IA(mkaddr_expr(guest_IA_next_instr));
14776 }
florian8844a632012-04-13 04:04:06 +000014777 break;
14778 default:
14779 vassert(0);
14780 }
sewardj2019a972011-03-07 16:04:07 +000014781 }
14782
14783 return dres;
14784}
14785
14786
14787/*------------------------------------------------------------*/
14788/*--- Top-level fn ---*/
14789/*------------------------------------------------------------*/
14790
14791/* Disassemble a single instruction into IR. The instruction
14792 is located in host memory at &guest_code[delta]. */
14793
14794DisResult
14795disInstr_S390(IRSB *irsb_IN,
sewardj2019a972011-03-07 16:04:07 +000014796 Bool (*resteerOkFn)(void *, Addr64),
14797 Bool resteerCisOk,
14798 void *callback_opaque,
14799 UChar *guest_code,
14800 Long delta,
14801 Addr64 guest_IP,
14802 VexArch guest_arch,
14803 VexArchInfo *archinfo,
14804 VexAbiInfo *abiinfo,
14805 Bool host_bigendian)
14806{
14807 vassert(guest_arch == VexArchS390X);
14808
14809 /* The instruction decoder requires a big-endian machine. */
14810 vassert(host_bigendian == True);
14811
14812 /* Set globals (see top of this file) */
14813 guest_IA_curr_instr = guest_IP;
sewardj2019a972011-03-07 16:04:07 +000014814 irsb = irsb_IN;
florian420c5012011-07-22 02:12:28 +000014815 resteer_fn = resteerOkFn;
14816 resteer_data = callback_opaque;
sewardj2019a972011-03-07 16:04:07 +000014817
florian420c5012011-07-22 02:12:28 +000014818 return disInstr_S390_WRK(guest_code + delta);
sewardj2019a972011-03-07 16:04:07 +000014819}
14820
14821/*---------------------------------------------------------------*/
14822/*--- end guest_s390_toIR.c ---*/
14823/*---------------------------------------------------------------*/