blob: 4ea8bb8bc8b2d6323104947c2787251b19aba7f9 [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 */
florian79af5752012-09-20 01:22:10 +000043#include "s390_disasm.h"
sewardj2019a972011-03-07 16:04:07 +000044#include "host_s390_defs.h" /* S390_ROUND_xyzzy */
45
sewardj2019a972011-03-07 16:04:07 +000046
47/*------------------------------------------------------------*/
florianb4df7682011-07-05 02:09:01 +000048/*--- Forward declarations ---*/
49/*------------------------------------------------------------*/
50static UInt s390_decode_and_irgen(UChar *, UInt, DisResult *);
florianb0bf6602012-05-05 00:01:16 +000051static void s390_irgen_xonc(IROp, IRTemp, IRTemp, IRTemp);
florian79e839e2012-05-05 02:20:30 +000052static void s390_irgen_CLC_EX(IRTemp, IRTemp, IRTemp);
florianb4df7682011-07-05 02:09:01 +000053
54
55/*------------------------------------------------------------*/
sewardj2019a972011-03-07 16:04:07 +000056/*--- Globals ---*/
57/*------------------------------------------------------------*/
58
59/* The IRSB* into which we're generating code. */
60static IRSB *irsb;
61
62/* The guest address for the instruction currently being
63 translated. */
64static Addr64 guest_IA_curr_instr;
65
66/* The guest address for the instruction following the current instruction. */
67static Addr64 guest_IA_next_instr;
68
69/* Result of disassembly step. */
70static DisResult *dis_res;
71
floriana64c2432011-07-16 02:11:50 +000072/* Resteer function and callback data */
73static Bool (*resteer_fn)(void *, Addr64);
74static void *resteer_data;
75
sewardj2019a972011-03-07 16:04:07 +000076/* The last seen execute target instruction */
77ULong last_execute_target;
78
79/* The possible outcomes of a decoding operation */
80typedef enum {
81 S390_DECODE_OK,
82 S390_DECODE_UNKNOWN_INSN,
83 S390_DECODE_UNIMPLEMENTED_INSN,
84 S390_DECODE_UNKNOWN_SPECIAL_INSN,
85 S390_DECODE_ERROR
86} s390_decode_t;
87
florian428dfdd2012-03-27 03:09:49 +000088
sewardj2019a972011-03-07 16:04:07 +000089/*------------------------------------------------------------*/
90/*--- Helpers for constructing IR. ---*/
91/*------------------------------------------------------------*/
92
93/* Sign extend a value with the given number of bits. This is a
94 macro because it allows us to overload the type of the value.
95 Note that VALUE must have a signed type! */
96#undef sign_extend
97#define sign_extend(value,num_bits) \
98(((value) << (sizeof(__typeof__(value)) * 8 - (num_bits))) >> \
99 (sizeof(__typeof__(value)) * 8 - (num_bits)))
100
101
102/* Add a statement to the current irsb. */
103static __inline__ void
104stmt(IRStmt *st)
105{
106 addStmtToIRSB(irsb, st);
107}
108
109/* Allocate a new temporary of the given type. */
110static __inline__ IRTemp
111newTemp(IRType type)
112{
113 vassert(isPlausibleIRType(type));
114
115 return newIRTemp(irsb->tyenv, type);
116}
117
118/* Create an expression node for a temporary */
119static __inline__ IRExpr *
120mkexpr(IRTemp tmp)
121{
122 return IRExpr_RdTmp(tmp);
123}
124
florian8844a632012-04-13 04:04:06 +0000125/* Generate an expression node for an address. */
126static __inline__ IRExpr *
127mkaddr_expr(Addr64 addr)
128{
129 return IRExpr_Const(IRConst_U64(addr));
130}
131
sewardj2019a972011-03-07 16:04:07 +0000132/* Add a statement that assigns to a temporary */
133static __inline__ void
134assign(IRTemp dst, IRExpr *expr)
135{
136 stmt(IRStmt_WrTmp(dst, expr));
137}
138
florian8844a632012-04-13 04:04:06 +0000139/* Write an address into the guest_IA */
140static __inline__ void
141put_IA(IRExpr *address)
142{
143 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_IA), address));
144}
145
sewardj2019a972011-03-07 16:04:07 +0000146/* Create a temporary of the given type and assign the expression to it */
147static __inline__ IRTemp
148mktemp(IRType type, IRExpr *expr)
149{
150 IRTemp temp = newTemp(type);
151
152 assign(temp, expr);
153
154 return temp;
155}
156
157/* Create a unary expression */
158static __inline__ IRExpr *
159unop(IROp kind, IRExpr *op)
160{
161 return IRExpr_Unop(kind, op);
162}
163
164/* Create a binary expression */
165static __inline__ IRExpr *
166binop(IROp kind, IRExpr *op1, IRExpr *op2)
167{
168 return IRExpr_Binop(kind, op1, op2);
169}
170
171/* Create a ternary expression */
172static __inline__ IRExpr *
173triop(IROp kind, IRExpr *op1, IRExpr *op2, IRExpr *op3)
174{
175 return IRExpr_Triop(kind, op1, op2, op3);
176}
177
178/* Create a quaternary expression */
179static __inline__ IRExpr *
180qop(IROp kind, IRExpr *op1, IRExpr *op2, IRExpr *op3, IRExpr *op4)
181{
182 return IRExpr_Qop(kind, op1, op2, op3, op4);
183}
184
185/* Create an expression node for an 8-bit integer constant */
186static __inline__ IRExpr *
187mkU8(UInt value)
188{
189 vassert(value < 256);
190
191 return IRExpr_Const(IRConst_U8((UChar)value));
192}
193
194/* Create an expression node for a 16-bit integer constant */
195static __inline__ IRExpr *
196mkU16(UInt value)
197{
198 vassert(value < 65536);
199
200 return IRExpr_Const(IRConst_U16((UShort)value));
201}
202
203/* Create an expression node for a 32-bit integer constant */
204static __inline__ IRExpr *
205mkU32(UInt value)
206{
207 return IRExpr_Const(IRConst_U32(value));
208}
209
210/* Create an expression node for a 64-bit integer constant */
211static __inline__ IRExpr *
212mkU64(ULong value)
213{
214 return IRExpr_Const(IRConst_U64(value));
215}
216
217/* Create an expression node for a 32-bit floating point constant
218 whose value is given by a bit pattern. */
219static __inline__ IRExpr *
220mkF32i(UInt value)
221{
222 return IRExpr_Const(IRConst_F32i(value));
223}
224
225/* Create an expression node for a 32-bit floating point constant
226 whose value is given by a bit pattern. */
227static __inline__ IRExpr *
228mkF64i(ULong value)
229{
230 return IRExpr_Const(IRConst_F64i(value));
231}
232
233/* Little helper function for my sanity. ITE = if-then-else */
234static IRExpr *
235mkite(IRExpr *condition, IRExpr *iftrue, IRExpr *iffalse)
236{
237 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
238
239 return IRExpr_Mux0X(unop(Iop_1Uto8, condition), iffalse, iftrue);
240}
241
242/* Add a statement that stores DATA at ADDR. This is a big-endian machine. */
243static void __inline__
244store(IRExpr *addr, IRExpr *data)
245{
246 stmt(IRStmt_Store(Iend_BE, addr, data));
247}
248
249/* Create an expression that loads a TYPE sized value from ADDR.
250 This is a big-endian machine. */
251static __inline__ IRExpr *
252load(IRType type, IRExpr *addr)
253{
254 return IRExpr_Load(Iend_BE, type, addr);
255}
256
257/* Function call */
258static void
259call_function(IRExpr *callee_address)
260{
florian8844a632012-04-13 04:04:06 +0000261 put_IA(callee_address);
sewardj2019a972011-03-07 16:04:07 +0000262
florian8844a632012-04-13 04:04:06 +0000263 dis_res->whatNext = Dis_StopHere;
264 dis_res->jk_StopHere = Ijk_Call;
sewardj2019a972011-03-07 16:04:07 +0000265}
266
floriana64c2432011-07-16 02:11:50 +0000267/* Function call with known target. */
268static void
269call_function_and_chase(Addr64 callee_address)
270{
271 if (resteer_fn(resteer_data, callee_address)) {
272 dis_res->whatNext = Dis_ResteerU;
273 dis_res->continueAt = callee_address;
274 } else {
florian8844a632012-04-13 04:04:06 +0000275 put_IA(mkaddr_expr(callee_address));
276
floriana64c2432011-07-16 02:11:50 +0000277 dis_res->whatNext = Dis_StopHere;
florian8844a632012-04-13 04:04:06 +0000278 dis_res->jk_StopHere = Ijk_Call;
floriana64c2432011-07-16 02:11:50 +0000279 }
280}
281
sewardj2019a972011-03-07 16:04:07 +0000282/* Function return sequence */
283static void
284return_from_function(IRExpr *return_address)
285{
florian8844a632012-04-13 04:04:06 +0000286 put_IA(return_address);
sewardj2019a972011-03-07 16:04:07 +0000287
florian8844a632012-04-13 04:04:06 +0000288 dis_res->whatNext = Dis_StopHere;
289 dis_res->jk_StopHere = Ijk_Ret;
sewardj2019a972011-03-07 16:04:07 +0000290}
291
292/* A conditional branch whose target is not known at instrumentation time.
293
294 if (condition) goto computed_target;
295
296 Needs to be represented as:
297
298 if (! condition) goto next_instruction;
299 goto computed_target;
sewardj2019a972011-03-07 16:04:07 +0000300*/
301static void
florianf321da72012-07-21 20:32:57 +0000302if_condition_goto_computed(IRExpr *condition, IRExpr *target)
sewardj2019a972011-03-07 16:04:07 +0000303{
304 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
305
florianf321da72012-07-21 20:32:57 +0000306 condition = unop(Iop_Not1, condition);
307
florian8844a632012-04-13 04:04:06 +0000308 stmt(IRStmt_Exit(condition, Ijk_Boring, IRConst_U64(guest_IA_next_instr),
309 S390X_GUEST_OFFSET(guest_IA)));
sewardj2019a972011-03-07 16:04:07 +0000310
florian8844a632012-04-13 04:04:06 +0000311 put_IA(target);
sewardj2019a972011-03-07 16:04:07 +0000312
florian8844a632012-04-13 04:04:06 +0000313 dis_res->whatNext = Dis_StopHere;
314 dis_res->jk_StopHere = Ijk_Boring;
sewardj2019a972011-03-07 16:04:07 +0000315}
316
317/* A conditional branch whose target is known at instrumentation time. */
318static void
319if_condition_goto(IRExpr *condition, Addr64 target)
320{
321 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
322
florian8844a632012-04-13 04:04:06 +0000323 stmt(IRStmt_Exit(condition, Ijk_Boring, IRConst_U64(target),
324 S390X_GUEST_OFFSET(guest_IA)));
325
florian7346c7a2012-04-13 21:14:24 +0000326 put_IA(mkaddr_expr(guest_IA_next_instr));
florian8844a632012-04-13 04:04:06 +0000327
328 dis_res->whatNext = Dis_StopHere;
329 dis_res->jk_StopHere = Ijk_Boring;
sewardj2019a972011-03-07 16:04:07 +0000330}
331
332/* An unconditional branch. Target may or may not be known at instrumentation
333 time. */
334static void
335always_goto(IRExpr *target)
336{
florian8844a632012-04-13 04:04:06 +0000337 put_IA(target);
sewardj2019a972011-03-07 16:04:07 +0000338
florian8844a632012-04-13 04:04:06 +0000339 dis_res->whatNext = Dis_StopHere;
340 dis_res->jk_StopHere = Ijk_Boring;
sewardj2019a972011-03-07 16:04:07 +0000341}
342
florian8844a632012-04-13 04:04:06 +0000343
floriana64c2432011-07-16 02:11:50 +0000344/* An unconditional branch to a known target. */
345static void
346always_goto_and_chase(Addr64 target)
347{
348 if (resteer_fn(resteer_data, target)) {
florian8844a632012-04-13 04:04:06 +0000349 /* Follow into the target */
floriana64c2432011-07-16 02:11:50 +0000350 dis_res->whatNext = Dis_ResteerU;
351 dis_res->continueAt = target;
352 } else {
florian8844a632012-04-13 04:04:06 +0000353 put_IA(mkaddr_expr(target));
354
355 dis_res->whatNext = Dis_StopHere;
356 dis_res->jk_StopHere = Ijk_Boring;
floriana64c2432011-07-16 02:11:50 +0000357 }
358}
359
sewardj2019a972011-03-07 16:04:07 +0000360/* A system call */
361static void
362system_call(IRExpr *sysno)
363{
364 /* Store the system call number in the pseudo register. */
florian428dfdd2012-03-27 03:09:49 +0000365 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_SYSNO), sysno));
sewardj2019a972011-03-07 16:04:07 +0000366
sewardj69007022011-04-28 20:13:45 +0000367 /* Store the current IA into guest_IP_AT_SYSCALL. libvex_ir.h says so. */
florian428dfdd2012-03-27 03:09:49 +0000368 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_IP_AT_SYSCALL),
369 mkU64(guest_IA_curr_instr)));
sewardj2019a972011-03-07 16:04:07 +0000370
florian8844a632012-04-13 04:04:06 +0000371 put_IA(mkaddr_expr(guest_IA_next_instr));
372
sewardj2019a972011-03-07 16:04:07 +0000373 /* It's important that all ArchRegs carry their up-to-date value
374 at this point. So we declare an end-of-block here, which
375 forces any TempRegs caching ArchRegs to be flushed. */
florian8844a632012-04-13 04:04:06 +0000376 dis_res->whatNext = Dis_StopHere;
377 dis_res->jk_StopHere = Ijk_Sys_syscall;
sewardj2019a972011-03-07 16:04:07 +0000378}
379
florian6820ba52012-07-26 02:01:50 +0000380/* A side exit that branches back to the current insn if CONDITION is
381 true. Does not set DisResult. */
382static void
383iterate_if(IRExpr *condition)
384{
385 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
386
387 stmt(IRStmt_Exit(condition, Ijk_Boring, IRConst_U64(guest_IA_curr_instr),
388 S390X_GUEST_OFFSET(guest_IA)));
389}
390
391/* A side exit that branches back to the current insn.
392 Does not set DisResult. */
393static __inline__ void
394iterate(void)
395{
396 iterate_if(IRExpr_Const(IRConst_U1(True)));
397}
398
399/* A side exit that branches back to the insn immediately following the
400 current insn if CONDITION is true. Does not set DisResult. */
401static void
402next_insn_if(IRExpr *condition)
403{
404 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
405
406 stmt(IRStmt_Exit(condition, Ijk_Boring, IRConst_U64(guest_IA_next_instr),
407 S390X_GUEST_OFFSET(guest_IA)));
408}
409
410/* Convenience function to restart the current insn */
411static void
412restart_if(IRExpr *condition)
413{
414 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
415
416 stmt(IRStmt_Exit(condition, Ijk_TInval, IRConst_U64(guest_IA_curr_instr),
417 S390X_GUEST_OFFSET(guest_IA)));
418}
419
420/* Convenience function to yield to thread scheduler */
421static void
422yield_if(IRExpr *condition)
423{
424 stmt(IRStmt_Exit(condition, Ijk_Yield, IRConst_U64(guest_IA_next_instr),
425 S390X_GUEST_OFFSET(guest_IA)));
426}
427
sewardj2019a972011-03-07 16:04:07 +0000428static __inline__ IRExpr *get_fpr_dw0(UInt);
429static __inline__ void put_fpr_dw0(UInt, IRExpr *);
430
431/* Read a floating point register pair and combine their contents into a
432 128-bit value */
433static IRExpr *
434get_fpr_pair(UInt archreg)
435{
436 IRExpr *high = get_fpr_dw0(archreg);
437 IRExpr *low = get_fpr_dw0(archreg + 2);
438
439 return binop(Iop_F64HLtoF128, high, low);
440}
441
442/* Write a 128-bit floating point value into a register pair. */
443static void
444put_fpr_pair(UInt archreg, IRExpr *expr)
445{
446 IRExpr *high = unop(Iop_F128HItoF64, expr);
447 IRExpr *low = unop(Iop_F128LOtoF64, expr);
448
449 put_fpr_dw0(archreg, high);
450 put_fpr_dw0(archreg + 2, low);
451}
452
floriane75dafa2012-09-01 17:54:09 +0000453/* Terminate the current IRSB with an emulation failure. */
454static void
455emulation_failure(VexEmNote fail_kind)
456{
457 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_EMNOTE), mkU32(fail_kind)));
floriane75dafa2012-09-01 17:54:09 +0000458 dis_res->whatNext = Dis_StopHere;
459 dis_res->jk_StopHere = Ijk_EmFail;
460}
sewardj2019a972011-03-07 16:04:07 +0000461
florian4b8efad2012-09-02 18:07:08 +0000462/* Terminate the current IRSB with an emulation warning. */
463static void
464emulation_warning(VexEmNote warn_kind)
465{
466 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_EMNOTE), mkU32(warn_kind)));
467 dis_res->whatNext = Dis_StopHere;
468 dis_res->jk_StopHere = Ijk_EmWarn;
469}
470
sewardj2019a972011-03-07 16:04:07 +0000471/*------------------------------------------------------------*/
florianf3410f92012-08-03 18:41:58 +0000472/*--- IR Debugging aids. ---*/
473/*------------------------------------------------------------*/
474#if 0
475
476static ULong
477s390_do_print(HChar *text, ULong value)
478{
479 vex_printf("%s %llu\n", text, value);
480 return 0;
481}
482
483static void
484s390_print(HChar *text, IRExpr *value)
485{
486 IRDirty *d;
487
488 d = unsafeIRDirty_0_N(0 /* regparms */, "s390_do_print", &s390_do_print,
489 mkIRExprVec_2(mkU64((ULong)text), value));
490 stmt(IRStmt_Dirty(d));
491}
492#endif
493
494
495/*------------------------------------------------------------*/
sewardj2019a972011-03-07 16:04:07 +0000496/*--- Build the flags thunk. ---*/
497/*------------------------------------------------------------*/
498
499/* Completely fill the flags thunk. We're always filling all fields.
500 Apparently, that is better for redundant PUT elimination. */
501static void
502s390_cc_thunk_fill(IRExpr *op, IRExpr *dep1, IRExpr *dep2, IRExpr *ndep)
503{
504 UInt op_off, dep1_off, dep2_off, ndep_off;
505
florian428dfdd2012-03-27 03:09:49 +0000506 op_off = S390X_GUEST_OFFSET(guest_CC_OP);
507 dep1_off = S390X_GUEST_OFFSET(guest_CC_DEP1);
508 dep2_off = S390X_GUEST_OFFSET(guest_CC_DEP2);
509 ndep_off = S390X_GUEST_OFFSET(guest_CC_NDEP);
sewardj2019a972011-03-07 16:04:07 +0000510
511 stmt(IRStmt_Put(op_off, op));
512 stmt(IRStmt_Put(dep1_off, dep1));
513 stmt(IRStmt_Put(dep2_off, dep2));
514 stmt(IRStmt_Put(ndep_off, ndep));
515}
516
517
518/* Create an expression for V and widen the result to 64 bit. */
519static IRExpr *
520s390_cc_widen(IRTemp v, Bool sign_extend)
521{
522 IRExpr *expr;
523
524 expr = mkexpr(v);
525
526 switch (typeOfIRTemp(irsb->tyenv, v)) {
527 case Ity_I64:
528 break;
529 case Ity_I32:
530 expr = unop(sign_extend ? Iop_32Sto64 : Iop_32Uto64, expr);
531 break;
532 case Ity_I16:
533 expr = unop(sign_extend ? Iop_16Sto64 : Iop_16Uto64, expr);
534 break;
535 case Ity_I8:
536 expr = unop(sign_extend ? Iop_8Sto64 : Iop_8Uto64, expr);
537 break;
538 default:
539 vpanic("s390_cc_widen");
540 }
541
542 return expr;
543}
544
545static void
546s390_cc_thunk_put1(UInt opc, IRTemp d1, Bool sign_extend)
547{
548 IRExpr *op, *dep1, *dep2, *ndep;
549
550 op = mkU64(opc);
551 dep1 = s390_cc_widen(d1, sign_extend);
552 dep2 = mkU64(0);
553 ndep = mkU64(0);
554
555 s390_cc_thunk_fill(op, dep1, dep2, ndep);
556}
557
558
559static void
560s390_cc_thunk_put2(UInt opc, IRTemp d1, IRTemp d2, Bool sign_extend)
561{
562 IRExpr *op, *dep1, *dep2, *ndep;
563
564 op = mkU64(opc);
565 dep1 = s390_cc_widen(d1, sign_extend);
566 dep2 = s390_cc_widen(d2, sign_extend);
567 ndep = mkU64(0);
568
569 s390_cc_thunk_fill(op, dep1, dep2, ndep);
570}
571
572
573/* memcheck believes that the NDEP field in the flags thunk is always
574 defined. But for some flag computations (e.g. add with carry) that is
575 just not true. We therefore need to convey to memcheck that the value
576 of the ndep field does matter and therefore we make the DEP2 field
577 depend on it:
578
579 DEP2 = original_DEP2 ^ NDEP
580
581 In s390_calculate_cc we exploit that (a^b)^b == a
582 I.e. we xor the DEP2 value with the NDEP value to recover the
583 original_DEP2 value. */
584static void
585s390_cc_thunk_put3(UInt opc, IRTemp d1, IRTemp d2, IRTemp nd, Bool sign_extend)
586{
587 IRExpr *op, *dep1, *dep2, *ndep, *dep2x;
588
589 op = mkU64(opc);
590 dep1 = s390_cc_widen(d1, sign_extend);
591 dep2 = s390_cc_widen(d2, sign_extend);
592 ndep = s390_cc_widen(nd, sign_extend);
593
594 dep2x = binop(Iop_Xor64, dep2, ndep);
595
596 s390_cc_thunk_fill(op, dep1, dep2x, ndep);
597}
598
599
600/* Write one floating point value into the flags thunk */
601static void
602s390_cc_thunk_put1f(UInt opc, IRTemp d1)
603{
604 IRExpr *op, *dep1, *dep2, *ndep;
605
606 op = mkU64(opc);
607 dep1 = mkexpr(d1);
608 dep2 = mkU64(0);
609 ndep = mkU64(0);
610
611 s390_cc_thunk_fill(op, dep1, dep2, ndep);
612}
613
614
615/* Write a floating point value and an integer into the flags thunk. The
616 integer value is zero-extended first. */
617static void
618s390_cc_thunk_putFZ(UInt opc, IRTemp d1, IRTemp d2)
619{
620 IRExpr *op, *dep1, *dep2, *ndep;
621
622 op = mkU64(opc);
623 dep1 = mkexpr(d1);
624 dep2 = s390_cc_widen(d2, False);
625 ndep = mkU64(0);
626
627 s390_cc_thunk_fill(op, dep1, dep2, ndep);
628}
629
630
631/* Write a 128-bit floating point value into the flags thunk. This is
632 done by splitting the value into two 64-bits values. */
633static void
634s390_cc_thunk_put1f128(UInt opc, IRTemp d1)
635{
636 IRExpr *op, *hi, *lo, *ndep;
637
638 op = mkU64(opc);
639 hi = unop(Iop_F128HItoF64, mkexpr(d1));
640 lo = unop(Iop_F128LOtoF64, mkexpr(d1));
641 ndep = mkU64(0);
642
643 s390_cc_thunk_fill(op, hi, lo, ndep);
644}
645
646
647/* Write a 128-bit floating point value and an integer into the flags thunk.
648 The integer value is zero-extended first. */
649static void
650s390_cc_thunk_put1f128Z(UInt opc, IRTemp d1, IRTemp nd)
651{
652 IRExpr *op, *hi, *lo, *lox, *ndep;
653
654 op = mkU64(opc);
655 hi = unop(Iop_F128HItoF64, mkexpr(d1));
656 lo = unop(Iop_ReinterpF64asI64, unop(Iop_F128LOtoF64, mkexpr(d1)));
657 ndep = s390_cc_widen(nd, False);
658
659 lox = binop(Iop_Xor64, lo, ndep); /* convey dependency */
660
661 s390_cc_thunk_fill(op, hi, lox, ndep);
662}
663
664
665static void
666s390_cc_set(UInt val)
667{
668 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
669 mkU64(val), mkU64(0), mkU64(0));
670}
671
672/* Build IR to calculate the condition code from flags thunk.
673 Returns an expression of type Ity_I32 */
674static IRExpr *
675s390_call_calculate_cc(void)
676{
677 IRExpr **args, *call, *op, *dep1, *dep2, *ndep;
678
florian428dfdd2012-03-27 03:09:49 +0000679 op = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_OP), Ity_I64);
680 dep1 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP1), Ity_I64);
681 dep2 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP2), Ity_I64);
682 ndep = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_NDEP), Ity_I64);
sewardj2019a972011-03-07 16:04:07 +0000683
684 args = mkIRExprVec_4(op, dep1, dep2, ndep);
685 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
686 "s390_calculate_cc", &s390_calculate_cc, args);
687
688 /* Exclude OP and NDEP from definedness checking. We're only
689 interested in DEP1 and DEP2. */
690 call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<3);
691
692 return call;
693}
694
695/* Build IR to calculate the internal condition code for a "compare and branch"
696 insn. Returns an expression of type Ity_I32 */
697static IRExpr *
florianff9613f2012-05-12 15:26:44 +0000698s390_call_calculate_icc(UInt m, UInt opc, IRTemp op1, IRTemp op2)
sewardj2019a972011-03-07 16:04:07 +0000699{
florianff9613f2012-05-12 15:26:44 +0000700 IRExpr **args, *call, *op, *dep1, *dep2, *mask;
sewardj2019a972011-03-07 16:04:07 +0000701
florianff9613f2012-05-12 15:26:44 +0000702 switch (opc) {
703 case S390_CC_OP_SIGNED_COMPARE:
704 dep1 = s390_cc_widen(op1, True);
705 dep2 = s390_cc_widen(op2, True);
706 break;
707
708 case S390_CC_OP_UNSIGNED_COMPARE:
709 dep1 = s390_cc_widen(op1, False);
710 dep2 = s390_cc_widen(op2, False);
711 break;
712
713 default:
714 vpanic("s390_call_calculate_icc");
715 }
716
717 mask = mkU64(m);
sewardj2019a972011-03-07 16:04:07 +0000718 op = mkU64(opc);
sewardj2019a972011-03-07 16:04:07 +0000719
florianff9613f2012-05-12 15:26:44 +0000720 args = mkIRExprVec_5(mask, op, dep1, dep2, mkU64(0) /* unused */);
sewardj2019a972011-03-07 16:04:07 +0000721 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
florianff9613f2012-05-12 15:26:44 +0000722 "s390_calculate_cond", &s390_calculate_cond, args);
sewardj2019a972011-03-07 16:04:07 +0000723
florianff9613f2012-05-12 15:26:44 +0000724 /* Exclude the requested condition, OP and NDEP from definedness
725 checking. We're only interested in DEP1 and DEP2. */
726 call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<1) | (1<<4);
sewardj2019a972011-03-07 16:04:07 +0000727
728 return call;
729}
730
731/* Build IR to calculate the condition code from flags thunk.
732 Returns an expression of type Ity_I32 */
733static IRExpr *
734s390_call_calculate_cond(UInt m)
735{
736 IRExpr **args, *call, *op, *dep1, *dep2, *ndep, *mask;
737
738 mask = mkU64(m);
florian428dfdd2012-03-27 03:09:49 +0000739 op = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_OP), Ity_I64);
740 dep1 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP1), Ity_I64);
741 dep2 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP2), Ity_I64);
742 ndep = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_NDEP), Ity_I64);
sewardj2019a972011-03-07 16:04:07 +0000743
744 args = mkIRExprVec_5(mask, op, dep1, dep2, ndep);
745 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
746 "s390_calculate_cond", &s390_calculate_cond, args);
747
748 /* Exclude the requested condition, OP and NDEP from definedness
749 checking. We're only interested in DEP1 and DEP2. */
750 call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<1) | (1<<4);
751
752 return call;
753}
754
755#define s390_cc_thunk_putZ(op,dep1) s390_cc_thunk_put1(op,dep1,False)
756#define s390_cc_thunk_putS(op,dep1) s390_cc_thunk_put1(op,dep1,True)
757#define s390_cc_thunk_putF(op,dep1) s390_cc_thunk_put1f(op,dep1)
758#define s390_cc_thunk_putZZ(op,dep1,dep2) s390_cc_thunk_put2(op,dep1,dep2,False)
759#define s390_cc_thunk_putSS(op,dep1,dep2) s390_cc_thunk_put2(op,dep1,dep2,True)
760#define s390_cc_thunk_putFF(op,dep1,dep2) s390_cc_thunk_put2f(op,dep1,dep2)
761#define s390_cc_thunk_putZZZ(op,dep1,dep2,ndep) \
762 s390_cc_thunk_put3(op,dep1,dep2,ndep,False)
763#define s390_cc_thunk_putSSS(op,dep1,dep2,ndep) \
764 s390_cc_thunk_put3(op,dep1,dep2,ndep,True)
sewardj2019a972011-03-07 16:04:07 +0000765
766
sewardj2019a972011-03-07 16:04:07 +0000767
768
769/*------------------------------------------------------------*/
770/*--- Guest register access ---*/
771/*------------------------------------------------------------*/
772
773
774/*------------------------------------------------------------*/
775/*--- ar registers ---*/
776/*------------------------------------------------------------*/
777
778/* Return the guest state offset of a ar register. */
779static UInt
780ar_offset(UInt archreg)
781{
782 static const UInt offset[16] = {
floriane88b3c92011-07-05 02:48:39 +0000783 S390X_GUEST_OFFSET(guest_a0),
784 S390X_GUEST_OFFSET(guest_a1),
785 S390X_GUEST_OFFSET(guest_a2),
786 S390X_GUEST_OFFSET(guest_a3),
787 S390X_GUEST_OFFSET(guest_a4),
788 S390X_GUEST_OFFSET(guest_a5),
789 S390X_GUEST_OFFSET(guest_a6),
790 S390X_GUEST_OFFSET(guest_a7),
791 S390X_GUEST_OFFSET(guest_a8),
792 S390X_GUEST_OFFSET(guest_a9),
793 S390X_GUEST_OFFSET(guest_a10),
794 S390X_GUEST_OFFSET(guest_a11),
795 S390X_GUEST_OFFSET(guest_a12),
796 S390X_GUEST_OFFSET(guest_a13),
797 S390X_GUEST_OFFSET(guest_a14),
798 S390X_GUEST_OFFSET(guest_a15),
sewardj2019a972011-03-07 16:04:07 +0000799 };
800
801 vassert(archreg < 16);
802
803 return offset[archreg];
804}
805
806
807/* Return the guest state offset of word #0 of a ar register. */
808static __inline__ UInt
809ar_w0_offset(UInt archreg)
810{
811 return ar_offset(archreg) + 0;
812}
813
814/* Write word #0 of a ar to the guest state. */
815static __inline__ void
816put_ar_w0(UInt archreg, IRExpr *expr)
817{
818 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
819
820 stmt(IRStmt_Put(ar_w0_offset(archreg), expr));
821}
822
823/* Read word #0 of a ar register. */
824static __inline__ IRExpr *
825get_ar_w0(UInt archreg)
826{
827 return IRExpr_Get(ar_w0_offset(archreg), Ity_I32);
828}
829
830
831/*------------------------------------------------------------*/
832/*--- fpr registers ---*/
833/*------------------------------------------------------------*/
834
835/* Return the guest state offset of a fpr register. */
836static UInt
837fpr_offset(UInt archreg)
838{
839 static const UInt offset[16] = {
floriane88b3c92011-07-05 02:48:39 +0000840 S390X_GUEST_OFFSET(guest_f0),
841 S390X_GUEST_OFFSET(guest_f1),
842 S390X_GUEST_OFFSET(guest_f2),
843 S390X_GUEST_OFFSET(guest_f3),
844 S390X_GUEST_OFFSET(guest_f4),
845 S390X_GUEST_OFFSET(guest_f5),
846 S390X_GUEST_OFFSET(guest_f6),
847 S390X_GUEST_OFFSET(guest_f7),
848 S390X_GUEST_OFFSET(guest_f8),
849 S390X_GUEST_OFFSET(guest_f9),
850 S390X_GUEST_OFFSET(guest_f10),
851 S390X_GUEST_OFFSET(guest_f11),
852 S390X_GUEST_OFFSET(guest_f12),
853 S390X_GUEST_OFFSET(guest_f13),
854 S390X_GUEST_OFFSET(guest_f14),
855 S390X_GUEST_OFFSET(guest_f15),
sewardj2019a972011-03-07 16:04:07 +0000856 };
857
858 vassert(archreg < 16);
859
860 return offset[archreg];
861}
862
863
864/* Return the guest state offset of word #0 of a fpr register. */
865static __inline__ UInt
866fpr_w0_offset(UInt archreg)
867{
868 return fpr_offset(archreg) + 0;
869}
870
871/* Write word #0 of a fpr to the guest state. */
872static __inline__ void
873put_fpr_w0(UInt archreg, IRExpr *expr)
874{
875 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_F32);
876
877 stmt(IRStmt_Put(fpr_w0_offset(archreg), expr));
878}
879
880/* Read word #0 of a fpr register. */
881static __inline__ IRExpr *
882get_fpr_w0(UInt archreg)
883{
884 return IRExpr_Get(fpr_w0_offset(archreg), Ity_F32);
885}
886
887/* Return the guest state offset of double word #0 of a fpr register. */
888static __inline__ UInt
889fpr_dw0_offset(UInt archreg)
890{
891 return fpr_offset(archreg) + 0;
892}
893
894/* Write double word #0 of a fpr to the guest state. */
895static __inline__ void
896put_fpr_dw0(UInt archreg, IRExpr *expr)
897{
898 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_F64);
899
900 stmt(IRStmt_Put(fpr_dw0_offset(archreg), expr));
901}
902
903/* Read double word #0 of a fpr register. */
904static __inline__ IRExpr *
905get_fpr_dw0(UInt archreg)
906{
907 return IRExpr_Get(fpr_dw0_offset(archreg), Ity_F64);
908}
909
910
911/*------------------------------------------------------------*/
912/*--- gpr registers ---*/
913/*------------------------------------------------------------*/
914
915/* Return the guest state offset of a gpr register. */
916static UInt
917gpr_offset(UInt archreg)
918{
919 static const UInt offset[16] = {
floriane88b3c92011-07-05 02:48:39 +0000920 S390X_GUEST_OFFSET(guest_r0),
921 S390X_GUEST_OFFSET(guest_r1),
922 S390X_GUEST_OFFSET(guest_r2),
923 S390X_GUEST_OFFSET(guest_r3),
924 S390X_GUEST_OFFSET(guest_r4),
925 S390X_GUEST_OFFSET(guest_r5),
926 S390X_GUEST_OFFSET(guest_r6),
927 S390X_GUEST_OFFSET(guest_r7),
928 S390X_GUEST_OFFSET(guest_r8),
929 S390X_GUEST_OFFSET(guest_r9),
930 S390X_GUEST_OFFSET(guest_r10),
931 S390X_GUEST_OFFSET(guest_r11),
932 S390X_GUEST_OFFSET(guest_r12),
933 S390X_GUEST_OFFSET(guest_r13),
934 S390X_GUEST_OFFSET(guest_r14),
935 S390X_GUEST_OFFSET(guest_r15),
sewardj2019a972011-03-07 16:04:07 +0000936 };
937
938 vassert(archreg < 16);
939
940 return offset[archreg];
941}
942
943
944/* Return the guest state offset of word #0 of a gpr register. */
945static __inline__ UInt
946gpr_w0_offset(UInt archreg)
947{
948 return gpr_offset(archreg) + 0;
949}
950
951/* Write word #0 of a gpr to the guest state. */
952static __inline__ void
953put_gpr_w0(UInt archreg, IRExpr *expr)
954{
955 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
956
957 stmt(IRStmt_Put(gpr_w0_offset(archreg), expr));
958}
959
960/* Read word #0 of a gpr register. */
961static __inline__ IRExpr *
962get_gpr_w0(UInt archreg)
963{
964 return IRExpr_Get(gpr_w0_offset(archreg), Ity_I32);
965}
966
967/* Return the guest state offset of double word #0 of a gpr register. */
968static __inline__ UInt
969gpr_dw0_offset(UInt archreg)
970{
971 return gpr_offset(archreg) + 0;
972}
973
974/* Write double word #0 of a gpr to the guest state. */
975static __inline__ void
976put_gpr_dw0(UInt archreg, IRExpr *expr)
977{
978 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I64);
979
980 stmt(IRStmt_Put(gpr_dw0_offset(archreg), expr));
981}
982
983/* Read double word #0 of a gpr register. */
984static __inline__ IRExpr *
985get_gpr_dw0(UInt archreg)
986{
987 return IRExpr_Get(gpr_dw0_offset(archreg), Ity_I64);
988}
989
990/* Return the guest state offset of half word #1 of a gpr register. */
991static __inline__ UInt
992gpr_hw1_offset(UInt archreg)
993{
994 return gpr_offset(archreg) + 2;
995}
996
997/* Write half word #1 of a gpr to the guest state. */
998static __inline__ void
999put_gpr_hw1(UInt archreg, IRExpr *expr)
1000{
1001 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1002
1003 stmt(IRStmt_Put(gpr_hw1_offset(archreg), expr));
1004}
1005
1006/* Read half word #1 of a gpr register. */
1007static __inline__ IRExpr *
1008get_gpr_hw1(UInt archreg)
1009{
1010 return IRExpr_Get(gpr_hw1_offset(archreg), Ity_I16);
1011}
1012
1013/* Return the guest state offset of byte #6 of a gpr register. */
1014static __inline__ UInt
1015gpr_b6_offset(UInt archreg)
1016{
1017 return gpr_offset(archreg) + 6;
1018}
1019
1020/* Write byte #6 of a gpr to the guest state. */
1021static __inline__ void
1022put_gpr_b6(UInt archreg, IRExpr *expr)
1023{
1024 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1025
1026 stmt(IRStmt_Put(gpr_b6_offset(archreg), expr));
1027}
1028
1029/* Read byte #6 of a gpr register. */
1030static __inline__ IRExpr *
1031get_gpr_b6(UInt archreg)
1032{
1033 return IRExpr_Get(gpr_b6_offset(archreg), Ity_I8);
1034}
1035
1036/* Return the guest state offset of byte #3 of a gpr register. */
1037static __inline__ UInt
1038gpr_b3_offset(UInt archreg)
1039{
1040 return gpr_offset(archreg) + 3;
1041}
1042
1043/* Write byte #3 of a gpr to the guest state. */
1044static __inline__ void
1045put_gpr_b3(UInt archreg, IRExpr *expr)
1046{
1047 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1048
1049 stmt(IRStmt_Put(gpr_b3_offset(archreg), expr));
1050}
1051
1052/* Read byte #3 of a gpr register. */
1053static __inline__ IRExpr *
1054get_gpr_b3(UInt archreg)
1055{
1056 return IRExpr_Get(gpr_b3_offset(archreg), Ity_I8);
1057}
1058
1059/* Return the guest state offset of byte #0 of a gpr register. */
1060static __inline__ UInt
1061gpr_b0_offset(UInt archreg)
1062{
1063 return gpr_offset(archreg) + 0;
1064}
1065
1066/* Write byte #0 of a gpr to the guest state. */
1067static __inline__ void
1068put_gpr_b0(UInt archreg, IRExpr *expr)
1069{
1070 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1071
1072 stmt(IRStmt_Put(gpr_b0_offset(archreg), expr));
1073}
1074
1075/* Read byte #0 of a gpr register. */
1076static __inline__ IRExpr *
1077get_gpr_b0(UInt archreg)
1078{
1079 return IRExpr_Get(gpr_b0_offset(archreg), Ity_I8);
1080}
1081
1082/* Return the guest state offset of word #1 of a gpr register. */
1083static __inline__ UInt
1084gpr_w1_offset(UInt archreg)
1085{
1086 return gpr_offset(archreg) + 4;
1087}
1088
1089/* Write word #1 of a gpr to the guest state. */
1090static __inline__ void
1091put_gpr_w1(UInt archreg, IRExpr *expr)
1092{
1093 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1094
1095 stmt(IRStmt_Put(gpr_w1_offset(archreg), expr));
1096}
1097
1098/* Read word #1 of a gpr register. */
1099static __inline__ IRExpr *
1100get_gpr_w1(UInt archreg)
1101{
1102 return IRExpr_Get(gpr_w1_offset(archreg), Ity_I32);
1103}
1104
1105/* Return the guest state offset of half word #3 of a gpr register. */
1106static __inline__ UInt
1107gpr_hw3_offset(UInt archreg)
1108{
1109 return gpr_offset(archreg) + 6;
1110}
1111
1112/* Write half word #3 of a gpr to the guest state. */
1113static __inline__ void
1114put_gpr_hw3(UInt archreg, IRExpr *expr)
1115{
1116 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1117
1118 stmt(IRStmt_Put(gpr_hw3_offset(archreg), expr));
1119}
1120
1121/* Read half word #3 of a gpr register. */
1122static __inline__ IRExpr *
1123get_gpr_hw3(UInt archreg)
1124{
1125 return IRExpr_Get(gpr_hw3_offset(archreg), Ity_I16);
1126}
1127
1128/* Return the guest state offset of byte #7 of a gpr register. */
1129static __inline__ UInt
1130gpr_b7_offset(UInt archreg)
1131{
1132 return gpr_offset(archreg) + 7;
1133}
1134
1135/* Write byte #7 of a gpr to the guest state. */
1136static __inline__ void
1137put_gpr_b7(UInt archreg, IRExpr *expr)
1138{
1139 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1140
1141 stmt(IRStmt_Put(gpr_b7_offset(archreg), expr));
1142}
1143
1144/* Read byte #7 of a gpr register. */
1145static __inline__ IRExpr *
1146get_gpr_b7(UInt archreg)
1147{
1148 return IRExpr_Get(gpr_b7_offset(archreg), Ity_I8);
1149}
1150
1151/* Return the guest state offset of half word #0 of a gpr register. */
1152static __inline__ UInt
1153gpr_hw0_offset(UInt archreg)
1154{
1155 return gpr_offset(archreg) + 0;
1156}
1157
1158/* Write half word #0 of a gpr to the guest state. */
1159static __inline__ void
1160put_gpr_hw0(UInt archreg, IRExpr *expr)
1161{
1162 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1163
1164 stmt(IRStmt_Put(gpr_hw0_offset(archreg), expr));
1165}
1166
1167/* Read half word #0 of a gpr register. */
1168static __inline__ IRExpr *
1169get_gpr_hw0(UInt archreg)
1170{
1171 return IRExpr_Get(gpr_hw0_offset(archreg), Ity_I16);
1172}
1173
1174/* Return the guest state offset of byte #4 of a gpr register. */
1175static __inline__ UInt
1176gpr_b4_offset(UInt archreg)
1177{
1178 return gpr_offset(archreg) + 4;
1179}
1180
1181/* Write byte #4 of a gpr to the guest state. */
1182static __inline__ void
1183put_gpr_b4(UInt archreg, IRExpr *expr)
1184{
1185 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1186
1187 stmt(IRStmt_Put(gpr_b4_offset(archreg), expr));
1188}
1189
1190/* Read byte #4 of a gpr register. */
1191static __inline__ IRExpr *
1192get_gpr_b4(UInt archreg)
1193{
1194 return IRExpr_Get(gpr_b4_offset(archreg), Ity_I8);
1195}
1196
1197/* Return the guest state offset of byte #1 of a gpr register. */
1198static __inline__ UInt
1199gpr_b1_offset(UInt archreg)
1200{
1201 return gpr_offset(archreg) + 1;
1202}
1203
1204/* Write byte #1 of a gpr to the guest state. */
1205static __inline__ void
1206put_gpr_b1(UInt archreg, IRExpr *expr)
1207{
1208 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1209
1210 stmt(IRStmt_Put(gpr_b1_offset(archreg), expr));
1211}
1212
1213/* Read byte #1 of a gpr register. */
1214static __inline__ IRExpr *
1215get_gpr_b1(UInt archreg)
1216{
1217 return IRExpr_Get(gpr_b1_offset(archreg), Ity_I8);
1218}
1219
1220/* Return the guest state offset of half word #2 of a gpr register. */
1221static __inline__ UInt
1222gpr_hw2_offset(UInt archreg)
1223{
1224 return gpr_offset(archreg) + 4;
1225}
1226
1227/* Write half word #2 of a gpr to the guest state. */
1228static __inline__ void
1229put_gpr_hw2(UInt archreg, IRExpr *expr)
1230{
1231 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1232
1233 stmt(IRStmt_Put(gpr_hw2_offset(archreg), expr));
1234}
1235
1236/* Read half word #2 of a gpr register. */
1237static __inline__ IRExpr *
1238get_gpr_hw2(UInt archreg)
1239{
1240 return IRExpr_Get(gpr_hw2_offset(archreg), Ity_I16);
1241}
1242
1243/* Return the guest state offset of byte #5 of a gpr register. */
1244static __inline__ UInt
1245gpr_b5_offset(UInt archreg)
1246{
1247 return gpr_offset(archreg) + 5;
1248}
1249
1250/* Write byte #5 of a gpr to the guest state. */
1251static __inline__ void
1252put_gpr_b5(UInt archreg, IRExpr *expr)
1253{
1254 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1255
1256 stmt(IRStmt_Put(gpr_b5_offset(archreg), expr));
1257}
1258
1259/* Read byte #5 of a gpr register. */
1260static __inline__ IRExpr *
1261get_gpr_b5(UInt archreg)
1262{
1263 return IRExpr_Get(gpr_b5_offset(archreg), Ity_I8);
1264}
1265
1266/* Return the guest state offset of byte #2 of a gpr register. */
1267static __inline__ UInt
1268gpr_b2_offset(UInt archreg)
1269{
1270 return gpr_offset(archreg) + 2;
1271}
1272
1273/* Write byte #2 of a gpr to the guest state. */
1274static __inline__ void
1275put_gpr_b2(UInt archreg, IRExpr *expr)
1276{
1277 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1278
1279 stmt(IRStmt_Put(gpr_b2_offset(archreg), expr));
1280}
1281
1282/* Read byte #2 of a gpr register. */
1283static __inline__ IRExpr *
1284get_gpr_b2(UInt archreg)
1285{
1286 return IRExpr_Get(gpr_b2_offset(archreg), Ity_I8);
1287}
1288
1289/* Return the guest state offset of the counter register. */
1290static UInt
1291counter_offset(void)
1292{
floriane88b3c92011-07-05 02:48:39 +00001293 return S390X_GUEST_OFFSET(guest_counter);
sewardj2019a972011-03-07 16:04:07 +00001294}
1295
1296/* Return the guest state offset of double word #0 of the counter register. */
1297static __inline__ UInt
1298counter_dw0_offset(void)
1299{
1300 return counter_offset() + 0;
1301}
1302
1303/* Write double word #0 of the counter to the guest state. */
1304static __inline__ void
1305put_counter_dw0(IRExpr *expr)
1306{
1307 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I64);
1308
1309 stmt(IRStmt_Put(counter_dw0_offset(), expr));
1310}
1311
1312/* Read double word #0 of the counter register. */
1313static __inline__ IRExpr *
1314get_counter_dw0(void)
1315{
1316 return IRExpr_Get(counter_dw0_offset(), Ity_I64);
1317}
1318
1319/* Return the guest state offset of word #0 of the counter register. */
1320static __inline__ UInt
1321counter_w0_offset(void)
1322{
1323 return counter_offset() + 0;
1324}
1325
1326/* Return the guest state offset of word #1 of the counter register. */
1327static __inline__ UInt
1328counter_w1_offset(void)
1329{
1330 return counter_offset() + 4;
1331}
1332
1333/* Write word #0 of the counter to the guest state. */
1334static __inline__ void
1335put_counter_w0(IRExpr *expr)
1336{
1337 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1338
1339 stmt(IRStmt_Put(counter_w0_offset(), expr));
1340}
1341
1342/* Read word #0 of the counter register. */
1343static __inline__ IRExpr *
1344get_counter_w0(void)
1345{
1346 return IRExpr_Get(counter_w0_offset(), Ity_I32);
1347}
1348
1349/* Write word #1 of the counter to the guest state. */
1350static __inline__ void
1351put_counter_w1(IRExpr *expr)
1352{
1353 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1354
1355 stmt(IRStmt_Put(counter_w1_offset(), expr));
1356}
1357
1358/* Read word #1 of the counter register. */
1359static __inline__ IRExpr *
1360get_counter_w1(void)
1361{
1362 return IRExpr_Get(counter_w1_offset(), Ity_I32);
1363}
1364
1365/* Return the guest state offset of the fpc register. */
1366static UInt
1367fpc_offset(void)
1368{
floriane88b3c92011-07-05 02:48:39 +00001369 return S390X_GUEST_OFFSET(guest_fpc);
sewardj2019a972011-03-07 16:04:07 +00001370}
1371
1372/* Return the guest state offset of word #0 of the fpc register. */
1373static __inline__ UInt
1374fpc_w0_offset(void)
1375{
1376 return fpc_offset() + 0;
1377}
1378
1379/* Write word #0 of the fpc to the guest state. */
1380static __inline__ void
1381put_fpc_w0(IRExpr *expr)
1382{
1383 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1384
1385 stmt(IRStmt_Put(fpc_w0_offset(), expr));
1386}
1387
1388/* Read word #0 of the fpc register. */
1389static __inline__ IRExpr *
1390get_fpc_w0(void)
1391{
1392 return IRExpr_Get(fpc_w0_offset(), Ity_I32);
1393}
1394
1395
1396/*------------------------------------------------------------*/
florian2c74d242012-09-12 19:38:42 +00001397/*--- Rounding modes ---*/
1398/*------------------------------------------------------------*/
1399
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{
florianf0fa1be2012-09-18 20:24:38 +00008177 UInt input_mask, fpc_mask;
sewardj2019a972011-03-07 16:04:07 +00008178
florianf0fa1be2012-09-18 20:24:38 +00008179 input_mask = 3;
8180 fpc_mask = s390_host_has_fpext ? 7 : 3;
sewardj2019a972011-03-07 16:04:07 +00008181
florianf0fa1be2012-09-18 20:24:38 +00008182 put_fpc_w0(binop(Iop_Or32,
8183 binop(Iop_And32, get_fpc_w0(), mkU32(~fpc_mask)),
8184 binop(Iop_And32, unop(Iop_64to32, mkexpr(op2addr)),
8185 mkU32(input_mask))));
sewardj2019a972011-03-07 16:04:07 +00008186 return "srnm";
8187}
8188
8189static HChar *
florianf0fa1be2012-09-18 20:24:38 +00008190s390_irgen_SRNMB(IRTemp op2addr)
8191{
8192 UInt input_mask, fpc_mask;
8193
8194 input_mask = 7;
8195 fpc_mask = 7;
8196
8197 put_fpc_w0(binop(Iop_Or32,
8198 binop(Iop_And32, get_fpc_w0(), mkU32(~fpc_mask)),
8199 binop(Iop_And32, unop(Iop_64to32, mkexpr(op2addr)),
8200 mkU32(input_mask))));
8201 return "srnmb";
8202}
8203
florian81a4bfe2012-09-20 01:25:28 +00008204static void
florianf0fa1be2012-09-18 20:24:38 +00008205s390_irgen_srnmb_wrapper(UChar b2, UShort d2)
8206{
8207 if (b2 == 0) { /* This is the typical case */
8208 if (d2 > 3) {
8209 if (s390_host_has_fpext && d2 == 7) {
8210 /* ok */
8211 } else {
8212 emulation_warning(EmWarn_S390X_invalid_rounding);
8213 d2 = S390_FPC_ROUND_NEAREST_EVEN;
8214 }
8215 }
8216 }
8217
8218 s390_format_S_RD(s390_irgen_SRNMB, b2, d2);
8219}
8220
8221
8222static HChar *
sewardj2019a972011-03-07 16:04:07 +00008223s390_irgen_SFPC(UChar r1)
8224{
8225 put_fpc_w0(get_gpr_w1(r1));
8226
8227 return "sfpc";
8228}
8229
8230static HChar *
8231s390_irgen_STE(UChar r1, IRTemp op2addr)
8232{
8233 store(mkexpr(op2addr), get_fpr_w0(r1));
8234
8235 return "ste";
8236}
8237
8238static HChar *
8239s390_irgen_STD(UChar r1, IRTemp op2addr)
8240{
8241 store(mkexpr(op2addr), get_fpr_dw0(r1));
8242
8243 return "std";
8244}
8245
8246static HChar *
8247s390_irgen_STEY(UChar r1, IRTemp op2addr)
8248{
8249 store(mkexpr(op2addr), get_fpr_w0(r1));
8250
8251 return "stey";
8252}
8253
8254static HChar *
8255s390_irgen_STDY(UChar r1, IRTemp op2addr)
8256{
8257 store(mkexpr(op2addr), get_fpr_dw0(r1));
8258
8259 return "stdy";
8260}
8261
8262static HChar *
8263s390_irgen_STFPC(IRTemp op2addr)
8264{
8265 store(mkexpr(op2addr), get_fpc_w0());
8266
8267 return "stfpc";
8268}
8269
8270static HChar *
8271s390_irgen_AEBR(UChar r1, UChar r2)
8272{
8273 IRTemp op1 = newTemp(Ity_F32);
8274 IRTemp op2 = newTemp(Ity_F32);
8275 IRTemp result = newTemp(Ity_F32);
floriandb4fcaa2012-09-05 19:54:08 +00008276 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008277
8278 assign(op1, get_fpr_w0(r1));
8279 assign(op2, get_fpr_w0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008280 assign(result, triop(Iop_AddF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008281 mkexpr(op2)));
8282 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
8283 put_fpr_w0(r1, mkexpr(result));
8284
8285 return "aebr";
8286}
8287
8288static HChar *
8289s390_irgen_ADBR(UChar r1, UChar r2)
8290{
8291 IRTemp op1 = newTemp(Ity_F64);
8292 IRTemp op2 = newTemp(Ity_F64);
8293 IRTemp result = newTemp(Ity_F64);
floriandb4fcaa2012-09-05 19:54:08 +00008294 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008295
8296 assign(op1, get_fpr_dw0(r1));
8297 assign(op2, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008298 assign(result, triop(Iop_AddF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008299 mkexpr(op2)));
8300 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
8301 put_fpr_dw0(r1, mkexpr(result));
8302
8303 return "adbr";
8304}
8305
8306static HChar *
8307s390_irgen_AEB(UChar r1, IRTemp op2addr)
8308{
8309 IRTemp op1 = newTemp(Ity_F32);
8310 IRTemp op2 = newTemp(Ity_F32);
8311 IRTemp result = newTemp(Ity_F32);
floriandb4fcaa2012-09-05 19:54:08 +00008312 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008313
8314 assign(op1, get_fpr_w0(r1));
8315 assign(op2, load(Ity_F32, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00008316 assign(result, triop(Iop_AddF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008317 mkexpr(op2)));
8318 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
8319 put_fpr_w0(r1, mkexpr(result));
8320
8321 return "aeb";
8322}
8323
8324static HChar *
8325s390_irgen_ADB(UChar r1, IRTemp op2addr)
8326{
8327 IRTemp op1 = newTemp(Ity_F64);
8328 IRTemp op2 = newTemp(Ity_F64);
8329 IRTemp result = newTemp(Ity_F64);
floriandb4fcaa2012-09-05 19:54:08 +00008330 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008331
8332 assign(op1, get_fpr_dw0(r1));
8333 assign(op2, load(Ity_F64, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00008334 assign(result, triop(Iop_AddF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008335 mkexpr(op2)));
8336 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
8337 put_fpr_dw0(r1, mkexpr(result));
8338
8339 return "adb";
8340}
8341
8342static HChar *
florian4b8efad2012-09-02 18:07:08 +00008343s390_irgen_CEFBR(UChar m3, UChar m4 __attribute__((unused)),
8344 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008345{
florian847684d2012-09-05 04:19:09 +00008346 if (! s390_host_has_fpext && m3 != S390_ROUND_PER_FPC) {
florian4b8efad2012-09-02 18:07:08 +00008347 emulation_warning(EmWarn_S390X_fpext_rounding);
florian847684d2012-09-05 04:19:09 +00008348 m3 = S390_ROUND_PER_FPC;
florian4b8efad2012-09-02 18:07:08 +00008349 }
sewardj2019a972011-03-07 16:04:07 +00008350 IRTemp op2 = newTemp(Ity_I32);
8351
8352 assign(op2, get_gpr_w1(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008353 put_fpr_w0(r1, binop(Iop_I32StoF32, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +00008354 mkexpr(op2)));
sewardj2019a972011-03-07 16:04:07 +00008355
8356 return "cefbr";
8357}
8358
8359static HChar *
florian4b8efad2012-09-02 18:07:08 +00008360s390_irgen_CDFBR(UChar m3 __attribute__((unused)),
8361 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008362{
8363 IRTemp op2 = newTemp(Ity_I32);
8364
8365 assign(op2, get_gpr_w1(r2));
8366 put_fpr_dw0(r1, unop(Iop_I32StoF64, mkexpr(op2)));
8367
8368 return "cdfbr";
8369}
8370
8371static HChar *
florian4b8efad2012-09-02 18:07:08 +00008372s390_irgen_CEGBR(UChar m3, UChar m4 __attribute__((unused)),
8373 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008374{
florian847684d2012-09-05 04:19:09 +00008375 if (! s390_host_has_fpext && m3 != S390_ROUND_PER_FPC) {
florian4b8efad2012-09-02 18:07:08 +00008376 emulation_warning(EmWarn_S390X_fpext_rounding);
florian847684d2012-09-05 04:19:09 +00008377 m3 = S390_ROUND_PER_FPC;
florian4b8efad2012-09-02 18:07:08 +00008378 }
sewardj2019a972011-03-07 16:04:07 +00008379 IRTemp op2 = newTemp(Ity_I64);
8380
8381 assign(op2, get_gpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008382 put_fpr_w0(r1, binop(Iop_I64StoF32, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +00008383 mkexpr(op2)));
sewardj2019a972011-03-07 16:04:07 +00008384
8385 return "cegbr";
8386}
8387
8388static HChar *
florian4b8efad2012-09-02 18:07:08 +00008389s390_irgen_CDGBR(UChar m3, UChar m4 __attribute__((unused)),
8390 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008391{
florian847684d2012-09-05 04:19:09 +00008392 if (! s390_host_has_fpext && m3 != S390_ROUND_PER_FPC) {
florian4b8efad2012-09-02 18:07:08 +00008393 emulation_warning(EmWarn_S390X_fpext_rounding);
florian847684d2012-09-05 04:19:09 +00008394 m3 = S390_ROUND_PER_FPC;
florian4b8efad2012-09-02 18:07:08 +00008395 }
sewardj2019a972011-03-07 16:04:07 +00008396 IRTemp op2 = newTemp(Ity_I64);
8397
8398 assign(op2, get_gpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008399 put_fpr_dw0(r1, binop(Iop_I64StoF64, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +00008400 mkexpr(op2)));
sewardj2019a972011-03-07 16:04:07 +00008401
8402 return "cdgbr";
8403}
8404
8405static HChar *
florian1c8f7ff2012-09-01 00:12:11 +00008406s390_irgen_CELFBR(UChar m3, UChar m4 __attribute__((unused)),
8407 UChar r1, UChar r2)
8408{
floriane75dafa2012-09-01 17:54:09 +00008409 if (! s390_host_has_fpext) {
8410 emulation_failure(EmFail_S390X_fpext);
8411 } else {
8412 IRTemp op2 = newTemp(Ity_I32);
florian1c8f7ff2012-09-01 00:12:11 +00008413
floriane75dafa2012-09-01 17:54:09 +00008414 assign(op2, get_gpr_w1(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008415 put_fpr_w0(r1, binop(Iop_I32UtoF32, mkexpr(encode_bfp_rounding_mode(m3)),
floriane75dafa2012-09-01 17:54:09 +00008416 mkexpr(op2)));
8417 }
florian1c8f7ff2012-09-01 00:12:11 +00008418 return "celfbr";
8419}
8420
8421static HChar *
floriand2129202012-09-01 20:01:39 +00008422s390_irgen_CDLFBR(UChar m3 __attribute__((unused)),
8423 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
florian1c8f7ff2012-09-01 00:12:11 +00008424{
floriane75dafa2012-09-01 17:54:09 +00008425 if (! s390_host_has_fpext) {
8426 emulation_failure(EmFail_S390X_fpext);
8427 } else {
8428 IRTemp op2 = newTemp(Ity_I32);
florian1c8f7ff2012-09-01 00:12:11 +00008429
floriane75dafa2012-09-01 17:54:09 +00008430 assign(op2, get_gpr_w1(r2));
8431 put_fpr_dw0(r1, unop(Iop_I32UtoF64, mkexpr(op2)));
8432 }
florian1c8f7ff2012-09-01 00:12:11 +00008433 return "cdlfbr";
8434}
8435
8436static HChar *
8437s390_irgen_CELGBR(UChar m3, UChar m4 __attribute__((unused)),
8438 UChar r1, UChar r2)
8439{
floriane75dafa2012-09-01 17:54:09 +00008440 if (! s390_host_has_fpext) {
8441 emulation_failure(EmFail_S390X_fpext);
8442 } else {
8443 IRTemp op2 = newTemp(Ity_I64);
florian1c8f7ff2012-09-01 00:12:11 +00008444
floriane75dafa2012-09-01 17:54:09 +00008445 assign(op2, get_gpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008446 put_fpr_w0(r1, binop(Iop_I64UtoF32, mkexpr(encode_bfp_rounding_mode(m3)),
floriane75dafa2012-09-01 17:54:09 +00008447 mkexpr(op2)));
8448 }
florian1c8f7ff2012-09-01 00:12:11 +00008449 return "celgbr";
8450}
8451
8452static HChar *
8453s390_irgen_CDLGBR(UChar m3, UChar m4 __attribute__((unused)),
8454 UChar r1, UChar r2)
8455{
floriane75dafa2012-09-01 17:54:09 +00008456 if (! s390_host_has_fpext) {
8457 emulation_failure(EmFail_S390X_fpext);
8458 } else {
8459 IRTemp op2 = newTemp(Ity_I64);
florian1c8f7ff2012-09-01 00:12:11 +00008460
floriane75dafa2012-09-01 17:54:09 +00008461 assign(op2, get_gpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008462 put_fpr_dw0(r1, binop(Iop_I64UtoF64,
8463 mkexpr(encode_bfp_rounding_mode(m3)),
floriane75dafa2012-09-01 17:54:09 +00008464 mkexpr(op2)));
8465 }
florian1c8f7ff2012-09-01 00:12:11 +00008466 return "cdlgbr";
8467}
8468
8469static HChar *
8470s390_irgen_CLFEBR(UChar m3, UChar m4 __attribute__((unused)),
8471 UChar r1, UChar r2)
8472{
floriane75dafa2012-09-01 17:54:09 +00008473 if (! s390_host_has_fpext) {
8474 emulation_failure(EmFail_S390X_fpext);
8475 } else {
8476 IRTemp op = newTemp(Ity_F32);
8477 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +00008478 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +00008479
floriane75dafa2012-09-01 17:54:09 +00008480 assign(op, get_fpr_w0(r2));
florian19e00772012-09-06 03:13:22 +00008481 assign(result, binop(Iop_F32toI32U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +00008482 mkexpr(op)));
8483 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008484 s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_UINT_32, op, rounding_mode);
floriane75dafa2012-09-01 17:54:09 +00008485 }
florian1c8f7ff2012-09-01 00:12:11 +00008486 return "clfebr";
8487}
8488
8489static HChar *
8490s390_irgen_CLFDBR(UChar m3, UChar m4 __attribute__((unused)),
8491 UChar r1, UChar r2)
8492{
floriane75dafa2012-09-01 17:54:09 +00008493 if (! s390_host_has_fpext) {
8494 emulation_failure(EmFail_S390X_fpext);
8495 } else {
8496 IRTemp op = newTemp(Ity_F64);
8497 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +00008498 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +00008499
floriane75dafa2012-09-01 17:54:09 +00008500 assign(op, get_fpr_dw0(r2));
florian19e00772012-09-06 03:13:22 +00008501 assign(result, binop(Iop_F64toI32U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +00008502 mkexpr(op)));
8503 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008504 s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_UINT_32, op, rounding_mode);
floriane75dafa2012-09-01 17:54:09 +00008505 }
florian1c8f7ff2012-09-01 00:12:11 +00008506 return "clfdbr";
8507}
8508
8509static HChar *
8510s390_irgen_CLGEBR(UChar m3, UChar m4 __attribute__((unused)),
8511 UChar r1, UChar r2)
8512{
floriane75dafa2012-09-01 17:54:09 +00008513 if (! s390_host_has_fpext) {
8514 emulation_failure(EmFail_S390X_fpext);
8515 } else {
8516 IRTemp op = newTemp(Ity_F32);
8517 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +00008518 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +00008519
floriane75dafa2012-09-01 17:54:09 +00008520 assign(op, get_fpr_w0(r2));
florian19e00772012-09-06 03:13:22 +00008521 assign(result, binop(Iop_F32toI64U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +00008522 mkexpr(op)));
8523 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008524 s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_UINT_64, op, rounding_mode);
floriane75dafa2012-09-01 17:54:09 +00008525 }
florian1c8f7ff2012-09-01 00:12:11 +00008526 return "clgebr";
8527}
8528
8529static HChar *
8530s390_irgen_CLGDBR(UChar m3, UChar m4 __attribute__((unused)),
8531 UChar r1, UChar r2)
8532{
floriane75dafa2012-09-01 17:54:09 +00008533 if (! s390_host_has_fpext) {
8534 emulation_failure(EmFail_S390X_fpext);
8535 } else {
8536 IRTemp op = newTemp(Ity_F64);
8537 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +00008538 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +00008539
floriane75dafa2012-09-01 17:54:09 +00008540 assign(op, get_fpr_dw0(r2));
florian19e00772012-09-06 03:13:22 +00008541 assign(result, binop(Iop_F64toI64U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +00008542 mkexpr(op)));
8543 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008544 s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_UINT_64, op, rounding_mode);
floriane75dafa2012-09-01 17:54:09 +00008545 }
florian1c8f7ff2012-09-01 00:12:11 +00008546 return "clgdbr";
8547}
8548
8549static HChar *
florian4b8efad2012-09-02 18:07:08 +00008550s390_irgen_CFEBR(UChar m3, UChar m4 __attribute__((unused)),
8551 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008552{
8553 IRTemp op = newTemp(Ity_F32);
8554 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +00008555 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +00008556
8557 assign(op, get_fpr_w0(r2));
florian19e00772012-09-06 03:13:22 +00008558 assign(result, binop(Iop_F32toI32S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +00008559 mkexpr(op)));
8560 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008561 s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_INT_32, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +00008562
8563 return "cfebr";
8564}
8565
8566static HChar *
florian4b8efad2012-09-02 18:07:08 +00008567s390_irgen_CFDBR(UChar m3, UChar m4 __attribute__((unused)),
8568 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008569{
8570 IRTemp op = newTemp(Ity_F64);
8571 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +00008572 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +00008573
8574 assign(op, get_fpr_dw0(r2));
florian19e00772012-09-06 03:13:22 +00008575 assign(result, binop(Iop_F64toI32S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +00008576 mkexpr(op)));
8577 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008578 s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_INT_32, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +00008579
8580 return "cfdbr";
8581}
8582
8583static HChar *
florian4b8efad2012-09-02 18:07:08 +00008584s390_irgen_CGEBR(UChar m3, UChar m4 __attribute__((unused)),
8585 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008586{
8587 IRTemp op = newTemp(Ity_F32);
8588 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +00008589 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +00008590
8591 assign(op, get_fpr_w0(r2));
florian19e00772012-09-06 03:13:22 +00008592 assign(result, binop(Iop_F32toI64S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +00008593 mkexpr(op)));
8594 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008595 s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_INT_64, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +00008596
8597 return "cgebr";
8598}
8599
8600static HChar *
florian4b8efad2012-09-02 18:07:08 +00008601s390_irgen_CGDBR(UChar m3, UChar m4 __attribute__((unused)),
8602 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008603{
8604 IRTemp op = newTemp(Ity_F64);
8605 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +00008606 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +00008607
8608 assign(op, get_fpr_dw0(r2));
florian19e00772012-09-06 03:13:22 +00008609 assign(result, binop(Iop_F64toI64S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +00008610 mkexpr(op)));
8611 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008612 s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_INT_64, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +00008613
8614 return "cgdbr";
8615}
8616
8617static HChar *
8618s390_irgen_DEBR(UChar r1, UChar r2)
8619{
8620 IRTemp op1 = newTemp(Ity_F32);
8621 IRTemp op2 = newTemp(Ity_F32);
8622 IRTemp result = newTemp(Ity_F32);
floriandb4fcaa2012-09-05 19:54:08 +00008623 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008624
8625 assign(op1, get_fpr_w0(r1));
8626 assign(op2, get_fpr_w0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008627 assign(result, triop(Iop_DivF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008628 mkexpr(op2)));
8629 put_fpr_w0(r1, mkexpr(result));
8630
8631 return "debr";
8632}
8633
8634static HChar *
8635s390_irgen_DDBR(UChar r1, UChar r2)
8636{
8637 IRTemp op1 = newTemp(Ity_F64);
8638 IRTemp op2 = newTemp(Ity_F64);
8639 IRTemp result = newTemp(Ity_F64);
floriandb4fcaa2012-09-05 19:54:08 +00008640 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008641
8642 assign(op1, get_fpr_dw0(r1));
8643 assign(op2, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008644 assign(result, triop(Iop_DivF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008645 mkexpr(op2)));
8646 put_fpr_dw0(r1, mkexpr(result));
8647
8648 return "ddbr";
8649}
8650
8651static HChar *
8652s390_irgen_DEB(UChar r1, IRTemp op2addr)
8653{
8654 IRTemp op1 = newTemp(Ity_F32);
8655 IRTemp op2 = newTemp(Ity_F32);
8656 IRTemp result = newTemp(Ity_F32);
floriandb4fcaa2012-09-05 19:54:08 +00008657 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008658
8659 assign(op1, get_fpr_w0(r1));
8660 assign(op2, load(Ity_F32, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00008661 assign(result, triop(Iop_DivF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008662 mkexpr(op2)));
8663 put_fpr_w0(r1, mkexpr(result));
8664
8665 return "deb";
8666}
8667
8668static HChar *
8669s390_irgen_DDB(UChar r1, IRTemp op2addr)
8670{
8671 IRTemp op1 = newTemp(Ity_F64);
8672 IRTemp op2 = newTemp(Ity_F64);
8673 IRTemp result = newTemp(Ity_F64);
floriandb4fcaa2012-09-05 19:54:08 +00008674 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008675
8676 assign(op1, get_fpr_dw0(r1));
8677 assign(op2, load(Ity_F64, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00008678 assign(result, triop(Iop_DivF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008679 mkexpr(op2)));
8680 put_fpr_dw0(r1, mkexpr(result));
8681
8682 return "ddb";
8683}
8684
8685static HChar *
8686s390_irgen_LTEBR(UChar r1, UChar r2)
8687{
8688 IRTemp result = newTemp(Ity_F32);
8689
8690 assign(result, get_fpr_w0(r2));
8691 put_fpr_w0(r1, mkexpr(result));
8692 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
8693
8694 return "ltebr";
8695}
8696
8697static HChar *
8698s390_irgen_LTDBR(UChar r1, UChar r2)
8699{
8700 IRTemp result = newTemp(Ity_F64);
8701
8702 assign(result, get_fpr_dw0(r2));
8703 put_fpr_dw0(r1, mkexpr(result));
8704 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
8705
8706 return "ltdbr";
8707}
8708
8709static HChar *
8710s390_irgen_LCEBR(UChar r1, UChar r2)
8711{
8712 IRTemp result = newTemp(Ity_F32);
8713
8714 assign(result, unop(Iop_NegF32, get_fpr_w0(r2)));
8715 put_fpr_w0(r1, mkexpr(result));
8716 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
8717
8718 return "lcebr";
8719}
8720
8721static HChar *
8722s390_irgen_LCDBR(UChar r1, UChar r2)
8723{
8724 IRTemp result = newTemp(Ity_F64);
8725
8726 assign(result, unop(Iop_NegF64, get_fpr_dw0(r2)));
8727 put_fpr_dw0(r1, mkexpr(result));
8728 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
8729
8730 return "lcdbr";
8731}
8732
8733static HChar *
8734s390_irgen_LDEBR(UChar r1, UChar r2)
8735{
8736 IRTemp op = newTemp(Ity_F32);
8737
8738 assign(op, get_fpr_w0(r2));
8739 put_fpr_dw0(r1, unop(Iop_F32toF64, mkexpr(op)));
8740
8741 return "ldebr";
8742}
8743
8744static HChar *
8745s390_irgen_LDEB(UChar r1, IRTemp op2addr)
8746{
8747 IRTemp op = newTemp(Ity_F32);
8748
8749 assign(op, load(Ity_F32, mkexpr(op2addr)));
8750 put_fpr_dw0(r1, unop(Iop_F32toF64, mkexpr(op)));
8751
8752 return "ldeb";
8753}
8754
8755static HChar *
florian4b8efad2012-09-02 18:07:08 +00008756s390_irgen_LEDBR(UChar m3, UChar m4 __attribute__((unused)),
8757 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008758{
florian12b0bca2012-09-05 20:05:20 +00008759 if (! s390_host_has_fpext && m3 != S390_ROUND_PER_FPC) {
8760 emulation_warning(EmWarn_S390X_fpext_rounding);
8761 m3 = S390_ROUND_PER_FPC;
8762 }
sewardj2019a972011-03-07 16:04:07 +00008763 IRTemp op = newTemp(Ity_F64);
8764
8765 assign(op, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008766 put_fpr_w0(r1, binop(Iop_F64toF32, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +00008767 mkexpr(op)));
sewardj2019a972011-03-07 16:04:07 +00008768
8769 return "ledbr";
8770}
8771
8772static HChar *
8773s390_irgen_MEEBR(UChar r1, UChar r2)
8774{
8775 IRTemp op1 = newTemp(Ity_F32);
8776 IRTemp op2 = newTemp(Ity_F32);
8777 IRTemp result = newTemp(Ity_F32);
floriandb4fcaa2012-09-05 19:54:08 +00008778 IRRoundingMode rounding_mode = encode_bfp_rounding_mode(S390_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008779
8780 assign(op1, get_fpr_w0(r1));
8781 assign(op2, get_fpr_w0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008782 assign(result, triop(Iop_MulF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008783 mkexpr(op2)));
8784 put_fpr_w0(r1, mkexpr(result));
8785
8786 return "meebr";
8787}
8788
8789static HChar *
8790s390_irgen_MDBR(UChar r1, UChar r2)
8791{
8792 IRTemp op1 = newTemp(Ity_F64);
8793 IRTemp op2 = newTemp(Ity_F64);
8794 IRTemp result = newTemp(Ity_F64);
floriandb4fcaa2012-09-05 19:54:08 +00008795 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008796
8797 assign(op1, get_fpr_dw0(r1));
8798 assign(op2, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008799 assign(result, triop(Iop_MulF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008800 mkexpr(op2)));
8801 put_fpr_dw0(r1, mkexpr(result));
8802
8803 return "mdbr";
8804}
8805
8806static HChar *
8807s390_irgen_MEEB(UChar r1, IRTemp op2addr)
8808{
8809 IRTemp op1 = newTemp(Ity_F32);
8810 IRTemp op2 = newTemp(Ity_F32);
8811 IRTemp result = newTemp(Ity_F32);
floriandb4fcaa2012-09-05 19:54:08 +00008812 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008813
8814 assign(op1, get_fpr_w0(r1));
8815 assign(op2, load(Ity_F32, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00008816 assign(result, triop(Iop_MulF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008817 mkexpr(op2)));
8818 put_fpr_w0(r1, mkexpr(result));
8819
8820 return "meeb";
8821}
8822
8823static HChar *
8824s390_irgen_MDB(UChar r1, IRTemp op2addr)
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, load(Ity_F64, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00008833 assign(result, triop(Iop_MulF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008834 mkexpr(op2)));
8835 put_fpr_dw0(r1, mkexpr(result));
8836
8837 return "mdb";
8838}
8839
8840static HChar *
8841s390_irgen_SEBR(UChar r1, UChar r2)
8842{
8843 IRTemp op1 = newTemp(Ity_F32);
8844 IRTemp op2 = newTemp(Ity_F32);
8845 IRTemp result = newTemp(Ity_F32);
floriandb4fcaa2012-09-05 19:54:08 +00008846 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008847
8848 assign(op1, get_fpr_w0(r1));
8849 assign(op2, get_fpr_w0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008850 assign(result, triop(Iop_SubF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008851 mkexpr(op2)));
8852 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
8853 put_fpr_w0(r1, mkexpr(result));
8854
8855 return "sebr";
8856}
8857
8858static HChar *
8859s390_irgen_SDBR(UChar r1, UChar r2)
8860{
8861 IRTemp op1 = newTemp(Ity_F64);
8862 IRTemp op2 = newTemp(Ity_F64);
8863 IRTemp result = newTemp(Ity_F64);
floriandb4fcaa2012-09-05 19:54:08 +00008864 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008865
8866 assign(op1, get_fpr_dw0(r1));
8867 assign(op2, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008868 assign(result, triop(Iop_SubF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008869 mkexpr(op2)));
8870 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
8871 put_fpr_dw0(r1, mkexpr(result));
8872
8873 return "sdbr";
8874}
8875
8876static HChar *
8877s390_irgen_SEB(UChar r1, IRTemp op2addr)
8878{
8879 IRTemp op1 = newTemp(Ity_F32);
8880 IRTemp op2 = newTemp(Ity_F32);
8881 IRTemp result = newTemp(Ity_F32);
floriandb4fcaa2012-09-05 19:54:08 +00008882 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008883
8884 assign(op1, get_fpr_w0(r1));
8885 assign(op2, load(Ity_F32, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00008886 assign(result, triop(Iop_SubF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008887 mkexpr(op2)));
8888 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
8889 put_fpr_w0(r1, mkexpr(result));
8890
8891 return "seb";
8892}
8893
8894static HChar *
8895s390_irgen_SDB(UChar r1, IRTemp op2addr)
8896{
8897 IRTemp op1 = newTemp(Ity_F64);
8898 IRTemp op2 = newTemp(Ity_F64);
8899 IRTemp result = newTemp(Ity_F64);
floriandb4fcaa2012-09-05 19:54:08 +00008900 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008901
8902 assign(op1, get_fpr_dw0(r1));
8903 assign(op2, load(Ity_F64, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00008904 assign(result, triop(Iop_SubF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008905 mkexpr(op2)));
8906 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
8907 put_fpr_dw0(r1, mkexpr(result));
8908
8909 return "sdb";
8910}
8911
8912
8913static HChar *
8914s390_irgen_CLC(UChar length, IRTemp start1, IRTemp start2)
8915{
florian79e839e2012-05-05 02:20:30 +00008916 IRTemp len = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00008917
florian79e839e2012-05-05 02:20:30 +00008918 assign(len, mkU64(length));
8919 s390_irgen_CLC_EX(len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +00008920
8921 return "clc";
8922}
8923
8924static HChar *
florianb0c9a132011-09-08 15:37:39 +00008925s390_irgen_CLCL(UChar r1, UChar r2)
8926{
8927 IRTemp addr1 = newTemp(Ity_I64);
8928 IRTemp addr2 = newTemp(Ity_I64);
8929 IRTemp addr1_load = newTemp(Ity_I64);
8930 IRTemp addr2_load = newTemp(Ity_I64);
8931 IRTemp len1 = newTemp(Ity_I32);
8932 IRTemp len2 = newTemp(Ity_I32);
8933 IRTemp r1p1 = newTemp(Ity_I32); /* contents of r1 + 1 */
8934 IRTemp r2p1 = newTemp(Ity_I32); /* contents of r2 + 1 */
8935 IRTemp single1 = newTemp(Ity_I8);
8936 IRTemp single2 = newTemp(Ity_I8);
8937 IRTemp pad = newTemp(Ity_I8);
8938
8939 assign(addr1, get_gpr_dw0(r1));
8940 assign(r1p1, get_gpr_w1(r1 + 1));
8941 assign(len1, binop(Iop_And32, mkexpr(r1p1), mkU32(0x00ffffff)));
8942 assign(addr2, get_gpr_dw0(r2));
8943 assign(r2p1, get_gpr_w1(r2 + 1));
8944 assign(len2, binop(Iop_And32, mkexpr(r2p1), mkU32(0x00ffffff)));
8945 assign(pad, get_gpr_b4(r2 + 1));
8946
8947 /* len1 == 0 and len2 == 0? Exit */
8948 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +00008949 next_insn_if(binop(Iop_CmpEQ32, binop(Iop_Or32, mkexpr(len1),
8950 mkexpr(len2)), mkU32(0)));
florianb0c9a132011-09-08 15:37:39 +00008951
8952 /* Because mkite evaluates both the then-clause and the else-clause
8953 we cannot load directly from addr1 here. If len1 is 0, then adddr1
8954 may be NULL and loading from there would segfault. So we provide a
8955 valid dummy address in that case. Loading from there does no harm and
8956 the value will be discarded at runtime. */
8957 assign(addr1_load,
8958 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
8959 mkU64(guest_IA_curr_instr), mkexpr(addr1)));
8960 assign(single1,
8961 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
8962 mkexpr(pad), load(Ity_I8, mkexpr(addr1_load))));
8963
8964 assign(addr2_load,
8965 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
8966 mkU64(guest_IA_curr_instr), mkexpr(addr2)));
8967 assign(single2,
8968 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
8969 mkexpr(pad), load(Ity_I8, mkexpr(addr2_load))));
8970
8971 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, single1, single2, False);
8972 /* Fields differ ? */
florian6820ba52012-07-26 02:01:50 +00008973 next_insn_if(binop(Iop_CmpNE8, mkexpr(single1), mkexpr(single2)));
florianb0c9a132011-09-08 15:37:39 +00008974
8975 /* Update len1 and addr1, unless len1 == 0. */
8976 put_gpr_dw0(r1,
8977 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
8978 mkexpr(addr1),
8979 binop(Iop_Add64, mkexpr(addr1), mkU64(1))));
8980
8981 /* When updating len1 we must not modify bits (r1+1)[0:39] */
8982 put_gpr_w1(r1 + 1,
8983 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
8984 binop(Iop_And32, mkexpr(r1p1), mkU32(0xFF000000u)),
8985 binop(Iop_Sub32, mkexpr(r1p1), mkU32(1))));
8986
8987 /* Update len2 and addr2, unless len2 == 0. */
8988 put_gpr_dw0(r2,
8989 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
8990 mkexpr(addr2),
8991 binop(Iop_Add64, mkexpr(addr2), mkU64(1))));
8992
8993 /* When updating len2 we must not modify bits (r2+1)[0:39] */
8994 put_gpr_w1(r2 + 1,
8995 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
8996 binop(Iop_And32, mkexpr(r2p1), mkU32(0xFF000000u)),
8997 binop(Iop_Sub32, mkexpr(r2p1), mkU32(1))));
8998
florian6820ba52012-07-26 02:01:50 +00008999 iterate();
florianb0c9a132011-09-08 15:37:39 +00009000
9001 return "clcl";
9002}
9003
9004static HChar *
sewardj2019a972011-03-07 16:04:07 +00009005s390_irgen_CLCLE(UChar r1, UChar r3, IRTemp pad2)
9006{
9007 IRTemp addr1, addr3, addr1_load, addr3_load, len1, len3, single1, single3;
9008
9009 addr1 = newTemp(Ity_I64);
9010 addr3 = newTemp(Ity_I64);
9011 addr1_load = newTemp(Ity_I64);
9012 addr3_load = newTemp(Ity_I64);
9013 len1 = newTemp(Ity_I64);
9014 len3 = newTemp(Ity_I64);
9015 single1 = newTemp(Ity_I8);
9016 single3 = newTemp(Ity_I8);
9017
9018 assign(addr1, get_gpr_dw0(r1));
9019 assign(len1, get_gpr_dw0(r1 + 1));
9020 assign(addr3, get_gpr_dw0(r3));
9021 assign(len3, get_gpr_dw0(r3 + 1));
9022
9023 /* len1 == 0 and len3 == 0? Exit */
9024 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +00009025 next_insn_if(binop(Iop_CmpEQ64,binop(Iop_Or64, mkexpr(len1),
9026 mkexpr(len3)), mkU64(0)));
sewardj2019a972011-03-07 16:04:07 +00009027
9028 /* A mux requires both ways to be possible. This is a way to prevent clcle
9029 from reading from addr1 if it should read from the pad. Since the pad
9030 has no address, just read from the instruction, we discard that anyway */
9031 assign(addr1_load,
florian6ad49522011-09-09 02:38:55 +00009032 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
9033 mkU64(guest_IA_curr_instr), mkexpr(addr1)));
sewardj2019a972011-03-07 16:04:07 +00009034
9035 /* same for addr3 */
9036 assign(addr3_load,
florian6ad49522011-09-09 02:38:55 +00009037 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
9038 mkU64(guest_IA_curr_instr), mkexpr(addr3)));
sewardj2019a972011-03-07 16:04:07 +00009039
9040 assign(single1,
florian6ad49522011-09-09 02:38:55 +00009041 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
9042 unop(Iop_64to8, mkexpr(pad2)),
9043 load(Ity_I8, mkexpr(addr1_load))));
sewardj2019a972011-03-07 16:04:07 +00009044
9045 assign(single3,
florian6ad49522011-09-09 02:38:55 +00009046 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
9047 unop(Iop_64to8, mkexpr(pad2)),
9048 load(Ity_I8, mkexpr(addr3_load))));
sewardj2019a972011-03-07 16:04:07 +00009049
9050 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, single1, single3, False);
9051 /* Both fields differ ? */
florian6820ba52012-07-26 02:01:50 +00009052 next_insn_if(binop(Iop_CmpNE8, mkexpr(single1), mkexpr(single3)));
sewardj2019a972011-03-07 16:04:07 +00009053
9054 /* If a length in 0 we must not change this length and the address */
9055 put_gpr_dw0(r1,
florian6ad49522011-09-09 02:38:55 +00009056 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
9057 mkexpr(addr1),
9058 binop(Iop_Add64, mkexpr(addr1), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +00009059
9060 put_gpr_dw0(r1 + 1,
florian6ad49522011-09-09 02:38:55 +00009061 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
9062 mkU64(0), binop(Iop_Sub64, mkexpr(len1), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +00009063
9064 put_gpr_dw0(r3,
florian6ad49522011-09-09 02:38:55 +00009065 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
9066 mkexpr(addr3),
9067 binop(Iop_Add64, mkexpr(addr3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +00009068
9069 put_gpr_dw0(r3 + 1,
florian6ad49522011-09-09 02:38:55 +00009070 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
9071 mkU64(0), binop(Iop_Sub64, mkexpr(len3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +00009072
florian6820ba52012-07-26 02:01:50 +00009073 iterate();
sewardj2019a972011-03-07 16:04:07 +00009074
9075 return "clcle";
9076}
floriana64c2432011-07-16 02:11:50 +00009077
florianb0bf6602012-05-05 00:01:16 +00009078
sewardj2019a972011-03-07 16:04:07 +00009079static void
9080s390_irgen_XC_EX(IRTemp length, IRTemp start1, IRTemp start2)
9081{
florianb0bf6602012-05-05 00:01:16 +00009082 s390_irgen_xonc(Iop_Xor8, length, start1, start2);
9083}
sewardj2019a972011-03-07 16:04:07 +00009084
sewardj2019a972011-03-07 16:04:07 +00009085
florianb0bf6602012-05-05 00:01:16 +00009086static void
9087s390_irgen_NC_EX(IRTemp length, IRTemp start1, IRTemp start2)
9088{
9089 s390_irgen_xonc(Iop_And8, length, start1, start2);
9090}
sewardj2019a972011-03-07 16:04:07 +00009091
sewardj2019a972011-03-07 16:04:07 +00009092
florianb0bf6602012-05-05 00:01:16 +00009093static void
9094s390_irgen_OC_EX(IRTemp length, IRTemp start1, IRTemp start2)
9095{
9096 s390_irgen_xonc(Iop_Or8, length, start1, start2);
sewardj2019a972011-03-07 16:04:07 +00009097}
9098
9099
9100static void
9101s390_irgen_CLC_EX(IRTemp length, IRTemp start1, IRTemp start2)
9102{
9103 IRTemp current1 = newTemp(Ity_I8);
9104 IRTemp current2 = newTemp(Ity_I8);
9105 IRTemp counter = newTemp(Ity_I64);
9106
9107 assign(counter, get_counter_dw0());
9108 put_counter_dw0(mkU64(0));
9109
9110 assign(current1, load(Ity_I8, binop(Iop_Add64, mkexpr(start1),
9111 mkexpr(counter))));
9112 assign(current2, load(Ity_I8, binop(Iop_Add64, mkexpr(start2),
9113 mkexpr(counter))));
9114 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, current1, current2,
9115 False);
9116
9117 /* Both fields differ ? */
florian6820ba52012-07-26 02:01:50 +00009118 next_insn_if(binop(Iop_CmpNE8, mkexpr(current1), mkexpr(current2)));
sewardj2019a972011-03-07 16:04:07 +00009119
9120 /* Check for end of field */
9121 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
florian6820ba52012-07-26 02:01:50 +00009122 iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)));
sewardj2019a972011-03-07 16:04:07 +00009123 put_counter_dw0(mkU64(0));
9124}
9125
9126static void
9127s390_irgen_MVC_EX(IRTemp length, IRTemp start1, IRTemp start2)
9128{
9129 IRTemp counter = newTemp(Ity_I64);
9130
9131 assign(counter, get_counter_dw0());
9132
9133 store(binop(Iop_Add64, mkexpr(start1), mkexpr(counter)),
9134 load(Ity_I8, binop(Iop_Add64, mkexpr(start2), mkexpr(counter))));
9135
9136 /* Check for end of field */
9137 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
florian6820ba52012-07-26 02:01:50 +00009138 iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)));
sewardj2019a972011-03-07 16:04:07 +00009139 put_counter_dw0(mkU64(0));
9140}
9141
florianf87d4fb2012-05-05 02:55:24 +00009142static void
9143s390_irgen_TR_EX(IRTemp length, IRTemp start1, IRTemp start2)
9144{
9145 IRTemp op = newTemp(Ity_I8);
9146 IRTemp op1 = newTemp(Ity_I8);
9147 IRTemp result = newTemp(Ity_I64);
9148 IRTemp counter = newTemp(Ity_I64);
9149
9150 assign(counter, get_counter_dw0());
9151
9152 assign(op, load(Ity_I8, binop(Iop_Add64, mkexpr(start1), mkexpr(counter))));
9153
9154 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)), mkexpr(start2)));
9155
9156 assign(op1, load(Ity_I8, mkexpr(result)));
9157 store(binop(Iop_Add64, mkexpr(start1), mkexpr(counter)), mkexpr(op1));
9158
9159 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
florian6820ba52012-07-26 02:01:50 +00009160 iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)));
florianf87d4fb2012-05-05 02:55:24 +00009161 put_counter_dw0(mkU64(0));
9162}
sewardj2019a972011-03-07 16:04:07 +00009163
9164
9165static void
9166s390_irgen_EX_SS(UChar r, IRTemp addr2,
florian6820ba52012-07-26 02:01:50 +00009167 void (*irgen)(IRTemp length, IRTemp start1, IRTemp start2),
9168 int lensize)
sewardj2019a972011-03-07 16:04:07 +00009169{
9170 struct SS {
9171 unsigned int op : 8;
9172 unsigned int l : 8;
9173 unsigned int b1 : 4;
9174 unsigned int d1 : 12;
9175 unsigned int b2 : 4;
9176 unsigned int d2 : 12;
9177 };
9178 union {
9179 struct SS dec;
9180 unsigned long bytes;
9181 } ss;
9182 IRTemp cond;
9183 IRDirty *d;
9184 IRTemp torun;
9185
9186 IRTemp start1 = newTemp(Ity_I64);
9187 IRTemp start2 = newTemp(Ity_I64);
9188 IRTemp len = newTemp(lensize == 64 ? Ity_I64 : Ity_I32);
9189 cond = newTemp(Ity_I1);
9190 torun = newTemp(Ity_I64);
9191
9192 assign(torun, load(Ity_I64, mkexpr(addr2)));
9193 /* Start with a check that the saved code is still correct */
9194 assign(cond, binop(Iop_CmpNE64, mkexpr(torun), mkU64(last_execute_target)));
9195 /* If not, save the new value */
9196 d = unsafeIRDirty_0_N (0, "s390x_dirtyhelper_EX", &s390x_dirtyhelper_EX,
9197 mkIRExprVec_1(mkexpr(torun)));
9198 d->guard = mkexpr(cond);
9199 stmt(IRStmt_Dirty(d));
9200
9201 /* and restart */
florian428dfdd2012-03-27 03:09:49 +00009202 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TISTART),
9203 mkU64(guest_IA_curr_instr)));
9204 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TILEN), mkU64(4)));
florian6820ba52012-07-26 02:01:50 +00009205 restart_if(mkexpr(cond));
sewardj2019a972011-03-07 16:04:07 +00009206
9207 ss.bytes = last_execute_target;
9208 assign(start1, binop(Iop_Add64, mkU64(ss.dec.d1),
9209 ss.dec.b1 != 0 ? get_gpr_dw0(ss.dec.b1) : mkU64(0)));
9210 assign(start2, binop(Iop_Add64, mkU64(ss.dec.d2),
9211 ss.dec.b2 != 0 ? get_gpr_dw0(ss.dec.b2) : mkU64(0)));
9212 assign(len, unop(lensize == 64 ? Iop_8Uto64 : Iop_8Uto32, binop(Iop_Or8,
9213 r != 0 ? get_gpr_b7(r): mkU8(0), mkU8(ss.dec.l))));
9214 irgen(len, start1, start2);
florian8844a632012-04-13 04:04:06 +00009215
sewardj2019a972011-03-07 16:04:07 +00009216 last_execute_target = 0;
9217}
9218
9219static HChar *
9220s390_irgen_EX(UChar r1, IRTemp addr2)
9221{
9222 switch(last_execute_target & 0xff00000000000000ULL) {
9223 case 0:
9224 {
9225 /* no code information yet */
9226 IRDirty *d;
9227
9228 /* so safe the code... */
9229 d = unsafeIRDirty_0_N (0, "s390x_dirtyhelper_EX", &s390x_dirtyhelper_EX,
9230 mkIRExprVec_1(load(Ity_I64, mkexpr(addr2))));
9231 stmt(IRStmt_Dirty(d));
9232 /* and restart */
florian428dfdd2012-03-27 03:09:49 +00009233 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TISTART),
9234 mkU64(guest_IA_curr_instr)));
9235 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TILEN), mkU64(4)));
florian6820ba52012-07-26 02:01:50 +00009236 restart_if(IRExpr_Const(IRConst_U1(True)));
9237
sewardj2019a972011-03-07 16:04:07 +00009238 /* we know that this will be invalidated */
florianf9e1ed72012-04-17 02:41:56 +00009239 put_IA(mkaddr_expr(guest_IA_next_instr));
sewardj2019a972011-03-07 16:04:07 +00009240 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +00009241 dis_res->jk_StopHere = Ijk_TInval;
sewardj2019a972011-03-07 16:04:07 +00009242 break;
9243 }
9244
9245 case 0xd200000000000000ULL:
9246 /* special case MVC */
9247 s390_irgen_EX_SS(r1, addr2, s390_irgen_MVC_EX, 64);
9248 return "mvc via ex";
9249
9250 case 0xd500000000000000ULL:
9251 /* special case CLC */
9252 s390_irgen_EX_SS(r1, addr2, s390_irgen_CLC_EX, 64);
9253 return "clc via ex";
9254
9255 case 0xd700000000000000ULL:
9256 /* special case XC */
9257 s390_irgen_EX_SS(r1, addr2, s390_irgen_XC_EX, 32);
9258 return "xc via ex";
9259
florianb0bf6602012-05-05 00:01:16 +00009260 case 0xd600000000000000ULL:
9261 /* special case OC */
9262 s390_irgen_EX_SS(r1, addr2, s390_irgen_OC_EX, 32);
9263 return "oc via ex";
9264
9265 case 0xd400000000000000ULL:
9266 /* special case NC */
9267 s390_irgen_EX_SS(r1, addr2, s390_irgen_NC_EX, 32);
9268 return "nc via ex";
sewardj2019a972011-03-07 16:04:07 +00009269
florianf87d4fb2012-05-05 02:55:24 +00009270 case 0xdc00000000000000ULL:
9271 /* special case TR */
9272 s390_irgen_EX_SS(r1, addr2, s390_irgen_TR_EX, 64);
9273 return "tr via ex";
9274
sewardj2019a972011-03-07 16:04:07 +00009275 default:
9276 {
9277 /* everything else will get a self checking prefix that also checks the
9278 register content */
9279 IRDirty *d;
9280 UChar *bytes;
9281 IRTemp cond;
9282 IRTemp orperand;
9283 IRTemp torun;
9284
9285 cond = newTemp(Ity_I1);
9286 orperand = newTemp(Ity_I64);
9287 torun = newTemp(Ity_I64);
9288
9289 if (r1 == 0)
9290 assign(orperand, mkU64(0));
9291 else
9292 assign(orperand, unop(Iop_8Uto64,get_gpr_b7(r1)));
9293 /* This code is going to be translated */
9294 assign(torun, binop(Iop_Or64, load(Ity_I64, mkexpr(addr2)),
9295 binop(Iop_Shl64, mkexpr(orperand), mkU8(48))));
9296
9297 /* Start with a check that saved code is still correct */
9298 assign(cond, binop(Iop_CmpNE64, mkexpr(torun),
9299 mkU64(last_execute_target)));
9300 /* If not, save the new value */
9301 d = unsafeIRDirty_0_N (0, "s390x_dirtyhelper_EX", &s390x_dirtyhelper_EX,
9302 mkIRExprVec_1(mkexpr(torun)));
9303 d->guard = mkexpr(cond);
9304 stmt(IRStmt_Dirty(d));
9305
9306 /* and restart */
florian428dfdd2012-03-27 03:09:49 +00009307 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TISTART), mkU64(guest_IA_curr_instr)));
9308 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TILEN), mkU64(4)));
florian6820ba52012-07-26 02:01:50 +00009309 restart_if(mkexpr(cond));
sewardj2019a972011-03-07 16:04:07 +00009310
9311 /* Now comes the actual translation */
9312 bytes = (UChar *) &last_execute_target;
9313 s390_decode_and_irgen(bytes, ((((bytes[0] >> 6) + 1) >> 1) + 1) << 1,
9314 dis_res);
sewardj7ee97522011-05-09 21:45:04 +00009315 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00009316 vex_printf(" which was executed by\n");
9317 /* dont make useless translations in the next execute */
9318 last_execute_target = 0;
9319 }
9320 }
9321 return "ex";
9322}
9323
9324static HChar *
9325s390_irgen_EXRL(UChar r1, UInt offset)
9326{
9327 IRTemp addr = newTemp(Ity_I64);
9328 /* we might save one round trip because we know the target */
9329 if (!last_execute_target)
9330 last_execute_target = *(ULong *)(HWord)
9331 (guest_IA_curr_instr + offset * 2UL);
9332 assign(addr, mkU64(guest_IA_curr_instr + offset * 2UL));
9333 s390_irgen_EX(r1, addr);
9334 return "exrl";
9335}
9336
9337static HChar *
9338s390_irgen_IPM(UChar r1)
9339{
9340 // As long as we dont support SPM, lets just assume 0 as program mask
9341 put_gpr_b4(r1, unop(Iop_32to8, binop(Iop_Or32, mkU32(0 /* program mask */),
9342 binop(Iop_Shl32, s390_call_calculate_cc(), mkU8(4)))));
9343
9344 return "ipm";
9345}
9346
9347
9348static HChar *
9349s390_irgen_SRST(UChar r1, UChar r2)
9350{
9351 IRTemp address = newTemp(Ity_I64);
9352 IRTemp next = newTemp(Ity_I64);
9353 IRTemp delim = newTemp(Ity_I8);
9354 IRTemp counter = newTemp(Ity_I64);
9355 IRTemp byte = newTemp(Ity_I8);
9356
9357 assign(address, get_gpr_dw0(r2));
9358 assign(next, get_gpr_dw0(r1));
9359
9360 assign(counter, get_counter_dw0());
9361 put_counter_dw0(mkU64(0));
9362
9363 // start = next? CC=2 and out r1 and r2 unchanged
9364 s390_cc_set(2);
9365 put_gpr_dw0(r2, binop(Iop_Sub64, mkexpr(address), mkexpr(counter)));
florian6820ba52012-07-26 02:01:50 +00009366 next_insn_if(binop(Iop_CmpEQ64, mkexpr(address), mkexpr(next)));
sewardj2019a972011-03-07 16:04:07 +00009367
9368 assign(byte, load(Ity_I8, mkexpr(address)));
9369 assign(delim, get_gpr_b7(0));
9370
9371 // byte = delim? CC=1, R1=address
9372 s390_cc_set(1);
9373 put_gpr_dw0(r1, mkexpr(address));
florian6820ba52012-07-26 02:01:50 +00009374 next_insn_if(binop(Iop_CmpEQ8, mkexpr(delim), mkexpr(byte)));
sewardj2019a972011-03-07 16:04:07 +00009375
9376 // else: all equal, no end yet, loop
9377 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
9378 put_gpr_dw0(r1, mkexpr(next));
9379 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(address), mkU64(1)));
floriancf87c942012-07-25 00:52:21 +00009380
florian6820ba52012-07-26 02:01:50 +00009381 iterate();
sewardj2019a972011-03-07 16:04:07 +00009382
9383 return "srst";
9384}
9385
9386static HChar *
9387s390_irgen_CLST(UChar r1, UChar r2)
9388{
9389 IRTemp address1 = newTemp(Ity_I64);
9390 IRTemp address2 = newTemp(Ity_I64);
9391 IRTemp end = newTemp(Ity_I8);
9392 IRTemp counter = newTemp(Ity_I64);
9393 IRTemp byte1 = newTemp(Ity_I8);
9394 IRTemp byte2 = newTemp(Ity_I8);
9395
9396 assign(address1, get_gpr_dw0(r1));
9397 assign(address2, get_gpr_dw0(r2));
9398 assign(end, get_gpr_b7(0));
9399 assign(counter, get_counter_dw0());
9400 put_counter_dw0(mkU64(0));
9401 assign(byte1, load(Ity_I8, mkexpr(address1)));
9402 assign(byte2, load(Ity_I8, mkexpr(address2)));
9403
9404 // end in both? all equal, reset r1 and r2 to start values
9405 s390_cc_set(0);
9406 put_gpr_dw0(r1, binop(Iop_Sub64, mkexpr(address1), mkexpr(counter)));
9407 put_gpr_dw0(r2, binop(Iop_Sub64, mkexpr(address2), mkexpr(counter)));
florian6820ba52012-07-26 02:01:50 +00009408 next_insn_if(binop(Iop_CmpEQ8, mkU8(0),
9409 binop(Iop_Or8,
9410 binop(Iop_Xor8, mkexpr(byte1), mkexpr(end)),
9411 binop(Iop_Xor8, mkexpr(byte2), mkexpr(end)))));
sewardj2019a972011-03-07 16:04:07 +00009412
9413 put_gpr_dw0(r1, mkexpr(address1));
9414 put_gpr_dw0(r2, mkexpr(address2));
9415
9416 // End found in string1
9417 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +00009418 next_insn_if(binop(Iop_CmpEQ8, mkexpr(end), mkexpr(byte1)));
sewardj2019a972011-03-07 16:04:07 +00009419
9420 // End found in string2
9421 s390_cc_set(2);
florian6820ba52012-07-26 02:01:50 +00009422 next_insn_if(binop(Iop_CmpEQ8, mkexpr(end), mkexpr(byte2)));
sewardj2019a972011-03-07 16:04:07 +00009423
9424 // string1 < string2
9425 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +00009426 next_insn_if(binop(Iop_CmpLT32U, unop(Iop_8Uto32, mkexpr(byte1)),
9427 unop(Iop_8Uto32, mkexpr(byte2))));
sewardj2019a972011-03-07 16:04:07 +00009428
9429 // string2 < string1
9430 s390_cc_set(2);
florian6820ba52012-07-26 02:01:50 +00009431 next_insn_if(binop(Iop_CmpLT32U, unop(Iop_8Uto32, mkexpr(byte2)),
9432 unop(Iop_8Uto32, mkexpr(byte1))));
sewardj2019a972011-03-07 16:04:07 +00009433
9434 // else: all equal, no end yet, loop
9435 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
9436 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), mkU64(1)));
9437 put_gpr_dw0(r2, binop(Iop_Add64, get_gpr_dw0(r2), mkU64(1)));
floriancf87c942012-07-25 00:52:21 +00009438
florian6820ba52012-07-26 02:01:50 +00009439 iterate();
sewardj2019a972011-03-07 16:04:07 +00009440
9441 return "clst";
9442}
9443
9444static void
9445s390_irgen_load_multiple_32bit(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_w1(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
9463static HChar *
9464s390_irgen_LM(UChar r1, UChar r3, IRTemp op2addr)
9465{
9466 s390_irgen_load_multiple_32bit(r1, r3, op2addr);
9467
9468 return "lm";
9469}
9470
9471static HChar *
9472s390_irgen_LMY(UChar r1, UChar r3, IRTemp op2addr)
9473{
9474 s390_irgen_load_multiple_32bit(r1, r3, op2addr);
9475
9476 return "lmy";
9477}
9478
9479static HChar *
9480s390_irgen_LMH(UChar r1, UChar r3, IRTemp op2addr)
9481{
9482 UChar reg;
9483 IRTemp addr = newTemp(Ity_I64);
9484
9485 assign(addr, mkexpr(op2addr));
9486 reg = r1;
9487 do {
9488 IRTemp old = addr;
9489
9490 reg %= 16;
9491 put_gpr_w0(reg, load(Ity_I32, mkexpr(addr)));
9492 addr = newTemp(Ity_I64);
9493 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
9494 reg++;
9495 } while (reg != (r3 + 1));
9496
9497 return "lmh";
9498}
9499
9500static HChar *
9501s390_irgen_LMG(UChar r1, UChar r3, IRTemp op2addr)
9502{
9503 UChar reg;
9504 IRTemp addr = newTemp(Ity_I64);
9505
9506 assign(addr, mkexpr(op2addr));
9507 reg = r1;
9508 do {
9509 IRTemp old = addr;
9510
9511 reg %= 16;
9512 put_gpr_dw0(reg, load(Ity_I64, mkexpr(addr)));
9513 addr = newTemp(Ity_I64);
9514 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(8)));
9515 reg++;
9516 } while (reg != (r3 + 1));
9517
9518 return "lmg";
9519}
9520
9521static void
9522s390_irgen_store_multiple_32bit(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_w1(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
9540static HChar *
9541s390_irgen_STM(UChar r1, UChar r3, IRTemp op2addr)
9542{
9543 s390_irgen_store_multiple_32bit(r1, r3, op2addr);
9544
9545 return "stm";
9546}
9547
9548static HChar *
9549s390_irgen_STMY(UChar r1, UChar r3, IRTemp op2addr)
9550{
9551 s390_irgen_store_multiple_32bit(r1, r3, op2addr);
9552
9553 return "stmy";
9554}
9555
9556static HChar *
9557s390_irgen_STMH(UChar r1, UChar r3, IRTemp op2addr)
9558{
9559 UChar reg;
9560 IRTemp addr = newTemp(Ity_I64);
9561
9562 assign(addr, mkexpr(op2addr));
9563 reg = r1;
9564 do {
9565 IRTemp old = addr;
9566
9567 reg %= 16;
9568 store(mkexpr(addr), get_gpr_w0(reg));
9569 addr = newTemp(Ity_I64);
9570 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
9571 reg++;
9572 } while( reg != (r3 + 1));
9573
9574 return "stmh";
9575}
9576
9577static HChar *
9578s390_irgen_STMG(UChar r1, UChar r3, IRTemp op2addr)
9579{
9580 UChar reg;
9581 IRTemp addr = newTemp(Ity_I64);
9582
9583 assign(addr, mkexpr(op2addr));
9584 reg = r1;
9585 do {
9586 IRTemp old = addr;
9587
9588 reg %= 16;
9589 store(mkexpr(addr), get_gpr_dw0(reg));
9590 addr = newTemp(Ity_I64);
9591 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(8)));
9592 reg++;
9593 } while( reg != (r3 + 1));
9594
9595 return "stmg";
9596}
9597
9598static void
florianb0bf6602012-05-05 00:01:16 +00009599s390_irgen_xonc(IROp op, IRTemp length, IRTemp start1, IRTemp start2)
sewardj2019a972011-03-07 16:04:07 +00009600{
9601 IRTemp old1 = newTemp(Ity_I8);
9602 IRTemp old2 = newTemp(Ity_I8);
9603 IRTemp new1 = newTemp(Ity_I8);
9604 IRTemp counter = newTemp(Ity_I32);
9605 IRTemp addr1 = newTemp(Ity_I64);
9606
9607 assign(counter, get_counter_w0());
9608
9609 assign(addr1, binop(Iop_Add64, mkexpr(start1),
9610 unop(Iop_32Uto64, mkexpr(counter))));
9611
9612 assign(old1, load(Ity_I8, mkexpr(addr1)));
9613 assign(old2, load(Ity_I8, binop(Iop_Add64, mkexpr(start2),
9614 unop(Iop_32Uto64,mkexpr(counter)))));
9615 assign(new1, binop(op, mkexpr(old1), mkexpr(old2)));
9616
9617 /* Special case: xc is used to zero memory */
sewardj2019a972011-03-07 16:04:07 +00009618 if (op == Iop_Xor8) {
9619 store(mkexpr(addr1),
florian6ad49522011-09-09 02:38:55 +00009620 mkite(binop(Iop_CmpEQ64, mkexpr(start1), mkexpr(start2)),
9621 mkU8(0), mkexpr(new1)));
sewardj2019a972011-03-07 16:04:07 +00009622 } else
9623 store(mkexpr(addr1), mkexpr(new1));
9624 put_counter_w1(binop(Iop_Or32, unop(Iop_8Uto32, mkexpr(new1)),
9625 get_counter_w1()));
9626
9627 /* Check for end of field */
9628 put_counter_w0(binop(Iop_Add32, mkexpr(counter), mkU32(1)));
florian6820ba52012-07-26 02:01:50 +00009629 iterate_if(binop(Iop_CmpNE32, mkexpr(counter), mkexpr(length)));
sewardj2019a972011-03-07 16:04:07 +00009630 s390_cc_thunk_put1(S390_CC_OP_BITWISE, mktemp(Ity_I32, get_counter_w1()),
9631 False);
9632 put_counter_dw0(mkU64(0));
9633}
9634
9635static HChar *
9636s390_irgen_XC(UChar length, IRTemp start1, IRTemp start2)
9637{
florianb0bf6602012-05-05 00:01:16 +00009638 IRTemp len = newTemp(Ity_I32);
9639
9640 assign(len, mkU32(length));
9641 s390_irgen_xonc(Iop_Xor8, len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +00009642
9643 return "xc";
9644}
9645
sewardjb63967e2011-03-24 08:50:04 +00009646static void
9647s390_irgen_XC_sameloc(UChar length, UChar b, UShort d)
9648{
9649 IRTemp counter = newTemp(Ity_I32);
9650 IRTemp start = newTemp(Ity_I64);
9651 IRTemp addr = newTemp(Ity_I64);
9652
9653 assign(start,
9654 binop(Iop_Add64, mkU64(d), b != 0 ? get_gpr_dw0(b) : mkU64(0)));
9655
9656 if (length < 8) {
9657 UInt i;
9658
9659 for (i = 0; i <= length; ++i) {
9660 store(binop(Iop_Add64, mkexpr(start), mkU64(i)), mkU8(0));
9661 }
9662 } else {
9663 assign(counter, get_counter_w0());
9664
9665 assign(addr, binop(Iop_Add64, mkexpr(start),
9666 unop(Iop_32Uto64, mkexpr(counter))));
9667
9668 store(mkexpr(addr), mkU8(0));
9669
9670 /* Check for end of field */
9671 put_counter_w0(binop(Iop_Add32, mkexpr(counter), mkU32(1)));
florian6820ba52012-07-26 02:01:50 +00009672 iterate_if(binop(Iop_CmpNE32, mkexpr(counter), mkU32(length)));
sewardjb63967e2011-03-24 08:50:04 +00009673
9674 /* Reset counter */
9675 put_counter_dw0(mkU64(0));
9676 }
9677
9678 s390_cc_thunk_put1(S390_CC_OP_BITWISE, mktemp(Ity_I32, mkU32(0)), False);
9679
sewardj7ee97522011-05-09 21:45:04 +00009680 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardjb63967e2011-03-24 08:50:04 +00009681 s390_disasm(ENC3(MNM, UDLB, UDXB), "xc", d, length, b, d, 0, b);
9682}
9683
sewardj2019a972011-03-07 16:04:07 +00009684static HChar *
9685s390_irgen_NC(UChar length, IRTemp start1, IRTemp start2)
9686{
florianb0bf6602012-05-05 00:01:16 +00009687 IRTemp len = newTemp(Ity_I32);
9688
9689 assign(len, mkU32(length));
9690 s390_irgen_xonc(Iop_And8, len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +00009691
9692 return "nc";
9693}
9694
9695static HChar *
9696s390_irgen_OC(UChar length, IRTemp start1, IRTemp start2)
9697{
florianb0bf6602012-05-05 00:01:16 +00009698 IRTemp len = newTemp(Ity_I32);
9699
9700 assign(len, mkU32(length));
9701 s390_irgen_xonc(Iop_Or8, len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +00009702
9703 return "oc";
9704}
9705
9706
9707static HChar *
9708s390_irgen_MVC(UChar length, IRTemp start1, IRTemp start2)
9709{
florian79e839e2012-05-05 02:20:30 +00009710 IRTemp len = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00009711
florian79e839e2012-05-05 02:20:30 +00009712 assign(len, mkU64(length));
9713 s390_irgen_MVC_EX(len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +00009714
9715 return "mvc";
9716}
9717
9718static HChar *
florianb0c9a132011-09-08 15:37:39 +00009719s390_irgen_MVCL(UChar r1, UChar r2)
9720{
9721 IRTemp addr1 = newTemp(Ity_I64);
9722 IRTemp addr2 = newTemp(Ity_I64);
9723 IRTemp addr2_load = newTemp(Ity_I64);
9724 IRTemp r1p1 = newTemp(Ity_I32); /* contents of r1 + 1 */
9725 IRTemp r2p1 = newTemp(Ity_I32); /* contents of r2 + 1 */
9726 IRTemp len1 = newTemp(Ity_I32);
9727 IRTemp len2 = newTemp(Ity_I32);
9728 IRTemp pad = newTemp(Ity_I8);
9729 IRTemp single = newTemp(Ity_I8);
9730
9731 assign(addr1, get_gpr_dw0(r1));
9732 assign(r1p1, get_gpr_w1(r1 + 1));
9733 assign(len1, binop(Iop_And32, mkexpr(r1p1), mkU32(0x00ffffff)));
9734 assign(addr2, get_gpr_dw0(r2));
9735 assign(r2p1, get_gpr_w1(r2 + 1));
9736 assign(len2, binop(Iop_And32, mkexpr(r2p1), mkU32(0x00ffffff)));
9737 assign(pad, get_gpr_b4(r2 + 1));
9738
9739 /* len1 == 0 ? */
9740 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len2, False);
florian6820ba52012-07-26 02:01:50 +00009741 next_insn_if(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)));
florianb0c9a132011-09-08 15:37:39 +00009742
9743 /* Check for destructive overlap:
9744 addr1 > addr2 && addr2 + len1 > addr1 && (addr2 + len2) > addr1 */
9745 s390_cc_set(3);
9746 IRTemp cond1 = newTemp(Ity_I32);
9747 assign(cond1, unop(Iop_1Uto32,
9748 binop(Iop_CmpLT64U, mkexpr(addr2), mkexpr(addr1))));
9749 IRTemp cond2 = newTemp(Ity_I32);
9750 assign(cond2, unop(Iop_1Uto32,
9751 binop(Iop_CmpLT64U, mkexpr(addr1),
9752 binop(Iop_Add64, mkexpr(addr2),
9753 unop(Iop_32Uto64, mkexpr(len1))))));
9754 IRTemp cond3 = newTemp(Ity_I32);
9755 assign(cond3, unop(Iop_1Uto32,
9756 binop(Iop_CmpLT64U,
9757 mkexpr(addr1),
9758 binop(Iop_Add64, mkexpr(addr2),
9759 unop(Iop_32Uto64, mkexpr(len2))))));
9760
florian6820ba52012-07-26 02:01:50 +00009761 next_insn_if(binop(Iop_CmpEQ32,
9762 binop(Iop_And32,
9763 binop(Iop_And32, mkexpr(cond1), mkexpr(cond2)),
9764 mkexpr(cond3)),
9765 mkU32(1)));
florianb0c9a132011-09-08 15:37:39 +00009766
9767 /* See s390_irgen_CLCL for explanation why we cannot load directly
9768 and need two steps. */
9769 assign(addr2_load,
9770 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
9771 mkU64(guest_IA_curr_instr), mkexpr(addr2)));
9772 assign(single,
9773 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
9774 mkexpr(pad), load(Ity_I8, mkexpr(addr2_load))));
9775
9776 store(mkexpr(addr1), mkexpr(single));
9777
9778 /* Update addr1 and len1 */
9779 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkU64(1)));
9780 put_gpr_w1(r1 + 1, binop(Iop_Sub32, mkexpr(r1p1), mkU32(1)));
9781
9782 /* Update addr2 and len2 */
9783 put_gpr_dw0(r2,
9784 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
9785 mkexpr(addr2),
9786 binop(Iop_Add64, mkexpr(addr2), mkU64(1))));
9787
9788 /* When updating len2 we must not modify bits (r2+1)[0:39] */
9789 put_gpr_w1(r2 + 1,
9790 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
9791 binop(Iop_And32, mkexpr(r2p1), mkU32(0xFF000000u)),
9792 binop(Iop_Sub32, mkexpr(r2p1), mkU32(1))));
9793
9794 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len2, False);
florian6820ba52012-07-26 02:01:50 +00009795 iterate_if(binop(Iop_CmpNE32, mkexpr(len1), mkU32(1)));
florianb0c9a132011-09-08 15:37:39 +00009796
9797 return "mvcl";
9798}
9799
9800
9801static HChar *
sewardj2019a972011-03-07 16:04:07 +00009802s390_irgen_MVCLE(UChar r1, UChar r3, IRTemp pad2)
9803{
9804 IRTemp addr1, addr3, addr3_load, len1, len3, single;
9805
9806 addr1 = newTemp(Ity_I64);
9807 addr3 = newTemp(Ity_I64);
9808 addr3_load = newTemp(Ity_I64);
9809 len1 = newTemp(Ity_I64);
9810 len3 = newTemp(Ity_I64);
9811 single = newTemp(Ity_I8);
9812
9813 assign(addr1, get_gpr_dw0(r1));
9814 assign(len1, get_gpr_dw0(r1 + 1));
9815 assign(addr3, get_gpr_dw0(r3));
9816 assign(len3, get_gpr_dw0(r3 + 1));
9817
9818 // len1 == 0 ?
9819 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len3, False);
florian6820ba52012-07-26 02:01:50 +00009820 next_insn_if(binop(Iop_CmpEQ64,mkexpr(len1), mkU64(0)));
sewardj2019a972011-03-07 16:04:07 +00009821
9822 /* This is a hack to prevent mvcle from reading from addr3 if it
9823 should read from the pad. Since the pad has no address, just
9824 read from the instruction, we discard that anyway */
9825 assign(addr3_load,
florian6ad49522011-09-09 02:38:55 +00009826 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
9827 mkU64(guest_IA_curr_instr), mkexpr(addr3)));
sewardj2019a972011-03-07 16:04:07 +00009828
9829 assign(single,
florian6ad49522011-09-09 02:38:55 +00009830 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
9831 unop(Iop_64to8, mkexpr(pad2)),
9832 load(Ity_I8, mkexpr(addr3_load))));
sewardj2019a972011-03-07 16:04:07 +00009833 store(mkexpr(addr1), mkexpr(single));
9834
9835 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkU64(1)));
9836
9837 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkU64(1)));
9838
9839 put_gpr_dw0(r3,
florian6ad49522011-09-09 02:38:55 +00009840 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
9841 mkexpr(addr3),
9842 binop(Iop_Add64, mkexpr(addr3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +00009843
9844 put_gpr_dw0(r3 + 1,
florian6ad49522011-09-09 02:38:55 +00009845 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
9846 mkU64(0), binop(Iop_Sub64, mkexpr(len3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +00009847
sewardj2019a972011-03-07 16:04:07 +00009848 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len3, False);
florian6820ba52012-07-26 02:01:50 +00009849 iterate_if(binop(Iop_CmpNE64, mkexpr(len1), mkU64(1)));
sewardj2019a972011-03-07 16:04:07 +00009850
9851 return "mvcle";
9852}
9853
9854static HChar *
9855s390_irgen_MVST(UChar r1, UChar r2)
9856{
9857 IRTemp addr1 = newTemp(Ity_I64);
9858 IRTemp addr2 = newTemp(Ity_I64);
9859 IRTemp end = newTemp(Ity_I8);
9860 IRTemp byte = newTemp(Ity_I8);
9861 IRTemp counter = newTemp(Ity_I64);
9862
9863 assign(addr1, get_gpr_dw0(r1));
9864 assign(addr2, get_gpr_dw0(r2));
9865 assign(counter, get_counter_dw0());
9866 assign(end, get_gpr_b7(0));
9867 assign(byte, load(Ity_I8, binop(Iop_Add64, mkexpr(addr2),mkexpr(counter))));
9868 store(binop(Iop_Add64,mkexpr(addr1),mkexpr(counter)), mkexpr(byte));
9869
9870 // We use unlimited as cpu-determined number
9871 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
florian6820ba52012-07-26 02:01:50 +00009872 iterate_if(binop(Iop_CmpNE8, mkexpr(end), mkexpr(byte)));
sewardj2019a972011-03-07 16:04:07 +00009873
9874 // and always set cc=1 at the end + update r1
9875 s390_cc_set(1);
9876 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(counter)));
9877 put_counter_dw0(mkU64(0));
9878
9879 return "mvst";
9880}
9881
9882static void
9883s390_irgen_divide_64to32(IROp op, UChar r1, IRTemp op2)
9884{
9885 IRTemp op1 = newTemp(Ity_I64);
9886 IRTemp result = newTemp(Ity_I64);
9887
9888 assign(op1, binop(Iop_32HLto64,
9889 get_gpr_w1(r1), // high 32 bits
9890 get_gpr_w1(r1 + 1))); // low 32 bits
9891 assign(result, binop(op, mkexpr(op1), mkexpr(op2)));
9892 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result))); // remainder
9893 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result))); // quotient
9894}
9895
9896static void
9897s390_irgen_divide_128to64(IROp op, UChar r1, IRTemp op2)
9898{
9899 IRTemp op1 = newTemp(Ity_I128);
9900 IRTemp result = newTemp(Ity_I128);
9901
9902 assign(op1, binop(Iop_64HLto128,
9903 get_gpr_dw0(r1), // high 64 bits
9904 get_gpr_dw0(r1 + 1))); // low 64 bits
9905 assign(result, binop(op, mkexpr(op1), mkexpr(op2)));
9906 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result))); // remainder
9907 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result))); // quotient
9908}
9909
9910static void
9911s390_irgen_divide_64to64(IROp op, UChar r1, IRTemp op2)
9912{
9913 IRTemp op1 = newTemp(Ity_I64);
9914 IRTemp result = newTemp(Ity_I128);
9915
9916 assign(op1, get_gpr_dw0(r1 + 1));
9917 assign(result, binop(op, mkexpr(op1), mkexpr(op2)));
9918 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result))); // remainder
9919 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result))); // quotient
9920}
9921
9922static HChar *
9923s390_irgen_DR(UChar r1, UChar r2)
9924{
9925 IRTemp op2 = newTemp(Ity_I32);
9926
9927 assign(op2, get_gpr_w1(r2));
9928
9929 s390_irgen_divide_64to32(Iop_DivModS64to32, r1, op2);
9930
9931 return "dr";
9932}
9933
9934static HChar *
9935s390_irgen_D(UChar r1, IRTemp op2addr)
9936{
9937 IRTemp op2 = newTemp(Ity_I32);
9938
9939 assign(op2, load(Ity_I32, mkexpr(op2addr)));
9940
9941 s390_irgen_divide_64to32(Iop_DivModS64to32, r1, op2);
9942
9943 return "d";
9944}
9945
9946static HChar *
9947s390_irgen_DLR(UChar r1, UChar r2)
9948{
9949 IRTemp op2 = newTemp(Ity_I32);
9950
9951 assign(op2, get_gpr_w1(r2));
9952
9953 s390_irgen_divide_64to32(Iop_DivModU64to32, r1, op2);
9954
florian7cd1cde2012-08-16 23:57:43 +00009955 return "dlr";
sewardj2019a972011-03-07 16:04:07 +00009956}
9957
9958static HChar *
9959s390_irgen_DL(UChar r1, IRTemp op2addr)
9960{
9961 IRTemp op2 = newTemp(Ity_I32);
9962
9963 assign(op2, load(Ity_I32, mkexpr(op2addr)));
9964
9965 s390_irgen_divide_64to32(Iop_DivModU64to32, r1, op2);
9966
9967 return "dl";
9968}
9969
9970static HChar *
9971s390_irgen_DLG(UChar r1, IRTemp op2addr)
9972{
9973 IRTemp op2 = newTemp(Ity_I64);
9974
9975 assign(op2, load(Ity_I64, mkexpr(op2addr)));
9976
9977 s390_irgen_divide_128to64(Iop_DivModU128to64, r1, op2);
9978
9979 return "dlg";
9980}
9981
9982static HChar *
9983s390_irgen_DLGR(UChar r1, UChar r2)
9984{
9985 IRTemp op2 = newTemp(Ity_I64);
9986
9987 assign(op2, get_gpr_dw0(r2));
9988
9989 s390_irgen_divide_128to64(Iop_DivModU128to64, r1, op2);
9990
9991 return "dlgr";
9992}
9993
9994static HChar *
9995s390_irgen_DSGR(UChar r1, UChar r2)
9996{
9997 IRTemp op2 = newTemp(Ity_I64);
9998
9999 assign(op2, get_gpr_dw0(r2));
10000
10001 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
10002
10003 return "dsgr";
10004}
10005
10006static HChar *
10007s390_irgen_DSG(UChar r1, IRTemp op2addr)
10008{
10009 IRTemp op2 = newTemp(Ity_I64);
10010
10011 assign(op2, load(Ity_I64, mkexpr(op2addr)));
10012
10013 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
10014
10015 return "dsg";
10016}
10017
10018static HChar *
10019s390_irgen_DSGFR(UChar r1, UChar r2)
10020{
10021 IRTemp op2 = newTemp(Ity_I64);
10022
10023 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
10024
10025 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
10026
10027 return "dsgfr";
10028}
10029
10030static HChar *
10031s390_irgen_DSGF(UChar r1, IRTemp op2addr)
10032{
10033 IRTemp op2 = newTemp(Ity_I64);
10034
10035 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
10036
10037 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
10038
10039 return "dsgf";
10040}
10041
10042static void
10043s390_irgen_load_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 put_ar_w0(reg, load(Ity_I32, mkexpr(addr)));
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_LAM(UChar r1, UChar r3, IRTemp op2addr)
10063{
10064 s390_irgen_load_ar_multiple(r1, r3, op2addr);
10065
10066 return "lam";
10067}
10068
10069static HChar *
10070s390_irgen_LAMY(UChar r1, UChar r3, IRTemp op2addr)
10071{
10072 s390_irgen_load_ar_multiple(r1, r3, op2addr);
10073
10074 return "lamy";
10075}
10076
10077static void
10078s390_irgen_store_ar_multiple(UChar r1, UChar r3, IRTemp op2addr)
10079{
10080 UChar reg;
10081 IRTemp addr = newTemp(Ity_I64);
10082
10083 assign(addr, mkexpr(op2addr));
10084 reg = r1;
10085 do {
10086 IRTemp old = addr;
10087
10088 reg %= 16;
10089 store(mkexpr(addr), get_ar_w0(reg));
10090 addr = newTemp(Ity_I64);
10091 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
10092 reg++;
10093 } while (reg != (r3 + 1));
10094}
10095
10096static HChar *
10097s390_irgen_STAM(UChar r1, UChar r3, IRTemp op2addr)
10098{
10099 s390_irgen_store_ar_multiple(r1, r3, op2addr);
10100
10101 return "stam";
10102}
10103
10104static HChar *
10105s390_irgen_STAMY(UChar r1, UChar r3, IRTemp op2addr)
10106{
10107 s390_irgen_store_ar_multiple(r1, r3, op2addr);
10108
10109 return "stamy";
10110}
10111
10112
10113/* Implementation for 32-bit compare-and-swap */
10114static void
10115s390_irgen_cas_32(UChar r1, UChar r3, IRTemp op2addr)
10116{
10117 IRCAS *cas;
10118 IRTemp op1 = newTemp(Ity_I32);
10119 IRTemp old_mem = newTemp(Ity_I32);
10120 IRTemp op3 = newTemp(Ity_I32);
10121 IRTemp result = newTemp(Ity_I32);
10122 IRTemp nequal = newTemp(Ity_I1);
10123
10124 assign(op1, get_gpr_w1(r1));
10125 assign(op3, get_gpr_w1(r3));
10126
10127 /* The first and second operands are compared. If they are equal,
10128 the third operand is stored at the second- operand location. */
10129 cas = mkIRCAS(IRTemp_INVALID, old_mem,
10130 Iend_BE, mkexpr(op2addr),
10131 NULL, mkexpr(op1), /* expected value */
10132 NULL, mkexpr(op3) /* new value */);
10133 stmt(IRStmt_CAS(cas));
10134
10135 /* Set CC. Operands compared equal -> 0, else 1. */
10136 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(old_mem)));
10137 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
10138
10139 /* If operands were equal (cc == 0) just store the old value op1 in r1.
10140 Otherwise, store the old_value from memory in r1 and yield. */
10141 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
10142 put_gpr_w1(r1, mkite(mkexpr(nequal), mkexpr(old_mem), mkexpr(op1)));
florian6820ba52012-07-26 02:01:50 +000010143 yield_if(mkexpr(nequal));
sewardj2019a972011-03-07 16:04:07 +000010144}
10145
10146static HChar *
10147s390_irgen_CS(UChar r1, UChar r3, IRTemp op2addr)
10148{
10149 s390_irgen_cas_32(r1, r3, op2addr);
10150
10151 return "cs";
10152}
10153
10154static HChar *
10155s390_irgen_CSY(UChar r1, UChar r3, IRTemp op2addr)
10156{
10157 s390_irgen_cas_32(r1, r3, op2addr);
10158
10159 return "csy";
10160}
10161
10162static HChar *
10163s390_irgen_CSG(UChar r1, UChar r3, IRTemp op2addr)
10164{
10165 IRCAS *cas;
10166 IRTemp op1 = newTemp(Ity_I64);
10167 IRTemp old_mem = newTemp(Ity_I64);
10168 IRTemp op3 = newTemp(Ity_I64);
10169 IRTemp result = newTemp(Ity_I64);
10170 IRTemp nequal = newTemp(Ity_I1);
10171
10172 assign(op1, get_gpr_dw0(r1));
10173 assign(op3, get_gpr_dw0(r3));
10174
10175 /* The first and second operands are compared. If they are equal,
10176 the third operand is stored at the second- operand location. */
10177 cas = mkIRCAS(IRTemp_INVALID, old_mem,
10178 Iend_BE, mkexpr(op2addr),
10179 NULL, mkexpr(op1), /* expected value */
10180 NULL, mkexpr(op3) /* new value */);
10181 stmt(IRStmt_CAS(cas));
10182
10183 /* Set CC. Operands compared equal -> 0, else 1. */
10184 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(old_mem)));
10185 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
10186
10187 /* If operands were equal (cc == 0) just store the old value op1 in r1.
10188 Otherwise, store the old_value from memory in r1 and yield. */
10189 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
10190 put_gpr_dw0(r1, mkite(mkexpr(nequal), mkexpr(old_mem), mkexpr(op1)));
florian6820ba52012-07-26 02:01:50 +000010191 yield_if(mkexpr(nequal));
sewardj2019a972011-03-07 16:04:07 +000010192
10193 return "csg";
10194}
10195
florian448cbba2012-06-06 02:26:01 +000010196/* Implementation for 32-bit compare-double-and-swap */
10197static void
10198s390_irgen_cdas_32(UChar r1, UChar r3, IRTemp op2addr)
10199{
10200 IRCAS *cas;
10201 IRTemp op1_high = newTemp(Ity_I32);
10202 IRTemp op1_low = newTemp(Ity_I32);
10203 IRTemp old_mem_high = newTemp(Ity_I32);
10204 IRTemp old_mem_low = newTemp(Ity_I32);
10205 IRTemp op3_high = newTemp(Ity_I32);
10206 IRTemp op3_low = newTemp(Ity_I32);
10207 IRTemp result = newTemp(Ity_I32);
10208 IRTemp nequal = newTemp(Ity_I1);
10209
10210 assign(op1_high, get_gpr_w1(r1));
10211 assign(op1_low, get_gpr_w1(r1+1));
10212 assign(op3_high, get_gpr_w1(r3));
10213 assign(op3_low, get_gpr_w1(r3+1));
10214
10215 /* The first and second operands are compared. If they are equal,
10216 the third operand is stored at the second-operand location. */
10217 cas = mkIRCAS(old_mem_high, old_mem_low,
10218 Iend_BE, mkexpr(op2addr),
10219 mkexpr(op1_high), mkexpr(op1_low), /* expected value */
10220 mkexpr(op3_high), mkexpr(op3_low) /* new value */);
10221 stmt(IRStmt_CAS(cas));
10222
10223 /* Set CC. Operands compared equal -> 0, else 1. */
10224 assign(result, unop(Iop_1Uto32,
10225 binop(Iop_CmpNE32,
10226 binop(Iop_Or32,
10227 binop(Iop_Xor32, mkexpr(op1_high), mkexpr(old_mem_high)),
10228 binop(Iop_Xor32, mkexpr(op1_low), mkexpr(old_mem_low))),
10229 mkU32(0))));
10230
10231 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
10232
10233 /* If operands were equal (cc == 0) just store the old value op1 in r1.
10234 Otherwise, store the old_value from memory in r1 and yield. */
10235 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
10236 put_gpr_w1(r1, mkite(mkexpr(nequal), mkexpr(old_mem_high), mkexpr(op1_high)));
10237 put_gpr_w1(r1+1, mkite(mkexpr(nequal), mkexpr(old_mem_low), mkexpr(op1_low)));
florian6820ba52012-07-26 02:01:50 +000010238 yield_if(mkexpr(nequal));
florian448cbba2012-06-06 02:26:01 +000010239}
10240
10241static HChar *
10242s390_irgen_CDS(UChar r1, UChar r3, IRTemp op2addr)
10243{
10244 s390_irgen_cdas_32(r1, r3, op2addr);
10245
10246 return "cds";
10247}
10248
10249static HChar *
10250s390_irgen_CDSY(UChar r1, UChar r3, IRTemp op2addr)
10251{
10252 s390_irgen_cdas_32(r1, r3, op2addr);
10253
10254 return "cdsy";
10255}
10256
10257static HChar *
10258s390_irgen_CDSG(UChar r1, UChar r3, IRTemp op2addr)
10259{
10260 IRCAS *cas;
10261 IRTemp op1_high = newTemp(Ity_I64);
10262 IRTemp op1_low = newTemp(Ity_I64);
10263 IRTemp old_mem_high = newTemp(Ity_I64);
10264 IRTemp old_mem_low = newTemp(Ity_I64);
10265 IRTemp op3_high = newTemp(Ity_I64);
10266 IRTemp op3_low = newTemp(Ity_I64);
10267 IRTemp result = newTemp(Ity_I64);
10268 IRTemp nequal = newTemp(Ity_I1);
10269
10270 assign(op1_high, get_gpr_dw0(r1));
10271 assign(op1_low, get_gpr_dw0(r1+1));
10272 assign(op3_high, get_gpr_dw0(r3));
10273 assign(op3_low, get_gpr_dw0(r3+1));
10274
10275 /* The first and second operands are compared. If they are equal,
10276 the third operand is stored at the second-operand location. */
10277 cas = mkIRCAS(old_mem_high, old_mem_low,
10278 Iend_BE, mkexpr(op2addr),
10279 mkexpr(op1_high), mkexpr(op1_low), /* expected value */
10280 mkexpr(op3_high), mkexpr(op3_low) /* new value */);
10281 stmt(IRStmt_CAS(cas));
10282
10283 /* Set CC. Operands compared equal -> 0, else 1. */
10284 assign(result, unop(Iop_1Uto64,
10285 binop(Iop_CmpNE64,
10286 binop(Iop_Or64,
10287 binop(Iop_Xor64, mkexpr(op1_high), mkexpr(old_mem_high)),
10288 binop(Iop_Xor64, mkexpr(op1_low), mkexpr(old_mem_low))),
10289 mkU64(0))));
10290
10291 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
10292
10293 /* If operands were equal (cc == 0) just store the old value op1 in r1.
10294 Otherwise, store the old_value from memory in r1 and yield. */
10295 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
10296 put_gpr_dw0(r1, mkite(mkexpr(nequal), mkexpr(old_mem_high), mkexpr(op1_high)));
10297 put_gpr_dw0(r1+1, mkite(mkexpr(nequal), mkexpr(old_mem_low), mkexpr(op1_low)));
florian6820ba52012-07-26 02:01:50 +000010298 yield_if(mkexpr(nequal));
10299
florian448cbba2012-06-06 02:26:01 +000010300 return "cdsg";
10301}
10302
sewardj2019a972011-03-07 16:04:07 +000010303
10304/* Binary floating point */
10305
10306static HChar *
10307s390_irgen_AXBR(UChar r1, UChar r2)
10308{
10309 IRTemp op1 = newTemp(Ity_F128);
10310 IRTemp op2 = newTemp(Ity_F128);
10311 IRTemp result = newTemp(Ity_F128);
floriandb4fcaa2012-09-05 19:54:08 +000010312 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000010313
10314 assign(op1, get_fpr_pair(r1));
10315 assign(op2, get_fpr_pair(r2));
floriandb4fcaa2012-09-05 19:54:08 +000010316 assign(result, triop(Iop_AddF128, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +000010317 mkexpr(op2)));
10318 put_fpr_pair(r1, mkexpr(result));
10319
10320 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
10321
10322 return "axbr";
10323}
10324
10325/* The result of a Iop_CmdFxx operation is a condition code. It is
10326 encoded using the values defined in type IRCmpFxxResult.
10327 Before we can store the condition code into the guest state (or do
10328 anything else with it for that matter) we need to convert it to
10329 the encoding that s390 uses. This is what this function does.
10330
10331 s390 VEX b6 b2 b0 cc.1 cc.0
10332 0 0x40 EQ 1 0 0 0 0
10333 1 0x01 LT 0 0 1 0 1
10334 2 0x00 GT 0 0 0 1 0
10335 3 0x45 Unordered 1 1 1 1 1
10336
10337 The following bits from the VEX encoding are interesting:
10338 b0, b2, b6 with b0 being the LSB. We observe:
10339
10340 cc.0 = b0;
10341 cc.1 = b2 | (~b0 & ~b6)
10342
10343 with cc being the s390 condition code.
10344*/
10345static IRExpr *
10346convert_vex_fpcc_to_s390(IRTemp vex_cc)
10347{
10348 IRTemp cc0 = newTemp(Ity_I32);
10349 IRTemp cc1 = newTemp(Ity_I32);
10350 IRTemp b0 = newTemp(Ity_I32);
10351 IRTemp b2 = newTemp(Ity_I32);
10352 IRTemp b6 = newTemp(Ity_I32);
10353
10354 assign(b0, binop(Iop_And32, mkexpr(vex_cc), mkU32(1)));
10355 assign(b2, binop(Iop_And32, binop(Iop_Shr32, mkexpr(vex_cc), mkU8(2)),
10356 mkU32(1)));
10357 assign(b6, binop(Iop_And32, binop(Iop_Shr32, mkexpr(vex_cc), mkU8(6)),
10358 mkU32(1)));
10359
10360 assign(cc0, mkexpr(b0));
10361 assign(cc1, binop(Iop_Or32, mkexpr(b2),
10362 binop(Iop_And32,
10363 binop(Iop_Sub32, mkU32(1), mkexpr(b0)), /* ~b0 */
10364 binop(Iop_Sub32, mkU32(1), mkexpr(b6)) /* ~b6 */
10365 )));
10366
10367 return binop(Iop_Or32, mkexpr(cc0), binop(Iop_Shl32, mkexpr(cc1), mkU8(1)));
10368}
10369
10370static HChar *
10371s390_irgen_CEBR(UChar r1, UChar r2)
10372{
10373 IRTemp op1 = newTemp(Ity_F32);
10374 IRTemp op2 = newTemp(Ity_F32);
10375 IRTemp cc_vex = newTemp(Ity_I32);
10376 IRTemp cc_s390 = newTemp(Ity_I32);
10377
10378 assign(op1, get_fpr_w0(r1));
10379 assign(op2, get_fpr_w0(r2));
10380 assign(cc_vex, binop(Iop_CmpF32, mkexpr(op1), mkexpr(op2)));
10381
10382 assign(cc_s390, convert_vex_fpcc_to_s390(cc_vex));
10383 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
10384
10385 return "cebr";
10386}
10387
10388static HChar *
10389s390_irgen_CDBR(UChar r1, UChar r2)
10390{
10391 IRTemp op1 = newTemp(Ity_F64);
10392 IRTemp op2 = newTemp(Ity_F64);
10393 IRTemp cc_vex = newTemp(Ity_I32);
10394 IRTemp cc_s390 = newTemp(Ity_I32);
10395
10396 assign(op1, get_fpr_dw0(r1));
10397 assign(op2, get_fpr_dw0(r2));
10398 assign(cc_vex, binop(Iop_CmpF64, mkexpr(op1), mkexpr(op2)));
10399
10400 assign(cc_s390, convert_vex_fpcc_to_s390(cc_vex));
10401 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
10402
10403 return "cdbr";
10404}
10405
10406static HChar *
10407s390_irgen_CXBR(UChar r1, UChar r2)
10408{
10409 IRTemp op1 = newTemp(Ity_F128);
10410 IRTemp op2 = newTemp(Ity_F128);
10411 IRTemp cc_vex = newTemp(Ity_I32);
10412 IRTemp cc_s390 = newTemp(Ity_I32);
10413
10414 assign(op1, get_fpr_pair(r1));
10415 assign(op2, get_fpr_pair(r2));
10416 assign(cc_vex, binop(Iop_CmpF128, mkexpr(op1), mkexpr(op2)));
10417
10418 assign(cc_s390, convert_vex_fpcc_to_s390(cc_vex));
10419 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
10420
10421 return "cxbr";
10422}
10423
10424static HChar *
10425s390_irgen_CEB(UChar r1, IRTemp op2addr)
10426{
10427 IRTemp op1 = newTemp(Ity_F32);
10428 IRTemp op2 = newTemp(Ity_F32);
10429 IRTemp cc_vex = newTemp(Ity_I32);
10430 IRTemp cc_s390 = newTemp(Ity_I32);
10431
10432 assign(op1, get_fpr_w0(r1));
10433 assign(op2, load(Ity_F32, mkexpr(op2addr)));
10434 assign(cc_vex, binop(Iop_CmpF32, mkexpr(op1), mkexpr(op2)));
10435
10436 assign(cc_s390, convert_vex_fpcc_to_s390(cc_vex));
10437 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
10438
10439 return "ceb";
10440}
10441
10442static HChar *
10443s390_irgen_CDB(UChar r1, IRTemp op2addr)
10444{
10445 IRTemp op1 = newTemp(Ity_F64);
10446 IRTemp op2 = newTemp(Ity_F64);
10447 IRTemp cc_vex = newTemp(Ity_I32);
10448 IRTemp cc_s390 = newTemp(Ity_I32);
10449
10450 assign(op1, get_fpr_dw0(r1));
10451 assign(op2, load(Ity_F64, mkexpr(op2addr)));
10452 assign(cc_vex, binop(Iop_CmpF64, mkexpr(op1), mkexpr(op2)));
10453
10454 assign(cc_s390, convert_vex_fpcc_to_s390(cc_vex));
10455 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
10456
10457 return "cdb";
10458}
10459
10460static HChar *
florian4b8efad2012-09-02 18:07:08 +000010461s390_irgen_CXFBR(UChar m3 __attribute__((unused)),
10462 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000010463{
10464 IRTemp op2 = newTemp(Ity_I32);
10465
10466 assign(op2, get_gpr_w1(r2));
10467 put_fpr_pair(r1, unop(Iop_I32StoF128, mkexpr(op2)));
10468
10469 return "cxfbr";
10470}
10471
10472static HChar *
floriand2129202012-09-01 20:01:39 +000010473s390_irgen_CXLFBR(UChar m3 __attribute__((unused)),
10474 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
florian1c8f7ff2012-09-01 00:12:11 +000010475{
floriane75dafa2012-09-01 17:54:09 +000010476 if (! s390_host_has_fpext) {
10477 emulation_failure(EmFail_S390X_fpext);
10478 } else {
10479 IRTemp op2 = newTemp(Ity_I32);
florian1c8f7ff2012-09-01 00:12:11 +000010480
floriane75dafa2012-09-01 17:54:09 +000010481 assign(op2, get_gpr_w1(r2));
10482 put_fpr_pair(r1, unop(Iop_I32UtoF128, mkexpr(op2)));
10483 }
florian1c8f7ff2012-09-01 00:12:11 +000010484 return "cxlfbr";
10485}
10486
10487
10488static HChar *
florian4b8efad2012-09-02 18:07:08 +000010489s390_irgen_CXGBR(UChar m3 __attribute__((unused)),
10490 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000010491{
10492 IRTemp op2 = newTemp(Ity_I64);
10493
10494 assign(op2, get_gpr_dw0(r2));
10495 put_fpr_pair(r1, unop(Iop_I64StoF128, mkexpr(op2)));
10496
10497 return "cxgbr";
10498}
10499
10500static HChar *
floriand2129202012-09-01 20:01:39 +000010501s390_irgen_CXLGBR(UChar m3 __attribute__((unused)),
10502 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
florian1c8f7ff2012-09-01 00:12:11 +000010503{
floriane75dafa2012-09-01 17:54:09 +000010504 if (! s390_host_has_fpext) {
10505 emulation_failure(EmFail_S390X_fpext);
10506 } else {
10507 IRTemp op2 = newTemp(Ity_I64);
florian1c8f7ff2012-09-01 00:12:11 +000010508
floriane75dafa2012-09-01 17:54:09 +000010509 assign(op2, get_gpr_dw0(r2));
10510 put_fpr_pair(r1, unop(Iop_I64UtoF128, mkexpr(op2)));
10511 }
florian1c8f7ff2012-09-01 00:12:11 +000010512 return "cxlgbr";
10513}
10514
10515static HChar *
florian4b8efad2012-09-02 18:07:08 +000010516s390_irgen_CFXBR(UChar m3, UChar m4 __attribute__((unused)),
10517 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000010518{
10519 IRTemp op = newTemp(Ity_F128);
10520 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +000010521 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +000010522
10523 assign(op, get_fpr_pair(r2));
florian19e00772012-09-06 03:13:22 +000010524 assign(result, binop(Iop_F128toI32S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +000010525 mkexpr(op)));
10526 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +000010527 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_INT_32, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +000010528
10529 return "cfxbr";
10530}
10531
10532static HChar *
florian1c8f7ff2012-09-01 00:12:11 +000010533s390_irgen_CLFXBR(UChar m3, UChar m4 __attribute__((unused)),
10534 UChar r1, UChar r2)
10535{
floriane75dafa2012-09-01 17:54:09 +000010536 if (! s390_host_has_fpext) {
10537 emulation_failure(EmFail_S390X_fpext);
10538 } else {
10539 IRTemp op = newTemp(Ity_F128);
10540 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +000010541 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +000010542
floriane75dafa2012-09-01 17:54:09 +000010543 assign(op, get_fpr_pair(r2));
florian19e00772012-09-06 03:13:22 +000010544 assign(result, binop(Iop_F128toI32U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +000010545 mkexpr(op)));
10546 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +000010547 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_UINT_32, op, rounding_mode);
floriane75dafa2012-09-01 17:54:09 +000010548 }
florian1c8f7ff2012-09-01 00:12:11 +000010549 return "clfxbr";
10550}
10551
10552
10553static HChar *
florian4b8efad2012-09-02 18:07:08 +000010554s390_irgen_CGXBR(UChar m3, UChar m4 __attribute__((unused)),
10555 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000010556{
10557 IRTemp op = newTemp(Ity_F128);
10558 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +000010559 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +000010560
10561 assign(op, get_fpr_pair(r2));
florian19e00772012-09-06 03:13:22 +000010562 assign(result, binop(Iop_F128toI64S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +000010563 mkexpr(op)));
10564 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +000010565 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_INT_64, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +000010566
10567 return "cgxbr";
10568}
10569
10570static HChar *
florian1c8f7ff2012-09-01 00:12:11 +000010571s390_irgen_CLGXBR(UChar m3, UChar m4 __attribute__((unused)),
10572 UChar r1, UChar r2)
10573{
floriane75dafa2012-09-01 17:54:09 +000010574 if (! s390_host_has_fpext) {
10575 emulation_failure(EmFail_S390X_fpext);
10576 } else {
10577 IRTemp op = newTemp(Ity_F128);
10578 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +000010579 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +000010580
floriane75dafa2012-09-01 17:54:09 +000010581 assign(op, get_fpr_pair(r2));
florian19e00772012-09-06 03:13:22 +000010582 assign(result, binop(Iop_F128toI64U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +000010583 mkexpr(op)));
10584 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +000010585 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_UINT_64, op,
10586 rounding_mode);
floriane75dafa2012-09-01 17:54:09 +000010587 }
florian1c8f7ff2012-09-01 00:12:11 +000010588 return "clgxbr";
10589}
10590
10591static HChar *
sewardj2019a972011-03-07 16:04:07 +000010592s390_irgen_DXBR(UChar r1, UChar r2)
10593{
10594 IRTemp op1 = newTemp(Ity_F128);
10595 IRTemp op2 = newTemp(Ity_F128);
10596 IRTemp result = newTemp(Ity_F128);
floriandb4fcaa2012-09-05 19:54:08 +000010597 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000010598
10599 assign(op1, get_fpr_pair(r1));
10600 assign(op2, get_fpr_pair(r2));
floriandb4fcaa2012-09-05 19:54:08 +000010601 assign(result, triop(Iop_DivF128, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +000010602 mkexpr(op2)));
10603 put_fpr_pair(r1, mkexpr(result));
10604
10605 return "dxbr";
10606}
10607
10608static HChar *
10609s390_irgen_LTXBR(UChar r1, UChar r2)
10610{
10611 IRTemp result = newTemp(Ity_F128);
10612
10613 assign(result, get_fpr_pair(r2));
10614 put_fpr_pair(r1, mkexpr(result));
10615 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
10616
10617 return "ltxbr";
10618}
10619
10620static HChar *
10621s390_irgen_LCXBR(UChar r1, UChar r2)
10622{
10623 IRTemp result = newTemp(Ity_F128);
10624
10625 assign(result, unop(Iop_NegF128, get_fpr_pair(r2)));
10626 put_fpr_pair(r1, mkexpr(result));
10627 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
10628
10629 return "lcxbr";
10630}
10631
10632static HChar *
10633s390_irgen_LXDBR(UChar r1, UChar r2)
10634{
10635 IRTemp op = newTemp(Ity_F64);
10636
10637 assign(op, get_fpr_dw0(r2));
10638 put_fpr_pair(r1, unop(Iop_F64toF128, mkexpr(op)));
10639
10640 return "lxdbr";
10641}
10642
10643static HChar *
10644s390_irgen_LXEBR(UChar r1, UChar r2)
10645{
10646 IRTemp op = newTemp(Ity_F32);
10647
10648 assign(op, get_fpr_w0(r2));
10649 put_fpr_pair(r1, unop(Iop_F32toF128, mkexpr(op)));
10650
10651 return "lxebr";
10652}
10653
10654static HChar *
10655s390_irgen_LXDB(UChar r1, IRTemp op2addr)
10656{
10657 IRTemp op = newTemp(Ity_F64);
10658
10659 assign(op, load(Ity_F64, mkexpr(op2addr)));
10660 put_fpr_pair(r1, unop(Iop_F64toF128, mkexpr(op)));
10661
10662 return "lxdb";
10663}
10664
10665static HChar *
10666s390_irgen_LXEB(UChar r1, IRTemp op2addr)
10667{
10668 IRTemp op = newTemp(Ity_F32);
10669
10670 assign(op, load(Ity_F32, mkexpr(op2addr)));
10671 put_fpr_pair(r1, unop(Iop_F32toF128, mkexpr(op)));
10672
10673 return "lxeb";
10674}
10675
10676static HChar *
10677s390_irgen_LNEBR(UChar r1, UChar r2)
10678{
10679 IRTemp result = newTemp(Ity_F32);
10680
10681 assign(result, unop(Iop_NegF32, unop(Iop_AbsF32, get_fpr_w0(r2))));
10682 put_fpr_w0(r1, mkexpr(result));
10683 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_32, result);
10684
10685 return "lnebr";
10686}
10687
10688static HChar *
10689s390_irgen_LNDBR(UChar r1, UChar r2)
10690{
10691 IRTemp result = newTemp(Ity_F64);
10692
10693 assign(result, unop(Iop_NegF64, unop(Iop_AbsF64, get_fpr_dw0(r2))));
10694 put_fpr_dw0(r1, mkexpr(result));
10695 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_64, result);
10696
10697 return "lndbr";
10698}
10699
10700static HChar *
10701s390_irgen_LNXBR(UChar r1, UChar r2)
10702{
10703 IRTemp result = newTemp(Ity_F128);
10704
10705 assign(result, unop(Iop_NegF128, unop(Iop_AbsF128, get_fpr_pair(r2))));
10706 put_fpr_pair(r1, mkexpr(result));
10707 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
10708
10709 return "lnxbr";
10710}
10711
10712static HChar *
10713s390_irgen_LPEBR(UChar r1, UChar r2)
10714{
10715 IRTemp result = newTemp(Ity_F32);
10716
10717 assign(result, unop(Iop_AbsF32, get_fpr_w0(r2)));
10718 put_fpr_w0(r1, mkexpr(result));
10719 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_32, result);
10720
10721 return "lpebr";
10722}
10723
10724static HChar *
10725s390_irgen_LPDBR(UChar r1, UChar r2)
10726{
10727 IRTemp result = newTemp(Ity_F64);
10728
10729 assign(result, unop(Iop_AbsF64, get_fpr_dw0(r2)));
10730 put_fpr_dw0(r1, mkexpr(result));
10731 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_64, result);
10732
10733 return "lpdbr";
10734}
10735
10736static HChar *
10737s390_irgen_LPXBR(UChar r1, UChar r2)
10738{
10739 IRTemp result = newTemp(Ity_F128);
10740
10741 assign(result, unop(Iop_AbsF128, get_fpr_pair(r2)));
10742 put_fpr_pair(r1, mkexpr(result));
10743 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
10744
10745 return "lpxbr";
10746}
10747
10748static HChar *
florian4b8efad2012-09-02 18:07:08 +000010749s390_irgen_LDXBR(UChar m3, UChar m4 __attribute__((unused)),
10750 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000010751{
florian12b0bca2012-09-05 20:05:20 +000010752 if (! s390_host_has_fpext && m3 != S390_ROUND_PER_FPC) {
10753 emulation_warning(EmWarn_S390X_fpext_rounding);
10754 m3 = S390_ROUND_PER_FPC;
10755 }
sewardj2019a972011-03-07 16:04:07 +000010756 IRTemp result = newTemp(Ity_F64);
10757
floriandb4fcaa2012-09-05 19:54:08 +000010758 assign(result, binop(Iop_F128toF64, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +000010759 get_fpr_pair(r2)));
sewardj2019a972011-03-07 16:04:07 +000010760 put_fpr_dw0(r1, mkexpr(result));
10761
10762 return "ldxbr";
10763}
10764
10765static HChar *
florian4b8efad2012-09-02 18:07:08 +000010766s390_irgen_LEXBR(UChar m3, UChar m4 __attribute__((unused)),
10767 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000010768{
florian12b0bca2012-09-05 20:05:20 +000010769 if (! s390_host_has_fpext && m3 != S390_ROUND_PER_FPC) {
10770 emulation_warning(EmWarn_S390X_fpext_rounding);
10771 m3 = S390_ROUND_PER_FPC;
10772 }
sewardj2019a972011-03-07 16:04:07 +000010773 IRTemp result = newTemp(Ity_F32);
10774
floriandb4fcaa2012-09-05 19:54:08 +000010775 assign(result, binop(Iop_F128toF32, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +000010776 get_fpr_pair(r2)));
sewardj2019a972011-03-07 16:04:07 +000010777 put_fpr_w0(r1, mkexpr(result));
10778
10779 return "lexbr";
10780}
10781
10782static HChar *
10783s390_irgen_MXBR(UChar r1, UChar r2)
10784{
10785 IRTemp op1 = newTemp(Ity_F128);
10786 IRTemp op2 = newTemp(Ity_F128);
10787 IRTemp result = newTemp(Ity_F128);
floriandb4fcaa2012-09-05 19:54:08 +000010788 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000010789
10790 assign(op1, get_fpr_pair(r1));
10791 assign(op2, get_fpr_pair(r2));
floriandb4fcaa2012-09-05 19:54:08 +000010792 assign(result, triop(Iop_MulF128, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +000010793 mkexpr(op2)));
10794 put_fpr_pair(r1, mkexpr(result));
10795
10796 return "mxbr";
10797}
10798
10799static HChar *
10800s390_irgen_MAEBR(UChar r1, UChar r3, UChar r2)
10801{
floriandb4fcaa2012-09-05 19:54:08 +000010802 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_ROUND_PER_FPC);
florian847684d2012-09-05 04:19:09 +000010803
floriandb4fcaa2012-09-05 19:54:08 +000010804 put_fpr_w0(r1, qop(Iop_MAddF32, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +000010805 get_fpr_w0(r1), get_fpr_w0(r2), get_fpr_w0(r3)));
10806
10807 return "maebr";
10808}
10809
10810static HChar *
10811s390_irgen_MADBR(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_dw0(r1, qop(Iop_MAddF64, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +000010816 get_fpr_dw0(r1), get_fpr_dw0(r2), get_fpr_dw0(r3)));
10817
10818 return "madbr";
10819}
10820
10821static HChar *
10822s390_irgen_MAEB(UChar r3, IRTemp op2addr, UChar r1)
10823{
10824 IRExpr *op2 = load(Ity_F32, mkexpr(op2addr));
floriandb4fcaa2012-09-05 19:54:08 +000010825 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000010826
floriandb4fcaa2012-09-05 19:54:08 +000010827 put_fpr_w0(r1, qop(Iop_MAddF32, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +000010828 get_fpr_w0(r1), op2, get_fpr_w0(r3)));
10829
10830 return "maeb";
10831}
10832
10833static HChar *
10834s390_irgen_MADB(UChar r3, IRTemp op2addr, UChar r1)
10835{
10836 IRExpr *op2 = load(Ity_F64, mkexpr(op2addr));
floriandb4fcaa2012-09-05 19:54:08 +000010837 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000010838
floriandb4fcaa2012-09-05 19:54:08 +000010839 put_fpr_dw0(r1, qop(Iop_MAddF64, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +000010840 get_fpr_dw0(r1), op2, get_fpr_dw0(r3)));
10841
10842 return "madb";
10843}
10844
10845static HChar *
10846s390_irgen_MSEBR(UChar r1, UChar r3, UChar r2)
10847{
floriandb4fcaa2012-09-05 19:54:08 +000010848 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_ROUND_PER_FPC);
florian847684d2012-09-05 04:19:09 +000010849
floriandb4fcaa2012-09-05 19:54:08 +000010850 put_fpr_w0(r1, qop(Iop_MSubF32, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +000010851 get_fpr_w0(r1), get_fpr_w0(r2), get_fpr_w0(r3)));
10852
10853 return "msebr";
10854}
10855
10856static HChar *
10857s390_irgen_MSDBR(UChar r1, UChar r3, UChar r2)
10858{
floriandb4fcaa2012-09-05 19:54:08 +000010859 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_ROUND_PER_FPC);
florian847684d2012-09-05 04:19:09 +000010860
floriandb4fcaa2012-09-05 19:54:08 +000010861 put_fpr_dw0(r1, qop(Iop_MSubF64, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +000010862 get_fpr_dw0(r1), get_fpr_dw0(r2), get_fpr_dw0(r3)));
10863
10864 return "msdbr";
10865}
10866
10867static HChar *
10868s390_irgen_MSEB(UChar r3, IRTemp op2addr, UChar r1)
10869{
10870 IRExpr *op2 = load(Ity_F32, mkexpr(op2addr));
floriandb4fcaa2012-09-05 19:54:08 +000010871 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000010872
floriandb4fcaa2012-09-05 19:54:08 +000010873 put_fpr_w0(r1, qop(Iop_MSubF32, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +000010874 get_fpr_w0(r1), op2, get_fpr_w0(r3)));
10875
10876 return "mseb";
10877}
10878
10879static HChar *
10880s390_irgen_MSDB(UChar r3, IRTemp op2addr, UChar r1)
10881{
10882 IRExpr *op2 = load(Ity_F64, mkexpr(op2addr));
floriandb4fcaa2012-09-05 19:54:08 +000010883 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000010884
floriandb4fcaa2012-09-05 19:54:08 +000010885 put_fpr_dw0(r1, qop(Iop_MSubF64, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +000010886 get_fpr_dw0(r1), op2, get_fpr_dw0(r3)));
10887
10888 return "msdb";
10889}
10890
10891static HChar *
10892s390_irgen_SQEBR(UChar r1, UChar r2)
10893{
10894 IRTemp result = newTemp(Ity_F32);
floriandb4fcaa2012-09-05 19:54:08 +000010895 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000010896
floriandb4fcaa2012-09-05 19:54:08 +000010897 assign(result, binop(Iop_SqrtF32, mkexpr(rounding_mode), get_fpr_w0(r2)));
sewardj2019a972011-03-07 16:04:07 +000010898 put_fpr_w0(r1, mkexpr(result));
10899
10900 return "sqebr";
10901}
10902
10903static HChar *
10904s390_irgen_SQDBR(UChar r1, UChar r2)
10905{
10906 IRTemp result = newTemp(Ity_F64);
floriandb4fcaa2012-09-05 19:54:08 +000010907 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000010908
floriandb4fcaa2012-09-05 19:54:08 +000010909 assign(result, binop(Iop_SqrtF64, mkexpr(rounding_mode), get_fpr_dw0(r2)));
sewardj2019a972011-03-07 16:04:07 +000010910 put_fpr_dw0(r1, mkexpr(result));
10911
10912 return "sqdbr";
10913}
10914
10915static HChar *
10916s390_irgen_SQXBR(UChar r1, UChar r2)
10917{
10918 IRTemp result = newTemp(Ity_F128);
floriandb4fcaa2012-09-05 19:54:08 +000010919 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000010920
floriandb4fcaa2012-09-05 19:54:08 +000010921 assign(result, binop(Iop_SqrtF128, mkexpr(rounding_mode),
10922 get_fpr_pair(r2)));
sewardj2019a972011-03-07 16:04:07 +000010923 put_fpr_pair(r1, mkexpr(result));
10924
10925 return "sqxbr";
10926}
10927
10928static HChar *
10929s390_irgen_SQEB(UChar r1, IRTemp op2addr)
10930{
10931 IRTemp op = newTemp(Ity_F32);
floriandb4fcaa2012-09-05 19:54:08 +000010932 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000010933
10934 assign(op, load(Ity_F32, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +000010935 put_fpr_w0(r1, binop(Iop_SqrtF32, mkexpr(rounding_mode), mkexpr(op)));
sewardj2019a972011-03-07 16:04:07 +000010936
10937 return "sqeb";
10938}
10939
10940static HChar *
10941s390_irgen_SQDB(UChar r1, IRTemp op2addr)
10942{
10943 IRTemp op = newTemp(Ity_F64);
floriandb4fcaa2012-09-05 19:54:08 +000010944 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000010945
10946 assign(op, load(Ity_F64, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +000010947 put_fpr_dw0(r1, binop(Iop_SqrtF64, mkexpr(rounding_mode), mkexpr(op)));
sewardj2019a972011-03-07 16:04:07 +000010948
10949 return "sqdb";
10950}
10951
10952static HChar *
10953s390_irgen_SXBR(UChar r1, UChar r2)
10954{
10955 IRTemp op1 = newTemp(Ity_F128);
10956 IRTemp op2 = newTemp(Ity_F128);
10957 IRTemp result = newTemp(Ity_F128);
floriandb4fcaa2012-09-05 19:54:08 +000010958 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000010959
10960 assign(op1, get_fpr_pair(r1));
10961 assign(op2, get_fpr_pair(r2));
floriandb4fcaa2012-09-05 19:54:08 +000010962 assign(result, triop(Iop_SubF128, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +000010963 mkexpr(op2)));
10964 put_fpr_pair(r1, mkexpr(result));
10965 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
10966
10967 return "sxbr";
10968}
10969
10970static HChar *
10971s390_irgen_TCEB(UChar r1, IRTemp op2addr)
10972{
10973 IRTemp value = newTemp(Ity_F32);
10974
10975 assign(value, get_fpr_w0(r1));
10976
10977 s390_cc_thunk_putFZ(S390_CC_OP_BFP_TDC_32, value, op2addr);
10978
10979 return "tceb";
10980}
10981
10982static HChar *
10983s390_irgen_TCDB(UChar r1, IRTemp op2addr)
10984{
10985 IRTemp value = newTemp(Ity_F64);
10986
10987 assign(value, get_fpr_dw0(r1));
10988
10989 s390_cc_thunk_putFZ(S390_CC_OP_BFP_TDC_64, value, op2addr);
10990
10991 return "tcdb";
10992}
10993
10994static HChar *
10995s390_irgen_TCXB(UChar r1, IRTemp op2addr)
10996{
10997 IRTemp value = newTemp(Ity_F128);
10998
10999 assign(value, get_fpr_pair(r1));
11000
11001 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_TDC_128, value, op2addr);
11002
11003 return "tcxb";
11004}
11005
11006static HChar *
11007s390_irgen_LCDFR(UChar r1, UChar r2)
11008{
11009 IRTemp result = newTemp(Ity_F64);
11010
11011 assign(result, unop(Iop_NegF64, get_fpr_dw0(r2)));
11012 put_fpr_dw0(r1, mkexpr(result));
11013
11014 return "lcdfr";
11015}
11016
11017static HChar *
11018s390_irgen_LNDFR(UChar r1, UChar r2)
11019{
11020 IRTemp result = newTemp(Ity_F64);
11021
11022 assign(result, unop(Iop_NegF64, unop(Iop_AbsF64, get_fpr_dw0(r2))));
11023 put_fpr_dw0(r1, mkexpr(result));
11024
11025 return "lndfr";
11026}
11027
11028static HChar *
11029s390_irgen_LPDFR(UChar r1, UChar r2)
11030{
11031 IRTemp result = newTemp(Ity_F64);
11032
11033 assign(result, unop(Iop_AbsF64, get_fpr_dw0(r2)));
11034 put_fpr_dw0(r1, mkexpr(result));
11035
11036 return "lpdfr";
11037}
11038
11039static HChar *
11040s390_irgen_LDGR(UChar r1, UChar r2)
11041{
11042 put_fpr_dw0(r1, unop(Iop_ReinterpI64asF64, get_gpr_dw0(r2)));
11043
11044 return "ldgr";
11045}
11046
11047static HChar *
11048s390_irgen_LGDR(UChar r1, UChar r2)
11049{
11050 put_gpr_dw0(r1, unop(Iop_ReinterpF64asI64, get_fpr_dw0(r2)));
11051
11052 return "lgdr";
11053}
11054
11055
11056static HChar *
11057s390_irgen_CPSDR(UChar r3, UChar r1, UChar r2)
11058{
11059 IRTemp sign = newTemp(Ity_I64);
11060 IRTemp value = newTemp(Ity_I64);
11061
11062 assign(sign, binop(Iop_And64, unop(Iop_ReinterpF64asI64, get_fpr_dw0(r3)),
11063 mkU64(1ULL << 63)));
11064 assign(value, binop(Iop_And64, unop(Iop_ReinterpF64asI64, get_fpr_dw0(r2)),
11065 mkU64((1ULL << 63) - 1)));
11066 put_fpr_dw0(r1, unop(Iop_ReinterpI64asF64, binop(Iop_Or64, mkexpr(value),
11067 mkexpr(sign))));
11068
11069 return "cpsdr";
11070}
11071
11072
sewardj2019a972011-03-07 16:04:07 +000011073static IRExpr *
11074s390_call_cvb(IRExpr *in)
11075{
11076 IRExpr **args, *call;
11077
11078 args = mkIRExprVec_1(in);
11079 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
11080 "s390_do_cvb", &s390_do_cvb, args);
11081
11082 /* Nothing is excluded from definedness checking. */
11083 call->Iex.CCall.cee->mcx_mask = 0;
11084
11085 return call;
11086}
11087
11088static HChar *
11089s390_irgen_CVB(UChar r1, IRTemp op2addr)
11090{
11091 put_gpr_w1(r1, s390_call_cvb(load(Ity_I64, mkexpr(op2addr))));
11092
11093 return "cvb";
11094}
11095
11096static HChar *
11097s390_irgen_CVBY(UChar r1, IRTemp op2addr)
11098{
11099 put_gpr_w1(r1, s390_call_cvb(load(Ity_I64, mkexpr(op2addr))));
11100
11101 return "cvby";
11102}
11103
11104
sewardj2019a972011-03-07 16:04:07 +000011105static IRExpr *
11106s390_call_cvd(IRExpr *in)
11107{
11108 IRExpr **args, *call;
11109
11110 args = mkIRExprVec_1(in);
11111 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
11112 "s390_do_cvd", &s390_do_cvd, args);
11113
11114 /* Nothing is excluded from definedness checking. */
11115 call->Iex.CCall.cee->mcx_mask = 0;
11116
11117 return call;
11118}
11119
11120static HChar *
11121s390_irgen_CVD(UChar r1, IRTemp op2addr)
11122{
florian11b8ee82012-08-06 13:35:33 +000011123 store(mkexpr(op2addr), s390_call_cvd(unop(Iop_32Uto64, get_gpr_w1(r1))));
sewardj2019a972011-03-07 16:04:07 +000011124
11125 return "cvd";
11126}
11127
11128static HChar *
11129s390_irgen_CVDY(UChar r1, IRTemp op2addr)
11130{
11131 store(mkexpr(op2addr), s390_call_cvd(get_gpr_w1(r1)));
11132
11133 return "cvdy";
11134}
11135
11136static HChar *
11137s390_irgen_FLOGR(UChar r1, UChar r2)
11138{
11139 IRTemp input = newTemp(Ity_I64);
11140 IRTemp not_zero = newTemp(Ity_I64);
11141 IRTemp tmpnum = newTemp(Ity_I64);
11142 IRTemp num = newTemp(Ity_I64);
11143 IRTemp shift_amount = newTemp(Ity_I8);
11144
11145 /* We use the "count leading zeroes" operator because the number of
11146 leading zeroes is identical with the bit position of the first '1' bit.
11147 However, that operator does not work when the input value is zero.
11148 Therefore, we set the LSB of the input value to 1 and use Clz64 on
11149 the modified value. If input == 0, then the result is 64. Otherwise,
11150 the result of Clz64 is what we want. */
11151
11152 assign(input, get_gpr_dw0(r2));
11153 assign(not_zero, binop(Iop_Or64, mkexpr(input), mkU64(1)));
11154 assign(tmpnum, unop(Iop_Clz64, mkexpr(not_zero)));
11155
11156 /* num = (input == 0) ? 64 : tmpnum */
11157 assign(num, mkite(binop(Iop_CmpEQ64, mkexpr(input), mkU64(0)),
11158 /* == 0 */ mkU64(64),
11159 /* != 0 */ mkexpr(tmpnum)));
11160
11161 put_gpr_dw0(r1, mkexpr(num));
11162
11163 /* Set the leftmost '1' bit of the input value to zero. The general scheme
11164 is to first shift the input value by NUM + 1 bits to the left which
11165 causes the leftmost '1' bit to disappear. Then we shift logically to
11166 the right by NUM + 1 bits. Because the semantics of Iop_Shl64 and
11167 Iop_Shr64 are undefined if the shift-amount is greater than or equal to
11168 the width of the value-to-be-shifted, we need to special case
11169 NUM + 1 >= 64. This is equivalent to INPUT != 0 && INPUT != 1.
11170 For both such INPUT values the result will be 0. */
11171
11172 assign(shift_amount, unop(Iop_64to8, binop(Iop_Add64, mkexpr(num),
11173 mkU64(1))));
11174
11175 put_gpr_dw0(r1 + 1,
florian6ad49522011-09-09 02:38:55 +000011176 mkite(binop(Iop_CmpLE64U, mkexpr(input), mkU64(1)),
11177 /* == 0 || == 1*/ mkU64(0),
11178 /* otherwise */
11179 binop(Iop_Shr64,
11180 binop(Iop_Shl64, mkexpr(input),
11181 mkexpr(shift_amount)),
11182 mkexpr(shift_amount))));
sewardj2019a972011-03-07 16:04:07 +000011183
11184 /* Compare the original value as an unsigned integer with 0. */
11185 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, input,
11186 mktemp(Ity_I64, mkU64(0)), False);
11187
11188 return "flogr";
11189}
11190
sewardj1e5fea62011-05-17 16:18:36 +000011191static HChar *
11192s390_irgen_STCK(IRTemp op2addr)
11193{
11194 IRDirty *d;
11195 IRTemp cc = newTemp(Ity_I64);
11196
11197 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STCK",
11198 &s390x_dirtyhelper_STCK,
11199 mkIRExprVec_1(mkexpr(op2addr)));
11200 d->mFx = Ifx_Write;
11201 d->mAddr = mkexpr(op2addr);
11202 d->mSize = 8;
11203 stmt(IRStmt_Dirty(d));
11204 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
11205 mkexpr(cc), mkU64(0), mkU64(0));
11206 return "stck";
11207}
11208
11209static HChar *
11210s390_irgen_STCKF(IRTemp op2addr)
11211{
florianc5c669b2012-08-26 14:32:28 +000011212 if (! s390_host_has_stckf) {
floriane75dafa2012-09-01 17:54:09 +000011213 emulation_failure(EmFail_S390X_stckf);
florianc5c669b2012-08-26 14:32:28 +000011214 } else {
11215 IRTemp cc = newTemp(Ity_I64);
sewardj1e5fea62011-05-17 16:18:36 +000011216
florianc5c669b2012-08-26 14:32:28 +000011217 IRDirty *d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STCKF",
11218 &s390x_dirtyhelper_STCKF,
11219 mkIRExprVec_1(mkexpr(op2addr)));
11220 d->mFx = Ifx_Write;
11221 d->mAddr = mkexpr(op2addr);
11222 d->mSize = 8;
11223 stmt(IRStmt_Dirty(d));
11224 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
11225 mkexpr(cc), mkU64(0), mkU64(0));
11226 }
sewardj1e5fea62011-05-17 16:18:36 +000011227 return "stckf";
11228}
11229
11230static HChar *
11231s390_irgen_STCKE(IRTemp op2addr)
11232{
11233 IRDirty *d;
11234 IRTemp cc = newTemp(Ity_I64);
11235
11236 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STCKE",
11237 &s390x_dirtyhelper_STCKE,
11238 mkIRExprVec_1(mkexpr(op2addr)));
11239 d->mFx = Ifx_Write;
11240 d->mAddr = mkexpr(op2addr);
11241 d->mSize = 16;
11242 stmt(IRStmt_Dirty(d));
11243 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
11244 mkexpr(cc), mkU64(0), mkU64(0));
11245 return "stcke";
11246}
11247
florian933065d2011-07-11 01:48:02 +000011248static HChar *
11249s390_irgen_STFLE(IRTemp op2addr)
11250{
florian4e0083e2012-08-26 03:41:56 +000011251 if (! s390_host_has_stfle) {
floriane75dafa2012-09-01 17:54:09 +000011252 emulation_failure(EmFail_S390X_stfle);
florian4e0083e2012-08-26 03:41:56 +000011253 return "stfle";
11254 }
11255
florian933065d2011-07-11 01:48:02 +000011256 IRDirty *d;
11257 IRTemp cc = newTemp(Ity_I64);
11258
11259 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STFLE",
11260 &s390x_dirtyhelper_STFLE,
11261 mkIRExprVec_1(mkexpr(op2addr)));
11262
11263 d->needsBBP = 1; /* Need to pass pointer to guest state to helper */
11264
sewardjc9069f22012-06-01 16:09:50 +000011265 d->nFxState = 1;
11266 vex_bzero(&d->fxState, sizeof(d->fxState));
11267
florian933065d2011-07-11 01:48:02 +000011268 d->fxState[0].fx = Ifx_Modify; /* read then write */
11269 d->fxState[0].offset = S390X_GUEST_OFFSET(guest_r0);
11270 d->fxState[0].size = sizeof(ULong);
florian933065d2011-07-11 01:48:02 +000011271
11272 d->mAddr = mkexpr(op2addr);
11273 /* Pretend all double words are written */
11274 d->mSize = S390_NUM_FACILITY_DW * sizeof(ULong);
11275 d->mFx = Ifx_Write;
11276
11277 stmt(IRStmt_Dirty(d));
11278
11279 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET), mkexpr(cc), mkU64(0), mkU64(0));
11280
11281 return "stfle";
11282}
11283
floriana4384a32011-08-11 16:58:45 +000011284static HChar *
11285s390_irgen_CKSM(UChar r1,UChar r2)
11286{
11287 IRTemp addr = newTemp(Ity_I64);
11288 IRTemp op = newTemp(Ity_I32);
11289 IRTemp len = newTemp(Ity_I64);
11290 IRTemp oldval = newTemp(Ity_I32);
11291 IRTemp mask = newTemp(Ity_I32);
11292 IRTemp newop = newTemp(Ity_I32);
11293 IRTemp result = newTemp(Ity_I32);
11294 IRTemp result1 = newTemp(Ity_I32);
11295 IRTemp inc = newTemp(Ity_I64);
11296
11297 assign(oldval, get_gpr_w1(r1));
11298 assign(addr, get_gpr_dw0(r2));
11299 assign(len, get_gpr_dw0(r2+1));
11300
11301 /* Condition code is always zero. */
11302 s390_cc_set(0);
11303
11304 /* If length is zero, there is no need to calculate the checksum */
florian6820ba52012-07-26 02:01:50 +000011305 next_insn_if(binop(Iop_CmpEQ64, mkexpr(len), mkU64(0)));
floriana4384a32011-08-11 16:58:45 +000011306
11307 /* Assiging the increment variable to adjust address and length
11308 later on. */
11309 assign(inc, mkite(binop(Iop_CmpLT64U, mkexpr(len), mkU64(4)),
11310 mkexpr(len), mkU64(4)));
11311
11312 /* If length < 4 the final 4-byte 2nd operand value is computed by
11313 appending the remaining bytes to the right with 0. This is done
11314 by AND'ing the 4 bytes loaded from memory with an appropriate
11315 mask. If length >= 4, that mask is simply 0xffffffff. */
11316
11317 assign(mask, mkite(binop(Iop_CmpLT64U, mkexpr(len), mkU64(4)),
11318 /* Mask computation when len < 4:
11319 0xffffffff << (32 - (len % 4)*8) */
11320 binop(Iop_Shl32, mkU32(0xffffffff),
11321 unop(Iop_32to8,
11322 binop(Iop_Sub32, mkU32(32),
11323 binop(Iop_Shl32,
11324 unop(Iop_64to32,
11325 binop(Iop_And64,
11326 mkexpr(len), mkU64(3))),
11327 mkU8(3))))),
11328 mkU32(0xffffffff)));
11329
11330 assign(op, load(Ity_I32, mkexpr(addr)));
11331 assign(newop, binop(Iop_And32, mkexpr(op), mkexpr(mask)));
11332 assign(result, binop(Iop_Add32, mkexpr(newop), mkexpr(oldval)));
11333
11334 /* Checking for carry */
11335 assign(result1, mkite(binop(Iop_CmpLT32U, mkexpr(result), mkexpr(newop)),
11336 binop(Iop_Add32, mkexpr(result), mkU32(1)),
11337 mkexpr(result)));
11338
11339 put_gpr_w1(r1, mkexpr(result1));
11340 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr), mkexpr(inc)));
11341 put_gpr_dw0(r2+1, binop(Iop_Sub64, mkexpr(len), mkexpr(inc)));
11342
florian6820ba52012-07-26 02:01:50 +000011343 iterate_if(binop(Iop_CmpNE64, mkexpr(len), mkU64(0)));
floriana4384a32011-08-11 16:58:45 +000011344
11345 return "cksm";
11346}
11347
florian9af37692012-01-15 21:01:16 +000011348static HChar *
11349s390_irgen_TROO(UChar m3, UChar r1, UChar r2)
11350{
11351 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
11352 src_addr = newTemp(Ity_I64);
11353 des_addr = newTemp(Ity_I64);
11354 tab_addr = newTemp(Ity_I64);
11355 test_byte = newTemp(Ity_I8);
11356 src_len = newTemp(Ity_I64);
11357
11358 assign(src_addr, get_gpr_dw0(r2));
11359 assign(des_addr, get_gpr_dw0(r1));
11360 assign(tab_addr, get_gpr_dw0(1));
florian53518532012-01-18 14:00:31 +000011361 assign(src_len, get_gpr_dw0(r1+1));
florian9af37692012-01-15 21:01:16 +000011362 assign(test_byte, get_gpr_b7(0));
11363
11364 IRTemp op = newTemp(Ity_I8);
11365 IRTemp op1 = newTemp(Ity_I8);
11366 IRTemp result = newTemp(Ity_I64);
11367
11368 /* End of source string? We're done; proceed to next insn */
11369 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000011370 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian9af37692012-01-15 21:01:16 +000011371
11372 /* Load character from source string, index translation table and
11373 store translated character in op1. */
11374 assign(op, load(Ity_I8, mkexpr(src_addr)));
11375
11376 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)),
11377 mkexpr(tab_addr)));
11378 assign(op1, load(Ity_I8, mkexpr(result)));
11379
11380 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
11381 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000011382 next_insn_if(binop(Iop_CmpEQ8, mkexpr(op1), mkexpr(test_byte)));
florian9af37692012-01-15 21:01:16 +000011383 }
11384 store(get_gpr_dw0(r1), mkexpr(op1));
11385
11386 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(1)));
11387 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(1)));
11388 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(1)));
11389
florian6820ba52012-07-26 02:01:50 +000011390 iterate();
florian9af37692012-01-15 21:01:16 +000011391
11392 return "troo";
11393}
11394
florian730448f2012-02-04 17:07:07 +000011395static HChar *
11396s390_irgen_TRTO(UChar m3, UChar r1, UChar r2)
11397{
11398 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
11399 src_addr = newTemp(Ity_I64);
11400 des_addr = newTemp(Ity_I64);
11401 tab_addr = newTemp(Ity_I64);
11402 test_byte = newTemp(Ity_I8);
11403 src_len = newTemp(Ity_I64);
11404
11405 assign(src_addr, get_gpr_dw0(r2));
11406 assign(des_addr, get_gpr_dw0(r1));
11407 assign(tab_addr, get_gpr_dw0(1));
11408 assign(src_len, get_gpr_dw0(r1+1));
11409 assign(test_byte, get_gpr_b7(0));
11410
11411 IRTemp op = newTemp(Ity_I16);
11412 IRTemp op1 = newTemp(Ity_I8);
11413 IRTemp result = newTemp(Ity_I64);
11414
11415 /* End of source string? We're done; proceed to next insn */
11416 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000011417 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian730448f2012-02-04 17:07:07 +000011418
11419 /* Load character from source string, index translation table and
11420 store translated character in op1. */
11421 assign(op, load(Ity_I16, mkexpr(src_addr)));
11422
11423 assign(result, binop(Iop_Add64, unop(Iop_16Uto64, mkexpr(op)),
11424 mkexpr(tab_addr)));
11425
11426 assign(op1, load(Ity_I8, mkexpr(result)));
11427
11428 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
11429 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000011430 next_insn_if(binop(Iop_CmpEQ8, mkexpr(op1), mkexpr(test_byte)));
florian730448f2012-02-04 17:07:07 +000011431 }
11432 store(get_gpr_dw0(r1), mkexpr(op1));
11433
11434 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(2)));
11435 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(1)));
11436 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(2)));
11437
florian6820ba52012-07-26 02:01:50 +000011438 iterate();
florian730448f2012-02-04 17:07:07 +000011439
11440 return "trto";
11441}
11442
11443static HChar *
11444s390_irgen_TROT(UChar m3, UChar r1, UChar r2)
11445{
11446 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
11447 src_addr = newTemp(Ity_I64);
11448 des_addr = newTemp(Ity_I64);
11449 tab_addr = newTemp(Ity_I64);
11450 test_byte = newTemp(Ity_I16);
11451 src_len = newTemp(Ity_I64);
11452
11453 assign(src_addr, get_gpr_dw0(r2));
11454 assign(des_addr, get_gpr_dw0(r1));
11455 assign(tab_addr, get_gpr_dw0(1));
11456 assign(src_len, get_gpr_dw0(r1+1));
11457 assign(test_byte, get_gpr_hw3(0));
11458
11459 IRTemp op = newTemp(Ity_I8);
11460 IRTemp op1 = newTemp(Ity_I16);
11461 IRTemp result = newTemp(Ity_I64);
11462
11463 /* End of source string? We're done; proceed to next insn */
11464 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000011465 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian730448f2012-02-04 17:07:07 +000011466
11467 /* Load character from source string, index translation table and
11468 store translated character in op1. */
11469 assign(op, binop(Iop_Shl8, load(Ity_I8, mkexpr(src_addr)), mkU8(1)));
11470
11471 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)),
11472 mkexpr(tab_addr)));
11473 assign(op1, load(Ity_I16, mkexpr(result)));
11474
11475 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
11476 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000011477 next_insn_if(binop(Iop_CmpEQ16, mkexpr(op1), mkexpr(test_byte)));
florian730448f2012-02-04 17:07:07 +000011478 }
11479 store(get_gpr_dw0(r1), mkexpr(op1));
11480
11481 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(1)));
11482 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(2)));
11483 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(1)));
11484
florian6820ba52012-07-26 02:01:50 +000011485 iterate();
florian730448f2012-02-04 17:07:07 +000011486
11487 return "trot";
11488}
11489
11490static HChar *
11491s390_irgen_TRTT(UChar m3, UChar r1, UChar r2)
11492{
11493 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
11494 src_addr = newTemp(Ity_I64);
11495 des_addr = newTemp(Ity_I64);
11496 tab_addr = newTemp(Ity_I64);
11497 test_byte = newTemp(Ity_I16);
11498 src_len = newTemp(Ity_I64);
11499
11500 assign(src_addr, get_gpr_dw0(r2));
11501 assign(des_addr, get_gpr_dw0(r1));
11502 assign(tab_addr, get_gpr_dw0(1));
11503 assign(src_len, get_gpr_dw0(r1+1));
11504 assign(test_byte, get_gpr_hw3(0));
11505
11506 IRTemp op = newTemp(Ity_I16);
11507 IRTemp op1 = newTemp(Ity_I16);
11508 IRTemp result = newTemp(Ity_I64);
11509
11510 /* End of source string? We're done; proceed to next insn */
11511 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000011512 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian730448f2012-02-04 17:07:07 +000011513
11514 /* Load character from source string, index translation table and
11515 store translated character in op1. */
11516 assign(op, binop(Iop_Shl16, load(Ity_I16, mkexpr(src_addr)), mkU8(1)));
11517
11518 assign(result, binop(Iop_Add64, unop(Iop_16Uto64, mkexpr(op)),
11519 mkexpr(tab_addr)));
11520 assign(op1, load(Ity_I16, mkexpr(result)));
11521
11522 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
11523 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000011524 next_insn_if(binop(Iop_CmpEQ16, mkexpr(op1), mkexpr(test_byte)));
florian730448f2012-02-04 17:07:07 +000011525 }
11526
11527 store(get_gpr_dw0(r1), mkexpr(op1));
11528
11529 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(2)));
11530 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(2)));
11531 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(2)));
11532
florian6820ba52012-07-26 02:01:50 +000011533 iterate();
florian730448f2012-02-04 17:07:07 +000011534
11535 return "trtt";
11536}
11537
11538static HChar *
11539s390_irgen_TR(UChar length, IRTemp start1, IRTemp start2)
11540{
florianf87d4fb2012-05-05 02:55:24 +000011541 IRTemp len = newTemp(Ity_I64);
florian730448f2012-02-04 17:07:07 +000011542
florianf87d4fb2012-05-05 02:55:24 +000011543 assign(len, mkU64(length));
11544 s390_irgen_TR_EX(len, start1, start2);
florian730448f2012-02-04 17:07:07 +000011545
11546 return "tr";
11547}
11548
11549static HChar *
11550s390_irgen_TRE(UChar r1,UChar r2)
11551{
11552 IRTemp src_addr, tab_addr, src_len, test_byte;
11553 src_addr = newTemp(Ity_I64);
11554 tab_addr = newTemp(Ity_I64);
11555 src_len = newTemp(Ity_I64);
11556 test_byte = newTemp(Ity_I8);
11557
11558 assign(src_addr, get_gpr_dw0(r1));
11559 assign(src_len, get_gpr_dw0(r1+1));
11560 assign(tab_addr, get_gpr_dw0(r2));
11561 assign(test_byte, get_gpr_b7(0));
11562
11563 IRTemp op = newTemp(Ity_I8);
11564 IRTemp op1 = newTemp(Ity_I8);
11565 IRTemp result = newTemp(Ity_I64);
11566
11567 /* End of source string? We're done; proceed to next insn */
11568 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000011569 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian730448f2012-02-04 17:07:07 +000011570
11571 /* Load character from source string and compare with test byte */
11572 assign(op, load(Ity_I8, mkexpr(src_addr)));
11573
11574 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000011575 next_insn_if(binop(Iop_CmpEQ8, mkexpr(op), mkexpr(test_byte)));
florian730448f2012-02-04 17:07:07 +000011576
11577 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)),
11578 mkexpr(tab_addr)));
11579
11580 assign(op1, load(Ity_I8, mkexpr(result)));
11581
11582 store(get_gpr_dw0(r1), mkexpr(op1));
11583 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(src_addr), mkU64(1)));
11584 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(1)));
11585
florian6820ba52012-07-26 02:01:50 +000011586 iterate();
florian730448f2012-02-04 17:07:07 +000011587
11588 return "tre";
11589}
11590
floriana0100c92012-07-20 00:06:35 +000011591static IRExpr *
11592s390_call_cu21(IRExpr *srcval, IRExpr *low_surrogate)
11593{
11594 IRExpr **args, *call;
11595 args = mkIRExprVec_2(srcval, low_surrogate);
11596 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
11597 "s390_do_cu21", &s390_do_cu21, args);
11598
11599 /* Nothing is excluded from definedness checking. */
11600 call->Iex.CCall.cee->mcx_mask = 0;
11601
11602 return call;
11603}
11604
11605static HChar *
11606s390_irgen_CU21(UChar m3, UChar r1, UChar r2)
11607{
11608 IRTemp addr1 = newTemp(Ity_I64);
11609 IRTemp addr2 = newTemp(Ity_I64);
11610 IRTemp len1 = newTemp(Ity_I64);
11611 IRTemp len2 = newTemp(Ity_I64);
11612
11613 assign(addr1, get_gpr_dw0(r1));
11614 assign(addr2, get_gpr_dw0(r2));
11615 assign(len1, get_gpr_dw0(r1 + 1));
11616 assign(len2, get_gpr_dw0(r2 + 1));
11617
11618 /* We're processing the 2nd operand 2 bytes at a time. Therefore, if
11619 there are less than 2 bytes left, then the 2nd operand is exhausted
11620 and we're done here. cc = 0 */
11621 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000011622 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(2)));
floriana0100c92012-07-20 00:06:35 +000011623
11624 /* There are at least two bytes there. Read them. */
11625 IRTemp srcval = newTemp(Ity_I32);
11626 assign(srcval, unop(Iop_16Uto32, load(Ity_I16, mkexpr(addr2))));
11627
11628 /* Find out whether this is a high surrogate. I.e. SRCVAL lies
11629 inside the interval [0xd800 - 0xdbff] */
11630 IRTemp is_high_surrogate = newTemp(Ity_I32);
11631 IRExpr *flag1 = mkite(binop(Iop_CmpLE32U, mkU32(0xd800), mkexpr(srcval)),
11632 mkU32(1), mkU32(0));
11633 IRExpr *flag2 = mkite(binop(Iop_CmpLE32U, mkexpr(srcval), mkU32(0xdbff)),
11634 mkU32(1), mkU32(0));
11635 assign(is_high_surrogate, binop(Iop_And32, flag1, flag2));
11636
11637 /* If SRCVAL is a high surrogate and there are less than 4 bytes left,
11638 then the 2nd operand is exhausted and we're done here. cc = 0 */
11639 IRExpr *not_enough_bytes =
11640 mkite(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)), mkU32(1), mkU32(0));
11641
florian6820ba52012-07-26 02:01:50 +000011642 next_insn_if(binop(Iop_CmpEQ32,
11643 binop(Iop_And32, mkexpr(is_high_surrogate),
11644 not_enough_bytes), mkU32(1)));
floriana0100c92012-07-20 00:06:35 +000011645
11646 /* The 2nd operand is not exhausted. If the first 2 bytes are a high
11647 surrogate, read the next two bytes (low surrogate). */
11648 IRTemp low_surrogate = newTemp(Ity_I32);
11649 IRExpr *low_surrogate_addr = binop(Iop_Add64, mkexpr(addr2), mkU64(2));
11650
11651 assign(low_surrogate,
11652 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
11653 unop(Iop_16Uto32, load(Ity_I16, low_surrogate_addr)),
11654 mkU32(0))); // any value is fine; it will not be used
11655
11656 /* Call the helper */
11657 IRTemp retval = newTemp(Ity_I64);
florian11b8ee82012-08-06 13:35:33 +000011658 assign(retval, s390_call_cu21(unop(Iop_32Uto64, mkexpr(srcval)),
11659 unop(Iop_32Uto64, mkexpr(low_surrogate))));
floriana0100c92012-07-20 00:06:35 +000011660
11661 /* Before we can test whether the 1st operand is exhausted we need to
11662 test for an invalid low surrogate. Because cc=2 outranks cc=1. */
11663 if (s390_host_has_etf3 && (m3 & 0x1) == 1) {
11664 IRExpr *invalid_low_surrogate =
11665 binop(Iop_And64, mkexpr(retval), mkU64(0xff));
11666
11667 s390_cc_set(2);
florian6820ba52012-07-26 02:01:50 +000011668 next_insn_if(binop(Iop_CmpEQ64, invalid_low_surrogate, mkU64(1)));
floriana0100c92012-07-20 00:06:35 +000011669 }
11670
11671 /* Now test whether the 1st operand is exhausted */
11672 IRTemp num_bytes = newTemp(Ity_I64);
11673 assign(num_bytes, binop(Iop_And64,
11674 binop(Iop_Shr64, mkexpr(retval), mkU8(8)),
11675 mkU64(0xff)));
11676 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000011677 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
floriana0100c92012-07-20 00:06:35 +000011678
11679 /* Extract the bytes to be stored at addr1 */
11680 IRTemp data = newTemp(Ity_I64);
11681 assign(data, binop(Iop_Shr64, mkexpr(retval), mkU8(16)));
11682
11683 /* To store the bytes construct 4 dirty helper calls. The helper calls
11684 are guarded (num_bytes == 1, num_bytes == 2, etc) such that only
11685 one of them will be called at runtime. */
11686 int i;
11687 for (i = 1; i <= 4; ++i) {
11688 IRDirty *d;
11689
11690 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
11691 &s390x_dirtyhelper_CUxy,
11692 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
11693 mkexpr(num_bytes)));
11694 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
11695 d->mFx = Ifx_Write;
11696 d->mAddr = mkexpr(addr1);
11697 d->mSize = i;
11698 stmt(IRStmt_Dirty(d));
11699 }
11700
11701 /* Update source address and length */
11702 IRTemp num_src_bytes = newTemp(Ity_I64);
11703 assign(num_src_bytes,
11704 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
11705 mkU64(4), mkU64(2)));
11706 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkexpr(num_src_bytes)));
11707 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkexpr(num_src_bytes)));
11708
11709 /* Update destination address and length */
11710 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
11711 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
11712
florian6820ba52012-07-26 02:01:50 +000011713 iterate();
floriana0100c92012-07-20 00:06:35 +000011714
11715 return "cu21";
11716}
11717
florian2a415a12012-07-21 17:41:36 +000011718static IRExpr *
11719s390_call_cu24(IRExpr *srcval, IRExpr *low_surrogate)
11720{
11721 IRExpr **args, *call;
11722 args = mkIRExprVec_2(srcval, low_surrogate);
11723 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
11724 "s390_do_cu24", &s390_do_cu24, args);
11725
11726 /* Nothing is excluded from definedness checking. */
11727 call->Iex.CCall.cee->mcx_mask = 0;
11728
11729 return call;
11730}
11731
11732static HChar *
11733s390_irgen_CU24(UChar m3, UChar r1, UChar r2)
11734{
11735 IRTemp addr1 = newTemp(Ity_I64);
11736 IRTemp addr2 = newTemp(Ity_I64);
11737 IRTemp len1 = newTemp(Ity_I64);
11738 IRTemp len2 = newTemp(Ity_I64);
11739
11740 assign(addr1, get_gpr_dw0(r1));
11741 assign(addr2, get_gpr_dw0(r2));
11742 assign(len1, get_gpr_dw0(r1 + 1));
11743 assign(len2, get_gpr_dw0(r2 + 1));
11744
11745 /* We're processing the 2nd operand 2 bytes at a time. Therefore, if
11746 there are less than 2 bytes left, then the 2nd operand is exhausted
11747 and we're done here. cc = 0 */
11748 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000011749 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(2)));
florian2a415a12012-07-21 17:41:36 +000011750
11751 /* There are at least two bytes there. Read them. */
11752 IRTemp srcval = newTemp(Ity_I32);
11753 assign(srcval, unop(Iop_16Uto32, load(Ity_I16, mkexpr(addr2))));
11754
11755 /* Find out whether this is a high surrogate. I.e. SRCVAL lies
11756 inside the interval [0xd800 - 0xdbff] */
11757 IRTemp is_high_surrogate = newTemp(Ity_I32);
11758 IRExpr *flag1 = mkite(binop(Iop_CmpLE32U, mkU32(0xd800), mkexpr(srcval)),
11759 mkU32(1), mkU32(0));
11760 IRExpr *flag2 = mkite(binop(Iop_CmpLE32U, mkexpr(srcval), mkU32(0xdbff)),
11761 mkU32(1), mkU32(0));
11762 assign(is_high_surrogate, binop(Iop_And32, flag1, flag2));
11763
11764 /* If SRCVAL is a high surrogate and there are less than 4 bytes left,
11765 then the 2nd operand is exhausted and we're done here. cc = 0 */
11766 IRExpr *not_enough_bytes =
11767 mkite(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)), mkU32(1), mkU32(0));
11768
florian6820ba52012-07-26 02:01:50 +000011769 next_insn_if(binop(Iop_CmpEQ32,
11770 binop(Iop_And32, mkexpr(is_high_surrogate),
11771 not_enough_bytes),
11772 mkU32(1)));
florian2a415a12012-07-21 17:41:36 +000011773
11774 /* The 2nd operand is not exhausted. If the first 2 bytes are a high
11775 surrogate, read the next two bytes (low surrogate). */
11776 IRTemp low_surrogate = newTemp(Ity_I32);
11777 IRExpr *low_surrogate_addr = binop(Iop_Add64, mkexpr(addr2), mkU64(2));
11778
11779 assign(low_surrogate,
11780 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
11781 unop(Iop_16Uto32, load(Ity_I16, low_surrogate_addr)),
11782 mkU32(0))); // any value is fine; it will not be used
11783
11784 /* Call the helper */
11785 IRTemp retval = newTemp(Ity_I64);
florian11b8ee82012-08-06 13:35:33 +000011786 assign(retval, s390_call_cu24(unop(Iop_32Uto64, mkexpr(srcval)),
11787 unop(Iop_32Uto64, mkexpr(low_surrogate))));
florian2a415a12012-07-21 17:41:36 +000011788
11789 /* Before we can test whether the 1st operand is exhausted we need to
11790 test for an invalid low surrogate. Because cc=2 outranks cc=1. */
11791 if (s390_host_has_etf3 && (m3 & 0x1) == 1) {
11792 IRExpr *invalid_low_surrogate =
11793 binop(Iop_And64, mkexpr(retval), mkU64(0xff));
11794
11795 s390_cc_set(2);
florian6820ba52012-07-26 02:01:50 +000011796 next_insn_if(binop(Iop_CmpEQ64, invalid_low_surrogate, mkU64(1)));
florian2a415a12012-07-21 17:41:36 +000011797 }
11798
11799 /* Now test whether the 1st operand is exhausted */
11800 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000011801 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkU64(4)));
florian2a415a12012-07-21 17:41:36 +000011802
11803 /* Extract the bytes to be stored at addr1 */
11804 IRExpr *data = unop(Iop_64to32, binop(Iop_Shr64, mkexpr(retval), mkU8(8)));
11805
11806 store(mkexpr(addr1), data);
11807
11808 /* Update source address and length */
11809 IRTemp num_src_bytes = newTemp(Ity_I64);
11810 assign(num_src_bytes,
11811 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
11812 mkU64(4), mkU64(2)));
11813 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkexpr(num_src_bytes)));
11814 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkexpr(num_src_bytes)));
11815
11816 /* Update destination address and length */
11817 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkU64(4)));
11818 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkU64(4)));
11819
florian6820ba52012-07-26 02:01:50 +000011820 iterate();
florian2a415a12012-07-21 17:41:36 +000011821
11822 return "cu24";
11823}
floriana4384a32011-08-11 16:58:45 +000011824
florian956194b2012-07-28 22:18:32 +000011825static IRExpr *
11826s390_call_cu42(IRExpr *srcval)
11827{
11828 IRExpr **args, *call;
11829 args = mkIRExprVec_1(srcval);
11830 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
11831 "s390_do_cu42", &s390_do_cu42, args);
11832
11833 /* Nothing is excluded from definedness checking. */
11834 call->Iex.CCall.cee->mcx_mask = 0;
11835
11836 return call;
11837}
11838
11839static HChar *
11840s390_irgen_CU42(UChar r1, UChar r2)
11841{
11842 IRTemp addr1 = newTemp(Ity_I64);
11843 IRTemp addr2 = newTemp(Ity_I64);
11844 IRTemp len1 = newTemp(Ity_I64);
11845 IRTemp len2 = newTemp(Ity_I64);
11846
11847 assign(addr1, get_gpr_dw0(r1));
11848 assign(addr2, get_gpr_dw0(r2));
11849 assign(len1, get_gpr_dw0(r1 + 1));
11850 assign(len2, get_gpr_dw0(r2 + 1));
11851
11852 /* We're processing the 2nd operand 4 bytes at a time. Therefore, if
11853 there are less than 4 bytes left, then the 2nd operand is exhausted
11854 and we're done here. cc = 0 */
11855 s390_cc_set(0);
11856 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)));
11857
11858 /* Read the 2nd operand. */
11859 IRTemp srcval = newTemp(Ity_I32);
11860 assign(srcval, load(Ity_I32, mkexpr(addr2)));
11861
11862 /* Call the helper */
11863 IRTemp retval = newTemp(Ity_I64);
florian11b8ee82012-08-06 13:35:33 +000011864 assign(retval, s390_call_cu42(unop(Iop_32Uto64, mkexpr(srcval))));
florian956194b2012-07-28 22:18:32 +000011865
11866 /* If the UTF-32 character was invalid, set cc=2 and we're done.
11867 cc=2 outranks cc=1 (1st operand exhausted) */
11868 IRExpr *invalid_character = binop(Iop_And64, mkexpr(retval), mkU64(0xff));
11869
11870 s390_cc_set(2);
11871 next_insn_if(binop(Iop_CmpEQ64, invalid_character, mkU64(1)));
11872
11873 /* Now test whether the 1st operand is exhausted */
11874 IRTemp num_bytes = newTemp(Ity_I64);
11875 assign(num_bytes, binop(Iop_And64,
11876 binop(Iop_Shr64, mkexpr(retval), mkU8(8)),
11877 mkU64(0xff)));
11878 s390_cc_set(1);
11879 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
11880
11881 /* Extract the bytes to be stored at addr1 */
11882 IRTemp data = newTemp(Ity_I64);
11883 assign(data, binop(Iop_Shr64, mkexpr(retval), mkU8(16)));
11884
11885 /* To store the bytes construct 2 dirty helper calls. The helper calls
11886 are guarded (num_bytes == 2 and num_bytes == 4, respectively) such
11887 that only one of them will be called at runtime. */
11888
11889 Int i;
11890 for (i = 2; i <= 4; ++i) {
11891 IRDirty *d;
11892
11893 if (i == 3) continue; // skip this one
11894
11895 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
11896 &s390x_dirtyhelper_CUxy,
11897 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
11898 mkexpr(num_bytes)));
11899 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
11900 d->mFx = Ifx_Write;
11901 d->mAddr = mkexpr(addr1);
11902 d->mSize = i;
11903 stmt(IRStmt_Dirty(d));
11904 }
11905
11906 /* Update source address and length */
11907 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkU64(4)));
11908 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkU64(4)));
11909
11910 /* Update destination address and length */
11911 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
11912 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
11913
11914 iterate();
11915
11916 return "cu42";
11917}
11918
florian6d9b9b22012-08-03 18:35:39 +000011919static IRExpr *
florianaf2194f2012-08-06 00:07:54 +000011920s390_call_cu41(IRExpr *srcval)
11921{
11922 IRExpr **args, *call;
11923 args = mkIRExprVec_1(srcval);
11924 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
11925 "s390_do_cu41", &s390_do_cu41, args);
11926
11927 /* Nothing is excluded from definedness checking. */
11928 call->Iex.CCall.cee->mcx_mask = 0;
11929
11930 return call;
11931}
11932
11933static HChar *
11934s390_irgen_CU41(UChar r1, UChar r2)
11935{
11936 IRTemp addr1 = newTemp(Ity_I64);
11937 IRTemp addr2 = newTemp(Ity_I64);
11938 IRTemp len1 = newTemp(Ity_I64);
11939 IRTemp len2 = newTemp(Ity_I64);
11940
11941 assign(addr1, get_gpr_dw0(r1));
11942 assign(addr2, get_gpr_dw0(r2));
11943 assign(len1, get_gpr_dw0(r1 + 1));
11944 assign(len2, get_gpr_dw0(r2 + 1));
11945
11946 /* We're processing the 2nd operand 4 bytes at a time. Therefore, if
11947 there are less than 4 bytes left, then the 2nd operand is exhausted
11948 and we're done here. cc = 0 */
11949 s390_cc_set(0);
11950 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)));
11951
11952 /* Read the 2nd operand. */
11953 IRTemp srcval = newTemp(Ity_I32);
11954 assign(srcval, load(Ity_I32, mkexpr(addr2)));
11955
11956 /* Call the helper */
11957 IRTemp retval = newTemp(Ity_I64);
florian11b8ee82012-08-06 13:35:33 +000011958 assign(retval, s390_call_cu41(unop(Iop_32Uto64, mkexpr(srcval))));
florianaf2194f2012-08-06 00:07:54 +000011959
11960 /* If the UTF-32 character was invalid, set cc=2 and we're done.
11961 cc=2 outranks cc=1 (1st operand exhausted) */
11962 IRExpr *invalid_character = binop(Iop_And64, mkexpr(retval), mkU64(0xff));
11963
11964 s390_cc_set(2);
11965 next_insn_if(binop(Iop_CmpEQ64, invalid_character, mkU64(1)));
11966
11967 /* Now test whether the 1st operand is exhausted */
11968 IRTemp num_bytes = newTemp(Ity_I64);
11969 assign(num_bytes, binop(Iop_And64,
11970 binop(Iop_Shr64, mkexpr(retval), mkU8(8)),
11971 mkU64(0xff)));
11972 s390_cc_set(1);
11973 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
11974
11975 /* Extract the bytes to be stored at addr1 */
11976 IRTemp data = newTemp(Ity_I64);
11977 assign(data, binop(Iop_Shr64, mkexpr(retval), mkU8(16)));
11978
11979 /* To store the bytes construct 4 dirty helper calls. The helper calls
11980 are guarded (num_bytes == 1, num_bytes == 2, etc) such that only
11981 one of them will be called at runtime. */
11982 int i;
11983 for (i = 1; i <= 4; ++i) {
11984 IRDirty *d;
11985
11986 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
11987 &s390x_dirtyhelper_CUxy,
11988 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
11989 mkexpr(num_bytes)));
11990 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
11991 d->mFx = Ifx_Write;
11992 d->mAddr = mkexpr(addr1);
11993 d->mSize = i;
11994 stmt(IRStmt_Dirty(d));
11995 }
11996
11997 /* Update source address and length */
11998 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkU64(4)));
11999 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkU64(4)));
12000
12001 /* Update destination address and length */
12002 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
12003 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
12004
12005 iterate();
12006
12007 return "cu41";
12008}
12009
12010static IRExpr *
florian3f8a96a2012-08-05 02:59:55 +000012011s390_call_cu12_cu14_helper1(IRExpr *byte1, IRExpr *etf3_and_m3_is_1)
florian6d9b9b22012-08-03 18:35:39 +000012012{
12013 IRExpr **args, *call;
12014 args = mkIRExprVec_2(byte1, etf3_and_m3_is_1);
florian3f8a96a2012-08-05 02:59:55 +000012015 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/, "s390_do_cu12_cu14_helper1",
12016 &s390_do_cu12_cu14_helper1, args);
florian6d9b9b22012-08-03 18:35:39 +000012017
12018 /* Nothing is excluded from definedness checking. */
12019 call->Iex.CCall.cee->mcx_mask = 0;
12020
12021 return call;
12022}
12023
12024static IRExpr *
12025s390_call_cu12_helper2(IRExpr *byte1, IRExpr *byte2, IRExpr *byte3,
12026 IRExpr *byte4, IRExpr *stuff)
12027{
12028 IRExpr **args, *call;
12029 args = mkIRExprVec_5(byte1, byte2, byte3, byte4, stuff);
12030 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
12031 "s390_do_cu12_helper2", &s390_do_cu12_helper2, args);
12032
12033 /* Nothing is excluded from definedness checking. */
12034 call->Iex.CCall.cee->mcx_mask = 0;
12035
12036 return call;
12037}
12038
florian3f8a96a2012-08-05 02:59:55 +000012039static IRExpr *
12040s390_call_cu14_helper2(IRExpr *byte1, IRExpr *byte2, IRExpr *byte3,
12041 IRExpr *byte4, IRExpr *stuff)
12042{
12043 IRExpr **args, *call;
12044 args = mkIRExprVec_5(byte1, byte2, byte3, byte4, stuff);
12045 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
12046 "s390_do_cu14_helper2", &s390_do_cu14_helper2, args);
12047
12048 /* Nothing is excluded from definedness checking. */
12049 call->Iex.CCall.cee->mcx_mask = 0;
12050
12051 return call;
12052}
12053
12054static void
12055s390_irgen_cu12_cu14(UChar m3, UChar r1, UChar r2, Bool is_cu12)
florian6d9b9b22012-08-03 18:35:39 +000012056{
12057 IRTemp addr1 = newTemp(Ity_I64);
12058 IRTemp addr2 = newTemp(Ity_I64);
12059 IRTemp len1 = newTemp(Ity_I64);
12060 IRTemp len2 = newTemp(Ity_I64);
12061
12062 assign(addr1, get_gpr_dw0(r1));
12063 assign(addr2, get_gpr_dw0(r2));
12064 assign(len1, get_gpr_dw0(r1 + 1));
12065 assign(len2, get_gpr_dw0(r2 + 1));
12066
12067 UInt extended_checking = s390_host_has_etf3 && (m3 & 0x1) == 1;
12068
12069 /* We're processing the 2nd operand 1 byte at a time. Therefore, if
12070 there is less than 1 byte left, then the 2nd operand is exhausted
12071 and we're done here. cc = 0 */
12072 s390_cc_set(0);
12073 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(1)));
12074
12075 /* There is at least one byte there. Read it. */
florian11b8ee82012-08-06 13:35:33 +000012076 IRTemp byte1 = newTemp(Ity_I64);
12077 assign(byte1, unop(Iop_8Uto64, load(Ity_I8, mkexpr(addr2))));
florian6d9b9b22012-08-03 18:35:39 +000012078
12079 /* Call the helper to get number of bytes and invalid byte indicator */
12080 IRTemp retval1 = newTemp(Ity_I64);
florian3f8a96a2012-08-05 02:59:55 +000012081 assign(retval1, s390_call_cu12_cu14_helper1(mkexpr(byte1),
florian11b8ee82012-08-06 13:35:33 +000012082 mkU64(extended_checking)));
florian6d9b9b22012-08-03 18:35:39 +000012083
12084 /* Check for invalid 1st byte */
12085 IRExpr *is_invalid = unop(Iop_64to1, mkexpr(retval1));
12086 s390_cc_set(2);
12087 next_insn_if(is_invalid);
12088
12089 /* How many bytes do we have to read? */
12090 IRTemp num_src_bytes = newTemp(Ity_I64);
12091 assign(num_src_bytes, binop(Iop_Shr64, mkexpr(retval1), mkU8(8)));
12092
12093 /* Now test whether the 2nd operand is exhausted */
12094 s390_cc_set(0);
12095 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkexpr(num_src_bytes)));
12096
12097 /* Read the remaining bytes */
12098 IRExpr *cond, *addr, *byte2, *byte3, *byte4;
12099
12100 cond = binop(Iop_CmpLE64U, mkU64(2), mkexpr(num_src_bytes));
12101 addr = binop(Iop_Add64, mkexpr(addr2), mkU64(1));
florian11b8ee82012-08-06 13:35:33 +000012102 byte2 = mkite(cond, unop(Iop_8Uto64, load(Ity_I8, addr)), mkU64(0));
florian6d9b9b22012-08-03 18:35:39 +000012103 cond = binop(Iop_CmpLE64U, mkU64(3), mkexpr(num_src_bytes));
12104 addr = binop(Iop_Add64, mkexpr(addr2), mkU64(2));
florian11b8ee82012-08-06 13:35:33 +000012105 byte3 = mkite(cond, unop(Iop_8Uto64, load(Ity_I8, addr)), mkU64(0));
florian6d9b9b22012-08-03 18:35:39 +000012106 cond = binop(Iop_CmpLE64U, mkU64(4), mkexpr(num_src_bytes));
12107 addr = binop(Iop_Add64, mkexpr(addr2), mkU64(3));
florian11b8ee82012-08-06 13:35:33 +000012108 byte4 = mkite(cond, unop(Iop_8Uto64, load(Ity_I8, addr)), mkU64(0));
florian6d9b9b22012-08-03 18:35:39 +000012109
12110 /* Call the helper to get the converted value and invalid byte indicator.
12111 We can pass at most 5 arguments; therefore some encoding is needed
12112 here */
12113 IRExpr *stuff = binop(Iop_Or64,
12114 binop(Iop_Shl64, mkexpr(num_src_bytes), mkU8(1)),
12115 mkU64(extended_checking));
12116 IRTemp retval2 = newTemp(Ity_I64);
florian3f8a96a2012-08-05 02:59:55 +000012117
12118 if (is_cu12) {
12119 assign(retval2, s390_call_cu12_helper2(mkexpr(byte1), byte2, byte3,
12120 byte4, stuff));
12121 } else {
12122 assign(retval2, s390_call_cu14_helper2(mkexpr(byte1), byte2, byte3,
12123 byte4, stuff));
12124 }
florian6d9b9b22012-08-03 18:35:39 +000012125
12126 /* Check for invalid character */
12127 s390_cc_set(2);
12128 is_invalid = unop(Iop_64to1, mkexpr(retval2));
12129 next_insn_if(is_invalid);
12130
12131 /* Now test whether the 1st operand is exhausted */
12132 IRTemp num_bytes = newTemp(Ity_I64);
12133 assign(num_bytes, binop(Iop_And64,
12134 binop(Iop_Shr64, mkexpr(retval2), mkU8(8)),
12135 mkU64(0xff)));
12136 s390_cc_set(1);
12137 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
12138
12139 /* Extract the bytes to be stored at addr1 */
12140 IRTemp data = newTemp(Ity_I64);
12141 assign(data, binop(Iop_Shr64, mkexpr(retval2), mkU8(16)));
12142
florian3f8a96a2012-08-05 02:59:55 +000012143 if (is_cu12) {
12144 /* To store the bytes construct 2 dirty helper calls. The helper calls
12145 are guarded (num_bytes == 2 and num_bytes == 4, respectively) such
12146 that only one of them will be called at runtime. */
florian6d9b9b22012-08-03 18:35:39 +000012147
florian3f8a96a2012-08-05 02:59:55 +000012148 Int i;
12149 for (i = 2; i <= 4; ++i) {
12150 IRDirty *d;
florian6d9b9b22012-08-03 18:35:39 +000012151
florian3f8a96a2012-08-05 02:59:55 +000012152 if (i == 3) continue; // skip this one
florian6d9b9b22012-08-03 18:35:39 +000012153
florian3f8a96a2012-08-05 02:59:55 +000012154 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
12155 &s390x_dirtyhelper_CUxy,
12156 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
12157 mkexpr(num_bytes)));
12158 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
12159 d->mFx = Ifx_Write;
12160 d->mAddr = mkexpr(addr1);
12161 d->mSize = i;
12162 stmt(IRStmt_Dirty(d));
12163 }
12164 } else {
12165 // cu14
12166 store(mkexpr(addr1), unop(Iop_64to32, mkexpr(data)));
florian6d9b9b22012-08-03 18:35:39 +000012167 }
12168
12169 /* Update source address and length */
12170 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkexpr(num_src_bytes)));
12171 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkexpr(num_src_bytes)));
12172
12173 /* Update destination address and length */
12174 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
12175 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
12176
12177 iterate();
florian3f8a96a2012-08-05 02:59:55 +000012178}
12179
12180static HChar *
12181s390_irgen_CU12(UChar m3, UChar r1, UChar r2)
12182{
12183 s390_irgen_cu12_cu14(m3, r1, r2, /* is_cu12 = */ 1);
florian6d9b9b22012-08-03 18:35:39 +000012184
12185 return "cu12";
12186}
12187
florian3f8a96a2012-08-05 02:59:55 +000012188static HChar *
12189s390_irgen_CU14(UChar m3, UChar r1, UChar r2)
12190{
12191 s390_irgen_cu12_cu14(m3, r1, r2, /* is_cu12 = */ 0);
12192
12193 return "cu14";
12194}
12195
florian8c88cb62012-08-26 18:58:13 +000012196static IRExpr *
12197s390_call_ecag(IRExpr *op2addr)
12198{
12199 IRExpr **args, *call;
12200
12201 args = mkIRExprVec_1(op2addr);
12202 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
12203 "s390_do_ecag", &s390_do_ecag, args);
12204
12205 /* Nothing is excluded from definedness checking. */
12206 call->Iex.CCall.cee->mcx_mask = 0;
12207
12208 return call;
12209}
12210
12211static HChar *
floriand2129202012-09-01 20:01:39 +000012212s390_irgen_ECAG(UChar r1, UChar r3 __attribute__((unused)), IRTemp op2addr)
florian8c88cb62012-08-26 18:58:13 +000012213{
12214 if (! s390_host_has_gie) {
floriane75dafa2012-09-01 17:54:09 +000012215 emulation_failure(EmFail_S390X_ecag);
florian8c88cb62012-08-26 18:58:13 +000012216 } else {
12217 put_gpr_dw0(r1, s390_call_ecag(mkexpr(op2addr)));
12218 }
12219
12220 return "ecag";
12221}
12222
12223
sewardj2019a972011-03-07 16:04:07 +000012224/*------------------------------------------------------------*/
12225/*--- Build IR for special instructions ---*/
12226/*------------------------------------------------------------*/
12227
florianb4df7682011-07-05 02:09:01 +000012228static void
sewardj2019a972011-03-07 16:04:07 +000012229s390_irgen_client_request(void)
12230{
12231 if (0)
12232 vex_printf("%%R3 = client_request ( %%R2 )\n");
12233
florianf9e1ed72012-04-17 02:41:56 +000012234 Addr64 next = guest_IA_curr_instr + S390_SPECIAL_OP_PREAMBLE_SIZE
12235 + S390_SPECIAL_OP_SIZE;
sewardj2019a972011-03-07 16:04:07 +000012236
florianf9e1ed72012-04-17 02:41:56 +000012237 dis_res->jk_StopHere = Ijk_ClientReq;
sewardj2019a972011-03-07 16:04:07 +000012238 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +000012239
12240 put_IA(mkaddr_expr(next));
sewardj2019a972011-03-07 16:04:07 +000012241}
12242
florianb4df7682011-07-05 02:09:01 +000012243static void
sewardj2019a972011-03-07 16:04:07 +000012244s390_irgen_guest_NRADDR(void)
12245{
12246 if (0)
12247 vex_printf("%%R3 = guest_NRADDR\n");
12248
floriane88b3c92011-07-05 02:48:39 +000012249 put_gpr_dw0(3, IRExpr_Get(S390X_GUEST_OFFSET(guest_NRADDR), Ity_I64));
sewardj2019a972011-03-07 16:04:07 +000012250}
12251
florianb4df7682011-07-05 02:09:01 +000012252static void
sewardj2019a972011-03-07 16:04:07 +000012253s390_irgen_call_noredir(void)
12254{
florianf9e1ed72012-04-17 02:41:56 +000012255 Addr64 next = guest_IA_curr_instr + S390_SPECIAL_OP_PREAMBLE_SIZE
12256 + S390_SPECIAL_OP_SIZE;
12257
sewardj2019a972011-03-07 16:04:07 +000012258 /* Continue after special op */
florianf9e1ed72012-04-17 02:41:56 +000012259 put_gpr_dw0(14, mkaddr_expr(next));
sewardj2019a972011-03-07 16:04:07 +000012260
12261 /* The address is in REG1, all parameters are in the right (guest) places */
florianf9e1ed72012-04-17 02:41:56 +000012262 put_IA(get_gpr_dw0(1));
sewardj2019a972011-03-07 16:04:07 +000012263
12264 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +000012265 dis_res->jk_StopHere = Ijk_NoRedir;
sewardj2019a972011-03-07 16:04:07 +000012266}
12267
12268/* Force proper alignment for the structures below. */
12269#pragma pack(1)
12270
12271
12272static s390_decode_t
12273s390_decode_2byte_and_irgen(UChar *bytes)
12274{
12275 typedef union {
12276 struct {
12277 unsigned int op : 16;
12278 } E;
12279 struct {
12280 unsigned int op : 8;
12281 unsigned int i : 8;
12282 } I;
12283 struct {
12284 unsigned int op : 8;
12285 unsigned int r1 : 4;
12286 unsigned int r2 : 4;
12287 } RR;
12288 } formats;
12289 union {
12290 formats fmt;
12291 UShort value;
12292 } ovl;
12293
12294 vassert(sizeof(formats) == 2);
12295
12296 ((char *)(&ovl.value))[0] = bytes[0];
12297 ((char *)(&ovl.value))[1] = bytes[1];
12298
12299 switch (ovl.value & 0xffff) {
12300 case 0x0101: /* PR */ goto unimplemented;
12301 case 0x0102: /* UPT */ goto unimplemented;
12302 case 0x0104: /* PTFF */ goto unimplemented;
12303 case 0x0107: /* SCKPF */ goto unimplemented;
12304 case 0x010a: /* PFPO */ goto unimplemented;
12305 case 0x010b: /* TAM */ goto unimplemented;
12306 case 0x010c: /* SAM24 */ goto unimplemented;
12307 case 0x010d: /* SAM31 */ goto unimplemented;
12308 case 0x010e: /* SAM64 */ goto unimplemented;
12309 case 0x01ff: /* TRAP2 */ goto unimplemented;
12310 }
12311
12312 switch ((ovl.value & 0xff00) >> 8) {
12313 case 0x04: /* SPM */ goto unimplemented;
12314 case 0x05: /* BALR */ goto unimplemented;
12315 case 0x06: s390_format_RR_RR(s390_irgen_BCTR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12316 goto ok;
12317 case 0x07: s390_format_RR(s390_irgen_BCR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12318 goto ok;
12319 case 0x0a: s390_format_I(s390_irgen_SVC, ovl.fmt.I.i); goto ok;
12320 case 0x0b: /* BSM */ goto unimplemented;
12321 case 0x0c: /* BASSM */ goto unimplemented;
12322 case 0x0d: s390_format_RR_RR(s390_irgen_BASR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12323 goto ok;
florianb0c9a132011-09-08 15:37:39 +000012324 case 0x0e: s390_format_RR(s390_irgen_MVCL, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12325 goto ok;
12326 case 0x0f: s390_format_RR(s390_irgen_CLCL, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12327 goto ok;
sewardj2019a972011-03-07 16:04:07 +000012328 case 0x10: s390_format_RR_RR(s390_irgen_LPR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12329 goto ok;
12330 case 0x11: s390_format_RR_RR(s390_irgen_LNR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12331 goto ok;
12332 case 0x12: s390_format_RR_RR(s390_irgen_LTR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12333 goto ok;
12334 case 0x13: s390_format_RR_RR(s390_irgen_LCR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12335 goto ok;
12336 case 0x14: s390_format_RR_RR(s390_irgen_NR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12337 goto ok;
12338 case 0x15: s390_format_RR_RR(s390_irgen_CLR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12339 goto ok;
12340 case 0x16: s390_format_RR_RR(s390_irgen_OR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12341 goto ok;
12342 case 0x17: s390_format_RR_RR(s390_irgen_XR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12343 goto ok;
12344 case 0x18: s390_format_RR_RR(s390_irgen_LR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12345 goto ok;
12346 case 0x19: s390_format_RR_RR(s390_irgen_CR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12347 goto ok;
12348 case 0x1a: s390_format_RR_RR(s390_irgen_AR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12349 goto ok;
12350 case 0x1b: s390_format_RR_RR(s390_irgen_SR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12351 goto ok;
12352 case 0x1c: s390_format_RR_RR(s390_irgen_MR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12353 goto ok;
12354 case 0x1d: s390_format_RR_RR(s390_irgen_DR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12355 goto ok;
12356 case 0x1e: s390_format_RR_RR(s390_irgen_ALR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12357 goto ok;
12358 case 0x1f: s390_format_RR_RR(s390_irgen_SLR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12359 goto ok;
12360 case 0x20: /* LPDR */ goto unimplemented;
12361 case 0x21: /* LNDR */ goto unimplemented;
12362 case 0x22: /* LTDR */ goto unimplemented;
12363 case 0x23: /* LCDR */ goto unimplemented;
12364 case 0x24: /* HDR */ goto unimplemented;
12365 case 0x25: /* LDXR */ goto unimplemented;
12366 case 0x26: /* MXR */ goto unimplemented;
12367 case 0x27: /* MXDR */ goto unimplemented;
12368 case 0x28: s390_format_RR_FF(s390_irgen_LDR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12369 goto ok;
12370 case 0x29: /* CDR */ goto unimplemented;
12371 case 0x2a: /* ADR */ goto unimplemented;
12372 case 0x2b: /* SDR */ goto unimplemented;
12373 case 0x2c: /* MDR */ goto unimplemented;
12374 case 0x2d: /* DDR */ goto unimplemented;
12375 case 0x2e: /* AWR */ goto unimplemented;
12376 case 0x2f: /* SWR */ goto unimplemented;
12377 case 0x30: /* LPER */ goto unimplemented;
12378 case 0x31: /* LNER */ goto unimplemented;
12379 case 0x32: /* LTER */ goto unimplemented;
12380 case 0x33: /* LCER */ goto unimplemented;
12381 case 0x34: /* HER */ goto unimplemented;
12382 case 0x35: /* LEDR */ goto unimplemented;
12383 case 0x36: /* AXR */ goto unimplemented;
12384 case 0x37: /* SXR */ goto unimplemented;
12385 case 0x38: s390_format_RR_FF(s390_irgen_LER, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12386 goto ok;
12387 case 0x39: /* CER */ goto unimplemented;
12388 case 0x3a: /* AER */ goto unimplemented;
12389 case 0x3b: /* SER */ goto unimplemented;
12390 case 0x3c: /* MDER */ goto unimplemented;
12391 case 0x3d: /* DER */ goto unimplemented;
12392 case 0x3e: /* AUR */ goto unimplemented;
12393 case 0x3f: /* SUR */ goto unimplemented;
12394 }
12395
12396 return S390_DECODE_UNKNOWN_INSN;
12397
12398ok:
12399 return S390_DECODE_OK;
12400
12401unimplemented:
12402 return S390_DECODE_UNIMPLEMENTED_INSN;
12403}
12404
12405static s390_decode_t
12406s390_decode_4byte_and_irgen(UChar *bytes)
12407{
12408 typedef union {
12409 struct {
12410 unsigned int op1 : 8;
12411 unsigned int r1 : 4;
12412 unsigned int op2 : 4;
12413 unsigned int i2 : 16;
12414 } RI;
12415 struct {
12416 unsigned int op : 16;
12417 unsigned int : 8;
12418 unsigned int r1 : 4;
12419 unsigned int r2 : 4;
12420 } RRE;
12421 struct {
12422 unsigned int op : 16;
12423 unsigned int r1 : 4;
12424 unsigned int : 4;
12425 unsigned int r3 : 4;
12426 unsigned int r2 : 4;
12427 } RRF;
12428 struct {
12429 unsigned int op : 16;
florian1c8f7ff2012-09-01 00:12:11 +000012430 unsigned int m3 : 4;
sewardj2019a972011-03-07 16:04:07 +000012431 unsigned int m4 : 4;
12432 unsigned int r1 : 4;
12433 unsigned int r2 : 4;
12434 } RRF2;
12435 struct {
12436 unsigned int op : 16;
12437 unsigned int r3 : 4;
12438 unsigned int : 4;
12439 unsigned int r1 : 4;
12440 unsigned int r2 : 4;
12441 } RRF3;
12442 struct {
12443 unsigned int op : 16;
12444 unsigned int r3 : 4;
12445 unsigned int : 4;
12446 unsigned int r1 : 4;
12447 unsigned int r2 : 4;
12448 } RRR;
12449 struct {
12450 unsigned int op : 16;
12451 unsigned int r3 : 4;
12452 unsigned int : 4;
12453 unsigned int r1 : 4;
12454 unsigned int r2 : 4;
12455 } RRF4;
12456 struct {
12457 unsigned int op : 8;
12458 unsigned int r1 : 4;
12459 unsigned int r3 : 4;
12460 unsigned int b2 : 4;
12461 unsigned int d2 : 12;
12462 } RS;
12463 struct {
12464 unsigned int op : 8;
12465 unsigned int r1 : 4;
12466 unsigned int r3 : 4;
12467 unsigned int i2 : 16;
12468 } RSI;
12469 struct {
12470 unsigned int op : 8;
12471 unsigned int r1 : 4;
12472 unsigned int x2 : 4;
12473 unsigned int b2 : 4;
12474 unsigned int d2 : 12;
12475 } RX;
12476 struct {
12477 unsigned int op : 16;
12478 unsigned int b2 : 4;
12479 unsigned int d2 : 12;
12480 } S;
12481 struct {
12482 unsigned int op : 8;
12483 unsigned int i2 : 8;
12484 unsigned int b1 : 4;
12485 unsigned int d1 : 12;
12486 } SI;
12487 } formats;
12488 union {
12489 formats fmt;
12490 UInt value;
12491 } ovl;
12492
12493 vassert(sizeof(formats) == 4);
12494
12495 ((char *)(&ovl.value))[0] = bytes[0];
12496 ((char *)(&ovl.value))[1] = bytes[1];
12497 ((char *)(&ovl.value))[2] = bytes[2];
12498 ((char *)(&ovl.value))[3] = bytes[3];
12499
12500 switch ((ovl.value & 0xff0f0000) >> 16) {
12501 case 0xa500: s390_format_RI_RU(s390_irgen_IIHH, ovl.fmt.RI.r1,
12502 ovl.fmt.RI.i2); goto ok;
12503 case 0xa501: s390_format_RI_RU(s390_irgen_IIHL, ovl.fmt.RI.r1,
12504 ovl.fmt.RI.i2); goto ok;
12505 case 0xa502: s390_format_RI_RU(s390_irgen_IILH, ovl.fmt.RI.r1,
12506 ovl.fmt.RI.i2); goto ok;
12507 case 0xa503: s390_format_RI_RU(s390_irgen_IILL, ovl.fmt.RI.r1,
12508 ovl.fmt.RI.i2); goto ok;
12509 case 0xa504: s390_format_RI_RU(s390_irgen_NIHH, ovl.fmt.RI.r1,
12510 ovl.fmt.RI.i2); goto ok;
12511 case 0xa505: s390_format_RI_RU(s390_irgen_NIHL, ovl.fmt.RI.r1,
12512 ovl.fmt.RI.i2); goto ok;
12513 case 0xa506: s390_format_RI_RU(s390_irgen_NILH, ovl.fmt.RI.r1,
12514 ovl.fmt.RI.i2); goto ok;
12515 case 0xa507: s390_format_RI_RU(s390_irgen_NILL, ovl.fmt.RI.r1,
12516 ovl.fmt.RI.i2); goto ok;
12517 case 0xa508: s390_format_RI_RU(s390_irgen_OIHH, ovl.fmt.RI.r1,
12518 ovl.fmt.RI.i2); goto ok;
12519 case 0xa509: s390_format_RI_RU(s390_irgen_OIHL, ovl.fmt.RI.r1,
12520 ovl.fmt.RI.i2); goto ok;
12521 case 0xa50a: s390_format_RI_RU(s390_irgen_OILH, ovl.fmt.RI.r1,
12522 ovl.fmt.RI.i2); goto ok;
12523 case 0xa50b: s390_format_RI_RU(s390_irgen_OILL, ovl.fmt.RI.r1,
12524 ovl.fmt.RI.i2); goto ok;
12525 case 0xa50c: s390_format_RI_RU(s390_irgen_LLIHH, ovl.fmt.RI.r1,
12526 ovl.fmt.RI.i2); goto ok;
12527 case 0xa50d: s390_format_RI_RU(s390_irgen_LLIHL, ovl.fmt.RI.r1,
12528 ovl.fmt.RI.i2); goto ok;
12529 case 0xa50e: s390_format_RI_RU(s390_irgen_LLILH, ovl.fmt.RI.r1,
12530 ovl.fmt.RI.i2); goto ok;
12531 case 0xa50f: s390_format_RI_RU(s390_irgen_LLILL, ovl.fmt.RI.r1,
12532 ovl.fmt.RI.i2); goto ok;
12533 case 0xa700: s390_format_RI_RU(s390_irgen_TMLH, ovl.fmt.RI.r1,
12534 ovl.fmt.RI.i2); goto ok;
12535 case 0xa701: s390_format_RI_RU(s390_irgen_TMLL, ovl.fmt.RI.r1,
12536 ovl.fmt.RI.i2); goto ok;
12537 case 0xa702: s390_format_RI_RU(s390_irgen_TMHH, ovl.fmt.RI.r1,
12538 ovl.fmt.RI.i2); goto ok;
12539 case 0xa703: s390_format_RI_RU(s390_irgen_TMHL, ovl.fmt.RI.r1,
12540 ovl.fmt.RI.i2); goto ok;
12541 case 0xa704: s390_format_RI(s390_irgen_BRC, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
12542 goto ok;
12543 case 0xa705: s390_format_RI_RP(s390_irgen_BRAS, ovl.fmt.RI.r1,
12544 ovl.fmt.RI.i2); goto ok;
12545 case 0xa706: s390_format_RI_RP(s390_irgen_BRCT, ovl.fmt.RI.r1,
12546 ovl.fmt.RI.i2); goto ok;
12547 case 0xa707: s390_format_RI_RP(s390_irgen_BRCTG, ovl.fmt.RI.r1,
12548 ovl.fmt.RI.i2); goto ok;
12549 case 0xa708: s390_format_RI_RI(s390_irgen_LHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
12550 goto ok;
12551 case 0xa709: s390_format_RI_RI(s390_irgen_LGHI, ovl.fmt.RI.r1,
12552 ovl.fmt.RI.i2); goto ok;
12553 case 0xa70a: s390_format_RI_RI(s390_irgen_AHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
12554 goto ok;
12555 case 0xa70b: s390_format_RI_RI(s390_irgen_AGHI, ovl.fmt.RI.r1,
12556 ovl.fmt.RI.i2); goto ok;
12557 case 0xa70c: s390_format_RI_RI(s390_irgen_MHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
12558 goto ok;
12559 case 0xa70d: s390_format_RI_RI(s390_irgen_MGHI, ovl.fmt.RI.r1,
12560 ovl.fmt.RI.i2); goto ok;
12561 case 0xa70e: s390_format_RI_RI(s390_irgen_CHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
12562 goto ok;
12563 case 0xa70f: s390_format_RI_RI(s390_irgen_CGHI, ovl.fmt.RI.r1,
12564 ovl.fmt.RI.i2); goto ok;
12565 }
12566
12567 switch ((ovl.value & 0xffff0000) >> 16) {
12568 case 0x8000: /* SSM */ goto unimplemented;
12569 case 0x8200: /* LPSW */ goto unimplemented;
florian7700fc92012-01-16 17:25:55 +000012570 case 0x9300: /* TS */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000012571 case 0xb202: /* STIDP */ goto unimplemented;
12572 case 0xb204: /* SCK */ goto unimplemented;
florian7700fc92012-01-16 17:25:55 +000012573 case 0xb205: s390_format_S_RD(s390_irgen_STCK, ovl.fmt.S.b2, ovl.fmt.S.d2);
12574 goto ok;
sewardj2019a972011-03-07 16:04:07 +000012575 case 0xb206: /* SCKC */ goto unimplemented;
12576 case 0xb207: /* STCKC */ goto unimplemented;
12577 case 0xb208: /* SPT */ goto unimplemented;
12578 case 0xb209: /* STPT */ goto unimplemented;
12579 case 0xb20a: /* SPKA */ goto unimplemented;
12580 case 0xb20b: /* IPK */ goto unimplemented;
12581 case 0xb20d: /* PTLB */ goto unimplemented;
12582 case 0xb210: /* SPX */ goto unimplemented;
12583 case 0xb211: /* STPX */ goto unimplemented;
12584 case 0xb212: /* STAP */ goto unimplemented;
12585 case 0xb214: /* SIE */ goto unimplemented;
12586 case 0xb218: /* PC */ goto unimplemented;
12587 case 0xb219: /* SAC */ goto unimplemented;
12588 case 0xb21a: /* CFC */ goto unimplemented;
12589 case 0xb221: /* IPTE */ goto unimplemented;
12590 case 0xb222: s390_format_RRE_R0(s390_irgen_IPM, ovl.fmt.RRE.r1); goto ok;
12591 case 0xb223: /* IVSK */ goto unimplemented;
12592 case 0xb224: /* IAC */ goto unimplemented;
12593 case 0xb225: /* SSAR */ goto unimplemented;
12594 case 0xb226: /* EPAR */ goto unimplemented;
12595 case 0xb227: /* ESAR */ goto unimplemented;
12596 case 0xb228: /* PT */ goto unimplemented;
12597 case 0xb229: /* ISKE */ goto unimplemented;
12598 case 0xb22a: /* RRBE */ goto unimplemented;
12599 case 0xb22b: /* SSKE */ goto unimplemented;
12600 case 0xb22c: /* TB */ goto unimplemented;
12601 case 0xb22d: /* DXR */ goto unimplemented;
12602 case 0xb22e: /* PGIN */ goto unimplemented;
12603 case 0xb22f: /* PGOUT */ goto unimplemented;
12604 case 0xb230: /* CSCH */ goto unimplemented;
12605 case 0xb231: /* HSCH */ goto unimplemented;
12606 case 0xb232: /* MSCH */ goto unimplemented;
12607 case 0xb233: /* SSCH */ goto unimplemented;
12608 case 0xb234: /* STSCH */ goto unimplemented;
12609 case 0xb235: /* TSCH */ goto unimplemented;
12610 case 0xb236: /* TPI */ goto unimplemented;
12611 case 0xb237: /* SAL */ goto unimplemented;
12612 case 0xb238: /* RSCH */ goto unimplemented;
12613 case 0xb239: /* STCRW */ goto unimplemented;
12614 case 0xb23a: /* STCPS */ goto unimplemented;
12615 case 0xb23b: /* RCHP */ goto unimplemented;
12616 case 0xb23c: /* SCHM */ goto unimplemented;
12617 case 0xb240: /* BAKR */ goto unimplemented;
floriana4384a32011-08-11 16:58:45 +000012618 case 0xb241: s390_format_RRE(s390_irgen_CKSM, ovl.fmt.RRE.r1,
12619 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000012620 case 0xb244: /* SQDR */ goto unimplemented;
12621 case 0xb245: /* SQER */ goto unimplemented;
12622 case 0xb246: /* STURA */ goto unimplemented;
12623 case 0xb247: /* MSTA */ goto unimplemented;
12624 case 0xb248: /* PALB */ goto unimplemented;
12625 case 0xb249: /* EREG */ goto unimplemented;
12626 case 0xb24a: /* ESTA */ goto unimplemented;
12627 case 0xb24b: /* LURA */ goto unimplemented;
12628 case 0xb24c: /* TAR */ goto unimplemented;
12629 case 0xb24d: s390_format_RRE(s390_irgen_CPYA, ovl.fmt.RRE.r1,
12630 ovl.fmt.RRE.r2); goto ok;
12631 case 0xb24e: s390_format_RRE(s390_irgen_SAR, ovl.fmt.RRE.r1, ovl.fmt.RRE.r2);
12632 goto ok;
12633 case 0xb24f: s390_format_RRE(s390_irgen_EAR, ovl.fmt.RRE.r1, ovl.fmt.RRE.r2);
12634 goto ok;
12635 case 0xb250: /* CSP */ goto unimplemented;
12636 case 0xb252: s390_format_RRE_RR(s390_irgen_MSR, ovl.fmt.RRE.r1,
12637 ovl.fmt.RRE.r2); goto ok;
12638 case 0xb254: /* MVPG */ goto unimplemented;
12639 case 0xb255: s390_format_RRE_RR(s390_irgen_MVST, ovl.fmt.RRE.r1,
12640 ovl.fmt.RRE.r2); goto ok;
12641 case 0xb257: /* CUSE */ goto unimplemented;
12642 case 0xb258: /* BSG */ goto unimplemented;
12643 case 0xb25a: /* BSA */ goto unimplemented;
12644 case 0xb25d: s390_format_RRE_RR(s390_irgen_CLST, ovl.fmt.RRE.r1,
12645 ovl.fmt.RRE.r2); goto ok;
12646 case 0xb25e: s390_format_RRE_RR(s390_irgen_SRST, ovl.fmt.RRE.r1,
12647 ovl.fmt.RRE.r2); goto ok;
12648 case 0xb263: /* CMPSC */ goto unimplemented;
12649 case 0xb274: /* SIGA */ goto unimplemented;
12650 case 0xb276: /* XSCH */ goto unimplemented;
12651 case 0xb277: /* RP */ goto unimplemented;
sewardj1e5fea62011-05-17 16:18:36 +000012652 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 +000012653 case 0xb279: /* SACF */ goto unimplemented;
sewardj1e5fea62011-05-17 16:18:36 +000012654 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 +000012655 case 0xb27d: /* STSI */ goto unimplemented;
12656 case 0xb299: s390_format_S_RD(s390_irgen_SRNM, ovl.fmt.S.b2, ovl.fmt.S.d2);
12657 goto ok;
12658 case 0xb29c: s390_format_S_RD(s390_irgen_STFPC, ovl.fmt.S.b2, ovl.fmt.S.d2);
12659 goto ok;
12660 case 0xb29d: s390_format_S_RD(s390_irgen_LFPC, ovl.fmt.S.b2, ovl.fmt.S.d2);
12661 goto ok;
florian730448f2012-02-04 17:07:07 +000012662 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 +000012663 case 0xb2a6: s390_format_RRF_M0RERE(s390_irgen_CU21, ovl.fmt.RRF3.r3,
12664 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
12665 goto ok;
florian6d9b9b22012-08-03 18:35:39 +000012666 case 0xb2a7: s390_format_RRF_M0RERE(s390_irgen_CU12, ovl.fmt.RRF3.r3,
12667 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
12668 goto ok;
florian933065d2011-07-11 01:48:02 +000012669 case 0xb2b0: s390_format_S_RD(s390_irgen_STFLE, ovl.fmt.S.b2, ovl.fmt.S.d2);
12670 goto ok;
sewardj2019a972011-03-07 16:04:07 +000012671 case 0xb2b1: /* STFL */ goto unimplemented;
12672 case 0xb2b2: /* LPSWE */ goto unimplemented;
florianf0fa1be2012-09-18 20:24:38 +000012673 case 0xb2b8: s390_irgen_srnmb_wrapper(ovl.fmt.S.b2, ovl.fmt.S.d2);
12674 goto ok;
sewardj2019a972011-03-07 16:04:07 +000012675 case 0xb2b9: /* SRNMT */ goto unimplemented;
12676 case 0xb2bd: /* LFAS */ goto unimplemented;
12677 case 0xb2ff: /* TRAP4 */ goto unimplemented;
12678 case 0xb300: s390_format_RRE_FF(s390_irgen_LPEBR, ovl.fmt.RRE.r1,
12679 ovl.fmt.RRE.r2); goto ok;
12680 case 0xb301: s390_format_RRE_FF(s390_irgen_LNEBR, ovl.fmt.RRE.r1,
12681 ovl.fmt.RRE.r2); goto ok;
12682 case 0xb302: s390_format_RRE_FF(s390_irgen_LTEBR, ovl.fmt.RRE.r1,
12683 ovl.fmt.RRE.r2); goto ok;
12684 case 0xb303: s390_format_RRE_FF(s390_irgen_LCEBR, ovl.fmt.RRE.r1,
12685 ovl.fmt.RRE.r2); goto ok;
12686 case 0xb304: s390_format_RRE_FF(s390_irgen_LDEBR, ovl.fmt.RRE.r1,
12687 ovl.fmt.RRE.r2); goto ok;
12688 case 0xb305: s390_format_RRE_FF(s390_irgen_LXDBR, ovl.fmt.RRE.r1,
12689 ovl.fmt.RRE.r2); goto ok;
12690 case 0xb306: s390_format_RRE_FF(s390_irgen_LXEBR, ovl.fmt.RRE.r1,
12691 ovl.fmt.RRE.r2); goto ok;
12692 case 0xb307: /* MXDBR */ goto unimplemented;
12693 case 0xb308: /* KEBR */ goto unimplemented;
12694 case 0xb309: s390_format_RRE_FF(s390_irgen_CEBR, ovl.fmt.RRE.r1,
12695 ovl.fmt.RRE.r2); goto ok;
12696 case 0xb30a: s390_format_RRE_FF(s390_irgen_AEBR, ovl.fmt.RRE.r1,
12697 ovl.fmt.RRE.r2); goto ok;
12698 case 0xb30b: s390_format_RRE_FF(s390_irgen_SEBR, ovl.fmt.RRE.r1,
12699 ovl.fmt.RRE.r2); goto ok;
12700 case 0xb30c: /* MDEBR */ goto unimplemented;
12701 case 0xb30d: s390_format_RRE_FF(s390_irgen_DEBR, ovl.fmt.RRE.r1,
12702 ovl.fmt.RRE.r2); goto ok;
12703 case 0xb30e: s390_format_RRF_F0FF(s390_irgen_MAEBR, ovl.fmt.RRF.r1,
12704 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
12705 case 0xb30f: s390_format_RRF_F0FF(s390_irgen_MSEBR, ovl.fmt.RRF.r1,
12706 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
12707 case 0xb310: s390_format_RRE_FF(s390_irgen_LPDBR, ovl.fmt.RRE.r1,
12708 ovl.fmt.RRE.r2); goto ok;
12709 case 0xb311: s390_format_RRE_FF(s390_irgen_LNDBR, ovl.fmt.RRE.r1,
12710 ovl.fmt.RRE.r2); goto ok;
12711 case 0xb312: s390_format_RRE_FF(s390_irgen_LTDBR, ovl.fmt.RRE.r1,
12712 ovl.fmt.RRE.r2); goto ok;
12713 case 0xb313: s390_format_RRE_FF(s390_irgen_LCDBR, ovl.fmt.RRE.r1,
12714 ovl.fmt.RRE.r2); goto ok;
12715 case 0xb314: s390_format_RRE_FF(s390_irgen_SQEBR, ovl.fmt.RRE.r1,
12716 ovl.fmt.RRE.r2); goto ok;
12717 case 0xb315: s390_format_RRE_FF(s390_irgen_SQDBR, ovl.fmt.RRE.r1,
12718 ovl.fmt.RRE.r2); goto ok;
12719 case 0xb316: s390_format_RRE_FF(s390_irgen_SQXBR, ovl.fmt.RRE.r1,
12720 ovl.fmt.RRE.r2); goto ok;
12721 case 0xb317: s390_format_RRE_FF(s390_irgen_MEEBR, ovl.fmt.RRE.r1,
12722 ovl.fmt.RRE.r2); goto ok;
12723 case 0xb318: /* KDBR */ goto unimplemented;
12724 case 0xb319: s390_format_RRE_FF(s390_irgen_CDBR, ovl.fmt.RRE.r1,
12725 ovl.fmt.RRE.r2); goto ok;
12726 case 0xb31a: s390_format_RRE_FF(s390_irgen_ADBR, ovl.fmt.RRE.r1,
12727 ovl.fmt.RRE.r2); goto ok;
12728 case 0xb31b: s390_format_RRE_FF(s390_irgen_SDBR, ovl.fmt.RRE.r1,
12729 ovl.fmt.RRE.r2); goto ok;
12730 case 0xb31c: s390_format_RRE_FF(s390_irgen_MDBR, ovl.fmt.RRE.r1,
12731 ovl.fmt.RRE.r2); goto ok;
12732 case 0xb31d: s390_format_RRE_FF(s390_irgen_DDBR, ovl.fmt.RRE.r1,
12733 ovl.fmt.RRE.r2); goto ok;
12734 case 0xb31e: s390_format_RRF_F0FF(s390_irgen_MADBR, ovl.fmt.RRF.r1,
12735 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
12736 case 0xb31f: s390_format_RRF_F0FF(s390_irgen_MSDBR, ovl.fmt.RRF.r1,
12737 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
12738 case 0xb324: /* LDER */ goto unimplemented;
12739 case 0xb325: /* LXDR */ goto unimplemented;
12740 case 0xb326: /* LXER */ goto unimplemented;
12741 case 0xb32e: /* MAER */ goto unimplemented;
12742 case 0xb32f: /* MSER */ goto unimplemented;
12743 case 0xb336: /* SQXR */ goto unimplemented;
12744 case 0xb337: /* MEER */ goto unimplemented;
12745 case 0xb338: /* MAYLR */ goto unimplemented;
12746 case 0xb339: /* MYLR */ goto unimplemented;
12747 case 0xb33a: /* MAYR */ goto unimplemented;
12748 case 0xb33b: /* MYR */ goto unimplemented;
12749 case 0xb33c: /* MAYHR */ goto unimplemented;
12750 case 0xb33d: /* MYHR */ goto unimplemented;
12751 case 0xb33e: /* MADR */ goto unimplemented;
12752 case 0xb33f: /* MSDR */ goto unimplemented;
12753 case 0xb340: s390_format_RRE_FF(s390_irgen_LPXBR, ovl.fmt.RRE.r1,
12754 ovl.fmt.RRE.r2); goto ok;
12755 case 0xb341: s390_format_RRE_FF(s390_irgen_LNXBR, ovl.fmt.RRE.r1,
12756 ovl.fmt.RRE.r2); goto ok;
12757 case 0xb342: s390_format_RRE_FF(s390_irgen_LTXBR, ovl.fmt.RRE.r1,
12758 ovl.fmt.RRE.r2); goto ok;
12759 case 0xb343: s390_format_RRE_FF(s390_irgen_LCXBR, ovl.fmt.RRE.r1,
12760 ovl.fmt.RRE.r2); goto ok;
florian4b8efad2012-09-02 18:07:08 +000012761 case 0xb344: s390_format_RRF_UUFF(s390_irgen_LEDBR, ovl.fmt.RRF2.m3,
12762 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12763 ovl.fmt.RRF2.r2); goto ok;
12764 case 0xb345: s390_format_RRF_UUFF(s390_irgen_LDXBR, ovl.fmt.RRF2.m3,
12765 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12766 ovl.fmt.RRF2.r2); goto ok;
12767 case 0xb346: s390_format_RRF_UUFF(s390_irgen_LEXBR, ovl.fmt.RRF2.m3,
12768 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12769 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000012770 case 0xb347: /* FIXBR */ goto unimplemented;
12771 case 0xb348: /* KXBR */ goto unimplemented;
12772 case 0xb349: s390_format_RRE_FF(s390_irgen_CXBR, ovl.fmt.RRE.r1,
12773 ovl.fmt.RRE.r2); goto ok;
12774 case 0xb34a: s390_format_RRE_FF(s390_irgen_AXBR, ovl.fmt.RRE.r1,
12775 ovl.fmt.RRE.r2); goto ok;
12776 case 0xb34b: s390_format_RRE_FF(s390_irgen_SXBR, ovl.fmt.RRE.r1,
12777 ovl.fmt.RRE.r2); goto ok;
12778 case 0xb34c: s390_format_RRE_FF(s390_irgen_MXBR, ovl.fmt.RRE.r1,
12779 ovl.fmt.RRE.r2); goto ok;
12780 case 0xb34d: s390_format_RRE_FF(s390_irgen_DXBR, ovl.fmt.RRE.r1,
12781 ovl.fmt.RRE.r2); goto ok;
12782 case 0xb350: /* TBEDR */ goto unimplemented;
12783 case 0xb351: /* TBDR */ goto unimplemented;
12784 case 0xb353: /* DIEBR */ goto unimplemented;
12785 case 0xb357: /* FIEBR */ goto unimplemented;
12786 case 0xb358: /* THDER */ goto unimplemented;
12787 case 0xb359: /* THDR */ goto unimplemented;
12788 case 0xb35b: /* DIDBR */ goto unimplemented;
12789 case 0xb35f: /* FIDBR */ goto unimplemented;
12790 case 0xb360: /* LPXR */ goto unimplemented;
12791 case 0xb361: /* LNXR */ goto unimplemented;
12792 case 0xb362: /* LTXR */ goto unimplemented;
12793 case 0xb363: /* LCXR */ goto unimplemented;
12794 case 0xb365: s390_format_RRE_FF(s390_irgen_LXR, ovl.fmt.RRE.r1,
12795 ovl.fmt.RRE.r2); goto ok;
12796 case 0xb366: /* LEXR */ goto unimplemented;
12797 case 0xb367: /* FIXR */ goto unimplemented;
12798 case 0xb369: /* CXR */ goto unimplemented;
12799 case 0xb370: s390_format_RRE_FF(s390_irgen_LPDFR, ovl.fmt.RRE.r1,
12800 ovl.fmt.RRE.r2); goto ok;
12801 case 0xb371: s390_format_RRE_FF(s390_irgen_LNDFR, ovl.fmt.RRE.r1,
12802 ovl.fmt.RRE.r2); goto ok;
12803 case 0xb372: s390_format_RRF_F0FF2(s390_irgen_CPSDR, ovl.fmt.RRF3.r3,
12804 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
12805 goto ok;
12806 case 0xb373: s390_format_RRE_FF(s390_irgen_LCDFR, ovl.fmt.RRE.r1,
12807 ovl.fmt.RRE.r2); goto ok;
12808 case 0xb374: s390_format_RRE_F0(s390_irgen_LZER, ovl.fmt.RRE.r1); goto ok;
12809 case 0xb375: s390_format_RRE_F0(s390_irgen_LZDR, ovl.fmt.RRE.r1); goto ok;
12810 case 0xb376: s390_format_RRE_F0(s390_irgen_LZXR, ovl.fmt.RRE.r1); goto ok;
12811 case 0xb377: /* FIER */ goto unimplemented;
12812 case 0xb37f: /* FIDR */ goto unimplemented;
12813 case 0xb384: s390_format_RRE_R0(s390_irgen_SFPC, ovl.fmt.RRE.r1); goto ok;
12814 case 0xb385: /* SFASR */ goto unimplemented;
12815 case 0xb38c: s390_format_RRE_R0(s390_irgen_EFPC, ovl.fmt.RRE.r1); goto ok;
florian1c8f7ff2012-09-01 00:12:11 +000012816 case 0xb390: s390_format_RRF_UUFR(s390_irgen_CELFBR, ovl.fmt.RRF2.m3,
12817 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12818 ovl.fmt.RRF2.r2); goto ok;
12819 case 0xb391: s390_format_RRF_UUFR(s390_irgen_CDLFBR, ovl.fmt.RRF2.m3,
12820 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12821 ovl.fmt.RRF2.r2); goto ok;
12822 case 0xb392: s390_format_RRF_UUFR(s390_irgen_CXLFBR, 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 0xb394: s390_format_RRF_UUFR(s390_irgen_CEFBR, ovl.fmt.RRF2.m3,
12826 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12827 ovl.fmt.RRF2.r2); goto ok;
12828 case 0xb395: s390_format_RRF_UUFR(s390_irgen_CDFBR, ovl.fmt.RRF2.m3,
12829 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12830 ovl.fmt.RRF2.r2); goto ok;
12831 case 0xb396: s390_format_RRF_UUFR(s390_irgen_CXFBR, ovl.fmt.RRF2.m3,
12832 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12833 ovl.fmt.RRF2.r2); goto ok;
12834 case 0xb398: s390_format_RRF_UURF(s390_irgen_CFEBR, ovl.fmt.RRF2.m3,
12835 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12836 ovl.fmt.RRF2.r2); goto ok;
12837 case 0xb399: s390_format_RRF_UURF(s390_irgen_CFDBR, ovl.fmt.RRF2.m3,
12838 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12839 ovl.fmt.RRF2.r2); goto ok;
12840 case 0xb39a: s390_format_RRF_UURF(s390_irgen_CFXBR, 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 0xb39c: s390_format_RRF_UURF(s390_irgen_CLFEBR, ovl.fmt.RRF2.m3,
12844 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12845 ovl.fmt.RRF2.r2); goto ok;
12846 case 0xb39d: s390_format_RRF_UURF(s390_irgen_CLFDBR, ovl.fmt.RRF2.m3,
12847 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12848 ovl.fmt.RRF2.r2); goto ok;
12849 case 0xb39e: s390_format_RRF_UURF(s390_irgen_CLFXBR, ovl.fmt.RRF2.m3,
12850 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12851 ovl.fmt.RRF2.r2); goto ok;
12852 case 0xb3a0: s390_format_RRF_UUFR(s390_irgen_CELGBR, ovl.fmt.RRF2.m3,
12853 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12854 ovl.fmt.RRF2.r2); goto ok;
12855 case 0xb3a1: s390_format_RRF_UUFR(s390_irgen_CDLGBR, ovl.fmt.RRF2.m3,
12856 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12857 ovl.fmt.RRF2.r2); goto ok;
12858 case 0xb3a2: s390_format_RRF_UUFR(s390_irgen_CXLGBR, ovl.fmt.RRF2.m3,
12859 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12860 ovl.fmt.RRF2.r2); goto ok;
florian4b8efad2012-09-02 18:07:08 +000012861 case 0xb3a4: s390_format_RRF_UUFR(s390_irgen_CEGBR, ovl.fmt.RRF2.m3,
12862 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12863 ovl.fmt.RRF2.r2); goto ok;
12864 case 0xb3a5: s390_format_RRF_UUFR(s390_irgen_CDGBR, ovl.fmt.RRF2.m3,
12865 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12866 ovl.fmt.RRF2.r2); goto ok;
12867 case 0xb3a6: s390_format_RRF_UUFR(s390_irgen_CXGBR, ovl.fmt.RRF2.m3,
12868 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12869 ovl.fmt.RRF2.r2); goto ok;
12870 case 0xb3a8: s390_format_RRF_UURF(s390_irgen_CGEBR, ovl.fmt.RRF2.m3,
12871 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12872 ovl.fmt.RRF2.r2); goto ok;
12873 case 0xb3a9: s390_format_RRF_UURF(s390_irgen_CGDBR, ovl.fmt.RRF2.m3,
12874 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12875 ovl.fmt.RRF2.r2); goto ok;
12876 case 0xb3aa: s390_format_RRF_UURF(s390_irgen_CGXBR, ovl.fmt.RRF2.m3,
12877 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12878 ovl.fmt.RRF2.r2); goto ok;
florian1c8f7ff2012-09-01 00:12:11 +000012879 case 0xb3ac: s390_format_RRF_UURF(s390_irgen_CLGEBR, ovl.fmt.RRF2.m3,
12880 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12881 ovl.fmt.RRF2.r2); goto ok;
12882 case 0xb3ad: s390_format_RRF_UURF(s390_irgen_CLGDBR, ovl.fmt.RRF2.m3,
12883 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12884 ovl.fmt.RRF2.r2); goto ok;
12885 case 0xb3ae: s390_format_RRF_UURF(s390_irgen_CLGXBR, ovl.fmt.RRF2.m3,
12886 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12887 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000012888 case 0xb3b4: /* CEFR */ goto unimplemented;
12889 case 0xb3b5: /* CDFR */ goto unimplemented;
12890 case 0xb3b6: /* CXFR */ goto unimplemented;
12891 case 0xb3b8: /* CFER */ goto unimplemented;
12892 case 0xb3b9: /* CFDR */ goto unimplemented;
12893 case 0xb3ba: /* CFXR */ goto unimplemented;
12894 case 0xb3c1: s390_format_RRE_FR(s390_irgen_LDGR, ovl.fmt.RRE.r1,
12895 ovl.fmt.RRE.r2); goto ok;
12896 case 0xb3c4: /* CEGR */ goto unimplemented;
12897 case 0xb3c5: /* CDGR */ goto unimplemented;
12898 case 0xb3c6: /* CXGR */ goto unimplemented;
12899 case 0xb3c8: /* CGER */ goto unimplemented;
12900 case 0xb3c9: /* CGDR */ goto unimplemented;
12901 case 0xb3ca: /* CGXR */ goto unimplemented;
12902 case 0xb3cd: s390_format_RRE_RF(s390_irgen_LGDR, ovl.fmt.RRE.r1,
12903 ovl.fmt.RRE.r2); goto ok;
12904 case 0xb3d0: /* MDTR */ goto unimplemented;
12905 case 0xb3d1: /* DDTR */ goto unimplemented;
12906 case 0xb3d2: /* ADTR */ goto unimplemented;
12907 case 0xb3d3: /* SDTR */ goto unimplemented;
12908 case 0xb3d4: /* LDETR */ goto unimplemented;
12909 case 0xb3d5: /* LEDTR */ goto unimplemented;
12910 case 0xb3d6: /* LTDTR */ goto unimplemented;
12911 case 0xb3d7: /* FIDTR */ goto unimplemented;
12912 case 0xb3d8: /* MXTR */ goto unimplemented;
12913 case 0xb3d9: /* DXTR */ goto unimplemented;
12914 case 0xb3da: /* AXTR */ goto unimplemented;
12915 case 0xb3db: /* SXTR */ goto unimplemented;
12916 case 0xb3dc: /* LXDTR */ goto unimplemented;
12917 case 0xb3dd: /* LDXTR */ goto unimplemented;
12918 case 0xb3de: /* LTXTR */ goto unimplemented;
12919 case 0xb3df: /* FIXTR */ goto unimplemented;
12920 case 0xb3e0: /* KDTR */ goto unimplemented;
12921 case 0xb3e1: /* CGDTR */ goto unimplemented;
12922 case 0xb3e2: /* CUDTR */ goto unimplemented;
12923 case 0xb3e3: /* CSDTR */ goto unimplemented;
12924 case 0xb3e4: /* CDTR */ goto unimplemented;
12925 case 0xb3e5: /* EEDTR */ goto unimplemented;
12926 case 0xb3e7: /* ESDTR */ goto unimplemented;
12927 case 0xb3e8: /* KXTR */ goto unimplemented;
12928 case 0xb3e9: /* CGXTR */ goto unimplemented;
12929 case 0xb3ea: /* CUXTR */ goto unimplemented;
12930 case 0xb3eb: /* CSXTR */ goto unimplemented;
12931 case 0xb3ec: /* CXTR */ goto unimplemented;
12932 case 0xb3ed: /* EEXTR */ goto unimplemented;
12933 case 0xb3ef: /* ESXTR */ goto unimplemented;
12934 case 0xb3f1: /* CDGTR */ goto unimplemented;
12935 case 0xb3f2: /* CDUTR */ goto unimplemented;
12936 case 0xb3f3: /* CDSTR */ goto unimplemented;
12937 case 0xb3f4: /* CEDTR */ goto unimplemented;
12938 case 0xb3f5: /* QADTR */ goto unimplemented;
12939 case 0xb3f6: /* IEDTR */ goto unimplemented;
12940 case 0xb3f7: /* RRDTR */ goto unimplemented;
12941 case 0xb3f9: /* CXGTR */ goto unimplemented;
12942 case 0xb3fa: /* CXUTR */ goto unimplemented;
12943 case 0xb3fb: /* CXSTR */ goto unimplemented;
12944 case 0xb3fc: /* CEXTR */ goto unimplemented;
12945 case 0xb3fd: /* QAXTR */ goto unimplemented;
12946 case 0xb3fe: /* IEXTR */ goto unimplemented;
12947 case 0xb3ff: /* RRXTR */ goto unimplemented;
12948 case 0xb900: s390_format_RRE_RR(s390_irgen_LPGR, ovl.fmt.RRE.r1,
12949 ovl.fmt.RRE.r2); goto ok;
12950 case 0xb901: s390_format_RRE_RR(s390_irgen_LNGR, ovl.fmt.RRE.r1,
12951 ovl.fmt.RRE.r2); goto ok;
12952 case 0xb902: s390_format_RRE_RR(s390_irgen_LTGR, ovl.fmt.RRE.r1,
12953 ovl.fmt.RRE.r2); goto ok;
12954 case 0xb903: s390_format_RRE_RR(s390_irgen_LCGR, ovl.fmt.RRE.r1,
12955 ovl.fmt.RRE.r2); goto ok;
12956 case 0xb904: s390_format_RRE_RR(s390_irgen_LGR, ovl.fmt.RRE.r1,
12957 ovl.fmt.RRE.r2); goto ok;
12958 case 0xb905: /* LURAG */ goto unimplemented;
12959 case 0xb906: s390_format_RRE_RR(s390_irgen_LGBR, ovl.fmt.RRE.r1,
12960 ovl.fmt.RRE.r2); goto ok;
12961 case 0xb907: s390_format_RRE_RR(s390_irgen_LGHR, ovl.fmt.RRE.r1,
12962 ovl.fmt.RRE.r2); goto ok;
12963 case 0xb908: s390_format_RRE_RR(s390_irgen_AGR, ovl.fmt.RRE.r1,
12964 ovl.fmt.RRE.r2); goto ok;
12965 case 0xb909: s390_format_RRE_RR(s390_irgen_SGR, ovl.fmt.RRE.r1,
12966 ovl.fmt.RRE.r2); goto ok;
12967 case 0xb90a: s390_format_RRE_RR(s390_irgen_ALGR, ovl.fmt.RRE.r1,
12968 ovl.fmt.RRE.r2); goto ok;
12969 case 0xb90b: s390_format_RRE_RR(s390_irgen_SLGR, ovl.fmt.RRE.r1,
12970 ovl.fmt.RRE.r2); goto ok;
12971 case 0xb90c: s390_format_RRE_RR(s390_irgen_MSGR, ovl.fmt.RRE.r1,
12972 ovl.fmt.RRE.r2); goto ok;
12973 case 0xb90d: s390_format_RRE_RR(s390_irgen_DSGR, ovl.fmt.RRE.r1,
12974 ovl.fmt.RRE.r2); goto ok;
12975 case 0xb90e: /* EREGG */ goto unimplemented;
12976 case 0xb90f: s390_format_RRE_RR(s390_irgen_LRVGR, ovl.fmt.RRE.r1,
12977 ovl.fmt.RRE.r2); goto ok;
12978 case 0xb910: s390_format_RRE_RR(s390_irgen_LPGFR, ovl.fmt.RRE.r1,
12979 ovl.fmt.RRE.r2); goto ok;
12980 case 0xb911: s390_format_RRE_RR(s390_irgen_LNGFR, ovl.fmt.RRE.r1,
12981 ovl.fmt.RRE.r2); goto ok;
12982 case 0xb912: s390_format_RRE_RR(s390_irgen_LTGFR, ovl.fmt.RRE.r1,
12983 ovl.fmt.RRE.r2); goto ok;
12984 case 0xb913: s390_format_RRE_RR(s390_irgen_LCGFR, ovl.fmt.RRE.r1,
12985 ovl.fmt.RRE.r2); goto ok;
12986 case 0xb914: s390_format_RRE_RR(s390_irgen_LGFR, ovl.fmt.RRE.r1,
12987 ovl.fmt.RRE.r2); goto ok;
12988 case 0xb916: s390_format_RRE_RR(s390_irgen_LLGFR, ovl.fmt.RRE.r1,
12989 ovl.fmt.RRE.r2); goto ok;
12990 case 0xb917: s390_format_RRE_RR(s390_irgen_LLGTR, ovl.fmt.RRE.r1,
12991 ovl.fmt.RRE.r2); goto ok;
12992 case 0xb918: s390_format_RRE_RR(s390_irgen_AGFR, ovl.fmt.RRE.r1,
12993 ovl.fmt.RRE.r2); goto ok;
12994 case 0xb919: s390_format_RRE_RR(s390_irgen_SGFR, ovl.fmt.RRE.r1,
12995 ovl.fmt.RRE.r2); goto ok;
12996 case 0xb91a: s390_format_RRE_RR(s390_irgen_ALGFR, ovl.fmt.RRE.r1,
12997 ovl.fmt.RRE.r2); goto ok;
12998 case 0xb91b: s390_format_RRE_RR(s390_irgen_SLGFR, ovl.fmt.RRE.r1,
12999 ovl.fmt.RRE.r2); goto ok;
13000 case 0xb91c: s390_format_RRE_RR(s390_irgen_MSGFR, ovl.fmt.RRE.r1,
13001 ovl.fmt.RRE.r2); goto ok;
13002 case 0xb91d: s390_format_RRE_RR(s390_irgen_DSGFR, ovl.fmt.RRE.r1,
13003 ovl.fmt.RRE.r2); goto ok;
13004 case 0xb91e: /* KMAC */ goto unimplemented;
13005 case 0xb91f: s390_format_RRE_RR(s390_irgen_LRVR, ovl.fmt.RRE.r1,
13006 ovl.fmt.RRE.r2); goto ok;
13007 case 0xb920: s390_format_RRE_RR(s390_irgen_CGR, ovl.fmt.RRE.r1,
13008 ovl.fmt.RRE.r2); goto ok;
13009 case 0xb921: s390_format_RRE_RR(s390_irgen_CLGR, ovl.fmt.RRE.r1,
13010 ovl.fmt.RRE.r2); goto ok;
13011 case 0xb925: /* STURG */ goto unimplemented;
13012 case 0xb926: s390_format_RRE_RR(s390_irgen_LBR, ovl.fmt.RRE.r1,
13013 ovl.fmt.RRE.r2); goto ok;
13014 case 0xb927: s390_format_RRE_RR(s390_irgen_LHR, ovl.fmt.RRE.r1,
13015 ovl.fmt.RRE.r2); goto ok;
13016 case 0xb928: /* PCKMO */ goto unimplemented;
13017 case 0xb92b: /* KMO */ goto unimplemented;
13018 case 0xb92c: /* PCC */ goto unimplemented;
13019 case 0xb92d: /* KMCTR */ goto unimplemented;
13020 case 0xb92e: /* KM */ goto unimplemented;
13021 case 0xb92f: /* KMC */ goto unimplemented;
13022 case 0xb930: s390_format_RRE_RR(s390_irgen_CGFR, ovl.fmt.RRE.r1,
13023 ovl.fmt.RRE.r2); goto ok;
13024 case 0xb931: s390_format_RRE_RR(s390_irgen_CLGFR, ovl.fmt.RRE.r1,
13025 ovl.fmt.RRE.r2); goto ok;
13026 case 0xb93e: /* KIMD */ goto unimplemented;
13027 case 0xb93f: /* KLMD */ goto unimplemented;
13028 case 0xb941: /* CFDTR */ goto unimplemented;
13029 case 0xb942: /* CLGDTR */ goto unimplemented;
13030 case 0xb943: /* CLFDTR */ goto unimplemented;
13031 case 0xb946: s390_format_RRE_RR(s390_irgen_BCTGR, ovl.fmt.RRE.r1,
13032 ovl.fmt.RRE.r2); goto ok;
13033 case 0xb949: /* CFXTR */ goto unimplemented;
13034 case 0xb94a: /* CLGXTR */ goto unimplemented;
13035 case 0xb94b: /* CLFXTR */ goto unimplemented;
13036 case 0xb951: /* CDFTR */ goto unimplemented;
13037 case 0xb952: /* CDLGTR */ goto unimplemented;
13038 case 0xb953: /* CDLFTR */ goto unimplemented;
13039 case 0xb959: /* CXFTR */ goto unimplemented;
13040 case 0xb95a: /* CXLGTR */ goto unimplemented;
13041 case 0xb95b: /* CXLFTR */ goto unimplemented;
13042 case 0xb960: /* CGRT */ goto unimplemented;
13043 case 0xb961: /* CLGRT */ goto unimplemented;
13044 case 0xb972: /* CRT */ goto unimplemented;
13045 case 0xb973: /* CLRT */ goto unimplemented;
13046 case 0xb980: s390_format_RRE_RR(s390_irgen_NGR, ovl.fmt.RRE.r1,
13047 ovl.fmt.RRE.r2); goto ok;
13048 case 0xb981: s390_format_RRE_RR(s390_irgen_OGR, ovl.fmt.RRE.r1,
13049 ovl.fmt.RRE.r2); goto ok;
13050 case 0xb982: s390_format_RRE_RR(s390_irgen_XGR, ovl.fmt.RRE.r1,
13051 ovl.fmt.RRE.r2); goto ok;
13052 case 0xb983: s390_format_RRE_RR(s390_irgen_FLOGR, ovl.fmt.RRE.r1,
13053 ovl.fmt.RRE.r2); goto ok;
13054 case 0xb984: s390_format_RRE_RR(s390_irgen_LLGCR, ovl.fmt.RRE.r1,
13055 ovl.fmt.RRE.r2); goto ok;
13056 case 0xb985: s390_format_RRE_RR(s390_irgen_LLGHR, ovl.fmt.RRE.r1,
13057 ovl.fmt.RRE.r2); goto ok;
13058 case 0xb986: s390_format_RRE_RR(s390_irgen_MLGR, ovl.fmt.RRE.r1,
13059 ovl.fmt.RRE.r2); goto ok;
13060 case 0xb987: s390_format_RRE_RR(s390_irgen_DLGR, ovl.fmt.RRE.r1,
13061 ovl.fmt.RRE.r2); goto ok;
13062 case 0xb988: s390_format_RRE_RR(s390_irgen_ALCGR, ovl.fmt.RRE.r1,
13063 ovl.fmt.RRE.r2); goto ok;
13064 case 0xb989: s390_format_RRE_RR(s390_irgen_SLBGR, ovl.fmt.RRE.r1,
13065 ovl.fmt.RRE.r2); goto ok;
13066 case 0xb98a: /* CSPG */ goto unimplemented;
13067 case 0xb98d: /* EPSW */ goto unimplemented;
13068 case 0xb98e: /* IDTE */ goto unimplemented;
florian730448f2012-02-04 17:07:07 +000013069 case 0xb990: s390_format_RRF_M0RERE(s390_irgen_TRTT, ovl.fmt.RRF3.r3,
13070 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
13071 case 0xb991: s390_format_RRF_M0RERE(s390_irgen_TRTO, ovl.fmt.RRF3.r3,
13072 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
13073 case 0xb992: s390_format_RRF_M0RERE(s390_irgen_TROT, ovl.fmt.RRF3.r3,
13074 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
florian9af37692012-01-15 21:01:16 +000013075 case 0xb993: s390_format_RRF_M0RERE(s390_irgen_TROO, ovl.fmt.RRF3.r3,
13076 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013077 case 0xb994: s390_format_RRE_RR(s390_irgen_LLCR, ovl.fmt.RRE.r1,
13078 ovl.fmt.RRE.r2); goto ok;
13079 case 0xb995: s390_format_RRE_RR(s390_irgen_LLHR, ovl.fmt.RRE.r1,
13080 ovl.fmt.RRE.r2); goto ok;
13081 case 0xb996: s390_format_RRE_RR(s390_irgen_MLR, ovl.fmt.RRE.r1,
13082 ovl.fmt.RRE.r2); goto ok;
13083 case 0xb997: s390_format_RRE_RR(s390_irgen_DLR, ovl.fmt.RRE.r1,
13084 ovl.fmt.RRE.r2); goto ok;
13085 case 0xb998: s390_format_RRE_RR(s390_irgen_ALCR, ovl.fmt.RRE.r1,
13086 ovl.fmt.RRE.r2); goto ok;
13087 case 0xb999: s390_format_RRE_RR(s390_irgen_SLBR, ovl.fmt.RRE.r1,
13088 ovl.fmt.RRE.r2); goto ok;
13089 case 0xb99a: /* EPAIR */ goto unimplemented;
13090 case 0xb99b: /* ESAIR */ goto unimplemented;
13091 case 0xb99d: /* ESEA */ goto unimplemented;
13092 case 0xb99e: /* PTI */ goto unimplemented;
13093 case 0xb99f: /* SSAIR */ goto unimplemented;
13094 case 0xb9a2: /* PTF */ goto unimplemented;
13095 case 0xb9aa: /* LPTEA */ goto unimplemented;
13096 case 0xb9ae: /* RRBM */ goto unimplemented;
13097 case 0xb9af: /* PFMF */ goto unimplemented;
florian3f8a96a2012-08-05 02:59:55 +000013098 case 0xb9b0: s390_format_RRF_M0RERE(s390_irgen_CU14, ovl.fmt.RRF3.r3,
13099 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
13100 goto ok;
florian2a415a12012-07-21 17:41:36 +000013101 case 0xb9b1: s390_format_RRF_M0RERE(s390_irgen_CU24, ovl.fmt.RRF3.r3,
13102 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
13103 goto ok;
florianaf2194f2012-08-06 00:07:54 +000013104 case 0xb9b2: s390_format_RRE_RR(s390_irgen_CU41, ovl.fmt.RRE.r1,
13105 ovl.fmt.RRE.r2); goto ok;
florian956194b2012-07-28 22:18:32 +000013106 case 0xb9b3: s390_format_RRE_RR(s390_irgen_CU42, ovl.fmt.RRE.r1,
13107 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013108 case 0xb9bd: /* TRTRE */ goto unimplemented;
13109 case 0xb9be: /* SRSTU */ goto unimplemented;
13110 case 0xb9bf: /* TRTE */ goto unimplemented;
13111 case 0xb9c8: s390_format_RRF_R0RR2(s390_irgen_AHHHR, ovl.fmt.RRF4.r3,
13112 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13113 goto ok;
13114 case 0xb9c9: s390_format_RRF_R0RR2(s390_irgen_SHHHR, ovl.fmt.RRF4.r3,
13115 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13116 goto ok;
13117 case 0xb9ca: s390_format_RRF_R0RR2(s390_irgen_ALHHHR, ovl.fmt.RRF4.r3,
13118 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13119 goto ok;
13120 case 0xb9cb: s390_format_RRF_R0RR2(s390_irgen_SLHHHR, ovl.fmt.RRF4.r3,
13121 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13122 goto ok;
13123 case 0xb9cd: s390_format_RRE_RR(s390_irgen_CHHR, ovl.fmt.RRE.r1,
13124 ovl.fmt.RRE.r2); goto ok;
13125 case 0xb9cf: s390_format_RRE_RR(s390_irgen_CLHHR, ovl.fmt.RRE.r1,
13126 ovl.fmt.RRE.r2); goto ok;
13127 case 0xb9d8: s390_format_RRF_R0RR2(s390_irgen_AHHLR, ovl.fmt.RRF4.r3,
13128 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13129 goto ok;
13130 case 0xb9d9: s390_format_RRF_R0RR2(s390_irgen_SHHLR, ovl.fmt.RRF4.r3,
13131 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13132 goto ok;
13133 case 0xb9da: s390_format_RRF_R0RR2(s390_irgen_ALHHLR, ovl.fmt.RRF4.r3,
13134 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13135 goto ok;
13136 case 0xb9db: s390_format_RRF_R0RR2(s390_irgen_SLHHLR, ovl.fmt.RRF4.r3,
13137 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13138 goto ok;
13139 case 0xb9dd: s390_format_RRE_RR(s390_irgen_CHLR, ovl.fmt.RRE.r1,
13140 ovl.fmt.RRE.r2); goto ok;
13141 case 0xb9df: s390_format_RRE_RR(s390_irgen_CLHLR, ovl.fmt.RRE.r1,
13142 ovl.fmt.RRE.r2); goto ok;
13143 case 0xb9e1: /* POPCNT */ goto unimplemented;
sewardjd7bde722011-04-05 13:19:33 +000013144 case 0xb9e2: s390_format_RRF_U0RR(s390_irgen_LOCGR, ovl.fmt.RRF3.r3,
13145 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2,
13146 S390_XMNM_LOCGR); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013147 case 0xb9e4: s390_format_RRF_R0RR2(s390_irgen_NGRK, ovl.fmt.RRF4.r3,
13148 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13149 goto ok;
13150 case 0xb9e6: s390_format_RRF_R0RR2(s390_irgen_OGRK, ovl.fmt.RRF4.r3,
13151 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13152 goto ok;
13153 case 0xb9e7: s390_format_RRF_R0RR2(s390_irgen_XGRK, ovl.fmt.RRF4.r3,
13154 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13155 goto ok;
13156 case 0xb9e8: s390_format_RRF_R0RR2(s390_irgen_AGRK, ovl.fmt.RRF4.r3,
13157 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13158 goto ok;
13159 case 0xb9e9: s390_format_RRF_R0RR2(s390_irgen_SGRK, ovl.fmt.RRF4.r3,
13160 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13161 goto ok;
13162 case 0xb9ea: s390_format_RRF_R0RR2(s390_irgen_ALGRK, ovl.fmt.RRF4.r3,
13163 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13164 goto ok;
13165 case 0xb9eb: s390_format_RRF_R0RR2(s390_irgen_SLGRK, ovl.fmt.RRF4.r3,
13166 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13167 goto ok;
sewardjd7bde722011-04-05 13:19:33 +000013168 case 0xb9f2: s390_format_RRF_U0RR(s390_irgen_LOCR, ovl.fmt.RRF3.r3,
13169 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2,
13170 S390_XMNM_LOCR); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013171 case 0xb9f4: s390_format_RRF_R0RR2(s390_irgen_NRK, ovl.fmt.RRF4.r3,
13172 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13173 goto ok;
13174 case 0xb9f6: s390_format_RRF_R0RR2(s390_irgen_ORK, ovl.fmt.RRF4.r3,
13175 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13176 goto ok;
13177 case 0xb9f7: s390_format_RRF_R0RR2(s390_irgen_XRK, ovl.fmt.RRF4.r3,
13178 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13179 goto ok;
13180 case 0xb9f8: s390_format_RRF_R0RR2(s390_irgen_ARK, ovl.fmt.RRF4.r3,
13181 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13182 goto ok;
13183 case 0xb9f9: s390_format_RRF_R0RR2(s390_irgen_SRK, ovl.fmt.RRF4.r3,
13184 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13185 goto ok;
13186 case 0xb9fa: s390_format_RRF_R0RR2(s390_irgen_ALRK, ovl.fmt.RRF4.r3,
13187 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13188 goto ok;
13189 case 0xb9fb: s390_format_RRF_R0RR2(s390_irgen_SLRK, ovl.fmt.RRF4.r3,
13190 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13191 goto ok;
13192 }
13193
13194 switch ((ovl.value & 0xff000000) >> 24) {
13195 case 0x40: s390_format_RX_RRRD(s390_irgen_STH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13196 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13197 case 0x41: s390_format_RX_RRRD(s390_irgen_LA, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13198 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13199 case 0x42: s390_format_RX_RRRD(s390_irgen_STC, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13200 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13201 case 0x43: s390_format_RX_RRRD(s390_irgen_IC, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13202 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13203 case 0x44: s390_format_RX_RRRD(s390_irgen_EX, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13204 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13205 case 0x45: /* BAL */ goto unimplemented;
13206 case 0x46: s390_format_RX_RRRD(s390_irgen_BCT, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13207 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13208 case 0x47: s390_format_RX(s390_irgen_BC, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13209 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13210 case 0x48: s390_format_RX_RRRD(s390_irgen_LH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13211 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13212 case 0x49: s390_format_RX_RRRD(s390_irgen_CH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13213 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13214 case 0x4a: s390_format_RX_RRRD(s390_irgen_AH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13215 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13216 case 0x4b: s390_format_RX_RRRD(s390_irgen_SH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13217 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13218 case 0x4c: s390_format_RX_RRRD(s390_irgen_MH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13219 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13220 case 0x4d: s390_format_RX_RRRD(s390_irgen_BAS, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13221 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13222 case 0x4e: s390_format_RX_RRRD(s390_irgen_CVD, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13223 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13224 case 0x4f: s390_format_RX_RRRD(s390_irgen_CVB, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13225 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13226 case 0x50: s390_format_RX_RRRD(s390_irgen_ST, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13227 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13228 case 0x51: s390_format_RX_RRRD(s390_irgen_LAE, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13229 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13230 case 0x54: s390_format_RX_RRRD(s390_irgen_N, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13231 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13232 case 0x55: s390_format_RX_RRRD(s390_irgen_CL, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13233 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13234 case 0x56: s390_format_RX_RRRD(s390_irgen_O, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13235 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13236 case 0x57: s390_format_RX_RRRD(s390_irgen_X, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13237 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13238 case 0x58: s390_format_RX_RRRD(s390_irgen_L, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13239 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13240 case 0x59: s390_format_RX_RRRD(s390_irgen_C, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13241 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13242 case 0x5a: s390_format_RX_RRRD(s390_irgen_A, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13243 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13244 case 0x5b: s390_format_RX_RRRD(s390_irgen_S, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13245 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13246 case 0x5c: s390_format_RX_RRRD(s390_irgen_M, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13247 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13248 case 0x5d: s390_format_RX_RRRD(s390_irgen_D, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13249 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13250 case 0x5e: s390_format_RX_RRRD(s390_irgen_AL, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13251 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13252 case 0x5f: s390_format_RX_RRRD(s390_irgen_SL, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13253 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13254 case 0x60: s390_format_RX_FRRD(s390_irgen_STD, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13255 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13256 case 0x67: /* MXD */ goto unimplemented;
13257 case 0x68: s390_format_RX_FRRD(s390_irgen_LD, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13258 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13259 case 0x69: /* CD */ goto unimplemented;
13260 case 0x6a: /* AD */ goto unimplemented;
13261 case 0x6b: /* SD */ goto unimplemented;
13262 case 0x6c: /* MD */ goto unimplemented;
13263 case 0x6d: /* DD */ goto unimplemented;
13264 case 0x6e: /* AW */ goto unimplemented;
13265 case 0x6f: /* SW */ goto unimplemented;
13266 case 0x70: s390_format_RX_FRRD(s390_irgen_STE, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13267 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13268 case 0x71: s390_format_RX_RRRD(s390_irgen_MS, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13269 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13270 case 0x78: s390_format_RX_FRRD(s390_irgen_LE, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13271 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13272 case 0x79: /* CE */ goto unimplemented;
13273 case 0x7a: /* AE */ goto unimplemented;
13274 case 0x7b: /* SE */ goto unimplemented;
13275 case 0x7c: /* MDE */ goto unimplemented;
13276 case 0x7d: /* DE */ goto unimplemented;
13277 case 0x7e: /* AU */ goto unimplemented;
13278 case 0x7f: /* SU */ goto unimplemented;
13279 case 0x83: /* DIAG */ goto unimplemented;
13280 case 0x84: s390_format_RSI_RRP(s390_irgen_BRXH, ovl.fmt.RSI.r1,
13281 ovl.fmt.RSI.r3, ovl.fmt.RSI.i2); goto ok;
13282 case 0x85: s390_format_RSI_RRP(s390_irgen_BRXLE, ovl.fmt.RSI.r1,
13283 ovl.fmt.RSI.r3, ovl.fmt.RSI.i2); goto ok;
13284 case 0x86: s390_format_RS_RRRD(s390_irgen_BXH, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13285 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13286 case 0x87: s390_format_RS_RRRD(s390_irgen_BXLE, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13287 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13288 case 0x88: s390_format_RS_R0RD(s390_irgen_SRL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
13289 ovl.fmt.RS.d2); goto ok;
13290 case 0x89: s390_format_RS_R0RD(s390_irgen_SLL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
13291 ovl.fmt.RS.d2); goto ok;
13292 case 0x8a: s390_format_RS_R0RD(s390_irgen_SRA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
13293 ovl.fmt.RS.d2); goto ok;
13294 case 0x8b: s390_format_RS_R0RD(s390_irgen_SLA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
13295 ovl.fmt.RS.d2); goto ok;
13296 case 0x8c: s390_format_RS_R0RD(s390_irgen_SRDL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
13297 ovl.fmt.RS.d2); goto ok;
13298 case 0x8d: s390_format_RS_R0RD(s390_irgen_SLDL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
13299 ovl.fmt.RS.d2); goto ok;
13300 case 0x8e: s390_format_RS_R0RD(s390_irgen_SRDA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
13301 ovl.fmt.RS.d2); goto ok;
13302 case 0x8f: s390_format_RS_R0RD(s390_irgen_SLDA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
13303 ovl.fmt.RS.d2); goto ok;
13304 case 0x90: s390_format_RS_RRRD(s390_irgen_STM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13305 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13306 case 0x91: s390_format_SI_URD(s390_irgen_TM, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
13307 ovl.fmt.SI.d1); goto ok;
13308 case 0x92: s390_format_SI_URD(s390_irgen_MVI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
13309 ovl.fmt.SI.d1); goto ok;
13310 case 0x94: s390_format_SI_URD(s390_irgen_NI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
13311 ovl.fmt.SI.d1); goto ok;
13312 case 0x95: s390_format_SI_URD(s390_irgen_CLI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
13313 ovl.fmt.SI.d1); goto ok;
13314 case 0x96: s390_format_SI_URD(s390_irgen_OI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
13315 ovl.fmt.SI.d1); goto ok;
13316 case 0x97: s390_format_SI_URD(s390_irgen_XI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
13317 ovl.fmt.SI.d1); goto ok;
13318 case 0x98: s390_format_RS_RRRD(s390_irgen_LM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13319 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13320 case 0x99: /* TRACE */ goto unimplemented;
13321 case 0x9a: s390_format_RS_AARD(s390_irgen_LAM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13322 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13323 case 0x9b: s390_format_RS_AARD(s390_irgen_STAM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13324 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13325 case 0xa8: s390_format_RS_RRRD(s390_irgen_MVCLE, ovl.fmt.RS.r1,
13326 ovl.fmt.RS.r3, ovl.fmt.RS.b2, ovl.fmt.RS.d2);
13327 goto ok;
13328 case 0xa9: s390_format_RS_RRRD(s390_irgen_CLCLE, ovl.fmt.RS.r1,
13329 ovl.fmt.RS.r3, ovl.fmt.RS.b2, ovl.fmt.RS.d2);
13330 goto ok;
13331 case 0xac: /* STNSM */ goto unimplemented;
13332 case 0xad: /* STOSM */ goto unimplemented;
13333 case 0xae: /* SIGP */ goto unimplemented;
13334 case 0xaf: /* MC */ goto unimplemented;
13335 case 0xb1: /* LRA */ goto unimplemented;
13336 case 0xb6: /* STCTL */ goto unimplemented;
13337 case 0xb7: /* LCTL */ goto unimplemented;
13338 case 0xba: s390_format_RS_RRRD(s390_irgen_CS, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13339 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
florian448cbba2012-06-06 02:26:01 +000013340 case 0xbb: s390_format_RS_RRRD(s390_irgen_CDS, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13341 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013342 case 0xbd: s390_format_RS_RURD(s390_irgen_CLM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13343 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13344 case 0xbe: s390_format_RS_RURD(s390_irgen_STCM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13345 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13346 case 0xbf: s390_format_RS_RURD(s390_irgen_ICM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13347 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13348 }
13349
13350 return S390_DECODE_UNKNOWN_INSN;
13351
13352ok:
13353 return S390_DECODE_OK;
13354
13355unimplemented:
13356 return S390_DECODE_UNIMPLEMENTED_INSN;
13357}
13358
13359static s390_decode_t
13360s390_decode_6byte_and_irgen(UChar *bytes)
13361{
13362 typedef union {
13363 struct {
13364 unsigned int op1 : 8;
13365 unsigned int r1 : 4;
13366 unsigned int r3 : 4;
13367 unsigned int i2 : 16;
13368 unsigned int : 8;
13369 unsigned int op2 : 8;
13370 } RIE;
13371 struct {
13372 unsigned int op1 : 8;
13373 unsigned int r1 : 4;
13374 unsigned int r2 : 4;
13375 unsigned int i3 : 8;
13376 unsigned int i4 : 8;
13377 unsigned int i5 : 8;
13378 unsigned int op2 : 8;
13379 } RIE_RRUUU;
13380 struct {
13381 unsigned int op1 : 8;
13382 unsigned int r1 : 4;
13383 unsigned int : 4;
13384 unsigned int i2 : 16;
13385 unsigned int m3 : 4;
13386 unsigned int : 4;
13387 unsigned int op2 : 8;
13388 } RIEv1;
13389 struct {
13390 unsigned int op1 : 8;
13391 unsigned int r1 : 4;
13392 unsigned int r2 : 4;
13393 unsigned int i4 : 16;
13394 unsigned int m3 : 4;
13395 unsigned int : 4;
13396 unsigned int op2 : 8;
13397 } RIE_RRPU;
13398 struct {
13399 unsigned int op1 : 8;
13400 unsigned int r1 : 4;
13401 unsigned int m3 : 4;
13402 unsigned int i4 : 16;
13403 unsigned int i2 : 8;
13404 unsigned int op2 : 8;
13405 } RIEv3;
13406 struct {
13407 unsigned int op1 : 8;
13408 unsigned int r1 : 4;
13409 unsigned int op2 : 4;
13410 unsigned int i2 : 32;
13411 } RIL;
13412 struct {
13413 unsigned int op1 : 8;
13414 unsigned int r1 : 4;
13415 unsigned int m3 : 4;
13416 unsigned int b4 : 4;
13417 unsigned int d4 : 12;
13418 unsigned int i2 : 8;
13419 unsigned int op2 : 8;
13420 } RIS;
13421 struct {
13422 unsigned int op1 : 8;
13423 unsigned int r1 : 4;
13424 unsigned int r2 : 4;
13425 unsigned int b4 : 4;
13426 unsigned int d4 : 12;
13427 unsigned int m3 : 4;
13428 unsigned int : 4;
13429 unsigned int op2 : 8;
13430 } RRS;
13431 struct {
13432 unsigned int op1 : 8;
13433 unsigned int l1 : 4;
13434 unsigned int : 4;
13435 unsigned int b1 : 4;
13436 unsigned int d1 : 12;
13437 unsigned int : 8;
13438 unsigned int op2 : 8;
13439 } RSL;
13440 struct {
13441 unsigned int op1 : 8;
13442 unsigned int r1 : 4;
13443 unsigned int r3 : 4;
13444 unsigned int b2 : 4;
13445 unsigned int dl2 : 12;
13446 unsigned int dh2 : 8;
13447 unsigned int op2 : 8;
13448 } RSY;
13449 struct {
13450 unsigned int op1 : 8;
13451 unsigned int r1 : 4;
13452 unsigned int x2 : 4;
13453 unsigned int b2 : 4;
13454 unsigned int d2 : 12;
13455 unsigned int : 8;
13456 unsigned int op2 : 8;
13457 } RXE;
13458 struct {
13459 unsigned int op1 : 8;
13460 unsigned int r3 : 4;
13461 unsigned int x2 : 4;
13462 unsigned int b2 : 4;
13463 unsigned int d2 : 12;
13464 unsigned int r1 : 4;
13465 unsigned int : 4;
13466 unsigned int op2 : 8;
13467 } RXF;
13468 struct {
13469 unsigned int op1 : 8;
13470 unsigned int r1 : 4;
13471 unsigned int x2 : 4;
13472 unsigned int b2 : 4;
13473 unsigned int dl2 : 12;
13474 unsigned int dh2 : 8;
13475 unsigned int op2 : 8;
13476 } RXY;
13477 struct {
13478 unsigned int op1 : 8;
13479 unsigned int i2 : 8;
13480 unsigned int b1 : 4;
13481 unsigned int dl1 : 12;
13482 unsigned int dh1 : 8;
13483 unsigned int op2 : 8;
13484 } SIY;
13485 struct {
13486 unsigned int op : 8;
13487 unsigned int l : 8;
13488 unsigned int b1 : 4;
13489 unsigned int d1 : 12;
13490 unsigned int b2 : 4;
13491 unsigned int d2 : 12;
13492 } SS;
13493 struct {
13494 unsigned int op : 8;
13495 unsigned int l1 : 4;
13496 unsigned int l2 : 4;
13497 unsigned int b1 : 4;
13498 unsigned int d1 : 12;
13499 unsigned int b2 : 4;
13500 unsigned int d2 : 12;
13501 } SS_LLRDRD;
13502 struct {
13503 unsigned int op : 8;
13504 unsigned int r1 : 4;
13505 unsigned int r3 : 4;
13506 unsigned int b2 : 4;
13507 unsigned int d2 : 12;
13508 unsigned int b4 : 4;
13509 unsigned int d4 : 12;
13510 } SS_RRRDRD2;
13511 struct {
13512 unsigned int op : 16;
13513 unsigned int b1 : 4;
13514 unsigned int d1 : 12;
13515 unsigned int b2 : 4;
13516 unsigned int d2 : 12;
13517 } SSE;
13518 struct {
13519 unsigned int op1 : 8;
13520 unsigned int r3 : 4;
13521 unsigned int op2 : 4;
13522 unsigned int b1 : 4;
13523 unsigned int d1 : 12;
13524 unsigned int b2 : 4;
13525 unsigned int d2 : 12;
13526 } SSF;
13527 struct {
13528 unsigned int op : 16;
13529 unsigned int b1 : 4;
13530 unsigned int d1 : 12;
13531 unsigned int i2 : 16;
13532 } SIL;
13533 } formats;
13534 union {
13535 formats fmt;
13536 ULong value;
13537 } ovl;
13538
13539 vassert(sizeof(formats) == 6);
13540
13541 ((char *)(&ovl.value))[0] = bytes[0];
13542 ((char *)(&ovl.value))[1] = bytes[1];
13543 ((char *)(&ovl.value))[2] = bytes[2];
13544 ((char *)(&ovl.value))[3] = bytes[3];
13545 ((char *)(&ovl.value))[4] = bytes[4];
13546 ((char *)(&ovl.value))[5] = bytes[5];
13547 ((char *)(&ovl.value))[6] = 0x0;
13548 ((char *)(&ovl.value))[7] = 0x0;
13549
13550 switch ((ovl.value >> 16) & 0xff00000000ffULL) {
13551 case 0xe30000000002ULL: s390_format_RXY_RRRD(s390_irgen_LTG, ovl.fmt.RXY.r1,
13552 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13553 ovl.fmt.RXY.dl2,
13554 ovl.fmt.RXY.dh2); goto ok;
13555 case 0xe30000000003ULL: /* LRAG */ goto unimplemented;
13556 case 0xe30000000004ULL: s390_format_RXY_RRRD(s390_irgen_LG, ovl.fmt.RXY.r1,
13557 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13558 ovl.fmt.RXY.dl2,
13559 ovl.fmt.RXY.dh2); goto ok;
13560 case 0xe30000000006ULL: s390_format_RXY_RRRD(s390_irgen_CVBY, ovl.fmt.RXY.r1,
13561 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13562 ovl.fmt.RXY.dl2,
13563 ovl.fmt.RXY.dh2); goto ok;
13564 case 0xe30000000008ULL: s390_format_RXY_RRRD(s390_irgen_AG, ovl.fmt.RXY.r1,
13565 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13566 ovl.fmt.RXY.dl2,
13567 ovl.fmt.RXY.dh2); goto ok;
13568 case 0xe30000000009ULL: s390_format_RXY_RRRD(s390_irgen_SG, ovl.fmt.RXY.r1,
13569 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13570 ovl.fmt.RXY.dl2,
13571 ovl.fmt.RXY.dh2); goto ok;
13572 case 0xe3000000000aULL: s390_format_RXY_RRRD(s390_irgen_ALG, ovl.fmt.RXY.r1,
13573 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13574 ovl.fmt.RXY.dl2,
13575 ovl.fmt.RXY.dh2); goto ok;
13576 case 0xe3000000000bULL: s390_format_RXY_RRRD(s390_irgen_SLG, ovl.fmt.RXY.r1,
13577 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13578 ovl.fmt.RXY.dl2,
13579 ovl.fmt.RXY.dh2); goto ok;
13580 case 0xe3000000000cULL: s390_format_RXY_RRRD(s390_irgen_MSG, ovl.fmt.RXY.r1,
13581 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13582 ovl.fmt.RXY.dl2,
13583 ovl.fmt.RXY.dh2); goto ok;
13584 case 0xe3000000000dULL: s390_format_RXY_RRRD(s390_irgen_DSG, ovl.fmt.RXY.r1,
13585 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13586 ovl.fmt.RXY.dl2,
13587 ovl.fmt.RXY.dh2); goto ok;
13588 case 0xe3000000000eULL: /* CVBG */ goto unimplemented;
13589 case 0xe3000000000fULL: s390_format_RXY_RRRD(s390_irgen_LRVG, ovl.fmt.RXY.r1,
13590 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13591 ovl.fmt.RXY.dl2,
13592 ovl.fmt.RXY.dh2); goto ok;
13593 case 0xe30000000012ULL: s390_format_RXY_RRRD(s390_irgen_LT, ovl.fmt.RXY.r1,
13594 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13595 ovl.fmt.RXY.dl2,
13596 ovl.fmt.RXY.dh2); goto ok;
13597 case 0xe30000000013ULL: /* LRAY */ goto unimplemented;
13598 case 0xe30000000014ULL: s390_format_RXY_RRRD(s390_irgen_LGF, 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 0xe30000000015ULL: s390_format_RXY_RRRD(s390_irgen_LGH, 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 0xe30000000016ULL: s390_format_RXY_RRRD(s390_irgen_LLGF, 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 0xe30000000017ULL: s390_format_RXY_RRRD(s390_irgen_LLGT, 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 0xe30000000018ULL: s390_format_RXY_RRRD(s390_irgen_AGF, 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 0xe30000000019ULL: s390_format_RXY_RRRD(s390_irgen_SGF, 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 0xe3000000001aULL: s390_format_RXY_RRRD(s390_irgen_ALGF, 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 0xe3000000001bULL: s390_format_RXY_RRRD(s390_irgen_SLGF, ovl.fmt.RXY.r1,
13627 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13628 ovl.fmt.RXY.dl2,
13629 ovl.fmt.RXY.dh2); goto ok;
13630 case 0xe3000000001cULL: s390_format_RXY_RRRD(s390_irgen_MSGF, ovl.fmt.RXY.r1,
13631 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13632 ovl.fmt.RXY.dl2,
13633 ovl.fmt.RXY.dh2); goto ok;
13634 case 0xe3000000001dULL: s390_format_RXY_RRRD(s390_irgen_DSGF, ovl.fmt.RXY.r1,
13635 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13636 ovl.fmt.RXY.dl2,
13637 ovl.fmt.RXY.dh2); goto ok;
13638 case 0xe3000000001eULL: s390_format_RXY_RRRD(s390_irgen_LRV, ovl.fmt.RXY.r1,
13639 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13640 ovl.fmt.RXY.dl2,
13641 ovl.fmt.RXY.dh2); goto ok;
13642 case 0xe3000000001fULL: s390_format_RXY_RRRD(s390_irgen_LRVH, ovl.fmt.RXY.r1,
13643 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13644 ovl.fmt.RXY.dl2,
13645 ovl.fmt.RXY.dh2); goto ok;
13646 case 0xe30000000020ULL: s390_format_RXY_RRRD(s390_irgen_CG, ovl.fmt.RXY.r1,
13647 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13648 ovl.fmt.RXY.dl2,
13649 ovl.fmt.RXY.dh2); goto ok;
13650 case 0xe30000000021ULL: s390_format_RXY_RRRD(s390_irgen_CLG, ovl.fmt.RXY.r1,
13651 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13652 ovl.fmt.RXY.dl2,
13653 ovl.fmt.RXY.dh2); goto ok;
13654 case 0xe30000000024ULL: s390_format_RXY_RRRD(s390_irgen_STG, ovl.fmt.RXY.r1,
13655 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13656 ovl.fmt.RXY.dl2,
13657 ovl.fmt.RXY.dh2); goto ok;
13658 case 0xe30000000026ULL: s390_format_RXY_RRRD(s390_irgen_CVDY, ovl.fmt.RXY.r1,
13659 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13660 ovl.fmt.RXY.dl2,
13661 ovl.fmt.RXY.dh2); goto ok;
13662 case 0xe3000000002eULL: /* CVDG */ goto unimplemented;
13663 case 0xe3000000002fULL: s390_format_RXY_RRRD(s390_irgen_STRVG,
13664 ovl.fmt.RXY.r1, ovl.fmt.RXY.x2,
13665 ovl.fmt.RXY.b2, ovl.fmt.RXY.dl2,
13666 ovl.fmt.RXY.dh2); goto ok;
13667 case 0xe30000000030ULL: s390_format_RXY_RRRD(s390_irgen_CGF, 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 0xe30000000031ULL: s390_format_RXY_RRRD(s390_irgen_CLGF, 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 0xe30000000032ULL: s390_format_RXY_RRRD(s390_irgen_LTGF, 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 0xe30000000034ULL: s390_format_RXY_RRRD(s390_irgen_CGH, 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 0xe30000000036ULL: s390_format_RXY_URRD(s390_irgen_PFD, 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 0xe3000000003eULL: s390_format_RXY_RRRD(s390_irgen_STRV, 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 0xe3000000003fULL: s390_format_RXY_RRRD(s390_irgen_STRVH,
13692 ovl.fmt.RXY.r1, ovl.fmt.RXY.x2,
13693 ovl.fmt.RXY.b2, ovl.fmt.RXY.dl2,
13694 ovl.fmt.RXY.dh2); goto ok;
13695 case 0xe30000000046ULL: s390_format_RXY_RRRD(s390_irgen_BCTG, 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 0xe30000000050ULL: s390_format_RXY_RRRD(s390_irgen_STY, 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 0xe30000000051ULL: s390_format_RXY_RRRD(s390_irgen_MSY, 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 0xe30000000054ULL: s390_format_RXY_RRRD(s390_irgen_NY, 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 0xe30000000055ULL: s390_format_RXY_RRRD(s390_irgen_CLY, 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 0xe30000000056ULL: s390_format_RXY_RRRD(s390_irgen_OY, 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 0xe30000000057ULL: s390_format_RXY_RRRD(s390_irgen_XY, 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 0xe30000000058ULL: s390_format_RXY_RRRD(s390_irgen_LY, 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 0xe30000000059ULL: s390_format_RXY_RRRD(s390_irgen_CY, 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 0xe3000000005aULL: s390_format_RXY_RRRD(s390_irgen_AY, 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 0xe3000000005bULL: s390_format_RXY_RRRD(s390_irgen_SY, 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 0xe3000000005cULL: s390_format_RXY_RRRD(s390_irgen_MFY, 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 0xe3000000005eULL: s390_format_RXY_RRRD(s390_irgen_ALY, 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 0xe3000000005fULL: s390_format_RXY_RRRD(s390_irgen_SLY, 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 0xe30000000070ULL: s390_format_RXY_RRRD(s390_irgen_STHY, 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 0xe30000000071ULL: s390_format_RXY_RRRD(s390_irgen_LAY, 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 0xe30000000072ULL: s390_format_RXY_RRRD(s390_irgen_STCY, 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 0xe30000000073ULL: s390_format_RXY_RRRD(s390_irgen_ICY, 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 0xe30000000075ULL: s390_format_RXY_RRRD(s390_irgen_LAEY, 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 0xe30000000076ULL: s390_format_RXY_RRRD(s390_irgen_LB, 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 0xe30000000077ULL: s390_format_RXY_RRRD(s390_irgen_LGB, 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 0xe30000000078ULL: s390_format_RXY_RRRD(s390_irgen_LHY, 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 0xe30000000079ULL: s390_format_RXY_RRRD(s390_irgen_CHY, 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 0xe3000000007aULL: s390_format_RXY_RRRD(s390_irgen_AHY, 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 0xe3000000007bULL: s390_format_RXY_RRRD(s390_irgen_SHY, 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 0xe3000000007cULL: s390_format_RXY_RRRD(s390_irgen_MHY, 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 0xe30000000080ULL: s390_format_RXY_RRRD(s390_irgen_NG, 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 0xe30000000081ULL: s390_format_RXY_RRRD(s390_irgen_OG, 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 0xe30000000082ULL: s390_format_RXY_RRRD(s390_irgen_XG, 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 0xe30000000086ULL: s390_format_RXY_RRRD(s390_irgen_MLG, 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 0xe30000000087ULL: s390_format_RXY_RRRD(s390_irgen_DLG, 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 0xe30000000088ULL: s390_format_RXY_RRRD(s390_irgen_ALCG, 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 0xe30000000089ULL: s390_format_RXY_RRRD(s390_irgen_SLBG, 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 0xe3000000008eULL: s390_format_RXY_RRRD(s390_irgen_STPQ, 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 0xe3000000008fULL: s390_format_RXY_RRRD(s390_irgen_LPQ, 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 0xe30000000090ULL: s390_format_RXY_RRRD(s390_irgen_LLGC, 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 0xe30000000091ULL: s390_format_RXY_RRRD(s390_irgen_LLGH, 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 0xe30000000094ULL: s390_format_RXY_RRRD(s390_irgen_LLC, 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 0xe30000000095ULL: s390_format_RXY_RRRD(s390_irgen_LLH, 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 0xe30000000096ULL: s390_format_RXY_RRRD(s390_irgen_ML, 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 0xe30000000097ULL: s390_format_RXY_RRRD(s390_irgen_DL, 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 0xe30000000098ULL: s390_format_RXY_RRRD(s390_irgen_ALC, 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 0xe30000000099ULL: s390_format_RXY_RRRD(s390_irgen_SLB, 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 0xe300000000c0ULL: s390_format_RXY_RRRD(s390_irgen_LBH, 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 0xe300000000c2ULL: s390_format_RXY_RRRD(s390_irgen_LLCH, ovl.fmt.RXY.r1,
13872 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13873 ovl.fmt.RXY.dl2,
13874 ovl.fmt.RXY.dh2); goto ok;
13875 case 0xe300000000c3ULL: s390_format_RXY_RRRD(s390_irgen_STCH, ovl.fmt.RXY.r1,
13876 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13877 ovl.fmt.RXY.dl2,
13878 ovl.fmt.RXY.dh2); goto ok;
13879 case 0xe300000000c4ULL: s390_format_RXY_RRRD(s390_irgen_LHH, ovl.fmt.RXY.r1,
13880 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13881 ovl.fmt.RXY.dl2,
13882 ovl.fmt.RXY.dh2); goto ok;
13883 case 0xe300000000c6ULL: s390_format_RXY_RRRD(s390_irgen_LLHH, ovl.fmt.RXY.r1,
13884 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13885 ovl.fmt.RXY.dl2,
13886 ovl.fmt.RXY.dh2); goto ok;
13887 case 0xe300000000c7ULL: s390_format_RXY_RRRD(s390_irgen_STHH, ovl.fmt.RXY.r1,
13888 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13889 ovl.fmt.RXY.dl2,
13890 ovl.fmt.RXY.dh2); goto ok;
13891 case 0xe300000000caULL: s390_format_RXY_RRRD(s390_irgen_LFH, ovl.fmt.RXY.r1,
13892 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13893 ovl.fmt.RXY.dl2,
13894 ovl.fmt.RXY.dh2); goto ok;
13895 case 0xe300000000cbULL: s390_format_RXY_RRRD(s390_irgen_STFH, ovl.fmt.RXY.r1,
13896 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13897 ovl.fmt.RXY.dl2,
13898 ovl.fmt.RXY.dh2); goto ok;
13899 case 0xe300000000cdULL: s390_format_RXY_RRRD(s390_irgen_CHF, ovl.fmt.RXY.r1,
13900 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13901 ovl.fmt.RXY.dl2,
13902 ovl.fmt.RXY.dh2); goto ok;
13903 case 0xe300000000cfULL: s390_format_RXY_RRRD(s390_irgen_CLHF, ovl.fmt.RXY.r1,
13904 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13905 ovl.fmt.RXY.dl2,
13906 ovl.fmt.RXY.dh2); goto ok;
13907 case 0xeb0000000004ULL: s390_format_RSY_RRRD(s390_irgen_LMG, ovl.fmt.RSY.r1,
13908 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13909 ovl.fmt.RSY.dl2,
13910 ovl.fmt.RSY.dh2); goto ok;
13911 case 0xeb000000000aULL: s390_format_RSY_RRRD(s390_irgen_SRAG, ovl.fmt.RSY.r1,
13912 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13913 ovl.fmt.RSY.dl2,
13914 ovl.fmt.RSY.dh2); goto ok;
13915 case 0xeb000000000bULL: s390_format_RSY_RRRD(s390_irgen_SLAG, ovl.fmt.RSY.r1,
13916 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13917 ovl.fmt.RSY.dl2,
13918 ovl.fmt.RSY.dh2); goto ok;
13919 case 0xeb000000000cULL: s390_format_RSY_RRRD(s390_irgen_SRLG, ovl.fmt.RSY.r1,
13920 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13921 ovl.fmt.RSY.dl2,
13922 ovl.fmt.RSY.dh2); goto ok;
13923 case 0xeb000000000dULL: s390_format_RSY_RRRD(s390_irgen_SLLG, ovl.fmt.RSY.r1,
13924 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13925 ovl.fmt.RSY.dl2,
13926 ovl.fmt.RSY.dh2); goto ok;
13927 case 0xeb000000000fULL: /* TRACG */ goto unimplemented;
13928 case 0xeb0000000014ULL: s390_format_RSY_RRRD(s390_irgen_CSY, ovl.fmt.RSY.r1,
13929 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13930 ovl.fmt.RSY.dl2,
13931 ovl.fmt.RSY.dh2); goto ok;
13932 case 0xeb000000001cULL: s390_format_RSY_RRRD(s390_irgen_RLLG, ovl.fmt.RSY.r1,
13933 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13934 ovl.fmt.RSY.dl2,
13935 ovl.fmt.RSY.dh2); goto ok;
13936 case 0xeb000000001dULL: s390_format_RSY_RRRD(s390_irgen_RLL, ovl.fmt.RSY.r1,
13937 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13938 ovl.fmt.RSY.dl2,
13939 ovl.fmt.RSY.dh2); goto ok;
13940 case 0xeb0000000020ULL: s390_format_RSY_RURD(s390_irgen_CLMH, ovl.fmt.RSY.r1,
13941 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13942 ovl.fmt.RSY.dl2,
13943 ovl.fmt.RSY.dh2); goto ok;
13944 case 0xeb0000000021ULL: s390_format_RSY_RURD(s390_irgen_CLMY, ovl.fmt.RSY.r1,
13945 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13946 ovl.fmt.RSY.dl2,
13947 ovl.fmt.RSY.dh2); goto ok;
13948 case 0xeb0000000024ULL: s390_format_RSY_RRRD(s390_irgen_STMG, ovl.fmt.RSY.r1,
13949 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13950 ovl.fmt.RSY.dl2,
13951 ovl.fmt.RSY.dh2); goto ok;
13952 case 0xeb0000000025ULL: /* STCTG */ goto unimplemented;
13953 case 0xeb0000000026ULL: s390_format_RSY_RRRD(s390_irgen_STMH, ovl.fmt.RSY.r1,
13954 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13955 ovl.fmt.RSY.dl2,
13956 ovl.fmt.RSY.dh2); goto ok;
13957 case 0xeb000000002cULL: s390_format_RSY_RURD(s390_irgen_STCMH,
13958 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
13959 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
13960 ovl.fmt.RSY.dh2); goto ok;
13961 case 0xeb000000002dULL: s390_format_RSY_RURD(s390_irgen_STCMY,
13962 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
13963 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
13964 ovl.fmt.RSY.dh2); goto ok;
13965 case 0xeb000000002fULL: /* LCTLG */ goto unimplemented;
13966 case 0xeb0000000030ULL: s390_format_RSY_RRRD(s390_irgen_CSG, ovl.fmt.RSY.r1,
13967 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13968 ovl.fmt.RSY.dl2,
13969 ovl.fmt.RSY.dh2); goto ok;
florian448cbba2012-06-06 02:26:01 +000013970 case 0xeb0000000031ULL: s390_format_RSY_RRRD(s390_irgen_CDSY, ovl.fmt.RSY.r1,
13971 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13972 ovl.fmt.RSY.dl2,
13973 ovl.fmt.RSY.dh2); goto ok;
13974 case 0xeb000000003eULL: s390_format_RSY_RRRD(s390_irgen_CDSG, ovl.fmt.RSY.r1,
13975 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13976 ovl.fmt.RSY.dl2,
13977 ovl.fmt.RSY.dh2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013978 case 0xeb0000000044ULL: s390_format_RSY_RRRD(s390_irgen_BXHG, ovl.fmt.RSY.r1,
13979 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13980 ovl.fmt.RSY.dl2,
13981 ovl.fmt.RSY.dh2); goto ok;
13982 case 0xeb0000000045ULL: s390_format_RSY_RRRD(s390_irgen_BXLEG,
13983 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
13984 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
13985 ovl.fmt.RSY.dh2); goto ok;
florian8c88cb62012-08-26 18:58:13 +000013986 case 0xeb000000004cULL: s390_format_RSY_RRRD(s390_irgen_ECAG, ovl.fmt.RSY.r1,
13987 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13988 ovl.fmt.RSY.dl2,
13989 ovl.fmt.RSY.dh2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013990 case 0xeb0000000051ULL: s390_format_SIY_URD(s390_irgen_TMY, ovl.fmt.SIY.i2,
13991 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
13992 ovl.fmt.SIY.dh1); goto ok;
13993 case 0xeb0000000052ULL: s390_format_SIY_URD(s390_irgen_MVIY, ovl.fmt.SIY.i2,
13994 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
13995 ovl.fmt.SIY.dh1); goto ok;
13996 case 0xeb0000000054ULL: s390_format_SIY_URD(s390_irgen_NIY, ovl.fmt.SIY.i2,
13997 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
13998 ovl.fmt.SIY.dh1); goto ok;
13999 case 0xeb0000000055ULL: s390_format_SIY_URD(s390_irgen_CLIY, ovl.fmt.SIY.i2,
14000 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
14001 ovl.fmt.SIY.dh1); goto ok;
14002 case 0xeb0000000056ULL: s390_format_SIY_URD(s390_irgen_OIY, ovl.fmt.SIY.i2,
14003 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
14004 ovl.fmt.SIY.dh1); goto ok;
14005 case 0xeb0000000057ULL: s390_format_SIY_URD(s390_irgen_XIY, ovl.fmt.SIY.i2,
14006 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
14007 ovl.fmt.SIY.dh1); goto ok;
14008 case 0xeb000000006aULL: s390_format_SIY_IRD(s390_irgen_ASI, ovl.fmt.SIY.i2,
14009 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
14010 ovl.fmt.SIY.dh1); goto ok;
14011 case 0xeb000000006eULL: s390_format_SIY_IRD(s390_irgen_ALSI, ovl.fmt.SIY.i2,
14012 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
14013 ovl.fmt.SIY.dh1); goto ok;
14014 case 0xeb000000007aULL: s390_format_SIY_IRD(s390_irgen_AGSI, ovl.fmt.SIY.i2,
14015 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
14016 ovl.fmt.SIY.dh1); goto ok;
14017 case 0xeb000000007eULL: s390_format_SIY_IRD(s390_irgen_ALGSI, ovl.fmt.SIY.i2,
14018 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
14019 ovl.fmt.SIY.dh1); goto ok;
14020 case 0xeb0000000080ULL: s390_format_RSY_RURD(s390_irgen_ICMH, ovl.fmt.RSY.r1,
14021 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14022 ovl.fmt.RSY.dl2,
14023 ovl.fmt.RSY.dh2); goto ok;
14024 case 0xeb0000000081ULL: s390_format_RSY_RURD(s390_irgen_ICMY, ovl.fmt.RSY.r1,
14025 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14026 ovl.fmt.RSY.dl2,
14027 ovl.fmt.RSY.dh2); goto ok;
14028 case 0xeb000000008eULL: /* MVCLU */ goto unimplemented;
14029 case 0xeb000000008fULL: /* CLCLU */ goto unimplemented;
14030 case 0xeb0000000090ULL: s390_format_RSY_RRRD(s390_irgen_STMY, ovl.fmt.RSY.r1,
14031 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14032 ovl.fmt.RSY.dl2,
14033 ovl.fmt.RSY.dh2); goto ok;
14034 case 0xeb0000000096ULL: s390_format_RSY_RRRD(s390_irgen_LMH, ovl.fmt.RSY.r1,
14035 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14036 ovl.fmt.RSY.dl2,
14037 ovl.fmt.RSY.dh2); goto ok;
14038 case 0xeb0000000098ULL: s390_format_RSY_RRRD(s390_irgen_LMY, ovl.fmt.RSY.r1,
14039 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14040 ovl.fmt.RSY.dl2,
14041 ovl.fmt.RSY.dh2); goto ok;
14042 case 0xeb000000009aULL: s390_format_RSY_AARD(s390_irgen_LAMY, ovl.fmt.RSY.r1,
14043 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14044 ovl.fmt.RSY.dl2,
14045 ovl.fmt.RSY.dh2); goto ok;
14046 case 0xeb000000009bULL: s390_format_RSY_AARD(s390_irgen_STAMY,
14047 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
14048 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
14049 ovl.fmt.RSY.dh2); goto ok;
14050 case 0xeb00000000c0ULL: /* TP */ goto unimplemented;
14051 case 0xeb00000000dcULL: s390_format_RSY_RRRD(s390_irgen_SRAK, ovl.fmt.RSY.r1,
14052 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14053 ovl.fmt.RSY.dl2,
14054 ovl.fmt.RSY.dh2); goto ok;
14055 case 0xeb00000000ddULL: s390_format_RSY_RRRD(s390_irgen_SLAK, ovl.fmt.RSY.r1,
14056 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14057 ovl.fmt.RSY.dl2,
14058 ovl.fmt.RSY.dh2); goto ok;
14059 case 0xeb00000000deULL: s390_format_RSY_RRRD(s390_irgen_SRLK, ovl.fmt.RSY.r1,
14060 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14061 ovl.fmt.RSY.dl2,
14062 ovl.fmt.RSY.dh2); goto ok;
14063 case 0xeb00000000dfULL: s390_format_RSY_RRRD(s390_irgen_SLLK, ovl.fmt.RSY.r1,
14064 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14065 ovl.fmt.RSY.dl2,
14066 ovl.fmt.RSY.dh2); goto ok;
sewardjd7bde722011-04-05 13:19:33 +000014067 case 0xeb00000000e2ULL: s390_format_RSY_RDRM(s390_irgen_LOCG, ovl.fmt.RSY.r1,
14068 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14069 ovl.fmt.RSY.dl2,
14070 ovl.fmt.RSY.dh2,
14071 S390_XMNM_LOCG); goto ok;
14072 case 0xeb00000000e3ULL: s390_format_RSY_RDRM(s390_irgen_STOCG,
14073 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
14074 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
14075 ovl.fmt.RSY.dh2,
14076 S390_XMNM_STOCG); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014077 case 0xeb00000000e4ULL: s390_format_RSY_RRRD(s390_irgen_LANG, ovl.fmt.RSY.r1,
14078 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14079 ovl.fmt.RSY.dl2,
14080 ovl.fmt.RSY.dh2); goto ok;
14081 case 0xeb00000000e6ULL: s390_format_RSY_RRRD(s390_irgen_LAOG, ovl.fmt.RSY.r1,
14082 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14083 ovl.fmt.RSY.dl2,
14084 ovl.fmt.RSY.dh2); goto ok;
14085 case 0xeb00000000e7ULL: s390_format_RSY_RRRD(s390_irgen_LAXG, ovl.fmt.RSY.r1,
14086 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14087 ovl.fmt.RSY.dl2,
14088 ovl.fmt.RSY.dh2); goto ok;
14089 case 0xeb00000000e8ULL: s390_format_RSY_RRRD(s390_irgen_LAAG, ovl.fmt.RSY.r1,
14090 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14091 ovl.fmt.RSY.dl2,
14092 ovl.fmt.RSY.dh2); goto ok;
14093 case 0xeb00000000eaULL: s390_format_RSY_RRRD(s390_irgen_LAALG,
14094 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
14095 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
14096 ovl.fmt.RSY.dh2); goto ok;
sewardjd7bde722011-04-05 13:19:33 +000014097 case 0xeb00000000f2ULL: s390_format_RSY_RDRM(s390_irgen_LOC, ovl.fmt.RSY.r1,
14098 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14099 ovl.fmt.RSY.dl2,
14100 ovl.fmt.RSY.dh2, S390_XMNM_LOC);
14101 goto ok;
14102 case 0xeb00000000f3ULL: s390_format_RSY_RDRM(s390_irgen_STOC, ovl.fmt.RSY.r1,
14103 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14104 ovl.fmt.RSY.dl2,
14105 ovl.fmt.RSY.dh2,
14106 S390_XMNM_STOC); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014107 case 0xeb00000000f4ULL: s390_format_RSY_RRRD(s390_irgen_LAN, ovl.fmt.RSY.r1,
14108 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14109 ovl.fmt.RSY.dl2,
14110 ovl.fmt.RSY.dh2); goto ok;
14111 case 0xeb00000000f6ULL: s390_format_RSY_RRRD(s390_irgen_LAO, ovl.fmt.RSY.r1,
14112 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14113 ovl.fmt.RSY.dl2,
14114 ovl.fmt.RSY.dh2); goto ok;
14115 case 0xeb00000000f7ULL: s390_format_RSY_RRRD(s390_irgen_LAX, ovl.fmt.RSY.r1,
14116 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14117 ovl.fmt.RSY.dl2,
14118 ovl.fmt.RSY.dh2); goto ok;
14119 case 0xeb00000000f8ULL: s390_format_RSY_RRRD(s390_irgen_LAA, ovl.fmt.RSY.r1,
14120 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14121 ovl.fmt.RSY.dl2,
14122 ovl.fmt.RSY.dh2); goto ok;
14123 case 0xeb00000000faULL: s390_format_RSY_RRRD(s390_irgen_LAAL, ovl.fmt.RSY.r1,
14124 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14125 ovl.fmt.RSY.dl2,
14126 ovl.fmt.RSY.dh2); goto ok;
14127 case 0xec0000000044ULL: s390_format_RIE_RRP(s390_irgen_BRXHG, ovl.fmt.RIE.r1,
14128 ovl.fmt.RIE.r3, ovl.fmt.RIE.i2);
14129 goto ok;
14130 case 0xec0000000045ULL: s390_format_RIE_RRP(s390_irgen_BRXLG, ovl.fmt.RIE.r1,
14131 ovl.fmt.RIE.r3, ovl.fmt.RIE.i2);
14132 goto ok;
14133 case 0xec0000000051ULL: /* RISBLG */ goto unimplemented;
14134 case 0xec0000000054ULL: s390_format_RIE_RRUUU(s390_irgen_RNSBG,
14135 ovl.fmt.RIE_RRUUU.r1,
14136 ovl.fmt.RIE_RRUUU.r2,
14137 ovl.fmt.RIE_RRUUU.i3,
14138 ovl.fmt.RIE_RRUUU.i4,
14139 ovl.fmt.RIE_RRUUU.i5);
14140 goto ok;
14141 case 0xec0000000055ULL: s390_format_RIE_RRUUU(s390_irgen_RISBG,
14142 ovl.fmt.RIE_RRUUU.r1,
14143 ovl.fmt.RIE_RRUUU.r2,
14144 ovl.fmt.RIE_RRUUU.i3,
14145 ovl.fmt.RIE_RRUUU.i4,
14146 ovl.fmt.RIE_RRUUU.i5);
14147 goto ok;
14148 case 0xec0000000056ULL: s390_format_RIE_RRUUU(s390_irgen_ROSBG,
14149 ovl.fmt.RIE_RRUUU.r1,
14150 ovl.fmt.RIE_RRUUU.r2,
14151 ovl.fmt.RIE_RRUUU.i3,
14152 ovl.fmt.RIE_RRUUU.i4,
14153 ovl.fmt.RIE_RRUUU.i5);
14154 goto ok;
14155 case 0xec0000000057ULL: s390_format_RIE_RRUUU(s390_irgen_RXSBG,
14156 ovl.fmt.RIE_RRUUU.r1,
14157 ovl.fmt.RIE_RRUUU.r2,
14158 ovl.fmt.RIE_RRUUU.i3,
14159 ovl.fmt.RIE_RRUUU.i4,
14160 ovl.fmt.RIE_RRUUU.i5);
14161 goto ok;
14162 case 0xec000000005dULL: /* RISBHG */ goto unimplemented;
14163 case 0xec0000000064ULL: s390_format_RIE_RRPU(s390_irgen_CGRJ,
14164 ovl.fmt.RIE_RRPU.r1,
14165 ovl.fmt.RIE_RRPU.r2,
14166 ovl.fmt.RIE_RRPU.i4,
14167 ovl.fmt.RIE_RRPU.m3); goto ok;
14168 case 0xec0000000065ULL: s390_format_RIE_RRPU(s390_irgen_CLGRJ,
14169 ovl.fmt.RIE_RRPU.r1,
14170 ovl.fmt.RIE_RRPU.r2,
14171 ovl.fmt.RIE_RRPU.i4,
14172 ovl.fmt.RIE_RRPU.m3); goto ok;
14173 case 0xec0000000070ULL: /* CGIT */ goto unimplemented;
14174 case 0xec0000000071ULL: /* CLGIT */ goto unimplemented;
14175 case 0xec0000000072ULL: /* CIT */ goto unimplemented;
14176 case 0xec0000000073ULL: /* CLFIT */ goto unimplemented;
14177 case 0xec0000000076ULL: s390_format_RIE_RRPU(s390_irgen_CRJ,
14178 ovl.fmt.RIE_RRPU.r1,
14179 ovl.fmt.RIE_RRPU.r2,
14180 ovl.fmt.RIE_RRPU.i4,
14181 ovl.fmt.RIE_RRPU.m3); goto ok;
14182 case 0xec0000000077ULL: s390_format_RIE_RRPU(s390_irgen_CLRJ,
14183 ovl.fmt.RIE_RRPU.r1,
14184 ovl.fmt.RIE_RRPU.r2,
14185 ovl.fmt.RIE_RRPU.i4,
14186 ovl.fmt.RIE_RRPU.m3); goto ok;
14187 case 0xec000000007cULL: s390_format_RIE_RUPI(s390_irgen_CGIJ,
14188 ovl.fmt.RIEv3.r1,
14189 ovl.fmt.RIEv3.m3,
14190 ovl.fmt.RIEv3.i4,
14191 ovl.fmt.RIEv3.i2); goto ok;
14192 case 0xec000000007dULL: s390_format_RIE_RUPU(s390_irgen_CLGIJ,
14193 ovl.fmt.RIEv3.r1,
14194 ovl.fmt.RIEv3.m3,
14195 ovl.fmt.RIEv3.i4,
14196 ovl.fmt.RIEv3.i2); goto ok;
14197 case 0xec000000007eULL: s390_format_RIE_RUPI(s390_irgen_CIJ,
14198 ovl.fmt.RIEv3.r1,
14199 ovl.fmt.RIEv3.m3,
14200 ovl.fmt.RIEv3.i4,
14201 ovl.fmt.RIEv3.i2); goto ok;
14202 case 0xec000000007fULL: s390_format_RIE_RUPU(s390_irgen_CLIJ,
14203 ovl.fmt.RIEv3.r1,
14204 ovl.fmt.RIEv3.m3,
14205 ovl.fmt.RIEv3.i4,
14206 ovl.fmt.RIEv3.i2); goto ok;
14207 case 0xec00000000d8ULL: s390_format_RIE_RRI0(s390_irgen_AHIK, ovl.fmt.RIE.r1,
14208 ovl.fmt.RIE.r3, ovl.fmt.RIE.i2);
14209 goto ok;
14210 case 0xec00000000d9ULL: s390_format_RIE_RRI0(s390_irgen_AGHIK,
14211 ovl.fmt.RIE.r1, ovl.fmt.RIE.r3,
14212 ovl.fmt.RIE.i2); goto ok;
14213 case 0xec00000000daULL: s390_format_RIE_RRI0(s390_irgen_ALHSIK,
14214 ovl.fmt.RIE.r1, ovl.fmt.RIE.r3,
14215 ovl.fmt.RIE.i2); goto ok;
14216 case 0xec00000000dbULL: s390_format_RIE_RRI0(s390_irgen_ALGHSIK,
14217 ovl.fmt.RIE.r1, ovl.fmt.RIE.r3,
14218 ovl.fmt.RIE.i2); goto ok;
14219 case 0xec00000000e4ULL: s390_format_RRS(s390_irgen_CGRB, ovl.fmt.RRS.r1,
14220 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
14221 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
14222 goto ok;
14223 case 0xec00000000e5ULL: s390_format_RRS(s390_irgen_CLGRB, ovl.fmt.RRS.r1,
14224 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
14225 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
14226 goto ok;
14227 case 0xec00000000f6ULL: s390_format_RRS(s390_irgen_CRB, ovl.fmt.RRS.r1,
14228 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
14229 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
14230 goto ok;
14231 case 0xec00000000f7ULL: s390_format_RRS(s390_irgen_CLRB, ovl.fmt.RRS.r1,
14232 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
14233 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
14234 goto ok;
14235 case 0xec00000000fcULL: s390_format_RIS_RURDI(s390_irgen_CGIB,
14236 ovl.fmt.RIS.r1, ovl.fmt.RIS.m3,
14237 ovl.fmt.RIS.b4, ovl.fmt.RIS.d4,
14238 ovl.fmt.RIS.i2); goto ok;
14239 case 0xec00000000fdULL: s390_format_RIS_RURDU(s390_irgen_CLGIB,
14240 ovl.fmt.RIS.r1, ovl.fmt.RIS.m3,
14241 ovl.fmt.RIS.b4, ovl.fmt.RIS.d4,
14242 ovl.fmt.RIS.i2); goto ok;
14243 case 0xec00000000feULL: s390_format_RIS_RURDI(s390_irgen_CIB, ovl.fmt.RIS.r1,
14244 ovl.fmt.RIS.m3, ovl.fmt.RIS.b4,
14245 ovl.fmt.RIS.d4,
14246 ovl.fmt.RIS.i2); goto ok;
14247 case 0xec00000000ffULL: s390_format_RIS_RURDU(s390_irgen_CLIB,
14248 ovl.fmt.RIS.r1, ovl.fmt.RIS.m3,
14249 ovl.fmt.RIS.b4, ovl.fmt.RIS.d4,
14250 ovl.fmt.RIS.i2); goto ok;
14251 case 0xed0000000004ULL: s390_format_RXE_FRRD(s390_irgen_LDEB, ovl.fmt.RXE.r1,
14252 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14253 ovl.fmt.RXE.d2); goto ok;
14254 case 0xed0000000005ULL: s390_format_RXE_FRRD(s390_irgen_LXDB, ovl.fmt.RXE.r1,
14255 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14256 ovl.fmt.RXE.d2); goto ok;
14257 case 0xed0000000006ULL: s390_format_RXE_FRRD(s390_irgen_LXEB, ovl.fmt.RXE.r1,
14258 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14259 ovl.fmt.RXE.d2); goto ok;
14260 case 0xed0000000007ULL: /* MXDB */ goto unimplemented;
14261 case 0xed0000000008ULL: /* KEB */ goto unimplemented;
14262 case 0xed0000000009ULL: s390_format_RXE_FRRD(s390_irgen_CEB, ovl.fmt.RXE.r1,
14263 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14264 ovl.fmt.RXE.d2); goto ok;
14265 case 0xed000000000aULL: s390_format_RXE_FRRD(s390_irgen_AEB, ovl.fmt.RXE.r1,
14266 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14267 ovl.fmt.RXE.d2); goto ok;
14268 case 0xed000000000bULL: s390_format_RXE_FRRD(s390_irgen_SEB, ovl.fmt.RXE.r1,
14269 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14270 ovl.fmt.RXE.d2); goto ok;
14271 case 0xed000000000cULL: /* MDEB */ goto unimplemented;
14272 case 0xed000000000dULL: s390_format_RXE_FRRD(s390_irgen_DEB, ovl.fmt.RXE.r1,
14273 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14274 ovl.fmt.RXE.d2); goto ok;
14275 case 0xed000000000eULL: s390_format_RXF_FRRDF(s390_irgen_MAEB,
14276 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
14277 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
14278 ovl.fmt.RXF.r1); goto ok;
14279 case 0xed000000000fULL: s390_format_RXF_FRRDF(s390_irgen_MSEB,
14280 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
14281 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
14282 ovl.fmt.RXF.r1); goto ok;
14283 case 0xed0000000010ULL: s390_format_RXE_FRRD(s390_irgen_TCEB, ovl.fmt.RXE.r1,
14284 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14285 ovl.fmt.RXE.d2); goto ok;
14286 case 0xed0000000011ULL: s390_format_RXE_FRRD(s390_irgen_TCDB, ovl.fmt.RXE.r1,
14287 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14288 ovl.fmt.RXE.d2); goto ok;
14289 case 0xed0000000012ULL: s390_format_RXE_FRRD(s390_irgen_TCXB, ovl.fmt.RXE.r1,
14290 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14291 ovl.fmt.RXE.d2); goto ok;
14292 case 0xed0000000014ULL: s390_format_RXE_FRRD(s390_irgen_SQEB, ovl.fmt.RXE.r1,
14293 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14294 ovl.fmt.RXE.d2); goto ok;
14295 case 0xed0000000015ULL: s390_format_RXE_FRRD(s390_irgen_SQDB, ovl.fmt.RXE.r1,
14296 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14297 ovl.fmt.RXE.d2); goto ok;
14298 case 0xed0000000017ULL: s390_format_RXE_FRRD(s390_irgen_MEEB, ovl.fmt.RXE.r1,
14299 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14300 ovl.fmt.RXE.d2); goto ok;
14301 case 0xed0000000018ULL: /* KDB */ goto unimplemented;
14302 case 0xed0000000019ULL: s390_format_RXE_FRRD(s390_irgen_CDB, ovl.fmt.RXE.r1,
14303 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14304 ovl.fmt.RXE.d2); goto ok;
14305 case 0xed000000001aULL: s390_format_RXE_FRRD(s390_irgen_ADB, ovl.fmt.RXE.r1,
14306 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14307 ovl.fmt.RXE.d2); goto ok;
14308 case 0xed000000001bULL: s390_format_RXE_FRRD(s390_irgen_SDB, ovl.fmt.RXE.r1,
14309 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14310 ovl.fmt.RXE.d2); goto ok;
14311 case 0xed000000001cULL: s390_format_RXE_FRRD(s390_irgen_MDB, ovl.fmt.RXE.r1,
14312 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14313 ovl.fmt.RXE.d2); goto ok;
14314 case 0xed000000001dULL: s390_format_RXE_FRRD(s390_irgen_DDB, ovl.fmt.RXE.r1,
14315 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14316 ovl.fmt.RXE.d2); goto ok;
14317 case 0xed000000001eULL: s390_format_RXF_FRRDF(s390_irgen_MADB,
14318 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
14319 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
14320 ovl.fmt.RXF.r1); goto ok;
14321 case 0xed000000001fULL: s390_format_RXF_FRRDF(s390_irgen_MSDB,
14322 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
14323 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
14324 ovl.fmt.RXF.r1); goto ok;
14325 case 0xed0000000024ULL: /* LDE */ goto unimplemented;
14326 case 0xed0000000025ULL: /* LXD */ goto unimplemented;
14327 case 0xed0000000026ULL: /* LXE */ goto unimplemented;
14328 case 0xed000000002eULL: /* MAE */ goto unimplemented;
14329 case 0xed000000002fULL: /* MSE */ goto unimplemented;
14330 case 0xed0000000034ULL: /* SQE */ goto unimplemented;
14331 case 0xed0000000035ULL: /* SQD */ goto unimplemented;
14332 case 0xed0000000037ULL: /* MEE */ goto unimplemented;
14333 case 0xed0000000038ULL: /* MAYL */ goto unimplemented;
14334 case 0xed0000000039ULL: /* MYL */ goto unimplemented;
14335 case 0xed000000003aULL: /* MAY */ goto unimplemented;
14336 case 0xed000000003bULL: /* MY */ goto unimplemented;
14337 case 0xed000000003cULL: /* MAYH */ goto unimplemented;
14338 case 0xed000000003dULL: /* MYH */ goto unimplemented;
14339 case 0xed000000003eULL: /* MAD */ goto unimplemented;
14340 case 0xed000000003fULL: /* MSD */ goto unimplemented;
14341 case 0xed0000000040ULL: /* SLDT */ goto unimplemented;
14342 case 0xed0000000041ULL: /* SRDT */ goto unimplemented;
14343 case 0xed0000000048ULL: /* SLXT */ goto unimplemented;
14344 case 0xed0000000049ULL: /* SRXT */ goto unimplemented;
14345 case 0xed0000000050ULL: /* TDCET */ goto unimplemented;
14346 case 0xed0000000051ULL: /* TDGET */ goto unimplemented;
14347 case 0xed0000000054ULL: /* TDCDT */ goto unimplemented;
14348 case 0xed0000000055ULL: /* TDGDT */ goto unimplemented;
14349 case 0xed0000000058ULL: /* TDCXT */ goto unimplemented;
14350 case 0xed0000000059ULL: /* TDGXT */ goto unimplemented;
14351 case 0xed0000000064ULL: s390_format_RXY_FRRD(s390_irgen_LEY, ovl.fmt.RXY.r1,
14352 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14353 ovl.fmt.RXY.dl2,
14354 ovl.fmt.RXY.dh2); goto ok;
14355 case 0xed0000000065ULL: s390_format_RXY_FRRD(s390_irgen_LDY, ovl.fmt.RXY.r1,
14356 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14357 ovl.fmt.RXY.dl2,
14358 ovl.fmt.RXY.dh2); goto ok;
14359 case 0xed0000000066ULL: s390_format_RXY_FRRD(s390_irgen_STEY, ovl.fmt.RXY.r1,
14360 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14361 ovl.fmt.RXY.dl2,
14362 ovl.fmt.RXY.dh2); goto ok;
14363 case 0xed0000000067ULL: s390_format_RXY_FRRD(s390_irgen_STDY, ovl.fmt.RXY.r1,
14364 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14365 ovl.fmt.RXY.dl2,
14366 ovl.fmt.RXY.dh2); goto ok;
14367 }
14368
14369 switch (((ovl.value >> 16) & 0xff0f00000000ULL) >> 32) {
14370 case 0xc000ULL: s390_format_RIL_RP(s390_irgen_LARL, ovl.fmt.RIL.r1,
14371 ovl.fmt.RIL.i2); goto ok;
14372 case 0xc001ULL: s390_format_RIL_RI(s390_irgen_LGFI, ovl.fmt.RIL.r1,
14373 ovl.fmt.RIL.i2); goto ok;
14374 case 0xc004ULL: s390_format_RIL(s390_irgen_BRCL, ovl.fmt.RIL.r1,
14375 ovl.fmt.RIL.i2); goto ok;
14376 case 0xc005ULL: s390_format_RIL_RP(s390_irgen_BRASL, ovl.fmt.RIL.r1,
14377 ovl.fmt.RIL.i2); goto ok;
14378 case 0xc006ULL: s390_format_RIL_RU(s390_irgen_XIHF, ovl.fmt.RIL.r1,
14379 ovl.fmt.RIL.i2); goto ok;
14380 case 0xc007ULL: s390_format_RIL_RU(s390_irgen_XILF, ovl.fmt.RIL.r1,
14381 ovl.fmt.RIL.i2); goto ok;
14382 case 0xc008ULL: s390_format_RIL_RU(s390_irgen_IIHF, ovl.fmt.RIL.r1,
14383 ovl.fmt.RIL.i2); goto ok;
14384 case 0xc009ULL: s390_format_RIL_RU(s390_irgen_IILF, ovl.fmt.RIL.r1,
14385 ovl.fmt.RIL.i2); goto ok;
14386 case 0xc00aULL: s390_format_RIL_RU(s390_irgen_NIHF, ovl.fmt.RIL.r1,
14387 ovl.fmt.RIL.i2); goto ok;
14388 case 0xc00bULL: s390_format_RIL_RU(s390_irgen_NILF, ovl.fmt.RIL.r1,
14389 ovl.fmt.RIL.i2); goto ok;
14390 case 0xc00cULL: s390_format_RIL_RU(s390_irgen_OIHF, ovl.fmt.RIL.r1,
14391 ovl.fmt.RIL.i2); goto ok;
14392 case 0xc00dULL: s390_format_RIL_RU(s390_irgen_OILF, ovl.fmt.RIL.r1,
14393 ovl.fmt.RIL.i2); goto ok;
14394 case 0xc00eULL: s390_format_RIL_RU(s390_irgen_LLIHF, ovl.fmt.RIL.r1,
14395 ovl.fmt.RIL.i2); goto ok;
14396 case 0xc00fULL: s390_format_RIL_RU(s390_irgen_LLILF, ovl.fmt.RIL.r1,
14397 ovl.fmt.RIL.i2); goto ok;
14398 case 0xc200ULL: s390_format_RIL_RI(s390_irgen_MSGFI, ovl.fmt.RIL.r1,
14399 ovl.fmt.RIL.i2); goto ok;
14400 case 0xc201ULL: s390_format_RIL_RI(s390_irgen_MSFI, ovl.fmt.RIL.r1,
14401 ovl.fmt.RIL.i2); goto ok;
14402 case 0xc204ULL: s390_format_RIL_RU(s390_irgen_SLGFI, ovl.fmt.RIL.r1,
14403 ovl.fmt.RIL.i2); goto ok;
14404 case 0xc205ULL: s390_format_RIL_RU(s390_irgen_SLFI, ovl.fmt.RIL.r1,
14405 ovl.fmt.RIL.i2); goto ok;
14406 case 0xc208ULL: s390_format_RIL_RI(s390_irgen_AGFI, ovl.fmt.RIL.r1,
14407 ovl.fmt.RIL.i2); goto ok;
14408 case 0xc209ULL: s390_format_RIL_RI(s390_irgen_AFI, ovl.fmt.RIL.r1,
14409 ovl.fmt.RIL.i2); goto ok;
14410 case 0xc20aULL: s390_format_RIL_RU(s390_irgen_ALGFI, ovl.fmt.RIL.r1,
14411 ovl.fmt.RIL.i2); goto ok;
14412 case 0xc20bULL: s390_format_RIL_RU(s390_irgen_ALFI, ovl.fmt.RIL.r1,
14413 ovl.fmt.RIL.i2); goto ok;
14414 case 0xc20cULL: s390_format_RIL_RI(s390_irgen_CGFI, ovl.fmt.RIL.r1,
14415 ovl.fmt.RIL.i2); goto ok;
14416 case 0xc20dULL: s390_format_RIL_RI(s390_irgen_CFI, ovl.fmt.RIL.r1,
14417 ovl.fmt.RIL.i2); goto ok;
14418 case 0xc20eULL: s390_format_RIL_RU(s390_irgen_CLGFI, ovl.fmt.RIL.r1,
14419 ovl.fmt.RIL.i2); goto ok;
14420 case 0xc20fULL: s390_format_RIL_RU(s390_irgen_CLFI, ovl.fmt.RIL.r1,
14421 ovl.fmt.RIL.i2); goto ok;
14422 case 0xc402ULL: s390_format_RIL_RP(s390_irgen_LLHRL, ovl.fmt.RIL.r1,
14423 ovl.fmt.RIL.i2); goto ok;
14424 case 0xc404ULL: s390_format_RIL_RP(s390_irgen_LGHRL, ovl.fmt.RIL.r1,
14425 ovl.fmt.RIL.i2); goto ok;
14426 case 0xc405ULL: s390_format_RIL_RP(s390_irgen_LHRL, ovl.fmt.RIL.r1,
14427 ovl.fmt.RIL.i2); goto ok;
14428 case 0xc406ULL: s390_format_RIL_RP(s390_irgen_LLGHRL, ovl.fmt.RIL.r1,
14429 ovl.fmt.RIL.i2); goto ok;
14430 case 0xc407ULL: s390_format_RIL_RP(s390_irgen_STHRL, ovl.fmt.RIL.r1,
14431 ovl.fmt.RIL.i2); goto ok;
14432 case 0xc408ULL: s390_format_RIL_RP(s390_irgen_LGRL, ovl.fmt.RIL.r1,
14433 ovl.fmt.RIL.i2); goto ok;
14434 case 0xc40bULL: s390_format_RIL_RP(s390_irgen_STGRL, ovl.fmt.RIL.r1,
14435 ovl.fmt.RIL.i2); goto ok;
14436 case 0xc40cULL: s390_format_RIL_RP(s390_irgen_LGFRL, ovl.fmt.RIL.r1,
14437 ovl.fmt.RIL.i2); goto ok;
14438 case 0xc40dULL: s390_format_RIL_RP(s390_irgen_LRL, ovl.fmt.RIL.r1,
14439 ovl.fmt.RIL.i2); goto ok;
14440 case 0xc40eULL: s390_format_RIL_RP(s390_irgen_LLGFRL, ovl.fmt.RIL.r1,
14441 ovl.fmt.RIL.i2); goto ok;
14442 case 0xc40fULL: s390_format_RIL_RP(s390_irgen_STRL, ovl.fmt.RIL.r1,
14443 ovl.fmt.RIL.i2); goto ok;
14444 case 0xc600ULL: s390_format_RIL_RP(s390_irgen_EXRL, ovl.fmt.RIL.r1,
14445 ovl.fmt.RIL.i2); goto ok;
14446 case 0xc602ULL: s390_format_RIL_UP(s390_irgen_PFDRL, ovl.fmt.RIL.r1,
14447 ovl.fmt.RIL.i2); goto ok;
14448 case 0xc604ULL: s390_format_RIL_RP(s390_irgen_CGHRL, ovl.fmt.RIL.r1,
14449 ovl.fmt.RIL.i2); goto ok;
14450 case 0xc605ULL: s390_format_RIL_RP(s390_irgen_CHRL, ovl.fmt.RIL.r1,
14451 ovl.fmt.RIL.i2); goto ok;
14452 case 0xc606ULL: s390_format_RIL_RP(s390_irgen_CLGHRL, ovl.fmt.RIL.r1,
14453 ovl.fmt.RIL.i2); goto ok;
14454 case 0xc607ULL: s390_format_RIL_RP(s390_irgen_CLHRL, ovl.fmt.RIL.r1,
14455 ovl.fmt.RIL.i2); goto ok;
14456 case 0xc608ULL: s390_format_RIL_RP(s390_irgen_CGRL, ovl.fmt.RIL.r1,
14457 ovl.fmt.RIL.i2); goto ok;
14458 case 0xc60aULL: s390_format_RIL_RP(s390_irgen_CLGRL, ovl.fmt.RIL.r1,
14459 ovl.fmt.RIL.i2); goto ok;
14460 case 0xc60cULL: s390_format_RIL_RP(s390_irgen_CGFRL, ovl.fmt.RIL.r1,
14461 ovl.fmt.RIL.i2); goto ok;
14462 case 0xc60dULL: s390_format_RIL_RP(s390_irgen_CRL, ovl.fmt.RIL.r1,
14463 ovl.fmt.RIL.i2); goto ok;
14464 case 0xc60eULL: s390_format_RIL_RP(s390_irgen_CLGFRL, ovl.fmt.RIL.r1,
14465 ovl.fmt.RIL.i2); goto ok;
14466 case 0xc60fULL: s390_format_RIL_RP(s390_irgen_CLRL, ovl.fmt.RIL.r1,
14467 ovl.fmt.RIL.i2); goto ok;
14468 case 0xc800ULL: /* MVCOS */ goto unimplemented;
14469 case 0xc801ULL: /* ECTG */ goto unimplemented;
14470 case 0xc802ULL: /* CSST */ goto unimplemented;
14471 case 0xc804ULL: /* LPD */ goto unimplemented;
14472 case 0xc805ULL: /* LPDG */ goto unimplemented;
14473 case 0xcc06ULL: /* BRCTH */ goto unimplemented;
14474 case 0xcc08ULL: s390_format_RIL_RI(s390_irgen_AIH, ovl.fmt.RIL.r1,
14475 ovl.fmt.RIL.i2); goto ok;
14476 case 0xcc0aULL: s390_format_RIL_RI(s390_irgen_ALSIH, ovl.fmt.RIL.r1,
14477 ovl.fmt.RIL.i2); goto ok;
14478 case 0xcc0bULL: s390_format_RIL_RI(s390_irgen_ALSIHN, ovl.fmt.RIL.r1,
14479 ovl.fmt.RIL.i2); goto ok;
14480 case 0xcc0dULL: s390_format_RIL_RI(s390_irgen_CIH, ovl.fmt.RIL.r1,
14481 ovl.fmt.RIL.i2); goto ok;
14482 case 0xcc0fULL: s390_format_RIL_RU(s390_irgen_CLIH, ovl.fmt.RIL.r1,
14483 ovl.fmt.RIL.i2); goto ok;
14484 }
14485
14486 switch (((ovl.value >> 16) & 0xff0000000000ULL) >> 40) {
14487 case 0xd0ULL: /* TRTR */ goto unimplemented;
14488 case 0xd1ULL: /* MVN */ goto unimplemented;
14489 case 0xd2ULL: s390_format_SS_L0RDRD(s390_irgen_MVC, ovl.fmt.SS.l,
14490 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
14491 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
14492 case 0xd3ULL: /* MVZ */ goto unimplemented;
14493 case 0xd4ULL: s390_format_SS_L0RDRD(s390_irgen_NC, ovl.fmt.SS.l,
14494 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
14495 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
14496 case 0xd5ULL: s390_format_SS_L0RDRD(s390_irgen_CLC, ovl.fmt.SS.l,
14497 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
14498 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
14499 case 0xd6ULL: s390_format_SS_L0RDRD(s390_irgen_OC, ovl.fmt.SS.l,
14500 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
14501 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
sewardjb63967e2011-03-24 08:50:04 +000014502 case 0xd7ULL:
14503 if (ovl.fmt.SS.b1 == ovl.fmt.SS.b2 && ovl.fmt.SS.d1 == ovl.fmt.SS.d2)
14504 s390_irgen_XC_sameloc(ovl.fmt.SS.l, ovl.fmt.SS.b1, ovl.fmt.SS.d1);
14505 else
14506 s390_format_SS_L0RDRD(s390_irgen_XC, ovl.fmt.SS.l,
14507 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
14508 ovl.fmt.SS.b2, ovl.fmt.SS.d2);
14509 goto ok;
sewardj2019a972011-03-07 16:04:07 +000014510 case 0xd9ULL: /* MVCK */ goto unimplemented;
14511 case 0xdaULL: /* MVCP */ goto unimplemented;
14512 case 0xdbULL: /* MVCS */ goto unimplemented;
florian730448f2012-02-04 17:07:07 +000014513 case 0xdcULL: s390_format_SS_L0RDRD(s390_irgen_TR, ovl.fmt.SS.l,
14514 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
14515 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014516 case 0xddULL: /* TRT */ goto unimplemented;
14517 case 0xdeULL: /* ED */ goto unimplemented;
14518 case 0xdfULL: /* EDMK */ goto unimplemented;
14519 case 0xe1ULL: /* PKU */ goto unimplemented;
14520 case 0xe2ULL: /* UNPKU */ goto unimplemented;
14521 case 0xe8ULL: /* MVCIN */ goto unimplemented;
14522 case 0xe9ULL: /* PKA */ goto unimplemented;
14523 case 0xeaULL: /* UNPKA */ goto unimplemented;
14524 case 0xeeULL: /* PLO */ goto unimplemented;
14525 case 0xefULL: /* LMD */ goto unimplemented;
14526 case 0xf0ULL: /* SRP */ goto unimplemented;
14527 case 0xf1ULL: /* MVO */ goto unimplemented;
14528 case 0xf2ULL: /* PACK */ goto unimplemented;
14529 case 0xf3ULL: /* UNPK */ goto unimplemented;
14530 case 0xf8ULL: /* ZAP */ goto unimplemented;
14531 case 0xf9ULL: /* CP */ goto unimplemented;
14532 case 0xfaULL: /* AP */ goto unimplemented;
14533 case 0xfbULL: /* SP */ goto unimplemented;
14534 case 0xfcULL: /* MP */ goto unimplemented;
14535 case 0xfdULL: /* DP */ goto unimplemented;
14536 }
14537
14538 switch (((ovl.value >> 16) & 0xffff00000000ULL) >> 32) {
14539 case 0xe500ULL: /* LASP */ goto unimplemented;
14540 case 0xe501ULL: /* TPROT */ goto unimplemented;
14541 case 0xe502ULL: /* STRAG */ goto unimplemented;
14542 case 0xe50eULL: /* MVCSK */ goto unimplemented;
14543 case 0xe50fULL: /* MVCDK */ goto unimplemented;
14544 case 0xe544ULL: s390_format_SIL_RDI(s390_irgen_MVHHI, ovl.fmt.SIL.b1,
14545 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14546 goto ok;
14547 case 0xe548ULL: s390_format_SIL_RDI(s390_irgen_MVGHI, ovl.fmt.SIL.b1,
14548 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14549 goto ok;
14550 case 0xe54cULL: s390_format_SIL_RDI(s390_irgen_MVHI, ovl.fmt.SIL.b1,
14551 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14552 goto ok;
14553 case 0xe554ULL: s390_format_SIL_RDI(s390_irgen_CHHSI, ovl.fmt.SIL.b1,
14554 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14555 goto ok;
14556 case 0xe555ULL: s390_format_SIL_RDU(s390_irgen_CLHHSI, ovl.fmt.SIL.b1,
14557 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14558 goto ok;
14559 case 0xe558ULL: s390_format_SIL_RDI(s390_irgen_CGHSI, ovl.fmt.SIL.b1,
14560 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14561 goto ok;
14562 case 0xe559ULL: s390_format_SIL_RDU(s390_irgen_CLGHSI, ovl.fmt.SIL.b1,
14563 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14564 goto ok;
14565 case 0xe55cULL: s390_format_SIL_RDI(s390_irgen_CHSI, ovl.fmt.SIL.b1,
14566 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14567 goto ok;
14568 case 0xe55dULL: s390_format_SIL_RDU(s390_irgen_CLFHSI, ovl.fmt.SIL.b1,
14569 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14570 goto ok;
14571 }
14572
14573 return S390_DECODE_UNKNOWN_INSN;
14574
14575ok:
14576 return S390_DECODE_OK;
14577
14578unimplemented:
14579 return S390_DECODE_UNIMPLEMENTED_INSN;
14580}
14581
14582/* Handle "special" instructions. */
14583static s390_decode_t
14584s390_decode_special_and_irgen(UChar *bytes)
14585{
14586 s390_decode_t status = S390_DECODE_OK;
14587
14588 /* Got a "Special" instruction preamble. Which one is it? */
14589 if (bytes[0] == 0x18 && bytes[1] == 0x22 /* lr %r2, %r2 */) {
14590 s390_irgen_client_request();
14591 } else if (bytes[0] == 0x18 && bytes[1] == 0x33 /* lr %r3, %r3 */) {
14592 s390_irgen_guest_NRADDR();
14593 } else if (bytes[0] == 0x18 && bytes[1] == 0x44 /* lr %r4, %r4 */) {
14594 s390_irgen_call_noredir();
florian2245ce92012-08-28 16:49:30 +000014595 } else if (bytes[0] == 0x18 && bytes[1] == 0x55 /* lr %r5, %r5 */) {
14596 vex_inject_ir(irsb, Iend_BE);
14597
14598 /* Invalidate the current insn. The reason is that the IRop we're
14599 injecting here can change. In which case the translation has to
14600 be redone. For ease of handling, we simply invalidate all the
14601 time. */
14602 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TISTART),
14603 mkU64(guest_IA_curr_instr)));
14604 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TILEN),
14605 mkU64(guest_IA_next_instr - guest_IA_curr_instr)));
14606 vassert(guest_IA_next_instr - guest_IA_curr_instr ==
14607 S390_SPECIAL_OP_PREAMBLE_SIZE + S390_SPECIAL_OP_SIZE);
14608
14609 put_IA(mkaddr_expr(guest_IA_next_instr));
14610 dis_res->whatNext = Dis_StopHere;
14611 dis_res->jk_StopHere = Ijk_TInval;
sewardj2019a972011-03-07 16:04:07 +000014612 } else {
14613 /* We don't know what it is. */
14614 return S390_DECODE_UNKNOWN_SPECIAL_INSN;
14615 }
14616
14617 dis_res->len = S390_SPECIAL_OP_PREAMBLE_SIZE + S390_SPECIAL_OP_SIZE;
14618
14619 return status;
14620}
14621
14622
14623/* Function returns # bytes that were decoded or 0 in case of failure */
florianb4df7682011-07-05 02:09:01 +000014624static UInt
sewardj2019a972011-03-07 16:04:07 +000014625s390_decode_and_irgen(UChar *bytes, UInt insn_length, DisResult *dres)
14626{
14627 s390_decode_t status;
14628
14629 dis_res = dres;
14630
14631 /* Spot the 8-byte preamble: 18ff lr r15,r15
14632 1811 lr r1,r1
14633 1822 lr r2,r2
14634 1833 lr r3,r3 */
14635 if (bytes[ 0] == 0x18 && bytes[ 1] == 0xff && bytes[ 2] == 0x18 &&
14636 bytes[ 3] == 0x11 && bytes[ 4] == 0x18 && bytes[ 5] == 0x22 &&
14637 bytes[ 6] == 0x18 && bytes[ 7] == 0x33) {
14638
14639 /* Handle special instruction that follows that preamble. */
14640 if (0) vex_printf("special function handling...\n");
florian2c8ed942011-08-01 22:07:51 +000014641
14642 insn_length = S390_SPECIAL_OP_PREAMBLE_SIZE + S390_SPECIAL_OP_SIZE;
14643 guest_IA_next_instr = guest_IA_curr_instr + insn_length;
14644
14645 status =
14646 s390_decode_special_and_irgen(bytes + S390_SPECIAL_OP_PREAMBLE_SIZE);
sewardj2019a972011-03-07 16:04:07 +000014647 } else {
14648 /* Handle normal instructions. */
14649 switch (insn_length) {
14650 case 2:
14651 status = s390_decode_2byte_and_irgen(bytes);
14652 break;
14653
14654 case 4:
14655 status = s390_decode_4byte_and_irgen(bytes);
14656 break;
14657
14658 case 6:
14659 status = s390_decode_6byte_and_irgen(bytes);
14660 break;
14661
14662 default:
14663 status = S390_DECODE_ERROR;
14664 break;
14665 }
14666 }
florian5fcbba22011-07-27 20:40:22 +000014667 /* If next instruction is execute, stop here */
florianf9e1ed72012-04-17 02:41:56 +000014668 if (dis_res->whatNext == Dis_Continue && bytes[insn_length] == 0x44) {
14669 put_IA(mkaddr_expr(guest_IA_next_instr));
sewardj2019a972011-03-07 16:04:07 +000014670 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +000014671 dis_res->jk_StopHere = Ijk_Boring;
sewardj2019a972011-03-07 16:04:07 +000014672 }
14673
14674 if (status == S390_DECODE_OK) return insn_length; /* OK */
14675
14676 /* Decoding failed somehow */
14677 vex_printf("vex s390->IR: ");
14678 switch (status) {
14679 case S390_DECODE_UNKNOWN_INSN:
14680 vex_printf("unknown insn: ");
14681 break;
14682
14683 case S390_DECODE_UNIMPLEMENTED_INSN:
14684 vex_printf("unimplemented insn: ");
14685 break;
14686
14687 case S390_DECODE_UNKNOWN_SPECIAL_INSN:
14688 vex_printf("unimplemented special insn: ");
14689 break;
14690
14691 default:
14692 case S390_DECODE_ERROR:
14693 vex_printf("decoding error: ");
14694 break;
14695 }
14696
14697 vex_printf("%02x%02x", bytes[0], bytes[1]);
14698 if (insn_length > 2) {
14699 vex_printf(" %02x%02x", bytes[2], bytes[3]);
14700 }
14701 if (insn_length > 4) {
14702 vex_printf(" %02x%02x", bytes[4], bytes[5]);
14703 }
14704 vex_printf("\n");
14705
14706 return 0; /* Failed */
14707}
14708
14709
sewardj2019a972011-03-07 16:04:07 +000014710/* Disassemble a single instruction INSN into IR. */
14711static DisResult
florian420c5012011-07-22 02:12:28 +000014712disInstr_S390_WRK(UChar *insn)
sewardj2019a972011-03-07 16:04:07 +000014713{
14714 UChar byte;
14715 UInt insn_length;
14716 DisResult dres;
14717
14718 /* ---------------------------------------------------- */
14719 /* --- Compute instruction length -- */
14720 /* ---------------------------------------------------- */
14721
14722 /* Get the first byte of the insn. */
14723 byte = insn[0];
14724
14725 /* The leftmost two bits (0:1) encode the length of the insn in bytes.
14726 00 -> 2 bytes, 01 -> 4 bytes, 10 -> 4 bytes, 11 -> 6 bytes. */
14727 insn_length = ((((byte >> 6) + 1) >> 1) + 1) << 1;
14728
14729 guest_IA_next_instr = guest_IA_curr_instr + insn_length;
14730
14731 /* ---------------------------------------------------- */
14732 /* --- Initialise the DisResult data -- */
14733 /* ---------------------------------------------------- */
14734 dres.whatNext = Dis_Continue;
14735 dres.len = insn_length;
14736 dres.continueAt = 0;
florian8844a632012-04-13 04:04:06 +000014737 dres.jk_StopHere = Ijk_INVALID;
sewardj2019a972011-03-07 16:04:07 +000014738
floriana99f20e2011-07-17 14:16:41 +000014739 /* fixs390: consider chasing of conditional jumps */
14740
sewardj2019a972011-03-07 16:04:07 +000014741 /* Normal and special instruction handling starts here. */
14742 if (s390_decode_and_irgen(insn, insn_length, &dres) == 0) {
14743 /* All decode failures end up here. The decoder has already issued an
14744 error message.
14745 Tell the dispatcher that this insn cannot be decoded, and so has
florian342e01a2012-07-26 02:37:49 +000014746 not been executed, and (is currently) the next to be executed.
14747 The insn address in the guest state needs to be set to
14748 guest_IA_curr_instr, otherwise the complaint will report an
14749 incorrect address. */
14750 put_IA(mkaddr_expr(guest_IA_curr_instr));
sewardj2019a972011-03-07 16:04:07 +000014751
florian8844a632012-04-13 04:04:06 +000014752 dres.whatNext = Dis_StopHere;
14753 dres.jk_StopHere = Ijk_NoDecode;
14754 dres.continueAt = 0;
14755 dres.len = 0;
14756 } else {
14757 /* Decode success */
14758 switch (dres.whatNext) {
14759 case Dis_Continue:
florian8559e412012-04-19 14:23:48 +000014760 put_IA(mkaddr_expr(guest_IA_next_instr));
florian8844a632012-04-13 04:04:06 +000014761 break;
14762 case Dis_ResteerU:
14763 case Dis_ResteerC:
14764 put_IA(mkaddr_expr(dres.continueAt));
14765 break;
14766 case Dis_StopHere:
florian4b8efad2012-09-02 18:07:08 +000014767 if (dres.jk_StopHere == Ijk_EmWarn ||
14768 dres.jk_StopHere == Ijk_EmFail) {
14769 /* We assume here, that emulation warnings are not given for
14770 insns that transfer control. There is no good way to
14771 do that. */
14772 put_IA(mkaddr_expr(guest_IA_next_instr));
14773 }
florian8844a632012-04-13 04:04:06 +000014774 break;
14775 default:
14776 vassert(0);
14777 }
sewardj2019a972011-03-07 16:04:07 +000014778 }
14779
14780 return dres;
14781}
14782
14783
14784/*------------------------------------------------------------*/
14785/*--- Top-level fn ---*/
14786/*------------------------------------------------------------*/
14787
14788/* Disassemble a single instruction into IR. The instruction
14789 is located in host memory at &guest_code[delta]. */
14790
14791DisResult
14792disInstr_S390(IRSB *irsb_IN,
sewardj2019a972011-03-07 16:04:07 +000014793 Bool (*resteerOkFn)(void *, Addr64),
14794 Bool resteerCisOk,
14795 void *callback_opaque,
14796 UChar *guest_code,
14797 Long delta,
14798 Addr64 guest_IP,
14799 VexArch guest_arch,
14800 VexArchInfo *archinfo,
14801 VexAbiInfo *abiinfo,
14802 Bool host_bigendian)
14803{
14804 vassert(guest_arch == VexArchS390X);
14805
14806 /* The instruction decoder requires a big-endian machine. */
14807 vassert(host_bigendian == True);
14808
14809 /* Set globals (see top of this file) */
14810 guest_IA_curr_instr = guest_IP;
sewardj2019a972011-03-07 16:04:07 +000014811 irsb = irsb_IN;
florian420c5012011-07-22 02:12:28 +000014812 resteer_fn = resteerOkFn;
14813 resteer_data = callback_opaque;
sewardj2019a972011-03-07 16:04:07 +000014814
florian420c5012011-07-22 02:12:28 +000014815 return disInstr_S390_WRK(guest_code + delta);
sewardj2019a972011-03-07 16:04:07 +000014816}
14817
14818/*---------------------------------------------------------------*/
14819/*--- end guest_s390_toIR.c ---*/
14820/*---------------------------------------------------------------*/