blob: d796171e77e31cac1124675c5b4f388e8fb2c7fe [file] [log] [blame]
sewardj2019a972011-03-07 16:04:07 +00001/* -*- mode: C; c-basic-offset: 3; -*- */
2
3/*---------------------------------------------------------------*/
4/*--- begin guest_s390_toIR.c ---*/
5/*---------------------------------------------------------------*/
6
7/*
8 This file is part of Valgrind, a dynamic binary instrumentation
9 framework.
10
florian61f23c12012-08-06 18:33:21 +000011 Copyright IBM Corp. 2010-2012
sewardj2019a972011-03-07 16:04:07 +000012
13 This program is free software; you can redistribute it and/or
14 modify it under the terms of the GNU General Public License as
15 published by the Free Software Foundation; either version 2 of the
16 License, or (at your option) any later version.
17
18 This program is distributed in the hope that it will be useful, but
19 WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 General Public License for more details.
22
23 You should have received a copy of the GNU General Public License
24 along with this program; if not, write to the Free Software
25 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
26 02110-1301, USA.
27
28 The GNU General Public License is contained in the file COPYING.
29*/
30
31/* Contributed by Florian Krohm and Christian Borntraeger */
32
33/* Translates s390 code to IR. */
34
35#include "libvex_basictypes.h"
36#include "libvex_ir.h"
sewardj2019a972011-03-07 16:04:07 +000037#include "libvex.h" /* needed for bb_to_IR.h */
florian933065d2011-07-11 01:48:02 +000038#include "libvex_s390x_common.h"
sewardj2019a972011-03-07 16:04:07 +000039#include "main_util.h" /* vassert */
40#include "main_globals.h" /* vex_traceflags */
41#include "guest_generic_bb_to_IR.h" /* DisResult */
42#include "guest_s390_defs.h" /* prototypes for this file's functions */
43#include "host_s390_disasm.h"
44#include "host_s390_defs.h" /* S390_ROUND_xyzzy */
45
sewardj2019a972011-03-07 16:04:07 +000046
47/*------------------------------------------------------------*/
florianb4df7682011-07-05 02:09:01 +000048/*--- Forward declarations ---*/
49/*------------------------------------------------------------*/
50static UInt s390_decode_and_irgen(UChar *, UInt, DisResult *);
florianb0bf6602012-05-05 00:01:16 +000051static void s390_irgen_xonc(IROp, IRTemp, IRTemp, IRTemp);
florian79e839e2012-05-05 02:20:30 +000052static void s390_irgen_CLC_EX(IRTemp, IRTemp, IRTemp);
florianb4df7682011-07-05 02:09:01 +000053
54
55/*------------------------------------------------------------*/
sewardj2019a972011-03-07 16:04:07 +000056/*--- Globals ---*/
57/*------------------------------------------------------------*/
58
59/* The IRSB* into which we're generating code. */
60static IRSB *irsb;
61
62/* The guest address for the instruction currently being
63 translated. */
64static Addr64 guest_IA_curr_instr;
65
66/* The guest address for the instruction following the current instruction. */
67static Addr64 guest_IA_next_instr;
68
69/* Result of disassembly step. */
70static DisResult *dis_res;
71
floriana64c2432011-07-16 02:11:50 +000072/* Resteer function and callback data */
73static Bool (*resteer_fn)(void *, Addr64);
74static void *resteer_data;
75
sewardj2019a972011-03-07 16:04:07 +000076/* The last seen execute target instruction */
77ULong last_execute_target;
78
79/* The possible outcomes of a decoding operation */
80typedef enum {
81 S390_DECODE_OK,
82 S390_DECODE_UNKNOWN_INSN,
83 S390_DECODE_UNIMPLEMENTED_INSN,
84 S390_DECODE_UNKNOWN_SPECIAL_INSN,
85 S390_DECODE_ERROR
86} s390_decode_t;
87
florian428dfdd2012-03-27 03:09:49 +000088
sewardj2019a972011-03-07 16:04:07 +000089/*------------------------------------------------------------*/
90/*--- Helpers for constructing IR. ---*/
91/*------------------------------------------------------------*/
92
93/* Sign extend a value with the given number of bits. This is a
94 macro because it allows us to overload the type of the value.
95 Note that VALUE must have a signed type! */
96#undef sign_extend
97#define sign_extend(value,num_bits) \
98(((value) << (sizeof(__typeof__(value)) * 8 - (num_bits))) >> \
99 (sizeof(__typeof__(value)) * 8 - (num_bits)))
100
101
102/* Add a statement to the current irsb. */
103static __inline__ void
104stmt(IRStmt *st)
105{
106 addStmtToIRSB(irsb, st);
107}
108
109/* Allocate a new temporary of the given type. */
110static __inline__ IRTemp
111newTemp(IRType type)
112{
113 vassert(isPlausibleIRType(type));
114
115 return newIRTemp(irsb->tyenv, type);
116}
117
118/* Create an expression node for a temporary */
119static __inline__ IRExpr *
120mkexpr(IRTemp tmp)
121{
122 return IRExpr_RdTmp(tmp);
123}
124
florian8844a632012-04-13 04:04:06 +0000125/* Generate an expression node for an address. */
126static __inline__ IRExpr *
127mkaddr_expr(Addr64 addr)
128{
129 return IRExpr_Const(IRConst_U64(addr));
130}
131
sewardj2019a972011-03-07 16:04:07 +0000132/* Add a statement that assigns to a temporary */
133static __inline__ void
134assign(IRTemp dst, IRExpr *expr)
135{
136 stmt(IRStmt_WrTmp(dst, expr));
137}
138
florian8844a632012-04-13 04:04:06 +0000139/* Write an address into the guest_IA */
140static __inline__ void
141put_IA(IRExpr *address)
142{
143 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_IA), address));
144}
145
sewardj2019a972011-03-07 16:04:07 +0000146/* Create a temporary of the given type and assign the expression to it */
147static __inline__ IRTemp
148mktemp(IRType type, IRExpr *expr)
149{
150 IRTemp temp = newTemp(type);
151
152 assign(temp, expr);
153
154 return temp;
155}
156
157/* Create a unary expression */
158static __inline__ IRExpr *
159unop(IROp kind, IRExpr *op)
160{
161 return IRExpr_Unop(kind, op);
162}
163
164/* Create a binary expression */
165static __inline__ IRExpr *
166binop(IROp kind, IRExpr *op1, IRExpr *op2)
167{
168 return IRExpr_Binop(kind, op1, op2);
169}
170
171/* Create a ternary expression */
172static __inline__ IRExpr *
173triop(IROp kind, IRExpr *op1, IRExpr *op2, IRExpr *op3)
174{
175 return IRExpr_Triop(kind, op1, op2, op3);
176}
177
178/* Create a quaternary expression */
179static __inline__ IRExpr *
180qop(IROp kind, IRExpr *op1, IRExpr *op2, IRExpr *op3, IRExpr *op4)
181{
182 return IRExpr_Qop(kind, op1, op2, op3, op4);
183}
184
185/* Create an expression node for an 8-bit integer constant */
186static __inline__ IRExpr *
187mkU8(UInt value)
188{
189 vassert(value < 256);
190
191 return IRExpr_Const(IRConst_U8((UChar)value));
192}
193
194/* Create an expression node for a 16-bit integer constant */
195static __inline__ IRExpr *
196mkU16(UInt value)
197{
198 vassert(value < 65536);
199
200 return IRExpr_Const(IRConst_U16((UShort)value));
201}
202
203/* Create an expression node for a 32-bit integer constant */
204static __inline__ IRExpr *
205mkU32(UInt value)
206{
207 return IRExpr_Const(IRConst_U32(value));
208}
209
210/* Create an expression node for a 64-bit integer constant */
211static __inline__ IRExpr *
212mkU64(ULong value)
213{
214 return IRExpr_Const(IRConst_U64(value));
215}
216
217/* Create an expression node for a 32-bit floating point constant
218 whose value is given by a bit pattern. */
219static __inline__ IRExpr *
220mkF32i(UInt value)
221{
222 return IRExpr_Const(IRConst_F32i(value));
223}
224
225/* Create an expression node for a 32-bit floating point constant
226 whose value is given by a bit pattern. */
227static __inline__ IRExpr *
228mkF64i(ULong value)
229{
230 return IRExpr_Const(IRConst_F64i(value));
231}
232
233/* Little helper function for my sanity. ITE = if-then-else */
234static IRExpr *
235mkite(IRExpr *condition, IRExpr *iftrue, IRExpr *iffalse)
236{
237 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
238
239 return IRExpr_Mux0X(unop(Iop_1Uto8, condition), iffalse, iftrue);
240}
241
242/* Add a statement that stores DATA at ADDR. This is a big-endian machine. */
243static void __inline__
244store(IRExpr *addr, IRExpr *data)
245{
246 stmt(IRStmt_Store(Iend_BE, addr, data));
247}
248
249/* Create an expression that loads a TYPE sized value from ADDR.
250 This is a big-endian machine. */
251static __inline__ IRExpr *
252load(IRType type, IRExpr *addr)
253{
254 return IRExpr_Load(Iend_BE, type, addr);
255}
256
257/* Function call */
258static void
259call_function(IRExpr *callee_address)
260{
florian8844a632012-04-13 04:04:06 +0000261 put_IA(callee_address);
sewardj2019a972011-03-07 16:04:07 +0000262
florian8844a632012-04-13 04:04:06 +0000263 dis_res->whatNext = Dis_StopHere;
264 dis_res->jk_StopHere = Ijk_Call;
sewardj2019a972011-03-07 16:04:07 +0000265}
266
floriana64c2432011-07-16 02:11:50 +0000267/* Function call with known target. */
268static void
269call_function_and_chase(Addr64 callee_address)
270{
271 if (resteer_fn(resteer_data, callee_address)) {
272 dis_res->whatNext = Dis_ResteerU;
273 dis_res->continueAt = callee_address;
274 } else {
florian8844a632012-04-13 04:04:06 +0000275 put_IA(mkaddr_expr(callee_address));
276
floriana64c2432011-07-16 02:11:50 +0000277 dis_res->whatNext = Dis_StopHere;
florian8844a632012-04-13 04:04:06 +0000278 dis_res->jk_StopHere = Ijk_Call;
floriana64c2432011-07-16 02:11:50 +0000279 }
280}
281
sewardj2019a972011-03-07 16:04:07 +0000282/* Function return sequence */
283static void
284return_from_function(IRExpr *return_address)
285{
florian8844a632012-04-13 04:04:06 +0000286 put_IA(return_address);
sewardj2019a972011-03-07 16:04:07 +0000287
florian8844a632012-04-13 04:04:06 +0000288 dis_res->whatNext = Dis_StopHere;
289 dis_res->jk_StopHere = Ijk_Ret;
sewardj2019a972011-03-07 16:04:07 +0000290}
291
292/* A conditional branch whose target is not known at instrumentation time.
293
294 if (condition) goto computed_target;
295
296 Needs to be represented as:
297
298 if (! condition) goto next_instruction;
299 goto computed_target;
sewardj2019a972011-03-07 16:04:07 +0000300*/
301static void
florianf321da72012-07-21 20:32:57 +0000302if_condition_goto_computed(IRExpr *condition, IRExpr *target)
sewardj2019a972011-03-07 16:04:07 +0000303{
304 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
305
florianf321da72012-07-21 20:32:57 +0000306 condition = unop(Iop_Not1, condition);
307
florian8844a632012-04-13 04:04:06 +0000308 stmt(IRStmt_Exit(condition, Ijk_Boring, IRConst_U64(guest_IA_next_instr),
309 S390X_GUEST_OFFSET(guest_IA)));
sewardj2019a972011-03-07 16:04:07 +0000310
florian8844a632012-04-13 04:04:06 +0000311 put_IA(target);
sewardj2019a972011-03-07 16:04:07 +0000312
florian8844a632012-04-13 04:04:06 +0000313 dis_res->whatNext = Dis_StopHere;
314 dis_res->jk_StopHere = Ijk_Boring;
sewardj2019a972011-03-07 16:04:07 +0000315}
316
317/* A conditional branch whose target is known at instrumentation time. */
318static void
319if_condition_goto(IRExpr *condition, Addr64 target)
320{
321 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
322
florian8844a632012-04-13 04:04:06 +0000323 stmt(IRStmt_Exit(condition, Ijk_Boring, IRConst_U64(target),
324 S390X_GUEST_OFFSET(guest_IA)));
325
florian7346c7a2012-04-13 21:14:24 +0000326 put_IA(mkaddr_expr(guest_IA_next_instr));
florian8844a632012-04-13 04:04:06 +0000327
328 dis_res->whatNext = Dis_StopHere;
329 dis_res->jk_StopHere = Ijk_Boring;
sewardj2019a972011-03-07 16:04:07 +0000330}
331
332/* An unconditional branch. Target may or may not be known at instrumentation
333 time. */
334static void
335always_goto(IRExpr *target)
336{
florian8844a632012-04-13 04:04:06 +0000337 put_IA(target);
sewardj2019a972011-03-07 16:04:07 +0000338
florian8844a632012-04-13 04:04:06 +0000339 dis_res->whatNext = Dis_StopHere;
340 dis_res->jk_StopHere = Ijk_Boring;
sewardj2019a972011-03-07 16:04:07 +0000341}
342
florian8844a632012-04-13 04:04:06 +0000343
floriana64c2432011-07-16 02:11:50 +0000344/* An unconditional branch to a known target. */
345static void
346always_goto_and_chase(Addr64 target)
347{
348 if (resteer_fn(resteer_data, target)) {
florian8844a632012-04-13 04:04:06 +0000349 /* Follow into the target */
floriana64c2432011-07-16 02:11:50 +0000350 dis_res->whatNext = Dis_ResteerU;
351 dis_res->continueAt = target;
352 } else {
florian8844a632012-04-13 04:04:06 +0000353 put_IA(mkaddr_expr(target));
354
355 dis_res->whatNext = Dis_StopHere;
356 dis_res->jk_StopHere = Ijk_Boring;
floriana64c2432011-07-16 02:11:50 +0000357 }
358}
359
sewardj2019a972011-03-07 16:04:07 +0000360/* A system call */
361static void
362system_call(IRExpr *sysno)
363{
364 /* Store the system call number in the pseudo register. */
florian428dfdd2012-03-27 03:09:49 +0000365 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_SYSNO), sysno));
sewardj2019a972011-03-07 16:04:07 +0000366
sewardj69007022011-04-28 20:13:45 +0000367 /* Store the current IA into guest_IP_AT_SYSCALL. libvex_ir.h says so. */
florian428dfdd2012-03-27 03:09:49 +0000368 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_IP_AT_SYSCALL),
369 mkU64(guest_IA_curr_instr)));
sewardj2019a972011-03-07 16:04:07 +0000370
florian8844a632012-04-13 04:04:06 +0000371 put_IA(mkaddr_expr(guest_IA_next_instr));
372
sewardj2019a972011-03-07 16:04:07 +0000373 /* It's important that all ArchRegs carry their up-to-date value
374 at this point. So we declare an end-of-block here, which
375 forces any TempRegs caching ArchRegs to be flushed. */
florian8844a632012-04-13 04:04:06 +0000376 dis_res->whatNext = Dis_StopHere;
377 dis_res->jk_StopHere = Ijk_Sys_syscall;
sewardj2019a972011-03-07 16:04:07 +0000378}
379
florian6820ba52012-07-26 02:01:50 +0000380/* A side exit that branches back to the current insn if CONDITION is
381 true. Does not set DisResult. */
382static void
383iterate_if(IRExpr *condition)
384{
385 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
386
387 stmt(IRStmt_Exit(condition, Ijk_Boring, IRConst_U64(guest_IA_curr_instr),
388 S390X_GUEST_OFFSET(guest_IA)));
389}
390
391/* A side exit that branches back to the current insn.
392 Does not set DisResult. */
393static __inline__ void
394iterate(void)
395{
396 iterate_if(IRExpr_Const(IRConst_U1(True)));
397}
398
399/* A side exit that branches back to the insn immediately following the
400 current insn if CONDITION is true. Does not set DisResult. */
401static void
402next_insn_if(IRExpr *condition)
403{
404 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
405
406 stmt(IRStmt_Exit(condition, Ijk_Boring, IRConst_U64(guest_IA_next_instr),
407 S390X_GUEST_OFFSET(guest_IA)));
408}
409
410/* Convenience function to restart the current insn */
411static void
412restart_if(IRExpr *condition)
413{
414 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
415
416 stmt(IRStmt_Exit(condition, Ijk_TInval, IRConst_U64(guest_IA_curr_instr),
417 S390X_GUEST_OFFSET(guest_IA)));
418}
419
420/* Convenience function to yield to thread scheduler */
421static void
422yield_if(IRExpr *condition)
423{
424 stmt(IRStmt_Exit(condition, Ijk_Yield, IRConst_U64(guest_IA_next_instr),
425 S390X_GUEST_OFFSET(guest_IA)));
426}
427
sewardj2019a972011-03-07 16:04:07 +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
1400/* Extract the rounding mode from the guest FPC reg and encode it as an
1401 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 *
1413get_rounding_mode_from_fpc(void)
1414{
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),
1435 mkU32(S390_FPC_ROUND_NEAREST_EVEN));
1436
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) {
1452 case S390_ROUND_PER_FPC: rm = get_rounding_mode_from_fpc(); break;
1453 case S390_ROUND_NEAREST_AWAY: /* not supported */
1454 case S390_ROUND_PREPARE_SHORT: /* not supported */
1455 case S390_ROUND_NEAREST_EVEN: rm = mkU32(Irrm_NEAREST); break;
1456 case S390_ROUND_ZERO: rm = mkU32(Irrm_ZERO); break;
1457 case S390_ROUND_POSINF: rm = mkU32(Irrm_PosINF); break;
1458 case S390_ROUND_NEGINF: rm = mkU32(Irrm_NegINF); break;
1459 default:
1460 vpanic("encode_bfp_rounding_mode");
1461 }
1462
1463 return mktemp(Ity_I32, rm);
1464}
1465
1466/*------------------------------------------------------------*/
sewardj2019a972011-03-07 16:04:07 +00001467/*--- Build IR for formats ---*/
1468/*------------------------------------------------------------*/
1469static void
1470s390_format_I(HChar *(*irgen)(UChar i),
1471 UChar i)
1472{
1473 HChar *mnm = irgen(i);
1474
sewardj7ee97522011-05-09 21:45:04 +00001475 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001476 s390_disasm(ENC2(MNM, UINT), mnm, i);
1477}
1478
1479static void
1480s390_format_RI(HChar *(*irgen)(UChar r1, UShort i2),
1481 UChar r1, UShort i2)
1482{
1483 irgen(r1, i2);
1484}
1485
1486static void
1487s390_format_RI_RU(HChar *(*irgen)(UChar r1, UShort i2),
1488 UChar r1, UShort i2)
1489{
1490 HChar *mnm = irgen(r1, i2);
1491
sewardj7ee97522011-05-09 21:45:04 +00001492 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001493 s390_disasm(ENC3(MNM, GPR, UINT), mnm, r1, i2);
1494}
1495
1496static void
1497s390_format_RI_RI(HChar *(*irgen)(UChar r1, UShort i2),
1498 UChar r1, UShort i2)
1499{
1500 HChar *mnm = irgen(r1, i2);
1501
sewardj7ee97522011-05-09 21:45:04 +00001502 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001503 s390_disasm(ENC3(MNM, GPR, INT), mnm, r1, (Int)(Short)i2);
1504}
1505
1506static void
1507s390_format_RI_RP(HChar *(*irgen)(UChar r1, UShort i2),
1508 UChar r1, UShort i2)
1509{
1510 HChar *mnm = irgen(r1, i2);
1511
sewardj7ee97522011-05-09 21:45:04 +00001512 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001513 s390_disasm(ENC3(MNM, GPR, PCREL), mnm, r1, (Int)(Short)i2);
1514}
1515
1516static void
1517s390_format_RIE_RRP(HChar *(*irgen)(UChar r1, UChar r3, UShort i2),
1518 UChar r1, UChar r3, UShort i2)
1519{
1520 HChar *mnm = irgen(r1, r3, i2);
1521
sewardj7ee97522011-05-09 21:45:04 +00001522 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001523 s390_disasm(ENC4(MNM, GPR, GPR, PCREL), mnm, r1, r3, (Int)(Short)i2);
1524}
1525
1526static void
1527s390_format_RIE_RRI0(HChar *(*irgen)(UChar r1, UChar r3, UShort i2),
1528 UChar r1, UChar r3, UShort i2)
1529{
1530 HChar *mnm = irgen(r1, r3, i2);
1531
sewardj7ee97522011-05-09 21:45:04 +00001532 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001533 s390_disasm(ENC4(MNM, GPR, GPR, INT), mnm, r1, r3, (Int)(Short)i2);
1534}
1535
1536static void
1537s390_format_RIE_RRUUU(HChar *(*irgen)(UChar r1, UChar r2, UChar i3, UChar i4,
1538 UChar i5),
1539 UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
1540{
1541 HChar *mnm = irgen(r1, r2, i3, i4, i5);
1542
sewardj7ee97522011-05-09 21:45:04 +00001543 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001544 s390_disasm(ENC6(MNM, GPR, GPR, UINT, UINT, UINT), mnm, r1, r2, i3, i4,
1545 i5);
1546}
1547
1548static void
1549s390_format_RIE_RRPU(HChar *(*irgen)(UChar r1, UChar r2, UShort i4, UChar m3),
1550 UChar r1, UChar r2, UShort i4, UChar m3)
1551{
1552 HChar *mnm = irgen(r1, r2, i4, m3);
1553
sewardj7ee97522011-05-09 21:45:04 +00001554 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001555 s390_disasm(ENC5(XMNM, GPR, GPR, CABM, PCREL), S390_XMNM_CAB, mnm, m3, r1,
1556 r2, m3, (Int)(Short)i4);
1557}
1558
1559static void
1560s390_format_RIE_RUPU(HChar *(*irgen)(UChar r1, UChar m3, UShort i4, UChar i2),
1561 UChar r1, UChar m3, UShort i4, UChar i2)
1562{
1563 HChar *mnm = irgen(r1, m3, i4, i2);
1564
sewardj7ee97522011-05-09 21:45:04 +00001565 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001566 s390_disasm(ENC5(XMNM, GPR, UINT, CABM, PCREL), S390_XMNM_CAB, mnm, m3,
1567 r1, i2, m3, (Int)(Short)i4);
1568}
1569
1570static void
1571s390_format_RIE_RUPI(HChar *(*irgen)(UChar r1, UChar m3, UShort i4, UChar i2),
1572 UChar r1, UChar m3, UShort i4, UChar i2)
1573{
1574 HChar *mnm = irgen(r1, m3, i4, i2);
1575
sewardj7ee97522011-05-09 21:45:04 +00001576 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001577 s390_disasm(ENC5(XMNM, GPR, INT, CABM, PCREL), S390_XMNM_CAB, mnm, m3, r1,
1578 (Int)(Char)i2, m3, (Int)(Short)i4);
1579}
1580
1581static void
1582s390_format_RIL(HChar *(*irgen)(UChar r1, UInt i2),
1583 UChar r1, UInt i2)
1584{
1585 irgen(r1, i2);
1586}
1587
1588static void
1589s390_format_RIL_RU(HChar *(*irgen)(UChar r1, UInt i2),
1590 UChar r1, UInt i2)
1591{
1592 HChar *mnm = irgen(r1, i2);
1593
sewardj7ee97522011-05-09 21:45:04 +00001594 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001595 s390_disasm(ENC3(MNM, GPR, UINT), mnm, r1, i2);
1596}
1597
1598static void
1599s390_format_RIL_RI(HChar *(*irgen)(UChar r1, UInt i2),
1600 UChar r1, UInt i2)
1601{
1602 HChar *mnm = irgen(r1, i2);
1603
sewardj7ee97522011-05-09 21:45:04 +00001604 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001605 s390_disasm(ENC3(MNM, GPR, INT), mnm, r1, i2);
1606}
1607
1608static void
1609s390_format_RIL_RP(HChar *(*irgen)(UChar r1, UInt i2),
1610 UChar r1, UInt i2)
1611{
1612 HChar *mnm = irgen(r1, i2);
1613
sewardj7ee97522011-05-09 21:45:04 +00001614 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001615 s390_disasm(ENC3(MNM, GPR, PCREL), mnm, r1, i2);
1616}
1617
1618static void
1619s390_format_RIL_UP(HChar *(*irgen)(void),
1620 UChar r1, UInt i2)
1621{
1622 HChar *mnm = irgen();
1623
sewardj7ee97522011-05-09 21:45:04 +00001624 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001625 s390_disasm(ENC3(MNM, UINT, PCREL), mnm, r1, i2);
1626}
1627
1628static void
1629s390_format_RIS_RURDI(HChar *(*irgen)(UChar r1, UChar m3, UChar i2,
1630 IRTemp op4addr),
1631 UChar r1, UChar m3, UChar b4, UShort d4, UChar i2)
1632{
1633 HChar *mnm;
1634 IRTemp op4addr = newTemp(Ity_I64);
1635
1636 assign(op4addr, binop(Iop_Add64, mkU64(d4), b4 != 0 ? get_gpr_dw0(b4) :
1637 mkU64(0)));
1638
1639 mnm = irgen(r1, m3, i2, op4addr);
1640
sewardj7ee97522011-05-09 21:45:04 +00001641 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001642 s390_disasm(ENC5(XMNM, GPR, INT, CABM, UDXB), S390_XMNM_CAB, mnm, m3, r1,
1643 (Int)(Char)i2, m3, d4, 0, b4);
1644}
1645
1646static void
1647s390_format_RIS_RURDU(HChar *(*irgen)(UChar r1, UChar m3, UChar i2,
1648 IRTemp op4addr),
1649 UChar r1, UChar m3, UChar b4, UShort d4, UChar i2)
1650{
1651 HChar *mnm;
1652 IRTemp op4addr = newTemp(Ity_I64);
1653
1654 assign(op4addr, binop(Iop_Add64, mkU64(d4), b4 != 0 ? get_gpr_dw0(b4) :
1655 mkU64(0)));
1656
1657 mnm = irgen(r1, m3, i2, op4addr);
1658
sewardj7ee97522011-05-09 21:45:04 +00001659 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001660 s390_disasm(ENC5(XMNM, GPR, UINT, CABM, UDXB), S390_XMNM_CAB, mnm, m3, r1,
1661 i2, m3, d4, 0, b4);
1662}
1663
1664static void
1665s390_format_RR(HChar *(*irgen)(UChar r1, UChar r2),
1666 UChar r1, UChar r2)
1667{
1668 irgen(r1, r2);
1669}
1670
1671static void
1672s390_format_RR_RR(HChar *(*irgen)(UChar r1, UChar r2),
1673 UChar r1, UChar r2)
1674{
1675 HChar *mnm = irgen(r1, r2);
1676
sewardj7ee97522011-05-09 21:45:04 +00001677 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001678 s390_disasm(ENC3(MNM, GPR, GPR), mnm, r1, r2);
1679}
1680
1681static void
1682s390_format_RR_FF(HChar *(*irgen)(UChar r1, UChar r2),
1683 UChar r1, UChar r2)
1684{
1685 HChar *mnm = irgen(r1, r2);
1686
sewardj7ee97522011-05-09 21:45:04 +00001687 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001688 s390_disasm(ENC3(MNM, FPR, FPR), mnm, r1, r2);
1689}
1690
1691static void
1692s390_format_RRE(HChar *(*irgen)(UChar r1, UChar r2),
1693 UChar r1, UChar r2)
1694{
1695 irgen(r1, r2);
1696}
1697
1698static void
1699s390_format_RRE_RR(HChar *(*irgen)(UChar r1, UChar r2),
1700 UChar r1, UChar r2)
1701{
1702 HChar *mnm = irgen(r1, r2);
1703
sewardj7ee97522011-05-09 21:45:04 +00001704 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001705 s390_disasm(ENC3(MNM, GPR, GPR), mnm, r1, r2);
1706}
1707
1708static void
1709s390_format_RRE_FF(HChar *(*irgen)(UChar r1, UChar r2),
1710 UChar r1, UChar r2)
1711{
1712 HChar *mnm = irgen(r1, r2);
1713
sewardj7ee97522011-05-09 21:45:04 +00001714 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001715 s390_disasm(ENC3(MNM, FPR, FPR), mnm, r1, r2);
1716}
1717
1718static void
1719s390_format_RRE_RF(HChar *(*irgen)(UChar, UChar),
1720 UChar r1, UChar r2)
1721{
1722 HChar *mnm = irgen(r1, r2);
1723
sewardj7ee97522011-05-09 21:45:04 +00001724 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001725 s390_disasm(ENC3(MNM, GPR, FPR), mnm, r1, r2);
1726}
1727
1728static void
1729s390_format_RRE_FR(HChar *(*irgen)(UChar r1, UChar r2),
1730 UChar r1, UChar r2)
1731{
1732 HChar *mnm = irgen(r1, r2);
1733
sewardj7ee97522011-05-09 21:45:04 +00001734 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001735 s390_disasm(ENC3(MNM, FPR, GPR), mnm, r1, r2);
1736}
1737
1738static void
1739s390_format_RRE_R0(HChar *(*irgen)(UChar r1),
1740 UChar r1)
1741{
1742 HChar *mnm = irgen(r1);
1743
sewardj7ee97522011-05-09 21:45:04 +00001744 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001745 s390_disasm(ENC2(MNM, GPR), mnm, r1);
1746}
1747
1748static void
1749s390_format_RRE_F0(HChar *(*irgen)(UChar r1),
1750 UChar r1)
1751{
1752 HChar *mnm = irgen(r1);
1753
sewardj7ee97522011-05-09 21:45:04 +00001754 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001755 s390_disasm(ENC2(MNM, FPR), mnm, r1);
1756}
1757
1758static void
florian9af37692012-01-15 21:01:16 +00001759s390_format_RRF_M0RERE(HChar *(*irgen)(UChar m3, UChar r1, UChar r2),
1760 UChar m3, UChar r1, UChar r2)
1761{
florianfed3ea32012-07-19 14:54:03 +00001762 HChar *mnm = irgen(m3, r1, r2);
florian9af37692012-01-15 21:01:16 +00001763
1764 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
florianfed3ea32012-07-19 14:54:03 +00001765 s390_disasm(ENC4(MNM, GPR, GPR, UINT), mnm, r1, r2, m3);
florian9af37692012-01-15 21:01:16 +00001766}
1767
1768static void
sewardj2019a972011-03-07 16:04:07 +00001769s390_format_RRF_F0FF(HChar *(*irgen)(UChar, UChar, UChar),
1770 UChar r1, UChar r3, UChar r2)
1771{
1772 HChar *mnm = irgen(r1, r3, r2);
1773
sewardj7ee97522011-05-09 21:45:04 +00001774 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001775 s390_disasm(ENC4(MNM, FPR, FPR, FPR), mnm, r1, r3, r2);
1776}
1777
1778static void
florian4b8efad2012-09-02 18:07:08 +00001779s390_format_RRF_UUFF(HChar *(*irgen)(UChar m3, UChar m4, UChar r1, UChar r2),
1780 UChar m3, UChar m4, UChar r1, UChar r2)
1781{
1782 HChar *mnm = irgen(m3, m4, r1, r2);
1783
1784 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
1785 s390_disasm(ENC5(MNM, FPR, UINT, FPR, UINT), mnm, r1, m3, r2, m4);
1786}
1787
1788static void
florian1c8f7ff2012-09-01 00:12:11 +00001789s390_format_RRF_UUFR(HChar *(*irgen)(UChar m3, UChar m4, UChar r1, UChar r2),
1790 UChar m3, UChar m4, UChar r1, UChar r2)
1791{
1792 HChar *mnm = irgen(m3, m4, r1, r2);
1793
1794 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
1795 s390_disasm(ENC5(MNM, FPR, UINT, GPR, UINT), mnm, r1, m3, r2, m4);
1796}
1797
1798static void
1799s390_format_RRF_UURF(HChar *(*irgen)(UChar m3, UChar m4, UChar r1, UChar r2),
1800 UChar m3, UChar m4, UChar r1, UChar r2)
1801{
1802 HChar *mnm = irgen(m3, m4, r1, r2);
1803
1804 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
1805 s390_disasm(ENC5(MNM, GPR, UINT, FPR, UINT), mnm, r1, m3, r2, m4);
1806}
1807
1808
1809static void
sewardjd7bde722011-04-05 13:19:33 +00001810s390_format_RRF_U0RR(HChar *(*irgen)(UChar m3, UChar r1, UChar r2),
1811 UChar m3, UChar r1, UChar r2, Int xmnm_kind)
1812{
1813 irgen(m3, r1, r2);
1814
sewardj7ee97522011-05-09 21:45:04 +00001815 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardjd7bde722011-04-05 13:19:33 +00001816 s390_disasm(ENC3(XMNM, GPR, GPR), xmnm_kind, m3, r1, r2);
1817}
1818
1819static void
sewardj2019a972011-03-07 16:04:07 +00001820s390_format_RRF_F0FF2(HChar *(*irgen)(UChar, UChar, UChar),
1821 UChar r3, UChar r1, UChar r2)
1822{
1823 HChar *mnm = irgen(r3, r1, r2);
1824
sewardj7ee97522011-05-09 21:45:04 +00001825 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001826 s390_disasm(ENC4(MNM, FPR, FPR, FPR), mnm, r1, r3, r2);
1827}
1828
1829static void
1830s390_format_RRF_R0RR2(HChar *(*irgen)(UChar r3, UChar r1, UChar r2),
1831 UChar r3, UChar r1, UChar r2)
1832{
1833 HChar *mnm = irgen(r3, r1, r2);
1834
sewardj7ee97522011-05-09 21:45:04 +00001835 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001836 s390_disasm(ENC4(MNM, GPR, GPR, GPR), mnm, r1, r2, r3);
1837}
1838
1839static void
1840s390_format_RRS(HChar *(*irgen)(UChar r1, UChar r2, UChar m3, IRTemp op4addr),
1841 UChar r1, UChar r2, UChar b4, UShort d4, UChar m3)
1842{
1843 HChar *mnm;
1844 IRTemp op4addr = newTemp(Ity_I64);
1845
1846 assign(op4addr, binop(Iop_Add64, mkU64(d4), b4 != 0 ? get_gpr_dw0(b4) :
1847 mkU64(0)));
1848
1849 mnm = irgen(r1, r2, m3, op4addr);
1850
sewardj7ee97522011-05-09 21:45:04 +00001851 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001852 s390_disasm(ENC5(XMNM, GPR, GPR, CABM, UDXB), S390_XMNM_CAB, mnm, m3, r1,
1853 r2, m3, d4, 0, b4);
1854}
1855
1856static void
1857s390_format_RS_R0RD(HChar *(*irgen)(UChar r1, IRTemp op2addr),
1858 UChar r1, UChar b2, UShort d2)
1859{
1860 HChar *mnm;
1861 IRTemp op2addr = newTemp(Ity_I64);
1862
1863 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
1864 mkU64(0)));
1865
1866 mnm = irgen(r1, op2addr);
1867
sewardj7ee97522011-05-09 21:45:04 +00001868 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001869 s390_disasm(ENC3(MNM, GPR, UDXB), mnm, r1, d2, 0, b2);
1870}
1871
1872static void
1873s390_format_RS_RRRD(HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
1874 UChar r1, UChar r3, UChar b2, UShort d2)
1875{
1876 HChar *mnm;
1877 IRTemp op2addr = newTemp(Ity_I64);
1878
1879 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
1880 mkU64(0)));
1881
1882 mnm = irgen(r1, r3, op2addr);
1883
sewardj7ee97522011-05-09 21:45:04 +00001884 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001885 s390_disasm(ENC4(MNM, GPR, GPR, UDXB), mnm, r1, r3, d2, 0, b2);
1886}
1887
1888static void
1889s390_format_RS_RURD(HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
1890 UChar r1, UChar r3, UChar b2, UShort d2)
1891{
1892 HChar *mnm;
1893 IRTemp op2addr = newTemp(Ity_I64);
1894
1895 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
1896 mkU64(0)));
1897
1898 mnm = irgen(r1, r3, op2addr);
1899
sewardj7ee97522011-05-09 21:45:04 +00001900 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001901 s390_disasm(ENC4(MNM, GPR, UINT, UDXB), mnm, r1, r3, d2, 0, b2);
1902}
1903
1904static void
1905s390_format_RS_AARD(HChar *(*irgen)(UChar, UChar, IRTemp),
1906 UChar r1, UChar r3, UChar b2, UShort d2)
1907{
1908 HChar *mnm;
1909 IRTemp op2addr = newTemp(Ity_I64);
1910
1911 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
1912 mkU64(0)));
1913
1914 mnm = irgen(r1, r3, op2addr);
1915
sewardj7ee97522011-05-09 21:45:04 +00001916 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001917 s390_disasm(ENC4(MNM, AR, AR, UDXB), mnm, r1, r3, d2, 0, b2);
1918}
1919
1920static void
1921s390_format_RSI_RRP(HChar *(*irgen)(UChar r1, UChar r3, UShort i2),
1922 UChar r1, UChar r3, UShort i2)
1923{
1924 HChar *mnm = irgen(r1, r3, i2);
1925
sewardj7ee97522011-05-09 21:45:04 +00001926 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001927 s390_disasm(ENC4(MNM, GPR, GPR, PCREL), mnm, r1, r3, (Int)(Short)i2);
1928}
1929
1930static void
1931s390_format_RSY_RRRD(HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
1932 UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2)
1933{
1934 HChar *mnm;
1935 IRTemp op2addr = newTemp(Ity_I64);
1936 IRTemp d2 = newTemp(Ity_I64);
1937
1938 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
1939 assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
1940 mkU64(0)));
1941
1942 mnm = irgen(r1, r3, op2addr);
1943
sewardj7ee97522011-05-09 21:45:04 +00001944 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001945 s390_disasm(ENC4(MNM, GPR, GPR, SDXB), mnm, r1, r3, dh2, dl2, 0, b2);
1946}
1947
1948static void
1949s390_format_RSY_AARD(HChar *(*irgen)(UChar, UChar, IRTemp),
1950 UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2)
1951{
1952 HChar *mnm;
1953 IRTemp op2addr = newTemp(Ity_I64);
1954 IRTemp d2 = newTemp(Ity_I64);
1955
1956 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
1957 assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
1958 mkU64(0)));
1959
1960 mnm = irgen(r1, r3, op2addr);
1961
sewardj7ee97522011-05-09 21:45:04 +00001962 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001963 s390_disasm(ENC4(MNM, AR, AR, SDXB), mnm, r1, r3, dh2, dl2, 0, b2);
1964}
1965
1966static void
1967s390_format_RSY_RURD(HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
1968 UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2)
1969{
1970 HChar *mnm;
1971 IRTemp op2addr = newTemp(Ity_I64);
1972 IRTemp d2 = newTemp(Ity_I64);
1973
1974 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
1975 assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
1976 mkU64(0)));
1977
1978 mnm = irgen(r1, r3, op2addr);
1979
sewardj7ee97522011-05-09 21:45:04 +00001980 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001981 s390_disasm(ENC4(MNM, GPR, UINT, SDXB), mnm, r1, r3, dh2, dl2, 0, b2);
1982}
1983
1984static void
sewardjd7bde722011-04-05 13:19:33 +00001985s390_format_RSY_RDRM(HChar *(*irgen)(UChar r1, IRTemp op2addr),
1986 UChar r1, UChar m3, UChar b2, UShort dl2, UChar dh2,
1987 Int xmnm_kind)
1988{
1989 IRTemp op2addr = newTemp(Ity_I64);
1990 IRTemp d2 = newTemp(Ity_I64);
1991
florian6820ba52012-07-26 02:01:50 +00001992 next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0)));
1993
sewardjd7bde722011-04-05 13:19:33 +00001994 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
1995 assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
1996 mkU64(0)));
1997
1998 irgen(r1, op2addr);
florian6820ba52012-07-26 02:01:50 +00001999
2000 vassert(dis_res->whatNext == Dis_Continue);
sewardjd7bde722011-04-05 13:19:33 +00002001
sewardj7ee97522011-05-09 21:45:04 +00002002 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardjd7bde722011-04-05 13:19:33 +00002003 s390_disasm(ENC3(XMNM, GPR, SDXB), xmnm_kind, m3, r1, dh2, dl2, 0, b2);
2004}
2005
2006static void
sewardj2019a972011-03-07 16:04:07 +00002007s390_format_RX(HChar *(*irgen)(UChar r1, UChar x2, UChar b2, UShort d2,
2008 IRTemp op2addr),
2009 UChar r1, UChar x2, UChar b2, UShort d2)
2010{
2011 IRTemp op2addr = newTemp(Ity_I64);
2012
2013 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
2014 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2015 mkU64(0)));
2016
2017 irgen(r1, x2, b2, d2, op2addr);
2018}
2019
2020static void
2021s390_format_RX_RRRD(HChar *(*irgen)(UChar r1, IRTemp op2addr),
2022 UChar r1, UChar x2, UChar b2, UShort d2)
2023{
2024 HChar *mnm;
2025 IRTemp op2addr = newTemp(Ity_I64);
2026
2027 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
2028 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2029 mkU64(0)));
2030
2031 mnm = irgen(r1, op2addr);
2032
sewardj7ee97522011-05-09 21:45:04 +00002033 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002034 s390_disasm(ENC3(MNM, GPR, UDXB), mnm, r1, d2, x2, b2);
2035}
2036
2037static void
2038s390_format_RX_FRRD(HChar *(*irgen)(UChar r1, IRTemp op2addr),
2039 UChar r1, UChar x2, UChar b2, UShort d2)
2040{
2041 HChar *mnm;
2042 IRTemp op2addr = newTemp(Ity_I64);
2043
2044 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
2045 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2046 mkU64(0)));
2047
2048 mnm = irgen(r1, op2addr);
2049
sewardj7ee97522011-05-09 21:45:04 +00002050 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002051 s390_disasm(ENC3(MNM, FPR, UDXB), mnm, r1, d2, x2, b2);
2052}
2053
2054static void
2055s390_format_RXE_FRRD(HChar *(*irgen)(UChar r1, IRTemp op2addr),
2056 UChar r1, UChar x2, UChar b2, UShort d2)
2057{
2058 HChar *mnm;
2059 IRTemp op2addr = newTemp(Ity_I64);
2060
2061 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
2062 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2063 mkU64(0)));
2064
2065 mnm = irgen(r1, op2addr);
2066
sewardj7ee97522011-05-09 21:45:04 +00002067 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002068 s390_disasm(ENC3(MNM, FPR, UDXB), mnm, r1, d2, x2, b2);
2069}
2070
2071static void
2072s390_format_RXF_FRRDF(HChar *(*irgen)(UChar, IRTemp, UChar),
2073 UChar r3, UChar x2, UChar b2, UShort d2, UChar r1)
2074{
2075 HChar *mnm;
2076 IRTemp op2addr = newTemp(Ity_I64);
2077
2078 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
2079 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2080 mkU64(0)));
2081
2082 mnm = irgen(r3, op2addr, r1);
2083
sewardj7ee97522011-05-09 21:45:04 +00002084 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002085 s390_disasm(ENC4(MNM, FPR, FPR, UDXB), mnm, r1, r3, d2, x2, b2);
2086}
2087
2088static void
2089s390_format_RXY_RRRD(HChar *(*irgen)(UChar r1, IRTemp op2addr),
2090 UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
2091{
2092 HChar *mnm;
2093 IRTemp op2addr = newTemp(Ity_I64);
2094 IRTemp d2 = newTemp(Ity_I64);
2095
2096 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2097 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkexpr(d2),
2098 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2099 mkU64(0)));
2100
2101 mnm = irgen(r1, op2addr);
2102
sewardj7ee97522011-05-09 21:45:04 +00002103 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002104 s390_disasm(ENC3(MNM, GPR, SDXB), mnm, r1, dh2, dl2, x2, b2);
2105}
2106
2107static void
2108s390_format_RXY_FRRD(HChar *(*irgen)(UChar r1, IRTemp op2addr),
2109 UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
2110{
2111 HChar *mnm;
2112 IRTemp op2addr = newTemp(Ity_I64);
2113 IRTemp d2 = newTemp(Ity_I64);
2114
2115 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2116 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkexpr(d2),
2117 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2118 mkU64(0)));
2119
2120 mnm = irgen(r1, op2addr);
2121
sewardj7ee97522011-05-09 21:45:04 +00002122 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002123 s390_disasm(ENC3(MNM, FPR, SDXB), mnm, r1, dh2, dl2, x2, b2);
2124}
2125
2126static void
2127s390_format_RXY_URRD(HChar *(*irgen)(void),
2128 UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
2129{
2130 HChar *mnm;
2131 IRTemp op2addr = newTemp(Ity_I64);
2132 IRTemp d2 = newTemp(Ity_I64);
2133
2134 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2135 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkexpr(d2),
2136 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2137 mkU64(0)));
2138
2139 mnm = irgen();
2140
sewardj7ee97522011-05-09 21:45:04 +00002141 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002142 s390_disasm(ENC3(MNM, UINT, SDXB), mnm, r1, dh2, dl2, x2, b2);
2143}
2144
2145static void
2146s390_format_S_RD(HChar *(*irgen)(IRTemp op2addr),
2147 UChar b2, UShort d2)
2148{
2149 HChar *mnm;
2150 IRTemp op2addr = newTemp(Ity_I64);
2151
2152 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2153 mkU64(0)));
2154
2155 mnm = irgen(op2addr);
2156
sewardj7ee97522011-05-09 21:45:04 +00002157 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002158 s390_disasm(ENC2(MNM, UDXB), mnm, d2, 0, b2);
2159}
2160
2161static void
2162s390_format_SI_URD(HChar *(*irgen)(UChar i2, IRTemp op1addr),
2163 UChar i2, UChar b1, UShort d1)
2164{
2165 HChar *mnm;
2166 IRTemp op1addr = newTemp(Ity_I64);
2167
2168 assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
2169 mkU64(0)));
2170
2171 mnm = irgen(i2, op1addr);
2172
sewardj7ee97522011-05-09 21:45:04 +00002173 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002174 s390_disasm(ENC3(MNM, UDXB, UINT), mnm, d1, 0, b1, i2);
2175}
2176
2177static void
2178s390_format_SIY_URD(HChar *(*irgen)(UChar i2, IRTemp op1addr),
2179 UChar i2, UChar b1, UShort dl1, UChar dh1)
2180{
2181 HChar *mnm;
2182 IRTemp op1addr = newTemp(Ity_I64);
2183 IRTemp d1 = newTemp(Ity_I64);
2184
2185 assign(d1, mkU64(((ULong)(Long)(Char)dh1 << 12) | ((ULong)dl1)));
2186 assign(op1addr, binop(Iop_Add64, mkexpr(d1), b1 != 0 ? get_gpr_dw0(b1) :
2187 mkU64(0)));
2188
2189 mnm = irgen(i2, op1addr);
2190
sewardj7ee97522011-05-09 21:45:04 +00002191 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002192 s390_disasm(ENC3(MNM, SDXB, UINT), mnm, dh1, dl1, 0, b1, i2);
2193}
2194
2195static void
2196s390_format_SIY_IRD(HChar *(*irgen)(UChar i2, IRTemp op1addr),
2197 UChar i2, UChar b1, UShort dl1, UChar dh1)
2198{
2199 HChar *mnm;
2200 IRTemp op1addr = newTemp(Ity_I64);
2201 IRTemp d1 = newTemp(Ity_I64);
2202
2203 assign(d1, mkU64(((ULong)(Long)(Char)dh1 << 12) | ((ULong)dl1)));
2204 assign(op1addr, binop(Iop_Add64, mkexpr(d1), b1 != 0 ? get_gpr_dw0(b1) :
2205 mkU64(0)));
2206
2207 mnm = irgen(i2, op1addr);
2208
sewardj7ee97522011-05-09 21:45:04 +00002209 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002210 s390_disasm(ENC3(MNM, SDXB, INT), mnm, dh1, dl1, 0, b1, (Int)(Char)i2);
2211}
2212
2213static void
2214s390_format_SS_L0RDRD(HChar *(*irgen)(UChar, IRTemp, IRTemp),
2215 UChar l, UChar b1, UShort d1, UChar b2, UShort d2)
2216{
2217 HChar *mnm;
2218 IRTemp op1addr = newTemp(Ity_I64);
2219 IRTemp op2addr = newTemp(Ity_I64);
2220
2221 assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
2222 mkU64(0)));
2223 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2224 mkU64(0)));
2225
2226 mnm = irgen(l, op1addr, op2addr);
2227
sewardj7ee97522011-05-09 21:45:04 +00002228 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002229 s390_disasm(ENC3(MNM, UDLB, UDXB), mnm, d1, l, b1, d2, 0, b2);
2230}
2231
2232static void
2233s390_format_SIL_RDI(HChar *(*irgen)(UShort i2, IRTemp op1addr),
2234 UChar b1, UShort d1, UShort i2)
2235{
2236 HChar *mnm;
2237 IRTemp op1addr = newTemp(Ity_I64);
2238
2239 assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
2240 mkU64(0)));
2241
2242 mnm = irgen(i2, op1addr);
2243
sewardj7ee97522011-05-09 21:45:04 +00002244 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002245 s390_disasm(ENC3(MNM, UDXB, INT), mnm, d1, 0, b1, (Int)(Short)i2);
2246}
2247
2248static void
2249s390_format_SIL_RDU(HChar *(*irgen)(UShort i2, IRTemp op1addr),
2250 UChar b1, UShort d1, UShort i2)
2251{
2252 HChar *mnm;
2253 IRTemp op1addr = newTemp(Ity_I64);
2254
2255 assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
2256 mkU64(0)));
2257
2258 mnm = irgen(i2, op1addr);
2259
sewardj7ee97522011-05-09 21:45:04 +00002260 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002261 s390_disasm(ENC3(MNM, UDXB, UINT), mnm, d1, 0, b1, i2);
2262}
2263
2264
2265
2266/*------------------------------------------------------------*/
2267/*--- Build IR for opcodes ---*/
2268/*------------------------------------------------------------*/
2269
2270static HChar *
2271s390_irgen_AR(UChar r1, UChar r2)
2272{
2273 IRTemp op1 = newTemp(Ity_I32);
2274 IRTemp op2 = newTemp(Ity_I32);
2275 IRTemp result = newTemp(Ity_I32);
2276
2277 assign(op1, get_gpr_w1(r1));
2278 assign(op2, get_gpr_w1(r2));
2279 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2280 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2281 put_gpr_w1(r1, mkexpr(result));
2282
2283 return "ar";
2284}
2285
2286static HChar *
2287s390_irgen_AGR(UChar r1, UChar r2)
2288{
2289 IRTemp op1 = newTemp(Ity_I64);
2290 IRTemp op2 = newTemp(Ity_I64);
2291 IRTemp result = newTemp(Ity_I64);
2292
2293 assign(op1, get_gpr_dw0(r1));
2294 assign(op2, get_gpr_dw0(r2));
2295 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2296 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
2297 put_gpr_dw0(r1, mkexpr(result));
2298
2299 return "agr";
2300}
2301
2302static HChar *
2303s390_irgen_AGFR(UChar r1, UChar r2)
2304{
2305 IRTemp op1 = newTemp(Ity_I64);
2306 IRTemp op2 = newTemp(Ity_I64);
2307 IRTemp result = newTemp(Ity_I64);
2308
2309 assign(op1, get_gpr_dw0(r1));
2310 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
2311 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2312 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
2313 put_gpr_dw0(r1, mkexpr(result));
2314
2315 return "agfr";
2316}
2317
2318static HChar *
2319s390_irgen_ARK(UChar r3, UChar r1, UChar r2)
2320{
2321 IRTemp op2 = newTemp(Ity_I32);
2322 IRTemp op3 = newTemp(Ity_I32);
2323 IRTemp result = newTemp(Ity_I32);
2324
2325 assign(op2, get_gpr_w1(r2));
2326 assign(op3, get_gpr_w1(r3));
2327 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2328 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
2329 put_gpr_w1(r1, mkexpr(result));
2330
2331 return "ark";
2332}
2333
2334static HChar *
2335s390_irgen_AGRK(UChar r3, UChar r1, UChar r2)
2336{
2337 IRTemp op2 = newTemp(Ity_I64);
2338 IRTemp op3 = newTemp(Ity_I64);
2339 IRTemp result = newTemp(Ity_I64);
2340
2341 assign(op2, get_gpr_dw0(r2));
2342 assign(op3, get_gpr_dw0(r3));
2343 assign(result, binop(Iop_Add64, mkexpr(op2), mkexpr(op3)));
2344 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op2, op3);
2345 put_gpr_dw0(r1, mkexpr(result));
2346
2347 return "agrk";
2348}
2349
2350static HChar *
2351s390_irgen_A(UChar r1, IRTemp op2addr)
2352{
2353 IRTemp op1 = newTemp(Ity_I32);
2354 IRTemp op2 = newTemp(Ity_I32);
2355 IRTemp result = newTemp(Ity_I32);
2356
2357 assign(op1, get_gpr_w1(r1));
2358 assign(op2, load(Ity_I32, mkexpr(op2addr)));
2359 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2360 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2361 put_gpr_w1(r1, mkexpr(result));
2362
2363 return "a";
2364}
2365
2366static HChar *
2367s390_irgen_AY(UChar r1, IRTemp op2addr)
2368{
2369 IRTemp op1 = newTemp(Ity_I32);
2370 IRTemp op2 = newTemp(Ity_I32);
2371 IRTemp result = newTemp(Ity_I32);
2372
2373 assign(op1, get_gpr_w1(r1));
2374 assign(op2, load(Ity_I32, mkexpr(op2addr)));
2375 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2376 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2377 put_gpr_w1(r1, mkexpr(result));
2378
2379 return "ay";
2380}
2381
2382static HChar *
2383s390_irgen_AG(UChar r1, IRTemp op2addr)
2384{
2385 IRTemp op1 = newTemp(Ity_I64);
2386 IRTemp op2 = newTemp(Ity_I64);
2387 IRTemp result = newTemp(Ity_I64);
2388
2389 assign(op1, get_gpr_dw0(r1));
2390 assign(op2, load(Ity_I64, mkexpr(op2addr)));
2391 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2392 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
2393 put_gpr_dw0(r1, mkexpr(result));
2394
2395 return "ag";
2396}
2397
2398static HChar *
2399s390_irgen_AGF(UChar r1, IRTemp op2addr)
2400{
2401 IRTemp op1 = newTemp(Ity_I64);
2402 IRTemp op2 = newTemp(Ity_I64);
2403 IRTemp result = newTemp(Ity_I64);
2404
2405 assign(op1, get_gpr_dw0(r1));
2406 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
2407 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2408 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
2409 put_gpr_dw0(r1, mkexpr(result));
2410
2411 return "agf";
2412}
2413
2414static HChar *
2415s390_irgen_AFI(UChar r1, UInt i2)
2416{
2417 IRTemp op1 = newTemp(Ity_I32);
2418 Int op2;
2419 IRTemp result = newTemp(Ity_I32);
2420
2421 assign(op1, get_gpr_w1(r1));
2422 op2 = (Int)i2;
2423 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
2424 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
2425 mkU32((UInt)op2)));
2426 put_gpr_w1(r1, mkexpr(result));
2427
2428 return "afi";
2429}
2430
2431static HChar *
2432s390_irgen_AGFI(UChar r1, UInt i2)
2433{
2434 IRTemp op1 = newTemp(Ity_I64);
2435 Long op2;
2436 IRTemp result = newTemp(Ity_I64);
2437
2438 assign(op1, get_gpr_dw0(r1));
2439 op2 = (Long)(Int)i2;
2440 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64((ULong)op2)));
2441 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, mktemp(Ity_I64,
2442 mkU64((ULong)op2)));
2443 put_gpr_dw0(r1, mkexpr(result));
2444
2445 return "agfi";
2446}
2447
2448static HChar *
2449s390_irgen_AHIK(UChar r1, UChar r3, UShort i2)
2450{
2451 Int op2;
2452 IRTemp op3 = newTemp(Ity_I32);
2453 IRTemp result = newTemp(Ity_I32);
2454
2455 op2 = (Int)(Short)i2;
2456 assign(op3, get_gpr_w1(r3));
2457 assign(result, binop(Iop_Add32, mkU32((UInt)op2), mkexpr(op3)));
2458 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, mktemp(Ity_I32, mkU32((UInt)
2459 op2)), op3);
2460 put_gpr_w1(r1, mkexpr(result));
2461
2462 return "ahik";
2463}
2464
2465static HChar *
2466s390_irgen_AGHIK(UChar r1, UChar r3, UShort i2)
2467{
2468 Long op2;
2469 IRTemp op3 = newTemp(Ity_I64);
2470 IRTemp result = newTemp(Ity_I64);
2471
2472 op2 = (Long)(Short)i2;
2473 assign(op3, get_gpr_dw0(r3));
2474 assign(result, binop(Iop_Add64, mkU64((ULong)op2), mkexpr(op3)));
2475 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, mktemp(Ity_I64, mkU64((ULong)
2476 op2)), op3);
2477 put_gpr_dw0(r1, mkexpr(result));
2478
2479 return "aghik";
2480}
2481
2482static HChar *
2483s390_irgen_ASI(UChar i2, IRTemp op1addr)
2484{
2485 IRTemp op1 = newTemp(Ity_I32);
2486 Int op2;
2487 IRTemp result = newTemp(Ity_I32);
2488
2489 assign(op1, load(Ity_I32, mkexpr(op1addr)));
2490 op2 = (Int)(Char)i2;
2491 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
2492 store(mkexpr(op1addr), mkexpr(result));
2493 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
2494 mkU32((UInt)op2)));
2495
2496 return "asi";
2497}
2498
2499static HChar *
2500s390_irgen_AGSI(UChar i2, IRTemp op1addr)
2501{
2502 IRTemp op1 = newTemp(Ity_I64);
2503 Long op2;
2504 IRTemp result = newTemp(Ity_I64);
2505
2506 assign(op1, load(Ity_I64, mkexpr(op1addr)));
2507 op2 = (Long)(Char)i2;
2508 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64((ULong)op2)));
2509 store(mkexpr(op1addr), mkexpr(result));
2510 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, mktemp(Ity_I64,
2511 mkU64((ULong)op2)));
2512
2513 return "agsi";
2514}
2515
2516static HChar *
2517s390_irgen_AH(UChar r1, IRTemp op2addr)
2518{
2519 IRTemp op1 = newTemp(Ity_I32);
2520 IRTemp op2 = newTemp(Ity_I32);
2521 IRTemp result = newTemp(Ity_I32);
2522
2523 assign(op1, get_gpr_w1(r1));
2524 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
2525 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2526 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2527 put_gpr_w1(r1, mkexpr(result));
2528
2529 return "ah";
2530}
2531
2532static HChar *
2533s390_irgen_AHY(UChar r1, IRTemp op2addr)
2534{
2535 IRTemp op1 = newTemp(Ity_I32);
2536 IRTemp op2 = newTemp(Ity_I32);
2537 IRTemp result = newTemp(Ity_I32);
2538
2539 assign(op1, get_gpr_w1(r1));
2540 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
2541 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2542 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2543 put_gpr_w1(r1, mkexpr(result));
2544
2545 return "ahy";
2546}
2547
2548static HChar *
2549s390_irgen_AHI(UChar r1, UShort i2)
2550{
2551 IRTemp op1 = newTemp(Ity_I32);
2552 Int op2;
2553 IRTemp result = newTemp(Ity_I32);
2554
2555 assign(op1, get_gpr_w1(r1));
2556 op2 = (Int)(Short)i2;
2557 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
2558 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
2559 mkU32((UInt)op2)));
2560 put_gpr_w1(r1, mkexpr(result));
2561
2562 return "ahi";
2563}
2564
2565static HChar *
2566s390_irgen_AGHI(UChar r1, UShort i2)
2567{
2568 IRTemp op1 = newTemp(Ity_I64);
2569 Long op2;
2570 IRTemp result = newTemp(Ity_I64);
2571
2572 assign(op1, get_gpr_dw0(r1));
2573 op2 = (Long)(Short)i2;
2574 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64((ULong)op2)));
2575 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, mktemp(Ity_I64,
2576 mkU64((ULong)op2)));
2577 put_gpr_dw0(r1, mkexpr(result));
2578
2579 return "aghi";
2580}
2581
2582static HChar *
2583s390_irgen_AHHHR(UChar r3, UChar r1, UChar r2)
2584{
2585 IRTemp op2 = newTemp(Ity_I32);
2586 IRTemp op3 = newTemp(Ity_I32);
2587 IRTemp result = newTemp(Ity_I32);
2588
2589 assign(op2, get_gpr_w0(r2));
2590 assign(op3, get_gpr_w0(r3));
2591 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2592 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
2593 put_gpr_w0(r1, mkexpr(result));
2594
2595 return "ahhhr";
2596}
2597
2598static HChar *
2599s390_irgen_AHHLR(UChar r3, UChar r1, UChar r2)
2600{
2601 IRTemp op2 = newTemp(Ity_I32);
2602 IRTemp op3 = newTemp(Ity_I32);
2603 IRTemp result = newTemp(Ity_I32);
2604
2605 assign(op2, get_gpr_w0(r2));
2606 assign(op3, get_gpr_w1(r3));
2607 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2608 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
2609 put_gpr_w0(r1, mkexpr(result));
2610
2611 return "ahhlr";
2612}
2613
2614static HChar *
2615s390_irgen_AIH(UChar r1, UInt i2)
2616{
2617 IRTemp op1 = newTemp(Ity_I32);
2618 Int op2;
2619 IRTemp result = newTemp(Ity_I32);
2620
2621 assign(op1, get_gpr_w0(r1));
2622 op2 = (Int)i2;
2623 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
2624 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
2625 mkU32((UInt)op2)));
2626 put_gpr_w0(r1, mkexpr(result));
2627
2628 return "aih";
2629}
2630
2631static HChar *
2632s390_irgen_ALR(UChar r1, UChar r2)
2633{
2634 IRTemp op1 = newTemp(Ity_I32);
2635 IRTemp op2 = newTemp(Ity_I32);
2636 IRTemp result = newTemp(Ity_I32);
2637
2638 assign(op1, get_gpr_w1(r1));
2639 assign(op2, get_gpr_w1(r2));
2640 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2641 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, op2);
2642 put_gpr_w1(r1, mkexpr(result));
2643
2644 return "alr";
2645}
2646
2647static HChar *
2648s390_irgen_ALGR(UChar r1, UChar r2)
2649{
2650 IRTemp op1 = newTemp(Ity_I64);
2651 IRTemp op2 = newTemp(Ity_I64);
2652 IRTemp result = newTemp(Ity_I64);
2653
2654 assign(op1, get_gpr_dw0(r1));
2655 assign(op2, get_gpr_dw0(r2));
2656 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2657 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
2658 put_gpr_dw0(r1, mkexpr(result));
2659
2660 return "algr";
2661}
2662
2663static HChar *
2664s390_irgen_ALGFR(UChar r1, UChar r2)
2665{
2666 IRTemp op1 = newTemp(Ity_I64);
2667 IRTemp op2 = newTemp(Ity_I64);
2668 IRTemp result = newTemp(Ity_I64);
2669
2670 assign(op1, get_gpr_dw0(r1));
2671 assign(op2, unop(Iop_32Uto64, get_gpr_w1(r2)));
2672 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2673 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
2674 put_gpr_dw0(r1, mkexpr(result));
2675
2676 return "algfr";
2677}
2678
2679static HChar *
2680s390_irgen_ALRK(UChar r3, UChar r1, UChar r2)
2681{
2682 IRTemp op2 = newTemp(Ity_I32);
2683 IRTemp op3 = newTemp(Ity_I32);
2684 IRTemp result = newTemp(Ity_I32);
2685
2686 assign(op2, get_gpr_w1(r2));
2687 assign(op3, get_gpr_w1(r3));
2688 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2689 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
2690 put_gpr_w1(r1, mkexpr(result));
2691
2692 return "alrk";
2693}
2694
2695static HChar *
2696s390_irgen_ALGRK(UChar r3, UChar r1, UChar r2)
2697{
2698 IRTemp op2 = newTemp(Ity_I64);
2699 IRTemp op3 = newTemp(Ity_I64);
2700 IRTemp result = newTemp(Ity_I64);
2701
2702 assign(op2, get_gpr_dw0(r2));
2703 assign(op3, get_gpr_dw0(r3));
2704 assign(result, binop(Iop_Add64, mkexpr(op2), mkexpr(op3)));
2705 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op2, op3);
2706 put_gpr_dw0(r1, mkexpr(result));
2707
2708 return "algrk";
2709}
2710
2711static HChar *
2712s390_irgen_AL(UChar r1, IRTemp op2addr)
2713{
2714 IRTemp op1 = newTemp(Ity_I32);
2715 IRTemp op2 = newTemp(Ity_I32);
2716 IRTemp result = newTemp(Ity_I32);
2717
2718 assign(op1, get_gpr_w1(r1));
2719 assign(op2, load(Ity_I32, mkexpr(op2addr)));
2720 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2721 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, op2);
2722 put_gpr_w1(r1, mkexpr(result));
2723
2724 return "al";
2725}
2726
2727static HChar *
2728s390_irgen_ALY(UChar r1, IRTemp op2addr)
2729{
2730 IRTemp op1 = newTemp(Ity_I32);
2731 IRTemp op2 = newTemp(Ity_I32);
2732 IRTemp result = newTemp(Ity_I32);
2733
2734 assign(op1, get_gpr_w1(r1));
2735 assign(op2, load(Ity_I32, mkexpr(op2addr)));
2736 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2737 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, op2);
2738 put_gpr_w1(r1, mkexpr(result));
2739
2740 return "aly";
2741}
2742
2743static HChar *
2744s390_irgen_ALG(UChar r1, IRTemp op2addr)
2745{
2746 IRTemp op1 = newTemp(Ity_I64);
2747 IRTemp op2 = newTemp(Ity_I64);
2748 IRTemp result = newTemp(Ity_I64);
2749
2750 assign(op1, get_gpr_dw0(r1));
2751 assign(op2, load(Ity_I64, mkexpr(op2addr)));
2752 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2753 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
2754 put_gpr_dw0(r1, mkexpr(result));
2755
2756 return "alg";
2757}
2758
2759static HChar *
2760s390_irgen_ALGF(UChar r1, IRTemp op2addr)
2761{
2762 IRTemp op1 = newTemp(Ity_I64);
2763 IRTemp op2 = newTemp(Ity_I64);
2764 IRTemp result = newTemp(Ity_I64);
2765
2766 assign(op1, get_gpr_dw0(r1));
2767 assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
2768 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2769 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
2770 put_gpr_dw0(r1, mkexpr(result));
2771
2772 return "algf";
2773}
2774
2775static HChar *
2776s390_irgen_ALFI(UChar r1, UInt i2)
2777{
2778 IRTemp op1 = newTemp(Ity_I32);
2779 UInt op2;
2780 IRTemp result = newTemp(Ity_I32);
2781
2782 assign(op1, get_gpr_w1(r1));
2783 op2 = i2;
2784 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
2785 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, mktemp(Ity_I32,
2786 mkU32(op2)));
2787 put_gpr_w1(r1, mkexpr(result));
2788
2789 return "alfi";
2790}
2791
2792static HChar *
2793s390_irgen_ALGFI(UChar r1, UInt i2)
2794{
2795 IRTemp op1 = newTemp(Ity_I64);
2796 ULong op2;
2797 IRTemp result = newTemp(Ity_I64);
2798
2799 assign(op1, get_gpr_dw0(r1));
2800 op2 = (ULong)i2;
2801 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64(op2)));
2802 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, mktemp(Ity_I64,
2803 mkU64(op2)));
2804 put_gpr_dw0(r1, mkexpr(result));
2805
2806 return "algfi";
2807}
2808
2809static HChar *
2810s390_irgen_ALHHHR(UChar r3, UChar r1, UChar r2)
2811{
2812 IRTemp op2 = newTemp(Ity_I32);
2813 IRTemp op3 = newTemp(Ity_I32);
2814 IRTemp result = newTemp(Ity_I32);
2815
2816 assign(op2, get_gpr_w0(r2));
2817 assign(op3, get_gpr_w0(r3));
2818 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2819 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
2820 put_gpr_w0(r1, mkexpr(result));
2821
2822 return "alhhhr";
2823}
2824
2825static HChar *
2826s390_irgen_ALHHLR(UChar r3, UChar r1, UChar r2)
2827{
2828 IRTemp op2 = newTemp(Ity_I32);
2829 IRTemp op3 = newTemp(Ity_I32);
2830 IRTemp result = newTemp(Ity_I32);
2831
2832 assign(op2, get_gpr_w0(r2));
2833 assign(op3, get_gpr_w1(r3));
2834 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2835 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
2836 put_gpr_w0(r1, mkexpr(result));
2837
2838 return "alhhlr";
2839}
2840
2841static HChar *
2842s390_irgen_ALCR(UChar r1, UChar r2)
2843{
2844 IRTemp op1 = newTemp(Ity_I32);
2845 IRTemp op2 = newTemp(Ity_I32);
2846 IRTemp result = newTemp(Ity_I32);
2847 IRTemp carry_in = newTemp(Ity_I32);
2848
2849 assign(op1, get_gpr_w1(r1));
2850 assign(op2, get_gpr_w1(r2));
2851 assign(carry_in, binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)));
2852 assign(result, binop(Iop_Add32, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)),
2853 mkexpr(carry_in)));
2854 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_32, op1, op2, carry_in);
2855 put_gpr_w1(r1, mkexpr(result));
2856
2857 return "alcr";
2858}
2859
2860static HChar *
2861s390_irgen_ALCGR(UChar r1, UChar r2)
2862{
2863 IRTemp op1 = newTemp(Ity_I64);
2864 IRTemp op2 = newTemp(Ity_I64);
2865 IRTemp result = newTemp(Ity_I64);
2866 IRTemp carry_in = newTemp(Ity_I64);
2867
2868 assign(op1, get_gpr_dw0(r1));
2869 assign(op2, get_gpr_dw0(r2));
2870 assign(carry_in, unop(Iop_32Uto64, binop(Iop_Shr32, s390_call_calculate_cc(),
2871 mkU8(1))));
2872 assign(result, binop(Iop_Add64, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)),
2873 mkexpr(carry_in)));
2874 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_64, op1, op2, carry_in);
2875 put_gpr_dw0(r1, mkexpr(result));
2876
2877 return "alcgr";
2878}
2879
2880static HChar *
2881s390_irgen_ALC(UChar r1, IRTemp op2addr)
2882{
2883 IRTemp op1 = newTemp(Ity_I32);
2884 IRTemp op2 = newTemp(Ity_I32);
2885 IRTemp result = newTemp(Ity_I32);
2886 IRTemp carry_in = newTemp(Ity_I32);
2887
2888 assign(op1, get_gpr_w1(r1));
2889 assign(op2, load(Ity_I32, mkexpr(op2addr)));
2890 assign(carry_in, binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)));
2891 assign(result, binop(Iop_Add32, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)),
2892 mkexpr(carry_in)));
2893 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_32, op1, op2, carry_in);
2894 put_gpr_w1(r1, mkexpr(result));
2895
2896 return "alc";
2897}
2898
2899static HChar *
2900s390_irgen_ALCG(UChar r1, IRTemp op2addr)
2901{
2902 IRTemp op1 = newTemp(Ity_I64);
2903 IRTemp op2 = newTemp(Ity_I64);
2904 IRTemp result = newTemp(Ity_I64);
2905 IRTemp carry_in = newTemp(Ity_I64);
2906
2907 assign(op1, get_gpr_dw0(r1));
2908 assign(op2, load(Ity_I64, mkexpr(op2addr)));
2909 assign(carry_in, unop(Iop_32Uto64, binop(Iop_Shr32, s390_call_calculate_cc(),
2910 mkU8(1))));
2911 assign(result, binop(Iop_Add64, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)),
2912 mkexpr(carry_in)));
2913 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_64, op1, op2, carry_in);
2914 put_gpr_dw0(r1, mkexpr(result));
2915
2916 return "alcg";
2917}
2918
2919static HChar *
2920s390_irgen_ALSI(UChar i2, IRTemp op1addr)
2921{
2922 IRTemp op1 = newTemp(Ity_I32);
2923 UInt op2;
2924 IRTemp result = newTemp(Ity_I32);
2925
2926 assign(op1, load(Ity_I32, mkexpr(op1addr)));
2927 op2 = (UInt)(Int)(Char)i2;
2928 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
2929 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, mktemp(Ity_I32,
2930 mkU32(op2)));
2931 store(mkexpr(op1addr), mkexpr(result));
2932
2933 return "alsi";
2934}
2935
2936static HChar *
2937s390_irgen_ALGSI(UChar i2, IRTemp op1addr)
2938{
2939 IRTemp op1 = newTemp(Ity_I64);
2940 ULong op2;
2941 IRTemp result = newTemp(Ity_I64);
2942
2943 assign(op1, load(Ity_I64, mkexpr(op1addr)));
2944 op2 = (ULong)(Long)(Char)i2;
2945 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64(op2)));
2946 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, mktemp(Ity_I64,
2947 mkU64(op2)));
2948 store(mkexpr(op1addr), mkexpr(result));
2949
2950 return "algsi";
2951}
2952
2953static HChar *
2954s390_irgen_ALHSIK(UChar r1, UChar r3, UShort i2)
2955{
2956 UInt op2;
2957 IRTemp op3 = newTemp(Ity_I32);
2958 IRTemp result = newTemp(Ity_I32);
2959
2960 op2 = (UInt)(Int)(Short)i2;
2961 assign(op3, get_gpr_w1(r3));
2962 assign(result, binop(Iop_Add32, mkU32(op2), mkexpr(op3)));
2963 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, mktemp(Ity_I32, mkU32(op2)),
2964 op3);
2965 put_gpr_w1(r1, mkexpr(result));
2966
2967 return "alhsik";
2968}
2969
2970static HChar *
2971s390_irgen_ALGHSIK(UChar r1, UChar r3, UShort i2)
2972{
2973 ULong op2;
2974 IRTemp op3 = newTemp(Ity_I64);
2975 IRTemp result = newTemp(Ity_I64);
2976
2977 op2 = (ULong)(Long)(Short)i2;
2978 assign(op3, get_gpr_dw0(r3));
2979 assign(result, binop(Iop_Add64, mkU64(op2), mkexpr(op3)));
2980 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, mktemp(Ity_I64, mkU64(op2)),
2981 op3);
2982 put_gpr_dw0(r1, mkexpr(result));
2983
2984 return "alghsik";
2985}
2986
2987static HChar *
2988s390_irgen_ALSIH(UChar r1, UInt i2)
2989{
2990 IRTemp op1 = newTemp(Ity_I32);
2991 UInt op2;
2992 IRTemp result = newTemp(Ity_I32);
2993
2994 assign(op1, get_gpr_w0(r1));
2995 op2 = i2;
2996 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
2997 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, mktemp(Ity_I32,
2998 mkU32(op2)));
2999 put_gpr_w0(r1, mkexpr(result));
3000
3001 return "alsih";
3002}
3003
3004static HChar *
3005s390_irgen_ALSIHN(UChar r1, UInt i2)
3006{
3007 IRTemp op1 = newTemp(Ity_I32);
3008 UInt op2;
3009 IRTemp result = newTemp(Ity_I32);
3010
3011 assign(op1, get_gpr_w0(r1));
3012 op2 = i2;
3013 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
3014 put_gpr_w0(r1, mkexpr(result));
3015
3016 return "alsihn";
3017}
3018
3019static HChar *
3020s390_irgen_NR(UChar r1, UChar r2)
3021{
3022 IRTemp op1 = newTemp(Ity_I32);
3023 IRTemp op2 = newTemp(Ity_I32);
3024 IRTemp result = newTemp(Ity_I32);
3025
3026 assign(op1, get_gpr_w1(r1));
3027 assign(op2, get_gpr_w1(r2));
3028 assign(result, binop(Iop_And32, mkexpr(op1), mkexpr(op2)));
3029 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3030 put_gpr_w1(r1, mkexpr(result));
3031
3032 return "nr";
3033}
3034
3035static HChar *
3036s390_irgen_NGR(UChar r1, UChar r2)
3037{
3038 IRTemp op1 = newTemp(Ity_I64);
3039 IRTemp op2 = newTemp(Ity_I64);
3040 IRTemp result = newTemp(Ity_I64);
3041
3042 assign(op1, get_gpr_dw0(r1));
3043 assign(op2, get_gpr_dw0(r2));
3044 assign(result, binop(Iop_And64, mkexpr(op1), mkexpr(op2)));
3045 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3046 put_gpr_dw0(r1, mkexpr(result));
3047
3048 return "ngr";
3049}
3050
3051static HChar *
3052s390_irgen_NRK(UChar r3, UChar r1, UChar r2)
3053{
3054 IRTemp op2 = newTemp(Ity_I32);
3055 IRTemp op3 = newTemp(Ity_I32);
3056 IRTemp result = newTemp(Ity_I32);
3057
3058 assign(op2, get_gpr_w1(r2));
3059 assign(op3, get_gpr_w1(r3));
3060 assign(result, binop(Iop_And32, mkexpr(op2), mkexpr(op3)));
3061 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3062 put_gpr_w1(r1, mkexpr(result));
3063
3064 return "nrk";
3065}
3066
3067static HChar *
3068s390_irgen_NGRK(UChar r3, UChar r1, UChar r2)
3069{
3070 IRTemp op2 = newTemp(Ity_I64);
3071 IRTemp op3 = newTemp(Ity_I64);
3072 IRTemp result = newTemp(Ity_I64);
3073
3074 assign(op2, get_gpr_dw0(r2));
3075 assign(op3, get_gpr_dw0(r3));
3076 assign(result, binop(Iop_And64, mkexpr(op2), mkexpr(op3)));
3077 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3078 put_gpr_dw0(r1, mkexpr(result));
3079
3080 return "ngrk";
3081}
3082
3083static HChar *
3084s390_irgen_N(UChar r1, IRTemp op2addr)
3085{
3086 IRTemp op1 = newTemp(Ity_I32);
3087 IRTemp op2 = newTemp(Ity_I32);
3088 IRTemp result = newTemp(Ity_I32);
3089
3090 assign(op1, get_gpr_w1(r1));
3091 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3092 assign(result, binop(Iop_And32, mkexpr(op1), mkexpr(op2)));
3093 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3094 put_gpr_w1(r1, mkexpr(result));
3095
3096 return "n";
3097}
3098
3099static HChar *
3100s390_irgen_NY(UChar r1, IRTemp op2addr)
3101{
3102 IRTemp op1 = newTemp(Ity_I32);
3103 IRTemp op2 = newTemp(Ity_I32);
3104 IRTemp result = newTemp(Ity_I32);
3105
3106 assign(op1, get_gpr_w1(r1));
3107 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3108 assign(result, binop(Iop_And32, mkexpr(op1), mkexpr(op2)));
3109 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3110 put_gpr_w1(r1, mkexpr(result));
3111
3112 return "ny";
3113}
3114
3115static HChar *
3116s390_irgen_NG(UChar r1, IRTemp op2addr)
3117{
3118 IRTemp op1 = newTemp(Ity_I64);
3119 IRTemp op2 = newTemp(Ity_I64);
3120 IRTemp result = newTemp(Ity_I64);
3121
3122 assign(op1, get_gpr_dw0(r1));
3123 assign(op2, load(Ity_I64, mkexpr(op2addr)));
3124 assign(result, binop(Iop_And64, mkexpr(op1), mkexpr(op2)));
3125 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3126 put_gpr_dw0(r1, mkexpr(result));
3127
3128 return "ng";
3129}
3130
3131static HChar *
3132s390_irgen_NI(UChar i2, IRTemp op1addr)
3133{
3134 IRTemp op1 = newTemp(Ity_I8);
3135 UChar op2;
3136 IRTemp result = newTemp(Ity_I8);
3137
3138 assign(op1, load(Ity_I8, mkexpr(op1addr)));
3139 op2 = i2;
3140 assign(result, binop(Iop_And8, mkexpr(op1), mkU8(op2)));
3141 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3142 store(mkexpr(op1addr), mkexpr(result));
3143
3144 return "ni";
3145}
3146
3147static HChar *
3148s390_irgen_NIY(UChar i2, IRTemp op1addr)
3149{
3150 IRTemp op1 = newTemp(Ity_I8);
3151 UChar op2;
3152 IRTemp result = newTemp(Ity_I8);
3153
3154 assign(op1, load(Ity_I8, mkexpr(op1addr)));
3155 op2 = i2;
3156 assign(result, binop(Iop_And8, mkexpr(op1), mkU8(op2)));
3157 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3158 store(mkexpr(op1addr), mkexpr(result));
3159
3160 return "niy";
3161}
3162
3163static HChar *
3164s390_irgen_NIHF(UChar r1, UInt i2)
3165{
3166 IRTemp op1 = newTemp(Ity_I32);
3167 UInt op2;
3168 IRTemp result = newTemp(Ity_I32);
3169
3170 assign(op1, get_gpr_w0(r1));
3171 op2 = i2;
3172 assign(result, binop(Iop_And32, mkexpr(op1), mkU32(op2)));
3173 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3174 put_gpr_w0(r1, mkexpr(result));
3175
3176 return "nihf";
3177}
3178
3179static HChar *
3180s390_irgen_NIHH(UChar r1, UShort i2)
3181{
3182 IRTemp op1 = newTemp(Ity_I16);
3183 UShort op2;
3184 IRTemp result = newTemp(Ity_I16);
3185
3186 assign(op1, get_gpr_hw0(r1));
3187 op2 = i2;
3188 assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
3189 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3190 put_gpr_hw0(r1, mkexpr(result));
3191
3192 return "nihh";
3193}
3194
3195static HChar *
3196s390_irgen_NIHL(UChar r1, UShort i2)
3197{
3198 IRTemp op1 = newTemp(Ity_I16);
3199 UShort op2;
3200 IRTemp result = newTemp(Ity_I16);
3201
3202 assign(op1, get_gpr_hw1(r1));
3203 op2 = i2;
3204 assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
3205 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3206 put_gpr_hw1(r1, mkexpr(result));
3207
3208 return "nihl";
3209}
3210
3211static HChar *
3212s390_irgen_NILF(UChar r1, UInt i2)
3213{
3214 IRTemp op1 = newTemp(Ity_I32);
3215 UInt op2;
3216 IRTemp result = newTemp(Ity_I32);
3217
3218 assign(op1, get_gpr_w1(r1));
3219 op2 = i2;
3220 assign(result, binop(Iop_And32, mkexpr(op1), mkU32(op2)));
3221 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3222 put_gpr_w1(r1, mkexpr(result));
3223
3224 return "nilf";
3225}
3226
3227static HChar *
3228s390_irgen_NILH(UChar r1, UShort i2)
3229{
3230 IRTemp op1 = newTemp(Ity_I16);
3231 UShort op2;
3232 IRTemp result = newTemp(Ity_I16);
3233
3234 assign(op1, get_gpr_hw2(r1));
3235 op2 = i2;
3236 assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
3237 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3238 put_gpr_hw2(r1, mkexpr(result));
3239
3240 return "nilh";
3241}
3242
3243static HChar *
3244s390_irgen_NILL(UChar r1, UShort i2)
3245{
3246 IRTemp op1 = newTemp(Ity_I16);
3247 UShort op2;
3248 IRTemp result = newTemp(Ity_I16);
3249
3250 assign(op1, get_gpr_hw3(r1));
3251 op2 = i2;
3252 assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
3253 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3254 put_gpr_hw3(r1, mkexpr(result));
3255
3256 return "nill";
3257}
3258
3259static HChar *
3260s390_irgen_BASR(UChar r1, UChar r2)
3261{
3262 IRTemp target = newTemp(Ity_I64);
3263
3264 if (r2 == 0) {
3265 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 2ULL));
3266 } else {
3267 if (r1 != r2) {
3268 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 2ULL));
3269 call_function(get_gpr_dw0(r2));
3270 } else {
3271 assign(target, get_gpr_dw0(r2));
3272 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 2ULL));
3273 call_function(mkexpr(target));
3274 }
3275 }
3276
3277 return "basr";
3278}
3279
3280static HChar *
3281s390_irgen_BAS(UChar r1, IRTemp op2addr)
3282{
3283 IRTemp target = newTemp(Ity_I64);
3284
3285 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 4ULL));
3286 assign(target, mkexpr(op2addr));
3287 call_function(mkexpr(target));
3288
3289 return "bas";
3290}
3291
3292static HChar *
3293s390_irgen_BCR(UChar r1, UChar r2)
3294{
3295 IRTemp cond = newTemp(Ity_I32);
3296
sewardja52e37e2011-04-28 18:48:06 +00003297 if (r2 == 0 && (r1 >= 14)) { /* serialization */
3298 stmt(IRStmt_MBE(Imbe_Fence));
3299 }
3300
sewardj2019a972011-03-07 16:04:07 +00003301 if ((r2 == 0) || (r1 == 0)) {
3302 } else {
3303 if (r1 == 15) {
3304 return_from_function(get_gpr_dw0(r2));
3305 } else {
3306 assign(cond, s390_call_calculate_cond(r1));
florianf321da72012-07-21 20:32:57 +00003307 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3308 get_gpr_dw0(r2));
sewardj2019a972011-03-07 16:04:07 +00003309 }
3310 }
sewardj7ee97522011-05-09 21:45:04 +00003311 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00003312 s390_disasm(ENC2(XMNM, GPR), S390_XMNM_BCR, r1, r2);
3313
3314 return "bcr";
3315}
3316
3317static HChar *
3318s390_irgen_BC(UChar r1, UChar x2, UChar b2, UShort d2, IRTemp op2addr)
3319{
3320 IRTemp cond = newTemp(Ity_I32);
3321
3322 if (r1 == 0) {
3323 } else {
3324 if (r1 == 15) {
3325 always_goto(mkexpr(op2addr));
3326 } else {
3327 assign(cond, s390_call_calculate_cond(r1));
florianf321da72012-07-21 20:32:57 +00003328 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3329 mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003330 }
3331 }
sewardj7ee97522011-05-09 21:45:04 +00003332 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00003333 s390_disasm(ENC2(XMNM, UDXB), S390_XMNM_BC, r1, d2, x2, b2);
3334
3335 return "bc";
3336}
3337
3338static HChar *
3339s390_irgen_BCTR(UChar r1, UChar r2)
3340{
3341 put_gpr_w1(r1, binop(Iop_Sub32, get_gpr_w1(r1), mkU32(1)));
3342 if (r2 != 0) {
florianf321da72012-07-21 20:32:57 +00003343 if_condition_goto_computed(binop(Iop_CmpNE32, get_gpr_w1(r1), mkU32(0)),
3344 get_gpr_dw0(r2));
sewardj2019a972011-03-07 16:04:07 +00003345 }
3346
3347 return "bctr";
3348}
3349
3350static HChar *
3351s390_irgen_BCTGR(UChar r1, UChar r2)
3352{
3353 put_gpr_dw0(r1, binop(Iop_Sub64, get_gpr_dw0(r1), mkU64(1)));
3354 if (r2 != 0) {
florianf321da72012-07-21 20:32:57 +00003355 if_condition_goto_computed(binop(Iop_CmpNE64, get_gpr_dw0(r1), mkU64(0)),
3356 get_gpr_dw0(r2));
sewardj2019a972011-03-07 16:04:07 +00003357 }
3358
3359 return "bctgr";
3360}
3361
3362static HChar *
3363s390_irgen_BCT(UChar r1, IRTemp op2addr)
3364{
3365 put_gpr_w1(r1, binop(Iop_Sub32, get_gpr_w1(r1), mkU32(1)));
florianf321da72012-07-21 20:32:57 +00003366 if_condition_goto_computed(binop(Iop_CmpNE32, get_gpr_w1(r1), mkU32(0)),
3367 mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003368
3369 return "bct";
3370}
3371
3372static HChar *
3373s390_irgen_BCTG(UChar r1, IRTemp op2addr)
3374{
3375 put_gpr_dw0(r1, binop(Iop_Sub64, get_gpr_dw0(r1), mkU64(1)));
florianf321da72012-07-21 20:32:57 +00003376 if_condition_goto_computed(binop(Iop_CmpNE64, get_gpr_dw0(r1), mkU64(0)),
3377 mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003378
3379 return "bctg";
3380}
3381
3382static HChar *
3383s390_irgen_BXH(UChar r1, UChar r3, IRTemp op2addr)
3384{
3385 IRTemp value = newTemp(Ity_I32);
3386
3387 assign(value, get_gpr_w1(r3 | 1));
3388 put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
florianf321da72012-07-21 20:32:57 +00003389 if_condition_goto_computed(binop(Iop_CmpLT32S, mkexpr(value),
3390 get_gpr_w1(r1)), mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003391
3392 return "bxh";
3393}
3394
3395static HChar *
3396s390_irgen_BXHG(UChar r1, UChar r3, IRTemp op2addr)
3397{
3398 IRTemp value = newTemp(Ity_I64);
3399
3400 assign(value, get_gpr_dw0(r3 | 1));
3401 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
florianf321da72012-07-21 20:32:57 +00003402 if_condition_goto_computed(binop(Iop_CmpLT64S, mkexpr(value),
3403 get_gpr_dw0(r1)), mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003404
3405 return "bxhg";
3406}
3407
3408static HChar *
3409s390_irgen_BXLE(UChar r1, UChar r3, IRTemp op2addr)
3410{
3411 IRTemp value = newTemp(Ity_I32);
3412
3413 assign(value, get_gpr_w1(r3 | 1));
3414 put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
florianf321da72012-07-21 20:32:57 +00003415 if_condition_goto_computed(binop(Iop_CmpLE32S, get_gpr_w1(r1),
3416 mkexpr(value)), mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003417
3418 return "bxle";
3419}
3420
3421static HChar *
3422s390_irgen_BXLEG(UChar r1, UChar r3, IRTemp op2addr)
3423{
3424 IRTemp value = newTemp(Ity_I64);
3425
3426 assign(value, get_gpr_dw0(r3 | 1));
3427 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
florianf321da72012-07-21 20:32:57 +00003428 if_condition_goto_computed(binop(Iop_CmpLE64S, get_gpr_dw0(r1),
3429 mkexpr(value)), mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003430
3431 return "bxleg";
3432}
3433
3434static HChar *
3435s390_irgen_BRAS(UChar r1, UShort i2)
3436{
3437 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 4ULL));
floriana64c2432011-07-16 02:11:50 +00003438 call_function_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
sewardj2019a972011-03-07 16:04:07 +00003439
3440 return "bras";
3441}
3442
3443static HChar *
3444s390_irgen_BRASL(UChar r1, UInt i2)
3445{
3446 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 6ULL));
floriana64c2432011-07-16 02:11:50 +00003447 call_function_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1));
sewardj2019a972011-03-07 16:04:07 +00003448
3449 return "brasl";
3450}
3451
3452static HChar *
3453s390_irgen_BRC(UChar r1, UShort i2)
3454{
3455 IRTemp cond = newTemp(Ity_I32);
3456
3457 if (r1 == 0) {
3458 } else {
3459 if (r1 == 15) {
floriana64c2432011-07-16 02:11:50 +00003460 always_goto_and_chase(
3461 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
sewardj2019a972011-03-07 16:04:07 +00003462 } else {
3463 assign(cond, s390_call_calculate_cond(r1));
3464 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3465 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3466
3467 }
3468 }
sewardj7ee97522011-05-09 21:45:04 +00003469 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00003470 s390_disasm(ENC2(XMNM, PCREL), S390_XMNM_BRC, r1, (Int)(Short)i2);
3471
3472 return "brc";
3473}
3474
3475static HChar *
3476s390_irgen_BRCL(UChar r1, UInt i2)
3477{
3478 IRTemp cond = newTemp(Ity_I32);
3479
3480 if (r1 == 0) {
3481 } else {
3482 if (r1 == 15) {
floriana64c2432011-07-16 02:11:50 +00003483 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1));
sewardj2019a972011-03-07 16:04:07 +00003484 } else {
3485 assign(cond, s390_call_calculate_cond(r1));
3486 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3487 guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1));
3488 }
3489 }
sewardj7ee97522011-05-09 21:45:04 +00003490 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00003491 s390_disasm(ENC2(XMNM, PCREL), S390_XMNM_BRCL, r1, i2);
3492
3493 return "brcl";
3494}
3495
3496static HChar *
3497s390_irgen_BRCT(UChar r1, UShort i2)
3498{
3499 put_gpr_w1(r1, binop(Iop_Sub32, get_gpr_w1(r1), mkU32(1)));
3500 if_condition_goto(binop(Iop_CmpNE32, get_gpr_w1(r1), mkU32(0)),
3501 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3502
3503 return "brct";
3504}
3505
3506static HChar *
3507s390_irgen_BRCTG(UChar r1, UShort i2)
3508{
3509 put_gpr_dw0(r1, binop(Iop_Sub64, get_gpr_dw0(r1), mkU64(1)));
3510 if_condition_goto(binop(Iop_CmpNE64, get_gpr_dw0(r1), mkU64(0)),
3511 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3512
3513 return "brctg";
3514}
3515
3516static HChar *
3517s390_irgen_BRXH(UChar r1, UChar r3, UShort i2)
3518{
3519 IRTemp value = newTemp(Ity_I32);
3520
3521 assign(value, get_gpr_w1(r3 | 1));
3522 put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
3523 if_condition_goto(binop(Iop_CmpLT32S, mkexpr(value), get_gpr_w1(r1)),
3524 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3525
3526 return "brxh";
3527}
3528
3529static HChar *
3530s390_irgen_BRXHG(UChar r1, UChar r3, UShort i2)
3531{
3532 IRTemp value = newTemp(Ity_I64);
3533
3534 assign(value, get_gpr_dw0(r3 | 1));
3535 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
3536 if_condition_goto(binop(Iop_CmpLT64S, mkexpr(value), get_gpr_dw0(r1)),
3537 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3538
3539 return "brxhg";
3540}
3541
3542static HChar *
3543s390_irgen_BRXLE(UChar r1, UChar r3, UShort i2)
3544{
3545 IRTemp value = newTemp(Ity_I32);
3546
3547 assign(value, get_gpr_w1(r3 | 1));
3548 put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
3549 if_condition_goto(binop(Iop_CmpLE32S, get_gpr_w1(r1), mkexpr(value)),
3550 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3551
3552 return "brxle";
3553}
3554
3555static HChar *
3556s390_irgen_BRXLG(UChar r1, UChar r3, UShort i2)
3557{
3558 IRTemp value = newTemp(Ity_I64);
3559
3560 assign(value, get_gpr_dw0(r3 | 1));
3561 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
3562 if_condition_goto(binop(Iop_CmpLE64S, get_gpr_dw0(r1), mkexpr(value)),
3563 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3564
3565 return "brxlg";
3566}
3567
3568static HChar *
3569s390_irgen_CR(UChar r1, UChar r2)
3570{
3571 IRTemp op1 = newTemp(Ity_I32);
3572 IRTemp op2 = newTemp(Ity_I32);
3573
3574 assign(op1, get_gpr_w1(r1));
3575 assign(op2, get_gpr_w1(r2));
3576 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3577
3578 return "cr";
3579}
3580
3581static HChar *
3582s390_irgen_CGR(UChar r1, UChar r2)
3583{
3584 IRTemp op1 = newTemp(Ity_I64);
3585 IRTemp op2 = newTemp(Ity_I64);
3586
3587 assign(op1, get_gpr_dw0(r1));
3588 assign(op2, get_gpr_dw0(r2));
3589 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3590
3591 return "cgr";
3592}
3593
3594static HChar *
3595s390_irgen_CGFR(UChar r1, UChar r2)
3596{
3597 IRTemp op1 = newTemp(Ity_I64);
3598 IRTemp op2 = newTemp(Ity_I64);
3599
3600 assign(op1, get_gpr_dw0(r1));
3601 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
3602 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3603
3604 return "cgfr";
3605}
3606
3607static HChar *
3608s390_irgen_C(UChar r1, IRTemp op2addr)
3609{
3610 IRTemp op1 = newTemp(Ity_I32);
3611 IRTemp op2 = newTemp(Ity_I32);
3612
3613 assign(op1, get_gpr_w1(r1));
3614 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3615 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3616
3617 return "c";
3618}
3619
3620static HChar *
3621s390_irgen_CY(UChar r1, IRTemp op2addr)
3622{
3623 IRTemp op1 = newTemp(Ity_I32);
3624 IRTemp op2 = newTemp(Ity_I32);
3625
3626 assign(op1, get_gpr_w1(r1));
3627 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3628 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3629
3630 return "cy";
3631}
3632
3633static HChar *
3634s390_irgen_CG(UChar r1, IRTemp op2addr)
3635{
3636 IRTemp op1 = newTemp(Ity_I64);
3637 IRTemp op2 = newTemp(Ity_I64);
3638
3639 assign(op1, get_gpr_dw0(r1));
3640 assign(op2, load(Ity_I64, mkexpr(op2addr)));
3641 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3642
3643 return "cg";
3644}
3645
3646static HChar *
3647s390_irgen_CGF(UChar r1, IRTemp op2addr)
3648{
3649 IRTemp op1 = newTemp(Ity_I64);
3650 IRTemp op2 = newTemp(Ity_I64);
3651
3652 assign(op1, get_gpr_dw0(r1));
3653 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
3654 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3655
3656 return "cgf";
3657}
3658
3659static HChar *
3660s390_irgen_CFI(UChar r1, UInt i2)
3661{
3662 IRTemp op1 = newTemp(Ity_I32);
3663 Int op2;
3664
3665 assign(op1, get_gpr_w1(r1));
3666 op2 = (Int)i2;
3667 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
3668 mkU32((UInt)op2)));
3669
3670 return "cfi";
3671}
3672
3673static HChar *
3674s390_irgen_CGFI(UChar r1, UInt i2)
3675{
3676 IRTemp op1 = newTemp(Ity_I64);
3677 Long op2;
3678
3679 assign(op1, get_gpr_dw0(r1));
3680 op2 = (Long)(Int)i2;
3681 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I64,
3682 mkU64((ULong)op2)));
3683
3684 return "cgfi";
3685}
3686
3687static HChar *
3688s390_irgen_CRL(UChar r1, UInt i2)
3689{
3690 IRTemp op1 = newTemp(Ity_I32);
3691 IRTemp op2 = newTemp(Ity_I32);
3692
3693 assign(op1, get_gpr_w1(r1));
3694 assign(op2, load(Ity_I32, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
3695 i2 << 1))));
3696 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3697
3698 return "crl";
3699}
3700
3701static HChar *
3702s390_irgen_CGRL(UChar r1, UInt i2)
3703{
3704 IRTemp op1 = newTemp(Ity_I64);
3705 IRTemp op2 = newTemp(Ity_I64);
3706
3707 assign(op1, get_gpr_dw0(r1));
3708 assign(op2, load(Ity_I64, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
3709 i2 << 1))));
3710 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3711
3712 return "cgrl";
3713}
3714
3715static HChar *
3716s390_irgen_CGFRL(UChar r1, UInt i2)
3717{
3718 IRTemp op1 = newTemp(Ity_I64);
3719 IRTemp op2 = newTemp(Ity_I64);
3720
3721 assign(op1, get_gpr_dw0(r1));
3722 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
3723 ((ULong)(Long)(Int)i2 << 1)))));
3724 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3725
3726 return "cgfrl";
3727}
3728
3729static HChar *
3730s390_irgen_CRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
3731{
3732 IRTemp op1 = newTemp(Ity_I32);
3733 IRTemp op2 = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00003734 IRTemp cond = newTemp(Ity_I32);
3735
3736 if (m3 == 0) {
3737 } else {
3738 if (m3 == 14) {
3739 always_goto(mkexpr(op4addr));
3740 } else {
3741 assign(op1, get_gpr_w1(r1));
3742 assign(op2, get_gpr_w1(r2));
florianff9613f2012-05-12 15:26:44 +00003743 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
3744 op1, op2));
florianf321da72012-07-21 20:32:57 +00003745 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond),
3746 mkU32(0)), mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00003747 }
3748 }
3749
3750 return "crb";
3751}
3752
3753static HChar *
3754s390_irgen_CGRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
3755{
3756 IRTemp op1 = newTemp(Ity_I64);
3757 IRTemp op2 = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00003758 IRTemp cond = newTemp(Ity_I32);
3759
3760 if (m3 == 0) {
3761 } else {
3762 if (m3 == 14) {
3763 always_goto(mkexpr(op4addr));
3764 } else {
3765 assign(op1, get_gpr_dw0(r1));
3766 assign(op2, get_gpr_dw0(r2));
florianff9613f2012-05-12 15:26:44 +00003767 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
3768 op1, op2));
florianf321da72012-07-21 20:32:57 +00003769 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond),
3770 mkU32(0)), mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00003771 }
3772 }
3773
3774 return "cgrb";
3775}
3776
3777static HChar *
3778s390_irgen_CRJ(UChar r1, UChar r2, UShort i4, UChar m3)
3779{
3780 IRTemp op1 = newTemp(Ity_I32);
3781 IRTemp op2 = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00003782 IRTemp cond = newTemp(Ity_I32);
3783
3784 if (m3 == 0) {
3785 } else {
3786 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00003787 always_goto_and_chase(
3788 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00003789 } else {
3790 assign(op1, get_gpr_w1(r1));
3791 assign(op2, get_gpr_w1(r2));
florianff9613f2012-05-12 15:26:44 +00003792 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
3793 op1, op2));
sewardj2019a972011-03-07 16:04:07 +00003794 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3795 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
3796
3797 }
3798 }
3799
3800 return "crj";
3801}
3802
3803static HChar *
3804s390_irgen_CGRJ(UChar r1, UChar r2, UShort i4, UChar m3)
3805{
3806 IRTemp op1 = newTemp(Ity_I64);
3807 IRTemp op2 = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00003808 IRTemp cond = newTemp(Ity_I32);
3809
3810 if (m3 == 0) {
3811 } else {
3812 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00003813 always_goto_and_chase(
3814 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00003815 } else {
3816 assign(op1, get_gpr_dw0(r1));
3817 assign(op2, get_gpr_dw0(r2));
florianff9613f2012-05-12 15:26:44 +00003818 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
3819 op1, op2));
sewardj2019a972011-03-07 16:04:07 +00003820 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3821 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
3822
3823 }
3824 }
3825
3826 return "cgrj";
3827}
3828
3829static HChar *
3830s390_irgen_CIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
3831{
3832 IRTemp op1 = newTemp(Ity_I32);
3833 Int op2;
sewardj2019a972011-03-07 16:04:07 +00003834 IRTemp cond = newTemp(Ity_I32);
3835
3836 if (m3 == 0) {
3837 } else {
3838 if (m3 == 14) {
3839 always_goto(mkexpr(op4addr));
3840 } else {
3841 assign(op1, get_gpr_w1(r1));
3842 op2 = (Int)(Char)i2;
florianff9613f2012-05-12 15:26:44 +00003843 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
3844 mktemp(Ity_I32, mkU32((UInt)op2))));
florianf321da72012-07-21 20:32:57 +00003845 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3846 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00003847 }
3848 }
3849
3850 return "cib";
3851}
3852
3853static HChar *
3854s390_irgen_CGIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
3855{
3856 IRTemp op1 = newTemp(Ity_I64);
3857 Long op2;
sewardj2019a972011-03-07 16:04:07 +00003858 IRTemp cond = newTemp(Ity_I32);
3859
3860 if (m3 == 0) {
3861 } else {
3862 if (m3 == 14) {
3863 always_goto(mkexpr(op4addr));
3864 } else {
3865 assign(op1, get_gpr_dw0(r1));
3866 op2 = (Long)(Char)i2;
florianff9613f2012-05-12 15:26:44 +00003867 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
3868 mktemp(Ity_I64, mkU64((ULong)op2))));
florianf321da72012-07-21 20:32:57 +00003869 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3870 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00003871 }
3872 }
3873
3874 return "cgib";
3875}
3876
3877static HChar *
3878s390_irgen_CIJ(UChar r1, UChar m3, UShort i4, UChar i2)
3879{
3880 IRTemp op1 = newTemp(Ity_I32);
3881 Int op2;
sewardj2019a972011-03-07 16:04:07 +00003882 IRTemp cond = newTemp(Ity_I32);
3883
3884 if (m3 == 0) {
3885 } else {
3886 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00003887 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00003888 } else {
3889 assign(op1, get_gpr_w1(r1));
3890 op2 = (Int)(Char)i2;
florianff9613f2012-05-12 15:26:44 +00003891 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
3892 mktemp(Ity_I32, mkU32((UInt)op2))));
sewardj2019a972011-03-07 16:04:07 +00003893 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3894 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
3895
3896 }
3897 }
3898
3899 return "cij";
3900}
3901
3902static HChar *
3903s390_irgen_CGIJ(UChar r1, UChar m3, UShort i4, UChar i2)
3904{
3905 IRTemp op1 = newTemp(Ity_I64);
3906 Long op2;
sewardj2019a972011-03-07 16:04:07 +00003907 IRTemp cond = newTemp(Ity_I32);
3908
3909 if (m3 == 0) {
3910 } else {
3911 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00003912 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00003913 } else {
3914 assign(op1, get_gpr_dw0(r1));
3915 op2 = (Long)(Char)i2;
florianff9613f2012-05-12 15:26:44 +00003916 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
3917 mktemp(Ity_I64, mkU64((ULong)op2))));
sewardj2019a972011-03-07 16:04:07 +00003918 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3919 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
3920
3921 }
3922 }
3923
3924 return "cgij";
3925}
3926
3927static HChar *
3928s390_irgen_CH(UChar r1, IRTemp op2addr)
3929{
3930 IRTemp op1 = newTemp(Ity_I32);
3931 IRTemp op2 = newTemp(Ity_I32);
3932
3933 assign(op1, get_gpr_w1(r1));
3934 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
3935 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3936
3937 return "ch";
3938}
3939
3940static HChar *
3941s390_irgen_CHY(UChar r1, IRTemp op2addr)
3942{
3943 IRTemp op1 = newTemp(Ity_I32);
3944 IRTemp op2 = newTemp(Ity_I32);
3945
3946 assign(op1, get_gpr_w1(r1));
3947 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
3948 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3949
3950 return "chy";
3951}
3952
3953static HChar *
3954s390_irgen_CGH(UChar r1, IRTemp op2addr)
3955{
3956 IRTemp op1 = newTemp(Ity_I64);
3957 IRTemp op2 = newTemp(Ity_I64);
3958
3959 assign(op1, get_gpr_dw0(r1));
3960 assign(op2, unop(Iop_16Sto64, load(Ity_I16, mkexpr(op2addr))));
3961 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3962
3963 return "cgh";
3964}
3965
3966static HChar *
3967s390_irgen_CHI(UChar r1, UShort i2)
3968{
3969 IRTemp op1 = newTemp(Ity_I32);
3970 Int op2;
3971
3972 assign(op1, get_gpr_w1(r1));
3973 op2 = (Int)(Short)i2;
3974 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
3975 mkU32((UInt)op2)));
3976
3977 return "chi";
3978}
3979
3980static HChar *
3981s390_irgen_CGHI(UChar r1, UShort i2)
3982{
3983 IRTemp op1 = newTemp(Ity_I64);
3984 Long op2;
3985
3986 assign(op1, get_gpr_dw0(r1));
3987 op2 = (Long)(Short)i2;
3988 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I64,
3989 mkU64((ULong)op2)));
3990
3991 return "cghi";
3992}
3993
3994static HChar *
3995s390_irgen_CHHSI(UShort i2, IRTemp op1addr)
3996{
3997 IRTemp op1 = newTemp(Ity_I16);
3998 Short op2;
3999
4000 assign(op1, load(Ity_I16, mkexpr(op1addr)));
4001 op2 = (Short)i2;
4002 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I16,
4003 mkU16((UShort)op2)));
4004
4005 return "chhsi";
4006}
4007
4008static HChar *
4009s390_irgen_CHSI(UShort i2, IRTemp op1addr)
4010{
4011 IRTemp op1 = newTemp(Ity_I32);
4012 Int op2;
4013
4014 assign(op1, load(Ity_I32, mkexpr(op1addr)));
4015 op2 = (Int)(Short)i2;
4016 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
4017 mkU32((UInt)op2)));
4018
4019 return "chsi";
4020}
4021
4022static HChar *
4023s390_irgen_CGHSI(UShort i2, IRTemp op1addr)
4024{
4025 IRTemp op1 = newTemp(Ity_I64);
4026 Long op2;
4027
4028 assign(op1, load(Ity_I64, mkexpr(op1addr)));
4029 op2 = (Long)(Short)i2;
4030 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I64,
4031 mkU64((ULong)op2)));
4032
4033 return "cghsi";
4034}
4035
4036static HChar *
4037s390_irgen_CHRL(UChar r1, UInt i2)
4038{
4039 IRTemp op1 = newTemp(Ity_I32);
4040 IRTemp op2 = newTemp(Ity_I32);
4041
4042 assign(op1, get_gpr_w1(r1));
4043 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
4044 ((ULong)(Long)(Int)i2 << 1)))));
4045 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4046
4047 return "chrl";
4048}
4049
4050static HChar *
4051s390_irgen_CGHRL(UChar r1, UInt i2)
4052{
4053 IRTemp op1 = newTemp(Ity_I64);
4054 IRTemp op2 = newTemp(Ity_I64);
4055
4056 assign(op1, get_gpr_dw0(r1));
4057 assign(op2, unop(Iop_16Sto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
4058 ((ULong)(Long)(Int)i2 << 1)))));
4059 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4060
4061 return "cghrl";
4062}
4063
4064static HChar *
4065s390_irgen_CHHR(UChar r1, UChar r2)
4066{
4067 IRTemp op1 = newTemp(Ity_I32);
4068 IRTemp op2 = newTemp(Ity_I32);
4069
4070 assign(op1, get_gpr_w0(r1));
4071 assign(op2, get_gpr_w0(r2));
4072 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4073
4074 return "chhr";
4075}
4076
4077static HChar *
4078s390_irgen_CHLR(UChar r1, UChar r2)
4079{
4080 IRTemp op1 = newTemp(Ity_I32);
4081 IRTemp op2 = newTemp(Ity_I32);
4082
4083 assign(op1, get_gpr_w0(r1));
4084 assign(op2, get_gpr_w1(r2));
4085 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4086
4087 return "chlr";
4088}
4089
4090static HChar *
4091s390_irgen_CHF(UChar r1, IRTemp op2addr)
4092{
4093 IRTemp op1 = newTemp(Ity_I32);
4094 IRTemp op2 = newTemp(Ity_I32);
4095
4096 assign(op1, get_gpr_w0(r1));
4097 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4098 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4099
4100 return "chf";
4101}
4102
4103static HChar *
4104s390_irgen_CIH(UChar r1, UInt i2)
4105{
4106 IRTemp op1 = newTemp(Ity_I32);
4107 Int op2;
4108
4109 assign(op1, get_gpr_w0(r1));
4110 op2 = (Int)i2;
4111 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
4112 mkU32((UInt)op2)));
4113
4114 return "cih";
4115}
4116
4117static HChar *
4118s390_irgen_CLR(UChar r1, UChar r2)
4119{
4120 IRTemp op1 = newTemp(Ity_I32);
4121 IRTemp op2 = newTemp(Ity_I32);
4122
4123 assign(op1, get_gpr_w1(r1));
4124 assign(op2, get_gpr_w1(r2));
4125 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4126
4127 return "clr";
4128}
4129
4130static HChar *
4131s390_irgen_CLGR(UChar r1, UChar r2)
4132{
4133 IRTemp op1 = newTemp(Ity_I64);
4134 IRTemp op2 = newTemp(Ity_I64);
4135
4136 assign(op1, get_gpr_dw0(r1));
4137 assign(op2, get_gpr_dw0(r2));
4138 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4139
4140 return "clgr";
4141}
4142
4143static HChar *
4144s390_irgen_CLGFR(UChar r1, UChar r2)
4145{
4146 IRTemp op1 = newTemp(Ity_I64);
4147 IRTemp op2 = newTemp(Ity_I64);
4148
4149 assign(op1, get_gpr_dw0(r1));
4150 assign(op2, unop(Iop_32Uto64, get_gpr_w1(r2)));
4151 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4152
4153 return "clgfr";
4154}
4155
4156static HChar *
4157s390_irgen_CL(UChar r1, IRTemp op2addr)
4158{
4159 IRTemp op1 = newTemp(Ity_I32);
4160 IRTemp op2 = newTemp(Ity_I32);
4161
4162 assign(op1, get_gpr_w1(r1));
4163 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4164 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4165
4166 return "cl";
4167}
4168
4169static HChar *
4170s390_irgen_CLY(UChar r1, IRTemp op2addr)
4171{
4172 IRTemp op1 = newTemp(Ity_I32);
4173 IRTemp op2 = newTemp(Ity_I32);
4174
4175 assign(op1, get_gpr_w1(r1));
4176 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4177 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4178
4179 return "cly";
4180}
4181
4182static HChar *
4183s390_irgen_CLG(UChar r1, IRTemp op2addr)
4184{
4185 IRTemp op1 = newTemp(Ity_I64);
4186 IRTemp op2 = newTemp(Ity_I64);
4187
4188 assign(op1, get_gpr_dw0(r1));
4189 assign(op2, load(Ity_I64, mkexpr(op2addr)));
4190 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4191
4192 return "clg";
4193}
4194
4195static HChar *
4196s390_irgen_CLGF(UChar r1, IRTemp op2addr)
4197{
4198 IRTemp op1 = newTemp(Ity_I64);
4199 IRTemp op2 = newTemp(Ity_I64);
4200
4201 assign(op1, get_gpr_dw0(r1));
4202 assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
4203 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4204
4205 return "clgf";
4206}
4207
4208static HChar *
4209s390_irgen_CLFI(UChar r1, UInt i2)
4210{
4211 IRTemp op1 = newTemp(Ity_I32);
4212 UInt op2;
4213
4214 assign(op1, get_gpr_w1(r1));
4215 op2 = i2;
4216 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I32,
4217 mkU32(op2)));
4218
4219 return "clfi";
4220}
4221
4222static HChar *
4223s390_irgen_CLGFI(UChar r1, UInt i2)
4224{
4225 IRTemp op1 = newTemp(Ity_I64);
4226 ULong op2;
4227
4228 assign(op1, get_gpr_dw0(r1));
4229 op2 = (ULong)i2;
4230 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I64,
4231 mkU64(op2)));
4232
4233 return "clgfi";
4234}
4235
4236static HChar *
4237s390_irgen_CLI(UChar i2, IRTemp op1addr)
4238{
4239 IRTemp op1 = newTemp(Ity_I8);
4240 UChar op2;
4241
4242 assign(op1, load(Ity_I8, mkexpr(op1addr)));
4243 op2 = i2;
4244 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I8,
4245 mkU8(op2)));
4246
4247 return "cli";
4248}
4249
4250static HChar *
4251s390_irgen_CLIY(UChar i2, IRTemp op1addr)
4252{
4253 IRTemp op1 = newTemp(Ity_I8);
4254 UChar op2;
4255
4256 assign(op1, load(Ity_I8, mkexpr(op1addr)));
4257 op2 = i2;
4258 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I8,
4259 mkU8(op2)));
4260
4261 return "cliy";
4262}
4263
4264static HChar *
4265s390_irgen_CLFHSI(UShort i2, IRTemp op1addr)
4266{
4267 IRTemp op1 = newTemp(Ity_I32);
4268 UInt op2;
4269
4270 assign(op1, load(Ity_I32, mkexpr(op1addr)));
4271 op2 = (UInt)i2;
4272 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I32,
4273 mkU32(op2)));
4274
4275 return "clfhsi";
4276}
4277
4278static HChar *
4279s390_irgen_CLGHSI(UShort i2, IRTemp op1addr)
4280{
4281 IRTemp op1 = newTemp(Ity_I64);
4282 ULong op2;
4283
4284 assign(op1, load(Ity_I64, mkexpr(op1addr)));
4285 op2 = (ULong)i2;
4286 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I64,
4287 mkU64(op2)));
4288
4289 return "clghsi";
4290}
4291
4292static HChar *
4293s390_irgen_CLHHSI(UShort i2, IRTemp op1addr)
4294{
4295 IRTemp op1 = newTemp(Ity_I16);
4296 UShort op2;
4297
4298 assign(op1, load(Ity_I16, mkexpr(op1addr)));
4299 op2 = i2;
4300 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I16,
4301 mkU16(op2)));
4302
4303 return "clhhsi";
4304}
4305
4306static HChar *
4307s390_irgen_CLRL(UChar r1, UInt i2)
4308{
4309 IRTemp op1 = newTemp(Ity_I32);
4310 IRTemp op2 = newTemp(Ity_I32);
4311
4312 assign(op1, get_gpr_w1(r1));
4313 assign(op2, load(Ity_I32, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
4314 i2 << 1))));
4315 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4316
4317 return "clrl";
4318}
4319
4320static HChar *
4321s390_irgen_CLGRL(UChar r1, UInt i2)
4322{
4323 IRTemp op1 = newTemp(Ity_I64);
4324 IRTemp op2 = newTemp(Ity_I64);
4325
4326 assign(op1, get_gpr_dw0(r1));
4327 assign(op2, load(Ity_I64, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
4328 i2 << 1))));
4329 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4330
4331 return "clgrl";
4332}
4333
4334static HChar *
4335s390_irgen_CLGFRL(UChar r1, UInt i2)
4336{
4337 IRTemp op1 = newTemp(Ity_I64);
4338 IRTemp op2 = newTemp(Ity_I64);
4339
4340 assign(op1, get_gpr_dw0(r1));
4341 assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
4342 ((ULong)(Long)(Int)i2 << 1)))));
4343 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4344
4345 return "clgfrl";
4346}
4347
4348static HChar *
4349s390_irgen_CLHRL(UChar r1, UInt i2)
4350{
4351 IRTemp op1 = newTemp(Ity_I32);
4352 IRTemp op2 = newTemp(Ity_I32);
4353
4354 assign(op1, get_gpr_w1(r1));
4355 assign(op2, unop(Iop_16Uto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
4356 ((ULong)(Long)(Int)i2 << 1)))));
4357 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4358
4359 return "clhrl";
4360}
4361
4362static HChar *
4363s390_irgen_CLGHRL(UChar r1, UInt i2)
4364{
4365 IRTemp op1 = newTemp(Ity_I64);
4366 IRTemp op2 = newTemp(Ity_I64);
4367
4368 assign(op1, get_gpr_dw0(r1));
4369 assign(op2, unop(Iop_16Uto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
4370 ((ULong)(Long)(Int)i2 << 1)))));
4371 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4372
4373 return "clghrl";
4374}
4375
4376static HChar *
4377s390_irgen_CLRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
4378{
4379 IRTemp op1 = newTemp(Ity_I32);
4380 IRTemp op2 = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00004381 IRTemp cond = newTemp(Ity_I32);
4382
4383 if (m3 == 0) {
4384 } else {
4385 if (m3 == 14) {
4386 always_goto(mkexpr(op4addr));
4387 } else {
4388 assign(op1, get_gpr_w1(r1));
4389 assign(op2, get_gpr_w1(r2));
florianff9613f2012-05-12 15:26:44 +00004390 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4391 op1, op2));
florianf321da72012-07-21 20:32:57 +00004392 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4393 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004394 }
4395 }
4396
4397 return "clrb";
4398}
4399
4400static HChar *
4401s390_irgen_CLGRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
4402{
4403 IRTemp op1 = newTemp(Ity_I64);
4404 IRTemp op2 = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00004405 IRTemp cond = newTemp(Ity_I32);
4406
4407 if (m3 == 0) {
4408 } else {
4409 if (m3 == 14) {
4410 always_goto(mkexpr(op4addr));
4411 } else {
4412 assign(op1, get_gpr_dw0(r1));
4413 assign(op2, get_gpr_dw0(r2));
florianff9613f2012-05-12 15:26:44 +00004414 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4415 op1, op2));
florianf321da72012-07-21 20:32:57 +00004416 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4417 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004418 }
4419 }
4420
4421 return "clgrb";
4422}
4423
4424static HChar *
4425s390_irgen_CLRJ(UChar r1, UChar r2, UShort i4, UChar m3)
4426{
4427 IRTemp op1 = newTemp(Ity_I32);
4428 IRTemp op2 = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00004429 IRTemp cond = newTemp(Ity_I32);
4430
4431 if (m3 == 0) {
4432 } else {
4433 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004434 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004435 } else {
4436 assign(op1, get_gpr_w1(r1));
4437 assign(op2, get_gpr_w1(r2));
florianff9613f2012-05-12 15:26:44 +00004438 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4439 op1, op2));
sewardj2019a972011-03-07 16:04:07 +00004440 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4441 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4442
4443 }
4444 }
4445
4446 return "clrj";
4447}
4448
4449static HChar *
4450s390_irgen_CLGRJ(UChar r1, UChar r2, UShort i4, UChar m3)
4451{
4452 IRTemp op1 = newTemp(Ity_I64);
4453 IRTemp op2 = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00004454 IRTemp cond = newTemp(Ity_I32);
4455
4456 if (m3 == 0) {
4457 } else {
4458 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004459 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004460 } else {
4461 assign(op1, get_gpr_dw0(r1));
4462 assign(op2, get_gpr_dw0(r2));
florianff9613f2012-05-12 15:26:44 +00004463 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4464 op1, op2));
sewardj2019a972011-03-07 16:04:07 +00004465 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4466 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4467
4468 }
4469 }
4470
4471 return "clgrj";
4472}
4473
4474static HChar *
4475s390_irgen_CLIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
4476{
4477 IRTemp op1 = newTemp(Ity_I32);
4478 UInt op2;
sewardj2019a972011-03-07 16:04:07 +00004479 IRTemp cond = newTemp(Ity_I32);
4480
4481 if (m3 == 0) {
4482 } else {
4483 if (m3 == 14) {
4484 always_goto(mkexpr(op4addr));
4485 } else {
4486 assign(op1, get_gpr_w1(r1));
4487 op2 = (UInt)i2;
florianff9613f2012-05-12 15:26:44 +00004488 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4489 mktemp(Ity_I32, mkU32(op2))));
florianf321da72012-07-21 20:32:57 +00004490 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4491 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004492 }
4493 }
4494
4495 return "clib";
4496}
4497
4498static HChar *
4499s390_irgen_CLGIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
4500{
4501 IRTemp op1 = newTemp(Ity_I64);
4502 ULong op2;
sewardj2019a972011-03-07 16:04:07 +00004503 IRTemp cond = newTemp(Ity_I32);
4504
4505 if (m3 == 0) {
4506 } else {
4507 if (m3 == 14) {
4508 always_goto(mkexpr(op4addr));
4509 } else {
4510 assign(op1, get_gpr_dw0(r1));
4511 op2 = (ULong)i2;
florianff9613f2012-05-12 15:26:44 +00004512 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4513 mktemp(Ity_I64, mkU64(op2))));
florianf321da72012-07-21 20:32:57 +00004514 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4515 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004516 }
4517 }
4518
4519 return "clgib";
4520}
4521
4522static HChar *
4523s390_irgen_CLIJ(UChar r1, UChar m3, UShort i4, UChar i2)
4524{
4525 IRTemp op1 = newTemp(Ity_I32);
4526 UInt op2;
sewardj2019a972011-03-07 16:04:07 +00004527 IRTemp cond = newTemp(Ity_I32);
4528
4529 if (m3 == 0) {
4530 } else {
4531 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004532 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004533 } else {
4534 assign(op1, get_gpr_w1(r1));
4535 op2 = (UInt)i2;
florianff9613f2012-05-12 15:26:44 +00004536 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4537 mktemp(Ity_I32, mkU32(op2))));
sewardj2019a972011-03-07 16:04:07 +00004538 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4539 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4540
4541 }
4542 }
4543
4544 return "clij";
4545}
4546
4547static HChar *
4548s390_irgen_CLGIJ(UChar r1, UChar m3, UShort i4, UChar i2)
4549{
4550 IRTemp op1 = newTemp(Ity_I64);
4551 ULong op2;
sewardj2019a972011-03-07 16:04:07 +00004552 IRTemp cond = newTemp(Ity_I32);
4553
4554 if (m3 == 0) {
4555 } else {
4556 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004557 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004558 } else {
4559 assign(op1, get_gpr_dw0(r1));
4560 op2 = (ULong)i2;
florianff9613f2012-05-12 15:26:44 +00004561 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4562 mktemp(Ity_I64, mkU64(op2))));
sewardj2019a972011-03-07 16:04:07 +00004563 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4564 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4565
4566 }
4567 }
4568
4569 return "clgij";
4570}
4571
4572static HChar *
4573s390_irgen_CLM(UChar r1, UChar r3, IRTemp op2addr)
4574{
4575 IRTemp op1 = newTemp(Ity_I32);
4576 IRTemp op2 = newTemp(Ity_I32);
4577 IRTemp b0 = newTemp(Ity_I32);
4578 IRTemp b1 = newTemp(Ity_I32);
4579 IRTemp b2 = newTemp(Ity_I32);
4580 IRTemp b3 = newTemp(Ity_I32);
4581 IRTemp c0 = newTemp(Ity_I32);
4582 IRTemp c1 = newTemp(Ity_I32);
4583 IRTemp c2 = newTemp(Ity_I32);
4584 IRTemp c3 = newTemp(Ity_I32);
4585 UChar n;
4586
4587 n = 0;
4588 if ((r3 & 8) != 0) {
4589 assign(b0, unop(Iop_8Uto32, get_gpr_b4(r1)));
4590 assign(c0, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
4591 n = n + 1;
4592 } else {
4593 assign(b0, mkU32(0));
4594 assign(c0, mkU32(0));
4595 }
4596 if ((r3 & 4) != 0) {
4597 assign(b1, unop(Iop_8Uto32, get_gpr_b5(r1)));
4598 assign(c1, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4599 mkU64(n)))));
4600 n = n + 1;
4601 } else {
4602 assign(b1, mkU32(0));
4603 assign(c1, mkU32(0));
4604 }
4605 if ((r3 & 2) != 0) {
4606 assign(b2, unop(Iop_8Uto32, get_gpr_b6(r1)));
4607 assign(c2, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4608 mkU64(n)))));
4609 n = n + 1;
4610 } else {
4611 assign(b2, mkU32(0));
4612 assign(c2, mkU32(0));
4613 }
4614 if ((r3 & 1) != 0) {
4615 assign(b3, unop(Iop_8Uto32, get_gpr_b7(r1)));
4616 assign(c3, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4617 mkU64(n)))));
4618 n = n + 1;
4619 } else {
4620 assign(b3, mkU32(0));
4621 assign(c3, mkU32(0));
4622 }
4623 assign(op1, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4624 mkexpr(b0), mkU8(24)), binop(Iop_Shl32, mkexpr(b1), mkU8(16))),
4625 binop(Iop_Shl32, mkexpr(b2), mkU8(8))), mkexpr(b3)));
4626 assign(op2, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4627 mkexpr(c0), mkU8(24)), binop(Iop_Shl32, mkexpr(c1), mkU8(16))),
4628 binop(Iop_Shl32, mkexpr(c2), mkU8(8))), mkexpr(c3)));
4629 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4630
4631 return "clm";
4632}
4633
4634static HChar *
4635s390_irgen_CLMY(UChar r1, UChar r3, IRTemp op2addr)
4636{
4637 IRTemp op1 = newTemp(Ity_I32);
4638 IRTemp op2 = newTemp(Ity_I32);
4639 IRTemp b0 = newTemp(Ity_I32);
4640 IRTemp b1 = newTemp(Ity_I32);
4641 IRTemp b2 = newTemp(Ity_I32);
4642 IRTemp b3 = newTemp(Ity_I32);
4643 IRTemp c0 = newTemp(Ity_I32);
4644 IRTemp c1 = newTemp(Ity_I32);
4645 IRTemp c2 = newTemp(Ity_I32);
4646 IRTemp c3 = newTemp(Ity_I32);
4647 UChar n;
4648
4649 n = 0;
4650 if ((r3 & 8) != 0) {
4651 assign(b0, unop(Iop_8Uto32, get_gpr_b4(r1)));
4652 assign(c0, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
4653 n = n + 1;
4654 } else {
4655 assign(b0, mkU32(0));
4656 assign(c0, mkU32(0));
4657 }
4658 if ((r3 & 4) != 0) {
4659 assign(b1, unop(Iop_8Uto32, get_gpr_b5(r1)));
4660 assign(c1, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4661 mkU64(n)))));
4662 n = n + 1;
4663 } else {
4664 assign(b1, mkU32(0));
4665 assign(c1, mkU32(0));
4666 }
4667 if ((r3 & 2) != 0) {
4668 assign(b2, unop(Iop_8Uto32, get_gpr_b6(r1)));
4669 assign(c2, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4670 mkU64(n)))));
4671 n = n + 1;
4672 } else {
4673 assign(b2, mkU32(0));
4674 assign(c2, mkU32(0));
4675 }
4676 if ((r3 & 1) != 0) {
4677 assign(b3, unop(Iop_8Uto32, get_gpr_b7(r1)));
4678 assign(c3, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4679 mkU64(n)))));
4680 n = n + 1;
4681 } else {
4682 assign(b3, mkU32(0));
4683 assign(c3, mkU32(0));
4684 }
4685 assign(op1, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4686 mkexpr(b0), mkU8(24)), binop(Iop_Shl32, mkexpr(b1), mkU8(16))),
4687 binop(Iop_Shl32, mkexpr(b2), mkU8(8))), mkexpr(b3)));
4688 assign(op2, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4689 mkexpr(c0), mkU8(24)), binop(Iop_Shl32, mkexpr(c1), mkU8(16))),
4690 binop(Iop_Shl32, mkexpr(c2), mkU8(8))), mkexpr(c3)));
4691 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4692
4693 return "clmy";
4694}
4695
4696static HChar *
4697s390_irgen_CLMH(UChar r1, UChar r3, IRTemp op2addr)
4698{
4699 IRTemp op1 = newTemp(Ity_I32);
4700 IRTemp op2 = newTemp(Ity_I32);
4701 IRTemp b0 = newTemp(Ity_I32);
4702 IRTemp b1 = newTemp(Ity_I32);
4703 IRTemp b2 = newTemp(Ity_I32);
4704 IRTemp b3 = newTemp(Ity_I32);
4705 IRTemp c0 = newTemp(Ity_I32);
4706 IRTemp c1 = newTemp(Ity_I32);
4707 IRTemp c2 = newTemp(Ity_I32);
4708 IRTemp c3 = newTemp(Ity_I32);
4709 UChar n;
4710
4711 n = 0;
4712 if ((r3 & 8) != 0) {
4713 assign(b0, unop(Iop_8Uto32, get_gpr_b0(r1)));
4714 assign(c0, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
4715 n = n + 1;
4716 } else {
4717 assign(b0, mkU32(0));
4718 assign(c0, mkU32(0));
4719 }
4720 if ((r3 & 4) != 0) {
4721 assign(b1, unop(Iop_8Uto32, get_gpr_b1(r1)));
4722 assign(c1, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4723 mkU64(n)))));
4724 n = n + 1;
4725 } else {
4726 assign(b1, mkU32(0));
4727 assign(c1, mkU32(0));
4728 }
4729 if ((r3 & 2) != 0) {
4730 assign(b2, unop(Iop_8Uto32, get_gpr_b2(r1)));
4731 assign(c2, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4732 mkU64(n)))));
4733 n = n + 1;
4734 } else {
4735 assign(b2, mkU32(0));
4736 assign(c2, mkU32(0));
4737 }
4738 if ((r3 & 1) != 0) {
4739 assign(b3, unop(Iop_8Uto32, get_gpr_b3(r1)));
4740 assign(c3, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4741 mkU64(n)))));
4742 n = n + 1;
4743 } else {
4744 assign(b3, mkU32(0));
4745 assign(c3, mkU32(0));
4746 }
4747 assign(op1, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4748 mkexpr(b0), mkU8(24)), binop(Iop_Shl32, mkexpr(b1), mkU8(16))),
4749 binop(Iop_Shl32, mkexpr(b2), mkU8(8))), mkexpr(b3)));
4750 assign(op2, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4751 mkexpr(c0), mkU8(24)), binop(Iop_Shl32, mkexpr(c1), mkU8(16))),
4752 binop(Iop_Shl32, mkexpr(c2), mkU8(8))), mkexpr(c3)));
4753 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4754
4755 return "clmh";
4756}
4757
4758static HChar *
4759s390_irgen_CLHHR(UChar r1, UChar r2)
4760{
4761 IRTemp op1 = newTemp(Ity_I32);
4762 IRTemp op2 = newTemp(Ity_I32);
4763
4764 assign(op1, get_gpr_w0(r1));
4765 assign(op2, get_gpr_w0(r2));
4766 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4767
4768 return "clhhr";
4769}
4770
4771static HChar *
4772s390_irgen_CLHLR(UChar r1, UChar r2)
4773{
4774 IRTemp op1 = newTemp(Ity_I32);
4775 IRTemp op2 = newTemp(Ity_I32);
4776
4777 assign(op1, get_gpr_w0(r1));
4778 assign(op2, get_gpr_w1(r2));
4779 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4780
4781 return "clhlr";
4782}
4783
4784static HChar *
4785s390_irgen_CLHF(UChar r1, IRTemp op2addr)
4786{
4787 IRTemp op1 = newTemp(Ity_I32);
4788 IRTemp op2 = newTemp(Ity_I32);
4789
4790 assign(op1, get_gpr_w0(r1));
4791 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4792 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4793
4794 return "clhf";
4795}
4796
4797static HChar *
4798s390_irgen_CLIH(UChar r1, UInt i2)
4799{
4800 IRTemp op1 = newTemp(Ity_I32);
4801 UInt op2;
4802
4803 assign(op1, get_gpr_w0(r1));
4804 op2 = i2;
4805 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I32,
4806 mkU32(op2)));
4807
4808 return "clih";
4809}
4810
4811static HChar *
4812s390_irgen_CPYA(UChar r1, UChar r2)
4813{
4814 put_ar_w0(r1, get_ar_w0(r2));
sewardj7ee97522011-05-09 21:45:04 +00004815 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00004816 s390_disasm(ENC3(MNM, AR, AR), "cpya", r1, r2);
4817
4818 return "cpya";
4819}
4820
4821static HChar *
4822s390_irgen_XR(UChar r1, UChar r2)
4823{
4824 IRTemp op1 = newTemp(Ity_I32);
4825 IRTemp op2 = newTemp(Ity_I32);
4826 IRTemp result = newTemp(Ity_I32);
4827
4828 if (r1 == r2) {
4829 assign(result, mkU32(0));
4830 } else {
4831 assign(op1, get_gpr_w1(r1));
4832 assign(op2, get_gpr_w1(r2));
4833 assign(result, binop(Iop_Xor32, mkexpr(op1), mkexpr(op2)));
4834 }
4835 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4836 put_gpr_w1(r1, mkexpr(result));
4837
4838 return "xr";
4839}
4840
4841static HChar *
4842s390_irgen_XGR(UChar r1, UChar r2)
4843{
4844 IRTemp op1 = newTemp(Ity_I64);
4845 IRTemp op2 = newTemp(Ity_I64);
4846 IRTemp result = newTemp(Ity_I64);
4847
4848 if (r1 == r2) {
4849 assign(result, mkU64(0));
4850 } else {
4851 assign(op1, get_gpr_dw0(r1));
4852 assign(op2, get_gpr_dw0(r2));
4853 assign(result, binop(Iop_Xor64, mkexpr(op1), mkexpr(op2)));
4854 }
4855 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4856 put_gpr_dw0(r1, mkexpr(result));
4857
4858 return "xgr";
4859}
4860
4861static HChar *
4862s390_irgen_XRK(UChar r3, UChar r1, UChar r2)
4863{
4864 IRTemp op2 = newTemp(Ity_I32);
4865 IRTemp op3 = newTemp(Ity_I32);
4866 IRTemp result = newTemp(Ity_I32);
4867
4868 assign(op2, get_gpr_w1(r2));
4869 assign(op3, get_gpr_w1(r3));
4870 assign(result, binop(Iop_Xor32, mkexpr(op2), mkexpr(op3)));
4871 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4872 put_gpr_w1(r1, mkexpr(result));
4873
4874 return "xrk";
4875}
4876
4877static HChar *
4878s390_irgen_XGRK(UChar r3, UChar r1, UChar r2)
4879{
4880 IRTemp op2 = newTemp(Ity_I64);
4881 IRTemp op3 = newTemp(Ity_I64);
4882 IRTemp result = newTemp(Ity_I64);
4883
4884 assign(op2, get_gpr_dw0(r2));
4885 assign(op3, get_gpr_dw0(r3));
4886 assign(result, binop(Iop_Xor64, mkexpr(op2), mkexpr(op3)));
4887 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4888 put_gpr_dw0(r1, mkexpr(result));
4889
4890 return "xgrk";
4891}
4892
4893static HChar *
4894s390_irgen_X(UChar r1, IRTemp op2addr)
4895{
4896 IRTemp op1 = newTemp(Ity_I32);
4897 IRTemp op2 = newTemp(Ity_I32);
4898 IRTemp result = newTemp(Ity_I32);
4899
4900 assign(op1, get_gpr_w1(r1));
4901 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4902 assign(result, binop(Iop_Xor32, mkexpr(op1), mkexpr(op2)));
4903 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4904 put_gpr_w1(r1, mkexpr(result));
4905
4906 return "x";
4907}
4908
4909static HChar *
4910s390_irgen_XY(UChar r1, IRTemp op2addr)
4911{
4912 IRTemp op1 = newTemp(Ity_I32);
4913 IRTemp op2 = newTemp(Ity_I32);
4914 IRTemp result = newTemp(Ity_I32);
4915
4916 assign(op1, get_gpr_w1(r1));
4917 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4918 assign(result, binop(Iop_Xor32, mkexpr(op1), mkexpr(op2)));
4919 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4920 put_gpr_w1(r1, mkexpr(result));
4921
4922 return "xy";
4923}
4924
4925static HChar *
4926s390_irgen_XG(UChar r1, IRTemp op2addr)
4927{
4928 IRTemp op1 = newTemp(Ity_I64);
4929 IRTemp op2 = newTemp(Ity_I64);
4930 IRTemp result = newTemp(Ity_I64);
4931
4932 assign(op1, get_gpr_dw0(r1));
4933 assign(op2, load(Ity_I64, mkexpr(op2addr)));
4934 assign(result, binop(Iop_Xor64, mkexpr(op1), mkexpr(op2)));
4935 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4936 put_gpr_dw0(r1, mkexpr(result));
4937
4938 return "xg";
4939}
4940
4941static HChar *
4942s390_irgen_XI(UChar i2, IRTemp op1addr)
4943{
4944 IRTemp op1 = newTemp(Ity_I8);
4945 UChar op2;
4946 IRTemp result = newTemp(Ity_I8);
4947
4948 assign(op1, load(Ity_I8, mkexpr(op1addr)));
4949 op2 = i2;
4950 assign(result, binop(Iop_Xor8, mkexpr(op1), mkU8(op2)));
4951 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4952 store(mkexpr(op1addr), mkexpr(result));
4953
4954 return "xi";
4955}
4956
4957static HChar *
4958s390_irgen_XIY(UChar i2, IRTemp op1addr)
4959{
4960 IRTemp op1 = newTemp(Ity_I8);
4961 UChar op2;
4962 IRTemp result = newTemp(Ity_I8);
4963
4964 assign(op1, load(Ity_I8, mkexpr(op1addr)));
4965 op2 = i2;
4966 assign(result, binop(Iop_Xor8, mkexpr(op1), mkU8(op2)));
4967 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4968 store(mkexpr(op1addr), mkexpr(result));
4969
4970 return "xiy";
4971}
4972
4973static HChar *
4974s390_irgen_XIHF(UChar r1, UInt i2)
4975{
4976 IRTemp op1 = newTemp(Ity_I32);
4977 UInt op2;
4978 IRTemp result = newTemp(Ity_I32);
4979
4980 assign(op1, get_gpr_w0(r1));
4981 op2 = i2;
4982 assign(result, binop(Iop_Xor32, mkexpr(op1), mkU32(op2)));
4983 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4984 put_gpr_w0(r1, mkexpr(result));
4985
4986 return "xihf";
4987}
4988
4989static HChar *
4990s390_irgen_XILF(UChar r1, UInt i2)
4991{
4992 IRTemp op1 = newTemp(Ity_I32);
4993 UInt op2;
4994 IRTemp result = newTemp(Ity_I32);
4995
4996 assign(op1, get_gpr_w1(r1));
4997 op2 = i2;
4998 assign(result, binop(Iop_Xor32, mkexpr(op1), mkU32(op2)));
4999 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5000 put_gpr_w1(r1, mkexpr(result));
5001
5002 return "xilf";
5003}
5004
5005static HChar *
5006s390_irgen_EAR(UChar r1, UChar r2)
5007{
5008 put_gpr_w1(r1, get_ar_w0(r2));
sewardj7ee97522011-05-09 21:45:04 +00005009 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00005010 s390_disasm(ENC3(MNM, GPR, AR), "ear", r1, r2);
5011
5012 return "ear";
5013}
5014
5015static HChar *
5016s390_irgen_IC(UChar r1, IRTemp op2addr)
5017{
5018 put_gpr_b7(r1, load(Ity_I8, mkexpr(op2addr)));
5019
5020 return "ic";
5021}
5022
5023static HChar *
5024s390_irgen_ICY(UChar r1, IRTemp op2addr)
5025{
5026 put_gpr_b7(r1, load(Ity_I8, mkexpr(op2addr)));
5027
5028 return "icy";
5029}
5030
5031static HChar *
5032s390_irgen_ICM(UChar r1, UChar r3, IRTemp op2addr)
5033{
5034 UChar n;
5035 IRTemp result = newTemp(Ity_I32);
5036 UInt mask;
5037
5038 n = 0;
5039 mask = (UInt)r3;
5040 if ((mask & 8) != 0) {
5041 put_gpr_b4(r1, load(Ity_I8, mkexpr(op2addr)));
5042 n = n + 1;
5043 }
5044 if ((mask & 4) != 0) {
5045 put_gpr_b5(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5046
5047 n = n + 1;
5048 }
5049 if ((mask & 2) != 0) {
5050 put_gpr_b6(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5051
5052 n = n + 1;
5053 }
5054 if ((mask & 1) != 0) {
5055 put_gpr_b7(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5056
5057 n = n + 1;
5058 }
5059 assign(result, get_gpr_w1(r1));
5060 s390_cc_thunk_putZZ(S390_CC_OP_INSERT_CHAR_MASK_32, result, mktemp(Ity_I32,
5061 mkU32(mask)));
5062
5063 return "icm";
5064}
5065
5066static HChar *
5067s390_irgen_ICMY(UChar r1, UChar r3, IRTemp op2addr)
5068{
5069 UChar n;
5070 IRTemp result = newTemp(Ity_I32);
5071 UInt mask;
5072
5073 n = 0;
5074 mask = (UInt)r3;
5075 if ((mask & 8) != 0) {
5076 put_gpr_b4(r1, load(Ity_I8, mkexpr(op2addr)));
5077 n = n + 1;
5078 }
5079 if ((mask & 4) != 0) {
5080 put_gpr_b5(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5081
5082 n = n + 1;
5083 }
5084 if ((mask & 2) != 0) {
5085 put_gpr_b6(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5086
5087 n = n + 1;
5088 }
5089 if ((mask & 1) != 0) {
5090 put_gpr_b7(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5091
5092 n = n + 1;
5093 }
5094 assign(result, get_gpr_w1(r1));
5095 s390_cc_thunk_putZZ(S390_CC_OP_INSERT_CHAR_MASK_32, result, mktemp(Ity_I32,
5096 mkU32(mask)));
5097
5098 return "icmy";
5099}
5100
5101static HChar *
5102s390_irgen_ICMH(UChar r1, UChar r3, IRTemp op2addr)
5103{
5104 UChar n;
5105 IRTemp result = newTemp(Ity_I32);
5106 UInt mask;
5107
5108 n = 0;
5109 mask = (UInt)r3;
5110 if ((mask & 8) != 0) {
5111 put_gpr_b0(r1, load(Ity_I8, mkexpr(op2addr)));
5112 n = n + 1;
5113 }
5114 if ((mask & 4) != 0) {
5115 put_gpr_b1(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5116
5117 n = n + 1;
5118 }
5119 if ((mask & 2) != 0) {
5120 put_gpr_b2(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5121
5122 n = n + 1;
5123 }
5124 if ((mask & 1) != 0) {
5125 put_gpr_b3(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5126
5127 n = n + 1;
5128 }
5129 assign(result, get_gpr_w0(r1));
5130 s390_cc_thunk_putZZ(S390_CC_OP_INSERT_CHAR_MASK_32, result, mktemp(Ity_I32,
5131 mkU32(mask)));
5132
5133 return "icmh";
5134}
5135
5136static HChar *
5137s390_irgen_IIHF(UChar r1, UInt i2)
5138{
5139 put_gpr_w0(r1, mkU32(i2));
5140
5141 return "iihf";
5142}
5143
5144static HChar *
5145s390_irgen_IIHH(UChar r1, UShort i2)
5146{
5147 put_gpr_hw0(r1, mkU16(i2));
5148
5149 return "iihh";
5150}
5151
5152static HChar *
5153s390_irgen_IIHL(UChar r1, UShort i2)
5154{
5155 put_gpr_hw1(r1, mkU16(i2));
5156
5157 return "iihl";
5158}
5159
5160static HChar *
5161s390_irgen_IILF(UChar r1, UInt i2)
5162{
5163 put_gpr_w1(r1, mkU32(i2));
5164
5165 return "iilf";
5166}
5167
5168static HChar *
5169s390_irgen_IILH(UChar r1, UShort i2)
5170{
5171 put_gpr_hw2(r1, mkU16(i2));
5172
5173 return "iilh";
5174}
5175
5176static HChar *
5177s390_irgen_IILL(UChar r1, UShort i2)
5178{
5179 put_gpr_hw3(r1, mkU16(i2));
5180
5181 return "iill";
5182}
5183
5184static HChar *
5185s390_irgen_LR(UChar r1, UChar r2)
5186{
5187 put_gpr_w1(r1, get_gpr_w1(r2));
5188
5189 return "lr";
5190}
5191
5192static HChar *
5193s390_irgen_LGR(UChar r1, UChar r2)
5194{
5195 put_gpr_dw0(r1, get_gpr_dw0(r2));
5196
5197 return "lgr";
5198}
5199
5200static HChar *
5201s390_irgen_LGFR(UChar r1, UChar r2)
5202{
5203 put_gpr_dw0(r1, unop(Iop_32Sto64, get_gpr_w1(r2)));
5204
5205 return "lgfr";
5206}
5207
5208static HChar *
5209s390_irgen_L(UChar r1, IRTemp op2addr)
5210{
5211 put_gpr_w1(r1, load(Ity_I32, mkexpr(op2addr)));
5212
5213 return "l";
5214}
5215
5216static HChar *
5217s390_irgen_LY(UChar r1, IRTemp op2addr)
5218{
5219 put_gpr_w1(r1, load(Ity_I32, mkexpr(op2addr)));
5220
5221 return "ly";
5222}
5223
5224static HChar *
5225s390_irgen_LG(UChar r1, IRTemp op2addr)
5226{
5227 put_gpr_dw0(r1, load(Ity_I64, mkexpr(op2addr)));
5228
5229 return "lg";
5230}
5231
5232static HChar *
5233s390_irgen_LGF(UChar r1, IRTemp op2addr)
5234{
5235 put_gpr_dw0(r1, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
5236
5237 return "lgf";
5238}
5239
5240static HChar *
5241s390_irgen_LGFI(UChar r1, UInt i2)
5242{
5243 put_gpr_dw0(r1, mkU64((ULong)(Long)(Int)i2));
5244
5245 return "lgfi";
5246}
5247
5248static HChar *
5249s390_irgen_LRL(UChar r1, UInt i2)
5250{
5251 put_gpr_w1(r1, load(Ity_I32, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
5252 i2 << 1))));
5253
5254 return "lrl";
5255}
5256
5257static HChar *
5258s390_irgen_LGRL(UChar r1, UInt i2)
5259{
5260 put_gpr_dw0(r1, load(Ity_I64, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
5261 i2 << 1))));
5262
5263 return "lgrl";
5264}
5265
5266static HChar *
5267s390_irgen_LGFRL(UChar r1, UInt i2)
5268{
5269 put_gpr_dw0(r1, unop(Iop_32Sto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
5270 ((ULong)(Long)(Int)i2 << 1)))));
5271
5272 return "lgfrl";
5273}
5274
5275static HChar *
5276s390_irgen_LA(UChar r1, IRTemp op2addr)
5277{
5278 put_gpr_dw0(r1, mkexpr(op2addr));
5279
5280 return "la";
5281}
5282
5283static HChar *
5284s390_irgen_LAY(UChar r1, IRTemp op2addr)
5285{
5286 put_gpr_dw0(r1, mkexpr(op2addr));
5287
5288 return "lay";
5289}
5290
5291static HChar *
5292s390_irgen_LAE(UChar r1, IRTemp op2addr)
5293{
5294 put_gpr_dw0(r1, mkexpr(op2addr));
5295
5296 return "lae";
5297}
5298
5299static HChar *
5300s390_irgen_LAEY(UChar r1, IRTemp op2addr)
5301{
5302 put_gpr_dw0(r1, mkexpr(op2addr));
5303
5304 return "laey";
5305}
5306
5307static HChar *
5308s390_irgen_LARL(UChar r1, UInt i2)
5309{
5310 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)));
5311
5312 return "larl";
5313}
5314
5315static HChar *
5316s390_irgen_LAA(UChar r1, UChar r3, IRTemp op2addr)
5317{
5318 IRTemp op2 = newTemp(Ity_I32);
5319 IRTemp op3 = newTemp(Ity_I32);
5320 IRTemp result = newTemp(Ity_I32);
5321
5322 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5323 assign(op3, get_gpr_w1(r3));
5324 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
5325 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
5326 store(mkexpr(op2addr), mkexpr(result));
5327 put_gpr_w1(r1, mkexpr(op2));
5328
5329 return "laa";
5330}
5331
5332static HChar *
5333s390_irgen_LAAG(UChar r1, UChar r3, IRTemp op2addr)
5334{
5335 IRTemp op2 = newTemp(Ity_I64);
5336 IRTemp op3 = newTemp(Ity_I64);
5337 IRTemp result = newTemp(Ity_I64);
5338
5339 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5340 assign(op3, get_gpr_dw0(r3));
5341 assign(result, binop(Iop_Add64, mkexpr(op2), mkexpr(op3)));
5342 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op2, op3);
5343 store(mkexpr(op2addr), mkexpr(result));
5344 put_gpr_dw0(r1, mkexpr(op2));
5345
5346 return "laag";
5347}
5348
5349static HChar *
5350s390_irgen_LAAL(UChar r1, UChar r3, IRTemp op2addr)
5351{
5352 IRTemp op2 = newTemp(Ity_I32);
5353 IRTemp op3 = newTemp(Ity_I32);
5354 IRTemp result = newTemp(Ity_I32);
5355
5356 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5357 assign(op3, get_gpr_w1(r3));
5358 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
5359 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
5360 store(mkexpr(op2addr), mkexpr(result));
5361 put_gpr_w1(r1, mkexpr(op2));
5362
5363 return "laal";
5364}
5365
5366static HChar *
5367s390_irgen_LAALG(UChar r1, UChar r3, IRTemp op2addr)
5368{
5369 IRTemp op2 = newTemp(Ity_I64);
5370 IRTemp op3 = newTemp(Ity_I64);
5371 IRTemp result = newTemp(Ity_I64);
5372
5373 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5374 assign(op3, get_gpr_dw0(r3));
5375 assign(result, binop(Iop_Add64, mkexpr(op2), mkexpr(op3)));
5376 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op2, op3);
5377 store(mkexpr(op2addr), mkexpr(result));
5378 put_gpr_dw0(r1, mkexpr(op2));
5379
5380 return "laalg";
5381}
5382
5383static HChar *
5384s390_irgen_LAN(UChar r1, UChar r3, IRTemp op2addr)
5385{
5386 IRTemp op2 = newTemp(Ity_I32);
5387 IRTemp op3 = newTemp(Ity_I32);
5388 IRTemp result = newTemp(Ity_I32);
5389
5390 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5391 assign(op3, get_gpr_w1(r3));
5392 assign(result, binop(Iop_And32, mkexpr(op2), mkexpr(op3)));
5393 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5394 store(mkexpr(op2addr), mkexpr(result));
5395 put_gpr_w1(r1, mkexpr(op2));
5396
5397 return "lan";
5398}
5399
5400static HChar *
5401s390_irgen_LANG(UChar r1, UChar r3, IRTemp op2addr)
5402{
5403 IRTemp op2 = newTemp(Ity_I64);
5404 IRTemp op3 = newTemp(Ity_I64);
5405 IRTemp result = newTemp(Ity_I64);
5406
5407 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5408 assign(op3, get_gpr_dw0(r3));
5409 assign(result, binop(Iop_And64, mkexpr(op2), mkexpr(op3)));
5410 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5411 store(mkexpr(op2addr), mkexpr(result));
5412 put_gpr_dw0(r1, mkexpr(op2));
5413
5414 return "lang";
5415}
5416
5417static HChar *
5418s390_irgen_LAX(UChar r1, UChar r3, IRTemp op2addr)
5419{
5420 IRTemp op2 = newTemp(Ity_I32);
5421 IRTemp op3 = newTemp(Ity_I32);
5422 IRTemp result = newTemp(Ity_I32);
5423
5424 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5425 assign(op3, get_gpr_w1(r3));
5426 assign(result, binop(Iop_Xor32, mkexpr(op2), mkexpr(op3)));
5427 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5428 store(mkexpr(op2addr), mkexpr(result));
5429 put_gpr_w1(r1, mkexpr(op2));
5430
5431 return "lax";
5432}
5433
5434static HChar *
5435s390_irgen_LAXG(UChar r1, UChar r3, IRTemp op2addr)
5436{
5437 IRTemp op2 = newTemp(Ity_I64);
5438 IRTemp op3 = newTemp(Ity_I64);
5439 IRTemp result = newTemp(Ity_I64);
5440
5441 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5442 assign(op3, get_gpr_dw0(r3));
5443 assign(result, binop(Iop_Xor64, mkexpr(op2), mkexpr(op3)));
5444 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5445 store(mkexpr(op2addr), mkexpr(result));
5446 put_gpr_dw0(r1, mkexpr(op2));
5447
5448 return "laxg";
5449}
5450
5451static HChar *
5452s390_irgen_LAO(UChar r1, UChar r3, IRTemp op2addr)
5453{
5454 IRTemp op2 = newTemp(Ity_I32);
5455 IRTemp op3 = newTemp(Ity_I32);
5456 IRTemp result = newTemp(Ity_I32);
5457
5458 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5459 assign(op3, get_gpr_w1(r3));
5460 assign(result, binop(Iop_Or32, mkexpr(op2), mkexpr(op3)));
5461 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5462 store(mkexpr(op2addr), mkexpr(result));
5463 put_gpr_w1(r1, mkexpr(op2));
5464
5465 return "lao";
5466}
5467
5468static HChar *
5469s390_irgen_LAOG(UChar r1, UChar r3, IRTemp op2addr)
5470{
5471 IRTemp op2 = newTemp(Ity_I64);
5472 IRTemp op3 = newTemp(Ity_I64);
5473 IRTemp result = newTemp(Ity_I64);
5474
5475 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5476 assign(op3, get_gpr_dw0(r3));
5477 assign(result, binop(Iop_Or64, mkexpr(op2), mkexpr(op3)));
5478 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5479 store(mkexpr(op2addr), mkexpr(result));
5480 put_gpr_dw0(r1, mkexpr(op2));
5481
5482 return "laog";
5483}
5484
5485static HChar *
5486s390_irgen_LTR(UChar r1, UChar r2)
5487{
5488 IRTemp op2 = newTemp(Ity_I32);
5489
5490 assign(op2, get_gpr_w1(r2));
5491 put_gpr_w1(r1, mkexpr(op2));
5492 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5493
5494 return "ltr";
5495}
5496
5497static HChar *
5498s390_irgen_LTGR(UChar r1, UChar r2)
5499{
5500 IRTemp op2 = newTemp(Ity_I64);
5501
5502 assign(op2, get_gpr_dw0(r2));
5503 put_gpr_dw0(r1, mkexpr(op2));
5504 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5505
5506 return "ltgr";
5507}
5508
5509static HChar *
5510s390_irgen_LTGFR(UChar r1, UChar r2)
5511{
5512 IRTemp op2 = newTemp(Ity_I64);
5513
5514 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
5515 put_gpr_dw0(r1, mkexpr(op2));
5516 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5517
5518 return "ltgfr";
5519}
5520
5521static HChar *
5522s390_irgen_LT(UChar r1, IRTemp op2addr)
5523{
5524 IRTemp op2 = newTemp(Ity_I32);
5525
5526 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5527 put_gpr_w1(r1, mkexpr(op2));
5528 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5529
5530 return "lt";
5531}
5532
5533static HChar *
5534s390_irgen_LTG(UChar r1, IRTemp op2addr)
5535{
5536 IRTemp op2 = newTemp(Ity_I64);
5537
5538 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5539 put_gpr_dw0(r1, mkexpr(op2));
5540 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5541
5542 return "ltg";
5543}
5544
5545static HChar *
5546s390_irgen_LTGF(UChar r1, IRTemp op2addr)
5547{
5548 IRTemp op2 = newTemp(Ity_I64);
5549
5550 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
5551 put_gpr_dw0(r1, mkexpr(op2));
5552 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5553
5554 return "ltgf";
5555}
5556
5557static HChar *
5558s390_irgen_LBR(UChar r1, UChar r2)
5559{
5560 put_gpr_w1(r1, unop(Iop_8Sto32, get_gpr_b7(r2)));
5561
5562 return "lbr";
5563}
5564
5565static HChar *
5566s390_irgen_LGBR(UChar r1, UChar r2)
5567{
5568 put_gpr_dw0(r1, unop(Iop_8Sto64, get_gpr_b7(r2)));
5569
5570 return "lgbr";
5571}
5572
5573static HChar *
5574s390_irgen_LB(UChar r1, IRTemp op2addr)
5575{
5576 put_gpr_w1(r1, unop(Iop_8Sto32, load(Ity_I8, mkexpr(op2addr))));
5577
5578 return "lb";
5579}
5580
5581static HChar *
5582s390_irgen_LGB(UChar r1, IRTemp op2addr)
5583{
5584 put_gpr_dw0(r1, unop(Iop_8Sto64, load(Ity_I8, mkexpr(op2addr))));
5585
5586 return "lgb";
5587}
5588
5589static HChar *
5590s390_irgen_LBH(UChar r1, IRTemp op2addr)
5591{
5592 put_gpr_w0(r1, unop(Iop_8Sto32, load(Ity_I8, mkexpr(op2addr))));
5593
5594 return "lbh";
5595}
5596
5597static HChar *
5598s390_irgen_LCR(UChar r1, UChar r2)
5599{
5600 Int op1;
5601 IRTemp op2 = newTemp(Ity_I32);
5602 IRTemp result = newTemp(Ity_I32);
5603
5604 op1 = 0;
5605 assign(op2, get_gpr_w1(r2));
5606 assign(result, binop(Iop_Sub32, mkU32((UInt)op1), mkexpr(op2)));
5607 put_gpr_w1(r1, mkexpr(result));
5608 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, mktemp(Ity_I32, mkU32((UInt)
5609 op1)), op2);
5610
5611 return "lcr";
5612}
5613
5614static HChar *
5615s390_irgen_LCGR(UChar r1, UChar r2)
5616{
5617 Long op1;
5618 IRTemp op2 = newTemp(Ity_I64);
5619 IRTemp result = newTemp(Ity_I64);
5620
5621 op1 = 0ULL;
5622 assign(op2, get_gpr_dw0(r2));
5623 assign(result, binop(Iop_Sub64, mkU64((ULong)op1), mkexpr(op2)));
5624 put_gpr_dw0(r1, mkexpr(result));
5625 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, mktemp(Ity_I64, mkU64((ULong)
5626 op1)), op2);
5627
5628 return "lcgr";
5629}
5630
5631static HChar *
5632s390_irgen_LCGFR(UChar r1, UChar r2)
5633{
5634 Long op1;
5635 IRTemp op2 = newTemp(Ity_I64);
5636 IRTemp result = newTemp(Ity_I64);
5637
5638 op1 = 0ULL;
5639 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
5640 assign(result, binop(Iop_Sub64, mkU64((ULong)op1), mkexpr(op2)));
5641 put_gpr_dw0(r1, mkexpr(result));
5642 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, mktemp(Ity_I64, mkU64((ULong)
5643 op1)), op2);
5644
5645 return "lcgfr";
5646}
5647
5648static HChar *
5649s390_irgen_LHR(UChar r1, UChar r2)
5650{
5651 put_gpr_w1(r1, unop(Iop_16Sto32, get_gpr_hw3(r2)));
5652
5653 return "lhr";
5654}
5655
5656static HChar *
5657s390_irgen_LGHR(UChar r1, UChar r2)
5658{
5659 put_gpr_dw0(r1, unop(Iop_16Sto64, get_gpr_hw3(r2)));
5660
5661 return "lghr";
5662}
5663
5664static HChar *
5665s390_irgen_LH(UChar r1, IRTemp op2addr)
5666{
5667 put_gpr_w1(r1, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
5668
5669 return "lh";
5670}
5671
5672static HChar *
5673s390_irgen_LHY(UChar r1, IRTemp op2addr)
5674{
5675 put_gpr_w1(r1, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
5676
5677 return "lhy";
5678}
5679
5680static HChar *
5681s390_irgen_LGH(UChar r1, IRTemp op2addr)
5682{
5683 put_gpr_dw0(r1, unop(Iop_16Sto64, load(Ity_I16, mkexpr(op2addr))));
5684
5685 return "lgh";
5686}
5687
5688static HChar *
5689s390_irgen_LHI(UChar r1, UShort i2)
5690{
5691 put_gpr_w1(r1, mkU32((UInt)(Int)(Short)i2));
5692
5693 return "lhi";
5694}
5695
5696static HChar *
5697s390_irgen_LGHI(UChar r1, UShort i2)
5698{
5699 put_gpr_dw0(r1, mkU64((ULong)(Long)(Short)i2));
5700
5701 return "lghi";
5702}
5703
5704static HChar *
5705s390_irgen_LHRL(UChar r1, UInt i2)
5706{
5707 put_gpr_w1(r1, unop(Iop_16Sto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
5708 ((ULong)(Long)(Int)i2 << 1)))));
5709
5710 return "lhrl";
5711}
5712
5713static HChar *
5714s390_irgen_LGHRL(UChar r1, UInt i2)
5715{
5716 put_gpr_dw0(r1, unop(Iop_16Sto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
5717 ((ULong)(Long)(Int)i2 << 1)))));
5718
5719 return "lghrl";
5720}
5721
5722static HChar *
5723s390_irgen_LHH(UChar r1, IRTemp op2addr)
5724{
5725 put_gpr_w0(r1, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
5726
5727 return "lhh";
5728}
5729
5730static HChar *
5731s390_irgen_LFH(UChar r1, IRTemp op2addr)
5732{
5733 put_gpr_w0(r1, load(Ity_I32, mkexpr(op2addr)));
5734
5735 return "lfh";
5736}
5737
5738static HChar *
5739s390_irgen_LLGFR(UChar r1, UChar r2)
5740{
5741 put_gpr_dw0(r1, unop(Iop_32Uto64, get_gpr_w1(r2)));
5742
5743 return "llgfr";
5744}
5745
5746static HChar *
5747s390_irgen_LLGF(UChar r1, IRTemp op2addr)
5748{
5749 put_gpr_dw0(r1, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
5750
5751 return "llgf";
5752}
5753
5754static HChar *
5755s390_irgen_LLGFRL(UChar r1, UInt i2)
5756{
5757 put_gpr_dw0(r1, unop(Iop_32Uto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
5758 ((ULong)(Long)(Int)i2 << 1)))));
5759
5760 return "llgfrl";
5761}
5762
5763static HChar *
5764s390_irgen_LLCR(UChar r1, UChar r2)
5765{
5766 put_gpr_w1(r1, unop(Iop_8Uto32, get_gpr_b7(r2)));
5767
5768 return "llcr";
5769}
5770
5771static HChar *
5772s390_irgen_LLGCR(UChar r1, UChar r2)
5773{
5774 put_gpr_dw0(r1, unop(Iop_8Uto64, get_gpr_b7(r2)));
5775
5776 return "llgcr";
5777}
5778
5779static HChar *
5780s390_irgen_LLC(UChar r1, IRTemp op2addr)
5781{
5782 put_gpr_w1(r1, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
5783
5784 return "llc";
5785}
5786
5787static HChar *
5788s390_irgen_LLGC(UChar r1, IRTemp op2addr)
5789{
5790 put_gpr_dw0(r1, unop(Iop_8Uto64, load(Ity_I8, mkexpr(op2addr))));
5791
5792 return "llgc";
5793}
5794
5795static HChar *
5796s390_irgen_LLCH(UChar r1, IRTemp op2addr)
5797{
5798 put_gpr_w0(r1, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
5799
5800 return "llch";
5801}
5802
5803static HChar *
5804s390_irgen_LLHR(UChar r1, UChar r2)
5805{
5806 put_gpr_w1(r1, unop(Iop_16Uto32, get_gpr_hw3(r2)));
5807
5808 return "llhr";
5809}
5810
5811static HChar *
5812s390_irgen_LLGHR(UChar r1, UChar r2)
5813{
5814 put_gpr_dw0(r1, unop(Iop_16Uto64, get_gpr_hw3(r2)));
5815
5816 return "llghr";
5817}
5818
5819static HChar *
5820s390_irgen_LLH(UChar r1, IRTemp op2addr)
5821{
5822 put_gpr_w1(r1, unop(Iop_16Uto32, load(Ity_I16, mkexpr(op2addr))));
5823
5824 return "llh";
5825}
5826
5827static HChar *
5828s390_irgen_LLGH(UChar r1, IRTemp op2addr)
5829{
5830 put_gpr_dw0(r1, unop(Iop_16Uto64, load(Ity_I16, mkexpr(op2addr))));
5831
5832 return "llgh";
5833}
5834
5835static HChar *
5836s390_irgen_LLHRL(UChar r1, UInt i2)
5837{
5838 put_gpr_w1(r1, unop(Iop_16Uto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
5839 ((ULong)(Long)(Int)i2 << 1)))));
5840
5841 return "llhrl";
5842}
5843
5844static HChar *
5845s390_irgen_LLGHRL(UChar r1, UInt i2)
5846{
5847 put_gpr_dw0(r1, unop(Iop_16Uto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
5848 ((ULong)(Long)(Int)i2 << 1)))));
5849
5850 return "llghrl";
5851}
5852
5853static HChar *
5854s390_irgen_LLHH(UChar r1, IRTemp op2addr)
5855{
5856 put_gpr_w0(r1, unop(Iop_16Uto32, load(Ity_I16, mkexpr(op2addr))));
5857
5858 return "llhh";
5859}
5860
5861static HChar *
5862s390_irgen_LLIHF(UChar r1, UInt i2)
5863{
5864 put_gpr_dw0(r1, mkU64(((ULong)i2) << 32));
5865
5866 return "llihf";
5867}
5868
5869static HChar *
5870s390_irgen_LLIHH(UChar r1, UShort i2)
5871{
5872 put_gpr_dw0(r1, mkU64(((ULong)i2) << 48));
5873
5874 return "llihh";
5875}
5876
5877static HChar *
5878s390_irgen_LLIHL(UChar r1, UShort i2)
5879{
5880 put_gpr_dw0(r1, mkU64(((ULong)i2) << 32));
5881
5882 return "llihl";
5883}
5884
5885static HChar *
5886s390_irgen_LLILF(UChar r1, UInt i2)
5887{
5888 put_gpr_dw0(r1, mkU64(i2));
5889
5890 return "llilf";
5891}
5892
5893static HChar *
5894s390_irgen_LLILH(UChar r1, UShort i2)
5895{
5896 put_gpr_dw0(r1, mkU64(((ULong)i2) << 16));
5897
5898 return "llilh";
5899}
5900
5901static HChar *
5902s390_irgen_LLILL(UChar r1, UShort i2)
5903{
5904 put_gpr_dw0(r1, mkU64(i2));
5905
5906 return "llill";
5907}
5908
5909static HChar *
5910s390_irgen_LLGTR(UChar r1, UChar r2)
5911{
5912 put_gpr_dw0(r1, unop(Iop_32Uto64, binop(Iop_And32, get_gpr_w1(r2),
5913 mkU32(2147483647))));
5914
5915 return "llgtr";
5916}
5917
5918static HChar *
5919s390_irgen_LLGT(UChar r1, IRTemp op2addr)
5920{
5921 put_gpr_dw0(r1, unop(Iop_32Uto64, binop(Iop_And32, load(Ity_I32,
5922 mkexpr(op2addr)), mkU32(2147483647))));
5923
5924 return "llgt";
5925}
5926
5927static HChar *
5928s390_irgen_LNR(UChar r1, UChar r2)
5929{
5930 IRTemp op2 = newTemp(Ity_I32);
5931 IRTemp result = newTemp(Ity_I32);
5932
5933 assign(op2, get_gpr_w1(r2));
5934 assign(result, mkite(binop(Iop_CmpLE32S, mkexpr(op2), mkU32(0)), mkexpr(op2),
5935 binop(Iop_Sub32, mkU32(0), mkexpr(op2))));
5936 put_gpr_w1(r1, mkexpr(result));
5937 s390_cc_thunk_putS(S390_CC_OP_BITWISE, result);
5938
5939 return "lnr";
5940}
5941
5942static HChar *
5943s390_irgen_LNGR(UChar r1, UChar r2)
5944{
5945 IRTemp op2 = newTemp(Ity_I64);
5946 IRTemp result = newTemp(Ity_I64);
5947
5948 assign(op2, get_gpr_dw0(r2));
5949 assign(result, mkite(binop(Iop_CmpLE64S, mkexpr(op2), mkU64(0)), mkexpr(op2),
5950 binop(Iop_Sub64, mkU64(0), mkexpr(op2))));
5951 put_gpr_dw0(r1, mkexpr(result));
5952 s390_cc_thunk_putS(S390_CC_OP_BITWISE, result);
5953
5954 return "lngr";
5955}
5956
5957static HChar *
5958s390_irgen_LNGFR(UChar r1, UChar r2 __attribute__((unused)))
5959{
5960 IRTemp op2 = newTemp(Ity_I64);
5961 IRTemp result = newTemp(Ity_I64);
5962
5963 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r1)));
5964 assign(result, mkite(binop(Iop_CmpLE64S, mkexpr(op2), mkU64(0)), mkexpr(op2),
5965 binop(Iop_Sub64, mkU64(0), mkexpr(op2))));
5966 put_gpr_dw0(r1, mkexpr(result));
5967 s390_cc_thunk_putS(S390_CC_OP_BITWISE, result);
5968
5969 return "lngfr";
5970}
5971
5972static HChar *
sewardjd7bde722011-04-05 13:19:33 +00005973s390_irgen_LOCR(UChar m3, UChar r1, UChar r2)
5974{
florian6820ba52012-07-26 02:01:50 +00005975 next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0)));
sewardjd7bde722011-04-05 13:19:33 +00005976 put_gpr_w1(r1, get_gpr_w1(r2));
5977
5978 return "locr";
5979}
5980
5981static HChar *
5982s390_irgen_LOCGR(UChar m3, UChar r1, UChar r2)
5983{
florian6820ba52012-07-26 02:01:50 +00005984 next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0)));
sewardjd7bde722011-04-05 13:19:33 +00005985 put_gpr_dw0(r1, get_gpr_dw0(r2));
5986
5987 return "locgr";
5988}
5989
5990static HChar *
5991s390_irgen_LOC(UChar r1, IRTemp op2addr)
5992{
5993 /* condition is checked in format handler */
5994 put_gpr_w1(r1, load(Ity_I32, mkexpr(op2addr)));
5995
5996 return "loc";
5997}
5998
5999static HChar *
6000s390_irgen_LOCG(UChar r1, IRTemp op2addr)
6001{
6002 /* condition is checked in format handler */
6003 put_gpr_dw0(r1, load(Ity_I64, mkexpr(op2addr)));
6004
6005 return "locg";
6006}
6007
6008static HChar *
sewardj2019a972011-03-07 16:04:07 +00006009s390_irgen_LPQ(UChar r1, IRTemp op2addr)
6010{
6011 put_gpr_dw0(r1, load(Ity_I64, mkexpr(op2addr)));
6012 put_gpr_dw0(r1 + 1, load(Ity_I64, binop(Iop_Add64, mkexpr(op2addr), mkU64(8))
6013 ));
6014
6015 return "lpq";
6016}
6017
6018static HChar *
6019s390_irgen_LPR(UChar r1, UChar r2)
6020{
6021 IRTemp op2 = newTemp(Ity_I32);
6022 IRTemp result = newTemp(Ity_I32);
6023
6024 assign(op2, get_gpr_w1(r2));
6025 assign(result, mkite(binop(Iop_CmpLT32S, mkexpr(op2), mkU32(0)),
6026 binop(Iop_Sub32, mkU32(0), mkexpr(op2)), mkexpr(op2)));
6027 put_gpr_w1(r1, mkexpr(result));
6028 s390_cc_thunk_putS(S390_CC_OP_LOAD_POSITIVE_32, op2);
6029
6030 return "lpr";
6031}
6032
6033static HChar *
6034s390_irgen_LPGR(UChar r1, UChar r2)
6035{
6036 IRTemp op2 = newTemp(Ity_I64);
6037 IRTemp result = newTemp(Ity_I64);
6038
6039 assign(op2, get_gpr_dw0(r2));
6040 assign(result, mkite(binop(Iop_CmpLT64S, mkexpr(op2), mkU64(0)),
6041 binop(Iop_Sub64, mkU64(0), mkexpr(op2)), mkexpr(op2)));
6042 put_gpr_dw0(r1, mkexpr(result));
6043 s390_cc_thunk_putS(S390_CC_OP_LOAD_POSITIVE_64, op2);
6044
6045 return "lpgr";
6046}
6047
6048static HChar *
6049s390_irgen_LPGFR(UChar r1, UChar r2)
6050{
6051 IRTemp op2 = newTemp(Ity_I64);
6052 IRTemp result = newTemp(Ity_I64);
6053
6054 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
6055 assign(result, mkite(binop(Iop_CmpLT64S, mkexpr(op2), mkU64(0)),
6056 binop(Iop_Sub64, mkU64(0), mkexpr(op2)), mkexpr(op2)));
6057 put_gpr_dw0(r1, mkexpr(result));
6058 s390_cc_thunk_putS(S390_CC_OP_LOAD_POSITIVE_64, op2);
6059
6060 return "lpgfr";
6061}
6062
6063static HChar *
6064s390_irgen_LRVR(UChar r1, UChar r2)
6065{
6066 IRTemp b0 = newTemp(Ity_I8);
6067 IRTemp b1 = newTemp(Ity_I8);
6068 IRTemp b2 = newTemp(Ity_I8);
6069 IRTemp b3 = newTemp(Ity_I8);
6070
6071 assign(b3, get_gpr_b7(r2));
6072 assign(b2, get_gpr_b6(r2));
6073 assign(b1, get_gpr_b5(r2));
6074 assign(b0, get_gpr_b4(r2));
6075 put_gpr_b4(r1, mkexpr(b3));
6076 put_gpr_b5(r1, mkexpr(b2));
6077 put_gpr_b6(r1, mkexpr(b1));
6078 put_gpr_b7(r1, mkexpr(b0));
6079
6080 return "lrvr";
6081}
6082
6083static HChar *
6084s390_irgen_LRVGR(UChar r1, UChar r2)
6085{
6086 IRTemp b0 = newTemp(Ity_I8);
6087 IRTemp b1 = newTemp(Ity_I8);
6088 IRTemp b2 = newTemp(Ity_I8);
6089 IRTemp b3 = newTemp(Ity_I8);
6090 IRTemp b4 = newTemp(Ity_I8);
6091 IRTemp b5 = newTemp(Ity_I8);
6092 IRTemp b6 = newTemp(Ity_I8);
6093 IRTemp b7 = newTemp(Ity_I8);
6094
6095 assign(b7, get_gpr_b7(r2));
6096 assign(b6, get_gpr_b6(r2));
6097 assign(b5, get_gpr_b5(r2));
6098 assign(b4, get_gpr_b4(r2));
6099 assign(b3, get_gpr_b3(r2));
6100 assign(b2, get_gpr_b2(r2));
6101 assign(b1, get_gpr_b1(r2));
6102 assign(b0, get_gpr_b0(r2));
6103 put_gpr_b0(r1, mkexpr(b7));
6104 put_gpr_b1(r1, mkexpr(b6));
6105 put_gpr_b2(r1, mkexpr(b5));
6106 put_gpr_b3(r1, mkexpr(b4));
6107 put_gpr_b4(r1, mkexpr(b3));
6108 put_gpr_b5(r1, mkexpr(b2));
6109 put_gpr_b6(r1, mkexpr(b1));
6110 put_gpr_b7(r1, mkexpr(b0));
6111
6112 return "lrvgr";
6113}
6114
6115static HChar *
6116s390_irgen_LRVH(UChar r1, IRTemp op2addr)
6117{
6118 IRTemp op2 = newTemp(Ity_I16);
6119
6120 assign(op2, load(Ity_I16, mkexpr(op2addr)));
6121 put_gpr_b6(r1, unop(Iop_16to8, mkexpr(op2)));
6122 put_gpr_b7(r1, unop(Iop_16HIto8, mkexpr(op2)));
6123
6124 return "lrvh";
6125}
6126
6127static HChar *
6128s390_irgen_LRV(UChar r1, IRTemp op2addr)
6129{
6130 IRTemp op2 = newTemp(Ity_I32);
6131
6132 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6133 put_gpr_b4(r1, unop(Iop_32to8, binop(Iop_And32, mkexpr(op2), mkU32(255))));
6134 put_gpr_b5(r1, unop(Iop_32to8, binop(Iop_And32, binop(Iop_Shr32, mkexpr(op2),
6135 mkU8(8)), mkU32(255))));
6136 put_gpr_b6(r1, unop(Iop_32to8, binop(Iop_And32, binop(Iop_Shr32, mkexpr(op2),
6137 mkU8(16)), mkU32(255))));
6138 put_gpr_b7(r1, unop(Iop_32to8, binop(Iop_And32, binop(Iop_Shr32, mkexpr(op2),
6139 mkU8(24)), mkU32(255))));
6140
6141 return "lrv";
6142}
6143
6144static HChar *
6145s390_irgen_LRVG(UChar r1, IRTemp op2addr)
6146{
6147 IRTemp op2 = newTemp(Ity_I64);
6148
6149 assign(op2, load(Ity_I64, mkexpr(op2addr)));
6150 put_gpr_b0(r1, unop(Iop_64to8, binop(Iop_And64, mkexpr(op2), mkU64(255))));
6151 put_gpr_b1(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6152 mkU8(8)), mkU64(255))));
6153 put_gpr_b2(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6154 mkU8(16)), mkU64(255))));
6155 put_gpr_b3(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6156 mkU8(24)), mkU64(255))));
6157 put_gpr_b4(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6158 mkU8(32)), mkU64(255))));
6159 put_gpr_b5(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6160 mkU8(40)), mkU64(255))));
6161 put_gpr_b6(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6162 mkU8(48)), mkU64(255))));
6163 put_gpr_b7(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6164 mkU8(56)), mkU64(255))));
6165
6166 return "lrvg";
6167}
6168
6169static HChar *
6170s390_irgen_MVHHI(UShort i2, IRTemp op1addr)
6171{
6172 store(mkexpr(op1addr), mkU16(i2));
6173
6174 return "mvhhi";
6175}
6176
6177static HChar *
6178s390_irgen_MVHI(UShort i2, IRTemp op1addr)
6179{
6180 store(mkexpr(op1addr), mkU32((UInt)(Int)(Short)i2));
6181
6182 return "mvhi";
6183}
6184
6185static HChar *
6186s390_irgen_MVGHI(UShort i2, IRTemp op1addr)
6187{
6188 store(mkexpr(op1addr), mkU64((ULong)(Long)(Short)i2));
6189
6190 return "mvghi";
6191}
6192
6193static HChar *
6194s390_irgen_MVI(UChar i2, IRTemp op1addr)
6195{
6196 store(mkexpr(op1addr), mkU8(i2));
6197
6198 return "mvi";
6199}
6200
6201static HChar *
6202s390_irgen_MVIY(UChar i2, IRTemp op1addr)
6203{
6204 store(mkexpr(op1addr), mkU8(i2));
6205
6206 return "mviy";
6207}
6208
6209static HChar *
6210s390_irgen_MR(UChar r1, UChar r2)
6211{
6212 IRTemp op1 = newTemp(Ity_I32);
6213 IRTemp op2 = newTemp(Ity_I32);
6214 IRTemp result = newTemp(Ity_I64);
6215
6216 assign(op1, get_gpr_w1(r1 + 1));
6217 assign(op2, get_gpr_w1(r2));
6218 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6219 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6220 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6221
6222 return "mr";
6223}
6224
6225static HChar *
6226s390_irgen_M(UChar r1, IRTemp op2addr)
6227{
6228 IRTemp op1 = newTemp(Ity_I32);
6229 IRTemp op2 = newTemp(Ity_I32);
6230 IRTemp result = newTemp(Ity_I64);
6231
6232 assign(op1, get_gpr_w1(r1 + 1));
6233 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6234 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6235 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6236 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6237
6238 return "m";
6239}
6240
6241static HChar *
6242s390_irgen_MFY(UChar r1, IRTemp op2addr)
6243{
6244 IRTemp op1 = newTemp(Ity_I32);
6245 IRTemp op2 = newTemp(Ity_I32);
6246 IRTemp result = newTemp(Ity_I64);
6247
6248 assign(op1, get_gpr_w1(r1 + 1));
6249 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6250 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6251 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6252 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6253
6254 return "mfy";
6255}
6256
6257static HChar *
6258s390_irgen_MH(UChar r1, IRTemp op2addr)
6259{
6260 IRTemp op1 = newTemp(Ity_I32);
6261 IRTemp op2 = newTemp(Ity_I16);
6262 IRTemp result = newTemp(Ity_I64);
6263
6264 assign(op1, get_gpr_w1(r1));
6265 assign(op2, load(Ity_I16, mkexpr(op2addr)));
6266 assign(result, binop(Iop_MullS32, mkexpr(op1), unop(Iop_16Sto32, mkexpr(op2))
6267 ));
6268 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6269
6270 return "mh";
6271}
6272
6273static HChar *
6274s390_irgen_MHY(UChar r1, IRTemp op2addr)
6275{
6276 IRTemp op1 = newTemp(Ity_I32);
6277 IRTemp op2 = newTemp(Ity_I16);
6278 IRTemp result = newTemp(Ity_I64);
6279
6280 assign(op1, get_gpr_w1(r1));
6281 assign(op2, load(Ity_I16, mkexpr(op2addr)));
6282 assign(result, binop(Iop_MullS32, mkexpr(op1), unop(Iop_16Sto32, mkexpr(op2))
6283 ));
6284 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6285
6286 return "mhy";
6287}
6288
6289static HChar *
6290s390_irgen_MHI(UChar r1, UShort i2)
6291{
6292 IRTemp op1 = newTemp(Ity_I32);
6293 Short op2;
6294 IRTemp result = newTemp(Ity_I64);
6295
6296 assign(op1, get_gpr_w1(r1));
6297 op2 = (Short)i2;
6298 assign(result, binop(Iop_MullS32, mkexpr(op1), unop(Iop_16Sto32,
6299 mkU16((UShort)op2))));
6300 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6301
6302 return "mhi";
6303}
6304
6305static HChar *
6306s390_irgen_MGHI(UChar r1, UShort i2)
6307{
6308 IRTemp op1 = newTemp(Ity_I64);
6309 Short op2;
6310 IRTemp result = newTemp(Ity_I128);
6311
6312 assign(op1, get_gpr_dw0(r1));
6313 op2 = (Short)i2;
6314 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_16Sto64,
6315 mkU16((UShort)op2))));
6316 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6317
6318 return "mghi";
6319}
6320
6321static HChar *
6322s390_irgen_MLR(UChar r1, UChar r2)
6323{
6324 IRTemp op1 = newTemp(Ity_I32);
6325 IRTemp op2 = newTemp(Ity_I32);
6326 IRTemp result = newTemp(Ity_I64);
6327
6328 assign(op1, get_gpr_w1(r1 + 1));
6329 assign(op2, get_gpr_w1(r2));
6330 assign(result, binop(Iop_MullU32, mkexpr(op1), mkexpr(op2)));
6331 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6332 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6333
6334 return "mlr";
6335}
6336
6337static HChar *
6338s390_irgen_MLGR(UChar r1, UChar r2)
6339{
6340 IRTemp op1 = newTemp(Ity_I64);
6341 IRTemp op2 = newTemp(Ity_I64);
6342 IRTemp result = newTemp(Ity_I128);
6343
6344 assign(op1, get_gpr_dw0(r1 + 1));
6345 assign(op2, get_gpr_dw0(r2));
6346 assign(result, binop(Iop_MullU64, mkexpr(op1), mkexpr(op2)));
6347 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result)));
6348 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result)));
6349
6350 return "mlgr";
6351}
6352
6353static HChar *
6354s390_irgen_ML(UChar r1, IRTemp op2addr)
6355{
6356 IRTemp op1 = newTemp(Ity_I32);
6357 IRTemp op2 = newTemp(Ity_I32);
6358 IRTemp result = newTemp(Ity_I64);
6359
6360 assign(op1, get_gpr_w1(r1 + 1));
6361 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6362 assign(result, binop(Iop_MullU32, mkexpr(op1), mkexpr(op2)));
6363 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6364 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6365
6366 return "ml";
6367}
6368
6369static HChar *
6370s390_irgen_MLG(UChar r1, IRTemp op2addr)
6371{
6372 IRTemp op1 = newTemp(Ity_I64);
6373 IRTemp op2 = newTemp(Ity_I64);
6374 IRTemp result = newTemp(Ity_I128);
6375
6376 assign(op1, get_gpr_dw0(r1 + 1));
6377 assign(op2, load(Ity_I64, mkexpr(op2addr)));
6378 assign(result, binop(Iop_MullU64, mkexpr(op1), mkexpr(op2)));
6379 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result)));
6380 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result)));
6381
6382 return "mlg";
6383}
6384
6385static HChar *
6386s390_irgen_MSR(UChar r1, UChar r2)
6387{
6388 IRTemp op1 = newTemp(Ity_I32);
6389 IRTemp op2 = newTemp(Ity_I32);
6390 IRTemp result = newTemp(Ity_I64);
6391
6392 assign(op1, get_gpr_w1(r1));
6393 assign(op2, get_gpr_w1(r2));
6394 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6395 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6396
6397 return "msr";
6398}
6399
6400static HChar *
6401s390_irgen_MSGR(UChar r1, UChar r2)
6402{
6403 IRTemp op1 = newTemp(Ity_I64);
6404 IRTemp op2 = newTemp(Ity_I64);
6405 IRTemp result = newTemp(Ity_I128);
6406
6407 assign(op1, get_gpr_dw0(r1));
6408 assign(op2, get_gpr_dw0(r2));
6409 assign(result, binop(Iop_MullS64, mkexpr(op1), mkexpr(op2)));
6410 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6411
6412 return "msgr";
6413}
6414
6415static HChar *
6416s390_irgen_MSGFR(UChar r1, UChar r2)
6417{
6418 IRTemp op1 = newTemp(Ity_I64);
6419 IRTemp op2 = newTemp(Ity_I32);
6420 IRTemp result = newTemp(Ity_I128);
6421
6422 assign(op1, get_gpr_dw0(r1));
6423 assign(op2, get_gpr_w1(r2));
6424 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_32Sto64, mkexpr(op2))
6425 ));
6426 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6427
6428 return "msgfr";
6429}
6430
6431static HChar *
6432s390_irgen_MS(UChar r1, IRTemp op2addr)
6433{
6434 IRTemp op1 = newTemp(Ity_I32);
6435 IRTemp op2 = newTemp(Ity_I32);
6436 IRTemp result = newTemp(Ity_I64);
6437
6438 assign(op1, get_gpr_w1(r1));
6439 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6440 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6441 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6442
6443 return "ms";
6444}
6445
6446static HChar *
6447s390_irgen_MSY(UChar r1, IRTemp op2addr)
6448{
6449 IRTemp op1 = newTemp(Ity_I32);
6450 IRTemp op2 = newTemp(Ity_I32);
6451 IRTemp result = newTemp(Ity_I64);
6452
6453 assign(op1, get_gpr_w1(r1));
6454 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6455 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6456 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6457
6458 return "msy";
6459}
6460
6461static HChar *
6462s390_irgen_MSG(UChar r1, IRTemp op2addr)
6463{
6464 IRTemp op1 = newTemp(Ity_I64);
6465 IRTemp op2 = newTemp(Ity_I64);
6466 IRTemp result = newTemp(Ity_I128);
6467
6468 assign(op1, get_gpr_dw0(r1));
6469 assign(op2, load(Ity_I64, mkexpr(op2addr)));
6470 assign(result, binop(Iop_MullS64, mkexpr(op1), mkexpr(op2)));
6471 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6472
6473 return "msg";
6474}
6475
6476static HChar *
6477s390_irgen_MSGF(UChar r1, IRTemp op2addr)
6478{
6479 IRTemp op1 = newTemp(Ity_I64);
6480 IRTemp op2 = newTemp(Ity_I32);
6481 IRTemp result = newTemp(Ity_I128);
6482
6483 assign(op1, get_gpr_dw0(r1));
6484 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6485 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_32Sto64, mkexpr(op2))
6486 ));
6487 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6488
6489 return "msgf";
6490}
6491
6492static HChar *
6493s390_irgen_MSFI(UChar r1, UInt i2)
6494{
6495 IRTemp op1 = newTemp(Ity_I32);
6496 Int op2;
6497 IRTemp result = newTemp(Ity_I64);
6498
6499 assign(op1, get_gpr_w1(r1));
6500 op2 = (Int)i2;
6501 assign(result, binop(Iop_MullS32, mkexpr(op1), mkU32((UInt)op2)));
6502 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6503
6504 return "msfi";
6505}
6506
6507static HChar *
6508s390_irgen_MSGFI(UChar r1, UInt i2)
6509{
6510 IRTemp op1 = newTemp(Ity_I64);
6511 Int op2;
6512 IRTemp result = newTemp(Ity_I128);
6513
6514 assign(op1, get_gpr_dw0(r1));
6515 op2 = (Int)i2;
6516 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_32Sto64, mkU32((UInt)
6517 op2))));
6518 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6519
6520 return "msgfi";
6521}
6522
6523static HChar *
6524s390_irgen_OR(UChar r1, UChar r2)
6525{
6526 IRTemp op1 = newTemp(Ity_I32);
6527 IRTemp op2 = newTemp(Ity_I32);
6528 IRTemp result = newTemp(Ity_I32);
6529
6530 assign(op1, get_gpr_w1(r1));
6531 assign(op2, get_gpr_w1(r2));
6532 assign(result, binop(Iop_Or32, mkexpr(op1), mkexpr(op2)));
6533 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6534 put_gpr_w1(r1, mkexpr(result));
6535
6536 return "or";
6537}
6538
6539static HChar *
6540s390_irgen_OGR(UChar r1, UChar r2)
6541{
6542 IRTemp op1 = newTemp(Ity_I64);
6543 IRTemp op2 = newTemp(Ity_I64);
6544 IRTemp result = newTemp(Ity_I64);
6545
6546 assign(op1, get_gpr_dw0(r1));
6547 assign(op2, get_gpr_dw0(r2));
6548 assign(result, binop(Iop_Or64, mkexpr(op1), mkexpr(op2)));
6549 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6550 put_gpr_dw0(r1, mkexpr(result));
6551
6552 return "ogr";
6553}
6554
6555static HChar *
6556s390_irgen_ORK(UChar r3, UChar r1, UChar r2)
6557{
6558 IRTemp op2 = newTemp(Ity_I32);
6559 IRTemp op3 = newTemp(Ity_I32);
6560 IRTemp result = newTemp(Ity_I32);
6561
6562 assign(op2, get_gpr_w1(r2));
6563 assign(op3, get_gpr_w1(r3));
6564 assign(result, binop(Iop_Or32, mkexpr(op2), mkexpr(op3)));
6565 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6566 put_gpr_w1(r1, mkexpr(result));
6567
6568 return "ork";
6569}
6570
6571static HChar *
6572s390_irgen_OGRK(UChar r3, UChar r1, UChar r2)
6573{
6574 IRTemp op2 = newTemp(Ity_I64);
6575 IRTemp op3 = newTemp(Ity_I64);
6576 IRTemp result = newTemp(Ity_I64);
6577
6578 assign(op2, get_gpr_dw0(r2));
6579 assign(op3, get_gpr_dw0(r3));
6580 assign(result, binop(Iop_Or64, mkexpr(op2), mkexpr(op3)));
6581 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6582 put_gpr_dw0(r1, mkexpr(result));
6583
6584 return "ogrk";
6585}
6586
6587static HChar *
6588s390_irgen_O(UChar r1, IRTemp op2addr)
6589{
6590 IRTemp op1 = newTemp(Ity_I32);
6591 IRTemp op2 = newTemp(Ity_I32);
6592 IRTemp result = newTemp(Ity_I32);
6593
6594 assign(op1, get_gpr_w1(r1));
6595 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6596 assign(result, binop(Iop_Or32, mkexpr(op1), mkexpr(op2)));
6597 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6598 put_gpr_w1(r1, mkexpr(result));
6599
6600 return "o";
6601}
6602
6603static HChar *
6604s390_irgen_OY(UChar r1, IRTemp op2addr)
6605{
6606 IRTemp op1 = newTemp(Ity_I32);
6607 IRTemp op2 = newTemp(Ity_I32);
6608 IRTemp result = newTemp(Ity_I32);
6609
6610 assign(op1, get_gpr_w1(r1));
6611 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6612 assign(result, binop(Iop_Or32, mkexpr(op1), mkexpr(op2)));
6613 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6614 put_gpr_w1(r1, mkexpr(result));
6615
6616 return "oy";
6617}
6618
6619static HChar *
6620s390_irgen_OG(UChar r1, IRTemp op2addr)
6621{
6622 IRTemp op1 = newTemp(Ity_I64);
6623 IRTemp op2 = newTemp(Ity_I64);
6624 IRTemp result = newTemp(Ity_I64);
6625
6626 assign(op1, get_gpr_dw0(r1));
6627 assign(op2, load(Ity_I64, mkexpr(op2addr)));
6628 assign(result, binop(Iop_Or64, mkexpr(op1), mkexpr(op2)));
6629 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6630 put_gpr_dw0(r1, mkexpr(result));
6631
6632 return "og";
6633}
6634
6635static HChar *
6636s390_irgen_OI(UChar i2, IRTemp op1addr)
6637{
6638 IRTemp op1 = newTemp(Ity_I8);
6639 UChar op2;
6640 IRTemp result = newTemp(Ity_I8);
6641
6642 assign(op1, load(Ity_I8, mkexpr(op1addr)));
6643 op2 = i2;
6644 assign(result, binop(Iop_Or8, mkexpr(op1), mkU8(op2)));
6645 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6646 store(mkexpr(op1addr), mkexpr(result));
6647
6648 return "oi";
6649}
6650
6651static HChar *
6652s390_irgen_OIY(UChar i2, IRTemp op1addr)
6653{
6654 IRTemp op1 = newTemp(Ity_I8);
6655 UChar op2;
6656 IRTemp result = newTemp(Ity_I8);
6657
6658 assign(op1, load(Ity_I8, mkexpr(op1addr)));
6659 op2 = i2;
6660 assign(result, binop(Iop_Or8, mkexpr(op1), mkU8(op2)));
6661 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6662 store(mkexpr(op1addr), mkexpr(result));
6663
6664 return "oiy";
6665}
6666
6667static HChar *
6668s390_irgen_OIHF(UChar r1, UInt i2)
6669{
6670 IRTemp op1 = newTemp(Ity_I32);
6671 UInt op2;
6672 IRTemp result = newTemp(Ity_I32);
6673
6674 assign(op1, get_gpr_w0(r1));
6675 op2 = i2;
6676 assign(result, binop(Iop_Or32, mkexpr(op1), mkU32(op2)));
6677 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6678 put_gpr_w0(r1, mkexpr(result));
6679
6680 return "oihf";
6681}
6682
6683static HChar *
6684s390_irgen_OIHH(UChar r1, UShort i2)
6685{
6686 IRTemp op1 = newTemp(Ity_I16);
6687 UShort op2;
6688 IRTemp result = newTemp(Ity_I16);
6689
6690 assign(op1, get_gpr_hw0(r1));
6691 op2 = i2;
6692 assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
6693 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6694 put_gpr_hw0(r1, mkexpr(result));
6695
6696 return "oihh";
6697}
6698
6699static HChar *
6700s390_irgen_OIHL(UChar r1, UShort i2)
6701{
6702 IRTemp op1 = newTemp(Ity_I16);
6703 UShort op2;
6704 IRTemp result = newTemp(Ity_I16);
6705
6706 assign(op1, get_gpr_hw1(r1));
6707 op2 = i2;
6708 assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
6709 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6710 put_gpr_hw1(r1, mkexpr(result));
6711
6712 return "oihl";
6713}
6714
6715static HChar *
6716s390_irgen_OILF(UChar r1, UInt i2)
6717{
6718 IRTemp op1 = newTemp(Ity_I32);
6719 UInt op2;
6720 IRTemp result = newTemp(Ity_I32);
6721
6722 assign(op1, get_gpr_w1(r1));
6723 op2 = i2;
6724 assign(result, binop(Iop_Or32, mkexpr(op1), mkU32(op2)));
6725 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6726 put_gpr_w1(r1, mkexpr(result));
6727
6728 return "oilf";
6729}
6730
6731static HChar *
6732s390_irgen_OILH(UChar r1, UShort i2)
6733{
6734 IRTemp op1 = newTemp(Ity_I16);
6735 UShort op2;
6736 IRTemp result = newTemp(Ity_I16);
6737
6738 assign(op1, get_gpr_hw2(r1));
6739 op2 = i2;
6740 assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
6741 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6742 put_gpr_hw2(r1, mkexpr(result));
6743
6744 return "oilh";
6745}
6746
6747static HChar *
6748s390_irgen_OILL(UChar r1, UShort i2)
6749{
6750 IRTemp op1 = newTemp(Ity_I16);
6751 UShort op2;
6752 IRTemp result = newTemp(Ity_I16);
6753
6754 assign(op1, get_gpr_hw3(r1));
6755 op2 = i2;
6756 assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
6757 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6758 put_gpr_hw3(r1, mkexpr(result));
6759
6760 return "oill";
6761}
6762
6763static HChar *
6764s390_irgen_PFD(void)
6765{
6766
6767 return "pfd";
6768}
6769
6770static HChar *
6771s390_irgen_PFDRL(void)
6772{
6773
6774 return "pfdrl";
6775}
6776
6777static HChar *
6778s390_irgen_RLL(UChar r1, UChar r3, IRTemp op2addr)
6779{
6780 IRTemp amount = newTemp(Ity_I64);
6781 IRTemp op = newTemp(Ity_I32);
6782
6783 assign(amount, binop(Iop_And64, mkexpr(op2addr), mkU64(31)));
6784 assign(op, get_gpr_w1(r3));
6785 put_gpr_w1(r1, binop(Iop_Or32, binop(Iop_Shl32, mkexpr(op), unop(Iop_64to8,
6786 mkexpr(amount))), binop(Iop_Shr32, mkexpr(op), unop(Iop_64to8,
6787 binop(Iop_Sub64, mkU64(32), mkexpr(amount))))));
6788
6789 return "rll";
6790}
6791
6792static HChar *
6793s390_irgen_RLLG(UChar r1, UChar r3, IRTemp op2addr)
6794{
6795 IRTemp amount = newTemp(Ity_I64);
6796 IRTemp op = newTemp(Ity_I64);
6797
6798 assign(amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
6799 assign(op, get_gpr_dw0(r3));
6800 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(op), unop(Iop_64to8,
6801 mkexpr(amount))), binop(Iop_Shr64, mkexpr(op), unop(Iop_64to8,
6802 binop(Iop_Sub64, mkU64(64), mkexpr(amount))))));
6803
6804 return "rllg";
6805}
6806
6807static HChar *
6808s390_irgen_RNSBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
6809{
6810 UChar from;
6811 UChar to;
6812 UChar rot;
6813 UChar t_bit;
6814 ULong mask;
6815 ULong maskc;
6816 IRTemp result = newTemp(Ity_I64);
6817 IRTemp op2 = newTemp(Ity_I64);
6818
6819 from = i3 & 63;
6820 to = i4 & 63;
6821 rot = i5 & 63;
6822 t_bit = i3 & 128;
6823 assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
6824 get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
6825 mkU8(64 - rot))));
6826 if (from <= to) {
6827 mask = ~0ULL;
6828 mask = (mask >> from) & (mask << (63 - to));
6829 maskc = ~mask;
6830 } else {
6831 maskc = ~0ULL;
6832 maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
6833 mask = ~maskc;
6834 }
6835 assign(result, binop(Iop_And64, binop(Iop_And64, get_gpr_dw0(r1), mkexpr(op2)
6836 ), mkU64(mask)));
6837 if (t_bit == 0) {
6838 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
6839 mkU64(maskc)), mkexpr(result)));
6840 }
6841 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6842
6843 return "rnsbg";
6844}
6845
6846static HChar *
6847s390_irgen_RXSBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
6848{
6849 UChar from;
6850 UChar to;
6851 UChar rot;
6852 UChar t_bit;
6853 ULong mask;
6854 ULong maskc;
6855 IRTemp result = newTemp(Ity_I64);
6856 IRTemp op2 = newTemp(Ity_I64);
6857
6858 from = i3 & 63;
6859 to = i4 & 63;
6860 rot = i5 & 63;
6861 t_bit = i3 & 128;
6862 assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
6863 get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
6864 mkU8(64 - rot))));
6865 if (from <= to) {
6866 mask = ~0ULL;
6867 mask = (mask >> from) & (mask << (63 - to));
6868 maskc = ~mask;
6869 } else {
6870 maskc = ~0ULL;
6871 maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
6872 mask = ~maskc;
6873 }
6874 assign(result, binop(Iop_And64, binop(Iop_Xor64, get_gpr_dw0(r1), mkexpr(op2)
6875 ), mkU64(mask)));
6876 if (t_bit == 0) {
6877 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
6878 mkU64(maskc)), mkexpr(result)));
6879 }
6880 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6881
6882 return "rxsbg";
6883}
6884
6885static HChar *
6886s390_irgen_ROSBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
6887{
6888 UChar from;
6889 UChar to;
6890 UChar rot;
6891 UChar t_bit;
6892 ULong mask;
6893 ULong maskc;
6894 IRTemp result = newTemp(Ity_I64);
6895 IRTemp op2 = newTemp(Ity_I64);
6896
6897 from = i3 & 63;
6898 to = i4 & 63;
6899 rot = i5 & 63;
6900 t_bit = i3 & 128;
6901 assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
6902 get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
6903 mkU8(64 - rot))));
6904 if (from <= to) {
6905 mask = ~0ULL;
6906 mask = (mask >> from) & (mask << (63 - to));
6907 maskc = ~mask;
6908 } else {
6909 maskc = ~0ULL;
6910 maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
6911 mask = ~maskc;
6912 }
6913 assign(result, binop(Iop_And64, binop(Iop_Or64, get_gpr_dw0(r1), mkexpr(op2)
6914 ), mkU64(mask)));
6915 if (t_bit == 0) {
6916 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
6917 mkU64(maskc)), mkexpr(result)));
6918 }
6919 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6920
6921 return "rosbg";
6922}
6923
6924static HChar *
6925s390_irgen_RISBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
6926{
6927 UChar from;
6928 UChar to;
6929 UChar rot;
6930 UChar z_bit;
6931 ULong mask;
6932 ULong maskc;
6933 IRTemp op2 = newTemp(Ity_I64);
6934 IRTemp result = newTemp(Ity_I64);
6935
6936 from = i3 & 63;
6937 to = i4 & 63;
6938 rot = i5 & 63;
6939 z_bit = i4 & 128;
6940 assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
6941 get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
6942 mkU8(64 - rot))));
6943 if (from <= to) {
6944 mask = ~0ULL;
6945 mask = (mask >> from) & (mask << (63 - to));
6946 maskc = ~mask;
6947 } else {
6948 maskc = ~0ULL;
6949 maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
6950 mask = ~maskc;
6951 }
6952 if (z_bit == 0) {
6953 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
6954 mkU64(maskc)), binop(Iop_And64, mkexpr(op2), mkU64(mask))));
6955 } else {
6956 put_gpr_dw0(r1, binop(Iop_And64, mkexpr(op2), mkU64(mask)));
6957 }
6958 assign(result, get_gpr_dw0(r1));
6959 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
6960
6961 return "risbg";
6962}
6963
6964static HChar *
6965s390_irgen_SAR(UChar r1, UChar r2)
6966{
6967 put_ar_w0(r1, get_gpr_w1(r2));
sewardj7ee97522011-05-09 21:45:04 +00006968 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00006969 s390_disasm(ENC3(MNM, AR, GPR), "sar", r1, r2);
6970
6971 return "sar";
6972}
6973
6974static HChar *
6975s390_irgen_SLDA(UChar r1, IRTemp op2addr)
6976{
6977 IRTemp p1 = newTemp(Ity_I64);
6978 IRTemp p2 = newTemp(Ity_I64);
6979 IRTemp op = newTemp(Ity_I64);
6980 IRTemp result = newTemp(Ity_I64);
florian417b22d2012-07-13 13:41:41 +00006981 ULong sign_mask;
sewardj2019a972011-03-07 16:04:07 +00006982 IRTemp shift_amount = newTemp(Ity_I64);
6983
6984 assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
6985 assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
6986 assign(op, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1), mkU8(32)), mkexpr(p2)
6987 ));
6988 sign_mask = 1ULL << 63;
6989 assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
6990 assign(result, binop(Iop_Or64, binop(Iop_And64, binop(Iop_Shl64, mkexpr(op),
florian417b22d2012-07-13 13:41:41 +00006991 unop(Iop_64to8, mkexpr(shift_amount))), mkU64(~sign_mask)),
6992 binop(Iop_And64, mkexpr(op), mkU64(sign_mask))));
sewardj2019a972011-03-07 16:04:07 +00006993 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6994 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6995 s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_64, op, shift_amount);
6996
6997 return "slda";
6998}
6999
7000static HChar *
7001s390_irgen_SLDL(UChar r1, IRTemp op2addr)
7002{
7003 IRTemp p1 = newTemp(Ity_I64);
7004 IRTemp p2 = newTemp(Ity_I64);
7005 IRTemp result = newTemp(Ity_I64);
7006
7007 assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
7008 assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
7009 assign(result, binop(Iop_Shl64, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1),
7010 mkU8(32)), mkexpr(p2)), unop(Iop_64to8, binop(Iop_And64,
7011 mkexpr(op2addr), mkU64(63)))));
7012 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
7013 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
7014
7015 return "sldl";
7016}
7017
7018static HChar *
7019s390_irgen_SLA(UChar r1, IRTemp op2addr)
7020{
7021 IRTemp uop = newTemp(Ity_I32);
7022 IRTemp result = newTemp(Ity_I32);
7023 UInt sign_mask;
7024 IRTemp shift_amount = newTemp(Ity_I64);
7025 IRTemp op = newTemp(Ity_I32);
7026
7027 assign(op, get_gpr_w1(r1));
7028 assign(uop, get_gpr_w1(r1));
7029 sign_mask = 2147483648U;
7030 assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7031 assign(result, binop(Iop_Or32, binop(Iop_And32, binop(Iop_Shl32, mkexpr(uop),
7032 unop(Iop_64to8, mkexpr(shift_amount))), mkU32(~sign_mask)),
7033 binop(Iop_And32, mkexpr(uop), mkU32(sign_mask))));
7034 put_gpr_w1(r1, mkexpr(result));
7035 s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_32, op, shift_amount);
7036
7037 return "sla";
7038}
7039
7040static HChar *
7041s390_irgen_SLAK(UChar r1, UChar r3, IRTemp op2addr)
7042{
7043 IRTemp uop = newTemp(Ity_I32);
7044 IRTemp result = newTemp(Ity_I32);
7045 UInt sign_mask;
7046 IRTemp shift_amount = newTemp(Ity_I64);
7047 IRTemp op = newTemp(Ity_I32);
7048
7049 assign(op, get_gpr_w1(r3));
7050 assign(uop, get_gpr_w1(r3));
7051 sign_mask = 2147483648U;
7052 assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7053 assign(result, binop(Iop_Or32, binop(Iop_And32, binop(Iop_Shl32, mkexpr(uop),
7054 unop(Iop_64to8, mkexpr(shift_amount))), mkU32(~sign_mask)),
7055 binop(Iop_And32, mkexpr(uop), mkU32(sign_mask))));
7056 put_gpr_w1(r1, mkexpr(result));
7057 s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_32, op, shift_amount);
7058
7059 return "slak";
7060}
7061
7062static HChar *
7063s390_irgen_SLAG(UChar r1, UChar r3, IRTemp op2addr)
7064{
7065 IRTemp uop = newTemp(Ity_I64);
7066 IRTemp result = newTemp(Ity_I64);
7067 ULong sign_mask;
7068 IRTemp shift_amount = newTemp(Ity_I64);
7069 IRTemp op = newTemp(Ity_I64);
7070
7071 assign(op, get_gpr_dw0(r3));
7072 assign(uop, get_gpr_dw0(r3));
7073 sign_mask = 9223372036854775808ULL;
7074 assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7075 assign(result, binop(Iop_Or64, binop(Iop_And64, binop(Iop_Shl64, mkexpr(uop),
7076 unop(Iop_64to8, mkexpr(shift_amount))), mkU64(~sign_mask)),
7077 binop(Iop_And64, mkexpr(uop), mkU64(sign_mask))));
7078 put_gpr_dw0(r1, mkexpr(result));
7079 s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_64, op, shift_amount);
7080
7081 return "slag";
7082}
7083
7084static HChar *
7085s390_irgen_SLL(UChar r1, IRTemp op2addr)
7086{
7087 put_gpr_w1(r1, binop(Iop_Shl32, get_gpr_w1(r1), unop(Iop_64to8,
7088 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
7089
7090 return "sll";
7091}
7092
7093static HChar *
7094s390_irgen_SLLK(UChar r1, UChar r3, IRTemp op2addr)
7095{
7096 put_gpr_w1(r1, binop(Iop_Shl32, get_gpr_w1(r3), unop(Iop_64to8,
7097 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
7098
7099 return "sllk";
7100}
7101
7102static HChar *
7103s390_irgen_SLLG(UChar r1, UChar r3, IRTemp op2addr)
7104{
7105 put_gpr_dw0(r1, binop(Iop_Shl64, get_gpr_dw0(r3), unop(Iop_64to8,
7106 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
7107
7108 return "sllg";
7109}
7110
7111static HChar *
7112s390_irgen_SRDA(UChar r1, IRTemp op2addr)
7113{
7114 IRTemp p1 = newTemp(Ity_I64);
7115 IRTemp p2 = newTemp(Ity_I64);
7116 IRTemp result = newTemp(Ity_I64);
7117
7118 assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
7119 assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
7120 assign(result, binop(Iop_Sar64, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1),
7121 mkU8(32)), mkexpr(p2)), unop(Iop_64to8, binop(Iop_And64,
7122 mkexpr(op2addr), mkU64(63)))));
7123 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
7124 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
7125 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7126
7127 return "srda";
7128}
7129
7130static HChar *
7131s390_irgen_SRDL(UChar r1, IRTemp op2addr)
7132{
7133 IRTemp p1 = newTemp(Ity_I64);
7134 IRTemp p2 = newTemp(Ity_I64);
7135 IRTemp result = newTemp(Ity_I64);
7136
7137 assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
7138 assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
7139 assign(result, binop(Iop_Shr64, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1),
7140 mkU8(32)), mkexpr(p2)), unop(Iop_64to8, binop(Iop_And64,
7141 mkexpr(op2addr), mkU64(63)))));
7142 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
7143 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
7144
7145 return "srdl";
7146}
7147
7148static HChar *
7149s390_irgen_SRA(UChar r1, IRTemp op2addr)
7150{
7151 IRTemp result = newTemp(Ity_I32);
7152 IRTemp op = newTemp(Ity_I32);
7153
7154 assign(op, get_gpr_w1(r1));
7155 assign(result, binop(Iop_Sar32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7156 mkexpr(op2addr), mkU64(63)))));
7157 put_gpr_w1(r1, mkexpr(result));
7158 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7159
7160 return "sra";
7161}
7162
7163static HChar *
7164s390_irgen_SRAK(UChar r1, UChar r3, IRTemp op2addr)
7165{
7166 IRTemp result = newTemp(Ity_I32);
7167 IRTemp op = newTemp(Ity_I32);
7168
7169 assign(op, get_gpr_w1(r3));
7170 assign(result, binop(Iop_Sar32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7171 mkexpr(op2addr), mkU64(63)))));
7172 put_gpr_w1(r1, mkexpr(result));
7173 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7174
7175 return "srak";
7176}
7177
7178static HChar *
7179s390_irgen_SRAG(UChar r1, UChar r3, IRTemp op2addr)
7180{
7181 IRTemp result = newTemp(Ity_I64);
7182 IRTemp op = newTemp(Ity_I64);
7183
7184 assign(op, get_gpr_dw0(r3));
7185 assign(result, binop(Iop_Sar64, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7186 mkexpr(op2addr), mkU64(63)))));
7187 put_gpr_dw0(r1, mkexpr(result));
7188 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7189
7190 return "srag";
7191}
7192
7193static HChar *
7194s390_irgen_SRL(UChar r1, IRTemp op2addr)
7195{
7196 IRTemp op = newTemp(Ity_I32);
7197
7198 assign(op, get_gpr_w1(r1));
7199 put_gpr_w1(r1, binop(Iop_Shr32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7200 mkexpr(op2addr), mkU64(63)))));
7201
7202 return "srl";
7203}
7204
7205static HChar *
7206s390_irgen_SRLK(UChar r1, UChar r3, IRTemp op2addr)
7207{
7208 IRTemp op = newTemp(Ity_I32);
7209
7210 assign(op, get_gpr_w1(r3));
7211 put_gpr_w1(r1, binop(Iop_Shr32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7212 mkexpr(op2addr), mkU64(63)))));
7213
7214 return "srlk";
7215}
7216
7217static HChar *
7218s390_irgen_SRLG(UChar r1, UChar r3, IRTemp op2addr)
7219{
7220 IRTemp op = newTemp(Ity_I64);
7221
7222 assign(op, get_gpr_dw0(r3));
7223 put_gpr_dw0(r1, binop(Iop_Shr64, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7224 mkexpr(op2addr), mkU64(63)))));
7225
7226 return "srlg";
7227}
7228
7229static HChar *
7230s390_irgen_ST(UChar r1, IRTemp op2addr)
7231{
7232 store(mkexpr(op2addr), get_gpr_w1(r1));
7233
7234 return "st";
7235}
7236
7237static HChar *
7238s390_irgen_STY(UChar r1, IRTemp op2addr)
7239{
7240 store(mkexpr(op2addr), get_gpr_w1(r1));
7241
7242 return "sty";
7243}
7244
7245static HChar *
7246s390_irgen_STG(UChar r1, IRTemp op2addr)
7247{
7248 store(mkexpr(op2addr), get_gpr_dw0(r1));
7249
7250 return "stg";
7251}
7252
7253static HChar *
7254s390_irgen_STRL(UChar r1, UInt i2)
7255{
7256 store(mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)),
7257 get_gpr_w1(r1));
7258
7259 return "strl";
7260}
7261
7262static HChar *
7263s390_irgen_STGRL(UChar r1, UInt i2)
7264{
7265 store(mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)),
7266 get_gpr_dw0(r1));
7267
7268 return "stgrl";
7269}
7270
7271static HChar *
7272s390_irgen_STC(UChar r1, IRTemp op2addr)
7273{
7274 store(mkexpr(op2addr), get_gpr_b7(r1));
7275
7276 return "stc";
7277}
7278
7279static HChar *
7280s390_irgen_STCY(UChar r1, IRTemp op2addr)
7281{
7282 store(mkexpr(op2addr), get_gpr_b7(r1));
7283
7284 return "stcy";
7285}
7286
7287static HChar *
7288s390_irgen_STCH(UChar r1, IRTemp op2addr)
7289{
7290 store(mkexpr(op2addr), get_gpr_b3(r1));
7291
7292 return "stch";
7293}
7294
7295static HChar *
7296s390_irgen_STCM(UChar r1, UChar r3, IRTemp op2addr)
7297{
7298 UChar mask;
7299 UChar n;
7300
7301 mask = (UChar)r3;
7302 n = 0;
7303 if ((mask & 8) != 0) {
7304 store(mkexpr(op2addr), get_gpr_b4(r1));
7305 n = n + 1;
7306 }
7307 if ((mask & 4) != 0) {
7308 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b5(r1));
7309 n = n + 1;
7310 }
7311 if ((mask & 2) != 0) {
7312 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b6(r1));
7313 n = n + 1;
7314 }
7315 if ((mask & 1) != 0) {
7316 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b7(r1));
7317 }
7318
7319 return "stcm";
7320}
7321
7322static HChar *
7323s390_irgen_STCMY(UChar r1, UChar r3, IRTemp op2addr)
7324{
7325 UChar mask;
7326 UChar n;
7327
7328 mask = (UChar)r3;
7329 n = 0;
7330 if ((mask & 8) != 0) {
7331 store(mkexpr(op2addr), get_gpr_b4(r1));
7332 n = n + 1;
7333 }
7334 if ((mask & 4) != 0) {
7335 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b5(r1));
7336 n = n + 1;
7337 }
7338 if ((mask & 2) != 0) {
7339 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b6(r1));
7340 n = n + 1;
7341 }
7342 if ((mask & 1) != 0) {
7343 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b7(r1));
7344 }
7345
7346 return "stcmy";
7347}
7348
7349static HChar *
7350s390_irgen_STCMH(UChar r1, UChar r3, IRTemp op2addr)
7351{
7352 UChar mask;
7353 UChar n;
7354
7355 mask = (UChar)r3;
7356 n = 0;
7357 if ((mask & 8) != 0) {
7358 store(mkexpr(op2addr), get_gpr_b0(r1));
7359 n = n + 1;
7360 }
7361 if ((mask & 4) != 0) {
7362 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b1(r1));
7363 n = n + 1;
7364 }
7365 if ((mask & 2) != 0) {
7366 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b2(r1));
7367 n = n + 1;
7368 }
7369 if ((mask & 1) != 0) {
7370 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b3(r1));
7371 }
7372
7373 return "stcmh";
7374}
7375
7376static HChar *
7377s390_irgen_STH(UChar r1, IRTemp op2addr)
7378{
7379 store(mkexpr(op2addr), get_gpr_hw3(r1));
7380
7381 return "sth";
7382}
7383
7384static HChar *
7385s390_irgen_STHY(UChar r1, IRTemp op2addr)
7386{
7387 store(mkexpr(op2addr), get_gpr_hw3(r1));
7388
7389 return "sthy";
7390}
7391
7392static HChar *
7393s390_irgen_STHRL(UChar r1, UInt i2)
7394{
7395 store(mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)),
7396 get_gpr_hw3(r1));
7397
7398 return "sthrl";
7399}
7400
7401static HChar *
7402s390_irgen_STHH(UChar r1, IRTemp op2addr)
7403{
7404 store(mkexpr(op2addr), get_gpr_hw1(r1));
7405
7406 return "sthh";
7407}
7408
7409static HChar *
7410s390_irgen_STFH(UChar r1, IRTemp op2addr)
7411{
7412 store(mkexpr(op2addr), get_gpr_w0(r1));
7413
7414 return "stfh";
7415}
7416
7417static HChar *
sewardjd7bde722011-04-05 13:19:33 +00007418s390_irgen_STOC(UChar r1, IRTemp op2addr)
7419{
7420 /* condition is checked in format handler */
7421 store(mkexpr(op2addr), get_gpr_w1(r1));
7422
7423 return "stoc";
7424}
7425
7426static HChar *
7427s390_irgen_STOCG(UChar r1, IRTemp op2addr)
7428{
7429 /* condition is checked in format handler */
7430 store(mkexpr(op2addr), get_gpr_dw0(r1));
7431
7432 return "stocg";
7433}
7434
7435static HChar *
sewardj2019a972011-03-07 16:04:07 +00007436s390_irgen_STPQ(UChar r1, IRTemp op2addr)
7437{
7438 store(mkexpr(op2addr), get_gpr_dw0(r1));
7439 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(8)), get_gpr_dw0(r1 + 1));
7440
7441 return "stpq";
7442}
7443
7444static HChar *
7445s390_irgen_STRVH(UChar r1, IRTemp op2addr)
7446{
7447 store(mkexpr(op2addr), get_gpr_b7(r1));
7448 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(1)), get_gpr_b6(r1));
7449
7450 return "strvh";
7451}
7452
7453static HChar *
7454s390_irgen_STRV(UChar r1, IRTemp op2addr)
7455{
7456 store(mkexpr(op2addr), get_gpr_b7(r1));
7457 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(1)), get_gpr_b6(r1));
7458 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(2)), get_gpr_b5(r1));
7459 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(3)), get_gpr_b4(r1));
7460
7461 return "strv";
7462}
7463
7464static HChar *
7465s390_irgen_STRVG(UChar r1, IRTemp op2addr)
7466{
7467 store(mkexpr(op2addr), get_gpr_b7(r1));
7468 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(1)), get_gpr_b6(r1));
7469 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(2)), get_gpr_b5(r1));
7470 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(3)), get_gpr_b4(r1));
7471 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(4)), get_gpr_b3(r1));
7472 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(5)), get_gpr_b2(r1));
7473 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(6)), get_gpr_b1(r1));
7474 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(7)), get_gpr_b0(r1));
7475
7476 return "strvg";
7477}
7478
7479static HChar *
7480s390_irgen_SR(UChar r1, UChar r2)
7481{
7482 IRTemp op1 = newTemp(Ity_I32);
7483 IRTemp op2 = newTemp(Ity_I32);
7484 IRTemp result = newTemp(Ity_I32);
7485
7486 assign(op1, get_gpr_w1(r1));
7487 assign(op2, get_gpr_w1(r2));
7488 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7489 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
7490 put_gpr_w1(r1, mkexpr(result));
7491
7492 return "sr";
7493}
7494
7495static HChar *
7496s390_irgen_SGR(UChar r1, UChar r2)
7497{
7498 IRTemp op1 = newTemp(Ity_I64);
7499 IRTemp op2 = newTemp(Ity_I64);
7500 IRTemp result = newTemp(Ity_I64);
7501
7502 assign(op1, get_gpr_dw0(r1));
7503 assign(op2, get_gpr_dw0(r2));
7504 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7505 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
7506 put_gpr_dw0(r1, mkexpr(result));
7507
7508 return "sgr";
7509}
7510
7511static HChar *
7512s390_irgen_SGFR(UChar r1, UChar r2)
7513{
7514 IRTemp op1 = newTemp(Ity_I64);
7515 IRTemp op2 = newTemp(Ity_I64);
7516 IRTemp result = newTemp(Ity_I64);
7517
7518 assign(op1, get_gpr_dw0(r1));
7519 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
7520 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7521 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
7522 put_gpr_dw0(r1, mkexpr(result));
7523
7524 return "sgfr";
7525}
7526
7527static HChar *
7528s390_irgen_SRK(UChar r3, UChar r1, UChar r2)
7529{
7530 IRTemp op2 = newTemp(Ity_I32);
7531 IRTemp op3 = newTemp(Ity_I32);
7532 IRTemp result = newTemp(Ity_I32);
7533
7534 assign(op2, get_gpr_w1(r2));
7535 assign(op3, get_gpr_w1(r3));
7536 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
7537 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op2, op3);
7538 put_gpr_w1(r1, mkexpr(result));
7539
7540 return "srk";
7541}
7542
7543static HChar *
7544s390_irgen_SGRK(UChar r3, UChar r1, UChar r2)
7545{
7546 IRTemp op2 = newTemp(Ity_I64);
7547 IRTemp op3 = newTemp(Ity_I64);
7548 IRTemp result = newTemp(Ity_I64);
7549
7550 assign(op2, get_gpr_dw0(r2));
7551 assign(op3, get_gpr_dw0(r3));
7552 assign(result, binop(Iop_Sub64, mkexpr(op2), mkexpr(op3)));
7553 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op2, op3);
7554 put_gpr_dw0(r1, mkexpr(result));
7555
7556 return "sgrk";
7557}
7558
7559static HChar *
7560s390_irgen_S(UChar r1, IRTemp op2addr)
7561{
7562 IRTemp op1 = newTemp(Ity_I32);
7563 IRTemp op2 = newTemp(Ity_I32);
7564 IRTemp result = newTemp(Ity_I32);
7565
7566 assign(op1, get_gpr_w1(r1));
7567 assign(op2, load(Ity_I32, mkexpr(op2addr)));
7568 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7569 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
7570 put_gpr_w1(r1, mkexpr(result));
7571
7572 return "s";
7573}
7574
7575static HChar *
7576s390_irgen_SY(UChar r1, IRTemp op2addr)
7577{
7578 IRTemp op1 = newTemp(Ity_I32);
7579 IRTemp op2 = newTemp(Ity_I32);
7580 IRTemp result = newTemp(Ity_I32);
7581
7582 assign(op1, get_gpr_w1(r1));
7583 assign(op2, load(Ity_I32, mkexpr(op2addr)));
7584 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7585 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
7586 put_gpr_w1(r1, mkexpr(result));
7587
7588 return "sy";
7589}
7590
7591static HChar *
7592s390_irgen_SG(UChar r1, IRTemp op2addr)
7593{
7594 IRTemp op1 = newTemp(Ity_I64);
7595 IRTemp op2 = newTemp(Ity_I64);
7596 IRTemp result = newTemp(Ity_I64);
7597
7598 assign(op1, get_gpr_dw0(r1));
7599 assign(op2, load(Ity_I64, mkexpr(op2addr)));
7600 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7601 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
7602 put_gpr_dw0(r1, mkexpr(result));
7603
7604 return "sg";
7605}
7606
7607static HChar *
7608s390_irgen_SGF(UChar r1, IRTemp op2addr)
7609{
7610 IRTemp op1 = newTemp(Ity_I64);
7611 IRTemp op2 = newTemp(Ity_I64);
7612 IRTemp result = newTemp(Ity_I64);
7613
7614 assign(op1, get_gpr_dw0(r1));
7615 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
7616 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7617 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
7618 put_gpr_dw0(r1, mkexpr(result));
7619
7620 return "sgf";
7621}
7622
7623static HChar *
7624s390_irgen_SH(UChar r1, IRTemp op2addr)
7625{
7626 IRTemp op1 = newTemp(Ity_I32);
7627 IRTemp op2 = newTemp(Ity_I32);
7628 IRTemp result = newTemp(Ity_I32);
7629
7630 assign(op1, get_gpr_w1(r1));
7631 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
7632 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7633 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
7634 put_gpr_w1(r1, mkexpr(result));
7635
7636 return "sh";
7637}
7638
7639static HChar *
7640s390_irgen_SHY(UChar r1, IRTemp op2addr)
7641{
7642 IRTemp op1 = newTemp(Ity_I32);
7643 IRTemp op2 = newTemp(Ity_I32);
7644 IRTemp result = newTemp(Ity_I32);
7645
7646 assign(op1, get_gpr_w1(r1));
7647 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
7648 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7649 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
7650 put_gpr_w1(r1, mkexpr(result));
7651
7652 return "shy";
7653}
7654
7655static HChar *
7656s390_irgen_SHHHR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
7657{
7658 IRTemp op2 = newTemp(Ity_I32);
7659 IRTemp op3 = newTemp(Ity_I32);
7660 IRTemp result = newTemp(Ity_I32);
7661
7662 assign(op2, get_gpr_w0(r1));
7663 assign(op3, get_gpr_w0(r2));
7664 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
7665 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op2, op3);
7666 put_gpr_w0(r1, mkexpr(result));
7667
7668 return "shhhr";
7669}
7670
7671static HChar *
7672s390_irgen_SHHLR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
7673{
7674 IRTemp op2 = newTemp(Ity_I32);
7675 IRTemp op3 = newTemp(Ity_I32);
7676 IRTemp result = newTemp(Ity_I32);
7677
7678 assign(op2, get_gpr_w0(r1));
7679 assign(op3, get_gpr_w1(r2));
7680 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
7681 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op2, op3);
7682 put_gpr_w0(r1, mkexpr(result));
7683
7684 return "shhlr";
7685}
7686
7687static HChar *
7688s390_irgen_SLR(UChar r1, UChar r2)
7689{
7690 IRTemp op1 = newTemp(Ity_I32);
7691 IRTemp op2 = newTemp(Ity_I32);
7692 IRTemp result = newTemp(Ity_I32);
7693
7694 assign(op1, get_gpr_w1(r1));
7695 assign(op2, get_gpr_w1(r2));
7696 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7697 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, op2);
7698 put_gpr_w1(r1, mkexpr(result));
7699
7700 return "slr";
7701}
7702
7703static HChar *
7704s390_irgen_SLGR(UChar r1, UChar r2)
7705{
7706 IRTemp op1 = newTemp(Ity_I64);
7707 IRTemp op2 = newTemp(Ity_I64);
7708 IRTemp result = newTemp(Ity_I64);
7709
7710 assign(op1, get_gpr_dw0(r1));
7711 assign(op2, get_gpr_dw0(r2));
7712 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7713 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
7714 put_gpr_dw0(r1, mkexpr(result));
7715
7716 return "slgr";
7717}
7718
7719static HChar *
7720s390_irgen_SLGFR(UChar r1, UChar r2)
7721{
7722 IRTemp op1 = newTemp(Ity_I64);
7723 IRTemp op2 = newTemp(Ity_I64);
7724 IRTemp result = newTemp(Ity_I64);
7725
7726 assign(op1, get_gpr_dw0(r1));
7727 assign(op2, unop(Iop_32Uto64, get_gpr_w1(r2)));
7728 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7729 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
7730 put_gpr_dw0(r1, mkexpr(result));
7731
7732 return "slgfr";
7733}
7734
7735static HChar *
7736s390_irgen_SLRK(UChar r3, UChar r1, UChar r2)
7737{
7738 IRTemp op2 = newTemp(Ity_I32);
7739 IRTemp op3 = newTemp(Ity_I32);
7740 IRTemp result = newTemp(Ity_I32);
7741
7742 assign(op2, get_gpr_w1(r2));
7743 assign(op3, get_gpr_w1(r3));
7744 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
7745 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op2, op3);
7746 put_gpr_w1(r1, mkexpr(result));
7747
7748 return "slrk";
7749}
7750
7751static HChar *
7752s390_irgen_SLGRK(UChar r3, UChar r1, UChar r2)
7753{
7754 IRTemp op2 = newTemp(Ity_I64);
7755 IRTemp op3 = newTemp(Ity_I64);
7756 IRTemp result = newTemp(Ity_I64);
7757
7758 assign(op2, get_gpr_dw0(r2));
7759 assign(op3, get_gpr_dw0(r3));
7760 assign(result, binop(Iop_Sub64, mkexpr(op2), mkexpr(op3)));
7761 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op2, op3);
7762 put_gpr_dw0(r1, mkexpr(result));
7763
7764 return "slgrk";
7765}
7766
7767static HChar *
7768s390_irgen_SL(UChar r1, IRTemp op2addr)
7769{
7770 IRTemp op1 = newTemp(Ity_I32);
7771 IRTemp op2 = newTemp(Ity_I32);
7772 IRTemp result = newTemp(Ity_I32);
7773
7774 assign(op1, get_gpr_w1(r1));
7775 assign(op2, load(Ity_I32, mkexpr(op2addr)));
7776 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7777 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, op2);
7778 put_gpr_w1(r1, mkexpr(result));
7779
7780 return "sl";
7781}
7782
7783static HChar *
7784s390_irgen_SLY(UChar r1, IRTemp op2addr)
7785{
7786 IRTemp op1 = newTemp(Ity_I32);
7787 IRTemp op2 = newTemp(Ity_I32);
7788 IRTemp result = newTemp(Ity_I32);
7789
7790 assign(op1, get_gpr_w1(r1));
7791 assign(op2, load(Ity_I32, mkexpr(op2addr)));
7792 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7793 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, op2);
7794 put_gpr_w1(r1, mkexpr(result));
7795
7796 return "sly";
7797}
7798
7799static HChar *
7800s390_irgen_SLG(UChar r1, IRTemp op2addr)
7801{
7802 IRTemp op1 = newTemp(Ity_I64);
7803 IRTemp op2 = newTemp(Ity_I64);
7804 IRTemp result = newTemp(Ity_I64);
7805
7806 assign(op1, get_gpr_dw0(r1));
7807 assign(op2, load(Ity_I64, mkexpr(op2addr)));
7808 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7809 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
7810 put_gpr_dw0(r1, mkexpr(result));
7811
7812 return "slg";
7813}
7814
7815static HChar *
7816s390_irgen_SLGF(UChar r1, IRTemp op2addr)
7817{
7818 IRTemp op1 = newTemp(Ity_I64);
7819 IRTemp op2 = newTemp(Ity_I64);
7820 IRTemp result = newTemp(Ity_I64);
7821
7822 assign(op1, get_gpr_dw0(r1));
7823 assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
7824 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7825 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
7826 put_gpr_dw0(r1, mkexpr(result));
7827
7828 return "slgf";
7829}
7830
7831static HChar *
7832s390_irgen_SLFI(UChar r1, UInt i2)
7833{
7834 IRTemp op1 = newTemp(Ity_I32);
7835 UInt op2;
7836 IRTemp result = newTemp(Ity_I32);
7837
7838 assign(op1, get_gpr_w1(r1));
7839 op2 = i2;
7840 assign(result, binop(Iop_Sub32, mkexpr(op1), mkU32(op2)));
7841 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, mktemp(Ity_I32,
7842 mkU32(op2)));
7843 put_gpr_w1(r1, mkexpr(result));
7844
7845 return "slfi";
7846}
7847
7848static HChar *
7849s390_irgen_SLGFI(UChar r1, UInt i2)
7850{
7851 IRTemp op1 = newTemp(Ity_I64);
7852 ULong op2;
7853 IRTemp result = newTemp(Ity_I64);
7854
7855 assign(op1, get_gpr_dw0(r1));
7856 op2 = (ULong)i2;
7857 assign(result, binop(Iop_Sub64, mkexpr(op1), mkU64(op2)));
7858 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, mktemp(Ity_I64,
7859 mkU64(op2)));
7860 put_gpr_dw0(r1, mkexpr(result));
7861
7862 return "slgfi";
7863}
7864
7865static HChar *
7866s390_irgen_SLHHHR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
7867{
7868 IRTemp op2 = newTemp(Ity_I32);
7869 IRTemp op3 = newTemp(Ity_I32);
7870 IRTemp result = newTemp(Ity_I32);
7871
7872 assign(op2, get_gpr_w0(r1));
7873 assign(op3, get_gpr_w0(r2));
7874 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
7875 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op2, op3);
7876 put_gpr_w0(r1, mkexpr(result));
7877
7878 return "slhhhr";
7879}
7880
7881static HChar *
7882s390_irgen_SLHHLR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
7883{
7884 IRTemp op2 = newTemp(Ity_I32);
7885 IRTemp op3 = newTemp(Ity_I32);
7886 IRTemp result = newTemp(Ity_I32);
7887
7888 assign(op2, get_gpr_w0(r1));
7889 assign(op3, get_gpr_w1(r2));
7890 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
7891 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op2, op3);
7892 put_gpr_w0(r1, mkexpr(result));
7893
7894 return "slhhlr";
7895}
7896
7897static HChar *
7898s390_irgen_SLBR(UChar r1, UChar r2)
7899{
7900 IRTemp op1 = newTemp(Ity_I32);
7901 IRTemp op2 = newTemp(Ity_I32);
7902 IRTemp result = newTemp(Ity_I32);
7903 IRTemp borrow_in = newTemp(Ity_I32);
7904
7905 assign(op1, get_gpr_w1(r1));
7906 assign(op2, get_gpr_w1(r2));
7907 assign(borrow_in, binop(Iop_Sub32, mkU32(1), binop(Iop_Shr32,
7908 s390_call_calculate_cc(), mkU8(1))));
7909 assign(result, binop(Iop_Sub32, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)),
7910 mkexpr(borrow_in)));
7911 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_32, op1, op2, borrow_in);
7912 put_gpr_w1(r1, mkexpr(result));
7913
7914 return "slbr";
7915}
7916
7917static HChar *
7918s390_irgen_SLBGR(UChar r1, UChar r2)
7919{
7920 IRTemp op1 = newTemp(Ity_I64);
7921 IRTemp op2 = newTemp(Ity_I64);
7922 IRTemp result = newTemp(Ity_I64);
7923 IRTemp borrow_in = newTemp(Ity_I64);
7924
7925 assign(op1, get_gpr_dw0(r1));
7926 assign(op2, get_gpr_dw0(r2));
7927 assign(borrow_in, unop(Iop_32Uto64, binop(Iop_Sub32, mkU32(1),
7928 binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)))));
7929 assign(result, binop(Iop_Sub64, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)),
7930 mkexpr(borrow_in)));
7931 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_64, op1, op2, borrow_in);
7932 put_gpr_dw0(r1, mkexpr(result));
7933
7934 return "slbgr";
7935}
7936
7937static HChar *
7938s390_irgen_SLB(UChar r1, IRTemp op2addr)
7939{
7940 IRTemp op1 = newTemp(Ity_I32);
7941 IRTemp op2 = newTemp(Ity_I32);
7942 IRTemp result = newTemp(Ity_I32);
7943 IRTemp borrow_in = newTemp(Ity_I32);
7944
7945 assign(op1, get_gpr_w1(r1));
7946 assign(op2, load(Ity_I32, mkexpr(op2addr)));
7947 assign(borrow_in, binop(Iop_Sub32, mkU32(1), binop(Iop_Shr32,
7948 s390_call_calculate_cc(), mkU8(1))));
7949 assign(result, binop(Iop_Sub32, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)),
7950 mkexpr(borrow_in)));
7951 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_32, op1, op2, borrow_in);
7952 put_gpr_w1(r1, mkexpr(result));
7953
7954 return "slb";
7955}
7956
7957static HChar *
7958s390_irgen_SLBG(UChar r1, IRTemp op2addr)
7959{
7960 IRTemp op1 = newTemp(Ity_I64);
7961 IRTemp op2 = newTemp(Ity_I64);
7962 IRTemp result = newTemp(Ity_I64);
7963 IRTemp borrow_in = newTemp(Ity_I64);
7964
7965 assign(op1, get_gpr_dw0(r1));
7966 assign(op2, load(Ity_I64, mkexpr(op2addr)));
7967 assign(borrow_in, unop(Iop_32Uto64, binop(Iop_Sub32, mkU32(1),
7968 binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)))));
7969 assign(result, binop(Iop_Sub64, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)),
7970 mkexpr(borrow_in)));
7971 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_64, op1, op2, borrow_in);
7972 put_gpr_dw0(r1, mkexpr(result));
7973
7974 return "slbg";
7975}
7976
7977static HChar *
7978s390_irgen_SVC(UChar i)
7979{
7980 IRTemp sysno = newTemp(Ity_I64);
7981
7982 if (i != 0) {
7983 assign(sysno, mkU64(i));
7984 } else {
7985 assign(sysno, unop(Iop_32Uto64, get_gpr_w1(1)));
7986 }
7987 system_call(mkexpr(sysno));
7988
7989 return "svc";
7990}
7991
7992static HChar *
sewardj2019a972011-03-07 16:04:07 +00007993s390_irgen_TM(UChar i2, IRTemp op1addr)
7994{
7995 UChar mask;
7996 IRTemp value = newTemp(Ity_I8);
7997
7998 mask = i2;
7999 assign(value, load(Ity_I8, mkexpr(op1addr)));
8000 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_8, value, mktemp(Ity_I8,
8001 mkU8(mask)));
8002
8003 return "tm";
8004}
8005
8006static HChar *
8007s390_irgen_TMY(UChar i2, IRTemp op1addr)
8008{
8009 UChar mask;
8010 IRTemp value = newTemp(Ity_I8);
8011
8012 mask = i2;
8013 assign(value, load(Ity_I8, mkexpr(op1addr)));
8014 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_8, value, mktemp(Ity_I8,
8015 mkU8(mask)));
8016
8017 return "tmy";
8018}
8019
8020static HChar *
8021s390_irgen_TMHH(UChar r1, UShort i2)
8022{
8023 UShort mask;
8024 IRTemp value = newTemp(Ity_I16);
8025
8026 mask = i2;
8027 assign(value, get_gpr_hw0(r1));
8028 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
8029 mkU16(mask)));
8030
8031 return "tmhh";
8032}
8033
8034static HChar *
8035s390_irgen_TMHL(UChar r1, UShort i2)
8036{
8037 UShort mask;
8038 IRTemp value = newTemp(Ity_I16);
8039
8040 mask = i2;
8041 assign(value, get_gpr_hw1(r1));
8042 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
8043 mkU16(mask)));
8044
8045 return "tmhl";
8046}
8047
8048static HChar *
8049s390_irgen_TMLH(UChar r1, UShort i2)
8050{
8051 UShort mask;
8052 IRTemp value = newTemp(Ity_I16);
8053
8054 mask = i2;
8055 assign(value, get_gpr_hw2(r1));
8056 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
8057 mkU16(mask)));
8058
8059 return "tmlh";
8060}
8061
8062static HChar *
8063s390_irgen_TMLL(UChar r1, UShort i2)
8064{
8065 UShort mask;
8066 IRTemp value = newTemp(Ity_I16);
8067
8068 mask = i2;
8069 assign(value, get_gpr_hw3(r1));
8070 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
8071 mkU16(mask)));
8072
8073 return "tmll";
8074}
8075
8076static HChar *
8077s390_irgen_EFPC(UChar r1)
8078{
8079 put_gpr_w1(r1, get_fpc_w0());
8080
8081 return "efpc";
8082}
8083
8084static HChar *
8085s390_irgen_LER(UChar r1, UChar r2)
8086{
8087 put_fpr_w0(r1, get_fpr_w0(r2));
8088
8089 return "ler";
8090}
8091
8092static HChar *
8093s390_irgen_LDR(UChar r1, UChar r2)
8094{
8095 put_fpr_dw0(r1, get_fpr_dw0(r2));
8096
8097 return "ldr";
8098}
8099
8100static HChar *
8101s390_irgen_LXR(UChar r1, UChar r2)
8102{
8103 put_fpr_dw0(r1, get_fpr_dw0(r2));
8104 put_fpr_dw0(r1 + 2, get_fpr_dw0(r2 + 2));
8105
8106 return "lxr";
8107}
8108
8109static HChar *
8110s390_irgen_LE(UChar r1, IRTemp op2addr)
8111{
8112 put_fpr_w0(r1, load(Ity_F32, mkexpr(op2addr)));
8113
8114 return "le";
8115}
8116
8117static HChar *
8118s390_irgen_LD(UChar r1, IRTemp op2addr)
8119{
8120 put_fpr_dw0(r1, load(Ity_F64, mkexpr(op2addr)));
8121
8122 return "ld";
8123}
8124
8125static HChar *
8126s390_irgen_LEY(UChar r1, IRTemp op2addr)
8127{
8128 put_fpr_w0(r1, load(Ity_F32, mkexpr(op2addr)));
8129
8130 return "ley";
8131}
8132
8133static HChar *
8134s390_irgen_LDY(UChar r1, IRTemp op2addr)
8135{
8136 put_fpr_dw0(r1, load(Ity_F64, mkexpr(op2addr)));
8137
8138 return "ldy";
8139}
8140
8141static HChar *
8142s390_irgen_LFPC(IRTemp op2addr)
8143{
8144 put_fpc_w0(load(Ity_I32, mkexpr(op2addr)));
8145
8146 return "lfpc";
8147}
8148
8149static HChar *
8150s390_irgen_LZER(UChar r1)
8151{
8152 put_fpr_w0(r1, mkF32i(0x0));
8153
8154 return "lzer";
8155}
8156
8157static HChar *
8158s390_irgen_LZDR(UChar r1)
8159{
8160 put_fpr_dw0(r1, mkF64i(0x0));
8161
8162 return "lzdr";
8163}
8164
8165static HChar *
8166s390_irgen_LZXR(UChar r1)
8167{
8168 put_fpr_dw0(r1, mkF64i(0x0));
8169 put_fpr_dw0(r1 + 2, mkF64i(0x0));
8170
8171 return "lzxr";
8172}
8173
8174static HChar *
8175s390_irgen_SRNM(IRTemp op2addr)
8176{
8177 UInt mask;
8178
8179 mask = 3;
8180 put_fpc_w0(binop(Iop_Or32, binop(Iop_And32, get_fpc_w0(), mkU32(~mask)),
8181 binop(Iop_And32, unop(Iop_64to32, mkexpr(op2addr)), mkU32(mask)))
8182 );
8183
8184 return "srnm";
8185}
8186
8187static HChar *
8188s390_irgen_SFPC(UChar r1)
8189{
8190 put_fpc_w0(get_gpr_w1(r1));
8191
8192 return "sfpc";
8193}
8194
8195static HChar *
8196s390_irgen_STE(UChar r1, IRTemp op2addr)
8197{
8198 store(mkexpr(op2addr), get_fpr_w0(r1));
8199
8200 return "ste";
8201}
8202
8203static HChar *
8204s390_irgen_STD(UChar r1, IRTemp op2addr)
8205{
8206 store(mkexpr(op2addr), get_fpr_dw0(r1));
8207
8208 return "std";
8209}
8210
8211static HChar *
8212s390_irgen_STEY(UChar r1, IRTemp op2addr)
8213{
8214 store(mkexpr(op2addr), get_fpr_w0(r1));
8215
8216 return "stey";
8217}
8218
8219static HChar *
8220s390_irgen_STDY(UChar r1, IRTemp op2addr)
8221{
8222 store(mkexpr(op2addr), get_fpr_dw0(r1));
8223
8224 return "stdy";
8225}
8226
8227static HChar *
8228s390_irgen_STFPC(IRTemp op2addr)
8229{
8230 store(mkexpr(op2addr), get_fpc_w0());
8231
8232 return "stfpc";
8233}
8234
8235static HChar *
8236s390_irgen_AEBR(UChar r1, UChar r2)
8237{
8238 IRTemp op1 = newTemp(Ity_F32);
8239 IRTemp op2 = newTemp(Ity_F32);
8240 IRTemp result = newTemp(Ity_F32);
floriandb4fcaa2012-09-05 19:54:08 +00008241 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008242
8243 assign(op1, get_fpr_w0(r1));
8244 assign(op2, get_fpr_w0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008245 assign(result, triop(Iop_AddF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008246 mkexpr(op2)));
8247 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
8248 put_fpr_w0(r1, mkexpr(result));
8249
8250 return "aebr";
8251}
8252
8253static HChar *
8254s390_irgen_ADBR(UChar r1, UChar r2)
8255{
8256 IRTemp op1 = newTemp(Ity_F64);
8257 IRTemp op2 = newTemp(Ity_F64);
8258 IRTemp result = newTemp(Ity_F64);
floriandb4fcaa2012-09-05 19:54:08 +00008259 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008260
8261 assign(op1, get_fpr_dw0(r1));
8262 assign(op2, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008263 assign(result, triop(Iop_AddF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008264 mkexpr(op2)));
8265 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
8266 put_fpr_dw0(r1, mkexpr(result));
8267
8268 return "adbr";
8269}
8270
8271static HChar *
8272s390_irgen_AEB(UChar r1, IRTemp op2addr)
8273{
8274 IRTemp op1 = newTemp(Ity_F32);
8275 IRTemp op2 = newTemp(Ity_F32);
8276 IRTemp result = newTemp(Ity_F32);
floriandb4fcaa2012-09-05 19:54:08 +00008277 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008278
8279 assign(op1, get_fpr_w0(r1));
8280 assign(op2, load(Ity_F32, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00008281 assign(result, triop(Iop_AddF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008282 mkexpr(op2)));
8283 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
8284 put_fpr_w0(r1, mkexpr(result));
8285
8286 return "aeb";
8287}
8288
8289static HChar *
8290s390_irgen_ADB(UChar r1, IRTemp op2addr)
8291{
8292 IRTemp op1 = newTemp(Ity_F64);
8293 IRTemp op2 = newTemp(Ity_F64);
8294 IRTemp result = newTemp(Ity_F64);
floriandb4fcaa2012-09-05 19:54:08 +00008295 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008296
8297 assign(op1, get_fpr_dw0(r1));
8298 assign(op2, load(Ity_F64, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00008299 assign(result, triop(Iop_AddF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008300 mkexpr(op2)));
8301 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
8302 put_fpr_dw0(r1, mkexpr(result));
8303
8304 return "adb";
8305}
8306
8307static HChar *
florian4b8efad2012-09-02 18:07:08 +00008308s390_irgen_CEFBR(UChar m3, UChar m4 __attribute__((unused)),
8309 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008310{
florian847684d2012-09-05 04:19:09 +00008311 if (! s390_host_has_fpext && m3 != S390_ROUND_PER_FPC) {
florian4b8efad2012-09-02 18:07:08 +00008312 emulation_warning(EmWarn_S390X_fpext_rounding);
florian847684d2012-09-05 04:19:09 +00008313 m3 = S390_ROUND_PER_FPC;
florian4b8efad2012-09-02 18:07:08 +00008314 }
sewardj2019a972011-03-07 16:04:07 +00008315 IRTemp op2 = newTemp(Ity_I32);
8316
8317 assign(op2, get_gpr_w1(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008318 put_fpr_w0(r1, binop(Iop_I32StoF32, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +00008319 mkexpr(op2)));
sewardj2019a972011-03-07 16:04:07 +00008320
8321 return "cefbr";
8322}
8323
8324static HChar *
florian4b8efad2012-09-02 18:07:08 +00008325s390_irgen_CDFBR(UChar m3 __attribute__((unused)),
8326 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008327{
8328 IRTemp op2 = newTemp(Ity_I32);
8329
8330 assign(op2, get_gpr_w1(r2));
8331 put_fpr_dw0(r1, unop(Iop_I32StoF64, mkexpr(op2)));
8332
8333 return "cdfbr";
8334}
8335
8336static HChar *
florian4b8efad2012-09-02 18:07:08 +00008337s390_irgen_CEGBR(UChar m3, UChar m4 __attribute__((unused)),
8338 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008339{
florian847684d2012-09-05 04:19:09 +00008340 if (! s390_host_has_fpext && m3 != S390_ROUND_PER_FPC) {
florian4b8efad2012-09-02 18:07:08 +00008341 emulation_warning(EmWarn_S390X_fpext_rounding);
florian847684d2012-09-05 04:19:09 +00008342 m3 = S390_ROUND_PER_FPC;
florian4b8efad2012-09-02 18:07:08 +00008343 }
sewardj2019a972011-03-07 16:04:07 +00008344 IRTemp op2 = newTemp(Ity_I64);
8345
8346 assign(op2, get_gpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008347 put_fpr_w0(r1, binop(Iop_I64StoF32, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +00008348 mkexpr(op2)));
sewardj2019a972011-03-07 16:04:07 +00008349
8350 return "cegbr";
8351}
8352
8353static HChar *
florian4b8efad2012-09-02 18:07:08 +00008354s390_irgen_CDGBR(UChar m3, UChar m4 __attribute__((unused)),
8355 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008356{
florian847684d2012-09-05 04:19:09 +00008357 if (! s390_host_has_fpext && m3 != S390_ROUND_PER_FPC) {
florian4b8efad2012-09-02 18:07:08 +00008358 emulation_warning(EmWarn_S390X_fpext_rounding);
florian847684d2012-09-05 04:19:09 +00008359 m3 = S390_ROUND_PER_FPC;
florian4b8efad2012-09-02 18:07:08 +00008360 }
sewardj2019a972011-03-07 16:04:07 +00008361 IRTemp op2 = newTemp(Ity_I64);
8362
8363 assign(op2, get_gpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008364 put_fpr_dw0(r1, binop(Iop_I64StoF64, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +00008365 mkexpr(op2)));
sewardj2019a972011-03-07 16:04:07 +00008366
8367 return "cdgbr";
8368}
8369
8370static HChar *
florian1c8f7ff2012-09-01 00:12:11 +00008371s390_irgen_CELFBR(UChar m3, UChar m4 __attribute__((unused)),
8372 UChar r1, UChar r2)
8373{
floriane75dafa2012-09-01 17:54:09 +00008374 if (! s390_host_has_fpext) {
8375 emulation_failure(EmFail_S390X_fpext);
8376 } else {
8377 IRTemp op2 = newTemp(Ity_I32);
florian1c8f7ff2012-09-01 00:12:11 +00008378
floriane75dafa2012-09-01 17:54:09 +00008379 assign(op2, get_gpr_w1(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008380 put_fpr_w0(r1, binop(Iop_I32UtoF32, mkexpr(encode_bfp_rounding_mode(m3)),
floriane75dafa2012-09-01 17:54:09 +00008381 mkexpr(op2)));
8382 }
florian1c8f7ff2012-09-01 00:12:11 +00008383 return "celfbr";
8384}
8385
8386static HChar *
floriand2129202012-09-01 20:01:39 +00008387s390_irgen_CDLFBR(UChar m3 __attribute__((unused)),
8388 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
florian1c8f7ff2012-09-01 00:12:11 +00008389{
floriane75dafa2012-09-01 17:54:09 +00008390 if (! s390_host_has_fpext) {
8391 emulation_failure(EmFail_S390X_fpext);
8392 } else {
8393 IRTemp op2 = newTemp(Ity_I32);
florian1c8f7ff2012-09-01 00:12:11 +00008394
floriane75dafa2012-09-01 17:54:09 +00008395 assign(op2, get_gpr_w1(r2));
8396 put_fpr_dw0(r1, unop(Iop_I32UtoF64, mkexpr(op2)));
8397 }
florian1c8f7ff2012-09-01 00:12:11 +00008398 return "cdlfbr";
8399}
8400
8401static HChar *
8402s390_irgen_CELGBR(UChar m3, UChar m4 __attribute__((unused)),
8403 UChar r1, UChar r2)
8404{
floriane75dafa2012-09-01 17:54:09 +00008405 if (! s390_host_has_fpext) {
8406 emulation_failure(EmFail_S390X_fpext);
8407 } else {
8408 IRTemp op2 = newTemp(Ity_I64);
florian1c8f7ff2012-09-01 00:12:11 +00008409
floriane75dafa2012-09-01 17:54:09 +00008410 assign(op2, get_gpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008411 put_fpr_w0(r1, binop(Iop_I64UtoF32, mkexpr(encode_bfp_rounding_mode(m3)),
floriane75dafa2012-09-01 17:54:09 +00008412 mkexpr(op2)));
8413 }
florian1c8f7ff2012-09-01 00:12:11 +00008414 return "celgbr";
8415}
8416
8417static HChar *
8418s390_irgen_CDLGBR(UChar m3, UChar m4 __attribute__((unused)),
8419 UChar r1, UChar r2)
8420{
floriane75dafa2012-09-01 17:54:09 +00008421 if (! s390_host_has_fpext) {
8422 emulation_failure(EmFail_S390X_fpext);
8423 } else {
8424 IRTemp op2 = newTemp(Ity_I64);
florian1c8f7ff2012-09-01 00:12:11 +00008425
floriane75dafa2012-09-01 17:54:09 +00008426 assign(op2, get_gpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008427 put_fpr_dw0(r1, binop(Iop_I64UtoF64,
8428 mkexpr(encode_bfp_rounding_mode(m3)),
floriane75dafa2012-09-01 17:54:09 +00008429 mkexpr(op2)));
8430 }
florian1c8f7ff2012-09-01 00:12:11 +00008431 return "cdlgbr";
8432}
8433
8434static HChar *
8435s390_irgen_CLFEBR(UChar m3, UChar m4 __attribute__((unused)),
8436 UChar r1, UChar r2)
8437{
floriane75dafa2012-09-01 17:54:09 +00008438 if (! s390_host_has_fpext) {
8439 emulation_failure(EmFail_S390X_fpext);
8440 } else {
8441 IRTemp op = newTemp(Ity_F32);
8442 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +00008443 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +00008444
floriane75dafa2012-09-01 17:54:09 +00008445 assign(op, get_fpr_w0(r2));
florian19e00772012-09-06 03:13:22 +00008446 assign(result, binop(Iop_F32toI32U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +00008447 mkexpr(op)));
8448 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008449 s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_UINT_32, op, rounding_mode);
floriane75dafa2012-09-01 17:54:09 +00008450 }
florian1c8f7ff2012-09-01 00:12:11 +00008451 return "clfebr";
8452}
8453
8454static HChar *
8455s390_irgen_CLFDBR(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 op = newTemp(Ity_F64);
8462 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +00008463 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +00008464
floriane75dafa2012-09-01 17:54:09 +00008465 assign(op, get_fpr_dw0(r2));
florian19e00772012-09-06 03:13:22 +00008466 assign(result, binop(Iop_F64toI32U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +00008467 mkexpr(op)));
8468 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008469 s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_UINT_32, op, rounding_mode);
floriane75dafa2012-09-01 17:54:09 +00008470 }
florian1c8f7ff2012-09-01 00:12:11 +00008471 return "clfdbr";
8472}
8473
8474static HChar *
8475s390_irgen_CLGEBR(UChar m3, UChar m4 __attribute__((unused)),
8476 UChar r1, UChar r2)
8477{
floriane75dafa2012-09-01 17:54:09 +00008478 if (! s390_host_has_fpext) {
8479 emulation_failure(EmFail_S390X_fpext);
8480 } else {
8481 IRTemp op = newTemp(Ity_F32);
8482 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +00008483 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +00008484
floriane75dafa2012-09-01 17:54:09 +00008485 assign(op, get_fpr_w0(r2));
florian19e00772012-09-06 03:13:22 +00008486 assign(result, binop(Iop_F32toI64U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +00008487 mkexpr(op)));
8488 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008489 s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_UINT_64, op, rounding_mode);
floriane75dafa2012-09-01 17:54:09 +00008490 }
florian1c8f7ff2012-09-01 00:12:11 +00008491 return "clgebr";
8492}
8493
8494static HChar *
8495s390_irgen_CLGDBR(UChar m3, UChar m4 __attribute__((unused)),
8496 UChar r1, UChar r2)
8497{
floriane75dafa2012-09-01 17:54:09 +00008498 if (! s390_host_has_fpext) {
8499 emulation_failure(EmFail_S390X_fpext);
8500 } else {
8501 IRTemp op = newTemp(Ity_F64);
8502 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +00008503 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +00008504
floriane75dafa2012-09-01 17:54:09 +00008505 assign(op, get_fpr_dw0(r2));
florian19e00772012-09-06 03:13:22 +00008506 assign(result, binop(Iop_F64toI64U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +00008507 mkexpr(op)));
8508 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008509 s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_UINT_64, op, rounding_mode);
floriane75dafa2012-09-01 17:54:09 +00008510 }
florian1c8f7ff2012-09-01 00:12:11 +00008511 return "clgdbr";
8512}
8513
8514static HChar *
florian4b8efad2012-09-02 18:07:08 +00008515s390_irgen_CFEBR(UChar m3, UChar m4 __attribute__((unused)),
8516 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008517{
8518 IRTemp op = newTemp(Ity_F32);
8519 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +00008520 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +00008521
8522 assign(op, get_fpr_w0(r2));
florian19e00772012-09-06 03:13:22 +00008523 assign(result, binop(Iop_F32toI32S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +00008524 mkexpr(op)));
8525 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008526 s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_INT_32, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +00008527
8528 return "cfebr";
8529}
8530
8531static HChar *
florian4b8efad2012-09-02 18:07:08 +00008532s390_irgen_CFDBR(UChar m3, UChar m4 __attribute__((unused)),
8533 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008534{
8535 IRTemp op = newTemp(Ity_F64);
8536 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +00008537 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +00008538
8539 assign(op, get_fpr_dw0(r2));
florian19e00772012-09-06 03:13:22 +00008540 assign(result, binop(Iop_F64toI32S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +00008541 mkexpr(op)));
8542 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008543 s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_INT_32, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +00008544
8545 return "cfdbr";
8546}
8547
8548static HChar *
florian4b8efad2012-09-02 18:07:08 +00008549s390_irgen_CGEBR(UChar m3, UChar m4 __attribute__((unused)),
8550 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008551{
8552 IRTemp op = newTemp(Ity_F32);
8553 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +00008554 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +00008555
8556 assign(op, get_fpr_w0(r2));
florian19e00772012-09-06 03:13:22 +00008557 assign(result, binop(Iop_F32toI64S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +00008558 mkexpr(op)));
8559 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008560 s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_INT_64, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +00008561
8562 return "cgebr";
8563}
8564
8565static HChar *
florian4b8efad2012-09-02 18:07:08 +00008566s390_irgen_CGDBR(UChar m3, UChar m4 __attribute__((unused)),
8567 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008568{
8569 IRTemp op = newTemp(Ity_F64);
8570 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +00008571 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +00008572
8573 assign(op, get_fpr_dw0(r2));
florian19e00772012-09-06 03:13:22 +00008574 assign(result, binop(Iop_F64toI64S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +00008575 mkexpr(op)));
8576 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008577 s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_INT_64, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +00008578
8579 return "cgdbr";
8580}
8581
8582static HChar *
8583s390_irgen_DEBR(UChar r1, UChar r2)
8584{
8585 IRTemp op1 = newTemp(Ity_F32);
8586 IRTemp op2 = newTemp(Ity_F32);
8587 IRTemp result = newTemp(Ity_F32);
floriandb4fcaa2012-09-05 19:54:08 +00008588 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008589
8590 assign(op1, get_fpr_w0(r1));
8591 assign(op2, get_fpr_w0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008592 assign(result, triop(Iop_DivF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008593 mkexpr(op2)));
8594 put_fpr_w0(r1, mkexpr(result));
8595
8596 return "debr";
8597}
8598
8599static HChar *
8600s390_irgen_DDBR(UChar r1, UChar r2)
8601{
8602 IRTemp op1 = newTemp(Ity_F64);
8603 IRTemp op2 = newTemp(Ity_F64);
8604 IRTemp result = newTemp(Ity_F64);
floriandb4fcaa2012-09-05 19:54:08 +00008605 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008606
8607 assign(op1, get_fpr_dw0(r1));
8608 assign(op2, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008609 assign(result, triop(Iop_DivF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008610 mkexpr(op2)));
8611 put_fpr_dw0(r1, mkexpr(result));
8612
8613 return "ddbr";
8614}
8615
8616static HChar *
8617s390_irgen_DEB(UChar r1, IRTemp op2addr)
8618{
8619 IRTemp op1 = newTemp(Ity_F32);
8620 IRTemp op2 = newTemp(Ity_F32);
8621 IRTemp result = newTemp(Ity_F32);
floriandb4fcaa2012-09-05 19:54:08 +00008622 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008623
8624 assign(op1, get_fpr_w0(r1));
8625 assign(op2, load(Ity_F32, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00008626 assign(result, triop(Iop_DivF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008627 mkexpr(op2)));
8628 put_fpr_w0(r1, mkexpr(result));
8629
8630 return "deb";
8631}
8632
8633static HChar *
8634s390_irgen_DDB(UChar r1, IRTemp op2addr)
8635{
8636 IRTemp op1 = newTemp(Ity_F64);
8637 IRTemp op2 = newTemp(Ity_F64);
8638 IRTemp result = newTemp(Ity_F64);
floriandb4fcaa2012-09-05 19:54:08 +00008639 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008640
8641 assign(op1, get_fpr_dw0(r1));
8642 assign(op2, load(Ity_F64, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00008643 assign(result, triop(Iop_DivF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008644 mkexpr(op2)));
8645 put_fpr_dw0(r1, mkexpr(result));
8646
8647 return "ddb";
8648}
8649
8650static HChar *
8651s390_irgen_LTEBR(UChar r1, UChar r2)
8652{
8653 IRTemp result = newTemp(Ity_F32);
8654
8655 assign(result, get_fpr_w0(r2));
8656 put_fpr_w0(r1, mkexpr(result));
8657 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
8658
8659 return "ltebr";
8660}
8661
8662static HChar *
8663s390_irgen_LTDBR(UChar r1, UChar r2)
8664{
8665 IRTemp result = newTemp(Ity_F64);
8666
8667 assign(result, get_fpr_dw0(r2));
8668 put_fpr_dw0(r1, mkexpr(result));
8669 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
8670
8671 return "ltdbr";
8672}
8673
8674static HChar *
8675s390_irgen_LCEBR(UChar r1, UChar r2)
8676{
8677 IRTemp result = newTemp(Ity_F32);
8678
8679 assign(result, unop(Iop_NegF32, get_fpr_w0(r2)));
8680 put_fpr_w0(r1, mkexpr(result));
8681 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
8682
8683 return "lcebr";
8684}
8685
8686static HChar *
8687s390_irgen_LCDBR(UChar r1, UChar r2)
8688{
8689 IRTemp result = newTemp(Ity_F64);
8690
8691 assign(result, unop(Iop_NegF64, get_fpr_dw0(r2)));
8692 put_fpr_dw0(r1, mkexpr(result));
8693 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
8694
8695 return "lcdbr";
8696}
8697
8698static HChar *
8699s390_irgen_LDEBR(UChar r1, UChar r2)
8700{
8701 IRTemp op = newTemp(Ity_F32);
8702
8703 assign(op, get_fpr_w0(r2));
8704 put_fpr_dw0(r1, unop(Iop_F32toF64, mkexpr(op)));
8705
8706 return "ldebr";
8707}
8708
8709static HChar *
8710s390_irgen_LDEB(UChar r1, IRTemp op2addr)
8711{
8712 IRTemp op = newTemp(Ity_F32);
8713
8714 assign(op, load(Ity_F32, mkexpr(op2addr)));
8715 put_fpr_dw0(r1, unop(Iop_F32toF64, mkexpr(op)));
8716
8717 return "ldeb";
8718}
8719
8720static HChar *
florian4b8efad2012-09-02 18:07:08 +00008721s390_irgen_LEDBR(UChar m3, UChar m4 __attribute__((unused)),
8722 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008723{
florian12b0bca2012-09-05 20:05:20 +00008724 if (! s390_host_has_fpext && m3 != S390_ROUND_PER_FPC) {
8725 emulation_warning(EmWarn_S390X_fpext_rounding);
8726 m3 = S390_ROUND_PER_FPC;
8727 }
sewardj2019a972011-03-07 16:04:07 +00008728 IRTemp op = newTemp(Ity_F64);
8729
8730 assign(op, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008731 put_fpr_w0(r1, binop(Iop_F64toF32, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +00008732 mkexpr(op)));
sewardj2019a972011-03-07 16:04:07 +00008733
8734 return "ledbr";
8735}
8736
8737static HChar *
8738s390_irgen_MEEBR(UChar r1, UChar r2)
8739{
8740 IRTemp op1 = newTemp(Ity_F32);
8741 IRTemp op2 = newTemp(Ity_F32);
8742 IRTemp result = newTemp(Ity_F32);
floriandb4fcaa2012-09-05 19:54:08 +00008743 IRRoundingMode rounding_mode = encode_bfp_rounding_mode(S390_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008744
8745 assign(op1, get_fpr_w0(r1));
8746 assign(op2, get_fpr_w0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008747 assign(result, triop(Iop_MulF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008748 mkexpr(op2)));
8749 put_fpr_w0(r1, mkexpr(result));
8750
8751 return "meebr";
8752}
8753
8754static HChar *
8755s390_irgen_MDBR(UChar r1, UChar r2)
8756{
8757 IRTemp op1 = newTemp(Ity_F64);
8758 IRTemp op2 = newTemp(Ity_F64);
8759 IRTemp result = newTemp(Ity_F64);
floriandb4fcaa2012-09-05 19:54:08 +00008760 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008761
8762 assign(op1, get_fpr_dw0(r1));
8763 assign(op2, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008764 assign(result, triop(Iop_MulF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008765 mkexpr(op2)));
8766 put_fpr_dw0(r1, mkexpr(result));
8767
8768 return "mdbr";
8769}
8770
8771static HChar *
8772s390_irgen_MEEB(UChar r1, IRTemp op2addr)
8773{
8774 IRTemp op1 = newTemp(Ity_F32);
8775 IRTemp op2 = newTemp(Ity_F32);
8776 IRTemp result = newTemp(Ity_F32);
floriandb4fcaa2012-09-05 19:54:08 +00008777 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008778
8779 assign(op1, get_fpr_w0(r1));
8780 assign(op2, load(Ity_F32, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00008781 assign(result, triop(Iop_MulF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008782 mkexpr(op2)));
8783 put_fpr_w0(r1, mkexpr(result));
8784
8785 return "meeb";
8786}
8787
8788static HChar *
8789s390_irgen_MDB(UChar r1, IRTemp op2addr)
8790{
8791 IRTemp op1 = newTemp(Ity_F64);
8792 IRTemp op2 = newTemp(Ity_F64);
8793 IRTemp result = newTemp(Ity_F64);
floriandb4fcaa2012-09-05 19:54:08 +00008794 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008795
8796 assign(op1, get_fpr_dw0(r1));
8797 assign(op2, load(Ity_F64, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00008798 assign(result, triop(Iop_MulF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008799 mkexpr(op2)));
8800 put_fpr_dw0(r1, mkexpr(result));
8801
8802 return "mdb";
8803}
8804
8805static HChar *
8806s390_irgen_SEBR(UChar r1, UChar r2)
8807{
8808 IRTemp op1 = newTemp(Ity_F32);
8809 IRTemp op2 = newTemp(Ity_F32);
8810 IRTemp result = newTemp(Ity_F32);
floriandb4fcaa2012-09-05 19:54:08 +00008811 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008812
8813 assign(op1, get_fpr_w0(r1));
8814 assign(op2, get_fpr_w0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008815 assign(result, triop(Iop_SubF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008816 mkexpr(op2)));
8817 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
8818 put_fpr_w0(r1, mkexpr(result));
8819
8820 return "sebr";
8821}
8822
8823static HChar *
8824s390_irgen_SDBR(UChar r1, UChar r2)
8825{
8826 IRTemp op1 = newTemp(Ity_F64);
8827 IRTemp op2 = newTemp(Ity_F64);
8828 IRTemp result = newTemp(Ity_F64);
floriandb4fcaa2012-09-05 19:54:08 +00008829 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008830
8831 assign(op1, get_fpr_dw0(r1));
8832 assign(op2, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008833 assign(result, triop(Iop_SubF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008834 mkexpr(op2)));
8835 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
8836 put_fpr_dw0(r1, mkexpr(result));
8837
8838 return "sdbr";
8839}
8840
8841static HChar *
8842s390_irgen_SEB(UChar r1, IRTemp op2addr)
8843{
8844 IRTemp op1 = newTemp(Ity_F32);
8845 IRTemp op2 = newTemp(Ity_F32);
8846 IRTemp result = newTemp(Ity_F32);
floriandb4fcaa2012-09-05 19:54:08 +00008847 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008848
8849 assign(op1, get_fpr_w0(r1));
8850 assign(op2, load(Ity_F32, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00008851 assign(result, triop(Iop_SubF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008852 mkexpr(op2)));
8853 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
8854 put_fpr_w0(r1, mkexpr(result));
8855
8856 return "seb";
8857}
8858
8859static HChar *
8860s390_irgen_SDB(UChar r1, IRTemp op2addr)
8861{
8862 IRTemp op1 = newTemp(Ity_F64);
8863 IRTemp op2 = newTemp(Ity_F64);
8864 IRTemp result = newTemp(Ity_F64);
floriandb4fcaa2012-09-05 19:54:08 +00008865 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008866
8867 assign(op1, get_fpr_dw0(r1));
8868 assign(op2, load(Ity_F64, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00008869 assign(result, triop(Iop_SubF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008870 mkexpr(op2)));
8871 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
8872 put_fpr_dw0(r1, mkexpr(result));
8873
8874 return "sdb";
8875}
8876
8877
8878static HChar *
8879s390_irgen_CLC(UChar length, IRTemp start1, IRTemp start2)
8880{
florian79e839e2012-05-05 02:20:30 +00008881 IRTemp len = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00008882
florian79e839e2012-05-05 02:20:30 +00008883 assign(len, mkU64(length));
8884 s390_irgen_CLC_EX(len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +00008885
8886 return "clc";
8887}
8888
8889static HChar *
florianb0c9a132011-09-08 15:37:39 +00008890s390_irgen_CLCL(UChar r1, UChar r2)
8891{
8892 IRTemp addr1 = newTemp(Ity_I64);
8893 IRTemp addr2 = newTemp(Ity_I64);
8894 IRTemp addr1_load = newTemp(Ity_I64);
8895 IRTemp addr2_load = newTemp(Ity_I64);
8896 IRTemp len1 = newTemp(Ity_I32);
8897 IRTemp len2 = newTemp(Ity_I32);
8898 IRTemp r1p1 = newTemp(Ity_I32); /* contents of r1 + 1 */
8899 IRTemp r2p1 = newTemp(Ity_I32); /* contents of r2 + 1 */
8900 IRTemp single1 = newTemp(Ity_I8);
8901 IRTemp single2 = newTemp(Ity_I8);
8902 IRTemp pad = newTemp(Ity_I8);
8903
8904 assign(addr1, get_gpr_dw0(r1));
8905 assign(r1p1, get_gpr_w1(r1 + 1));
8906 assign(len1, binop(Iop_And32, mkexpr(r1p1), mkU32(0x00ffffff)));
8907 assign(addr2, get_gpr_dw0(r2));
8908 assign(r2p1, get_gpr_w1(r2 + 1));
8909 assign(len2, binop(Iop_And32, mkexpr(r2p1), mkU32(0x00ffffff)));
8910 assign(pad, get_gpr_b4(r2 + 1));
8911
8912 /* len1 == 0 and len2 == 0? Exit */
8913 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +00008914 next_insn_if(binop(Iop_CmpEQ32, binop(Iop_Or32, mkexpr(len1),
8915 mkexpr(len2)), mkU32(0)));
florianb0c9a132011-09-08 15:37:39 +00008916
8917 /* Because mkite evaluates both the then-clause and the else-clause
8918 we cannot load directly from addr1 here. If len1 is 0, then adddr1
8919 may be NULL and loading from there would segfault. So we provide a
8920 valid dummy address in that case. Loading from there does no harm and
8921 the value will be discarded at runtime. */
8922 assign(addr1_load,
8923 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
8924 mkU64(guest_IA_curr_instr), mkexpr(addr1)));
8925 assign(single1,
8926 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
8927 mkexpr(pad), load(Ity_I8, mkexpr(addr1_load))));
8928
8929 assign(addr2_load,
8930 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
8931 mkU64(guest_IA_curr_instr), mkexpr(addr2)));
8932 assign(single2,
8933 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
8934 mkexpr(pad), load(Ity_I8, mkexpr(addr2_load))));
8935
8936 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, single1, single2, False);
8937 /* Fields differ ? */
florian6820ba52012-07-26 02:01:50 +00008938 next_insn_if(binop(Iop_CmpNE8, mkexpr(single1), mkexpr(single2)));
florianb0c9a132011-09-08 15:37:39 +00008939
8940 /* Update len1 and addr1, unless len1 == 0. */
8941 put_gpr_dw0(r1,
8942 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
8943 mkexpr(addr1),
8944 binop(Iop_Add64, mkexpr(addr1), mkU64(1))));
8945
8946 /* When updating len1 we must not modify bits (r1+1)[0:39] */
8947 put_gpr_w1(r1 + 1,
8948 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
8949 binop(Iop_And32, mkexpr(r1p1), mkU32(0xFF000000u)),
8950 binop(Iop_Sub32, mkexpr(r1p1), mkU32(1))));
8951
8952 /* Update len2 and addr2, unless len2 == 0. */
8953 put_gpr_dw0(r2,
8954 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
8955 mkexpr(addr2),
8956 binop(Iop_Add64, mkexpr(addr2), mkU64(1))));
8957
8958 /* When updating len2 we must not modify bits (r2+1)[0:39] */
8959 put_gpr_w1(r2 + 1,
8960 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
8961 binop(Iop_And32, mkexpr(r2p1), mkU32(0xFF000000u)),
8962 binop(Iop_Sub32, mkexpr(r2p1), mkU32(1))));
8963
florian6820ba52012-07-26 02:01:50 +00008964 iterate();
florianb0c9a132011-09-08 15:37:39 +00008965
8966 return "clcl";
8967}
8968
8969static HChar *
sewardj2019a972011-03-07 16:04:07 +00008970s390_irgen_CLCLE(UChar r1, UChar r3, IRTemp pad2)
8971{
8972 IRTemp addr1, addr3, addr1_load, addr3_load, len1, len3, single1, single3;
8973
8974 addr1 = newTemp(Ity_I64);
8975 addr3 = newTemp(Ity_I64);
8976 addr1_load = newTemp(Ity_I64);
8977 addr3_load = newTemp(Ity_I64);
8978 len1 = newTemp(Ity_I64);
8979 len3 = newTemp(Ity_I64);
8980 single1 = newTemp(Ity_I8);
8981 single3 = newTemp(Ity_I8);
8982
8983 assign(addr1, get_gpr_dw0(r1));
8984 assign(len1, get_gpr_dw0(r1 + 1));
8985 assign(addr3, get_gpr_dw0(r3));
8986 assign(len3, get_gpr_dw0(r3 + 1));
8987
8988 /* len1 == 0 and len3 == 0? Exit */
8989 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +00008990 next_insn_if(binop(Iop_CmpEQ64,binop(Iop_Or64, mkexpr(len1),
8991 mkexpr(len3)), mkU64(0)));
sewardj2019a972011-03-07 16:04:07 +00008992
8993 /* A mux requires both ways to be possible. This is a way to prevent clcle
8994 from reading from addr1 if it should read from the pad. Since the pad
8995 has no address, just read from the instruction, we discard that anyway */
8996 assign(addr1_load,
florian6ad49522011-09-09 02:38:55 +00008997 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
8998 mkU64(guest_IA_curr_instr), mkexpr(addr1)));
sewardj2019a972011-03-07 16:04:07 +00008999
9000 /* same for addr3 */
9001 assign(addr3_load,
florian6ad49522011-09-09 02:38:55 +00009002 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
9003 mkU64(guest_IA_curr_instr), mkexpr(addr3)));
sewardj2019a972011-03-07 16:04:07 +00009004
9005 assign(single1,
florian6ad49522011-09-09 02:38:55 +00009006 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
9007 unop(Iop_64to8, mkexpr(pad2)),
9008 load(Ity_I8, mkexpr(addr1_load))));
sewardj2019a972011-03-07 16:04:07 +00009009
9010 assign(single3,
florian6ad49522011-09-09 02:38:55 +00009011 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
9012 unop(Iop_64to8, mkexpr(pad2)),
9013 load(Ity_I8, mkexpr(addr3_load))));
sewardj2019a972011-03-07 16:04:07 +00009014
9015 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, single1, single3, False);
9016 /* Both fields differ ? */
florian6820ba52012-07-26 02:01:50 +00009017 next_insn_if(binop(Iop_CmpNE8, mkexpr(single1), mkexpr(single3)));
sewardj2019a972011-03-07 16:04:07 +00009018
9019 /* If a length in 0 we must not change this length and the address */
9020 put_gpr_dw0(r1,
florian6ad49522011-09-09 02:38:55 +00009021 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
9022 mkexpr(addr1),
9023 binop(Iop_Add64, mkexpr(addr1), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +00009024
9025 put_gpr_dw0(r1 + 1,
florian6ad49522011-09-09 02:38:55 +00009026 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
9027 mkU64(0), binop(Iop_Sub64, mkexpr(len1), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +00009028
9029 put_gpr_dw0(r3,
florian6ad49522011-09-09 02:38:55 +00009030 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
9031 mkexpr(addr3),
9032 binop(Iop_Add64, mkexpr(addr3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +00009033
9034 put_gpr_dw0(r3 + 1,
florian6ad49522011-09-09 02:38:55 +00009035 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
9036 mkU64(0), binop(Iop_Sub64, mkexpr(len3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +00009037
florian6820ba52012-07-26 02:01:50 +00009038 iterate();
sewardj2019a972011-03-07 16:04:07 +00009039
9040 return "clcle";
9041}
floriana64c2432011-07-16 02:11:50 +00009042
florianb0bf6602012-05-05 00:01:16 +00009043
sewardj2019a972011-03-07 16:04:07 +00009044static void
9045s390_irgen_XC_EX(IRTemp length, IRTemp start1, IRTemp start2)
9046{
florianb0bf6602012-05-05 00:01:16 +00009047 s390_irgen_xonc(Iop_Xor8, length, start1, start2);
9048}
sewardj2019a972011-03-07 16:04:07 +00009049
sewardj2019a972011-03-07 16:04:07 +00009050
florianb0bf6602012-05-05 00:01:16 +00009051static void
9052s390_irgen_NC_EX(IRTemp length, IRTemp start1, IRTemp start2)
9053{
9054 s390_irgen_xonc(Iop_And8, length, start1, start2);
9055}
sewardj2019a972011-03-07 16:04:07 +00009056
sewardj2019a972011-03-07 16:04:07 +00009057
florianb0bf6602012-05-05 00:01:16 +00009058static void
9059s390_irgen_OC_EX(IRTemp length, IRTemp start1, IRTemp start2)
9060{
9061 s390_irgen_xonc(Iop_Or8, length, start1, start2);
sewardj2019a972011-03-07 16:04:07 +00009062}
9063
9064
9065static void
9066s390_irgen_CLC_EX(IRTemp length, IRTemp start1, IRTemp start2)
9067{
9068 IRTemp current1 = newTemp(Ity_I8);
9069 IRTemp current2 = newTemp(Ity_I8);
9070 IRTemp counter = newTemp(Ity_I64);
9071
9072 assign(counter, get_counter_dw0());
9073 put_counter_dw0(mkU64(0));
9074
9075 assign(current1, load(Ity_I8, binop(Iop_Add64, mkexpr(start1),
9076 mkexpr(counter))));
9077 assign(current2, load(Ity_I8, binop(Iop_Add64, mkexpr(start2),
9078 mkexpr(counter))));
9079 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, current1, current2,
9080 False);
9081
9082 /* Both fields differ ? */
florian6820ba52012-07-26 02:01:50 +00009083 next_insn_if(binop(Iop_CmpNE8, mkexpr(current1), mkexpr(current2)));
sewardj2019a972011-03-07 16:04:07 +00009084
9085 /* Check for end of field */
9086 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
florian6820ba52012-07-26 02:01:50 +00009087 iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)));
sewardj2019a972011-03-07 16:04:07 +00009088 put_counter_dw0(mkU64(0));
9089}
9090
9091static void
9092s390_irgen_MVC_EX(IRTemp length, IRTemp start1, IRTemp start2)
9093{
9094 IRTemp counter = newTemp(Ity_I64);
9095
9096 assign(counter, get_counter_dw0());
9097
9098 store(binop(Iop_Add64, mkexpr(start1), mkexpr(counter)),
9099 load(Ity_I8, binop(Iop_Add64, mkexpr(start2), mkexpr(counter))));
9100
9101 /* Check for end of field */
9102 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
florian6820ba52012-07-26 02:01:50 +00009103 iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)));
sewardj2019a972011-03-07 16:04:07 +00009104 put_counter_dw0(mkU64(0));
9105}
9106
florianf87d4fb2012-05-05 02:55:24 +00009107static void
9108s390_irgen_TR_EX(IRTemp length, IRTemp start1, IRTemp start2)
9109{
9110 IRTemp op = newTemp(Ity_I8);
9111 IRTemp op1 = newTemp(Ity_I8);
9112 IRTemp result = newTemp(Ity_I64);
9113 IRTemp counter = newTemp(Ity_I64);
9114
9115 assign(counter, get_counter_dw0());
9116
9117 assign(op, load(Ity_I8, binop(Iop_Add64, mkexpr(start1), mkexpr(counter))));
9118
9119 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)), mkexpr(start2)));
9120
9121 assign(op1, load(Ity_I8, mkexpr(result)));
9122 store(binop(Iop_Add64, mkexpr(start1), mkexpr(counter)), mkexpr(op1));
9123
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)));
florianf87d4fb2012-05-05 02:55:24 +00009126 put_counter_dw0(mkU64(0));
9127}
sewardj2019a972011-03-07 16:04:07 +00009128
9129
9130static void
9131s390_irgen_EX_SS(UChar r, IRTemp addr2,
florian6820ba52012-07-26 02:01:50 +00009132 void (*irgen)(IRTemp length, IRTemp start1, IRTemp start2),
9133 int lensize)
sewardj2019a972011-03-07 16:04:07 +00009134{
9135 struct SS {
9136 unsigned int op : 8;
9137 unsigned int l : 8;
9138 unsigned int b1 : 4;
9139 unsigned int d1 : 12;
9140 unsigned int b2 : 4;
9141 unsigned int d2 : 12;
9142 };
9143 union {
9144 struct SS dec;
9145 unsigned long bytes;
9146 } ss;
9147 IRTemp cond;
9148 IRDirty *d;
9149 IRTemp torun;
9150
9151 IRTemp start1 = newTemp(Ity_I64);
9152 IRTemp start2 = newTemp(Ity_I64);
9153 IRTemp len = newTemp(lensize == 64 ? Ity_I64 : Ity_I32);
9154 cond = newTemp(Ity_I1);
9155 torun = newTemp(Ity_I64);
9156
9157 assign(torun, load(Ity_I64, mkexpr(addr2)));
9158 /* Start with a check that the saved code is still correct */
9159 assign(cond, binop(Iop_CmpNE64, mkexpr(torun), mkU64(last_execute_target)));
9160 /* If not, save the new value */
9161 d = unsafeIRDirty_0_N (0, "s390x_dirtyhelper_EX", &s390x_dirtyhelper_EX,
9162 mkIRExprVec_1(mkexpr(torun)));
9163 d->guard = mkexpr(cond);
9164 stmt(IRStmt_Dirty(d));
9165
9166 /* and restart */
florian428dfdd2012-03-27 03:09:49 +00009167 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TISTART),
9168 mkU64(guest_IA_curr_instr)));
9169 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TILEN), mkU64(4)));
florian6820ba52012-07-26 02:01:50 +00009170 restart_if(mkexpr(cond));
sewardj2019a972011-03-07 16:04:07 +00009171
9172 ss.bytes = last_execute_target;
9173 assign(start1, binop(Iop_Add64, mkU64(ss.dec.d1),
9174 ss.dec.b1 != 0 ? get_gpr_dw0(ss.dec.b1) : mkU64(0)));
9175 assign(start2, binop(Iop_Add64, mkU64(ss.dec.d2),
9176 ss.dec.b2 != 0 ? get_gpr_dw0(ss.dec.b2) : mkU64(0)));
9177 assign(len, unop(lensize == 64 ? Iop_8Uto64 : Iop_8Uto32, binop(Iop_Or8,
9178 r != 0 ? get_gpr_b7(r): mkU8(0), mkU8(ss.dec.l))));
9179 irgen(len, start1, start2);
florian8844a632012-04-13 04:04:06 +00009180
sewardj2019a972011-03-07 16:04:07 +00009181 last_execute_target = 0;
9182}
9183
9184static HChar *
9185s390_irgen_EX(UChar r1, IRTemp addr2)
9186{
9187 switch(last_execute_target & 0xff00000000000000ULL) {
9188 case 0:
9189 {
9190 /* no code information yet */
9191 IRDirty *d;
9192
9193 /* so safe the code... */
9194 d = unsafeIRDirty_0_N (0, "s390x_dirtyhelper_EX", &s390x_dirtyhelper_EX,
9195 mkIRExprVec_1(load(Ity_I64, mkexpr(addr2))));
9196 stmt(IRStmt_Dirty(d));
9197 /* and restart */
florian428dfdd2012-03-27 03:09:49 +00009198 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TISTART),
9199 mkU64(guest_IA_curr_instr)));
9200 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TILEN), mkU64(4)));
florian6820ba52012-07-26 02:01:50 +00009201 restart_if(IRExpr_Const(IRConst_U1(True)));
9202
sewardj2019a972011-03-07 16:04:07 +00009203 /* we know that this will be invalidated */
florianf9e1ed72012-04-17 02:41:56 +00009204 put_IA(mkaddr_expr(guest_IA_next_instr));
sewardj2019a972011-03-07 16:04:07 +00009205 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +00009206 dis_res->jk_StopHere = Ijk_TInval;
sewardj2019a972011-03-07 16:04:07 +00009207 break;
9208 }
9209
9210 case 0xd200000000000000ULL:
9211 /* special case MVC */
9212 s390_irgen_EX_SS(r1, addr2, s390_irgen_MVC_EX, 64);
9213 return "mvc via ex";
9214
9215 case 0xd500000000000000ULL:
9216 /* special case CLC */
9217 s390_irgen_EX_SS(r1, addr2, s390_irgen_CLC_EX, 64);
9218 return "clc via ex";
9219
9220 case 0xd700000000000000ULL:
9221 /* special case XC */
9222 s390_irgen_EX_SS(r1, addr2, s390_irgen_XC_EX, 32);
9223 return "xc via ex";
9224
florianb0bf6602012-05-05 00:01:16 +00009225 case 0xd600000000000000ULL:
9226 /* special case OC */
9227 s390_irgen_EX_SS(r1, addr2, s390_irgen_OC_EX, 32);
9228 return "oc via ex";
9229
9230 case 0xd400000000000000ULL:
9231 /* special case NC */
9232 s390_irgen_EX_SS(r1, addr2, s390_irgen_NC_EX, 32);
9233 return "nc via ex";
sewardj2019a972011-03-07 16:04:07 +00009234
florianf87d4fb2012-05-05 02:55:24 +00009235 case 0xdc00000000000000ULL:
9236 /* special case TR */
9237 s390_irgen_EX_SS(r1, addr2, s390_irgen_TR_EX, 64);
9238 return "tr via ex";
9239
sewardj2019a972011-03-07 16:04:07 +00009240 default:
9241 {
9242 /* everything else will get a self checking prefix that also checks the
9243 register content */
9244 IRDirty *d;
9245 UChar *bytes;
9246 IRTemp cond;
9247 IRTemp orperand;
9248 IRTemp torun;
9249
9250 cond = newTemp(Ity_I1);
9251 orperand = newTemp(Ity_I64);
9252 torun = newTemp(Ity_I64);
9253
9254 if (r1 == 0)
9255 assign(orperand, mkU64(0));
9256 else
9257 assign(orperand, unop(Iop_8Uto64,get_gpr_b7(r1)));
9258 /* This code is going to be translated */
9259 assign(torun, binop(Iop_Or64, load(Ity_I64, mkexpr(addr2)),
9260 binop(Iop_Shl64, mkexpr(orperand), mkU8(48))));
9261
9262 /* Start with a check that saved code is still correct */
9263 assign(cond, binop(Iop_CmpNE64, mkexpr(torun),
9264 mkU64(last_execute_target)));
9265 /* If not, save the new value */
9266 d = unsafeIRDirty_0_N (0, "s390x_dirtyhelper_EX", &s390x_dirtyhelper_EX,
9267 mkIRExprVec_1(mkexpr(torun)));
9268 d->guard = mkexpr(cond);
9269 stmt(IRStmt_Dirty(d));
9270
9271 /* and restart */
florian428dfdd2012-03-27 03:09:49 +00009272 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TISTART), mkU64(guest_IA_curr_instr)));
9273 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TILEN), mkU64(4)));
florian6820ba52012-07-26 02:01:50 +00009274 restart_if(mkexpr(cond));
sewardj2019a972011-03-07 16:04:07 +00009275
9276 /* Now comes the actual translation */
9277 bytes = (UChar *) &last_execute_target;
9278 s390_decode_and_irgen(bytes, ((((bytes[0] >> 6) + 1) >> 1) + 1) << 1,
9279 dis_res);
sewardj7ee97522011-05-09 21:45:04 +00009280 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00009281 vex_printf(" which was executed by\n");
9282 /* dont make useless translations in the next execute */
9283 last_execute_target = 0;
9284 }
9285 }
9286 return "ex";
9287}
9288
9289static HChar *
9290s390_irgen_EXRL(UChar r1, UInt offset)
9291{
9292 IRTemp addr = newTemp(Ity_I64);
9293 /* we might save one round trip because we know the target */
9294 if (!last_execute_target)
9295 last_execute_target = *(ULong *)(HWord)
9296 (guest_IA_curr_instr + offset * 2UL);
9297 assign(addr, mkU64(guest_IA_curr_instr + offset * 2UL));
9298 s390_irgen_EX(r1, addr);
9299 return "exrl";
9300}
9301
9302static HChar *
9303s390_irgen_IPM(UChar r1)
9304{
9305 // As long as we dont support SPM, lets just assume 0 as program mask
9306 put_gpr_b4(r1, unop(Iop_32to8, binop(Iop_Or32, mkU32(0 /* program mask */),
9307 binop(Iop_Shl32, s390_call_calculate_cc(), mkU8(4)))));
9308
9309 return "ipm";
9310}
9311
9312
9313static HChar *
9314s390_irgen_SRST(UChar r1, UChar r2)
9315{
9316 IRTemp address = newTemp(Ity_I64);
9317 IRTemp next = newTemp(Ity_I64);
9318 IRTemp delim = newTemp(Ity_I8);
9319 IRTemp counter = newTemp(Ity_I64);
9320 IRTemp byte = newTemp(Ity_I8);
9321
9322 assign(address, get_gpr_dw0(r2));
9323 assign(next, get_gpr_dw0(r1));
9324
9325 assign(counter, get_counter_dw0());
9326 put_counter_dw0(mkU64(0));
9327
9328 // start = next? CC=2 and out r1 and r2 unchanged
9329 s390_cc_set(2);
9330 put_gpr_dw0(r2, binop(Iop_Sub64, mkexpr(address), mkexpr(counter)));
florian6820ba52012-07-26 02:01:50 +00009331 next_insn_if(binop(Iop_CmpEQ64, mkexpr(address), mkexpr(next)));
sewardj2019a972011-03-07 16:04:07 +00009332
9333 assign(byte, load(Ity_I8, mkexpr(address)));
9334 assign(delim, get_gpr_b7(0));
9335
9336 // byte = delim? CC=1, R1=address
9337 s390_cc_set(1);
9338 put_gpr_dw0(r1, mkexpr(address));
florian6820ba52012-07-26 02:01:50 +00009339 next_insn_if(binop(Iop_CmpEQ8, mkexpr(delim), mkexpr(byte)));
sewardj2019a972011-03-07 16:04:07 +00009340
9341 // else: all equal, no end yet, loop
9342 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
9343 put_gpr_dw0(r1, mkexpr(next));
9344 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(address), mkU64(1)));
floriancf87c942012-07-25 00:52:21 +00009345
florian6820ba52012-07-26 02:01:50 +00009346 iterate();
sewardj2019a972011-03-07 16:04:07 +00009347
9348 return "srst";
9349}
9350
9351static HChar *
9352s390_irgen_CLST(UChar r1, UChar r2)
9353{
9354 IRTemp address1 = newTemp(Ity_I64);
9355 IRTemp address2 = newTemp(Ity_I64);
9356 IRTemp end = newTemp(Ity_I8);
9357 IRTemp counter = newTemp(Ity_I64);
9358 IRTemp byte1 = newTemp(Ity_I8);
9359 IRTemp byte2 = newTemp(Ity_I8);
9360
9361 assign(address1, get_gpr_dw0(r1));
9362 assign(address2, get_gpr_dw0(r2));
9363 assign(end, get_gpr_b7(0));
9364 assign(counter, get_counter_dw0());
9365 put_counter_dw0(mkU64(0));
9366 assign(byte1, load(Ity_I8, mkexpr(address1)));
9367 assign(byte2, load(Ity_I8, mkexpr(address2)));
9368
9369 // end in both? all equal, reset r1 and r2 to start values
9370 s390_cc_set(0);
9371 put_gpr_dw0(r1, binop(Iop_Sub64, mkexpr(address1), mkexpr(counter)));
9372 put_gpr_dw0(r2, binop(Iop_Sub64, mkexpr(address2), mkexpr(counter)));
florian6820ba52012-07-26 02:01:50 +00009373 next_insn_if(binop(Iop_CmpEQ8, mkU8(0),
9374 binop(Iop_Or8,
9375 binop(Iop_Xor8, mkexpr(byte1), mkexpr(end)),
9376 binop(Iop_Xor8, mkexpr(byte2), mkexpr(end)))));
sewardj2019a972011-03-07 16:04:07 +00009377
9378 put_gpr_dw0(r1, mkexpr(address1));
9379 put_gpr_dw0(r2, mkexpr(address2));
9380
9381 // End found in string1
9382 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +00009383 next_insn_if(binop(Iop_CmpEQ8, mkexpr(end), mkexpr(byte1)));
sewardj2019a972011-03-07 16:04:07 +00009384
9385 // End found in string2
9386 s390_cc_set(2);
florian6820ba52012-07-26 02:01:50 +00009387 next_insn_if(binop(Iop_CmpEQ8, mkexpr(end), mkexpr(byte2)));
sewardj2019a972011-03-07 16:04:07 +00009388
9389 // string1 < string2
9390 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +00009391 next_insn_if(binop(Iop_CmpLT32U, unop(Iop_8Uto32, mkexpr(byte1)),
9392 unop(Iop_8Uto32, mkexpr(byte2))));
sewardj2019a972011-03-07 16:04:07 +00009393
9394 // string2 < string1
9395 s390_cc_set(2);
florian6820ba52012-07-26 02:01:50 +00009396 next_insn_if(binop(Iop_CmpLT32U, unop(Iop_8Uto32, mkexpr(byte2)),
9397 unop(Iop_8Uto32, mkexpr(byte1))));
sewardj2019a972011-03-07 16:04:07 +00009398
9399 // else: all equal, no end yet, loop
9400 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
9401 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), mkU64(1)));
9402 put_gpr_dw0(r2, binop(Iop_Add64, get_gpr_dw0(r2), mkU64(1)));
floriancf87c942012-07-25 00:52:21 +00009403
florian6820ba52012-07-26 02:01:50 +00009404 iterate();
sewardj2019a972011-03-07 16:04:07 +00009405
9406 return "clst";
9407}
9408
9409static void
9410s390_irgen_load_multiple_32bit(UChar r1, UChar r3, IRTemp op2addr)
9411{
9412 UChar reg;
9413 IRTemp addr = newTemp(Ity_I64);
9414
9415 assign(addr, mkexpr(op2addr));
9416 reg = r1;
9417 do {
9418 IRTemp old = addr;
9419
9420 reg %= 16;
9421 put_gpr_w1(reg, load(Ity_I32, mkexpr(addr)));
9422 addr = newTemp(Ity_I64);
9423 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
9424 reg++;
9425 } while (reg != (r3 + 1));
9426}
9427
9428static HChar *
9429s390_irgen_LM(UChar r1, UChar r3, IRTemp op2addr)
9430{
9431 s390_irgen_load_multiple_32bit(r1, r3, op2addr);
9432
9433 return "lm";
9434}
9435
9436static HChar *
9437s390_irgen_LMY(UChar r1, UChar r3, IRTemp op2addr)
9438{
9439 s390_irgen_load_multiple_32bit(r1, r3, op2addr);
9440
9441 return "lmy";
9442}
9443
9444static HChar *
9445s390_irgen_LMH(UChar r1, UChar r3, IRTemp op2addr)
9446{
9447 UChar reg;
9448 IRTemp addr = newTemp(Ity_I64);
9449
9450 assign(addr, mkexpr(op2addr));
9451 reg = r1;
9452 do {
9453 IRTemp old = addr;
9454
9455 reg %= 16;
9456 put_gpr_w0(reg, load(Ity_I32, mkexpr(addr)));
9457 addr = newTemp(Ity_I64);
9458 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
9459 reg++;
9460 } while (reg != (r3 + 1));
9461
9462 return "lmh";
9463}
9464
9465static HChar *
9466s390_irgen_LMG(UChar r1, UChar r3, IRTemp op2addr)
9467{
9468 UChar reg;
9469 IRTemp addr = newTemp(Ity_I64);
9470
9471 assign(addr, mkexpr(op2addr));
9472 reg = r1;
9473 do {
9474 IRTemp old = addr;
9475
9476 reg %= 16;
9477 put_gpr_dw0(reg, load(Ity_I64, mkexpr(addr)));
9478 addr = newTemp(Ity_I64);
9479 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(8)));
9480 reg++;
9481 } while (reg != (r3 + 1));
9482
9483 return "lmg";
9484}
9485
9486static void
9487s390_irgen_store_multiple_32bit(UChar r1, UChar r3, IRTemp op2addr)
9488{
9489 UChar reg;
9490 IRTemp addr = newTemp(Ity_I64);
9491
9492 assign(addr, mkexpr(op2addr));
9493 reg = r1;
9494 do {
9495 IRTemp old = addr;
9496
9497 reg %= 16;
9498 store(mkexpr(addr), get_gpr_w1(reg));
9499 addr = newTemp(Ity_I64);
9500 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
9501 reg++;
9502 } while( reg != (r3 + 1));
9503}
9504
9505static HChar *
9506s390_irgen_STM(UChar r1, UChar r3, IRTemp op2addr)
9507{
9508 s390_irgen_store_multiple_32bit(r1, r3, op2addr);
9509
9510 return "stm";
9511}
9512
9513static HChar *
9514s390_irgen_STMY(UChar r1, UChar r3, IRTemp op2addr)
9515{
9516 s390_irgen_store_multiple_32bit(r1, r3, op2addr);
9517
9518 return "stmy";
9519}
9520
9521static HChar *
9522s390_irgen_STMH(UChar r1, UChar r3, IRTemp op2addr)
9523{
9524 UChar reg;
9525 IRTemp addr = newTemp(Ity_I64);
9526
9527 assign(addr, mkexpr(op2addr));
9528 reg = r1;
9529 do {
9530 IRTemp old = addr;
9531
9532 reg %= 16;
9533 store(mkexpr(addr), get_gpr_w0(reg));
9534 addr = newTemp(Ity_I64);
9535 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
9536 reg++;
9537 } while( reg != (r3 + 1));
9538
9539 return "stmh";
9540}
9541
9542static HChar *
9543s390_irgen_STMG(UChar r1, UChar r3, IRTemp op2addr)
9544{
9545 UChar reg;
9546 IRTemp addr = newTemp(Ity_I64);
9547
9548 assign(addr, mkexpr(op2addr));
9549 reg = r1;
9550 do {
9551 IRTemp old = addr;
9552
9553 reg %= 16;
9554 store(mkexpr(addr), get_gpr_dw0(reg));
9555 addr = newTemp(Ity_I64);
9556 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(8)));
9557 reg++;
9558 } while( reg != (r3 + 1));
9559
9560 return "stmg";
9561}
9562
9563static void
florianb0bf6602012-05-05 00:01:16 +00009564s390_irgen_xonc(IROp op, IRTemp length, IRTemp start1, IRTemp start2)
sewardj2019a972011-03-07 16:04:07 +00009565{
9566 IRTemp old1 = newTemp(Ity_I8);
9567 IRTemp old2 = newTemp(Ity_I8);
9568 IRTemp new1 = newTemp(Ity_I8);
9569 IRTemp counter = newTemp(Ity_I32);
9570 IRTemp addr1 = newTemp(Ity_I64);
9571
9572 assign(counter, get_counter_w0());
9573
9574 assign(addr1, binop(Iop_Add64, mkexpr(start1),
9575 unop(Iop_32Uto64, mkexpr(counter))));
9576
9577 assign(old1, load(Ity_I8, mkexpr(addr1)));
9578 assign(old2, load(Ity_I8, binop(Iop_Add64, mkexpr(start2),
9579 unop(Iop_32Uto64,mkexpr(counter)))));
9580 assign(new1, binop(op, mkexpr(old1), mkexpr(old2)));
9581
9582 /* Special case: xc is used to zero memory */
sewardj2019a972011-03-07 16:04:07 +00009583 if (op == Iop_Xor8) {
9584 store(mkexpr(addr1),
florian6ad49522011-09-09 02:38:55 +00009585 mkite(binop(Iop_CmpEQ64, mkexpr(start1), mkexpr(start2)),
9586 mkU8(0), mkexpr(new1)));
sewardj2019a972011-03-07 16:04:07 +00009587 } else
9588 store(mkexpr(addr1), mkexpr(new1));
9589 put_counter_w1(binop(Iop_Or32, unop(Iop_8Uto32, mkexpr(new1)),
9590 get_counter_w1()));
9591
9592 /* Check for end of field */
9593 put_counter_w0(binop(Iop_Add32, mkexpr(counter), mkU32(1)));
florian6820ba52012-07-26 02:01:50 +00009594 iterate_if(binop(Iop_CmpNE32, mkexpr(counter), mkexpr(length)));
sewardj2019a972011-03-07 16:04:07 +00009595 s390_cc_thunk_put1(S390_CC_OP_BITWISE, mktemp(Ity_I32, get_counter_w1()),
9596 False);
9597 put_counter_dw0(mkU64(0));
9598}
9599
9600static HChar *
9601s390_irgen_XC(UChar length, IRTemp start1, IRTemp start2)
9602{
florianb0bf6602012-05-05 00:01:16 +00009603 IRTemp len = newTemp(Ity_I32);
9604
9605 assign(len, mkU32(length));
9606 s390_irgen_xonc(Iop_Xor8, len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +00009607
9608 return "xc";
9609}
9610
sewardjb63967e2011-03-24 08:50:04 +00009611static void
9612s390_irgen_XC_sameloc(UChar length, UChar b, UShort d)
9613{
9614 IRTemp counter = newTemp(Ity_I32);
9615 IRTemp start = newTemp(Ity_I64);
9616 IRTemp addr = newTemp(Ity_I64);
9617
9618 assign(start,
9619 binop(Iop_Add64, mkU64(d), b != 0 ? get_gpr_dw0(b) : mkU64(0)));
9620
9621 if (length < 8) {
9622 UInt i;
9623
9624 for (i = 0; i <= length; ++i) {
9625 store(binop(Iop_Add64, mkexpr(start), mkU64(i)), mkU8(0));
9626 }
9627 } else {
9628 assign(counter, get_counter_w0());
9629
9630 assign(addr, binop(Iop_Add64, mkexpr(start),
9631 unop(Iop_32Uto64, mkexpr(counter))));
9632
9633 store(mkexpr(addr), mkU8(0));
9634
9635 /* Check for end of field */
9636 put_counter_w0(binop(Iop_Add32, mkexpr(counter), mkU32(1)));
florian6820ba52012-07-26 02:01:50 +00009637 iterate_if(binop(Iop_CmpNE32, mkexpr(counter), mkU32(length)));
sewardjb63967e2011-03-24 08:50:04 +00009638
9639 /* Reset counter */
9640 put_counter_dw0(mkU64(0));
9641 }
9642
9643 s390_cc_thunk_put1(S390_CC_OP_BITWISE, mktemp(Ity_I32, mkU32(0)), False);
9644
sewardj7ee97522011-05-09 21:45:04 +00009645 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardjb63967e2011-03-24 08:50:04 +00009646 s390_disasm(ENC3(MNM, UDLB, UDXB), "xc", d, length, b, d, 0, b);
9647}
9648
sewardj2019a972011-03-07 16:04:07 +00009649static HChar *
9650s390_irgen_NC(UChar length, IRTemp start1, IRTemp start2)
9651{
florianb0bf6602012-05-05 00:01:16 +00009652 IRTemp len = newTemp(Ity_I32);
9653
9654 assign(len, mkU32(length));
9655 s390_irgen_xonc(Iop_And8, len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +00009656
9657 return "nc";
9658}
9659
9660static HChar *
9661s390_irgen_OC(UChar length, IRTemp start1, IRTemp start2)
9662{
florianb0bf6602012-05-05 00:01:16 +00009663 IRTemp len = newTemp(Ity_I32);
9664
9665 assign(len, mkU32(length));
9666 s390_irgen_xonc(Iop_Or8, len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +00009667
9668 return "oc";
9669}
9670
9671
9672static HChar *
9673s390_irgen_MVC(UChar length, IRTemp start1, IRTemp start2)
9674{
florian79e839e2012-05-05 02:20:30 +00009675 IRTemp len = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00009676
florian79e839e2012-05-05 02:20:30 +00009677 assign(len, mkU64(length));
9678 s390_irgen_MVC_EX(len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +00009679
9680 return "mvc";
9681}
9682
9683static HChar *
florianb0c9a132011-09-08 15:37:39 +00009684s390_irgen_MVCL(UChar r1, UChar r2)
9685{
9686 IRTemp addr1 = newTemp(Ity_I64);
9687 IRTemp addr2 = newTemp(Ity_I64);
9688 IRTemp addr2_load = newTemp(Ity_I64);
9689 IRTemp r1p1 = newTemp(Ity_I32); /* contents of r1 + 1 */
9690 IRTemp r2p1 = newTemp(Ity_I32); /* contents of r2 + 1 */
9691 IRTemp len1 = newTemp(Ity_I32);
9692 IRTemp len2 = newTemp(Ity_I32);
9693 IRTemp pad = newTemp(Ity_I8);
9694 IRTemp single = newTemp(Ity_I8);
9695
9696 assign(addr1, get_gpr_dw0(r1));
9697 assign(r1p1, get_gpr_w1(r1 + 1));
9698 assign(len1, binop(Iop_And32, mkexpr(r1p1), mkU32(0x00ffffff)));
9699 assign(addr2, get_gpr_dw0(r2));
9700 assign(r2p1, get_gpr_w1(r2 + 1));
9701 assign(len2, binop(Iop_And32, mkexpr(r2p1), mkU32(0x00ffffff)));
9702 assign(pad, get_gpr_b4(r2 + 1));
9703
9704 /* len1 == 0 ? */
9705 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len2, False);
florian6820ba52012-07-26 02:01:50 +00009706 next_insn_if(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)));
florianb0c9a132011-09-08 15:37:39 +00009707
9708 /* Check for destructive overlap:
9709 addr1 > addr2 && addr2 + len1 > addr1 && (addr2 + len2) > addr1 */
9710 s390_cc_set(3);
9711 IRTemp cond1 = newTemp(Ity_I32);
9712 assign(cond1, unop(Iop_1Uto32,
9713 binop(Iop_CmpLT64U, mkexpr(addr2), mkexpr(addr1))));
9714 IRTemp cond2 = newTemp(Ity_I32);
9715 assign(cond2, unop(Iop_1Uto32,
9716 binop(Iop_CmpLT64U, mkexpr(addr1),
9717 binop(Iop_Add64, mkexpr(addr2),
9718 unop(Iop_32Uto64, mkexpr(len1))))));
9719 IRTemp cond3 = newTemp(Ity_I32);
9720 assign(cond3, unop(Iop_1Uto32,
9721 binop(Iop_CmpLT64U,
9722 mkexpr(addr1),
9723 binop(Iop_Add64, mkexpr(addr2),
9724 unop(Iop_32Uto64, mkexpr(len2))))));
9725
florian6820ba52012-07-26 02:01:50 +00009726 next_insn_if(binop(Iop_CmpEQ32,
9727 binop(Iop_And32,
9728 binop(Iop_And32, mkexpr(cond1), mkexpr(cond2)),
9729 mkexpr(cond3)),
9730 mkU32(1)));
florianb0c9a132011-09-08 15:37:39 +00009731
9732 /* See s390_irgen_CLCL for explanation why we cannot load directly
9733 and need two steps. */
9734 assign(addr2_load,
9735 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
9736 mkU64(guest_IA_curr_instr), mkexpr(addr2)));
9737 assign(single,
9738 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
9739 mkexpr(pad), load(Ity_I8, mkexpr(addr2_load))));
9740
9741 store(mkexpr(addr1), mkexpr(single));
9742
9743 /* Update addr1 and len1 */
9744 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkU64(1)));
9745 put_gpr_w1(r1 + 1, binop(Iop_Sub32, mkexpr(r1p1), mkU32(1)));
9746
9747 /* Update addr2 and len2 */
9748 put_gpr_dw0(r2,
9749 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
9750 mkexpr(addr2),
9751 binop(Iop_Add64, mkexpr(addr2), mkU64(1))));
9752
9753 /* When updating len2 we must not modify bits (r2+1)[0:39] */
9754 put_gpr_w1(r2 + 1,
9755 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
9756 binop(Iop_And32, mkexpr(r2p1), mkU32(0xFF000000u)),
9757 binop(Iop_Sub32, mkexpr(r2p1), mkU32(1))));
9758
9759 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len2, False);
florian6820ba52012-07-26 02:01:50 +00009760 iterate_if(binop(Iop_CmpNE32, mkexpr(len1), mkU32(1)));
florianb0c9a132011-09-08 15:37:39 +00009761
9762 return "mvcl";
9763}
9764
9765
9766static HChar *
sewardj2019a972011-03-07 16:04:07 +00009767s390_irgen_MVCLE(UChar r1, UChar r3, IRTemp pad2)
9768{
9769 IRTemp addr1, addr3, addr3_load, len1, len3, single;
9770
9771 addr1 = newTemp(Ity_I64);
9772 addr3 = newTemp(Ity_I64);
9773 addr3_load = newTemp(Ity_I64);
9774 len1 = newTemp(Ity_I64);
9775 len3 = newTemp(Ity_I64);
9776 single = newTemp(Ity_I8);
9777
9778 assign(addr1, get_gpr_dw0(r1));
9779 assign(len1, get_gpr_dw0(r1 + 1));
9780 assign(addr3, get_gpr_dw0(r3));
9781 assign(len3, get_gpr_dw0(r3 + 1));
9782
9783 // len1 == 0 ?
9784 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len3, False);
florian6820ba52012-07-26 02:01:50 +00009785 next_insn_if(binop(Iop_CmpEQ64,mkexpr(len1), mkU64(0)));
sewardj2019a972011-03-07 16:04:07 +00009786
9787 /* This is a hack to prevent mvcle from reading from addr3 if it
9788 should read from the pad. Since the pad has no address, just
9789 read from the instruction, we discard that anyway */
9790 assign(addr3_load,
florian6ad49522011-09-09 02:38:55 +00009791 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
9792 mkU64(guest_IA_curr_instr), mkexpr(addr3)));
sewardj2019a972011-03-07 16:04:07 +00009793
9794 assign(single,
florian6ad49522011-09-09 02:38:55 +00009795 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
9796 unop(Iop_64to8, mkexpr(pad2)),
9797 load(Ity_I8, mkexpr(addr3_load))));
sewardj2019a972011-03-07 16:04:07 +00009798 store(mkexpr(addr1), mkexpr(single));
9799
9800 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkU64(1)));
9801
9802 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkU64(1)));
9803
9804 put_gpr_dw0(r3,
florian6ad49522011-09-09 02:38:55 +00009805 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
9806 mkexpr(addr3),
9807 binop(Iop_Add64, mkexpr(addr3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +00009808
9809 put_gpr_dw0(r3 + 1,
florian6ad49522011-09-09 02:38:55 +00009810 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
9811 mkU64(0), binop(Iop_Sub64, mkexpr(len3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +00009812
sewardj2019a972011-03-07 16:04:07 +00009813 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len3, False);
florian6820ba52012-07-26 02:01:50 +00009814 iterate_if(binop(Iop_CmpNE64, mkexpr(len1), mkU64(1)));
sewardj2019a972011-03-07 16:04:07 +00009815
9816 return "mvcle";
9817}
9818
9819static HChar *
9820s390_irgen_MVST(UChar r1, UChar r2)
9821{
9822 IRTemp addr1 = newTemp(Ity_I64);
9823 IRTemp addr2 = newTemp(Ity_I64);
9824 IRTemp end = newTemp(Ity_I8);
9825 IRTemp byte = newTemp(Ity_I8);
9826 IRTemp counter = newTemp(Ity_I64);
9827
9828 assign(addr1, get_gpr_dw0(r1));
9829 assign(addr2, get_gpr_dw0(r2));
9830 assign(counter, get_counter_dw0());
9831 assign(end, get_gpr_b7(0));
9832 assign(byte, load(Ity_I8, binop(Iop_Add64, mkexpr(addr2),mkexpr(counter))));
9833 store(binop(Iop_Add64,mkexpr(addr1),mkexpr(counter)), mkexpr(byte));
9834
9835 // We use unlimited as cpu-determined number
9836 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
florian6820ba52012-07-26 02:01:50 +00009837 iterate_if(binop(Iop_CmpNE8, mkexpr(end), mkexpr(byte)));
sewardj2019a972011-03-07 16:04:07 +00009838
9839 // and always set cc=1 at the end + update r1
9840 s390_cc_set(1);
9841 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(counter)));
9842 put_counter_dw0(mkU64(0));
9843
9844 return "mvst";
9845}
9846
9847static void
9848s390_irgen_divide_64to32(IROp op, UChar r1, IRTemp op2)
9849{
9850 IRTemp op1 = newTemp(Ity_I64);
9851 IRTemp result = newTemp(Ity_I64);
9852
9853 assign(op1, binop(Iop_32HLto64,
9854 get_gpr_w1(r1), // high 32 bits
9855 get_gpr_w1(r1 + 1))); // low 32 bits
9856 assign(result, binop(op, mkexpr(op1), mkexpr(op2)));
9857 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result))); // remainder
9858 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result))); // quotient
9859}
9860
9861static void
9862s390_irgen_divide_128to64(IROp op, UChar r1, IRTemp op2)
9863{
9864 IRTemp op1 = newTemp(Ity_I128);
9865 IRTemp result = newTemp(Ity_I128);
9866
9867 assign(op1, binop(Iop_64HLto128,
9868 get_gpr_dw0(r1), // high 64 bits
9869 get_gpr_dw0(r1 + 1))); // low 64 bits
9870 assign(result, binop(op, mkexpr(op1), mkexpr(op2)));
9871 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result))); // remainder
9872 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result))); // quotient
9873}
9874
9875static void
9876s390_irgen_divide_64to64(IROp op, UChar r1, IRTemp op2)
9877{
9878 IRTemp op1 = newTemp(Ity_I64);
9879 IRTemp result = newTemp(Ity_I128);
9880
9881 assign(op1, get_gpr_dw0(r1 + 1));
9882 assign(result, binop(op, mkexpr(op1), mkexpr(op2)));
9883 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result))); // remainder
9884 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result))); // quotient
9885}
9886
9887static HChar *
9888s390_irgen_DR(UChar r1, UChar r2)
9889{
9890 IRTemp op2 = newTemp(Ity_I32);
9891
9892 assign(op2, get_gpr_w1(r2));
9893
9894 s390_irgen_divide_64to32(Iop_DivModS64to32, r1, op2);
9895
9896 return "dr";
9897}
9898
9899static HChar *
9900s390_irgen_D(UChar r1, IRTemp op2addr)
9901{
9902 IRTemp op2 = newTemp(Ity_I32);
9903
9904 assign(op2, load(Ity_I32, mkexpr(op2addr)));
9905
9906 s390_irgen_divide_64to32(Iop_DivModS64to32, r1, op2);
9907
9908 return "d";
9909}
9910
9911static HChar *
9912s390_irgen_DLR(UChar r1, UChar r2)
9913{
9914 IRTemp op2 = newTemp(Ity_I32);
9915
9916 assign(op2, get_gpr_w1(r2));
9917
9918 s390_irgen_divide_64to32(Iop_DivModU64to32, r1, op2);
9919
florian7cd1cde2012-08-16 23:57:43 +00009920 return "dlr";
sewardj2019a972011-03-07 16:04:07 +00009921}
9922
9923static HChar *
9924s390_irgen_DL(UChar r1, IRTemp op2addr)
9925{
9926 IRTemp op2 = newTemp(Ity_I32);
9927
9928 assign(op2, load(Ity_I32, mkexpr(op2addr)));
9929
9930 s390_irgen_divide_64to32(Iop_DivModU64to32, r1, op2);
9931
9932 return "dl";
9933}
9934
9935static HChar *
9936s390_irgen_DLG(UChar r1, IRTemp op2addr)
9937{
9938 IRTemp op2 = newTemp(Ity_I64);
9939
9940 assign(op2, load(Ity_I64, mkexpr(op2addr)));
9941
9942 s390_irgen_divide_128to64(Iop_DivModU128to64, r1, op2);
9943
9944 return "dlg";
9945}
9946
9947static HChar *
9948s390_irgen_DLGR(UChar r1, UChar r2)
9949{
9950 IRTemp op2 = newTemp(Ity_I64);
9951
9952 assign(op2, get_gpr_dw0(r2));
9953
9954 s390_irgen_divide_128to64(Iop_DivModU128to64, r1, op2);
9955
9956 return "dlgr";
9957}
9958
9959static HChar *
9960s390_irgen_DSGR(UChar r1, UChar r2)
9961{
9962 IRTemp op2 = newTemp(Ity_I64);
9963
9964 assign(op2, get_gpr_dw0(r2));
9965
9966 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
9967
9968 return "dsgr";
9969}
9970
9971static HChar *
9972s390_irgen_DSG(UChar r1, IRTemp op2addr)
9973{
9974 IRTemp op2 = newTemp(Ity_I64);
9975
9976 assign(op2, load(Ity_I64, mkexpr(op2addr)));
9977
9978 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
9979
9980 return "dsg";
9981}
9982
9983static HChar *
9984s390_irgen_DSGFR(UChar r1, UChar r2)
9985{
9986 IRTemp op2 = newTemp(Ity_I64);
9987
9988 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
9989
9990 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
9991
9992 return "dsgfr";
9993}
9994
9995static HChar *
9996s390_irgen_DSGF(UChar r1, IRTemp op2addr)
9997{
9998 IRTemp op2 = newTemp(Ity_I64);
9999
10000 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
10001
10002 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
10003
10004 return "dsgf";
10005}
10006
10007static void
10008s390_irgen_load_ar_multiple(UChar r1, UChar r3, IRTemp op2addr)
10009{
10010 UChar reg;
10011 IRTemp addr = newTemp(Ity_I64);
10012
10013 assign(addr, mkexpr(op2addr));
10014 reg = r1;
10015 do {
10016 IRTemp old = addr;
10017
10018 reg %= 16;
10019 put_ar_w0(reg, load(Ity_I32, mkexpr(addr)));
10020 addr = newTemp(Ity_I64);
10021 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
10022 reg++;
10023 } while (reg != (r3 + 1));
10024}
10025
10026static HChar *
10027s390_irgen_LAM(UChar r1, UChar r3, IRTemp op2addr)
10028{
10029 s390_irgen_load_ar_multiple(r1, r3, op2addr);
10030
10031 return "lam";
10032}
10033
10034static HChar *
10035s390_irgen_LAMY(UChar r1, UChar r3, IRTemp op2addr)
10036{
10037 s390_irgen_load_ar_multiple(r1, r3, op2addr);
10038
10039 return "lamy";
10040}
10041
10042static void
10043s390_irgen_store_ar_multiple(UChar r1, UChar r3, IRTemp op2addr)
10044{
10045 UChar reg;
10046 IRTemp addr = newTemp(Ity_I64);
10047
10048 assign(addr, mkexpr(op2addr));
10049 reg = r1;
10050 do {
10051 IRTemp old = addr;
10052
10053 reg %= 16;
10054 store(mkexpr(addr), get_ar_w0(reg));
10055 addr = newTemp(Ity_I64);
10056 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
10057 reg++;
10058 } while (reg != (r3 + 1));
10059}
10060
10061static HChar *
10062s390_irgen_STAM(UChar r1, UChar r3, IRTemp op2addr)
10063{
10064 s390_irgen_store_ar_multiple(r1, r3, op2addr);
10065
10066 return "stam";
10067}
10068
10069static HChar *
10070s390_irgen_STAMY(UChar r1, UChar r3, IRTemp op2addr)
10071{
10072 s390_irgen_store_ar_multiple(r1, r3, op2addr);
10073
10074 return "stamy";
10075}
10076
10077
10078/* Implementation for 32-bit compare-and-swap */
10079static void
10080s390_irgen_cas_32(UChar r1, UChar r3, IRTemp op2addr)
10081{
10082 IRCAS *cas;
10083 IRTemp op1 = newTemp(Ity_I32);
10084 IRTemp old_mem = newTemp(Ity_I32);
10085 IRTemp op3 = newTemp(Ity_I32);
10086 IRTemp result = newTemp(Ity_I32);
10087 IRTemp nequal = newTemp(Ity_I1);
10088
10089 assign(op1, get_gpr_w1(r1));
10090 assign(op3, get_gpr_w1(r3));
10091
10092 /* The first and second operands are compared. If they are equal,
10093 the third operand is stored at the second- operand location. */
10094 cas = mkIRCAS(IRTemp_INVALID, old_mem,
10095 Iend_BE, mkexpr(op2addr),
10096 NULL, mkexpr(op1), /* expected value */
10097 NULL, mkexpr(op3) /* new value */);
10098 stmt(IRStmt_CAS(cas));
10099
10100 /* Set CC. Operands compared equal -> 0, else 1. */
10101 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(old_mem)));
10102 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
10103
10104 /* If operands were equal (cc == 0) just store the old value op1 in r1.
10105 Otherwise, store the old_value from memory in r1 and yield. */
10106 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
10107 put_gpr_w1(r1, mkite(mkexpr(nequal), mkexpr(old_mem), mkexpr(op1)));
florian6820ba52012-07-26 02:01:50 +000010108 yield_if(mkexpr(nequal));
sewardj2019a972011-03-07 16:04:07 +000010109}
10110
10111static HChar *
10112s390_irgen_CS(UChar r1, UChar r3, IRTemp op2addr)
10113{
10114 s390_irgen_cas_32(r1, r3, op2addr);
10115
10116 return "cs";
10117}
10118
10119static HChar *
10120s390_irgen_CSY(UChar r1, UChar r3, IRTemp op2addr)
10121{
10122 s390_irgen_cas_32(r1, r3, op2addr);
10123
10124 return "csy";
10125}
10126
10127static HChar *
10128s390_irgen_CSG(UChar r1, UChar r3, IRTemp op2addr)
10129{
10130 IRCAS *cas;
10131 IRTemp op1 = newTemp(Ity_I64);
10132 IRTemp old_mem = newTemp(Ity_I64);
10133 IRTemp op3 = newTemp(Ity_I64);
10134 IRTemp result = newTemp(Ity_I64);
10135 IRTemp nequal = newTemp(Ity_I1);
10136
10137 assign(op1, get_gpr_dw0(r1));
10138 assign(op3, get_gpr_dw0(r3));
10139
10140 /* The first and second operands are compared. If they are equal,
10141 the third operand is stored at the second- operand location. */
10142 cas = mkIRCAS(IRTemp_INVALID, old_mem,
10143 Iend_BE, mkexpr(op2addr),
10144 NULL, mkexpr(op1), /* expected value */
10145 NULL, mkexpr(op3) /* new value */);
10146 stmt(IRStmt_CAS(cas));
10147
10148 /* Set CC. Operands compared equal -> 0, else 1. */
10149 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(old_mem)));
10150 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
10151
10152 /* If operands were equal (cc == 0) just store the old value op1 in r1.
10153 Otherwise, store the old_value from memory in r1 and yield. */
10154 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
10155 put_gpr_dw0(r1, mkite(mkexpr(nequal), mkexpr(old_mem), mkexpr(op1)));
florian6820ba52012-07-26 02:01:50 +000010156 yield_if(mkexpr(nequal));
sewardj2019a972011-03-07 16:04:07 +000010157
10158 return "csg";
10159}
10160
florian448cbba2012-06-06 02:26:01 +000010161/* Implementation for 32-bit compare-double-and-swap */
10162static void
10163s390_irgen_cdas_32(UChar r1, UChar r3, IRTemp op2addr)
10164{
10165 IRCAS *cas;
10166 IRTemp op1_high = newTemp(Ity_I32);
10167 IRTemp op1_low = newTemp(Ity_I32);
10168 IRTemp old_mem_high = newTemp(Ity_I32);
10169 IRTemp old_mem_low = newTemp(Ity_I32);
10170 IRTemp op3_high = newTemp(Ity_I32);
10171 IRTemp op3_low = newTemp(Ity_I32);
10172 IRTemp result = newTemp(Ity_I32);
10173 IRTemp nequal = newTemp(Ity_I1);
10174
10175 assign(op1_high, get_gpr_w1(r1));
10176 assign(op1_low, get_gpr_w1(r1+1));
10177 assign(op3_high, get_gpr_w1(r3));
10178 assign(op3_low, get_gpr_w1(r3+1));
10179
10180 /* The first and second operands are compared. If they are equal,
10181 the third operand is stored at the second-operand location. */
10182 cas = mkIRCAS(old_mem_high, old_mem_low,
10183 Iend_BE, mkexpr(op2addr),
10184 mkexpr(op1_high), mkexpr(op1_low), /* expected value */
10185 mkexpr(op3_high), mkexpr(op3_low) /* new value */);
10186 stmt(IRStmt_CAS(cas));
10187
10188 /* Set CC. Operands compared equal -> 0, else 1. */
10189 assign(result, unop(Iop_1Uto32,
10190 binop(Iop_CmpNE32,
10191 binop(Iop_Or32,
10192 binop(Iop_Xor32, mkexpr(op1_high), mkexpr(old_mem_high)),
10193 binop(Iop_Xor32, mkexpr(op1_low), mkexpr(old_mem_low))),
10194 mkU32(0))));
10195
10196 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
10197
10198 /* If operands were equal (cc == 0) just store the old value op1 in r1.
10199 Otherwise, store the old_value from memory in r1 and yield. */
10200 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
10201 put_gpr_w1(r1, mkite(mkexpr(nequal), mkexpr(old_mem_high), mkexpr(op1_high)));
10202 put_gpr_w1(r1+1, mkite(mkexpr(nequal), mkexpr(old_mem_low), mkexpr(op1_low)));
florian6820ba52012-07-26 02:01:50 +000010203 yield_if(mkexpr(nequal));
florian448cbba2012-06-06 02:26:01 +000010204}
10205
10206static HChar *
10207s390_irgen_CDS(UChar r1, UChar r3, IRTemp op2addr)
10208{
10209 s390_irgen_cdas_32(r1, r3, op2addr);
10210
10211 return "cds";
10212}
10213
10214static HChar *
10215s390_irgen_CDSY(UChar r1, UChar r3, IRTemp op2addr)
10216{
10217 s390_irgen_cdas_32(r1, r3, op2addr);
10218
10219 return "cdsy";
10220}
10221
10222static HChar *
10223s390_irgen_CDSG(UChar r1, UChar r3, IRTemp op2addr)
10224{
10225 IRCAS *cas;
10226 IRTemp op1_high = newTemp(Ity_I64);
10227 IRTemp op1_low = newTemp(Ity_I64);
10228 IRTemp old_mem_high = newTemp(Ity_I64);
10229 IRTemp old_mem_low = newTemp(Ity_I64);
10230 IRTemp op3_high = newTemp(Ity_I64);
10231 IRTemp op3_low = newTemp(Ity_I64);
10232 IRTemp result = newTemp(Ity_I64);
10233 IRTemp nequal = newTemp(Ity_I1);
10234
10235 assign(op1_high, get_gpr_dw0(r1));
10236 assign(op1_low, get_gpr_dw0(r1+1));
10237 assign(op3_high, get_gpr_dw0(r3));
10238 assign(op3_low, get_gpr_dw0(r3+1));
10239
10240 /* The first and second operands are compared. If they are equal,
10241 the third operand is stored at the second-operand location. */
10242 cas = mkIRCAS(old_mem_high, old_mem_low,
10243 Iend_BE, mkexpr(op2addr),
10244 mkexpr(op1_high), mkexpr(op1_low), /* expected value */
10245 mkexpr(op3_high), mkexpr(op3_low) /* new value */);
10246 stmt(IRStmt_CAS(cas));
10247
10248 /* Set CC. Operands compared equal -> 0, else 1. */
10249 assign(result, unop(Iop_1Uto64,
10250 binop(Iop_CmpNE64,
10251 binop(Iop_Or64,
10252 binop(Iop_Xor64, mkexpr(op1_high), mkexpr(old_mem_high)),
10253 binop(Iop_Xor64, mkexpr(op1_low), mkexpr(old_mem_low))),
10254 mkU64(0))));
10255
10256 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
10257
10258 /* If operands were equal (cc == 0) just store the old value op1 in r1.
10259 Otherwise, store the old_value from memory in r1 and yield. */
10260 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
10261 put_gpr_dw0(r1, mkite(mkexpr(nequal), mkexpr(old_mem_high), mkexpr(op1_high)));
10262 put_gpr_dw0(r1+1, mkite(mkexpr(nequal), mkexpr(old_mem_low), mkexpr(op1_low)));
florian6820ba52012-07-26 02:01:50 +000010263 yield_if(mkexpr(nequal));
10264
florian448cbba2012-06-06 02:26:01 +000010265 return "cdsg";
10266}
10267
sewardj2019a972011-03-07 16:04:07 +000010268
10269/* Binary floating point */
10270
10271static HChar *
10272s390_irgen_AXBR(UChar r1, UChar r2)
10273{
10274 IRTemp op1 = newTemp(Ity_F128);
10275 IRTemp op2 = newTemp(Ity_F128);
10276 IRTemp result = newTemp(Ity_F128);
floriandb4fcaa2012-09-05 19:54:08 +000010277 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000010278
10279 assign(op1, get_fpr_pair(r1));
10280 assign(op2, get_fpr_pair(r2));
floriandb4fcaa2012-09-05 19:54:08 +000010281 assign(result, triop(Iop_AddF128, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +000010282 mkexpr(op2)));
10283 put_fpr_pair(r1, mkexpr(result));
10284
10285 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
10286
10287 return "axbr";
10288}
10289
10290/* The result of a Iop_CmdFxx operation is a condition code. It is
10291 encoded using the values defined in type IRCmpFxxResult.
10292 Before we can store the condition code into the guest state (or do
10293 anything else with it for that matter) we need to convert it to
10294 the encoding that s390 uses. This is what this function does.
10295
10296 s390 VEX b6 b2 b0 cc.1 cc.0
10297 0 0x40 EQ 1 0 0 0 0
10298 1 0x01 LT 0 0 1 0 1
10299 2 0x00 GT 0 0 0 1 0
10300 3 0x45 Unordered 1 1 1 1 1
10301
10302 The following bits from the VEX encoding are interesting:
10303 b0, b2, b6 with b0 being the LSB. We observe:
10304
10305 cc.0 = b0;
10306 cc.1 = b2 | (~b0 & ~b6)
10307
10308 with cc being the s390 condition code.
10309*/
10310static IRExpr *
10311convert_vex_fpcc_to_s390(IRTemp vex_cc)
10312{
10313 IRTemp cc0 = newTemp(Ity_I32);
10314 IRTemp cc1 = newTemp(Ity_I32);
10315 IRTemp b0 = newTemp(Ity_I32);
10316 IRTemp b2 = newTemp(Ity_I32);
10317 IRTemp b6 = newTemp(Ity_I32);
10318
10319 assign(b0, binop(Iop_And32, mkexpr(vex_cc), mkU32(1)));
10320 assign(b2, binop(Iop_And32, binop(Iop_Shr32, mkexpr(vex_cc), mkU8(2)),
10321 mkU32(1)));
10322 assign(b6, binop(Iop_And32, binop(Iop_Shr32, mkexpr(vex_cc), mkU8(6)),
10323 mkU32(1)));
10324
10325 assign(cc0, mkexpr(b0));
10326 assign(cc1, binop(Iop_Or32, mkexpr(b2),
10327 binop(Iop_And32,
10328 binop(Iop_Sub32, mkU32(1), mkexpr(b0)), /* ~b0 */
10329 binop(Iop_Sub32, mkU32(1), mkexpr(b6)) /* ~b6 */
10330 )));
10331
10332 return binop(Iop_Or32, mkexpr(cc0), binop(Iop_Shl32, mkexpr(cc1), mkU8(1)));
10333}
10334
10335static HChar *
10336s390_irgen_CEBR(UChar r1, UChar r2)
10337{
10338 IRTemp op1 = newTemp(Ity_F32);
10339 IRTemp op2 = newTemp(Ity_F32);
10340 IRTemp cc_vex = newTemp(Ity_I32);
10341 IRTemp cc_s390 = newTemp(Ity_I32);
10342
10343 assign(op1, get_fpr_w0(r1));
10344 assign(op2, get_fpr_w0(r2));
10345 assign(cc_vex, binop(Iop_CmpF32, mkexpr(op1), mkexpr(op2)));
10346
10347 assign(cc_s390, convert_vex_fpcc_to_s390(cc_vex));
10348 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
10349
10350 return "cebr";
10351}
10352
10353static HChar *
10354s390_irgen_CDBR(UChar r1, UChar r2)
10355{
10356 IRTemp op1 = newTemp(Ity_F64);
10357 IRTemp op2 = newTemp(Ity_F64);
10358 IRTemp cc_vex = newTemp(Ity_I32);
10359 IRTemp cc_s390 = newTemp(Ity_I32);
10360
10361 assign(op1, get_fpr_dw0(r1));
10362 assign(op2, get_fpr_dw0(r2));
10363 assign(cc_vex, binop(Iop_CmpF64, mkexpr(op1), mkexpr(op2)));
10364
10365 assign(cc_s390, convert_vex_fpcc_to_s390(cc_vex));
10366 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
10367
10368 return "cdbr";
10369}
10370
10371static HChar *
10372s390_irgen_CXBR(UChar r1, UChar r2)
10373{
10374 IRTemp op1 = newTemp(Ity_F128);
10375 IRTemp op2 = newTemp(Ity_F128);
10376 IRTemp cc_vex = newTemp(Ity_I32);
10377 IRTemp cc_s390 = newTemp(Ity_I32);
10378
10379 assign(op1, get_fpr_pair(r1));
10380 assign(op2, get_fpr_pair(r2));
10381 assign(cc_vex, binop(Iop_CmpF128, mkexpr(op1), mkexpr(op2)));
10382
10383 assign(cc_s390, convert_vex_fpcc_to_s390(cc_vex));
10384 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
10385
10386 return "cxbr";
10387}
10388
10389static HChar *
10390s390_irgen_CEB(UChar r1, IRTemp op2addr)
10391{
10392 IRTemp op1 = newTemp(Ity_F32);
10393 IRTemp op2 = newTemp(Ity_F32);
10394 IRTemp cc_vex = newTemp(Ity_I32);
10395 IRTemp cc_s390 = newTemp(Ity_I32);
10396
10397 assign(op1, get_fpr_w0(r1));
10398 assign(op2, load(Ity_F32, mkexpr(op2addr)));
10399 assign(cc_vex, binop(Iop_CmpF32, mkexpr(op1), mkexpr(op2)));
10400
10401 assign(cc_s390, convert_vex_fpcc_to_s390(cc_vex));
10402 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
10403
10404 return "ceb";
10405}
10406
10407static HChar *
10408s390_irgen_CDB(UChar r1, IRTemp op2addr)
10409{
10410 IRTemp op1 = newTemp(Ity_F64);
10411 IRTemp op2 = newTemp(Ity_F64);
10412 IRTemp cc_vex = newTemp(Ity_I32);
10413 IRTemp cc_s390 = newTemp(Ity_I32);
10414
10415 assign(op1, get_fpr_dw0(r1));
10416 assign(op2, load(Ity_F64, mkexpr(op2addr)));
10417 assign(cc_vex, binop(Iop_CmpF64, mkexpr(op1), mkexpr(op2)));
10418
10419 assign(cc_s390, convert_vex_fpcc_to_s390(cc_vex));
10420 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
10421
10422 return "cdb";
10423}
10424
10425static HChar *
florian4b8efad2012-09-02 18:07:08 +000010426s390_irgen_CXFBR(UChar m3 __attribute__((unused)),
10427 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000010428{
10429 IRTemp op2 = newTemp(Ity_I32);
10430
10431 assign(op2, get_gpr_w1(r2));
10432 put_fpr_pair(r1, unop(Iop_I32StoF128, mkexpr(op2)));
10433
10434 return "cxfbr";
10435}
10436
10437static HChar *
floriand2129202012-09-01 20:01:39 +000010438s390_irgen_CXLFBR(UChar m3 __attribute__((unused)),
10439 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
florian1c8f7ff2012-09-01 00:12:11 +000010440{
floriane75dafa2012-09-01 17:54:09 +000010441 if (! s390_host_has_fpext) {
10442 emulation_failure(EmFail_S390X_fpext);
10443 } else {
10444 IRTemp op2 = newTemp(Ity_I32);
florian1c8f7ff2012-09-01 00:12:11 +000010445
floriane75dafa2012-09-01 17:54:09 +000010446 assign(op2, get_gpr_w1(r2));
10447 put_fpr_pair(r1, unop(Iop_I32UtoF128, mkexpr(op2)));
10448 }
florian1c8f7ff2012-09-01 00:12:11 +000010449 return "cxlfbr";
10450}
10451
10452
10453static HChar *
florian4b8efad2012-09-02 18:07:08 +000010454s390_irgen_CXGBR(UChar m3 __attribute__((unused)),
10455 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000010456{
10457 IRTemp op2 = newTemp(Ity_I64);
10458
10459 assign(op2, get_gpr_dw0(r2));
10460 put_fpr_pair(r1, unop(Iop_I64StoF128, mkexpr(op2)));
10461
10462 return "cxgbr";
10463}
10464
10465static HChar *
floriand2129202012-09-01 20:01:39 +000010466s390_irgen_CXLGBR(UChar m3 __attribute__((unused)),
10467 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
florian1c8f7ff2012-09-01 00:12:11 +000010468{
floriane75dafa2012-09-01 17:54:09 +000010469 if (! s390_host_has_fpext) {
10470 emulation_failure(EmFail_S390X_fpext);
10471 } else {
10472 IRTemp op2 = newTemp(Ity_I64);
florian1c8f7ff2012-09-01 00:12:11 +000010473
floriane75dafa2012-09-01 17:54:09 +000010474 assign(op2, get_gpr_dw0(r2));
10475 put_fpr_pair(r1, unop(Iop_I64UtoF128, mkexpr(op2)));
10476 }
florian1c8f7ff2012-09-01 00:12:11 +000010477 return "cxlgbr";
10478}
10479
10480static HChar *
florian4b8efad2012-09-02 18:07:08 +000010481s390_irgen_CFXBR(UChar m3, UChar m4 __attribute__((unused)),
10482 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000010483{
10484 IRTemp op = newTemp(Ity_F128);
10485 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +000010486 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +000010487
10488 assign(op, get_fpr_pair(r2));
florian19e00772012-09-06 03:13:22 +000010489 assign(result, binop(Iop_F128toI32S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +000010490 mkexpr(op)));
10491 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +000010492 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_INT_32, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +000010493
10494 return "cfxbr";
10495}
10496
10497static HChar *
florian1c8f7ff2012-09-01 00:12:11 +000010498s390_irgen_CLFXBR(UChar m3, UChar m4 __attribute__((unused)),
10499 UChar r1, UChar r2)
10500{
floriane75dafa2012-09-01 17:54:09 +000010501 if (! s390_host_has_fpext) {
10502 emulation_failure(EmFail_S390X_fpext);
10503 } else {
10504 IRTemp op = newTemp(Ity_F128);
10505 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +000010506 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +000010507
floriane75dafa2012-09-01 17:54:09 +000010508 assign(op, get_fpr_pair(r2));
florian19e00772012-09-06 03:13:22 +000010509 assign(result, binop(Iop_F128toI32U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +000010510 mkexpr(op)));
10511 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +000010512 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_UINT_32, op, rounding_mode);
floriane75dafa2012-09-01 17:54:09 +000010513 }
florian1c8f7ff2012-09-01 00:12:11 +000010514 return "clfxbr";
10515}
10516
10517
10518static HChar *
florian4b8efad2012-09-02 18:07:08 +000010519s390_irgen_CGXBR(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_I64);
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_F128toI64S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +000010528 mkexpr(op)));
10529 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +000010530 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_INT_64, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +000010531
10532 return "cgxbr";
10533}
10534
10535static HChar *
florian1c8f7ff2012-09-01 00:12:11 +000010536s390_irgen_CLGXBR(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_I64);
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_F128toI64U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +000010548 mkexpr(op)));
10549 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +000010550 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_UINT_64, op,
10551 rounding_mode);
floriane75dafa2012-09-01 17:54:09 +000010552 }
florian1c8f7ff2012-09-01 00:12:11 +000010553 return "clgxbr";
10554}
10555
10556static HChar *
sewardj2019a972011-03-07 16:04:07 +000010557s390_irgen_DXBR(UChar r1, UChar r2)
10558{
10559 IRTemp op1 = newTemp(Ity_F128);
10560 IRTemp op2 = newTemp(Ity_F128);
10561 IRTemp result = newTemp(Ity_F128);
floriandb4fcaa2012-09-05 19:54:08 +000010562 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000010563
10564 assign(op1, get_fpr_pair(r1));
10565 assign(op2, get_fpr_pair(r2));
floriandb4fcaa2012-09-05 19:54:08 +000010566 assign(result, triop(Iop_DivF128, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +000010567 mkexpr(op2)));
10568 put_fpr_pair(r1, mkexpr(result));
10569
10570 return "dxbr";
10571}
10572
10573static HChar *
10574s390_irgen_LTXBR(UChar r1, UChar r2)
10575{
10576 IRTemp result = newTemp(Ity_F128);
10577
10578 assign(result, get_fpr_pair(r2));
10579 put_fpr_pair(r1, mkexpr(result));
10580 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
10581
10582 return "ltxbr";
10583}
10584
10585static HChar *
10586s390_irgen_LCXBR(UChar r1, UChar r2)
10587{
10588 IRTemp result = newTemp(Ity_F128);
10589
10590 assign(result, unop(Iop_NegF128, get_fpr_pair(r2)));
10591 put_fpr_pair(r1, mkexpr(result));
10592 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
10593
10594 return "lcxbr";
10595}
10596
10597static HChar *
10598s390_irgen_LXDBR(UChar r1, UChar r2)
10599{
10600 IRTemp op = newTemp(Ity_F64);
10601
10602 assign(op, get_fpr_dw0(r2));
10603 put_fpr_pair(r1, unop(Iop_F64toF128, mkexpr(op)));
10604
10605 return "lxdbr";
10606}
10607
10608static HChar *
10609s390_irgen_LXEBR(UChar r1, UChar r2)
10610{
10611 IRTemp op = newTemp(Ity_F32);
10612
10613 assign(op, get_fpr_w0(r2));
10614 put_fpr_pair(r1, unop(Iop_F32toF128, mkexpr(op)));
10615
10616 return "lxebr";
10617}
10618
10619static HChar *
10620s390_irgen_LXDB(UChar r1, IRTemp op2addr)
10621{
10622 IRTemp op = newTemp(Ity_F64);
10623
10624 assign(op, load(Ity_F64, mkexpr(op2addr)));
10625 put_fpr_pair(r1, unop(Iop_F64toF128, mkexpr(op)));
10626
10627 return "lxdb";
10628}
10629
10630static HChar *
10631s390_irgen_LXEB(UChar r1, IRTemp op2addr)
10632{
10633 IRTemp op = newTemp(Ity_F32);
10634
10635 assign(op, load(Ity_F32, mkexpr(op2addr)));
10636 put_fpr_pair(r1, unop(Iop_F32toF128, mkexpr(op)));
10637
10638 return "lxeb";
10639}
10640
10641static HChar *
10642s390_irgen_LNEBR(UChar r1, UChar r2)
10643{
10644 IRTemp result = newTemp(Ity_F32);
10645
10646 assign(result, unop(Iop_NegF32, unop(Iop_AbsF32, get_fpr_w0(r2))));
10647 put_fpr_w0(r1, mkexpr(result));
10648 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_32, result);
10649
10650 return "lnebr";
10651}
10652
10653static HChar *
10654s390_irgen_LNDBR(UChar r1, UChar r2)
10655{
10656 IRTemp result = newTemp(Ity_F64);
10657
10658 assign(result, unop(Iop_NegF64, unop(Iop_AbsF64, get_fpr_dw0(r2))));
10659 put_fpr_dw0(r1, mkexpr(result));
10660 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_64, result);
10661
10662 return "lndbr";
10663}
10664
10665static HChar *
10666s390_irgen_LNXBR(UChar r1, UChar r2)
10667{
10668 IRTemp result = newTemp(Ity_F128);
10669
10670 assign(result, unop(Iop_NegF128, unop(Iop_AbsF128, get_fpr_pair(r2))));
10671 put_fpr_pair(r1, mkexpr(result));
10672 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
10673
10674 return "lnxbr";
10675}
10676
10677static HChar *
10678s390_irgen_LPEBR(UChar r1, UChar r2)
10679{
10680 IRTemp result = newTemp(Ity_F32);
10681
10682 assign(result, unop(Iop_AbsF32, get_fpr_w0(r2)));
10683 put_fpr_w0(r1, mkexpr(result));
10684 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_32, result);
10685
10686 return "lpebr";
10687}
10688
10689static HChar *
10690s390_irgen_LPDBR(UChar r1, UChar r2)
10691{
10692 IRTemp result = newTemp(Ity_F64);
10693
10694 assign(result, unop(Iop_AbsF64, get_fpr_dw0(r2)));
10695 put_fpr_dw0(r1, mkexpr(result));
10696 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_64, result);
10697
10698 return "lpdbr";
10699}
10700
10701static HChar *
10702s390_irgen_LPXBR(UChar r1, UChar r2)
10703{
10704 IRTemp result = newTemp(Ity_F128);
10705
10706 assign(result, unop(Iop_AbsF128, get_fpr_pair(r2)));
10707 put_fpr_pair(r1, mkexpr(result));
10708 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
10709
10710 return "lpxbr";
10711}
10712
10713static HChar *
florian4b8efad2012-09-02 18:07:08 +000010714s390_irgen_LDXBR(UChar m3, UChar m4 __attribute__((unused)),
10715 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000010716{
florian12b0bca2012-09-05 20:05:20 +000010717 if (! s390_host_has_fpext && m3 != S390_ROUND_PER_FPC) {
10718 emulation_warning(EmWarn_S390X_fpext_rounding);
10719 m3 = S390_ROUND_PER_FPC;
10720 }
sewardj2019a972011-03-07 16:04:07 +000010721 IRTemp result = newTemp(Ity_F64);
10722
floriandb4fcaa2012-09-05 19:54:08 +000010723 assign(result, binop(Iop_F128toF64, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +000010724 get_fpr_pair(r2)));
sewardj2019a972011-03-07 16:04:07 +000010725 put_fpr_dw0(r1, mkexpr(result));
10726
10727 return "ldxbr";
10728}
10729
10730static HChar *
florian4b8efad2012-09-02 18:07:08 +000010731s390_irgen_LEXBR(UChar m3, UChar m4 __attribute__((unused)),
10732 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000010733{
florian12b0bca2012-09-05 20:05:20 +000010734 if (! s390_host_has_fpext && m3 != S390_ROUND_PER_FPC) {
10735 emulation_warning(EmWarn_S390X_fpext_rounding);
10736 m3 = S390_ROUND_PER_FPC;
10737 }
sewardj2019a972011-03-07 16:04:07 +000010738 IRTemp result = newTemp(Ity_F32);
10739
floriandb4fcaa2012-09-05 19:54:08 +000010740 assign(result, binop(Iop_F128toF32, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +000010741 get_fpr_pair(r2)));
sewardj2019a972011-03-07 16:04:07 +000010742 put_fpr_w0(r1, mkexpr(result));
10743
10744 return "lexbr";
10745}
10746
10747static HChar *
10748s390_irgen_MXBR(UChar r1, UChar r2)
10749{
10750 IRTemp op1 = newTemp(Ity_F128);
10751 IRTemp op2 = newTemp(Ity_F128);
10752 IRTemp result = newTemp(Ity_F128);
floriandb4fcaa2012-09-05 19:54:08 +000010753 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000010754
10755 assign(op1, get_fpr_pair(r1));
10756 assign(op2, get_fpr_pair(r2));
floriandb4fcaa2012-09-05 19:54:08 +000010757 assign(result, triop(Iop_MulF128, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +000010758 mkexpr(op2)));
10759 put_fpr_pair(r1, mkexpr(result));
10760
10761 return "mxbr";
10762}
10763
10764static HChar *
10765s390_irgen_MAEBR(UChar r1, UChar r3, UChar r2)
10766{
floriandb4fcaa2012-09-05 19:54:08 +000010767 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_ROUND_PER_FPC);
florian847684d2012-09-05 04:19:09 +000010768
floriandb4fcaa2012-09-05 19:54:08 +000010769 put_fpr_w0(r1, qop(Iop_MAddF32, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +000010770 get_fpr_w0(r1), get_fpr_w0(r2), get_fpr_w0(r3)));
10771
10772 return "maebr";
10773}
10774
10775static HChar *
10776s390_irgen_MADBR(UChar r1, UChar r3, UChar r2)
10777{
floriandb4fcaa2012-09-05 19:54:08 +000010778 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_ROUND_PER_FPC);
florian847684d2012-09-05 04:19:09 +000010779
floriandb4fcaa2012-09-05 19:54:08 +000010780 put_fpr_dw0(r1, qop(Iop_MAddF64, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +000010781 get_fpr_dw0(r1), get_fpr_dw0(r2), get_fpr_dw0(r3)));
10782
10783 return "madbr";
10784}
10785
10786static HChar *
10787s390_irgen_MAEB(UChar r3, IRTemp op2addr, UChar r1)
10788{
10789 IRExpr *op2 = load(Ity_F32, mkexpr(op2addr));
floriandb4fcaa2012-09-05 19:54:08 +000010790 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000010791
floriandb4fcaa2012-09-05 19:54:08 +000010792 put_fpr_w0(r1, qop(Iop_MAddF32, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +000010793 get_fpr_w0(r1), op2, get_fpr_w0(r3)));
10794
10795 return "maeb";
10796}
10797
10798static HChar *
10799s390_irgen_MADB(UChar r3, IRTemp op2addr, UChar r1)
10800{
10801 IRExpr *op2 = load(Ity_F64, mkexpr(op2addr));
floriandb4fcaa2012-09-05 19:54:08 +000010802 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000010803
floriandb4fcaa2012-09-05 19:54:08 +000010804 put_fpr_dw0(r1, qop(Iop_MAddF64, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +000010805 get_fpr_dw0(r1), op2, get_fpr_dw0(r3)));
10806
10807 return "madb";
10808}
10809
10810static HChar *
10811s390_irgen_MSEBR(UChar r1, UChar r3, UChar r2)
10812{
floriandb4fcaa2012-09-05 19:54:08 +000010813 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_ROUND_PER_FPC);
florian847684d2012-09-05 04:19:09 +000010814
floriandb4fcaa2012-09-05 19:54:08 +000010815 put_fpr_w0(r1, qop(Iop_MSubF32, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +000010816 get_fpr_w0(r1), get_fpr_w0(r2), get_fpr_w0(r3)));
10817
10818 return "msebr";
10819}
10820
10821static HChar *
10822s390_irgen_MSDBR(UChar r1, UChar r3, UChar r2)
10823{
floriandb4fcaa2012-09-05 19:54:08 +000010824 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_ROUND_PER_FPC);
florian847684d2012-09-05 04:19:09 +000010825
floriandb4fcaa2012-09-05 19:54:08 +000010826 put_fpr_dw0(r1, qop(Iop_MSubF64, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +000010827 get_fpr_dw0(r1), get_fpr_dw0(r2), get_fpr_dw0(r3)));
10828
10829 return "msdbr";
10830}
10831
10832static HChar *
10833s390_irgen_MSEB(UChar r3, IRTemp op2addr, UChar r1)
10834{
10835 IRExpr *op2 = load(Ity_F32, mkexpr(op2addr));
floriandb4fcaa2012-09-05 19:54:08 +000010836 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000010837
floriandb4fcaa2012-09-05 19:54:08 +000010838 put_fpr_w0(r1, qop(Iop_MSubF32, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +000010839 get_fpr_w0(r1), op2, get_fpr_w0(r3)));
10840
10841 return "mseb";
10842}
10843
10844static HChar *
10845s390_irgen_MSDB(UChar r3, IRTemp op2addr, UChar r1)
10846{
10847 IRExpr *op2 = load(Ity_F64, mkexpr(op2addr));
floriandb4fcaa2012-09-05 19:54:08 +000010848 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000010849
floriandb4fcaa2012-09-05 19:54:08 +000010850 put_fpr_dw0(r1, qop(Iop_MSubF64, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +000010851 get_fpr_dw0(r1), op2, get_fpr_dw0(r3)));
10852
10853 return "msdb";
10854}
10855
10856static HChar *
10857s390_irgen_SQEBR(UChar r1, UChar r2)
10858{
10859 IRTemp result = newTemp(Ity_F32);
floriandb4fcaa2012-09-05 19:54:08 +000010860 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000010861
floriandb4fcaa2012-09-05 19:54:08 +000010862 assign(result, binop(Iop_SqrtF32, mkexpr(rounding_mode), get_fpr_w0(r2)));
sewardj2019a972011-03-07 16:04:07 +000010863 put_fpr_w0(r1, mkexpr(result));
10864
10865 return "sqebr";
10866}
10867
10868static HChar *
10869s390_irgen_SQDBR(UChar r1, UChar r2)
10870{
10871 IRTemp result = newTemp(Ity_F64);
floriandb4fcaa2012-09-05 19:54:08 +000010872 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000010873
floriandb4fcaa2012-09-05 19:54:08 +000010874 assign(result, binop(Iop_SqrtF64, mkexpr(rounding_mode), get_fpr_dw0(r2)));
sewardj2019a972011-03-07 16:04:07 +000010875 put_fpr_dw0(r1, mkexpr(result));
10876
10877 return "sqdbr";
10878}
10879
10880static HChar *
10881s390_irgen_SQXBR(UChar r1, UChar r2)
10882{
10883 IRTemp result = newTemp(Ity_F128);
floriandb4fcaa2012-09-05 19:54:08 +000010884 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000010885
floriandb4fcaa2012-09-05 19:54:08 +000010886 assign(result, binop(Iop_SqrtF128, mkexpr(rounding_mode),
10887 get_fpr_pair(r2)));
sewardj2019a972011-03-07 16:04:07 +000010888 put_fpr_pair(r1, mkexpr(result));
10889
10890 return "sqxbr";
10891}
10892
10893static HChar *
10894s390_irgen_SQEB(UChar r1, IRTemp op2addr)
10895{
10896 IRTemp op = newTemp(Ity_F32);
floriandb4fcaa2012-09-05 19:54:08 +000010897 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000010898
10899 assign(op, load(Ity_F32, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +000010900 put_fpr_w0(r1, binop(Iop_SqrtF32, mkexpr(rounding_mode), mkexpr(op)));
sewardj2019a972011-03-07 16:04:07 +000010901
10902 return "sqeb";
10903}
10904
10905static HChar *
10906s390_irgen_SQDB(UChar r1, IRTemp op2addr)
10907{
10908 IRTemp op = newTemp(Ity_F64);
floriandb4fcaa2012-09-05 19:54:08 +000010909 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000010910
10911 assign(op, load(Ity_F64, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +000010912 put_fpr_dw0(r1, binop(Iop_SqrtF64, mkexpr(rounding_mode), mkexpr(op)));
sewardj2019a972011-03-07 16:04:07 +000010913
10914 return "sqdb";
10915}
10916
10917static HChar *
10918s390_irgen_SXBR(UChar r1, UChar r2)
10919{
10920 IRTemp op1 = newTemp(Ity_F128);
10921 IRTemp op2 = newTemp(Ity_F128);
10922 IRTemp result = newTemp(Ity_F128);
floriandb4fcaa2012-09-05 19:54:08 +000010923 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000010924
10925 assign(op1, get_fpr_pair(r1));
10926 assign(op2, get_fpr_pair(r2));
floriandb4fcaa2012-09-05 19:54:08 +000010927 assign(result, triop(Iop_SubF128, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +000010928 mkexpr(op2)));
10929 put_fpr_pair(r1, mkexpr(result));
10930 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
10931
10932 return "sxbr";
10933}
10934
10935static HChar *
10936s390_irgen_TCEB(UChar r1, IRTemp op2addr)
10937{
10938 IRTemp value = newTemp(Ity_F32);
10939
10940 assign(value, get_fpr_w0(r1));
10941
10942 s390_cc_thunk_putFZ(S390_CC_OP_BFP_TDC_32, value, op2addr);
10943
10944 return "tceb";
10945}
10946
10947static HChar *
10948s390_irgen_TCDB(UChar r1, IRTemp op2addr)
10949{
10950 IRTemp value = newTemp(Ity_F64);
10951
10952 assign(value, get_fpr_dw0(r1));
10953
10954 s390_cc_thunk_putFZ(S390_CC_OP_BFP_TDC_64, value, op2addr);
10955
10956 return "tcdb";
10957}
10958
10959static HChar *
10960s390_irgen_TCXB(UChar r1, IRTemp op2addr)
10961{
10962 IRTemp value = newTemp(Ity_F128);
10963
10964 assign(value, get_fpr_pair(r1));
10965
10966 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_TDC_128, value, op2addr);
10967
10968 return "tcxb";
10969}
10970
10971static HChar *
10972s390_irgen_LCDFR(UChar r1, UChar r2)
10973{
10974 IRTemp result = newTemp(Ity_F64);
10975
10976 assign(result, unop(Iop_NegF64, get_fpr_dw0(r2)));
10977 put_fpr_dw0(r1, mkexpr(result));
10978
10979 return "lcdfr";
10980}
10981
10982static HChar *
10983s390_irgen_LNDFR(UChar r1, UChar r2)
10984{
10985 IRTemp result = newTemp(Ity_F64);
10986
10987 assign(result, unop(Iop_NegF64, unop(Iop_AbsF64, get_fpr_dw0(r2))));
10988 put_fpr_dw0(r1, mkexpr(result));
10989
10990 return "lndfr";
10991}
10992
10993static HChar *
10994s390_irgen_LPDFR(UChar r1, UChar r2)
10995{
10996 IRTemp result = newTemp(Ity_F64);
10997
10998 assign(result, unop(Iop_AbsF64, get_fpr_dw0(r2)));
10999 put_fpr_dw0(r1, mkexpr(result));
11000
11001 return "lpdfr";
11002}
11003
11004static HChar *
11005s390_irgen_LDGR(UChar r1, UChar r2)
11006{
11007 put_fpr_dw0(r1, unop(Iop_ReinterpI64asF64, get_gpr_dw0(r2)));
11008
11009 return "ldgr";
11010}
11011
11012static HChar *
11013s390_irgen_LGDR(UChar r1, UChar r2)
11014{
11015 put_gpr_dw0(r1, unop(Iop_ReinterpF64asI64, get_fpr_dw0(r2)));
11016
11017 return "lgdr";
11018}
11019
11020
11021static HChar *
11022s390_irgen_CPSDR(UChar r3, UChar r1, UChar r2)
11023{
11024 IRTemp sign = newTemp(Ity_I64);
11025 IRTemp value = newTemp(Ity_I64);
11026
11027 assign(sign, binop(Iop_And64, unop(Iop_ReinterpF64asI64, get_fpr_dw0(r3)),
11028 mkU64(1ULL << 63)));
11029 assign(value, binop(Iop_And64, unop(Iop_ReinterpF64asI64, get_fpr_dw0(r2)),
11030 mkU64((1ULL << 63) - 1)));
11031 put_fpr_dw0(r1, unop(Iop_ReinterpI64asF64, binop(Iop_Or64, mkexpr(value),
11032 mkexpr(sign))));
11033
11034 return "cpsdr";
11035}
11036
11037
sewardj2019a972011-03-07 16:04:07 +000011038static IRExpr *
11039s390_call_cvb(IRExpr *in)
11040{
11041 IRExpr **args, *call;
11042
11043 args = mkIRExprVec_1(in);
11044 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
11045 "s390_do_cvb", &s390_do_cvb, args);
11046
11047 /* Nothing is excluded from definedness checking. */
11048 call->Iex.CCall.cee->mcx_mask = 0;
11049
11050 return call;
11051}
11052
11053static HChar *
11054s390_irgen_CVB(UChar r1, IRTemp op2addr)
11055{
11056 put_gpr_w1(r1, s390_call_cvb(load(Ity_I64, mkexpr(op2addr))));
11057
11058 return "cvb";
11059}
11060
11061static HChar *
11062s390_irgen_CVBY(UChar r1, IRTemp op2addr)
11063{
11064 put_gpr_w1(r1, s390_call_cvb(load(Ity_I64, mkexpr(op2addr))));
11065
11066 return "cvby";
11067}
11068
11069
sewardj2019a972011-03-07 16:04:07 +000011070static IRExpr *
11071s390_call_cvd(IRExpr *in)
11072{
11073 IRExpr **args, *call;
11074
11075 args = mkIRExprVec_1(in);
11076 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
11077 "s390_do_cvd", &s390_do_cvd, args);
11078
11079 /* Nothing is excluded from definedness checking. */
11080 call->Iex.CCall.cee->mcx_mask = 0;
11081
11082 return call;
11083}
11084
11085static HChar *
11086s390_irgen_CVD(UChar r1, IRTemp op2addr)
11087{
florian11b8ee82012-08-06 13:35:33 +000011088 store(mkexpr(op2addr), s390_call_cvd(unop(Iop_32Uto64, get_gpr_w1(r1))));
sewardj2019a972011-03-07 16:04:07 +000011089
11090 return "cvd";
11091}
11092
11093static HChar *
11094s390_irgen_CVDY(UChar r1, IRTemp op2addr)
11095{
11096 store(mkexpr(op2addr), s390_call_cvd(get_gpr_w1(r1)));
11097
11098 return "cvdy";
11099}
11100
11101static HChar *
11102s390_irgen_FLOGR(UChar r1, UChar r2)
11103{
11104 IRTemp input = newTemp(Ity_I64);
11105 IRTemp not_zero = newTemp(Ity_I64);
11106 IRTemp tmpnum = newTemp(Ity_I64);
11107 IRTemp num = newTemp(Ity_I64);
11108 IRTemp shift_amount = newTemp(Ity_I8);
11109
11110 /* We use the "count leading zeroes" operator because the number of
11111 leading zeroes is identical with the bit position of the first '1' bit.
11112 However, that operator does not work when the input value is zero.
11113 Therefore, we set the LSB of the input value to 1 and use Clz64 on
11114 the modified value. If input == 0, then the result is 64. Otherwise,
11115 the result of Clz64 is what we want. */
11116
11117 assign(input, get_gpr_dw0(r2));
11118 assign(not_zero, binop(Iop_Or64, mkexpr(input), mkU64(1)));
11119 assign(tmpnum, unop(Iop_Clz64, mkexpr(not_zero)));
11120
11121 /* num = (input == 0) ? 64 : tmpnum */
11122 assign(num, mkite(binop(Iop_CmpEQ64, mkexpr(input), mkU64(0)),
11123 /* == 0 */ mkU64(64),
11124 /* != 0 */ mkexpr(tmpnum)));
11125
11126 put_gpr_dw0(r1, mkexpr(num));
11127
11128 /* Set the leftmost '1' bit of the input value to zero. The general scheme
11129 is to first shift the input value by NUM + 1 bits to the left which
11130 causes the leftmost '1' bit to disappear. Then we shift logically to
11131 the right by NUM + 1 bits. Because the semantics of Iop_Shl64 and
11132 Iop_Shr64 are undefined if the shift-amount is greater than or equal to
11133 the width of the value-to-be-shifted, we need to special case
11134 NUM + 1 >= 64. This is equivalent to INPUT != 0 && INPUT != 1.
11135 For both such INPUT values the result will be 0. */
11136
11137 assign(shift_amount, unop(Iop_64to8, binop(Iop_Add64, mkexpr(num),
11138 mkU64(1))));
11139
11140 put_gpr_dw0(r1 + 1,
florian6ad49522011-09-09 02:38:55 +000011141 mkite(binop(Iop_CmpLE64U, mkexpr(input), mkU64(1)),
11142 /* == 0 || == 1*/ mkU64(0),
11143 /* otherwise */
11144 binop(Iop_Shr64,
11145 binop(Iop_Shl64, mkexpr(input),
11146 mkexpr(shift_amount)),
11147 mkexpr(shift_amount))));
sewardj2019a972011-03-07 16:04:07 +000011148
11149 /* Compare the original value as an unsigned integer with 0. */
11150 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, input,
11151 mktemp(Ity_I64, mkU64(0)), False);
11152
11153 return "flogr";
11154}
11155
sewardj1e5fea62011-05-17 16:18:36 +000011156static HChar *
11157s390_irgen_STCK(IRTemp op2addr)
11158{
11159 IRDirty *d;
11160 IRTemp cc = newTemp(Ity_I64);
11161
11162 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STCK",
11163 &s390x_dirtyhelper_STCK,
11164 mkIRExprVec_1(mkexpr(op2addr)));
11165 d->mFx = Ifx_Write;
11166 d->mAddr = mkexpr(op2addr);
11167 d->mSize = 8;
11168 stmt(IRStmt_Dirty(d));
11169 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
11170 mkexpr(cc), mkU64(0), mkU64(0));
11171 return "stck";
11172}
11173
11174static HChar *
11175s390_irgen_STCKF(IRTemp op2addr)
11176{
florianc5c669b2012-08-26 14:32:28 +000011177 if (! s390_host_has_stckf) {
floriane75dafa2012-09-01 17:54:09 +000011178 emulation_failure(EmFail_S390X_stckf);
florianc5c669b2012-08-26 14:32:28 +000011179 } else {
11180 IRTemp cc = newTemp(Ity_I64);
sewardj1e5fea62011-05-17 16:18:36 +000011181
florianc5c669b2012-08-26 14:32:28 +000011182 IRDirty *d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STCKF",
11183 &s390x_dirtyhelper_STCKF,
11184 mkIRExprVec_1(mkexpr(op2addr)));
11185 d->mFx = Ifx_Write;
11186 d->mAddr = mkexpr(op2addr);
11187 d->mSize = 8;
11188 stmt(IRStmt_Dirty(d));
11189 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
11190 mkexpr(cc), mkU64(0), mkU64(0));
11191 }
sewardj1e5fea62011-05-17 16:18:36 +000011192 return "stckf";
11193}
11194
11195static HChar *
11196s390_irgen_STCKE(IRTemp op2addr)
11197{
11198 IRDirty *d;
11199 IRTemp cc = newTemp(Ity_I64);
11200
11201 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STCKE",
11202 &s390x_dirtyhelper_STCKE,
11203 mkIRExprVec_1(mkexpr(op2addr)));
11204 d->mFx = Ifx_Write;
11205 d->mAddr = mkexpr(op2addr);
11206 d->mSize = 16;
11207 stmt(IRStmt_Dirty(d));
11208 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
11209 mkexpr(cc), mkU64(0), mkU64(0));
11210 return "stcke";
11211}
11212
florian933065d2011-07-11 01:48:02 +000011213static HChar *
11214s390_irgen_STFLE(IRTemp op2addr)
11215{
florian4e0083e2012-08-26 03:41:56 +000011216 if (! s390_host_has_stfle) {
floriane75dafa2012-09-01 17:54:09 +000011217 emulation_failure(EmFail_S390X_stfle);
florian4e0083e2012-08-26 03:41:56 +000011218 return "stfle";
11219 }
11220
florian933065d2011-07-11 01:48:02 +000011221 IRDirty *d;
11222 IRTemp cc = newTemp(Ity_I64);
11223
11224 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STFLE",
11225 &s390x_dirtyhelper_STFLE,
11226 mkIRExprVec_1(mkexpr(op2addr)));
11227
11228 d->needsBBP = 1; /* Need to pass pointer to guest state to helper */
11229
sewardjc9069f22012-06-01 16:09:50 +000011230 d->nFxState = 1;
11231 vex_bzero(&d->fxState, sizeof(d->fxState));
11232
florian933065d2011-07-11 01:48:02 +000011233 d->fxState[0].fx = Ifx_Modify; /* read then write */
11234 d->fxState[0].offset = S390X_GUEST_OFFSET(guest_r0);
11235 d->fxState[0].size = sizeof(ULong);
florian933065d2011-07-11 01:48:02 +000011236
11237 d->mAddr = mkexpr(op2addr);
11238 /* Pretend all double words are written */
11239 d->mSize = S390_NUM_FACILITY_DW * sizeof(ULong);
11240 d->mFx = Ifx_Write;
11241
11242 stmt(IRStmt_Dirty(d));
11243
11244 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET), mkexpr(cc), mkU64(0), mkU64(0));
11245
11246 return "stfle";
11247}
11248
floriana4384a32011-08-11 16:58:45 +000011249static HChar *
11250s390_irgen_CKSM(UChar r1,UChar r2)
11251{
11252 IRTemp addr = newTemp(Ity_I64);
11253 IRTemp op = newTemp(Ity_I32);
11254 IRTemp len = newTemp(Ity_I64);
11255 IRTemp oldval = newTemp(Ity_I32);
11256 IRTemp mask = newTemp(Ity_I32);
11257 IRTemp newop = newTemp(Ity_I32);
11258 IRTemp result = newTemp(Ity_I32);
11259 IRTemp result1 = newTemp(Ity_I32);
11260 IRTemp inc = newTemp(Ity_I64);
11261
11262 assign(oldval, get_gpr_w1(r1));
11263 assign(addr, get_gpr_dw0(r2));
11264 assign(len, get_gpr_dw0(r2+1));
11265
11266 /* Condition code is always zero. */
11267 s390_cc_set(0);
11268
11269 /* If length is zero, there is no need to calculate the checksum */
florian6820ba52012-07-26 02:01:50 +000011270 next_insn_if(binop(Iop_CmpEQ64, mkexpr(len), mkU64(0)));
floriana4384a32011-08-11 16:58:45 +000011271
11272 /* Assiging the increment variable to adjust address and length
11273 later on. */
11274 assign(inc, mkite(binop(Iop_CmpLT64U, mkexpr(len), mkU64(4)),
11275 mkexpr(len), mkU64(4)));
11276
11277 /* If length < 4 the final 4-byte 2nd operand value is computed by
11278 appending the remaining bytes to the right with 0. This is done
11279 by AND'ing the 4 bytes loaded from memory with an appropriate
11280 mask. If length >= 4, that mask is simply 0xffffffff. */
11281
11282 assign(mask, mkite(binop(Iop_CmpLT64U, mkexpr(len), mkU64(4)),
11283 /* Mask computation when len < 4:
11284 0xffffffff << (32 - (len % 4)*8) */
11285 binop(Iop_Shl32, mkU32(0xffffffff),
11286 unop(Iop_32to8,
11287 binop(Iop_Sub32, mkU32(32),
11288 binop(Iop_Shl32,
11289 unop(Iop_64to32,
11290 binop(Iop_And64,
11291 mkexpr(len), mkU64(3))),
11292 mkU8(3))))),
11293 mkU32(0xffffffff)));
11294
11295 assign(op, load(Ity_I32, mkexpr(addr)));
11296 assign(newop, binop(Iop_And32, mkexpr(op), mkexpr(mask)));
11297 assign(result, binop(Iop_Add32, mkexpr(newop), mkexpr(oldval)));
11298
11299 /* Checking for carry */
11300 assign(result1, mkite(binop(Iop_CmpLT32U, mkexpr(result), mkexpr(newop)),
11301 binop(Iop_Add32, mkexpr(result), mkU32(1)),
11302 mkexpr(result)));
11303
11304 put_gpr_w1(r1, mkexpr(result1));
11305 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr), mkexpr(inc)));
11306 put_gpr_dw0(r2+1, binop(Iop_Sub64, mkexpr(len), mkexpr(inc)));
11307
florian6820ba52012-07-26 02:01:50 +000011308 iterate_if(binop(Iop_CmpNE64, mkexpr(len), mkU64(0)));
floriana4384a32011-08-11 16:58:45 +000011309
11310 return "cksm";
11311}
11312
florian9af37692012-01-15 21:01:16 +000011313static HChar *
11314s390_irgen_TROO(UChar m3, UChar r1, UChar r2)
11315{
11316 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
11317 src_addr = newTemp(Ity_I64);
11318 des_addr = newTemp(Ity_I64);
11319 tab_addr = newTemp(Ity_I64);
11320 test_byte = newTemp(Ity_I8);
11321 src_len = newTemp(Ity_I64);
11322
11323 assign(src_addr, get_gpr_dw0(r2));
11324 assign(des_addr, get_gpr_dw0(r1));
11325 assign(tab_addr, get_gpr_dw0(1));
florian53518532012-01-18 14:00:31 +000011326 assign(src_len, get_gpr_dw0(r1+1));
florian9af37692012-01-15 21:01:16 +000011327 assign(test_byte, get_gpr_b7(0));
11328
11329 IRTemp op = newTemp(Ity_I8);
11330 IRTemp op1 = newTemp(Ity_I8);
11331 IRTemp result = newTemp(Ity_I64);
11332
11333 /* End of source string? We're done; proceed to next insn */
11334 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000011335 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian9af37692012-01-15 21:01:16 +000011336
11337 /* Load character from source string, index translation table and
11338 store translated character in op1. */
11339 assign(op, load(Ity_I8, mkexpr(src_addr)));
11340
11341 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)),
11342 mkexpr(tab_addr)));
11343 assign(op1, load(Ity_I8, mkexpr(result)));
11344
11345 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
11346 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000011347 next_insn_if(binop(Iop_CmpEQ8, mkexpr(op1), mkexpr(test_byte)));
florian9af37692012-01-15 21:01:16 +000011348 }
11349 store(get_gpr_dw0(r1), mkexpr(op1));
11350
11351 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(1)));
11352 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(1)));
11353 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(1)));
11354
florian6820ba52012-07-26 02:01:50 +000011355 iterate();
florian9af37692012-01-15 21:01:16 +000011356
11357 return "troo";
11358}
11359
florian730448f2012-02-04 17:07:07 +000011360static HChar *
11361s390_irgen_TRTO(UChar m3, UChar r1, UChar r2)
11362{
11363 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
11364 src_addr = newTemp(Ity_I64);
11365 des_addr = newTemp(Ity_I64);
11366 tab_addr = newTemp(Ity_I64);
11367 test_byte = newTemp(Ity_I8);
11368 src_len = newTemp(Ity_I64);
11369
11370 assign(src_addr, get_gpr_dw0(r2));
11371 assign(des_addr, get_gpr_dw0(r1));
11372 assign(tab_addr, get_gpr_dw0(1));
11373 assign(src_len, get_gpr_dw0(r1+1));
11374 assign(test_byte, get_gpr_b7(0));
11375
11376 IRTemp op = newTemp(Ity_I16);
11377 IRTemp op1 = newTemp(Ity_I8);
11378 IRTemp result = newTemp(Ity_I64);
11379
11380 /* End of source string? We're done; proceed to next insn */
11381 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000011382 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian730448f2012-02-04 17:07:07 +000011383
11384 /* Load character from source string, index translation table and
11385 store translated character in op1. */
11386 assign(op, load(Ity_I16, mkexpr(src_addr)));
11387
11388 assign(result, binop(Iop_Add64, unop(Iop_16Uto64, mkexpr(op)),
11389 mkexpr(tab_addr)));
11390
11391 assign(op1, load(Ity_I8, mkexpr(result)));
11392
11393 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
11394 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000011395 next_insn_if(binop(Iop_CmpEQ8, mkexpr(op1), mkexpr(test_byte)));
florian730448f2012-02-04 17:07:07 +000011396 }
11397 store(get_gpr_dw0(r1), mkexpr(op1));
11398
11399 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(2)));
11400 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(1)));
11401 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(2)));
11402
florian6820ba52012-07-26 02:01:50 +000011403 iterate();
florian730448f2012-02-04 17:07:07 +000011404
11405 return "trto";
11406}
11407
11408static HChar *
11409s390_irgen_TROT(UChar m3, UChar r1, UChar r2)
11410{
11411 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
11412 src_addr = newTemp(Ity_I64);
11413 des_addr = newTemp(Ity_I64);
11414 tab_addr = newTemp(Ity_I64);
11415 test_byte = newTemp(Ity_I16);
11416 src_len = newTemp(Ity_I64);
11417
11418 assign(src_addr, get_gpr_dw0(r2));
11419 assign(des_addr, get_gpr_dw0(r1));
11420 assign(tab_addr, get_gpr_dw0(1));
11421 assign(src_len, get_gpr_dw0(r1+1));
11422 assign(test_byte, get_gpr_hw3(0));
11423
11424 IRTemp op = newTemp(Ity_I8);
11425 IRTemp op1 = newTemp(Ity_I16);
11426 IRTemp result = newTemp(Ity_I64);
11427
11428 /* End of source string? We're done; proceed to next insn */
11429 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000011430 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian730448f2012-02-04 17:07:07 +000011431
11432 /* Load character from source string, index translation table and
11433 store translated character in op1. */
11434 assign(op, binop(Iop_Shl8, load(Ity_I8, mkexpr(src_addr)), mkU8(1)));
11435
11436 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)),
11437 mkexpr(tab_addr)));
11438 assign(op1, load(Ity_I16, mkexpr(result)));
11439
11440 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
11441 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000011442 next_insn_if(binop(Iop_CmpEQ16, mkexpr(op1), mkexpr(test_byte)));
florian730448f2012-02-04 17:07:07 +000011443 }
11444 store(get_gpr_dw0(r1), mkexpr(op1));
11445
11446 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(1)));
11447 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(2)));
11448 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(1)));
11449
florian6820ba52012-07-26 02:01:50 +000011450 iterate();
florian730448f2012-02-04 17:07:07 +000011451
11452 return "trot";
11453}
11454
11455static HChar *
11456s390_irgen_TRTT(UChar m3, UChar r1, UChar r2)
11457{
11458 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
11459 src_addr = newTemp(Ity_I64);
11460 des_addr = newTemp(Ity_I64);
11461 tab_addr = newTemp(Ity_I64);
11462 test_byte = newTemp(Ity_I16);
11463 src_len = newTemp(Ity_I64);
11464
11465 assign(src_addr, get_gpr_dw0(r2));
11466 assign(des_addr, get_gpr_dw0(r1));
11467 assign(tab_addr, get_gpr_dw0(1));
11468 assign(src_len, get_gpr_dw0(r1+1));
11469 assign(test_byte, get_gpr_hw3(0));
11470
11471 IRTemp op = newTemp(Ity_I16);
11472 IRTemp op1 = newTemp(Ity_I16);
11473 IRTemp result = newTemp(Ity_I64);
11474
11475 /* End of source string? We're done; proceed to next insn */
11476 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000011477 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian730448f2012-02-04 17:07:07 +000011478
11479 /* Load character from source string, index translation table and
11480 store translated character in op1. */
11481 assign(op, binop(Iop_Shl16, load(Ity_I16, mkexpr(src_addr)), mkU8(1)));
11482
11483 assign(result, binop(Iop_Add64, unop(Iop_16Uto64, mkexpr(op)),
11484 mkexpr(tab_addr)));
11485 assign(op1, load(Ity_I16, mkexpr(result)));
11486
11487 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
11488 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000011489 next_insn_if(binop(Iop_CmpEQ16, mkexpr(op1), mkexpr(test_byte)));
florian730448f2012-02-04 17:07:07 +000011490 }
11491
11492 store(get_gpr_dw0(r1), mkexpr(op1));
11493
11494 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(2)));
11495 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(2)));
11496 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(2)));
11497
florian6820ba52012-07-26 02:01:50 +000011498 iterate();
florian730448f2012-02-04 17:07:07 +000011499
11500 return "trtt";
11501}
11502
11503static HChar *
11504s390_irgen_TR(UChar length, IRTemp start1, IRTemp start2)
11505{
florianf87d4fb2012-05-05 02:55:24 +000011506 IRTemp len = newTemp(Ity_I64);
florian730448f2012-02-04 17:07:07 +000011507
florianf87d4fb2012-05-05 02:55:24 +000011508 assign(len, mkU64(length));
11509 s390_irgen_TR_EX(len, start1, start2);
florian730448f2012-02-04 17:07:07 +000011510
11511 return "tr";
11512}
11513
11514static HChar *
11515s390_irgen_TRE(UChar r1,UChar r2)
11516{
11517 IRTemp src_addr, tab_addr, src_len, test_byte;
11518 src_addr = newTemp(Ity_I64);
11519 tab_addr = newTemp(Ity_I64);
11520 src_len = newTemp(Ity_I64);
11521 test_byte = newTemp(Ity_I8);
11522
11523 assign(src_addr, get_gpr_dw0(r1));
11524 assign(src_len, get_gpr_dw0(r1+1));
11525 assign(tab_addr, get_gpr_dw0(r2));
11526 assign(test_byte, get_gpr_b7(0));
11527
11528 IRTemp op = newTemp(Ity_I8);
11529 IRTemp op1 = newTemp(Ity_I8);
11530 IRTemp result = newTemp(Ity_I64);
11531
11532 /* End of source string? We're done; proceed to next insn */
11533 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000011534 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian730448f2012-02-04 17:07:07 +000011535
11536 /* Load character from source string and compare with test byte */
11537 assign(op, load(Ity_I8, mkexpr(src_addr)));
11538
11539 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000011540 next_insn_if(binop(Iop_CmpEQ8, mkexpr(op), mkexpr(test_byte)));
florian730448f2012-02-04 17:07:07 +000011541
11542 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)),
11543 mkexpr(tab_addr)));
11544
11545 assign(op1, load(Ity_I8, mkexpr(result)));
11546
11547 store(get_gpr_dw0(r1), mkexpr(op1));
11548 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(src_addr), mkU64(1)));
11549 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(1)));
11550
florian6820ba52012-07-26 02:01:50 +000011551 iterate();
florian730448f2012-02-04 17:07:07 +000011552
11553 return "tre";
11554}
11555
floriana0100c92012-07-20 00:06:35 +000011556static IRExpr *
11557s390_call_cu21(IRExpr *srcval, IRExpr *low_surrogate)
11558{
11559 IRExpr **args, *call;
11560 args = mkIRExprVec_2(srcval, low_surrogate);
11561 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
11562 "s390_do_cu21", &s390_do_cu21, args);
11563
11564 /* Nothing is excluded from definedness checking. */
11565 call->Iex.CCall.cee->mcx_mask = 0;
11566
11567 return call;
11568}
11569
11570static HChar *
11571s390_irgen_CU21(UChar m3, UChar r1, UChar r2)
11572{
11573 IRTemp addr1 = newTemp(Ity_I64);
11574 IRTemp addr2 = newTemp(Ity_I64);
11575 IRTemp len1 = newTemp(Ity_I64);
11576 IRTemp len2 = newTemp(Ity_I64);
11577
11578 assign(addr1, get_gpr_dw0(r1));
11579 assign(addr2, get_gpr_dw0(r2));
11580 assign(len1, get_gpr_dw0(r1 + 1));
11581 assign(len2, get_gpr_dw0(r2 + 1));
11582
11583 /* We're processing the 2nd operand 2 bytes at a time. Therefore, if
11584 there are less than 2 bytes left, then the 2nd operand is exhausted
11585 and we're done here. cc = 0 */
11586 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000011587 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(2)));
floriana0100c92012-07-20 00:06:35 +000011588
11589 /* There are at least two bytes there. Read them. */
11590 IRTemp srcval = newTemp(Ity_I32);
11591 assign(srcval, unop(Iop_16Uto32, load(Ity_I16, mkexpr(addr2))));
11592
11593 /* Find out whether this is a high surrogate. I.e. SRCVAL lies
11594 inside the interval [0xd800 - 0xdbff] */
11595 IRTemp is_high_surrogate = newTemp(Ity_I32);
11596 IRExpr *flag1 = mkite(binop(Iop_CmpLE32U, mkU32(0xd800), mkexpr(srcval)),
11597 mkU32(1), mkU32(0));
11598 IRExpr *flag2 = mkite(binop(Iop_CmpLE32U, mkexpr(srcval), mkU32(0xdbff)),
11599 mkU32(1), mkU32(0));
11600 assign(is_high_surrogate, binop(Iop_And32, flag1, flag2));
11601
11602 /* If SRCVAL is a high surrogate and there are less than 4 bytes left,
11603 then the 2nd operand is exhausted and we're done here. cc = 0 */
11604 IRExpr *not_enough_bytes =
11605 mkite(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)), mkU32(1), mkU32(0));
11606
florian6820ba52012-07-26 02:01:50 +000011607 next_insn_if(binop(Iop_CmpEQ32,
11608 binop(Iop_And32, mkexpr(is_high_surrogate),
11609 not_enough_bytes), mkU32(1)));
floriana0100c92012-07-20 00:06:35 +000011610
11611 /* The 2nd operand is not exhausted. If the first 2 bytes are a high
11612 surrogate, read the next two bytes (low surrogate). */
11613 IRTemp low_surrogate = newTemp(Ity_I32);
11614 IRExpr *low_surrogate_addr = binop(Iop_Add64, mkexpr(addr2), mkU64(2));
11615
11616 assign(low_surrogate,
11617 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
11618 unop(Iop_16Uto32, load(Ity_I16, low_surrogate_addr)),
11619 mkU32(0))); // any value is fine; it will not be used
11620
11621 /* Call the helper */
11622 IRTemp retval = newTemp(Ity_I64);
florian11b8ee82012-08-06 13:35:33 +000011623 assign(retval, s390_call_cu21(unop(Iop_32Uto64, mkexpr(srcval)),
11624 unop(Iop_32Uto64, mkexpr(low_surrogate))));
floriana0100c92012-07-20 00:06:35 +000011625
11626 /* Before we can test whether the 1st operand is exhausted we need to
11627 test for an invalid low surrogate. Because cc=2 outranks cc=1. */
11628 if (s390_host_has_etf3 && (m3 & 0x1) == 1) {
11629 IRExpr *invalid_low_surrogate =
11630 binop(Iop_And64, mkexpr(retval), mkU64(0xff));
11631
11632 s390_cc_set(2);
florian6820ba52012-07-26 02:01:50 +000011633 next_insn_if(binop(Iop_CmpEQ64, invalid_low_surrogate, mkU64(1)));
floriana0100c92012-07-20 00:06:35 +000011634 }
11635
11636 /* Now test whether the 1st operand is exhausted */
11637 IRTemp num_bytes = newTemp(Ity_I64);
11638 assign(num_bytes, binop(Iop_And64,
11639 binop(Iop_Shr64, mkexpr(retval), mkU8(8)),
11640 mkU64(0xff)));
11641 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000011642 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
floriana0100c92012-07-20 00:06:35 +000011643
11644 /* Extract the bytes to be stored at addr1 */
11645 IRTemp data = newTemp(Ity_I64);
11646 assign(data, binop(Iop_Shr64, mkexpr(retval), mkU8(16)));
11647
11648 /* To store the bytes construct 4 dirty helper calls. The helper calls
11649 are guarded (num_bytes == 1, num_bytes == 2, etc) such that only
11650 one of them will be called at runtime. */
11651 int i;
11652 for (i = 1; i <= 4; ++i) {
11653 IRDirty *d;
11654
11655 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
11656 &s390x_dirtyhelper_CUxy,
11657 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
11658 mkexpr(num_bytes)));
11659 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
11660 d->mFx = Ifx_Write;
11661 d->mAddr = mkexpr(addr1);
11662 d->mSize = i;
11663 stmt(IRStmt_Dirty(d));
11664 }
11665
11666 /* Update source address and length */
11667 IRTemp num_src_bytes = newTemp(Ity_I64);
11668 assign(num_src_bytes,
11669 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
11670 mkU64(4), mkU64(2)));
11671 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkexpr(num_src_bytes)));
11672 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkexpr(num_src_bytes)));
11673
11674 /* Update destination address and length */
11675 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
11676 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
11677
florian6820ba52012-07-26 02:01:50 +000011678 iterate();
floriana0100c92012-07-20 00:06:35 +000011679
11680 return "cu21";
11681}
11682
florian2a415a12012-07-21 17:41:36 +000011683static IRExpr *
11684s390_call_cu24(IRExpr *srcval, IRExpr *low_surrogate)
11685{
11686 IRExpr **args, *call;
11687 args = mkIRExprVec_2(srcval, low_surrogate);
11688 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
11689 "s390_do_cu24", &s390_do_cu24, args);
11690
11691 /* Nothing is excluded from definedness checking. */
11692 call->Iex.CCall.cee->mcx_mask = 0;
11693
11694 return call;
11695}
11696
11697static HChar *
11698s390_irgen_CU24(UChar m3, UChar r1, UChar r2)
11699{
11700 IRTemp addr1 = newTemp(Ity_I64);
11701 IRTemp addr2 = newTemp(Ity_I64);
11702 IRTemp len1 = newTemp(Ity_I64);
11703 IRTemp len2 = newTemp(Ity_I64);
11704
11705 assign(addr1, get_gpr_dw0(r1));
11706 assign(addr2, get_gpr_dw0(r2));
11707 assign(len1, get_gpr_dw0(r1 + 1));
11708 assign(len2, get_gpr_dw0(r2 + 1));
11709
11710 /* We're processing the 2nd operand 2 bytes at a time. Therefore, if
11711 there are less than 2 bytes left, then the 2nd operand is exhausted
11712 and we're done here. cc = 0 */
11713 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000011714 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(2)));
florian2a415a12012-07-21 17:41:36 +000011715
11716 /* There are at least two bytes there. Read them. */
11717 IRTemp srcval = newTemp(Ity_I32);
11718 assign(srcval, unop(Iop_16Uto32, load(Ity_I16, mkexpr(addr2))));
11719
11720 /* Find out whether this is a high surrogate. I.e. SRCVAL lies
11721 inside the interval [0xd800 - 0xdbff] */
11722 IRTemp is_high_surrogate = newTemp(Ity_I32);
11723 IRExpr *flag1 = mkite(binop(Iop_CmpLE32U, mkU32(0xd800), mkexpr(srcval)),
11724 mkU32(1), mkU32(0));
11725 IRExpr *flag2 = mkite(binop(Iop_CmpLE32U, mkexpr(srcval), mkU32(0xdbff)),
11726 mkU32(1), mkU32(0));
11727 assign(is_high_surrogate, binop(Iop_And32, flag1, flag2));
11728
11729 /* If SRCVAL is a high surrogate and there are less than 4 bytes left,
11730 then the 2nd operand is exhausted and we're done here. cc = 0 */
11731 IRExpr *not_enough_bytes =
11732 mkite(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)), mkU32(1), mkU32(0));
11733
florian6820ba52012-07-26 02:01:50 +000011734 next_insn_if(binop(Iop_CmpEQ32,
11735 binop(Iop_And32, mkexpr(is_high_surrogate),
11736 not_enough_bytes),
11737 mkU32(1)));
florian2a415a12012-07-21 17:41:36 +000011738
11739 /* The 2nd operand is not exhausted. If the first 2 bytes are a high
11740 surrogate, read the next two bytes (low surrogate). */
11741 IRTemp low_surrogate = newTemp(Ity_I32);
11742 IRExpr *low_surrogate_addr = binop(Iop_Add64, mkexpr(addr2), mkU64(2));
11743
11744 assign(low_surrogate,
11745 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
11746 unop(Iop_16Uto32, load(Ity_I16, low_surrogate_addr)),
11747 mkU32(0))); // any value is fine; it will not be used
11748
11749 /* Call the helper */
11750 IRTemp retval = newTemp(Ity_I64);
florian11b8ee82012-08-06 13:35:33 +000011751 assign(retval, s390_call_cu24(unop(Iop_32Uto64, mkexpr(srcval)),
11752 unop(Iop_32Uto64, mkexpr(low_surrogate))));
florian2a415a12012-07-21 17:41:36 +000011753
11754 /* Before we can test whether the 1st operand is exhausted we need to
11755 test for an invalid low surrogate. Because cc=2 outranks cc=1. */
11756 if (s390_host_has_etf3 && (m3 & 0x1) == 1) {
11757 IRExpr *invalid_low_surrogate =
11758 binop(Iop_And64, mkexpr(retval), mkU64(0xff));
11759
11760 s390_cc_set(2);
florian6820ba52012-07-26 02:01:50 +000011761 next_insn_if(binop(Iop_CmpEQ64, invalid_low_surrogate, mkU64(1)));
florian2a415a12012-07-21 17:41:36 +000011762 }
11763
11764 /* Now test whether the 1st operand is exhausted */
11765 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000011766 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkU64(4)));
florian2a415a12012-07-21 17:41:36 +000011767
11768 /* Extract the bytes to be stored at addr1 */
11769 IRExpr *data = unop(Iop_64to32, binop(Iop_Shr64, mkexpr(retval), mkU8(8)));
11770
11771 store(mkexpr(addr1), data);
11772
11773 /* Update source address and length */
11774 IRTemp num_src_bytes = newTemp(Ity_I64);
11775 assign(num_src_bytes,
11776 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
11777 mkU64(4), mkU64(2)));
11778 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkexpr(num_src_bytes)));
11779 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkexpr(num_src_bytes)));
11780
11781 /* Update destination address and length */
11782 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkU64(4)));
11783 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkU64(4)));
11784
florian6820ba52012-07-26 02:01:50 +000011785 iterate();
florian2a415a12012-07-21 17:41:36 +000011786
11787 return "cu24";
11788}
floriana4384a32011-08-11 16:58:45 +000011789
florian956194b2012-07-28 22:18:32 +000011790static IRExpr *
11791s390_call_cu42(IRExpr *srcval)
11792{
11793 IRExpr **args, *call;
11794 args = mkIRExprVec_1(srcval);
11795 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
11796 "s390_do_cu42", &s390_do_cu42, args);
11797
11798 /* Nothing is excluded from definedness checking. */
11799 call->Iex.CCall.cee->mcx_mask = 0;
11800
11801 return call;
11802}
11803
11804static HChar *
11805s390_irgen_CU42(UChar r1, UChar r2)
11806{
11807 IRTemp addr1 = newTemp(Ity_I64);
11808 IRTemp addr2 = newTemp(Ity_I64);
11809 IRTemp len1 = newTemp(Ity_I64);
11810 IRTemp len2 = newTemp(Ity_I64);
11811
11812 assign(addr1, get_gpr_dw0(r1));
11813 assign(addr2, get_gpr_dw0(r2));
11814 assign(len1, get_gpr_dw0(r1 + 1));
11815 assign(len2, get_gpr_dw0(r2 + 1));
11816
11817 /* We're processing the 2nd operand 4 bytes at a time. Therefore, if
11818 there are less than 4 bytes left, then the 2nd operand is exhausted
11819 and we're done here. cc = 0 */
11820 s390_cc_set(0);
11821 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)));
11822
11823 /* Read the 2nd operand. */
11824 IRTemp srcval = newTemp(Ity_I32);
11825 assign(srcval, load(Ity_I32, mkexpr(addr2)));
11826
11827 /* Call the helper */
11828 IRTemp retval = newTemp(Ity_I64);
florian11b8ee82012-08-06 13:35:33 +000011829 assign(retval, s390_call_cu42(unop(Iop_32Uto64, mkexpr(srcval))));
florian956194b2012-07-28 22:18:32 +000011830
11831 /* If the UTF-32 character was invalid, set cc=2 and we're done.
11832 cc=2 outranks cc=1 (1st operand exhausted) */
11833 IRExpr *invalid_character = binop(Iop_And64, mkexpr(retval), mkU64(0xff));
11834
11835 s390_cc_set(2);
11836 next_insn_if(binop(Iop_CmpEQ64, invalid_character, mkU64(1)));
11837
11838 /* Now test whether the 1st operand is exhausted */
11839 IRTemp num_bytes = newTemp(Ity_I64);
11840 assign(num_bytes, binop(Iop_And64,
11841 binop(Iop_Shr64, mkexpr(retval), mkU8(8)),
11842 mkU64(0xff)));
11843 s390_cc_set(1);
11844 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
11845
11846 /* Extract the bytes to be stored at addr1 */
11847 IRTemp data = newTemp(Ity_I64);
11848 assign(data, binop(Iop_Shr64, mkexpr(retval), mkU8(16)));
11849
11850 /* To store the bytes construct 2 dirty helper calls. The helper calls
11851 are guarded (num_bytes == 2 and num_bytes == 4, respectively) such
11852 that only one of them will be called at runtime. */
11853
11854 Int i;
11855 for (i = 2; i <= 4; ++i) {
11856 IRDirty *d;
11857
11858 if (i == 3) continue; // skip this one
11859
11860 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
11861 &s390x_dirtyhelper_CUxy,
11862 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
11863 mkexpr(num_bytes)));
11864 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
11865 d->mFx = Ifx_Write;
11866 d->mAddr = mkexpr(addr1);
11867 d->mSize = i;
11868 stmt(IRStmt_Dirty(d));
11869 }
11870
11871 /* Update source address and length */
11872 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkU64(4)));
11873 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkU64(4)));
11874
11875 /* Update destination address and length */
11876 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
11877 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
11878
11879 iterate();
11880
11881 return "cu42";
11882}
11883
florian6d9b9b22012-08-03 18:35:39 +000011884static IRExpr *
florianaf2194f2012-08-06 00:07:54 +000011885s390_call_cu41(IRExpr *srcval)
11886{
11887 IRExpr **args, *call;
11888 args = mkIRExprVec_1(srcval);
11889 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
11890 "s390_do_cu41", &s390_do_cu41, args);
11891
11892 /* Nothing is excluded from definedness checking. */
11893 call->Iex.CCall.cee->mcx_mask = 0;
11894
11895 return call;
11896}
11897
11898static HChar *
11899s390_irgen_CU41(UChar r1, UChar r2)
11900{
11901 IRTemp addr1 = newTemp(Ity_I64);
11902 IRTemp addr2 = newTemp(Ity_I64);
11903 IRTemp len1 = newTemp(Ity_I64);
11904 IRTemp len2 = newTemp(Ity_I64);
11905
11906 assign(addr1, get_gpr_dw0(r1));
11907 assign(addr2, get_gpr_dw0(r2));
11908 assign(len1, get_gpr_dw0(r1 + 1));
11909 assign(len2, get_gpr_dw0(r2 + 1));
11910
11911 /* We're processing the 2nd operand 4 bytes at a time. Therefore, if
11912 there are less than 4 bytes left, then the 2nd operand is exhausted
11913 and we're done here. cc = 0 */
11914 s390_cc_set(0);
11915 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)));
11916
11917 /* Read the 2nd operand. */
11918 IRTemp srcval = newTemp(Ity_I32);
11919 assign(srcval, load(Ity_I32, mkexpr(addr2)));
11920
11921 /* Call the helper */
11922 IRTemp retval = newTemp(Ity_I64);
florian11b8ee82012-08-06 13:35:33 +000011923 assign(retval, s390_call_cu41(unop(Iop_32Uto64, mkexpr(srcval))));
florianaf2194f2012-08-06 00:07:54 +000011924
11925 /* If the UTF-32 character was invalid, set cc=2 and we're done.
11926 cc=2 outranks cc=1 (1st operand exhausted) */
11927 IRExpr *invalid_character = binop(Iop_And64, mkexpr(retval), mkU64(0xff));
11928
11929 s390_cc_set(2);
11930 next_insn_if(binop(Iop_CmpEQ64, invalid_character, mkU64(1)));
11931
11932 /* Now test whether the 1st operand is exhausted */
11933 IRTemp num_bytes = newTemp(Ity_I64);
11934 assign(num_bytes, binop(Iop_And64,
11935 binop(Iop_Shr64, mkexpr(retval), mkU8(8)),
11936 mkU64(0xff)));
11937 s390_cc_set(1);
11938 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
11939
11940 /* Extract the bytes to be stored at addr1 */
11941 IRTemp data = newTemp(Ity_I64);
11942 assign(data, binop(Iop_Shr64, mkexpr(retval), mkU8(16)));
11943
11944 /* To store the bytes construct 4 dirty helper calls. The helper calls
11945 are guarded (num_bytes == 1, num_bytes == 2, etc) such that only
11946 one of them will be called at runtime. */
11947 int i;
11948 for (i = 1; i <= 4; ++i) {
11949 IRDirty *d;
11950
11951 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
11952 &s390x_dirtyhelper_CUxy,
11953 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
11954 mkexpr(num_bytes)));
11955 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
11956 d->mFx = Ifx_Write;
11957 d->mAddr = mkexpr(addr1);
11958 d->mSize = i;
11959 stmt(IRStmt_Dirty(d));
11960 }
11961
11962 /* Update source address and length */
11963 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkU64(4)));
11964 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkU64(4)));
11965
11966 /* Update destination address and length */
11967 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
11968 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
11969
11970 iterate();
11971
11972 return "cu41";
11973}
11974
11975static IRExpr *
florian3f8a96a2012-08-05 02:59:55 +000011976s390_call_cu12_cu14_helper1(IRExpr *byte1, IRExpr *etf3_and_m3_is_1)
florian6d9b9b22012-08-03 18:35:39 +000011977{
11978 IRExpr **args, *call;
11979 args = mkIRExprVec_2(byte1, etf3_and_m3_is_1);
florian3f8a96a2012-08-05 02:59:55 +000011980 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/, "s390_do_cu12_cu14_helper1",
11981 &s390_do_cu12_cu14_helper1, args);
florian6d9b9b22012-08-03 18:35:39 +000011982
11983 /* Nothing is excluded from definedness checking. */
11984 call->Iex.CCall.cee->mcx_mask = 0;
11985
11986 return call;
11987}
11988
11989static IRExpr *
11990s390_call_cu12_helper2(IRExpr *byte1, IRExpr *byte2, IRExpr *byte3,
11991 IRExpr *byte4, IRExpr *stuff)
11992{
11993 IRExpr **args, *call;
11994 args = mkIRExprVec_5(byte1, byte2, byte3, byte4, stuff);
11995 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
11996 "s390_do_cu12_helper2", &s390_do_cu12_helper2, args);
11997
11998 /* Nothing is excluded from definedness checking. */
11999 call->Iex.CCall.cee->mcx_mask = 0;
12000
12001 return call;
12002}
12003
florian3f8a96a2012-08-05 02:59:55 +000012004static IRExpr *
12005s390_call_cu14_helper2(IRExpr *byte1, IRExpr *byte2, IRExpr *byte3,
12006 IRExpr *byte4, IRExpr *stuff)
12007{
12008 IRExpr **args, *call;
12009 args = mkIRExprVec_5(byte1, byte2, byte3, byte4, stuff);
12010 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
12011 "s390_do_cu14_helper2", &s390_do_cu14_helper2, args);
12012
12013 /* Nothing is excluded from definedness checking. */
12014 call->Iex.CCall.cee->mcx_mask = 0;
12015
12016 return call;
12017}
12018
12019static void
12020s390_irgen_cu12_cu14(UChar m3, UChar r1, UChar r2, Bool is_cu12)
florian6d9b9b22012-08-03 18:35:39 +000012021{
12022 IRTemp addr1 = newTemp(Ity_I64);
12023 IRTemp addr2 = newTemp(Ity_I64);
12024 IRTemp len1 = newTemp(Ity_I64);
12025 IRTemp len2 = newTemp(Ity_I64);
12026
12027 assign(addr1, get_gpr_dw0(r1));
12028 assign(addr2, get_gpr_dw0(r2));
12029 assign(len1, get_gpr_dw0(r1 + 1));
12030 assign(len2, get_gpr_dw0(r2 + 1));
12031
12032 UInt extended_checking = s390_host_has_etf3 && (m3 & 0x1) == 1;
12033
12034 /* We're processing the 2nd operand 1 byte at a time. Therefore, if
12035 there is less than 1 byte left, then the 2nd operand is exhausted
12036 and we're done here. cc = 0 */
12037 s390_cc_set(0);
12038 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(1)));
12039
12040 /* There is at least one byte there. Read it. */
florian11b8ee82012-08-06 13:35:33 +000012041 IRTemp byte1 = newTemp(Ity_I64);
12042 assign(byte1, unop(Iop_8Uto64, load(Ity_I8, mkexpr(addr2))));
florian6d9b9b22012-08-03 18:35:39 +000012043
12044 /* Call the helper to get number of bytes and invalid byte indicator */
12045 IRTemp retval1 = newTemp(Ity_I64);
florian3f8a96a2012-08-05 02:59:55 +000012046 assign(retval1, s390_call_cu12_cu14_helper1(mkexpr(byte1),
florian11b8ee82012-08-06 13:35:33 +000012047 mkU64(extended_checking)));
florian6d9b9b22012-08-03 18:35:39 +000012048
12049 /* Check for invalid 1st byte */
12050 IRExpr *is_invalid = unop(Iop_64to1, mkexpr(retval1));
12051 s390_cc_set(2);
12052 next_insn_if(is_invalid);
12053
12054 /* How many bytes do we have to read? */
12055 IRTemp num_src_bytes = newTemp(Ity_I64);
12056 assign(num_src_bytes, binop(Iop_Shr64, mkexpr(retval1), mkU8(8)));
12057
12058 /* Now test whether the 2nd operand is exhausted */
12059 s390_cc_set(0);
12060 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkexpr(num_src_bytes)));
12061
12062 /* Read the remaining bytes */
12063 IRExpr *cond, *addr, *byte2, *byte3, *byte4;
12064
12065 cond = binop(Iop_CmpLE64U, mkU64(2), mkexpr(num_src_bytes));
12066 addr = binop(Iop_Add64, mkexpr(addr2), mkU64(1));
florian11b8ee82012-08-06 13:35:33 +000012067 byte2 = mkite(cond, unop(Iop_8Uto64, load(Ity_I8, addr)), mkU64(0));
florian6d9b9b22012-08-03 18:35:39 +000012068 cond = binop(Iop_CmpLE64U, mkU64(3), mkexpr(num_src_bytes));
12069 addr = binop(Iop_Add64, mkexpr(addr2), mkU64(2));
florian11b8ee82012-08-06 13:35:33 +000012070 byte3 = mkite(cond, unop(Iop_8Uto64, load(Ity_I8, addr)), mkU64(0));
florian6d9b9b22012-08-03 18:35:39 +000012071 cond = binop(Iop_CmpLE64U, mkU64(4), mkexpr(num_src_bytes));
12072 addr = binop(Iop_Add64, mkexpr(addr2), mkU64(3));
florian11b8ee82012-08-06 13:35:33 +000012073 byte4 = mkite(cond, unop(Iop_8Uto64, load(Ity_I8, addr)), mkU64(0));
florian6d9b9b22012-08-03 18:35:39 +000012074
12075 /* Call the helper to get the converted value and invalid byte indicator.
12076 We can pass at most 5 arguments; therefore some encoding is needed
12077 here */
12078 IRExpr *stuff = binop(Iop_Or64,
12079 binop(Iop_Shl64, mkexpr(num_src_bytes), mkU8(1)),
12080 mkU64(extended_checking));
12081 IRTemp retval2 = newTemp(Ity_I64);
florian3f8a96a2012-08-05 02:59:55 +000012082
12083 if (is_cu12) {
12084 assign(retval2, s390_call_cu12_helper2(mkexpr(byte1), byte2, byte3,
12085 byte4, stuff));
12086 } else {
12087 assign(retval2, s390_call_cu14_helper2(mkexpr(byte1), byte2, byte3,
12088 byte4, stuff));
12089 }
florian6d9b9b22012-08-03 18:35:39 +000012090
12091 /* Check for invalid character */
12092 s390_cc_set(2);
12093 is_invalid = unop(Iop_64to1, mkexpr(retval2));
12094 next_insn_if(is_invalid);
12095
12096 /* Now test whether the 1st operand is exhausted */
12097 IRTemp num_bytes = newTemp(Ity_I64);
12098 assign(num_bytes, binop(Iop_And64,
12099 binop(Iop_Shr64, mkexpr(retval2), mkU8(8)),
12100 mkU64(0xff)));
12101 s390_cc_set(1);
12102 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
12103
12104 /* Extract the bytes to be stored at addr1 */
12105 IRTemp data = newTemp(Ity_I64);
12106 assign(data, binop(Iop_Shr64, mkexpr(retval2), mkU8(16)));
12107
florian3f8a96a2012-08-05 02:59:55 +000012108 if (is_cu12) {
12109 /* To store the bytes construct 2 dirty helper calls. The helper calls
12110 are guarded (num_bytes == 2 and num_bytes == 4, respectively) such
12111 that only one of them will be called at runtime. */
florian6d9b9b22012-08-03 18:35:39 +000012112
florian3f8a96a2012-08-05 02:59:55 +000012113 Int i;
12114 for (i = 2; i <= 4; ++i) {
12115 IRDirty *d;
florian6d9b9b22012-08-03 18:35:39 +000012116
florian3f8a96a2012-08-05 02:59:55 +000012117 if (i == 3) continue; // skip this one
florian6d9b9b22012-08-03 18:35:39 +000012118
florian3f8a96a2012-08-05 02:59:55 +000012119 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
12120 &s390x_dirtyhelper_CUxy,
12121 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
12122 mkexpr(num_bytes)));
12123 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
12124 d->mFx = Ifx_Write;
12125 d->mAddr = mkexpr(addr1);
12126 d->mSize = i;
12127 stmt(IRStmt_Dirty(d));
12128 }
12129 } else {
12130 // cu14
12131 store(mkexpr(addr1), unop(Iop_64to32, mkexpr(data)));
florian6d9b9b22012-08-03 18:35:39 +000012132 }
12133
12134 /* Update source address and length */
12135 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkexpr(num_src_bytes)));
12136 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkexpr(num_src_bytes)));
12137
12138 /* Update destination address and length */
12139 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
12140 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
12141
12142 iterate();
florian3f8a96a2012-08-05 02:59:55 +000012143}
12144
12145static HChar *
12146s390_irgen_CU12(UChar m3, UChar r1, UChar r2)
12147{
12148 s390_irgen_cu12_cu14(m3, r1, r2, /* is_cu12 = */ 1);
florian6d9b9b22012-08-03 18:35:39 +000012149
12150 return "cu12";
12151}
12152
florian3f8a96a2012-08-05 02:59:55 +000012153static HChar *
12154s390_irgen_CU14(UChar m3, UChar r1, UChar r2)
12155{
12156 s390_irgen_cu12_cu14(m3, r1, r2, /* is_cu12 = */ 0);
12157
12158 return "cu14";
12159}
12160
florian8c88cb62012-08-26 18:58:13 +000012161static IRExpr *
12162s390_call_ecag(IRExpr *op2addr)
12163{
12164 IRExpr **args, *call;
12165
12166 args = mkIRExprVec_1(op2addr);
12167 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
12168 "s390_do_ecag", &s390_do_ecag, args);
12169
12170 /* Nothing is excluded from definedness checking. */
12171 call->Iex.CCall.cee->mcx_mask = 0;
12172
12173 return call;
12174}
12175
12176static HChar *
floriand2129202012-09-01 20:01:39 +000012177s390_irgen_ECAG(UChar r1, UChar r3 __attribute__((unused)), IRTemp op2addr)
florian8c88cb62012-08-26 18:58:13 +000012178{
12179 if (! s390_host_has_gie) {
floriane75dafa2012-09-01 17:54:09 +000012180 emulation_failure(EmFail_S390X_ecag);
florian8c88cb62012-08-26 18:58:13 +000012181 } else {
12182 put_gpr_dw0(r1, s390_call_ecag(mkexpr(op2addr)));
12183 }
12184
12185 return "ecag";
12186}
12187
12188
sewardj2019a972011-03-07 16:04:07 +000012189/*------------------------------------------------------------*/
12190/*--- Build IR for special instructions ---*/
12191/*------------------------------------------------------------*/
12192
florianb4df7682011-07-05 02:09:01 +000012193static void
sewardj2019a972011-03-07 16:04:07 +000012194s390_irgen_client_request(void)
12195{
12196 if (0)
12197 vex_printf("%%R3 = client_request ( %%R2 )\n");
12198
florianf9e1ed72012-04-17 02:41:56 +000012199 Addr64 next = guest_IA_curr_instr + S390_SPECIAL_OP_PREAMBLE_SIZE
12200 + S390_SPECIAL_OP_SIZE;
sewardj2019a972011-03-07 16:04:07 +000012201
florianf9e1ed72012-04-17 02:41:56 +000012202 dis_res->jk_StopHere = Ijk_ClientReq;
sewardj2019a972011-03-07 16:04:07 +000012203 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +000012204
12205 put_IA(mkaddr_expr(next));
sewardj2019a972011-03-07 16:04:07 +000012206}
12207
florianb4df7682011-07-05 02:09:01 +000012208static void
sewardj2019a972011-03-07 16:04:07 +000012209s390_irgen_guest_NRADDR(void)
12210{
12211 if (0)
12212 vex_printf("%%R3 = guest_NRADDR\n");
12213
floriane88b3c92011-07-05 02:48:39 +000012214 put_gpr_dw0(3, IRExpr_Get(S390X_GUEST_OFFSET(guest_NRADDR), Ity_I64));
sewardj2019a972011-03-07 16:04:07 +000012215}
12216
florianb4df7682011-07-05 02:09:01 +000012217static void
sewardj2019a972011-03-07 16:04:07 +000012218s390_irgen_call_noredir(void)
12219{
florianf9e1ed72012-04-17 02:41:56 +000012220 Addr64 next = guest_IA_curr_instr + S390_SPECIAL_OP_PREAMBLE_SIZE
12221 + S390_SPECIAL_OP_SIZE;
12222
sewardj2019a972011-03-07 16:04:07 +000012223 /* Continue after special op */
florianf9e1ed72012-04-17 02:41:56 +000012224 put_gpr_dw0(14, mkaddr_expr(next));
sewardj2019a972011-03-07 16:04:07 +000012225
12226 /* The address is in REG1, all parameters are in the right (guest) places */
florianf9e1ed72012-04-17 02:41:56 +000012227 put_IA(get_gpr_dw0(1));
sewardj2019a972011-03-07 16:04:07 +000012228
12229 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +000012230 dis_res->jk_StopHere = Ijk_NoRedir;
sewardj2019a972011-03-07 16:04:07 +000012231}
12232
12233/* Force proper alignment for the structures below. */
12234#pragma pack(1)
12235
12236
12237static s390_decode_t
12238s390_decode_2byte_and_irgen(UChar *bytes)
12239{
12240 typedef union {
12241 struct {
12242 unsigned int op : 16;
12243 } E;
12244 struct {
12245 unsigned int op : 8;
12246 unsigned int i : 8;
12247 } I;
12248 struct {
12249 unsigned int op : 8;
12250 unsigned int r1 : 4;
12251 unsigned int r2 : 4;
12252 } RR;
12253 } formats;
12254 union {
12255 formats fmt;
12256 UShort value;
12257 } ovl;
12258
12259 vassert(sizeof(formats) == 2);
12260
12261 ((char *)(&ovl.value))[0] = bytes[0];
12262 ((char *)(&ovl.value))[1] = bytes[1];
12263
12264 switch (ovl.value & 0xffff) {
12265 case 0x0101: /* PR */ goto unimplemented;
12266 case 0x0102: /* UPT */ goto unimplemented;
12267 case 0x0104: /* PTFF */ goto unimplemented;
12268 case 0x0107: /* SCKPF */ goto unimplemented;
12269 case 0x010a: /* PFPO */ goto unimplemented;
12270 case 0x010b: /* TAM */ goto unimplemented;
12271 case 0x010c: /* SAM24 */ goto unimplemented;
12272 case 0x010d: /* SAM31 */ goto unimplemented;
12273 case 0x010e: /* SAM64 */ goto unimplemented;
12274 case 0x01ff: /* TRAP2 */ goto unimplemented;
12275 }
12276
12277 switch ((ovl.value & 0xff00) >> 8) {
12278 case 0x04: /* SPM */ goto unimplemented;
12279 case 0x05: /* BALR */ goto unimplemented;
12280 case 0x06: s390_format_RR_RR(s390_irgen_BCTR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12281 goto ok;
12282 case 0x07: s390_format_RR(s390_irgen_BCR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12283 goto ok;
12284 case 0x0a: s390_format_I(s390_irgen_SVC, ovl.fmt.I.i); goto ok;
12285 case 0x0b: /* BSM */ goto unimplemented;
12286 case 0x0c: /* BASSM */ goto unimplemented;
12287 case 0x0d: s390_format_RR_RR(s390_irgen_BASR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12288 goto ok;
florianb0c9a132011-09-08 15:37:39 +000012289 case 0x0e: s390_format_RR(s390_irgen_MVCL, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12290 goto ok;
12291 case 0x0f: s390_format_RR(s390_irgen_CLCL, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12292 goto ok;
sewardj2019a972011-03-07 16:04:07 +000012293 case 0x10: s390_format_RR_RR(s390_irgen_LPR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12294 goto ok;
12295 case 0x11: s390_format_RR_RR(s390_irgen_LNR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12296 goto ok;
12297 case 0x12: s390_format_RR_RR(s390_irgen_LTR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12298 goto ok;
12299 case 0x13: s390_format_RR_RR(s390_irgen_LCR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12300 goto ok;
12301 case 0x14: s390_format_RR_RR(s390_irgen_NR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12302 goto ok;
12303 case 0x15: s390_format_RR_RR(s390_irgen_CLR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12304 goto ok;
12305 case 0x16: s390_format_RR_RR(s390_irgen_OR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12306 goto ok;
12307 case 0x17: s390_format_RR_RR(s390_irgen_XR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12308 goto ok;
12309 case 0x18: s390_format_RR_RR(s390_irgen_LR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12310 goto ok;
12311 case 0x19: s390_format_RR_RR(s390_irgen_CR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12312 goto ok;
12313 case 0x1a: s390_format_RR_RR(s390_irgen_AR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12314 goto ok;
12315 case 0x1b: s390_format_RR_RR(s390_irgen_SR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12316 goto ok;
12317 case 0x1c: s390_format_RR_RR(s390_irgen_MR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12318 goto ok;
12319 case 0x1d: s390_format_RR_RR(s390_irgen_DR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12320 goto ok;
12321 case 0x1e: s390_format_RR_RR(s390_irgen_ALR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12322 goto ok;
12323 case 0x1f: s390_format_RR_RR(s390_irgen_SLR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12324 goto ok;
12325 case 0x20: /* LPDR */ goto unimplemented;
12326 case 0x21: /* LNDR */ goto unimplemented;
12327 case 0x22: /* LTDR */ goto unimplemented;
12328 case 0x23: /* LCDR */ goto unimplemented;
12329 case 0x24: /* HDR */ goto unimplemented;
12330 case 0x25: /* LDXR */ goto unimplemented;
12331 case 0x26: /* MXR */ goto unimplemented;
12332 case 0x27: /* MXDR */ goto unimplemented;
12333 case 0x28: s390_format_RR_FF(s390_irgen_LDR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12334 goto ok;
12335 case 0x29: /* CDR */ goto unimplemented;
12336 case 0x2a: /* ADR */ goto unimplemented;
12337 case 0x2b: /* SDR */ goto unimplemented;
12338 case 0x2c: /* MDR */ goto unimplemented;
12339 case 0x2d: /* DDR */ goto unimplemented;
12340 case 0x2e: /* AWR */ goto unimplemented;
12341 case 0x2f: /* SWR */ goto unimplemented;
12342 case 0x30: /* LPER */ goto unimplemented;
12343 case 0x31: /* LNER */ goto unimplemented;
12344 case 0x32: /* LTER */ goto unimplemented;
12345 case 0x33: /* LCER */ goto unimplemented;
12346 case 0x34: /* HER */ goto unimplemented;
12347 case 0x35: /* LEDR */ goto unimplemented;
12348 case 0x36: /* AXR */ goto unimplemented;
12349 case 0x37: /* SXR */ goto unimplemented;
12350 case 0x38: s390_format_RR_FF(s390_irgen_LER, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12351 goto ok;
12352 case 0x39: /* CER */ goto unimplemented;
12353 case 0x3a: /* AER */ goto unimplemented;
12354 case 0x3b: /* SER */ goto unimplemented;
12355 case 0x3c: /* MDER */ goto unimplemented;
12356 case 0x3d: /* DER */ goto unimplemented;
12357 case 0x3e: /* AUR */ goto unimplemented;
12358 case 0x3f: /* SUR */ goto unimplemented;
12359 }
12360
12361 return S390_DECODE_UNKNOWN_INSN;
12362
12363ok:
12364 return S390_DECODE_OK;
12365
12366unimplemented:
12367 return S390_DECODE_UNIMPLEMENTED_INSN;
12368}
12369
12370static s390_decode_t
12371s390_decode_4byte_and_irgen(UChar *bytes)
12372{
12373 typedef union {
12374 struct {
12375 unsigned int op1 : 8;
12376 unsigned int r1 : 4;
12377 unsigned int op2 : 4;
12378 unsigned int i2 : 16;
12379 } RI;
12380 struct {
12381 unsigned int op : 16;
12382 unsigned int : 8;
12383 unsigned int r1 : 4;
12384 unsigned int r2 : 4;
12385 } RRE;
12386 struct {
12387 unsigned int op : 16;
12388 unsigned int r1 : 4;
12389 unsigned int : 4;
12390 unsigned int r3 : 4;
12391 unsigned int r2 : 4;
12392 } RRF;
12393 struct {
12394 unsigned int op : 16;
florian1c8f7ff2012-09-01 00:12:11 +000012395 unsigned int m3 : 4;
sewardj2019a972011-03-07 16:04:07 +000012396 unsigned int m4 : 4;
12397 unsigned int r1 : 4;
12398 unsigned int r2 : 4;
12399 } RRF2;
12400 struct {
12401 unsigned int op : 16;
12402 unsigned int r3 : 4;
12403 unsigned int : 4;
12404 unsigned int r1 : 4;
12405 unsigned int r2 : 4;
12406 } RRF3;
12407 struct {
12408 unsigned int op : 16;
12409 unsigned int r3 : 4;
12410 unsigned int : 4;
12411 unsigned int r1 : 4;
12412 unsigned int r2 : 4;
12413 } RRR;
12414 struct {
12415 unsigned int op : 16;
12416 unsigned int r3 : 4;
12417 unsigned int : 4;
12418 unsigned int r1 : 4;
12419 unsigned int r2 : 4;
12420 } RRF4;
12421 struct {
12422 unsigned int op : 8;
12423 unsigned int r1 : 4;
12424 unsigned int r3 : 4;
12425 unsigned int b2 : 4;
12426 unsigned int d2 : 12;
12427 } RS;
12428 struct {
12429 unsigned int op : 8;
12430 unsigned int r1 : 4;
12431 unsigned int r3 : 4;
12432 unsigned int i2 : 16;
12433 } RSI;
12434 struct {
12435 unsigned int op : 8;
12436 unsigned int r1 : 4;
12437 unsigned int x2 : 4;
12438 unsigned int b2 : 4;
12439 unsigned int d2 : 12;
12440 } RX;
12441 struct {
12442 unsigned int op : 16;
12443 unsigned int b2 : 4;
12444 unsigned int d2 : 12;
12445 } S;
12446 struct {
12447 unsigned int op : 8;
12448 unsigned int i2 : 8;
12449 unsigned int b1 : 4;
12450 unsigned int d1 : 12;
12451 } SI;
12452 } formats;
12453 union {
12454 formats fmt;
12455 UInt value;
12456 } ovl;
12457
12458 vassert(sizeof(formats) == 4);
12459
12460 ((char *)(&ovl.value))[0] = bytes[0];
12461 ((char *)(&ovl.value))[1] = bytes[1];
12462 ((char *)(&ovl.value))[2] = bytes[2];
12463 ((char *)(&ovl.value))[3] = bytes[3];
12464
12465 switch ((ovl.value & 0xff0f0000) >> 16) {
12466 case 0xa500: s390_format_RI_RU(s390_irgen_IIHH, ovl.fmt.RI.r1,
12467 ovl.fmt.RI.i2); goto ok;
12468 case 0xa501: s390_format_RI_RU(s390_irgen_IIHL, ovl.fmt.RI.r1,
12469 ovl.fmt.RI.i2); goto ok;
12470 case 0xa502: s390_format_RI_RU(s390_irgen_IILH, ovl.fmt.RI.r1,
12471 ovl.fmt.RI.i2); goto ok;
12472 case 0xa503: s390_format_RI_RU(s390_irgen_IILL, ovl.fmt.RI.r1,
12473 ovl.fmt.RI.i2); goto ok;
12474 case 0xa504: s390_format_RI_RU(s390_irgen_NIHH, ovl.fmt.RI.r1,
12475 ovl.fmt.RI.i2); goto ok;
12476 case 0xa505: s390_format_RI_RU(s390_irgen_NIHL, ovl.fmt.RI.r1,
12477 ovl.fmt.RI.i2); goto ok;
12478 case 0xa506: s390_format_RI_RU(s390_irgen_NILH, ovl.fmt.RI.r1,
12479 ovl.fmt.RI.i2); goto ok;
12480 case 0xa507: s390_format_RI_RU(s390_irgen_NILL, ovl.fmt.RI.r1,
12481 ovl.fmt.RI.i2); goto ok;
12482 case 0xa508: s390_format_RI_RU(s390_irgen_OIHH, ovl.fmt.RI.r1,
12483 ovl.fmt.RI.i2); goto ok;
12484 case 0xa509: s390_format_RI_RU(s390_irgen_OIHL, ovl.fmt.RI.r1,
12485 ovl.fmt.RI.i2); goto ok;
12486 case 0xa50a: s390_format_RI_RU(s390_irgen_OILH, ovl.fmt.RI.r1,
12487 ovl.fmt.RI.i2); goto ok;
12488 case 0xa50b: s390_format_RI_RU(s390_irgen_OILL, ovl.fmt.RI.r1,
12489 ovl.fmt.RI.i2); goto ok;
12490 case 0xa50c: s390_format_RI_RU(s390_irgen_LLIHH, ovl.fmt.RI.r1,
12491 ovl.fmt.RI.i2); goto ok;
12492 case 0xa50d: s390_format_RI_RU(s390_irgen_LLIHL, ovl.fmt.RI.r1,
12493 ovl.fmt.RI.i2); goto ok;
12494 case 0xa50e: s390_format_RI_RU(s390_irgen_LLILH, ovl.fmt.RI.r1,
12495 ovl.fmt.RI.i2); goto ok;
12496 case 0xa50f: s390_format_RI_RU(s390_irgen_LLILL, ovl.fmt.RI.r1,
12497 ovl.fmt.RI.i2); goto ok;
12498 case 0xa700: s390_format_RI_RU(s390_irgen_TMLH, ovl.fmt.RI.r1,
12499 ovl.fmt.RI.i2); goto ok;
12500 case 0xa701: s390_format_RI_RU(s390_irgen_TMLL, ovl.fmt.RI.r1,
12501 ovl.fmt.RI.i2); goto ok;
12502 case 0xa702: s390_format_RI_RU(s390_irgen_TMHH, ovl.fmt.RI.r1,
12503 ovl.fmt.RI.i2); goto ok;
12504 case 0xa703: s390_format_RI_RU(s390_irgen_TMHL, ovl.fmt.RI.r1,
12505 ovl.fmt.RI.i2); goto ok;
12506 case 0xa704: s390_format_RI(s390_irgen_BRC, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
12507 goto ok;
12508 case 0xa705: s390_format_RI_RP(s390_irgen_BRAS, ovl.fmt.RI.r1,
12509 ovl.fmt.RI.i2); goto ok;
12510 case 0xa706: s390_format_RI_RP(s390_irgen_BRCT, ovl.fmt.RI.r1,
12511 ovl.fmt.RI.i2); goto ok;
12512 case 0xa707: s390_format_RI_RP(s390_irgen_BRCTG, ovl.fmt.RI.r1,
12513 ovl.fmt.RI.i2); goto ok;
12514 case 0xa708: s390_format_RI_RI(s390_irgen_LHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
12515 goto ok;
12516 case 0xa709: s390_format_RI_RI(s390_irgen_LGHI, ovl.fmt.RI.r1,
12517 ovl.fmt.RI.i2); goto ok;
12518 case 0xa70a: s390_format_RI_RI(s390_irgen_AHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
12519 goto ok;
12520 case 0xa70b: s390_format_RI_RI(s390_irgen_AGHI, ovl.fmt.RI.r1,
12521 ovl.fmt.RI.i2); goto ok;
12522 case 0xa70c: s390_format_RI_RI(s390_irgen_MHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
12523 goto ok;
12524 case 0xa70d: s390_format_RI_RI(s390_irgen_MGHI, ovl.fmt.RI.r1,
12525 ovl.fmt.RI.i2); goto ok;
12526 case 0xa70e: s390_format_RI_RI(s390_irgen_CHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
12527 goto ok;
12528 case 0xa70f: s390_format_RI_RI(s390_irgen_CGHI, ovl.fmt.RI.r1,
12529 ovl.fmt.RI.i2); goto ok;
12530 }
12531
12532 switch ((ovl.value & 0xffff0000) >> 16) {
12533 case 0x8000: /* SSM */ goto unimplemented;
12534 case 0x8200: /* LPSW */ goto unimplemented;
florian7700fc92012-01-16 17:25:55 +000012535 case 0x9300: /* TS */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000012536 case 0xb202: /* STIDP */ goto unimplemented;
12537 case 0xb204: /* SCK */ goto unimplemented;
florian7700fc92012-01-16 17:25:55 +000012538 case 0xb205: s390_format_S_RD(s390_irgen_STCK, ovl.fmt.S.b2, ovl.fmt.S.d2);
12539 goto ok;
sewardj2019a972011-03-07 16:04:07 +000012540 case 0xb206: /* SCKC */ goto unimplemented;
12541 case 0xb207: /* STCKC */ goto unimplemented;
12542 case 0xb208: /* SPT */ goto unimplemented;
12543 case 0xb209: /* STPT */ goto unimplemented;
12544 case 0xb20a: /* SPKA */ goto unimplemented;
12545 case 0xb20b: /* IPK */ goto unimplemented;
12546 case 0xb20d: /* PTLB */ goto unimplemented;
12547 case 0xb210: /* SPX */ goto unimplemented;
12548 case 0xb211: /* STPX */ goto unimplemented;
12549 case 0xb212: /* STAP */ goto unimplemented;
12550 case 0xb214: /* SIE */ goto unimplemented;
12551 case 0xb218: /* PC */ goto unimplemented;
12552 case 0xb219: /* SAC */ goto unimplemented;
12553 case 0xb21a: /* CFC */ goto unimplemented;
12554 case 0xb221: /* IPTE */ goto unimplemented;
12555 case 0xb222: s390_format_RRE_R0(s390_irgen_IPM, ovl.fmt.RRE.r1); goto ok;
12556 case 0xb223: /* IVSK */ goto unimplemented;
12557 case 0xb224: /* IAC */ goto unimplemented;
12558 case 0xb225: /* SSAR */ goto unimplemented;
12559 case 0xb226: /* EPAR */ goto unimplemented;
12560 case 0xb227: /* ESAR */ goto unimplemented;
12561 case 0xb228: /* PT */ goto unimplemented;
12562 case 0xb229: /* ISKE */ goto unimplemented;
12563 case 0xb22a: /* RRBE */ goto unimplemented;
12564 case 0xb22b: /* SSKE */ goto unimplemented;
12565 case 0xb22c: /* TB */ goto unimplemented;
12566 case 0xb22d: /* DXR */ goto unimplemented;
12567 case 0xb22e: /* PGIN */ goto unimplemented;
12568 case 0xb22f: /* PGOUT */ goto unimplemented;
12569 case 0xb230: /* CSCH */ goto unimplemented;
12570 case 0xb231: /* HSCH */ goto unimplemented;
12571 case 0xb232: /* MSCH */ goto unimplemented;
12572 case 0xb233: /* SSCH */ goto unimplemented;
12573 case 0xb234: /* STSCH */ goto unimplemented;
12574 case 0xb235: /* TSCH */ goto unimplemented;
12575 case 0xb236: /* TPI */ goto unimplemented;
12576 case 0xb237: /* SAL */ goto unimplemented;
12577 case 0xb238: /* RSCH */ goto unimplemented;
12578 case 0xb239: /* STCRW */ goto unimplemented;
12579 case 0xb23a: /* STCPS */ goto unimplemented;
12580 case 0xb23b: /* RCHP */ goto unimplemented;
12581 case 0xb23c: /* SCHM */ goto unimplemented;
12582 case 0xb240: /* BAKR */ goto unimplemented;
floriana4384a32011-08-11 16:58:45 +000012583 case 0xb241: s390_format_RRE(s390_irgen_CKSM, ovl.fmt.RRE.r1,
12584 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000012585 case 0xb244: /* SQDR */ goto unimplemented;
12586 case 0xb245: /* SQER */ goto unimplemented;
12587 case 0xb246: /* STURA */ goto unimplemented;
12588 case 0xb247: /* MSTA */ goto unimplemented;
12589 case 0xb248: /* PALB */ goto unimplemented;
12590 case 0xb249: /* EREG */ goto unimplemented;
12591 case 0xb24a: /* ESTA */ goto unimplemented;
12592 case 0xb24b: /* LURA */ goto unimplemented;
12593 case 0xb24c: /* TAR */ goto unimplemented;
12594 case 0xb24d: s390_format_RRE(s390_irgen_CPYA, ovl.fmt.RRE.r1,
12595 ovl.fmt.RRE.r2); goto ok;
12596 case 0xb24e: s390_format_RRE(s390_irgen_SAR, ovl.fmt.RRE.r1, ovl.fmt.RRE.r2);
12597 goto ok;
12598 case 0xb24f: s390_format_RRE(s390_irgen_EAR, ovl.fmt.RRE.r1, ovl.fmt.RRE.r2);
12599 goto ok;
12600 case 0xb250: /* CSP */ goto unimplemented;
12601 case 0xb252: s390_format_RRE_RR(s390_irgen_MSR, ovl.fmt.RRE.r1,
12602 ovl.fmt.RRE.r2); goto ok;
12603 case 0xb254: /* MVPG */ goto unimplemented;
12604 case 0xb255: s390_format_RRE_RR(s390_irgen_MVST, ovl.fmt.RRE.r1,
12605 ovl.fmt.RRE.r2); goto ok;
12606 case 0xb257: /* CUSE */ goto unimplemented;
12607 case 0xb258: /* BSG */ goto unimplemented;
12608 case 0xb25a: /* BSA */ goto unimplemented;
12609 case 0xb25d: s390_format_RRE_RR(s390_irgen_CLST, ovl.fmt.RRE.r1,
12610 ovl.fmt.RRE.r2); goto ok;
12611 case 0xb25e: s390_format_RRE_RR(s390_irgen_SRST, ovl.fmt.RRE.r1,
12612 ovl.fmt.RRE.r2); goto ok;
12613 case 0xb263: /* CMPSC */ goto unimplemented;
12614 case 0xb274: /* SIGA */ goto unimplemented;
12615 case 0xb276: /* XSCH */ goto unimplemented;
12616 case 0xb277: /* RP */ goto unimplemented;
sewardj1e5fea62011-05-17 16:18:36 +000012617 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 +000012618 case 0xb279: /* SACF */ goto unimplemented;
sewardj1e5fea62011-05-17 16:18:36 +000012619 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 +000012620 case 0xb27d: /* STSI */ goto unimplemented;
12621 case 0xb299: s390_format_S_RD(s390_irgen_SRNM, ovl.fmt.S.b2, ovl.fmt.S.d2);
12622 goto ok;
12623 case 0xb29c: s390_format_S_RD(s390_irgen_STFPC, ovl.fmt.S.b2, ovl.fmt.S.d2);
12624 goto ok;
12625 case 0xb29d: s390_format_S_RD(s390_irgen_LFPC, ovl.fmt.S.b2, ovl.fmt.S.d2);
12626 goto ok;
florian730448f2012-02-04 17:07:07 +000012627 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 +000012628 case 0xb2a6: s390_format_RRF_M0RERE(s390_irgen_CU21, ovl.fmt.RRF3.r3,
12629 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
12630 goto ok;
florian6d9b9b22012-08-03 18:35:39 +000012631 case 0xb2a7: s390_format_RRF_M0RERE(s390_irgen_CU12, ovl.fmt.RRF3.r3,
12632 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
12633 goto ok;
florian933065d2011-07-11 01:48:02 +000012634 case 0xb2b0: s390_format_S_RD(s390_irgen_STFLE, ovl.fmt.S.b2, ovl.fmt.S.d2);
12635 goto ok;
sewardj2019a972011-03-07 16:04:07 +000012636 case 0xb2b1: /* STFL */ goto unimplemented;
12637 case 0xb2b2: /* LPSWE */ goto unimplemented;
12638 case 0xb2b8: /* SRNMB */ goto unimplemented;
12639 case 0xb2b9: /* SRNMT */ goto unimplemented;
12640 case 0xb2bd: /* LFAS */ goto unimplemented;
12641 case 0xb2ff: /* TRAP4 */ goto unimplemented;
12642 case 0xb300: s390_format_RRE_FF(s390_irgen_LPEBR, ovl.fmt.RRE.r1,
12643 ovl.fmt.RRE.r2); goto ok;
12644 case 0xb301: s390_format_RRE_FF(s390_irgen_LNEBR, ovl.fmt.RRE.r1,
12645 ovl.fmt.RRE.r2); goto ok;
12646 case 0xb302: s390_format_RRE_FF(s390_irgen_LTEBR, ovl.fmt.RRE.r1,
12647 ovl.fmt.RRE.r2); goto ok;
12648 case 0xb303: s390_format_RRE_FF(s390_irgen_LCEBR, ovl.fmt.RRE.r1,
12649 ovl.fmt.RRE.r2); goto ok;
12650 case 0xb304: s390_format_RRE_FF(s390_irgen_LDEBR, ovl.fmt.RRE.r1,
12651 ovl.fmt.RRE.r2); goto ok;
12652 case 0xb305: s390_format_RRE_FF(s390_irgen_LXDBR, ovl.fmt.RRE.r1,
12653 ovl.fmt.RRE.r2); goto ok;
12654 case 0xb306: s390_format_RRE_FF(s390_irgen_LXEBR, ovl.fmt.RRE.r1,
12655 ovl.fmt.RRE.r2); goto ok;
12656 case 0xb307: /* MXDBR */ goto unimplemented;
12657 case 0xb308: /* KEBR */ goto unimplemented;
12658 case 0xb309: s390_format_RRE_FF(s390_irgen_CEBR, ovl.fmt.RRE.r1,
12659 ovl.fmt.RRE.r2); goto ok;
12660 case 0xb30a: s390_format_RRE_FF(s390_irgen_AEBR, ovl.fmt.RRE.r1,
12661 ovl.fmt.RRE.r2); goto ok;
12662 case 0xb30b: s390_format_RRE_FF(s390_irgen_SEBR, ovl.fmt.RRE.r1,
12663 ovl.fmt.RRE.r2); goto ok;
12664 case 0xb30c: /* MDEBR */ goto unimplemented;
12665 case 0xb30d: s390_format_RRE_FF(s390_irgen_DEBR, ovl.fmt.RRE.r1,
12666 ovl.fmt.RRE.r2); goto ok;
12667 case 0xb30e: s390_format_RRF_F0FF(s390_irgen_MAEBR, ovl.fmt.RRF.r1,
12668 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
12669 case 0xb30f: s390_format_RRF_F0FF(s390_irgen_MSEBR, ovl.fmt.RRF.r1,
12670 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
12671 case 0xb310: s390_format_RRE_FF(s390_irgen_LPDBR, ovl.fmt.RRE.r1,
12672 ovl.fmt.RRE.r2); goto ok;
12673 case 0xb311: s390_format_RRE_FF(s390_irgen_LNDBR, ovl.fmt.RRE.r1,
12674 ovl.fmt.RRE.r2); goto ok;
12675 case 0xb312: s390_format_RRE_FF(s390_irgen_LTDBR, ovl.fmt.RRE.r1,
12676 ovl.fmt.RRE.r2); goto ok;
12677 case 0xb313: s390_format_RRE_FF(s390_irgen_LCDBR, ovl.fmt.RRE.r1,
12678 ovl.fmt.RRE.r2); goto ok;
12679 case 0xb314: s390_format_RRE_FF(s390_irgen_SQEBR, ovl.fmt.RRE.r1,
12680 ovl.fmt.RRE.r2); goto ok;
12681 case 0xb315: s390_format_RRE_FF(s390_irgen_SQDBR, ovl.fmt.RRE.r1,
12682 ovl.fmt.RRE.r2); goto ok;
12683 case 0xb316: s390_format_RRE_FF(s390_irgen_SQXBR, ovl.fmt.RRE.r1,
12684 ovl.fmt.RRE.r2); goto ok;
12685 case 0xb317: s390_format_RRE_FF(s390_irgen_MEEBR, ovl.fmt.RRE.r1,
12686 ovl.fmt.RRE.r2); goto ok;
12687 case 0xb318: /* KDBR */ goto unimplemented;
12688 case 0xb319: s390_format_RRE_FF(s390_irgen_CDBR, ovl.fmt.RRE.r1,
12689 ovl.fmt.RRE.r2); goto ok;
12690 case 0xb31a: s390_format_RRE_FF(s390_irgen_ADBR, ovl.fmt.RRE.r1,
12691 ovl.fmt.RRE.r2); goto ok;
12692 case 0xb31b: s390_format_RRE_FF(s390_irgen_SDBR, ovl.fmt.RRE.r1,
12693 ovl.fmt.RRE.r2); goto ok;
12694 case 0xb31c: s390_format_RRE_FF(s390_irgen_MDBR, ovl.fmt.RRE.r1,
12695 ovl.fmt.RRE.r2); goto ok;
12696 case 0xb31d: s390_format_RRE_FF(s390_irgen_DDBR, ovl.fmt.RRE.r1,
12697 ovl.fmt.RRE.r2); goto ok;
12698 case 0xb31e: s390_format_RRF_F0FF(s390_irgen_MADBR, ovl.fmt.RRF.r1,
12699 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
12700 case 0xb31f: s390_format_RRF_F0FF(s390_irgen_MSDBR, ovl.fmt.RRF.r1,
12701 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
12702 case 0xb324: /* LDER */ goto unimplemented;
12703 case 0xb325: /* LXDR */ goto unimplemented;
12704 case 0xb326: /* LXER */ goto unimplemented;
12705 case 0xb32e: /* MAER */ goto unimplemented;
12706 case 0xb32f: /* MSER */ goto unimplemented;
12707 case 0xb336: /* SQXR */ goto unimplemented;
12708 case 0xb337: /* MEER */ goto unimplemented;
12709 case 0xb338: /* MAYLR */ goto unimplemented;
12710 case 0xb339: /* MYLR */ goto unimplemented;
12711 case 0xb33a: /* MAYR */ goto unimplemented;
12712 case 0xb33b: /* MYR */ goto unimplemented;
12713 case 0xb33c: /* MAYHR */ goto unimplemented;
12714 case 0xb33d: /* MYHR */ goto unimplemented;
12715 case 0xb33e: /* MADR */ goto unimplemented;
12716 case 0xb33f: /* MSDR */ goto unimplemented;
12717 case 0xb340: s390_format_RRE_FF(s390_irgen_LPXBR, ovl.fmt.RRE.r1,
12718 ovl.fmt.RRE.r2); goto ok;
12719 case 0xb341: s390_format_RRE_FF(s390_irgen_LNXBR, ovl.fmt.RRE.r1,
12720 ovl.fmt.RRE.r2); goto ok;
12721 case 0xb342: s390_format_RRE_FF(s390_irgen_LTXBR, ovl.fmt.RRE.r1,
12722 ovl.fmt.RRE.r2); goto ok;
12723 case 0xb343: s390_format_RRE_FF(s390_irgen_LCXBR, ovl.fmt.RRE.r1,
12724 ovl.fmt.RRE.r2); goto ok;
florian4b8efad2012-09-02 18:07:08 +000012725 case 0xb344: s390_format_RRF_UUFF(s390_irgen_LEDBR, ovl.fmt.RRF2.m3,
12726 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12727 ovl.fmt.RRF2.r2); goto ok;
12728 case 0xb345: s390_format_RRF_UUFF(s390_irgen_LDXBR, ovl.fmt.RRF2.m3,
12729 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12730 ovl.fmt.RRF2.r2); goto ok;
12731 case 0xb346: s390_format_RRF_UUFF(s390_irgen_LEXBR, ovl.fmt.RRF2.m3,
12732 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12733 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000012734 case 0xb347: /* FIXBR */ goto unimplemented;
12735 case 0xb348: /* KXBR */ goto unimplemented;
12736 case 0xb349: s390_format_RRE_FF(s390_irgen_CXBR, ovl.fmt.RRE.r1,
12737 ovl.fmt.RRE.r2); goto ok;
12738 case 0xb34a: s390_format_RRE_FF(s390_irgen_AXBR, ovl.fmt.RRE.r1,
12739 ovl.fmt.RRE.r2); goto ok;
12740 case 0xb34b: s390_format_RRE_FF(s390_irgen_SXBR, ovl.fmt.RRE.r1,
12741 ovl.fmt.RRE.r2); goto ok;
12742 case 0xb34c: s390_format_RRE_FF(s390_irgen_MXBR, ovl.fmt.RRE.r1,
12743 ovl.fmt.RRE.r2); goto ok;
12744 case 0xb34d: s390_format_RRE_FF(s390_irgen_DXBR, ovl.fmt.RRE.r1,
12745 ovl.fmt.RRE.r2); goto ok;
12746 case 0xb350: /* TBEDR */ goto unimplemented;
12747 case 0xb351: /* TBDR */ goto unimplemented;
12748 case 0xb353: /* DIEBR */ goto unimplemented;
12749 case 0xb357: /* FIEBR */ goto unimplemented;
12750 case 0xb358: /* THDER */ goto unimplemented;
12751 case 0xb359: /* THDR */ goto unimplemented;
12752 case 0xb35b: /* DIDBR */ goto unimplemented;
12753 case 0xb35f: /* FIDBR */ goto unimplemented;
12754 case 0xb360: /* LPXR */ goto unimplemented;
12755 case 0xb361: /* LNXR */ goto unimplemented;
12756 case 0xb362: /* LTXR */ goto unimplemented;
12757 case 0xb363: /* LCXR */ goto unimplemented;
12758 case 0xb365: s390_format_RRE_FF(s390_irgen_LXR, ovl.fmt.RRE.r1,
12759 ovl.fmt.RRE.r2); goto ok;
12760 case 0xb366: /* LEXR */ goto unimplemented;
12761 case 0xb367: /* FIXR */ goto unimplemented;
12762 case 0xb369: /* CXR */ goto unimplemented;
12763 case 0xb370: s390_format_RRE_FF(s390_irgen_LPDFR, ovl.fmt.RRE.r1,
12764 ovl.fmt.RRE.r2); goto ok;
12765 case 0xb371: s390_format_RRE_FF(s390_irgen_LNDFR, ovl.fmt.RRE.r1,
12766 ovl.fmt.RRE.r2); goto ok;
12767 case 0xb372: s390_format_RRF_F0FF2(s390_irgen_CPSDR, ovl.fmt.RRF3.r3,
12768 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
12769 goto ok;
12770 case 0xb373: s390_format_RRE_FF(s390_irgen_LCDFR, ovl.fmt.RRE.r1,
12771 ovl.fmt.RRE.r2); goto ok;
12772 case 0xb374: s390_format_RRE_F0(s390_irgen_LZER, ovl.fmt.RRE.r1); goto ok;
12773 case 0xb375: s390_format_RRE_F0(s390_irgen_LZDR, ovl.fmt.RRE.r1); goto ok;
12774 case 0xb376: s390_format_RRE_F0(s390_irgen_LZXR, ovl.fmt.RRE.r1); goto ok;
12775 case 0xb377: /* FIER */ goto unimplemented;
12776 case 0xb37f: /* FIDR */ goto unimplemented;
12777 case 0xb384: s390_format_RRE_R0(s390_irgen_SFPC, ovl.fmt.RRE.r1); goto ok;
12778 case 0xb385: /* SFASR */ goto unimplemented;
12779 case 0xb38c: s390_format_RRE_R0(s390_irgen_EFPC, ovl.fmt.RRE.r1); goto ok;
florian1c8f7ff2012-09-01 00:12:11 +000012780 case 0xb390: s390_format_RRF_UUFR(s390_irgen_CELFBR, ovl.fmt.RRF2.m3,
12781 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12782 ovl.fmt.RRF2.r2); goto ok;
12783 case 0xb391: s390_format_RRF_UUFR(s390_irgen_CDLFBR, ovl.fmt.RRF2.m3,
12784 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12785 ovl.fmt.RRF2.r2); goto ok;
12786 case 0xb392: s390_format_RRF_UUFR(s390_irgen_CXLFBR, ovl.fmt.RRF2.m3,
12787 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12788 ovl.fmt.RRF2.r2); goto ok;
florian4b8efad2012-09-02 18:07:08 +000012789 case 0xb394: s390_format_RRF_UUFR(s390_irgen_CEFBR, ovl.fmt.RRF2.m3,
12790 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12791 ovl.fmt.RRF2.r2); goto ok;
12792 case 0xb395: s390_format_RRF_UUFR(s390_irgen_CDFBR, ovl.fmt.RRF2.m3,
12793 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12794 ovl.fmt.RRF2.r2); goto ok;
12795 case 0xb396: s390_format_RRF_UUFR(s390_irgen_CXFBR, ovl.fmt.RRF2.m3,
12796 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12797 ovl.fmt.RRF2.r2); goto ok;
12798 case 0xb398: s390_format_RRF_UURF(s390_irgen_CFEBR, ovl.fmt.RRF2.m3,
12799 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12800 ovl.fmt.RRF2.r2); goto ok;
12801 case 0xb399: s390_format_RRF_UURF(s390_irgen_CFDBR, ovl.fmt.RRF2.m3,
12802 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12803 ovl.fmt.RRF2.r2); goto ok;
12804 case 0xb39a: s390_format_RRF_UURF(s390_irgen_CFXBR, ovl.fmt.RRF2.m3,
12805 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12806 ovl.fmt.RRF2.r2); goto ok;
florian1c8f7ff2012-09-01 00:12:11 +000012807 case 0xb39c: s390_format_RRF_UURF(s390_irgen_CLFEBR, ovl.fmt.RRF2.m3,
12808 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12809 ovl.fmt.RRF2.r2); goto ok;
12810 case 0xb39d: s390_format_RRF_UURF(s390_irgen_CLFDBR, ovl.fmt.RRF2.m3,
12811 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12812 ovl.fmt.RRF2.r2); goto ok;
12813 case 0xb39e: s390_format_RRF_UURF(s390_irgen_CLFXBR, ovl.fmt.RRF2.m3,
12814 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12815 ovl.fmt.RRF2.r2); goto ok;
12816 case 0xb3a0: s390_format_RRF_UUFR(s390_irgen_CELGBR, ovl.fmt.RRF2.m3,
12817 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12818 ovl.fmt.RRF2.r2); goto ok;
12819 case 0xb3a1: s390_format_RRF_UUFR(s390_irgen_CDLGBR, ovl.fmt.RRF2.m3,
12820 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12821 ovl.fmt.RRF2.r2); goto ok;
12822 case 0xb3a2: s390_format_RRF_UUFR(s390_irgen_CXLGBR, ovl.fmt.RRF2.m3,
12823 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12824 ovl.fmt.RRF2.r2); goto ok;
florian4b8efad2012-09-02 18:07:08 +000012825 case 0xb3a4: s390_format_RRF_UUFR(s390_irgen_CEGBR, ovl.fmt.RRF2.m3,
12826 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12827 ovl.fmt.RRF2.r2); goto ok;
12828 case 0xb3a5: s390_format_RRF_UUFR(s390_irgen_CDGBR, ovl.fmt.RRF2.m3,
12829 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12830 ovl.fmt.RRF2.r2); goto ok;
12831 case 0xb3a6: s390_format_RRF_UUFR(s390_irgen_CXGBR, ovl.fmt.RRF2.m3,
12832 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12833 ovl.fmt.RRF2.r2); goto ok;
12834 case 0xb3a8: s390_format_RRF_UURF(s390_irgen_CGEBR, ovl.fmt.RRF2.m3,
12835 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12836 ovl.fmt.RRF2.r2); goto ok;
12837 case 0xb3a9: s390_format_RRF_UURF(s390_irgen_CGDBR, ovl.fmt.RRF2.m3,
12838 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12839 ovl.fmt.RRF2.r2); goto ok;
12840 case 0xb3aa: s390_format_RRF_UURF(s390_irgen_CGXBR, ovl.fmt.RRF2.m3,
12841 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12842 ovl.fmt.RRF2.r2); goto ok;
florian1c8f7ff2012-09-01 00:12:11 +000012843 case 0xb3ac: s390_format_RRF_UURF(s390_irgen_CLGEBR, ovl.fmt.RRF2.m3,
12844 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12845 ovl.fmt.RRF2.r2); goto ok;
12846 case 0xb3ad: s390_format_RRF_UURF(s390_irgen_CLGDBR, ovl.fmt.RRF2.m3,
12847 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12848 ovl.fmt.RRF2.r2); goto ok;
12849 case 0xb3ae: s390_format_RRF_UURF(s390_irgen_CLGXBR, ovl.fmt.RRF2.m3,
12850 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12851 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000012852 case 0xb3b4: /* CEFR */ goto unimplemented;
12853 case 0xb3b5: /* CDFR */ goto unimplemented;
12854 case 0xb3b6: /* CXFR */ goto unimplemented;
12855 case 0xb3b8: /* CFER */ goto unimplemented;
12856 case 0xb3b9: /* CFDR */ goto unimplemented;
12857 case 0xb3ba: /* CFXR */ goto unimplemented;
12858 case 0xb3c1: s390_format_RRE_FR(s390_irgen_LDGR, ovl.fmt.RRE.r1,
12859 ovl.fmt.RRE.r2); goto ok;
12860 case 0xb3c4: /* CEGR */ goto unimplemented;
12861 case 0xb3c5: /* CDGR */ goto unimplemented;
12862 case 0xb3c6: /* CXGR */ goto unimplemented;
12863 case 0xb3c8: /* CGER */ goto unimplemented;
12864 case 0xb3c9: /* CGDR */ goto unimplemented;
12865 case 0xb3ca: /* CGXR */ goto unimplemented;
12866 case 0xb3cd: s390_format_RRE_RF(s390_irgen_LGDR, ovl.fmt.RRE.r1,
12867 ovl.fmt.RRE.r2); goto ok;
12868 case 0xb3d0: /* MDTR */ goto unimplemented;
12869 case 0xb3d1: /* DDTR */ goto unimplemented;
12870 case 0xb3d2: /* ADTR */ goto unimplemented;
12871 case 0xb3d3: /* SDTR */ goto unimplemented;
12872 case 0xb3d4: /* LDETR */ goto unimplemented;
12873 case 0xb3d5: /* LEDTR */ goto unimplemented;
12874 case 0xb3d6: /* LTDTR */ goto unimplemented;
12875 case 0xb3d7: /* FIDTR */ goto unimplemented;
12876 case 0xb3d8: /* MXTR */ goto unimplemented;
12877 case 0xb3d9: /* DXTR */ goto unimplemented;
12878 case 0xb3da: /* AXTR */ goto unimplemented;
12879 case 0xb3db: /* SXTR */ goto unimplemented;
12880 case 0xb3dc: /* LXDTR */ goto unimplemented;
12881 case 0xb3dd: /* LDXTR */ goto unimplemented;
12882 case 0xb3de: /* LTXTR */ goto unimplemented;
12883 case 0xb3df: /* FIXTR */ goto unimplemented;
12884 case 0xb3e0: /* KDTR */ goto unimplemented;
12885 case 0xb3e1: /* CGDTR */ goto unimplemented;
12886 case 0xb3e2: /* CUDTR */ goto unimplemented;
12887 case 0xb3e3: /* CSDTR */ goto unimplemented;
12888 case 0xb3e4: /* CDTR */ goto unimplemented;
12889 case 0xb3e5: /* EEDTR */ goto unimplemented;
12890 case 0xb3e7: /* ESDTR */ goto unimplemented;
12891 case 0xb3e8: /* KXTR */ goto unimplemented;
12892 case 0xb3e9: /* CGXTR */ goto unimplemented;
12893 case 0xb3ea: /* CUXTR */ goto unimplemented;
12894 case 0xb3eb: /* CSXTR */ goto unimplemented;
12895 case 0xb3ec: /* CXTR */ goto unimplemented;
12896 case 0xb3ed: /* EEXTR */ goto unimplemented;
12897 case 0xb3ef: /* ESXTR */ goto unimplemented;
12898 case 0xb3f1: /* CDGTR */ goto unimplemented;
12899 case 0xb3f2: /* CDUTR */ goto unimplemented;
12900 case 0xb3f3: /* CDSTR */ goto unimplemented;
12901 case 0xb3f4: /* CEDTR */ goto unimplemented;
12902 case 0xb3f5: /* QADTR */ goto unimplemented;
12903 case 0xb3f6: /* IEDTR */ goto unimplemented;
12904 case 0xb3f7: /* RRDTR */ goto unimplemented;
12905 case 0xb3f9: /* CXGTR */ goto unimplemented;
12906 case 0xb3fa: /* CXUTR */ goto unimplemented;
12907 case 0xb3fb: /* CXSTR */ goto unimplemented;
12908 case 0xb3fc: /* CEXTR */ goto unimplemented;
12909 case 0xb3fd: /* QAXTR */ goto unimplemented;
12910 case 0xb3fe: /* IEXTR */ goto unimplemented;
12911 case 0xb3ff: /* RRXTR */ goto unimplemented;
12912 case 0xb900: s390_format_RRE_RR(s390_irgen_LPGR, ovl.fmt.RRE.r1,
12913 ovl.fmt.RRE.r2); goto ok;
12914 case 0xb901: s390_format_RRE_RR(s390_irgen_LNGR, ovl.fmt.RRE.r1,
12915 ovl.fmt.RRE.r2); goto ok;
12916 case 0xb902: s390_format_RRE_RR(s390_irgen_LTGR, ovl.fmt.RRE.r1,
12917 ovl.fmt.RRE.r2); goto ok;
12918 case 0xb903: s390_format_RRE_RR(s390_irgen_LCGR, ovl.fmt.RRE.r1,
12919 ovl.fmt.RRE.r2); goto ok;
12920 case 0xb904: s390_format_RRE_RR(s390_irgen_LGR, ovl.fmt.RRE.r1,
12921 ovl.fmt.RRE.r2); goto ok;
12922 case 0xb905: /* LURAG */ goto unimplemented;
12923 case 0xb906: s390_format_RRE_RR(s390_irgen_LGBR, ovl.fmt.RRE.r1,
12924 ovl.fmt.RRE.r2); goto ok;
12925 case 0xb907: s390_format_RRE_RR(s390_irgen_LGHR, ovl.fmt.RRE.r1,
12926 ovl.fmt.RRE.r2); goto ok;
12927 case 0xb908: s390_format_RRE_RR(s390_irgen_AGR, ovl.fmt.RRE.r1,
12928 ovl.fmt.RRE.r2); goto ok;
12929 case 0xb909: s390_format_RRE_RR(s390_irgen_SGR, ovl.fmt.RRE.r1,
12930 ovl.fmt.RRE.r2); goto ok;
12931 case 0xb90a: s390_format_RRE_RR(s390_irgen_ALGR, ovl.fmt.RRE.r1,
12932 ovl.fmt.RRE.r2); goto ok;
12933 case 0xb90b: s390_format_RRE_RR(s390_irgen_SLGR, ovl.fmt.RRE.r1,
12934 ovl.fmt.RRE.r2); goto ok;
12935 case 0xb90c: s390_format_RRE_RR(s390_irgen_MSGR, ovl.fmt.RRE.r1,
12936 ovl.fmt.RRE.r2); goto ok;
12937 case 0xb90d: s390_format_RRE_RR(s390_irgen_DSGR, ovl.fmt.RRE.r1,
12938 ovl.fmt.RRE.r2); goto ok;
12939 case 0xb90e: /* EREGG */ goto unimplemented;
12940 case 0xb90f: s390_format_RRE_RR(s390_irgen_LRVGR, ovl.fmt.RRE.r1,
12941 ovl.fmt.RRE.r2); goto ok;
12942 case 0xb910: s390_format_RRE_RR(s390_irgen_LPGFR, ovl.fmt.RRE.r1,
12943 ovl.fmt.RRE.r2); goto ok;
12944 case 0xb911: s390_format_RRE_RR(s390_irgen_LNGFR, ovl.fmt.RRE.r1,
12945 ovl.fmt.RRE.r2); goto ok;
12946 case 0xb912: s390_format_RRE_RR(s390_irgen_LTGFR, ovl.fmt.RRE.r1,
12947 ovl.fmt.RRE.r2); goto ok;
12948 case 0xb913: s390_format_RRE_RR(s390_irgen_LCGFR, ovl.fmt.RRE.r1,
12949 ovl.fmt.RRE.r2); goto ok;
12950 case 0xb914: s390_format_RRE_RR(s390_irgen_LGFR, ovl.fmt.RRE.r1,
12951 ovl.fmt.RRE.r2); goto ok;
12952 case 0xb916: s390_format_RRE_RR(s390_irgen_LLGFR, ovl.fmt.RRE.r1,
12953 ovl.fmt.RRE.r2); goto ok;
12954 case 0xb917: s390_format_RRE_RR(s390_irgen_LLGTR, ovl.fmt.RRE.r1,
12955 ovl.fmt.RRE.r2); goto ok;
12956 case 0xb918: s390_format_RRE_RR(s390_irgen_AGFR, ovl.fmt.RRE.r1,
12957 ovl.fmt.RRE.r2); goto ok;
12958 case 0xb919: s390_format_RRE_RR(s390_irgen_SGFR, ovl.fmt.RRE.r1,
12959 ovl.fmt.RRE.r2); goto ok;
12960 case 0xb91a: s390_format_RRE_RR(s390_irgen_ALGFR, ovl.fmt.RRE.r1,
12961 ovl.fmt.RRE.r2); goto ok;
12962 case 0xb91b: s390_format_RRE_RR(s390_irgen_SLGFR, ovl.fmt.RRE.r1,
12963 ovl.fmt.RRE.r2); goto ok;
12964 case 0xb91c: s390_format_RRE_RR(s390_irgen_MSGFR, ovl.fmt.RRE.r1,
12965 ovl.fmt.RRE.r2); goto ok;
12966 case 0xb91d: s390_format_RRE_RR(s390_irgen_DSGFR, ovl.fmt.RRE.r1,
12967 ovl.fmt.RRE.r2); goto ok;
12968 case 0xb91e: /* KMAC */ goto unimplemented;
12969 case 0xb91f: s390_format_RRE_RR(s390_irgen_LRVR, ovl.fmt.RRE.r1,
12970 ovl.fmt.RRE.r2); goto ok;
12971 case 0xb920: s390_format_RRE_RR(s390_irgen_CGR, ovl.fmt.RRE.r1,
12972 ovl.fmt.RRE.r2); goto ok;
12973 case 0xb921: s390_format_RRE_RR(s390_irgen_CLGR, ovl.fmt.RRE.r1,
12974 ovl.fmt.RRE.r2); goto ok;
12975 case 0xb925: /* STURG */ goto unimplemented;
12976 case 0xb926: s390_format_RRE_RR(s390_irgen_LBR, ovl.fmt.RRE.r1,
12977 ovl.fmt.RRE.r2); goto ok;
12978 case 0xb927: s390_format_RRE_RR(s390_irgen_LHR, ovl.fmt.RRE.r1,
12979 ovl.fmt.RRE.r2); goto ok;
12980 case 0xb928: /* PCKMO */ goto unimplemented;
12981 case 0xb92b: /* KMO */ goto unimplemented;
12982 case 0xb92c: /* PCC */ goto unimplemented;
12983 case 0xb92d: /* KMCTR */ goto unimplemented;
12984 case 0xb92e: /* KM */ goto unimplemented;
12985 case 0xb92f: /* KMC */ goto unimplemented;
12986 case 0xb930: s390_format_RRE_RR(s390_irgen_CGFR, ovl.fmt.RRE.r1,
12987 ovl.fmt.RRE.r2); goto ok;
12988 case 0xb931: s390_format_RRE_RR(s390_irgen_CLGFR, ovl.fmt.RRE.r1,
12989 ovl.fmt.RRE.r2); goto ok;
12990 case 0xb93e: /* KIMD */ goto unimplemented;
12991 case 0xb93f: /* KLMD */ goto unimplemented;
12992 case 0xb941: /* CFDTR */ goto unimplemented;
12993 case 0xb942: /* CLGDTR */ goto unimplemented;
12994 case 0xb943: /* CLFDTR */ goto unimplemented;
12995 case 0xb946: s390_format_RRE_RR(s390_irgen_BCTGR, ovl.fmt.RRE.r1,
12996 ovl.fmt.RRE.r2); goto ok;
12997 case 0xb949: /* CFXTR */ goto unimplemented;
12998 case 0xb94a: /* CLGXTR */ goto unimplemented;
12999 case 0xb94b: /* CLFXTR */ goto unimplemented;
13000 case 0xb951: /* CDFTR */ goto unimplemented;
13001 case 0xb952: /* CDLGTR */ goto unimplemented;
13002 case 0xb953: /* CDLFTR */ goto unimplemented;
13003 case 0xb959: /* CXFTR */ goto unimplemented;
13004 case 0xb95a: /* CXLGTR */ goto unimplemented;
13005 case 0xb95b: /* CXLFTR */ goto unimplemented;
13006 case 0xb960: /* CGRT */ goto unimplemented;
13007 case 0xb961: /* CLGRT */ goto unimplemented;
13008 case 0xb972: /* CRT */ goto unimplemented;
13009 case 0xb973: /* CLRT */ goto unimplemented;
13010 case 0xb980: s390_format_RRE_RR(s390_irgen_NGR, ovl.fmt.RRE.r1,
13011 ovl.fmt.RRE.r2); goto ok;
13012 case 0xb981: s390_format_RRE_RR(s390_irgen_OGR, ovl.fmt.RRE.r1,
13013 ovl.fmt.RRE.r2); goto ok;
13014 case 0xb982: s390_format_RRE_RR(s390_irgen_XGR, ovl.fmt.RRE.r1,
13015 ovl.fmt.RRE.r2); goto ok;
13016 case 0xb983: s390_format_RRE_RR(s390_irgen_FLOGR, ovl.fmt.RRE.r1,
13017 ovl.fmt.RRE.r2); goto ok;
13018 case 0xb984: s390_format_RRE_RR(s390_irgen_LLGCR, ovl.fmt.RRE.r1,
13019 ovl.fmt.RRE.r2); goto ok;
13020 case 0xb985: s390_format_RRE_RR(s390_irgen_LLGHR, ovl.fmt.RRE.r1,
13021 ovl.fmt.RRE.r2); goto ok;
13022 case 0xb986: s390_format_RRE_RR(s390_irgen_MLGR, ovl.fmt.RRE.r1,
13023 ovl.fmt.RRE.r2); goto ok;
13024 case 0xb987: s390_format_RRE_RR(s390_irgen_DLGR, ovl.fmt.RRE.r1,
13025 ovl.fmt.RRE.r2); goto ok;
13026 case 0xb988: s390_format_RRE_RR(s390_irgen_ALCGR, ovl.fmt.RRE.r1,
13027 ovl.fmt.RRE.r2); goto ok;
13028 case 0xb989: s390_format_RRE_RR(s390_irgen_SLBGR, ovl.fmt.RRE.r1,
13029 ovl.fmt.RRE.r2); goto ok;
13030 case 0xb98a: /* CSPG */ goto unimplemented;
13031 case 0xb98d: /* EPSW */ goto unimplemented;
13032 case 0xb98e: /* IDTE */ goto unimplemented;
florian730448f2012-02-04 17:07:07 +000013033 case 0xb990: s390_format_RRF_M0RERE(s390_irgen_TRTT, ovl.fmt.RRF3.r3,
13034 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
13035 case 0xb991: s390_format_RRF_M0RERE(s390_irgen_TRTO, ovl.fmt.RRF3.r3,
13036 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
13037 case 0xb992: s390_format_RRF_M0RERE(s390_irgen_TROT, ovl.fmt.RRF3.r3,
13038 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
florian9af37692012-01-15 21:01:16 +000013039 case 0xb993: s390_format_RRF_M0RERE(s390_irgen_TROO, ovl.fmt.RRF3.r3,
13040 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013041 case 0xb994: s390_format_RRE_RR(s390_irgen_LLCR, ovl.fmt.RRE.r1,
13042 ovl.fmt.RRE.r2); goto ok;
13043 case 0xb995: s390_format_RRE_RR(s390_irgen_LLHR, ovl.fmt.RRE.r1,
13044 ovl.fmt.RRE.r2); goto ok;
13045 case 0xb996: s390_format_RRE_RR(s390_irgen_MLR, ovl.fmt.RRE.r1,
13046 ovl.fmt.RRE.r2); goto ok;
13047 case 0xb997: s390_format_RRE_RR(s390_irgen_DLR, ovl.fmt.RRE.r1,
13048 ovl.fmt.RRE.r2); goto ok;
13049 case 0xb998: s390_format_RRE_RR(s390_irgen_ALCR, ovl.fmt.RRE.r1,
13050 ovl.fmt.RRE.r2); goto ok;
13051 case 0xb999: s390_format_RRE_RR(s390_irgen_SLBR, ovl.fmt.RRE.r1,
13052 ovl.fmt.RRE.r2); goto ok;
13053 case 0xb99a: /* EPAIR */ goto unimplemented;
13054 case 0xb99b: /* ESAIR */ goto unimplemented;
13055 case 0xb99d: /* ESEA */ goto unimplemented;
13056 case 0xb99e: /* PTI */ goto unimplemented;
13057 case 0xb99f: /* SSAIR */ goto unimplemented;
13058 case 0xb9a2: /* PTF */ goto unimplemented;
13059 case 0xb9aa: /* LPTEA */ goto unimplemented;
13060 case 0xb9ae: /* RRBM */ goto unimplemented;
13061 case 0xb9af: /* PFMF */ goto unimplemented;
florian3f8a96a2012-08-05 02:59:55 +000013062 case 0xb9b0: s390_format_RRF_M0RERE(s390_irgen_CU14, ovl.fmt.RRF3.r3,
13063 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
13064 goto ok;
florian2a415a12012-07-21 17:41:36 +000013065 case 0xb9b1: s390_format_RRF_M0RERE(s390_irgen_CU24, ovl.fmt.RRF3.r3,
13066 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
13067 goto ok;
florianaf2194f2012-08-06 00:07:54 +000013068 case 0xb9b2: s390_format_RRE_RR(s390_irgen_CU41, ovl.fmt.RRE.r1,
13069 ovl.fmt.RRE.r2); goto ok;
florian956194b2012-07-28 22:18:32 +000013070 case 0xb9b3: s390_format_RRE_RR(s390_irgen_CU42, ovl.fmt.RRE.r1,
13071 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013072 case 0xb9bd: /* TRTRE */ goto unimplemented;
13073 case 0xb9be: /* SRSTU */ goto unimplemented;
13074 case 0xb9bf: /* TRTE */ goto unimplemented;
13075 case 0xb9c8: s390_format_RRF_R0RR2(s390_irgen_AHHHR, ovl.fmt.RRF4.r3,
13076 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13077 goto ok;
13078 case 0xb9c9: s390_format_RRF_R0RR2(s390_irgen_SHHHR, ovl.fmt.RRF4.r3,
13079 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13080 goto ok;
13081 case 0xb9ca: s390_format_RRF_R0RR2(s390_irgen_ALHHHR, ovl.fmt.RRF4.r3,
13082 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13083 goto ok;
13084 case 0xb9cb: s390_format_RRF_R0RR2(s390_irgen_SLHHHR, ovl.fmt.RRF4.r3,
13085 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13086 goto ok;
13087 case 0xb9cd: s390_format_RRE_RR(s390_irgen_CHHR, ovl.fmt.RRE.r1,
13088 ovl.fmt.RRE.r2); goto ok;
13089 case 0xb9cf: s390_format_RRE_RR(s390_irgen_CLHHR, ovl.fmt.RRE.r1,
13090 ovl.fmt.RRE.r2); goto ok;
13091 case 0xb9d8: s390_format_RRF_R0RR2(s390_irgen_AHHLR, ovl.fmt.RRF4.r3,
13092 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13093 goto ok;
13094 case 0xb9d9: s390_format_RRF_R0RR2(s390_irgen_SHHLR, ovl.fmt.RRF4.r3,
13095 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13096 goto ok;
13097 case 0xb9da: s390_format_RRF_R0RR2(s390_irgen_ALHHLR, ovl.fmt.RRF4.r3,
13098 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13099 goto ok;
13100 case 0xb9db: s390_format_RRF_R0RR2(s390_irgen_SLHHLR, ovl.fmt.RRF4.r3,
13101 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13102 goto ok;
13103 case 0xb9dd: s390_format_RRE_RR(s390_irgen_CHLR, ovl.fmt.RRE.r1,
13104 ovl.fmt.RRE.r2); goto ok;
13105 case 0xb9df: s390_format_RRE_RR(s390_irgen_CLHLR, ovl.fmt.RRE.r1,
13106 ovl.fmt.RRE.r2); goto ok;
13107 case 0xb9e1: /* POPCNT */ goto unimplemented;
sewardjd7bde722011-04-05 13:19:33 +000013108 case 0xb9e2: s390_format_RRF_U0RR(s390_irgen_LOCGR, ovl.fmt.RRF3.r3,
13109 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2,
13110 S390_XMNM_LOCGR); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013111 case 0xb9e4: s390_format_RRF_R0RR2(s390_irgen_NGRK, ovl.fmt.RRF4.r3,
13112 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13113 goto ok;
13114 case 0xb9e6: s390_format_RRF_R0RR2(s390_irgen_OGRK, ovl.fmt.RRF4.r3,
13115 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13116 goto ok;
13117 case 0xb9e7: s390_format_RRF_R0RR2(s390_irgen_XGRK, ovl.fmt.RRF4.r3,
13118 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13119 goto ok;
13120 case 0xb9e8: s390_format_RRF_R0RR2(s390_irgen_AGRK, ovl.fmt.RRF4.r3,
13121 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13122 goto ok;
13123 case 0xb9e9: s390_format_RRF_R0RR2(s390_irgen_SGRK, ovl.fmt.RRF4.r3,
13124 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13125 goto ok;
13126 case 0xb9ea: s390_format_RRF_R0RR2(s390_irgen_ALGRK, ovl.fmt.RRF4.r3,
13127 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13128 goto ok;
13129 case 0xb9eb: s390_format_RRF_R0RR2(s390_irgen_SLGRK, ovl.fmt.RRF4.r3,
13130 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13131 goto ok;
sewardjd7bde722011-04-05 13:19:33 +000013132 case 0xb9f2: s390_format_RRF_U0RR(s390_irgen_LOCR, ovl.fmt.RRF3.r3,
13133 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2,
13134 S390_XMNM_LOCR); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013135 case 0xb9f4: s390_format_RRF_R0RR2(s390_irgen_NRK, ovl.fmt.RRF4.r3,
13136 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13137 goto ok;
13138 case 0xb9f6: s390_format_RRF_R0RR2(s390_irgen_ORK, ovl.fmt.RRF4.r3,
13139 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13140 goto ok;
13141 case 0xb9f7: s390_format_RRF_R0RR2(s390_irgen_XRK, ovl.fmt.RRF4.r3,
13142 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13143 goto ok;
13144 case 0xb9f8: s390_format_RRF_R0RR2(s390_irgen_ARK, ovl.fmt.RRF4.r3,
13145 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13146 goto ok;
13147 case 0xb9f9: s390_format_RRF_R0RR2(s390_irgen_SRK, ovl.fmt.RRF4.r3,
13148 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13149 goto ok;
13150 case 0xb9fa: s390_format_RRF_R0RR2(s390_irgen_ALRK, ovl.fmt.RRF4.r3,
13151 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13152 goto ok;
13153 case 0xb9fb: s390_format_RRF_R0RR2(s390_irgen_SLRK, ovl.fmt.RRF4.r3,
13154 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13155 goto ok;
13156 }
13157
13158 switch ((ovl.value & 0xff000000) >> 24) {
13159 case 0x40: s390_format_RX_RRRD(s390_irgen_STH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13160 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13161 case 0x41: s390_format_RX_RRRD(s390_irgen_LA, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13162 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13163 case 0x42: s390_format_RX_RRRD(s390_irgen_STC, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13164 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13165 case 0x43: s390_format_RX_RRRD(s390_irgen_IC, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13166 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13167 case 0x44: s390_format_RX_RRRD(s390_irgen_EX, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13168 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13169 case 0x45: /* BAL */ goto unimplemented;
13170 case 0x46: s390_format_RX_RRRD(s390_irgen_BCT, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13171 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13172 case 0x47: s390_format_RX(s390_irgen_BC, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13173 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13174 case 0x48: s390_format_RX_RRRD(s390_irgen_LH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13175 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13176 case 0x49: s390_format_RX_RRRD(s390_irgen_CH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13177 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13178 case 0x4a: s390_format_RX_RRRD(s390_irgen_AH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13179 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13180 case 0x4b: s390_format_RX_RRRD(s390_irgen_SH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13181 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13182 case 0x4c: s390_format_RX_RRRD(s390_irgen_MH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13183 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13184 case 0x4d: s390_format_RX_RRRD(s390_irgen_BAS, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13185 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13186 case 0x4e: s390_format_RX_RRRD(s390_irgen_CVD, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13187 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13188 case 0x4f: s390_format_RX_RRRD(s390_irgen_CVB, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13189 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13190 case 0x50: s390_format_RX_RRRD(s390_irgen_ST, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13191 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13192 case 0x51: s390_format_RX_RRRD(s390_irgen_LAE, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13193 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13194 case 0x54: s390_format_RX_RRRD(s390_irgen_N, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13195 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13196 case 0x55: s390_format_RX_RRRD(s390_irgen_CL, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13197 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13198 case 0x56: s390_format_RX_RRRD(s390_irgen_O, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13199 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13200 case 0x57: s390_format_RX_RRRD(s390_irgen_X, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13201 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13202 case 0x58: s390_format_RX_RRRD(s390_irgen_L, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13203 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13204 case 0x59: s390_format_RX_RRRD(s390_irgen_C, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13205 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13206 case 0x5a: s390_format_RX_RRRD(s390_irgen_A, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13207 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13208 case 0x5b: s390_format_RX_RRRD(s390_irgen_S, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13209 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13210 case 0x5c: s390_format_RX_RRRD(s390_irgen_M, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13211 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13212 case 0x5d: s390_format_RX_RRRD(s390_irgen_D, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13213 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13214 case 0x5e: s390_format_RX_RRRD(s390_irgen_AL, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13215 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13216 case 0x5f: s390_format_RX_RRRD(s390_irgen_SL, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13217 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13218 case 0x60: s390_format_RX_FRRD(s390_irgen_STD, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13219 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13220 case 0x67: /* MXD */ goto unimplemented;
13221 case 0x68: s390_format_RX_FRRD(s390_irgen_LD, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13222 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13223 case 0x69: /* CD */ goto unimplemented;
13224 case 0x6a: /* AD */ goto unimplemented;
13225 case 0x6b: /* SD */ goto unimplemented;
13226 case 0x6c: /* MD */ goto unimplemented;
13227 case 0x6d: /* DD */ goto unimplemented;
13228 case 0x6e: /* AW */ goto unimplemented;
13229 case 0x6f: /* SW */ goto unimplemented;
13230 case 0x70: s390_format_RX_FRRD(s390_irgen_STE, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13231 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13232 case 0x71: s390_format_RX_RRRD(s390_irgen_MS, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13233 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13234 case 0x78: s390_format_RX_FRRD(s390_irgen_LE, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13235 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13236 case 0x79: /* CE */ goto unimplemented;
13237 case 0x7a: /* AE */ goto unimplemented;
13238 case 0x7b: /* SE */ goto unimplemented;
13239 case 0x7c: /* MDE */ goto unimplemented;
13240 case 0x7d: /* DE */ goto unimplemented;
13241 case 0x7e: /* AU */ goto unimplemented;
13242 case 0x7f: /* SU */ goto unimplemented;
13243 case 0x83: /* DIAG */ goto unimplemented;
13244 case 0x84: s390_format_RSI_RRP(s390_irgen_BRXH, ovl.fmt.RSI.r1,
13245 ovl.fmt.RSI.r3, ovl.fmt.RSI.i2); goto ok;
13246 case 0x85: s390_format_RSI_RRP(s390_irgen_BRXLE, ovl.fmt.RSI.r1,
13247 ovl.fmt.RSI.r3, ovl.fmt.RSI.i2); goto ok;
13248 case 0x86: s390_format_RS_RRRD(s390_irgen_BXH, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13249 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13250 case 0x87: s390_format_RS_RRRD(s390_irgen_BXLE, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13251 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13252 case 0x88: s390_format_RS_R0RD(s390_irgen_SRL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
13253 ovl.fmt.RS.d2); goto ok;
13254 case 0x89: s390_format_RS_R0RD(s390_irgen_SLL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
13255 ovl.fmt.RS.d2); goto ok;
13256 case 0x8a: s390_format_RS_R0RD(s390_irgen_SRA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
13257 ovl.fmt.RS.d2); goto ok;
13258 case 0x8b: s390_format_RS_R0RD(s390_irgen_SLA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
13259 ovl.fmt.RS.d2); goto ok;
13260 case 0x8c: s390_format_RS_R0RD(s390_irgen_SRDL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
13261 ovl.fmt.RS.d2); goto ok;
13262 case 0x8d: s390_format_RS_R0RD(s390_irgen_SLDL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
13263 ovl.fmt.RS.d2); goto ok;
13264 case 0x8e: s390_format_RS_R0RD(s390_irgen_SRDA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
13265 ovl.fmt.RS.d2); goto ok;
13266 case 0x8f: s390_format_RS_R0RD(s390_irgen_SLDA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
13267 ovl.fmt.RS.d2); goto ok;
13268 case 0x90: s390_format_RS_RRRD(s390_irgen_STM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13269 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13270 case 0x91: s390_format_SI_URD(s390_irgen_TM, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
13271 ovl.fmt.SI.d1); goto ok;
13272 case 0x92: s390_format_SI_URD(s390_irgen_MVI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
13273 ovl.fmt.SI.d1); goto ok;
13274 case 0x94: s390_format_SI_URD(s390_irgen_NI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
13275 ovl.fmt.SI.d1); goto ok;
13276 case 0x95: s390_format_SI_URD(s390_irgen_CLI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
13277 ovl.fmt.SI.d1); goto ok;
13278 case 0x96: s390_format_SI_URD(s390_irgen_OI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
13279 ovl.fmt.SI.d1); goto ok;
13280 case 0x97: s390_format_SI_URD(s390_irgen_XI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
13281 ovl.fmt.SI.d1); goto ok;
13282 case 0x98: s390_format_RS_RRRD(s390_irgen_LM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13283 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13284 case 0x99: /* TRACE */ goto unimplemented;
13285 case 0x9a: s390_format_RS_AARD(s390_irgen_LAM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13286 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13287 case 0x9b: s390_format_RS_AARD(s390_irgen_STAM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13288 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13289 case 0xa8: s390_format_RS_RRRD(s390_irgen_MVCLE, ovl.fmt.RS.r1,
13290 ovl.fmt.RS.r3, ovl.fmt.RS.b2, ovl.fmt.RS.d2);
13291 goto ok;
13292 case 0xa9: s390_format_RS_RRRD(s390_irgen_CLCLE, ovl.fmt.RS.r1,
13293 ovl.fmt.RS.r3, ovl.fmt.RS.b2, ovl.fmt.RS.d2);
13294 goto ok;
13295 case 0xac: /* STNSM */ goto unimplemented;
13296 case 0xad: /* STOSM */ goto unimplemented;
13297 case 0xae: /* SIGP */ goto unimplemented;
13298 case 0xaf: /* MC */ goto unimplemented;
13299 case 0xb1: /* LRA */ goto unimplemented;
13300 case 0xb6: /* STCTL */ goto unimplemented;
13301 case 0xb7: /* LCTL */ goto unimplemented;
13302 case 0xba: s390_format_RS_RRRD(s390_irgen_CS, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13303 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
florian448cbba2012-06-06 02:26:01 +000013304 case 0xbb: s390_format_RS_RRRD(s390_irgen_CDS, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13305 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013306 case 0xbd: s390_format_RS_RURD(s390_irgen_CLM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13307 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13308 case 0xbe: s390_format_RS_RURD(s390_irgen_STCM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13309 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13310 case 0xbf: s390_format_RS_RURD(s390_irgen_ICM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13311 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13312 }
13313
13314 return S390_DECODE_UNKNOWN_INSN;
13315
13316ok:
13317 return S390_DECODE_OK;
13318
13319unimplemented:
13320 return S390_DECODE_UNIMPLEMENTED_INSN;
13321}
13322
13323static s390_decode_t
13324s390_decode_6byte_and_irgen(UChar *bytes)
13325{
13326 typedef union {
13327 struct {
13328 unsigned int op1 : 8;
13329 unsigned int r1 : 4;
13330 unsigned int r3 : 4;
13331 unsigned int i2 : 16;
13332 unsigned int : 8;
13333 unsigned int op2 : 8;
13334 } RIE;
13335 struct {
13336 unsigned int op1 : 8;
13337 unsigned int r1 : 4;
13338 unsigned int r2 : 4;
13339 unsigned int i3 : 8;
13340 unsigned int i4 : 8;
13341 unsigned int i5 : 8;
13342 unsigned int op2 : 8;
13343 } RIE_RRUUU;
13344 struct {
13345 unsigned int op1 : 8;
13346 unsigned int r1 : 4;
13347 unsigned int : 4;
13348 unsigned int i2 : 16;
13349 unsigned int m3 : 4;
13350 unsigned int : 4;
13351 unsigned int op2 : 8;
13352 } RIEv1;
13353 struct {
13354 unsigned int op1 : 8;
13355 unsigned int r1 : 4;
13356 unsigned int r2 : 4;
13357 unsigned int i4 : 16;
13358 unsigned int m3 : 4;
13359 unsigned int : 4;
13360 unsigned int op2 : 8;
13361 } RIE_RRPU;
13362 struct {
13363 unsigned int op1 : 8;
13364 unsigned int r1 : 4;
13365 unsigned int m3 : 4;
13366 unsigned int i4 : 16;
13367 unsigned int i2 : 8;
13368 unsigned int op2 : 8;
13369 } RIEv3;
13370 struct {
13371 unsigned int op1 : 8;
13372 unsigned int r1 : 4;
13373 unsigned int op2 : 4;
13374 unsigned int i2 : 32;
13375 } RIL;
13376 struct {
13377 unsigned int op1 : 8;
13378 unsigned int r1 : 4;
13379 unsigned int m3 : 4;
13380 unsigned int b4 : 4;
13381 unsigned int d4 : 12;
13382 unsigned int i2 : 8;
13383 unsigned int op2 : 8;
13384 } RIS;
13385 struct {
13386 unsigned int op1 : 8;
13387 unsigned int r1 : 4;
13388 unsigned int r2 : 4;
13389 unsigned int b4 : 4;
13390 unsigned int d4 : 12;
13391 unsigned int m3 : 4;
13392 unsigned int : 4;
13393 unsigned int op2 : 8;
13394 } RRS;
13395 struct {
13396 unsigned int op1 : 8;
13397 unsigned int l1 : 4;
13398 unsigned int : 4;
13399 unsigned int b1 : 4;
13400 unsigned int d1 : 12;
13401 unsigned int : 8;
13402 unsigned int op2 : 8;
13403 } RSL;
13404 struct {
13405 unsigned int op1 : 8;
13406 unsigned int r1 : 4;
13407 unsigned int r3 : 4;
13408 unsigned int b2 : 4;
13409 unsigned int dl2 : 12;
13410 unsigned int dh2 : 8;
13411 unsigned int op2 : 8;
13412 } RSY;
13413 struct {
13414 unsigned int op1 : 8;
13415 unsigned int r1 : 4;
13416 unsigned int x2 : 4;
13417 unsigned int b2 : 4;
13418 unsigned int d2 : 12;
13419 unsigned int : 8;
13420 unsigned int op2 : 8;
13421 } RXE;
13422 struct {
13423 unsigned int op1 : 8;
13424 unsigned int r3 : 4;
13425 unsigned int x2 : 4;
13426 unsigned int b2 : 4;
13427 unsigned int d2 : 12;
13428 unsigned int r1 : 4;
13429 unsigned int : 4;
13430 unsigned int op2 : 8;
13431 } RXF;
13432 struct {
13433 unsigned int op1 : 8;
13434 unsigned int r1 : 4;
13435 unsigned int x2 : 4;
13436 unsigned int b2 : 4;
13437 unsigned int dl2 : 12;
13438 unsigned int dh2 : 8;
13439 unsigned int op2 : 8;
13440 } RXY;
13441 struct {
13442 unsigned int op1 : 8;
13443 unsigned int i2 : 8;
13444 unsigned int b1 : 4;
13445 unsigned int dl1 : 12;
13446 unsigned int dh1 : 8;
13447 unsigned int op2 : 8;
13448 } SIY;
13449 struct {
13450 unsigned int op : 8;
13451 unsigned int l : 8;
13452 unsigned int b1 : 4;
13453 unsigned int d1 : 12;
13454 unsigned int b2 : 4;
13455 unsigned int d2 : 12;
13456 } SS;
13457 struct {
13458 unsigned int op : 8;
13459 unsigned int l1 : 4;
13460 unsigned int l2 : 4;
13461 unsigned int b1 : 4;
13462 unsigned int d1 : 12;
13463 unsigned int b2 : 4;
13464 unsigned int d2 : 12;
13465 } SS_LLRDRD;
13466 struct {
13467 unsigned int op : 8;
13468 unsigned int r1 : 4;
13469 unsigned int r3 : 4;
13470 unsigned int b2 : 4;
13471 unsigned int d2 : 12;
13472 unsigned int b4 : 4;
13473 unsigned int d4 : 12;
13474 } SS_RRRDRD2;
13475 struct {
13476 unsigned int op : 16;
13477 unsigned int b1 : 4;
13478 unsigned int d1 : 12;
13479 unsigned int b2 : 4;
13480 unsigned int d2 : 12;
13481 } SSE;
13482 struct {
13483 unsigned int op1 : 8;
13484 unsigned int r3 : 4;
13485 unsigned int op2 : 4;
13486 unsigned int b1 : 4;
13487 unsigned int d1 : 12;
13488 unsigned int b2 : 4;
13489 unsigned int d2 : 12;
13490 } SSF;
13491 struct {
13492 unsigned int op : 16;
13493 unsigned int b1 : 4;
13494 unsigned int d1 : 12;
13495 unsigned int i2 : 16;
13496 } SIL;
13497 } formats;
13498 union {
13499 formats fmt;
13500 ULong value;
13501 } ovl;
13502
13503 vassert(sizeof(formats) == 6);
13504
13505 ((char *)(&ovl.value))[0] = bytes[0];
13506 ((char *)(&ovl.value))[1] = bytes[1];
13507 ((char *)(&ovl.value))[2] = bytes[2];
13508 ((char *)(&ovl.value))[3] = bytes[3];
13509 ((char *)(&ovl.value))[4] = bytes[4];
13510 ((char *)(&ovl.value))[5] = bytes[5];
13511 ((char *)(&ovl.value))[6] = 0x0;
13512 ((char *)(&ovl.value))[7] = 0x0;
13513
13514 switch ((ovl.value >> 16) & 0xff00000000ffULL) {
13515 case 0xe30000000002ULL: s390_format_RXY_RRRD(s390_irgen_LTG, ovl.fmt.RXY.r1,
13516 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13517 ovl.fmt.RXY.dl2,
13518 ovl.fmt.RXY.dh2); goto ok;
13519 case 0xe30000000003ULL: /* LRAG */ goto unimplemented;
13520 case 0xe30000000004ULL: s390_format_RXY_RRRD(s390_irgen_LG, ovl.fmt.RXY.r1,
13521 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13522 ovl.fmt.RXY.dl2,
13523 ovl.fmt.RXY.dh2); goto ok;
13524 case 0xe30000000006ULL: s390_format_RXY_RRRD(s390_irgen_CVBY, ovl.fmt.RXY.r1,
13525 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13526 ovl.fmt.RXY.dl2,
13527 ovl.fmt.RXY.dh2); goto ok;
13528 case 0xe30000000008ULL: s390_format_RXY_RRRD(s390_irgen_AG, ovl.fmt.RXY.r1,
13529 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13530 ovl.fmt.RXY.dl2,
13531 ovl.fmt.RXY.dh2); goto ok;
13532 case 0xe30000000009ULL: s390_format_RXY_RRRD(s390_irgen_SG, ovl.fmt.RXY.r1,
13533 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13534 ovl.fmt.RXY.dl2,
13535 ovl.fmt.RXY.dh2); goto ok;
13536 case 0xe3000000000aULL: s390_format_RXY_RRRD(s390_irgen_ALG, ovl.fmt.RXY.r1,
13537 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13538 ovl.fmt.RXY.dl2,
13539 ovl.fmt.RXY.dh2); goto ok;
13540 case 0xe3000000000bULL: s390_format_RXY_RRRD(s390_irgen_SLG, ovl.fmt.RXY.r1,
13541 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13542 ovl.fmt.RXY.dl2,
13543 ovl.fmt.RXY.dh2); goto ok;
13544 case 0xe3000000000cULL: s390_format_RXY_RRRD(s390_irgen_MSG, ovl.fmt.RXY.r1,
13545 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13546 ovl.fmt.RXY.dl2,
13547 ovl.fmt.RXY.dh2); goto ok;
13548 case 0xe3000000000dULL: s390_format_RXY_RRRD(s390_irgen_DSG, ovl.fmt.RXY.r1,
13549 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13550 ovl.fmt.RXY.dl2,
13551 ovl.fmt.RXY.dh2); goto ok;
13552 case 0xe3000000000eULL: /* CVBG */ goto unimplemented;
13553 case 0xe3000000000fULL: s390_format_RXY_RRRD(s390_irgen_LRVG, ovl.fmt.RXY.r1,
13554 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13555 ovl.fmt.RXY.dl2,
13556 ovl.fmt.RXY.dh2); goto ok;
13557 case 0xe30000000012ULL: s390_format_RXY_RRRD(s390_irgen_LT, ovl.fmt.RXY.r1,
13558 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13559 ovl.fmt.RXY.dl2,
13560 ovl.fmt.RXY.dh2); goto ok;
13561 case 0xe30000000013ULL: /* LRAY */ goto unimplemented;
13562 case 0xe30000000014ULL: s390_format_RXY_RRRD(s390_irgen_LGF, ovl.fmt.RXY.r1,
13563 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13564 ovl.fmt.RXY.dl2,
13565 ovl.fmt.RXY.dh2); goto ok;
13566 case 0xe30000000015ULL: s390_format_RXY_RRRD(s390_irgen_LGH, ovl.fmt.RXY.r1,
13567 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13568 ovl.fmt.RXY.dl2,
13569 ovl.fmt.RXY.dh2); goto ok;
13570 case 0xe30000000016ULL: s390_format_RXY_RRRD(s390_irgen_LLGF, ovl.fmt.RXY.r1,
13571 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13572 ovl.fmt.RXY.dl2,
13573 ovl.fmt.RXY.dh2); goto ok;
13574 case 0xe30000000017ULL: s390_format_RXY_RRRD(s390_irgen_LLGT, ovl.fmt.RXY.r1,
13575 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13576 ovl.fmt.RXY.dl2,
13577 ovl.fmt.RXY.dh2); goto ok;
13578 case 0xe30000000018ULL: s390_format_RXY_RRRD(s390_irgen_AGF, ovl.fmt.RXY.r1,
13579 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13580 ovl.fmt.RXY.dl2,
13581 ovl.fmt.RXY.dh2); goto ok;
13582 case 0xe30000000019ULL: s390_format_RXY_RRRD(s390_irgen_SGF, ovl.fmt.RXY.r1,
13583 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13584 ovl.fmt.RXY.dl2,
13585 ovl.fmt.RXY.dh2); goto ok;
13586 case 0xe3000000001aULL: s390_format_RXY_RRRD(s390_irgen_ALGF, ovl.fmt.RXY.r1,
13587 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13588 ovl.fmt.RXY.dl2,
13589 ovl.fmt.RXY.dh2); goto ok;
13590 case 0xe3000000001bULL: s390_format_RXY_RRRD(s390_irgen_SLGF, ovl.fmt.RXY.r1,
13591 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13592 ovl.fmt.RXY.dl2,
13593 ovl.fmt.RXY.dh2); goto ok;
13594 case 0xe3000000001cULL: s390_format_RXY_RRRD(s390_irgen_MSGF, ovl.fmt.RXY.r1,
13595 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13596 ovl.fmt.RXY.dl2,
13597 ovl.fmt.RXY.dh2); goto ok;
13598 case 0xe3000000001dULL: s390_format_RXY_RRRD(s390_irgen_DSGF, ovl.fmt.RXY.r1,
13599 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13600 ovl.fmt.RXY.dl2,
13601 ovl.fmt.RXY.dh2); goto ok;
13602 case 0xe3000000001eULL: s390_format_RXY_RRRD(s390_irgen_LRV, ovl.fmt.RXY.r1,
13603 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13604 ovl.fmt.RXY.dl2,
13605 ovl.fmt.RXY.dh2); goto ok;
13606 case 0xe3000000001fULL: s390_format_RXY_RRRD(s390_irgen_LRVH, ovl.fmt.RXY.r1,
13607 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13608 ovl.fmt.RXY.dl2,
13609 ovl.fmt.RXY.dh2); goto ok;
13610 case 0xe30000000020ULL: s390_format_RXY_RRRD(s390_irgen_CG, ovl.fmt.RXY.r1,
13611 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13612 ovl.fmt.RXY.dl2,
13613 ovl.fmt.RXY.dh2); goto ok;
13614 case 0xe30000000021ULL: s390_format_RXY_RRRD(s390_irgen_CLG, ovl.fmt.RXY.r1,
13615 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13616 ovl.fmt.RXY.dl2,
13617 ovl.fmt.RXY.dh2); goto ok;
13618 case 0xe30000000024ULL: s390_format_RXY_RRRD(s390_irgen_STG, ovl.fmt.RXY.r1,
13619 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13620 ovl.fmt.RXY.dl2,
13621 ovl.fmt.RXY.dh2); goto ok;
13622 case 0xe30000000026ULL: s390_format_RXY_RRRD(s390_irgen_CVDY, ovl.fmt.RXY.r1,
13623 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13624 ovl.fmt.RXY.dl2,
13625 ovl.fmt.RXY.dh2); goto ok;
13626 case 0xe3000000002eULL: /* CVDG */ goto unimplemented;
13627 case 0xe3000000002fULL: s390_format_RXY_RRRD(s390_irgen_STRVG,
13628 ovl.fmt.RXY.r1, ovl.fmt.RXY.x2,
13629 ovl.fmt.RXY.b2, ovl.fmt.RXY.dl2,
13630 ovl.fmt.RXY.dh2); goto ok;
13631 case 0xe30000000030ULL: s390_format_RXY_RRRD(s390_irgen_CGF, ovl.fmt.RXY.r1,
13632 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13633 ovl.fmt.RXY.dl2,
13634 ovl.fmt.RXY.dh2); goto ok;
13635 case 0xe30000000031ULL: s390_format_RXY_RRRD(s390_irgen_CLGF, ovl.fmt.RXY.r1,
13636 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13637 ovl.fmt.RXY.dl2,
13638 ovl.fmt.RXY.dh2); goto ok;
13639 case 0xe30000000032ULL: s390_format_RXY_RRRD(s390_irgen_LTGF, ovl.fmt.RXY.r1,
13640 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13641 ovl.fmt.RXY.dl2,
13642 ovl.fmt.RXY.dh2); goto ok;
13643 case 0xe30000000034ULL: s390_format_RXY_RRRD(s390_irgen_CGH, ovl.fmt.RXY.r1,
13644 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13645 ovl.fmt.RXY.dl2,
13646 ovl.fmt.RXY.dh2); goto ok;
13647 case 0xe30000000036ULL: s390_format_RXY_URRD(s390_irgen_PFD, ovl.fmt.RXY.r1,
13648 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13649 ovl.fmt.RXY.dl2,
13650 ovl.fmt.RXY.dh2); goto ok;
13651 case 0xe3000000003eULL: s390_format_RXY_RRRD(s390_irgen_STRV, ovl.fmt.RXY.r1,
13652 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13653 ovl.fmt.RXY.dl2,
13654 ovl.fmt.RXY.dh2); goto ok;
13655 case 0xe3000000003fULL: s390_format_RXY_RRRD(s390_irgen_STRVH,
13656 ovl.fmt.RXY.r1, ovl.fmt.RXY.x2,
13657 ovl.fmt.RXY.b2, ovl.fmt.RXY.dl2,
13658 ovl.fmt.RXY.dh2); goto ok;
13659 case 0xe30000000046ULL: s390_format_RXY_RRRD(s390_irgen_BCTG, ovl.fmt.RXY.r1,
13660 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13661 ovl.fmt.RXY.dl2,
13662 ovl.fmt.RXY.dh2); goto ok;
13663 case 0xe30000000050ULL: s390_format_RXY_RRRD(s390_irgen_STY, ovl.fmt.RXY.r1,
13664 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13665 ovl.fmt.RXY.dl2,
13666 ovl.fmt.RXY.dh2); goto ok;
13667 case 0xe30000000051ULL: s390_format_RXY_RRRD(s390_irgen_MSY, ovl.fmt.RXY.r1,
13668 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13669 ovl.fmt.RXY.dl2,
13670 ovl.fmt.RXY.dh2); goto ok;
13671 case 0xe30000000054ULL: s390_format_RXY_RRRD(s390_irgen_NY, ovl.fmt.RXY.r1,
13672 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13673 ovl.fmt.RXY.dl2,
13674 ovl.fmt.RXY.dh2); goto ok;
13675 case 0xe30000000055ULL: s390_format_RXY_RRRD(s390_irgen_CLY, ovl.fmt.RXY.r1,
13676 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13677 ovl.fmt.RXY.dl2,
13678 ovl.fmt.RXY.dh2); goto ok;
13679 case 0xe30000000056ULL: s390_format_RXY_RRRD(s390_irgen_OY, ovl.fmt.RXY.r1,
13680 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13681 ovl.fmt.RXY.dl2,
13682 ovl.fmt.RXY.dh2); goto ok;
13683 case 0xe30000000057ULL: s390_format_RXY_RRRD(s390_irgen_XY, ovl.fmt.RXY.r1,
13684 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13685 ovl.fmt.RXY.dl2,
13686 ovl.fmt.RXY.dh2); goto ok;
13687 case 0xe30000000058ULL: s390_format_RXY_RRRD(s390_irgen_LY, ovl.fmt.RXY.r1,
13688 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13689 ovl.fmt.RXY.dl2,
13690 ovl.fmt.RXY.dh2); goto ok;
13691 case 0xe30000000059ULL: s390_format_RXY_RRRD(s390_irgen_CY, ovl.fmt.RXY.r1,
13692 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13693 ovl.fmt.RXY.dl2,
13694 ovl.fmt.RXY.dh2); goto ok;
13695 case 0xe3000000005aULL: s390_format_RXY_RRRD(s390_irgen_AY, ovl.fmt.RXY.r1,
13696 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13697 ovl.fmt.RXY.dl2,
13698 ovl.fmt.RXY.dh2); goto ok;
13699 case 0xe3000000005bULL: s390_format_RXY_RRRD(s390_irgen_SY, ovl.fmt.RXY.r1,
13700 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13701 ovl.fmt.RXY.dl2,
13702 ovl.fmt.RXY.dh2); goto ok;
13703 case 0xe3000000005cULL: s390_format_RXY_RRRD(s390_irgen_MFY, ovl.fmt.RXY.r1,
13704 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13705 ovl.fmt.RXY.dl2,
13706 ovl.fmt.RXY.dh2); goto ok;
13707 case 0xe3000000005eULL: s390_format_RXY_RRRD(s390_irgen_ALY, ovl.fmt.RXY.r1,
13708 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13709 ovl.fmt.RXY.dl2,
13710 ovl.fmt.RXY.dh2); goto ok;
13711 case 0xe3000000005fULL: s390_format_RXY_RRRD(s390_irgen_SLY, ovl.fmt.RXY.r1,
13712 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13713 ovl.fmt.RXY.dl2,
13714 ovl.fmt.RXY.dh2); goto ok;
13715 case 0xe30000000070ULL: s390_format_RXY_RRRD(s390_irgen_STHY, ovl.fmt.RXY.r1,
13716 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13717 ovl.fmt.RXY.dl2,
13718 ovl.fmt.RXY.dh2); goto ok;
13719 case 0xe30000000071ULL: s390_format_RXY_RRRD(s390_irgen_LAY, ovl.fmt.RXY.r1,
13720 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13721 ovl.fmt.RXY.dl2,
13722 ovl.fmt.RXY.dh2); goto ok;
13723 case 0xe30000000072ULL: s390_format_RXY_RRRD(s390_irgen_STCY, ovl.fmt.RXY.r1,
13724 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13725 ovl.fmt.RXY.dl2,
13726 ovl.fmt.RXY.dh2); goto ok;
13727 case 0xe30000000073ULL: s390_format_RXY_RRRD(s390_irgen_ICY, ovl.fmt.RXY.r1,
13728 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13729 ovl.fmt.RXY.dl2,
13730 ovl.fmt.RXY.dh2); goto ok;
13731 case 0xe30000000075ULL: s390_format_RXY_RRRD(s390_irgen_LAEY, ovl.fmt.RXY.r1,
13732 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13733 ovl.fmt.RXY.dl2,
13734 ovl.fmt.RXY.dh2); goto ok;
13735 case 0xe30000000076ULL: s390_format_RXY_RRRD(s390_irgen_LB, ovl.fmt.RXY.r1,
13736 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13737 ovl.fmt.RXY.dl2,
13738 ovl.fmt.RXY.dh2); goto ok;
13739 case 0xe30000000077ULL: s390_format_RXY_RRRD(s390_irgen_LGB, ovl.fmt.RXY.r1,
13740 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13741 ovl.fmt.RXY.dl2,
13742 ovl.fmt.RXY.dh2); goto ok;
13743 case 0xe30000000078ULL: s390_format_RXY_RRRD(s390_irgen_LHY, ovl.fmt.RXY.r1,
13744 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13745 ovl.fmt.RXY.dl2,
13746 ovl.fmt.RXY.dh2); goto ok;
13747 case 0xe30000000079ULL: s390_format_RXY_RRRD(s390_irgen_CHY, ovl.fmt.RXY.r1,
13748 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13749 ovl.fmt.RXY.dl2,
13750 ovl.fmt.RXY.dh2); goto ok;
13751 case 0xe3000000007aULL: s390_format_RXY_RRRD(s390_irgen_AHY, ovl.fmt.RXY.r1,
13752 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13753 ovl.fmt.RXY.dl2,
13754 ovl.fmt.RXY.dh2); goto ok;
13755 case 0xe3000000007bULL: s390_format_RXY_RRRD(s390_irgen_SHY, ovl.fmt.RXY.r1,
13756 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13757 ovl.fmt.RXY.dl2,
13758 ovl.fmt.RXY.dh2); goto ok;
13759 case 0xe3000000007cULL: s390_format_RXY_RRRD(s390_irgen_MHY, ovl.fmt.RXY.r1,
13760 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13761 ovl.fmt.RXY.dl2,
13762 ovl.fmt.RXY.dh2); goto ok;
13763 case 0xe30000000080ULL: s390_format_RXY_RRRD(s390_irgen_NG, ovl.fmt.RXY.r1,
13764 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13765 ovl.fmt.RXY.dl2,
13766 ovl.fmt.RXY.dh2); goto ok;
13767 case 0xe30000000081ULL: s390_format_RXY_RRRD(s390_irgen_OG, ovl.fmt.RXY.r1,
13768 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13769 ovl.fmt.RXY.dl2,
13770 ovl.fmt.RXY.dh2); goto ok;
13771 case 0xe30000000082ULL: s390_format_RXY_RRRD(s390_irgen_XG, ovl.fmt.RXY.r1,
13772 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13773 ovl.fmt.RXY.dl2,
13774 ovl.fmt.RXY.dh2); goto ok;
13775 case 0xe30000000086ULL: s390_format_RXY_RRRD(s390_irgen_MLG, ovl.fmt.RXY.r1,
13776 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13777 ovl.fmt.RXY.dl2,
13778 ovl.fmt.RXY.dh2); goto ok;
13779 case 0xe30000000087ULL: s390_format_RXY_RRRD(s390_irgen_DLG, ovl.fmt.RXY.r1,
13780 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13781 ovl.fmt.RXY.dl2,
13782 ovl.fmt.RXY.dh2); goto ok;
13783 case 0xe30000000088ULL: s390_format_RXY_RRRD(s390_irgen_ALCG, ovl.fmt.RXY.r1,
13784 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13785 ovl.fmt.RXY.dl2,
13786 ovl.fmt.RXY.dh2); goto ok;
13787 case 0xe30000000089ULL: s390_format_RXY_RRRD(s390_irgen_SLBG, ovl.fmt.RXY.r1,
13788 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13789 ovl.fmt.RXY.dl2,
13790 ovl.fmt.RXY.dh2); goto ok;
13791 case 0xe3000000008eULL: s390_format_RXY_RRRD(s390_irgen_STPQ, ovl.fmt.RXY.r1,
13792 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13793 ovl.fmt.RXY.dl2,
13794 ovl.fmt.RXY.dh2); goto ok;
13795 case 0xe3000000008fULL: s390_format_RXY_RRRD(s390_irgen_LPQ, ovl.fmt.RXY.r1,
13796 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13797 ovl.fmt.RXY.dl2,
13798 ovl.fmt.RXY.dh2); goto ok;
13799 case 0xe30000000090ULL: s390_format_RXY_RRRD(s390_irgen_LLGC, ovl.fmt.RXY.r1,
13800 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13801 ovl.fmt.RXY.dl2,
13802 ovl.fmt.RXY.dh2); goto ok;
13803 case 0xe30000000091ULL: s390_format_RXY_RRRD(s390_irgen_LLGH, ovl.fmt.RXY.r1,
13804 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13805 ovl.fmt.RXY.dl2,
13806 ovl.fmt.RXY.dh2); goto ok;
13807 case 0xe30000000094ULL: s390_format_RXY_RRRD(s390_irgen_LLC, ovl.fmt.RXY.r1,
13808 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13809 ovl.fmt.RXY.dl2,
13810 ovl.fmt.RXY.dh2); goto ok;
13811 case 0xe30000000095ULL: s390_format_RXY_RRRD(s390_irgen_LLH, ovl.fmt.RXY.r1,
13812 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13813 ovl.fmt.RXY.dl2,
13814 ovl.fmt.RXY.dh2); goto ok;
13815 case 0xe30000000096ULL: s390_format_RXY_RRRD(s390_irgen_ML, ovl.fmt.RXY.r1,
13816 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13817 ovl.fmt.RXY.dl2,
13818 ovl.fmt.RXY.dh2); goto ok;
13819 case 0xe30000000097ULL: s390_format_RXY_RRRD(s390_irgen_DL, ovl.fmt.RXY.r1,
13820 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13821 ovl.fmt.RXY.dl2,
13822 ovl.fmt.RXY.dh2); goto ok;
13823 case 0xe30000000098ULL: s390_format_RXY_RRRD(s390_irgen_ALC, ovl.fmt.RXY.r1,
13824 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13825 ovl.fmt.RXY.dl2,
13826 ovl.fmt.RXY.dh2); goto ok;
13827 case 0xe30000000099ULL: s390_format_RXY_RRRD(s390_irgen_SLB, ovl.fmt.RXY.r1,
13828 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13829 ovl.fmt.RXY.dl2,
13830 ovl.fmt.RXY.dh2); goto ok;
13831 case 0xe300000000c0ULL: s390_format_RXY_RRRD(s390_irgen_LBH, ovl.fmt.RXY.r1,
13832 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13833 ovl.fmt.RXY.dl2,
13834 ovl.fmt.RXY.dh2); goto ok;
13835 case 0xe300000000c2ULL: s390_format_RXY_RRRD(s390_irgen_LLCH, ovl.fmt.RXY.r1,
13836 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13837 ovl.fmt.RXY.dl2,
13838 ovl.fmt.RXY.dh2); goto ok;
13839 case 0xe300000000c3ULL: s390_format_RXY_RRRD(s390_irgen_STCH, ovl.fmt.RXY.r1,
13840 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13841 ovl.fmt.RXY.dl2,
13842 ovl.fmt.RXY.dh2); goto ok;
13843 case 0xe300000000c4ULL: s390_format_RXY_RRRD(s390_irgen_LHH, ovl.fmt.RXY.r1,
13844 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13845 ovl.fmt.RXY.dl2,
13846 ovl.fmt.RXY.dh2); goto ok;
13847 case 0xe300000000c6ULL: s390_format_RXY_RRRD(s390_irgen_LLHH, ovl.fmt.RXY.r1,
13848 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13849 ovl.fmt.RXY.dl2,
13850 ovl.fmt.RXY.dh2); goto ok;
13851 case 0xe300000000c7ULL: s390_format_RXY_RRRD(s390_irgen_STHH, ovl.fmt.RXY.r1,
13852 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13853 ovl.fmt.RXY.dl2,
13854 ovl.fmt.RXY.dh2); goto ok;
13855 case 0xe300000000caULL: s390_format_RXY_RRRD(s390_irgen_LFH, ovl.fmt.RXY.r1,
13856 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13857 ovl.fmt.RXY.dl2,
13858 ovl.fmt.RXY.dh2); goto ok;
13859 case 0xe300000000cbULL: s390_format_RXY_RRRD(s390_irgen_STFH, ovl.fmt.RXY.r1,
13860 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13861 ovl.fmt.RXY.dl2,
13862 ovl.fmt.RXY.dh2); goto ok;
13863 case 0xe300000000cdULL: s390_format_RXY_RRRD(s390_irgen_CHF, ovl.fmt.RXY.r1,
13864 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13865 ovl.fmt.RXY.dl2,
13866 ovl.fmt.RXY.dh2); goto ok;
13867 case 0xe300000000cfULL: s390_format_RXY_RRRD(s390_irgen_CLHF, ovl.fmt.RXY.r1,
13868 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13869 ovl.fmt.RXY.dl2,
13870 ovl.fmt.RXY.dh2); goto ok;
13871 case 0xeb0000000004ULL: s390_format_RSY_RRRD(s390_irgen_LMG, ovl.fmt.RSY.r1,
13872 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13873 ovl.fmt.RSY.dl2,
13874 ovl.fmt.RSY.dh2); goto ok;
13875 case 0xeb000000000aULL: s390_format_RSY_RRRD(s390_irgen_SRAG, ovl.fmt.RSY.r1,
13876 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13877 ovl.fmt.RSY.dl2,
13878 ovl.fmt.RSY.dh2); goto ok;
13879 case 0xeb000000000bULL: s390_format_RSY_RRRD(s390_irgen_SLAG, ovl.fmt.RSY.r1,
13880 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13881 ovl.fmt.RSY.dl2,
13882 ovl.fmt.RSY.dh2); goto ok;
13883 case 0xeb000000000cULL: s390_format_RSY_RRRD(s390_irgen_SRLG, ovl.fmt.RSY.r1,
13884 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13885 ovl.fmt.RSY.dl2,
13886 ovl.fmt.RSY.dh2); goto ok;
13887 case 0xeb000000000dULL: s390_format_RSY_RRRD(s390_irgen_SLLG, ovl.fmt.RSY.r1,
13888 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13889 ovl.fmt.RSY.dl2,
13890 ovl.fmt.RSY.dh2); goto ok;
13891 case 0xeb000000000fULL: /* TRACG */ goto unimplemented;
13892 case 0xeb0000000014ULL: s390_format_RSY_RRRD(s390_irgen_CSY, ovl.fmt.RSY.r1,
13893 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13894 ovl.fmt.RSY.dl2,
13895 ovl.fmt.RSY.dh2); goto ok;
13896 case 0xeb000000001cULL: s390_format_RSY_RRRD(s390_irgen_RLLG, ovl.fmt.RSY.r1,
13897 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13898 ovl.fmt.RSY.dl2,
13899 ovl.fmt.RSY.dh2); goto ok;
13900 case 0xeb000000001dULL: s390_format_RSY_RRRD(s390_irgen_RLL, ovl.fmt.RSY.r1,
13901 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13902 ovl.fmt.RSY.dl2,
13903 ovl.fmt.RSY.dh2); goto ok;
13904 case 0xeb0000000020ULL: s390_format_RSY_RURD(s390_irgen_CLMH, ovl.fmt.RSY.r1,
13905 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13906 ovl.fmt.RSY.dl2,
13907 ovl.fmt.RSY.dh2); goto ok;
13908 case 0xeb0000000021ULL: s390_format_RSY_RURD(s390_irgen_CLMY, ovl.fmt.RSY.r1,
13909 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13910 ovl.fmt.RSY.dl2,
13911 ovl.fmt.RSY.dh2); goto ok;
13912 case 0xeb0000000024ULL: s390_format_RSY_RRRD(s390_irgen_STMG, ovl.fmt.RSY.r1,
13913 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13914 ovl.fmt.RSY.dl2,
13915 ovl.fmt.RSY.dh2); goto ok;
13916 case 0xeb0000000025ULL: /* STCTG */ goto unimplemented;
13917 case 0xeb0000000026ULL: s390_format_RSY_RRRD(s390_irgen_STMH, ovl.fmt.RSY.r1,
13918 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13919 ovl.fmt.RSY.dl2,
13920 ovl.fmt.RSY.dh2); goto ok;
13921 case 0xeb000000002cULL: s390_format_RSY_RURD(s390_irgen_STCMH,
13922 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
13923 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
13924 ovl.fmt.RSY.dh2); goto ok;
13925 case 0xeb000000002dULL: s390_format_RSY_RURD(s390_irgen_STCMY,
13926 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
13927 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
13928 ovl.fmt.RSY.dh2); goto ok;
13929 case 0xeb000000002fULL: /* LCTLG */ goto unimplemented;
13930 case 0xeb0000000030ULL: s390_format_RSY_RRRD(s390_irgen_CSG, ovl.fmt.RSY.r1,
13931 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13932 ovl.fmt.RSY.dl2,
13933 ovl.fmt.RSY.dh2); goto ok;
florian448cbba2012-06-06 02:26:01 +000013934 case 0xeb0000000031ULL: s390_format_RSY_RRRD(s390_irgen_CDSY, ovl.fmt.RSY.r1,
13935 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13936 ovl.fmt.RSY.dl2,
13937 ovl.fmt.RSY.dh2); goto ok;
13938 case 0xeb000000003eULL: s390_format_RSY_RRRD(s390_irgen_CDSG, ovl.fmt.RSY.r1,
13939 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13940 ovl.fmt.RSY.dl2,
13941 ovl.fmt.RSY.dh2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013942 case 0xeb0000000044ULL: s390_format_RSY_RRRD(s390_irgen_BXHG, ovl.fmt.RSY.r1,
13943 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13944 ovl.fmt.RSY.dl2,
13945 ovl.fmt.RSY.dh2); goto ok;
13946 case 0xeb0000000045ULL: s390_format_RSY_RRRD(s390_irgen_BXLEG,
13947 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
13948 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
13949 ovl.fmt.RSY.dh2); goto ok;
florian8c88cb62012-08-26 18:58:13 +000013950 case 0xeb000000004cULL: s390_format_RSY_RRRD(s390_irgen_ECAG, ovl.fmt.RSY.r1,
13951 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13952 ovl.fmt.RSY.dl2,
13953 ovl.fmt.RSY.dh2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013954 case 0xeb0000000051ULL: s390_format_SIY_URD(s390_irgen_TMY, ovl.fmt.SIY.i2,
13955 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
13956 ovl.fmt.SIY.dh1); goto ok;
13957 case 0xeb0000000052ULL: s390_format_SIY_URD(s390_irgen_MVIY, ovl.fmt.SIY.i2,
13958 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
13959 ovl.fmt.SIY.dh1); goto ok;
13960 case 0xeb0000000054ULL: s390_format_SIY_URD(s390_irgen_NIY, ovl.fmt.SIY.i2,
13961 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
13962 ovl.fmt.SIY.dh1); goto ok;
13963 case 0xeb0000000055ULL: s390_format_SIY_URD(s390_irgen_CLIY, ovl.fmt.SIY.i2,
13964 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
13965 ovl.fmt.SIY.dh1); goto ok;
13966 case 0xeb0000000056ULL: s390_format_SIY_URD(s390_irgen_OIY, ovl.fmt.SIY.i2,
13967 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
13968 ovl.fmt.SIY.dh1); goto ok;
13969 case 0xeb0000000057ULL: s390_format_SIY_URD(s390_irgen_XIY, ovl.fmt.SIY.i2,
13970 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
13971 ovl.fmt.SIY.dh1); goto ok;
13972 case 0xeb000000006aULL: s390_format_SIY_IRD(s390_irgen_ASI, ovl.fmt.SIY.i2,
13973 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
13974 ovl.fmt.SIY.dh1); goto ok;
13975 case 0xeb000000006eULL: s390_format_SIY_IRD(s390_irgen_ALSI, ovl.fmt.SIY.i2,
13976 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
13977 ovl.fmt.SIY.dh1); goto ok;
13978 case 0xeb000000007aULL: s390_format_SIY_IRD(s390_irgen_AGSI, ovl.fmt.SIY.i2,
13979 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
13980 ovl.fmt.SIY.dh1); goto ok;
13981 case 0xeb000000007eULL: s390_format_SIY_IRD(s390_irgen_ALGSI, ovl.fmt.SIY.i2,
13982 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
13983 ovl.fmt.SIY.dh1); goto ok;
13984 case 0xeb0000000080ULL: s390_format_RSY_RURD(s390_irgen_ICMH, ovl.fmt.RSY.r1,
13985 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13986 ovl.fmt.RSY.dl2,
13987 ovl.fmt.RSY.dh2); goto ok;
13988 case 0xeb0000000081ULL: s390_format_RSY_RURD(s390_irgen_ICMY, ovl.fmt.RSY.r1,
13989 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13990 ovl.fmt.RSY.dl2,
13991 ovl.fmt.RSY.dh2); goto ok;
13992 case 0xeb000000008eULL: /* MVCLU */ goto unimplemented;
13993 case 0xeb000000008fULL: /* CLCLU */ goto unimplemented;
13994 case 0xeb0000000090ULL: s390_format_RSY_RRRD(s390_irgen_STMY, ovl.fmt.RSY.r1,
13995 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13996 ovl.fmt.RSY.dl2,
13997 ovl.fmt.RSY.dh2); goto ok;
13998 case 0xeb0000000096ULL: s390_format_RSY_RRRD(s390_irgen_LMH, ovl.fmt.RSY.r1,
13999 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14000 ovl.fmt.RSY.dl2,
14001 ovl.fmt.RSY.dh2); goto ok;
14002 case 0xeb0000000098ULL: s390_format_RSY_RRRD(s390_irgen_LMY, ovl.fmt.RSY.r1,
14003 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14004 ovl.fmt.RSY.dl2,
14005 ovl.fmt.RSY.dh2); goto ok;
14006 case 0xeb000000009aULL: s390_format_RSY_AARD(s390_irgen_LAMY, ovl.fmt.RSY.r1,
14007 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14008 ovl.fmt.RSY.dl2,
14009 ovl.fmt.RSY.dh2); goto ok;
14010 case 0xeb000000009bULL: s390_format_RSY_AARD(s390_irgen_STAMY,
14011 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
14012 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
14013 ovl.fmt.RSY.dh2); goto ok;
14014 case 0xeb00000000c0ULL: /* TP */ goto unimplemented;
14015 case 0xeb00000000dcULL: s390_format_RSY_RRRD(s390_irgen_SRAK, ovl.fmt.RSY.r1,
14016 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14017 ovl.fmt.RSY.dl2,
14018 ovl.fmt.RSY.dh2); goto ok;
14019 case 0xeb00000000ddULL: s390_format_RSY_RRRD(s390_irgen_SLAK, ovl.fmt.RSY.r1,
14020 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14021 ovl.fmt.RSY.dl2,
14022 ovl.fmt.RSY.dh2); goto ok;
14023 case 0xeb00000000deULL: s390_format_RSY_RRRD(s390_irgen_SRLK, 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 0xeb00000000dfULL: s390_format_RSY_RRRD(s390_irgen_SLLK, 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;
sewardjd7bde722011-04-05 13:19:33 +000014031 case 0xeb00000000e2ULL: s390_format_RSY_RDRM(s390_irgen_LOCG, ovl.fmt.RSY.r1,
14032 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14033 ovl.fmt.RSY.dl2,
14034 ovl.fmt.RSY.dh2,
14035 S390_XMNM_LOCG); goto ok;
14036 case 0xeb00000000e3ULL: s390_format_RSY_RDRM(s390_irgen_STOCG,
14037 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
14038 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
14039 ovl.fmt.RSY.dh2,
14040 S390_XMNM_STOCG); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014041 case 0xeb00000000e4ULL: s390_format_RSY_RRRD(s390_irgen_LANG, 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 0xeb00000000e6ULL: s390_format_RSY_RRRD(s390_irgen_LAOG, 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 0xeb00000000e7ULL: s390_format_RSY_RRRD(s390_irgen_LAXG, ovl.fmt.RSY.r1,
14050 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14051 ovl.fmt.RSY.dl2,
14052 ovl.fmt.RSY.dh2); goto ok;
14053 case 0xeb00000000e8ULL: s390_format_RSY_RRRD(s390_irgen_LAAG, ovl.fmt.RSY.r1,
14054 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14055 ovl.fmt.RSY.dl2,
14056 ovl.fmt.RSY.dh2); goto ok;
14057 case 0xeb00000000eaULL: s390_format_RSY_RRRD(s390_irgen_LAALG,
14058 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
14059 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
14060 ovl.fmt.RSY.dh2); goto ok;
sewardjd7bde722011-04-05 13:19:33 +000014061 case 0xeb00000000f2ULL: s390_format_RSY_RDRM(s390_irgen_LOC, ovl.fmt.RSY.r1,
14062 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14063 ovl.fmt.RSY.dl2,
14064 ovl.fmt.RSY.dh2, S390_XMNM_LOC);
14065 goto ok;
14066 case 0xeb00000000f3ULL: s390_format_RSY_RDRM(s390_irgen_STOC, ovl.fmt.RSY.r1,
14067 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14068 ovl.fmt.RSY.dl2,
14069 ovl.fmt.RSY.dh2,
14070 S390_XMNM_STOC); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014071 case 0xeb00000000f4ULL: s390_format_RSY_RRRD(s390_irgen_LAN, ovl.fmt.RSY.r1,
14072 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14073 ovl.fmt.RSY.dl2,
14074 ovl.fmt.RSY.dh2); goto ok;
14075 case 0xeb00000000f6ULL: s390_format_RSY_RRRD(s390_irgen_LAO, ovl.fmt.RSY.r1,
14076 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14077 ovl.fmt.RSY.dl2,
14078 ovl.fmt.RSY.dh2); goto ok;
14079 case 0xeb00000000f7ULL: s390_format_RSY_RRRD(s390_irgen_LAX, ovl.fmt.RSY.r1,
14080 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14081 ovl.fmt.RSY.dl2,
14082 ovl.fmt.RSY.dh2); goto ok;
14083 case 0xeb00000000f8ULL: s390_format_RSY_RRRD(s390_irgen_LAA, ovl.fmt.RSY.r1,
14084 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14085 ovl.fmt.RSY.dl2,
14086 ovl.fmt.RSY.dh2); goto ok;
14087 case 0xeb00000000faULL: s390_format_RSY_RRRD(s390_irgen_LAAL, ovl.fmt.RSY.r1,
14088 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14089 ovl.fmt.RSY.dl2,
14090 ovl.fmt.RSY.dh2); goto ok;
14091 case 0xec0000000044ULL: s390_format_RIE_RRP(s390_irgen_BRXHG, ovl.fmt.RIE.r1,
14092 ovl.fmt.RIE.r3, ovl.fmt.RIE.i2);
14093 goto ok;
14094 case 0xec0000000045ULL: s390_format_RIE_RRP(s390_irgen_BRXLG, ovl.fmt.RIE.r1,
14095 ovl.fmt.RIE.r3, ovl.fmt.RIE.i2);
14096 goto ok;
14097 case 0xec0000000051ULL: /* RISBLG */ goto unimplemented;
14098 case 0xec0000000054ULL: s390_format_RIE_RRUUU(s390_irgen_RNSBG,
14099 ovl.fmt.RIE_RRUUU.r1,
14100 ovl.fmt.RIE_RRUUU.r2,
14101 ovl.fmt.RIE_RRUUU.i3,
14102 ovl.fmt.RIE_RRUUU.i4,
14103 ovl.fmt.RIE_RRUUU.i5);
14104 goto ok;
14105 case 0xec0000000055ULL: s390_format_RIE_RRUUU(s390_irgen_RISBG,
14106 ovl.fmt.RIE_RRUUU.r1,
14107 ovl.fmt.RIE_RRUUU.r2,
14108 ovl.fmt.RIE_RRUUU.i3,
14109 ovl.fmt.RIE_RRUUU.i4,
14110 ovl.fmt.RIE_RRUUU.i5);
14111 goto ok;
14112 case 0xec0000000056ULL: s390_format_RIE_RRUUU(s390_irgen_ROSBG,
14113 ovl.fmt.RIE_RRUUU.r1,
14114 ovl.fmt.RIE_RRUUU.r2,
14115 ovl.fmt.RIE_RRUUU.i3,
14116 ovl.fmt.RIE_RRUUU.i4,
14117 ovl.fmt.RIE_RRUUU.i5);
14118 goto ok;
14119 case 0xec0000000057ULL: s390_format_RIE_RRUUU(s390_irgen_RXSBG,
14120 ovl.fmt.RIE_RRUUU.r1,
14121 ovl.fmt.RIE_RRUUU.r2,
14122 ovl.fmt.RIE_RRUUU.i3,
14123 ovl.fmt.RIE_RRUUU.i4,
14124 ovl.fmt.RIE_RRUUU.i5);
14125 goto ok;
14126 case 0xec000000005dULL: /* RISBHG */ goto unimplemented;
14127 case 0xec0000000064ULL: s390_format_RIE_RRPU(s390_irgen_CGRJ,
14128 ovl.fmt.RIE_RRPU.r1,
14129 ovl.fmt.RIE_RRPU.r2,
14130 ovl.fmt.RIE_RRPU.i4,
14131 ovl.fmt.RIE_RRPU.m3); goto ok;
14132 case 0xec0000000065ULL: s390_format_RIE_RRPU(s390_irgen_CLGRJ,
14133 ovl.fmt.RIE_RRPU.r1,
14134 ovl.fmt.RIE_RRPU.r2,
14135 ovl.fmt.RIE_RRPU.i4,
14136 ovl.fmt.RIE_RRPU.m3); goto ok;
14137 case 0xec0000000070ULL: /* CGIT */ goto unimplemented;
14138 case 0xec0000000071ULL: /* CLGIT */ goto unimplemented;
14139 case 0xec0000000072ULL: /* CIT */ goto unimplemented;
14140 case 0xec0000000073ULL: /* CLFIT */ goto unimplemented;
14141 case 0xec0000000076ULL: s390_format_RIE_RRPU(s390_irgen_CRJ,
14142 ovl.fmt.RIE_RRPU.r1,
14143 ovl.fmt.RIE_RRPU.r2,
14144 ovl.fmt.RIE_RRPU.i4,
14145 ovl.fmt.RIE_RRPU.m3); goto ok;
14146 case 0xec0000000077ULL: s390_format_RIE_RRPU(s390_irgen_CLRJ,
14147 ovl.fmt.RIE_RRPU.r1,
14148 ovl.fmt.RIE_RRPU.r2,
14149 ovl.fmt.RIE_RRPU.i4,
14150 ovl.fmt.RIE_RRPU.m3); goto ok;
14151 case 0xec000000007cULL: s390_format_RIE_RUPI(s390_irgen_CGIJ,
14152 ovl.fmt.RIEv3.r1,
14153 ovl.fmt.RIEv3.m3,
14154 ovl.fmt.RIEv3.i4,
14155 ovl.fmt.RIEv3.i2); goto ok;
14156 case 0xec000000007dULL: s390_format_RIE_RUPU(s390_irgen_CLGIJ,
14157 ovl.fmt.RIEv3.r1,
14158 ovl.fmt.RIEv3.m3,
14159 ovl.fmt.RIEv3.i4,
14160 ovl.fmt.RIEv3.i2); goto ok;
14161 case 0xec000000007eULL: s390_format_RIE_RUPI(s390_irgen_CIJ,
14162 ovl.fmt.RIEv3.r1,
14163 ovl.fmt.RIEv3.m3,
14164 ovl.fmt.RIEv3.i4,
14165 ovl.fmt.RIEv3.i2); goto ok;
14166 case 0xec000000007fULL: s390_format_RIE_RUPU(s390_irgen_CLIJ,
14167 ovl.fmt.RIEv3.r1,
14168 ovl.fmt.RIEv3.m3,
14169 ovl.fmt.RIEv3.i4,
14170 ovl.fmt.RIEv3.i2); goto ok;
14171 case 0xec00000000d8ULL: s390_format_RIE_RRI0(s390_irgen_AHIK, ovl.fmt.RIE.r1,
14172 ovl.fmt.RIE.r3, ovl.fmt.RIE.i2);
14173 goto ok;
14174 case 0xec00000000d9ULL: s390_format_RIE_RRI0(s390_irgen_AGHIK,
14175 ovl.fmt.RIE.r1, ovl.fmt.RIE.r3,
14176 ovl.fmt.RIE.i2); goto ok;
14177 case 0xec00000000daULL: s390_format_RIE_RRI0(s390_irgen_ALHSIK,
14178 ovl.fmt.RIE.r1, ovl.fmt.RIE.r3,
14179 ovl.fmt.RIE.i2); goto ok;
14180 case 0xec00000000dbULL: s390_format_RIE_RRI0(s390_irgen_ALGHSIK,
14181 ovl.fmt.RIE.r1, ovl.fmt.RIE.r3,
14182 ovl.fmt.RIE.i2); goto ok;
14183 case 0xec00000000e4ULL: s390_format_RRS(s390_irgen_CGRB, ovl.fmt.RRS.r1,
14184 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
14185 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
14186 goto ok;
14187 case 0xec00000000e5ULL: s390_format_RRS(s390_irgen_CLGRB, ovl.fmt.RRS.r1,
14188 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
14189 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
14190 goto ok;
14191 case 0xec00000000f6ULL: s390_format_RRS(s390_irgen_CRB, ovl.fmt.RRS.r1,
14192 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
14193 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
14194 goto ok;
14195 case 0xec00000000f7ULL: s390_format_RRS(s390_irgen_CLRB, ovl.fmt.RRS.r1,
14196 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
14197 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
14198 goto ok;
14199 case 0xec00000000fcULL: s390_format_RIS_RURDI(s390_irgen_CGIB,
14200 ovl.fmt.RIS.r1, ovl.fmt.RIS.m3,
14201 ovl.fmt.RIS.b4, ovl.fmt.RIS.d4,
14202 ovl.fmt.RIS.i2); goto ok;
14203 case 0xec00000000fdULL: s390_format_RIS_RURDU(s390_irgen_CLGIB,
14204 ovl.fmt.RIS.r1, ovl.fmt.RIS.m3,
14205 ovl.fmt.RIS.b4, ovl.fmt.RIS.d4,
14206 ovl.fmt.RIS.i2); goto ok;
14207 case 0xec00000000feULL: s390_format_RIS_RURDI(s390_irgen_CIB, ovl.fmt.RIS.r1,
14208 ovl.fmt.RIS.m3, ovl.fmt.RIS.b4,
14209 ovl.fmt.RIS.d4,
14210 ovl.fmt.RIS.i2); goto ok;
14211 case 0xec00000000ffULL: s390_format_RIS_RURDU(s390_irgen_CLIB,
14212 ovl.fmt.RIS.r1, ovl.fmt.RIS.m3,
14213 ovl.fmt.RIS.b4, ovl.fmt.RIS.d4,
14214 ovl.fmt.RIS.i2); goto ok;
14215 case 0xed0000000004ULL: s390_format_RXE_FRRD(s390_irgen_LDEB, ovl.fmt.RXE.r1,
14216 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14217 ovl.fmt.RXE.d2); goto ok;
14218 case 0xed0000000005ULL: s390_format_RXE_FRRD(s390_irgen_LXDB, ovl.fmt.RXE.r1,
14219 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14220 ovl.fmt.RXE.d2); goto ok;
14221 case 0xed0000000006ULL: s390_format_RXE_FRRD(s390_irgen_LXEB, ovl.fmt.RXE.r1,
14222 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14223 ovl.fmt.RXE.d2); goto ok;
14224 case 0xed0000000007ULL: /* MXDB */ goto unimplemented;
14225 case 0xed0000000008ULL: /* KEB */ goto unimplemented;
14226 case 0xed0000000009ULL: s390_format_RXE_FRRD(s390_irgen_CEB, ovl.fmt.RXE.r1,
14227 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14228 ovl.fmt.RXE.d2); goto ok;
14229 case 0xed000000000aULL: s390_format_RXE_FRRD(s390_irgen_AEB, ovl.fmt.RXE.r1,
14230 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14231 ovl.fmt.RXE.d2); goto ok;
14232 case 0xed000000000bULL: s390_format_RXE_FRRD(s390_irgen_SEB, ovl.fmt.RXE.r1,
14233 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14234 ovl.fmt.RXE.d2); goto ok;
14235 case 0xed000000000cULL: /* MDEB */ goto unimplemented;
14236 case 0xed000000000dULL: s390_format_RXE_FRRD(s390_irgen_DEB, ovl.fmt.RXE.r1,
14237 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14238 ovl.fmt.RXE.d2); goto ok;
14239 case 0xed000000000eULL: s390_format_RXF_FRRDF(s390_irgen_MAEB,
14240 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
14241 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
14242 ovl.fmt.RXF.r1); goto ok;
14243 case 0xed000000000fULL: s390_format_RXF_FRRDF(s390_irgen_MSEB,
14244 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
14245 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
14246 ovl.fmt.RXF.r1); goto ok;
14247 case 0xed0000000010ULL: s390_format_RXE_FRRD(s390_irgen_TCEB, ovl.fmt.RXE.r1,
14248 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14249 ovl.fmt.RXE.d2); goto ok;
14250 case 0xed0000000011ULL: s390_format_RXE_FRRD(s390_irgen_TCDB, ovl.fmt.RXE.r1,
14251 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14252 ovl.fmt.RXE.d2); goto ok;
14253 case 0xed0000000012ULL: s390_format_RXE_FRRD(s390_irgen_TCXB, ovl.fmt.RXE.r1,
14254 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14255 ovl.fmt.RXE.d2); goto ok;
14256 case 0xed0000000014ULL: s390_format_RXE_FRRD(s390_irgen_SQEB, ovl.fmt.RXE.r1,
14257 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14258 ovl.fmt.RXE.d2); goto ok;
14259 case 0xed0000000015ULL: s390_format_RXE_FRRD(s390_irgen_SQDB, ovl.fmt.RXE.r1,
14260 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14261 ovl.fmt.RXE.d2); goto ok;
14262 case 0xed0000000017ULL: s390_format_RXE_FRRD(s390_irgen_MEEB, ovl.fmt.RXE.r1,
14263 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14264 ovl.fmt.RXE.d2); goto ok;
14265 case 0xed0000000018ULL: /* KDB */ goto unimplemented;
14266 case 0xed0000000019ULL: s390_format_RXE_FRRD(s390_irgen_CDB, ovl.fmt.RXE.r1,
14267 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14268 ovl.fmt.RXE.d2); goto ok;
14269 case 0xed000000001aULL: s390_format_RXE_FRRD(s390_irgen_ADB, ovl.fmt.RXE.r1,
14270 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14271 ovl.fmt.RXE.d2); goto ok;
14272 case 0xed000000001bULL: s390_format_RXE_FRRD(s390_irgen_SDB, ovl.fmt.RXE.r1,
14273 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14274 ovl.fmt.RXE.d2); goto ok;
14275 case 0xed000000001cULL: s390_format_RXE_FRRD(s390_irgen_MDB, ovl.fmt.RXE.r1,
14276 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14277 ovl.fmt.RXE.d2); goto ok;
14278 case 0xed000000001dULL: s390_format_RXE_FRRD(s390_irgen_DDB, ovl.fmt.RXE.r1,
14279 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14280 ovl.fmt.RXE.d2); goto ok;
14281 case 0xed000000001eULL: s390_format_RXF_FRRDF(s390_irgen_MADB,
14282 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
14283 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
14284 ovl.fmt.RXF.r1); goto ok;
14285 case 0xed000000001fULL: s390_format_RXF_FRRDF(s390_irgen_MSDB,
14286 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
14287 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
14288 ovl.fmt.RXF.r1); goto ok;
14289 case 0xed0000000024ULL: /* LDE */ goto unimplemented;
14290 case 0xed0000000025ULL: /* LXD */ goto unimplemented;
14291 case 0xed0000000026ULL: /* LXE */ goto unimplemented;
14292 case 0xed000000002eULL: /* MAE */ goto unimplemented;
14293 case 0xed000000002fULL: /* MSE */ goto unimplemented;
14294 case 0xed0000000034ULL: /* SQE */ goto unimplemented;
14295 case 0xed0000000035ULL: /* SQD */ goto unimplemented;
14296 case 0xed0000000037ULL: /* MEE */ goto unimplemented;
14297 case 0xed0000000038ULL: /* MAYL */ goto unimplemented;
14298 case 0xed0000000039ULL: /* MYL */ goto unimplemented;
14299 case 0xed000000003aULL: /* MAY */ goto unimplemented;
14300 case 0xed000000003bULL: /* MY */ goto unimplemented;
14301 case 0xed000000003cULL: /* MAYH */ goto unimplemented;
14302 case 0xed000000003dULL: /* MYH */ goto unimplemented;
14303 case 0xed000000003eULL: /* MAD */ goto unimplemented;
14304 case 0xed000000003fULL: /* MSD */ goto unimplemented;
14305 case 0xed0000000040ULL: /* SLDT */ goto unimplemented;
14306 case 0xed0000000041ULL: /* SRDT */ goto unimplemented;
14307 case 0xed0000000048ULL: /* SLXT */ goto unimplemented;
14308 case 0xed0000000049ULL: /* SRXT */ goto unimplemented;
14309 case 0xed0000000050ULL: /* TDCET */ goto unimplemented;
14310 case 0xed0000000051ULL: /* TDGET */ goto unimplemented;
14311 case 0xed0000000054ULL: /* TDCDT */ goto unimplemented;
14312 case 0xed0000000055ULL: /* TDGDT */ goto unimplemented;
14313 case 0xed0000000058ULL: /* TDCXT */ goto unimplemented;
14314 case 0xed0000000059ULL: /* TDGXT */ goto unimplemented;
14315 case 0xed0000000064ULL: s390_format_RXY_FRRD(s390_irgen_LEY, ovl.fmt.RXY.r1,
14316 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14317 ovl.fmt.RXY.dl2,
14318 ovl.fmt.RXY.dh2); goto ok;
14319 case 0xed0000000065ULL: s390_format_RXY_FRRD(s390_irgen_LDY, ovl.fmt.RXY.r1,
14320 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14321 ovl.fmt.RXY.dl2,
14322 ovl.fmt.RXY.dh2); goto ok;
14323 case 0xed0000000066ULL: s390_format_RXY_FRRD(s390_irgen_STEY, ovl.fmt.RXY.r1,
14324 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14325 ovl.fmt.RXY.dl2,
14326 ovl.fmt.RXY.dh2); goto ok;
14327 case 0xed0000000067ULL: s390_format_RXY_FRRD(s390_irgen_STDY, ovl.fmt.RXY.r1,
14328 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14329 ovl.fmt.RXY.dl2,
14330 ovl.fmt.RXY.dh2); goto ok;
14331 }
14332
14333 switch (((ovl.value >> 16) & 0xff0f00000000ULL) >> 32) {
14334 case 0xc000ULL: s390_format_RIL_RP(s390_irgen_LARL, ovl.fmt.RIL.r1,
14335 ovl.fmt.RIL.i2); goto ok;
14336 case 0xc001ULL: s390_format_RIL_RI(s390_irgen_LGFI, ovl.fmt.RIL.r1,
14337 ovl.fmt.RIL.i2); goto ok;
14338 case 0xc004ULL: s390_format_RIL(s390_irgen_BRCL, ovl.fmt.RIL.r1,
14339 ovl.fmt.RIL.i2); goto ok;
14340 case 0xc005ULL: s390_format_RIL_RP(s390_irgen_BRASL, ovl.fmt.RIL.r1,
14341 ovl.fmt.RIL.i2); goto ok;
14342 case 0xc006ULL: s390_format_RIL_RU(s390_irgen_XIHF, ovl.fmt.RIL.r1,
14343 ovl.fmt.RIL.i2); goto ok;
14344 case 0xc007ULL: s390_format_RIL_RU(s390_irgen_XILF, ovl.fmt.RIL.r1,
14345 ovl.fmt.RIL.i2); goto ok;
14346 case 0xc008ULL: s390_format_RIL_RU(s390_irgen_IIHF, ovl.fmt.RIL.r1,
14347 ovl.fmt.RIL.i2); goto ok;
14348 case 0xc009ULL: s390_format_RIL_RU(s390_irgen_IILF, ovl.fmt.RIL.r1,
14349 ovl.fmt.RIL.i2); goto ok;
14350 case 0xc00aULL: s390_format_RIL_RU(s390_irgen_NIHF, ovl.fmt.RIL.r1,
14351 ovl.fmt.RIL.i2); goto ok;
14352 case 0xc00bULL: s390_format_RIL_RU(s390_irgen_NILF, ovl.fmt.RIL.r1,
14353 ovl.fmt.RIL.i2); goto ok;
14354 case 0xc00cULL: s390_format_RIL_RU(s390_irgen_OIHF, ovl.fmt.RIL.r1,
14355 ovl.fmt.RIL.i2); goto ok;
14356 case 0xc00dULL: s390_format_RIL_RU(s390_irgen_OILF, ovl.fmt.RIL.r1,
14357 ovl.fmt.RIL.i2); goto ok;
14358 case 0xc00eULL: s390_format_RIL_RU(s390_irgen_LLIHF, ovl.fmt.RIL.r1,
14359 ovl.fmt.RIL.i2); goto ok;
14360 case 0xc00fULL: s390_format_RIL_RU(s390_irgen_LLILF, ovl.fmt.RIL.r1,
14361 ovl.fmt.RIL.i2); goto ok;
14362 case 0xc200ULL: s390_format_RIL_RI(s390_irgen_MSGFI, ovl.fmt.RIL.r1,
14363 ovl.fmt.RIL.i2); goto ok;
14364 case 0xc201ULL: s390_format_RIL_RI(s390_irgen_MSFI, ovl.fmt.RIL.r1,
14365 ovl.fmt.RIL.i2); goto ok;
14366 case 0xc204ULL: s390_format_RIL_RU(s390_irgen_SLGFI, ovl.fmt.RIL.r1,
14367 ovl.fmt.RIL.i2); goto ok;
14368 case 0xc205ULL: s390_format_RIL_RU(s390_irgen_SLFI, ovl.fmt.RIL.r1,
14369 ovl.fmt.RIL.i2); goto ok;
14370 case 0xc208ULL: s390_format_RIL_RI(s390_irgen_AGFI, ovl.fmt.RIL.r1,
14371 ovl.fmt.RIL.i2); goto ok;
14372 case 0xc209ULL: s390_format_RIL_RI(s390_irgen_AFI, ovl.fmt.RIL.r1,
14373 ovl.fmt.RIL.i2); goto ok;
14374 case 0xc20aULL: s390_format_RIL_RU(s390_irgen_ALGFI, ovl.fmt.RIL.r1,
14375 ovl.fmt.RIL.i2); goto ok;
14376 case 0xc20bULL: s390_format_RIL_RU(s390_irgen_ALFI, ovl.fmt.RIL.r1,
14377 ovl.fmt.RIL.i2); goto ok;
14378 case 0xc20cULL: s390_format_RIL_RI(s390_irgen_CGFI, ovl.fmt.RIL.r1,
14379 ovl.fmt.RIL.i2); goto ok;
14380 case 0xc20dULL: s390_format_RIL_RI(s390_irgen_CFI, ovl.fmt.RIL.r1,
14381 ovl.fmt.RIL.i2); goto ok;
14382 case 0xc20eULL: s390_format_RIL_RU(s390_irgen_CLGFI, ovl.fmt.RIL.r1,
14383 ovl.fmt.RIL.i2); goto ok;
14384 case 0xc20fULL: s390_format_RIL_RU(s390_irgen_CLFI, ovl.fmt.RIL.r1,
14385 ovl.fmt.RIL.i2); goto ok;
14386 case 0xc402ULL: s390_format_RIL_RP(s390_irgen_LLHRL, ovl.fmt.RIL.r1,
14387 ovl.fmt.RIL.i2); goto ok;
14388 case 0xc404ULL: s390_format_RIL_RP(s390_irgen_LGHRL, ovl.fmt.RIL.r1,
14389 ovl.fmt.RIL.i2); goto ok;
14390 case 0xc405ULL: s390_format_RIL_RP(s390_irgen_LHRL, ovl.fmt.RIL.r1,
14391 ovl.fmt.RIL.i2); goto ok;
14392 case 0xc406ULL: s390_format_RIL_RP(s390_irgen_LLGHRL, ovl.fmt.RIL.r1,
14393 ovl.fmt.RIL.i2); goto ok;
14394 case 0xc407ULL: s390_format_RIL_RP(s390_irgen_STHRL, ovl.fmt.RIL.r1,
14395 ovl.fmt.RIL.i2); goto ok;
14396 case 0xc408ULL: s390_format_RIL_RP(s390_irgen_LGRL, ovl.fmt.RIL.r1,
14397 ovl.fmt.RIL.i2); goto ok;
14398 case 0xc40bULL: s390_format_RIL_RP(s390_irgen_STGRL, ovl.fmt.RIL.r1,
14399 ovl.fmt.RIL.i2); goto ok;
14400 case 0xc40cULL: s390_format_RIL_RP(s390_irgen_LGFRL, ovl.fmt.RIL.r1,
14401 ovl.fmt.RIL.i2); goto ok;
14402 case 0xc40dULL: s390_format_RIL_RP(s390_irgen_LRL, ovl.fmt.RIL.r1,
14403 ovl.fmt.RIL.i2); goto ok;
14404 case 0xc40eULL: s390_format_RIL_RP(s390_irgen_LLGFRL, ovl.fmt.RIL.r1,
14405 ovl.fmt.RIL.i2); goto ok;
14406 case 0xc40fULL: s390_format_RIL_RP(s390_irgen_STRL, ovl.fmt.RIL.r1,
14407 ovl.fmt.RIL.i2); goto ok;
14408 case 0xc600ULL: s390_format_RIL_RP(s390_irgen_EXRL, ovl.fmt.RIL.r1,
14409 ovl.fmt.RIL.i2); goto ok;
14410 case 0xc602ULL: s390_format_RIL_UP(s390_irgen_PFDRL, ovl.fmt.RIL.r1,
14411 ovl.fmt.RIL.i2); goto ok;
14412 case 0xc604ULL: s390_format_RIL_RP(s390_irgen_CGHRL, ovl.fmt.RIL.r1,
14413 ovl.fmt.RIL.i2); goto ok;
14414 case 0xc605ULL: s390_format_RIL_RP(s390_irgen_CHRL, ovl.fmt.RIL.r1,
14415 ovl.fmt.RIL.i2); goto ok;
14416 case 0xc606ULL: s390_format_RIL_RP(s390_irgen_CLGHRL, ovl.fmt.RIL.r1,
14417 ovl.fmt.RIL.i2); goto ok;
14418 case 0xc607ULL: s390_format_RIL_RP(s390_irgen_CLHRL, ovl.fmt.RIL.r1,
14419 ovl.fmt.RIL.i2); goto ok;
14420 case 0xc608ULL: s390_format_RIL_RP(s390_irgen_CGRL, ovl.fmt.RIL.r1,
14421 ovl.fmt.RIL.i2); goto ok;
14422 case 0xc60aULL: s390_format_RIL_RP(s390_irgen_CLGRL, ovl.fmt.RIL.r1,
14423 ovl.fmt.RIL.i2); goto ok;
14424 case 0xc60cULL: s390_format_RIL_RP(s390_irgen_CGFRL, ovl.fmt.RIL.r1,
14425 ovl.fmt.RIL.i2); goto ok;
14426 case 0xc60dULL: s390_format_RIL_RP(s390_irgen_CRL, ovl.fmt.RIL.r1,
14427 ovl.fmt.RIL.i2); goto ok;
14428 case 0xc60eULL: s390_format_RIL_RP(s390_irgen_CLGFRL, ovl.fmt.RIL.r1,
14429 ovl.fmt.RIL.i2); goto ok;
14430 case 0xc60fULL: s390_format_RIL_RP(s390_irgen_CLRL, ovl.fmt.RIL.r1,
14431 ovl.fmt.RIL.i2); goto ok;
14432 case 0xc800ULL: /* MVCOS */ goto unimplemented;
14433 case 0xc801ULL: /* ECTG */ goto unimplemented;
14434 case 0xc802ULL: /* CSST */ goto unimplemented;
14435 case 0xc804ULL: /* LPD */ goto unimplemented;
14436 case 0xc805ULL: /* LPDG */ goto unimplemented;
14437 case 0xcc06ULL: /* BRCTH */ goto unimplemented;
14438 case 0xcc08ULL: s390_format_RIL_RI(s390_irgen_AIH, ovl.fmt.RIL.r1,
14439 ovl.fmt.RIL.i2); goto ok;
14440 case 0xcc0aULL: s390_format_RIL_RI(s390_irgen_ALSIH, ovl.fmt.RIL.r1,
14441 ovl.fmt.RIL.i2); goto ok;
14442 case 0xcc0bULL: s390_format_RIL_RI(s390_irgen_ALSIHN, ovl.fmt.RIL.r1,
14443 ovl.fmt.RIL.i2); goto ok;
14444 case 0xcc0dULL: s390_format_RIL_RI(s390_irgen_CIH, ovl.fmt.RIL.r1,
14445 ovl.fmt.RIL.i2); goto ok;
14446 case 0xcc0fULL: s390_format_RIL_RU(s390_irgen_CLIH, ovl.fmt.RIL.r1,
14447 ovl.fmt.RIL.i2); goto ok;
14448 }
14449
14450 switch (((ovl.value >> 16) & 0xff0000000000ULL) >> 40) {
14451 case 0xd0ULL: /* TRTR */ goto unimplemented;
14452 case 0xd1ULL: /* MVN */ goto unimplemented;
14453 case 0xd2ULL: s390_format_SS_L0RDRD(s390_irgen_MVC, ovl.fmt.SS.l,
14454 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
14455 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
14456 case 0xd3ULL: /* MVZ */ goto unimplemented;
14457 case 0xd4ULL: s390_format_SS_L0RDRD(s390_irgen_NC, ovl.fmt.SS.l,
14458 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
14459 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
14460 case 0xd5ULL: s390_format_SS_L0RDRD(s390_irgen_CLC, ovl.fmt.SS.l,
14461 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
14462 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
14463 case 0xd6ULL: s390_format_SS_L0RDRD(s390_irgen_OC, ovl.fmt.SS.l,
14464 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
14465 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
sewardjb63967e2011-03-24 08:50:04 +000014466 case 0xd7ULL:
14467 if (ovl.fmt.SS.b1 == ovl.fmt.SS.b2 && ovl.fmt.SS.d1 == ovl.fmt.SS.d2)
14468 s390_irgen_XC_sameloc(ovl.fmt.SS.l, ovl.fmt.SS.b1, ovl.fmt.SS.d1);
14469 else
14470 s390_format_SS_L0RDRD(s390_irgen_XC, ovl.fmt.SS.l,
14471 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
14472 ovl.fmt.SS.b2, ovl.fmt.SS.d2);
14473 goto ok;
sewardj2019a972011-03-07 16:04:07 +000014474 case 0xd9ULL: /* MVCK */ goto unimplemented;
14475 case 0xdaULL: /* MVCP */ goto unimplemented;
14476 case 0xdbULL: /* MVCS */ goto unimplemented;
florian730448f2012-02-04 17:07:07 +000014477 case 0xdcULL: s390_format_SS_L0RDRD(s390_irgen_TR, ovl.fmt.SS.l,
14478 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
14479 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014480 case 0xddULL: /* TRT */ goto unimplemented;
14481 case 0xdeULL: /* ED */ goto unimplemented;
14482 case 0xdfULL: /* EDMK */ goto unimplemented;
14483 case 0xe1ULL: /* PKU */ goto unimplemented;
14484 case 0xe2ULL: /* UNPKU */ goto unimplemented;
14485 case 0xe8ULL: /* MVCIN */ goto unimplemented;
14486 case 0xe9ULL: /* PKA */ goto unimplemented;
14487 case 0xeaULL: /* UNPKA */ goto unimplemented;
14488 case 0xeeULL: /* PLO */ goto unimplemented;
14489 case 0xefULL: /* LMD */ goto unimplemented;
14490 case 0xf0ULL: /* SRP */ goto unimplemented;
14491 case 0xf1ULL: /* MVO */ goto unimplemented;
14492 case 0xf2ULL: /* PACK */ goto unimplemented;
14493 case 0xf3ULL: /* UNPK */ goto unimplemented;
14494 case 0xf8ULL: /* ZAP */ goto unimplemented;
14495 case 0xf9ULL: /* CP */ goto unimplemented;
14496 case 0xfaULL: /* AP */ goto unimplemented;
14497 case 0xfbULL: /* SP */ goto unimplemented;
14498 case 0xfcULL: /* MP */ goto unimplemented;
14499 case 0xfdULL: /* DP */ goto unimplemented;
14500 }
14501
14502 switch (((ovl.value >> 16) & 0xffff00000000ULL) >> 32) {
14503 case 0xe500ULL: /* LASP */ goto unimplemented;
14504 case 0xe501ULL: /* TPROT */ goto unimplemented;
14505 case 0xe502ULL: /* STRAG */ goto unimplemented;
14506 case 0xe50eULL: /* MVCSK */ goto unimplemented;
14507 case 0xe50fULL: /* MVCDK */ goto unimplemented;
14508 case 0xe544ULL: s390_format_SIL_RDI(s390_irgen_MVHHI, ovl.fmt.SIL.b1,
14509 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14510 goto ok;
14511 case 0xe548ULL: s390_format_SIL_RDI(s390_irgen_MVGHI, ovl.fmt.SIL.b1,
14512 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14513 goto ok;
14514 case 0xe54cULL: s390_format_SIL_RDI(s390_irgen_MVHI, ovl.fmt.SIL.b1,
14515 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14516 goto ok;
14517 case 0xe554ULL: s390_format_SIL_RDI(s390_irgen_CHHSI, ovl.fmt.SIL.b1,
14518 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14519 goto ok;
14520 case 0xe555ULL: s390_format_SIL_RDU(s390_irgen_CLHHSI, ovl.fmt.SIL.b1,
14521 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14522 goto ok;
14523 case 0xe558ULL: s390_format_SIL_RDI(s390_irgen_CGHSI, ovl.fmt.SIL.b1,
14524 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14525 goto ok;
14526 case 0xe559ULL: s390_format_SIL_RDU(s390_irgen_CLGHSI, ovl.fmt.SIL.b1,
14527 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14528 goto ok;
14529 case 0xe55cULL: s390_format_SIL_RDI(s390_irgen_CHSI, ovl.fmt.SIL.b1,
14530 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14531 goto ok;
14532 case 0xe55dULL: s390_format_SIL_RDU(s390_irgen_CLFHSI, ovl.fmt.SIL.b1,
14533 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14534 goto ok;
14535 }
14536
14537 return S390_DECODE_UNKNOWN_INSN;
14538
14539ok:
14540 return S390_DECODE_OK;
14541
14542unimplemented:
14543 return S390_DECODE_UNIMPLEMENTED_INSN;
14544}
14545
14546/* Handle "special" instructions. */
14547static s390_decode_t
14548s390_decode_special_and_irgen(UChar *bytes)
14549{
14550 s390_decode_t status = S390_DECODE_OK;
14551
14552 /* Got a "Special" instruction preamble. Which one is it? */
14553 if (bytes[0] == 0x18 && bytes[1] == 0x22 /* lr %r2, %r2 */) {
14554 s390_irgen_client_request();
14555 } else if (bytes[0] == 0x18 && bytes[1] == 0x33 /* lr %r3, %r3 */) {
14556 s390_irgen_guest_NRADDR();
14557 } else if (bytes[0] == 0x18 && bytes[1] == 0x44 /* lr %r4, %r4 */) {
14558 s390_irgen_call_noredir();
florian2245ce92012-08-28 16:49:30 +000014559 } else if (bytes[0] == 0x18 && bytes[1] == 0x55 /* lr %r5, %r5 */) {
14560 vex_inject_ir(irsb, Iend_BE);
14561
14562 /* Invalidate the current insn. The reason is that the IRop we're
14563 injecting here can change. In which case the translation has to
14564 be redone. For ease of handling, we simply invalidate all the
14565 time. */
14566 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TISTART),
14567 mkU64(guest_IA_curr_instr)));
14568 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TILEN),
14569 mkU64(guest_IA_next_instr - guest_IA_curr_instr)));
14570 vassert(guest_IA_next_instr - guest_IA_curr_instr ==
14571 S390_SPECIAL_OP_PREAMBLE_SIZE + S390_SPECIAL_OP_SIZE);
14572
14573 put_IA(mkaddr_expr(guest_IA_next_instr));
14574 dis_res->whatNext = Dis_StopHere;
14575 dis_res->jk_StopHere = Ijk_TInval;
sewardj2019a972011-03-07 16:04:07 +000014576 } else {
14577 /* We don't know what it is. */
14578 return S390_DECODE_UNKNOWN_SPECIAL_INSN;
14579 }
14580
14581 dis_res->len = S390_SPECIAL_OP_PREAMBLE_SIZE + S390_SPECIAL_OP_SIZE;
14582
14583 return status;
14584}
14585
14586
14587/* Function returns # bytes that were decoded or 0 in case of failure */
florianb4df7682011-07-05 02:09:01 +000014588static UInt
sewardj2019a972011-03-07 16:04:07 +000014589s390_decode_and_irgen(UChar *bytes, UInt insn_length, DisResult *dres)
14590{
14591 s390_decode_t status;
14592
14593 dis_res = dres;
14594
14595 /* Spot the 8-byte preamble: 18ff lr r15,r15
14596 1811 lr r1,r1
14597 1822 lr r2,r2
14598 1833 lr r3,r3 */
14599 if (bytes[ 0] == 0x18 && bytes[ 1] == 0xff && bytes[ 2] == 0x18 &&
14600 bytes[ 3] == 0x11 && bytes[ 4] == 0x18 && bytes[ 5] == 0x22 &&
14601 bytes[ 6] == 0x18 && bytes[ 7] == 0x33) {
14602
14603 /* Handle special instruction that follows that preamble. */
14604 if (0) vex_printf("special function handling...\n");
florian2c8ed942011-08-01 22:07:51 +000014605
14606 insn_length = S390_SPECIAL_OP_PREAMBLE_SIZE + S390_SPECIAL_OP_SIZE;
14607 guest_IA_next_instr = guest_IA_curr_instr + insn_length;
14608
14609 status =
14610 s390_decode_special_and_irgen(bytes + S390_SPECIAL_OP_PREAMBLE_SIZE);
sewardj2019a972011-03-07 16:04:07 +000014611 } else {
14612 /* Handle normal instructions. */
14613 switch (insn_length) {
14614 case 2:
14615 status = s390_decode_2byte_and_irgen(bytes);
14616 break;
14617
14618 case 4:
14619 status = s390_decode_4byte_and_irgen(bytes);
14620 break;
14621
14622 case 6:
14623 status = s390_decode_6byte_and_irgen(bytes);
14624 break;
14625
14626 default:
14627 status = S390_DECODE_ERROR;
14628 break;
14629 }
14630 }
florian5fcbba22011-07-27 20:40:22 +000014631 /* If next instruction is execute, stop here */
florianf9e1ed72012-04-17 02:41:56 +000014632 if (dis_res->whatNext == Dis_Continue && bytes[insn_length] == 0x44) {
14633 put_IA(mkaddr_expr(guest_IA_next_instr));
sewardj2019a972011-03-07 16:04:07 +000014634 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +000014635 dis_res->jk_StopHere = Ijk_Boring;
sewardj2019a972011-03-07 16:04:07 +000014636 }
14637
14638 if (status == S390_DECODE_OK) return insn_length; /* OK */
14639
14640 /* Decoding failed somehow */
14641 vex_printf("vex s390->IR: ");
14642 switch (status) {
14643 case S390_DECODE_UNKNOWN_INSN:
14644 vex_printf("unknown insn: ");
14645 break;
14646
14647 case S390_DECODE_UNIMPLEMENTED_INSN:
14648 vex_printf("unimplemented insn: ");
14649 break;
14650
14651 case S390_DECODE_UNKNOWN_SPECIAL_INSN:
14652 vex_printf("unimplemented special insn: ");
14653 break;
14654
14655 default:
14656 case S390_DECODE_ERROR:
14657 vex_printf("decoding error: ");
14658 break;
14659 }
14660
14661 vex_printf("%02x%02x", bytes[0], bytes[1]);
14662 if (insn_length > 2) {
14663 vex_printf(" %02x%02x", bytes[2], bytes[3]);
14664 }
14665 if (insn_length > 4) {
14666 vex_printf(" %02x%02x", bytes[4], bytes[5]);
14667 }
14668 vex_printf("\n");
14669
14670 return 0; /* Failed */
14671}
14672
14673
sewardj2019a972011-03-07 16:04:07 +000014674/* Disassemble a single instruction INSN into IR. */
14675static DisResult
florian420c5012011-07-22 02:12:28 +000014676disInstr_S390_WRK(UChar *insn)
sewardj2019a972011-03-07 16:04:07 +000014677{
14678 UChar byte;
14679 UInt insn_length;
14680 DisResult dres;
14681
14682 /* ---------------------------------------------------- */
14683 /* --- Compute instruction length -- */
14684 /* ---------------------------------------------------- */
14685
14686 /* Get the first byte of the insn. */
14687 byte = insn[0];
14688
14689 /* The leftmost two bits (0:1) encode the length of the insn in bytes.
14690 00 -> 2 bytes, 01 -> 4 bytes, 10 -> 4 bytes, 11 -> 6 bytes. */
14691 insn_length = ((((byte >> 6) + 1) >> 1) + 1) << 1;
14692
14693 guest_IA_next_instr = guest_IA_curr_instr + insn_length;
14694
14695 /* ---------------------------------------------------- */
14696 /* --- Initialise the DisResult data -- */
14697 /* ---------------------------------------------------- */
14698 dres.whatNext = Dis_Continue;
14699 dres.len = insn_length;
14700 dres.continueAt = 0;
florian8844a632012-04-13 04:04:06 +000014701 dres.jk_StopHere = Ijk_INVALID;
sewardj2019a972011-03-07 16:04:07 +000014702
floriana99f20e2011-07-17 14:16:41 +000014703 /* fixs390: consider chasing of conditional jumps */
14704
sewardj2019a972011-03-07 16:04:07 +000014705 /* Normal and special instruction handling starts here. */
14706 if (s390_decode_and_irgen(insn, insn_length, &dres) == 0) {
14707 /* All decode failures end up here. The decoder has already issued an
14708 error message.
14709 Tell the dispatcher that this insn cannot be decoded, and so has
florian342e01a2012-07-26 02:37:49 +000014710 not been executed, and (is currently) the next to be executed.
14711 The insn address in the guest state needs to be set to
14712 guest_IA_curr_instr, otherwise the complaint will report an
14713 incorrect address. */
14714 put_IA(mkaddr_expr(guest_IA_curr_instr));
sewardj2019a972011-03-07 16:04:07 +000014715
florian8844a632012-04-13 04:04:06 +000014716 dres.whatNext = Dis_StopHere;
14717 dres.jk_StopHere = Ijk_NoDecode;
14718 dres.continueAt = 0;
14719 dres.len = 0;
14720 } else {
14721 /* Decode success */
14722 switch (dres.whatNext) {
14723 case Dis_Continue:
florian8559e412012-04-19 14:23:48 +000014724 put_IA(mkaddr_expr(guest_IA_next_instr));
florian8844a632012-04-13 04:04:06 +000014725 break;
14726 case Dis_ResteerU:
14727 case Dis_ResteerC:
14728 put_IA(mkaddr_expr(dres.continueAt));
14729 break;
14730 case Dis_StopHere:
florian4b8efad2012-09-02 18:07:08 +000014731 if (dres.jk_StopHere == Ijk_EmWarn ||
14732 dres.jk_StopHere == Ijk_EmFail) {
14733 /* We assume here, that emulation warnings are not given for
14734 insns that transfer control. There is no good way to
14735 do that. */
14736 put_IA(mkaddr_expr(guest_IA_next_instr));
14737 }
florian8844a632012-04-13 04:04:06 +000014738 break;
14739 default:
14740 vassert(0);
14741 }
sewardj2019a972011-03-07 16:04:07 +000014742 }
14743
14744 return dres;
14745}
14746
14747
14748/*------------------------------------------------------------*/
14749/*--- Top-level fn ---*/
14750/*------------------------------------------------------------*/
14751
14752/* Disassemble a single instruction into IR. The instruction
14753 is located in host memory at &guest_code[delta]. */
14754
14755DisResult
14756disInstr_S390(IRSB *irsb_IN,
sewardj2019a972011-03-07 16:04:07 +000014757 Bool (*resteerOkFn)(void *, Addr64),
14758 Bool resteerCisOk,
14759 void *callback_opaque,
14760 UChar *guest_code,
14761 Long delta,
14762 Addr64 guest_IP,
14763 VexArch guest_arch,
14764 VexArchInfo *archinfo,
14765 VexAbiInfo *abiinfo,
14766 Bool host_bigendian)
14767{
14768 vassert(guest_arch == VexArchS390X);
14769
14770 /* The instruction decoder requires a big-endian machine. */
14771 vassert(host_bigendian == True);
14772
14773 /* Set globals (see top of this file) */
14774 guest_IA_curr_instr = guest_IP;
sewardj2019a972011-03-07 16:04:07 +000014775 irsb = irsb_IN;
florian420c5012011-07-22 02:12:28 +000014776 resteer_fn = resteerOkFn;
14777 resteer_data = callback_opaque;
sewardj2019a972011-03-07 16:04:07 +000014778
florian420c5012011-07-22 02:12:28 +000014779 return disInstr_S390_WRK(guest_code + delta);
sewardj2019a972011-03-07 16:04:07 +000014780}
14781
14782/*---------------------------------------------------------------*/
14783/*--- end guest_s390_toIR.c ---*/
14784/*---------------------------------------------------------------*/