blob: 07486853c8081e875fc5a58f5998ccbba399e63a [file] [log] [blame]
sewardj2019a972011-03-07 16:04:07 +00001/* -*- mode: C; c-basic-offset: 3; -*- */
2
3/*---------------------------------------------------------------*/
4/*--- begin guest_s390_toIR.c ---*/
5/*---------------------------------------------------------------*/
6
7/*
8 This file is part of Valgrind, a dynamic binary instrumentation
9 framework.
10
florian61f23c12012-08-06 18:33:21 +000011 Copyright IBM Corp. 2010-2012
sewardj2019a972011-03-07 16:04:07 +000012
13 This program is free software; you can redistribute it and/or
14 modify it under the terms of the GNU General Public License as
15 published by the Free Software Foundation; either version 2 of the
16 License, or (at your option) any later version.
17
18 This program is distributed in the hope that it will be useful, but
19 WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 General Public License for more details.
22
23 You should have received a copy of the GNU General Public License
24 along with this program; if not, write to the Free Software
25 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
26 02110-1301, USA.
27
28 The GNU General Public License is contained in the file COPYING.
29*/
30
31/* Contributed by Florian Krohm and Christian Borntraeger */
32
33/* Translates s390 code to IR. */
34
35#include "libvex_basictypes.h"
36#include "libvex_ir.h"
florian58a637b2012-09-30 20:30:17 +000037#include "libvex_emnote.h"
florian933065d2011-07-11 01:48:02 +000038#include "libvex_s390x_common.h"
sewardj2019a972011-03-07 16:04:07 +000039#include "main_util.h" /* vassert */
40#include "main_globals.h" /* vex_traceflags */
41#include "guest_generic_bb_to_IR.h" /* DisResult */
42#include "guest_s390_defs.h" /* prototypes for this file's functions */
florian79af5752012-09-20 01:22:10 +000043#include "s390_disasm.h"
sewardj2019a972011-03-07 16:04:07 +000044#include "host_s390_defs.h" /* S390_ROUND_xyzzy */
45
sewardj2019a972011-03-07 16:04:07 +000046
47/*------------------------------------------------------------*/
florianb4df7682011-07-05 02:09:01 +000048/*--- Forward declarations ---*/
49/*------------------------------------------------------------*/
50static UInt s390_decode_and_irgen(UChar *, UInt, DisResult *);
florianb0bf6602012-05-05 00:01:16 +000051static void s390_irgen_xonc(IROp, IRTemp, IRTemp, IRTemp);
florian79e839e2012-05-05 02:20:30 +000052static void s390_irgen_CLC_EX(IRTemp, IRTemp, IRTemp);
florianb4df7682011-07-05 02:09:01 +000053
54
55/*------------------------------------------------------------*/
sewardj2019a972011-03-07 16:04:07 +000056/*--- Globals ---*/
57/*------------------------------------------------------------*/
58
59/* The IRSB* into which we're generating code. */
60static IRSB *irsb;
61
62/* The guest address for the instruction currently being
63 translated. */
64static Addr64 guest_IA_curr_instr;
65
66/* The guest address for the instruction following the current instruction. */
67static Addr64 guest_IA_next_instr;
68
69/* Result of disassembly step. */
70static DisResult *dis_res;
71
floriana64c2432011-07-16 02:11:50 +000072/* Resteer function and callback data */
73static Bool (*resteer_fn)(void *, Addr64);
74static void *resteer_data;
75
sewardj2019a972011-03-07 16:04:07 +000076/* The last seen execute target instruction */
77ULong last_execute_target;
78
79/* The possible outcomes of a decoding operation */
80typedef enum {
81 S390_DECODE_OK,
82 S390_DECODE_UNKNOWN_INSN,
83 S390_DECODE_UNIMPLEMENTED_INSN,
84 S390_DECODE_UNKNOWN_SPECIAL_INSN,
85 S390_DECODE_ERROR
86} s390_decode_t;
87
florian428dfdd2012-03-27 03:09:49 +000088
sewardj2019a972011-03-07 16:04:07 +000089/*------------------------------------------------------------*/
90/*--- Helpers for constructing IR. ---*/
91/*------------------------------------------------------------*/
92
93/* Sign extend a value with the given number of bits. This is a
94 macro because it allows us to overload the type of the value.
95 Note that VALUE must have a signed type! */
96#undef sign_extend
97#define sign_extend(value,num_bits) \
98(((value) << (sizeof(__typeof__(value)) * 8 - (num_bits))) >> \
99 (sizeof(__typeof__(value)) * 8 - (num_bits)))
100
101
102/* Add a statement to the current irsb. */
103static __inline__ void
104stmt(IRStmt *st)
105{
106 addStmtToIRSB(irsb, st);
107}
108
109/* Allocate a new temporary of the given type. */
110static __inline__ IRTemp
111newTemp(IRType type)
112{
113 vassert(isPlausibleIRType(type));
114
115 return newIRTemp(irsb->tyenv, type);
116}
117
118/* Create an expression node for a temporary */
119static __inline__ IRExpr *
120mkexpr(IRTemp tmp)
121{
122 return IRExpr_RdTmp(tmp);
123}
124
florian8844a632012-04-13 04:04:06 +0000125/* Generate an expression node for an address. */
126static __inline__ IRExpr *
127mkaddr_expr(Addr64 addr)
128{
129 return IRExpr_Const(IRConst_U64(addr));
130}
131
sewardj2019a972011-03-07 16:04:07 +0000132/* Add a statement that assigns to a temporary */
133static __inline__ void
134assign(IRTemp dst, IRExpr *expr)
135{
136 stmt(IRStmt_WrTmp(dst, expr));
137}
138
florian8844a632012-04-13 04:04:06 +0000139/* Write an address into the guest_IA */
140static __inline__ void
141put_IA(IRExpr *address)
142{
143 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_IA), address));
144}
145
sewardj2019a972011-03-07 16:04:07 +0000146/* Create a temporary of the given type and assign the expression to it */
147static __inline__ IRTemp
148mktemp(IRType type, IRExpr *expr)
149{
150 IRTemp temp = newTemp(type);
151
152 assign(temp, expr);
153
154 return temp;
155}
156
157/* Create a unary expression */
158static __inline__ IRExpr *
159unop(IROp kind, IRExpr *op)
160{
161 return IRExpr_Unop(kind, op);
162}
163
164/* Create a binary expression */
165static __inline__ IRExpr *
166binop(IROp kind, IRExpr *op1, IRExpr *op2)
167{
168 return IRExpr_Binop(kind, op1, op2);
169}
170
171/* Create a ternary expression */
172static __inline__ IRExpr *
173triop(IROp kind, IRExpr *op1, IRExpr *op2, IRExpr *op3)
174{
175 return IRExpr_Triop(kind, op1, op2, op3);
176}
177
178/* Create a quaternary expression */
179static __inline__ IRExpr *
180qop(IROp kind, IRExpr *op1, IRExpr *op2, IRExpr *op3, IRExpr *op4)
181{
182 return IRExpr_Qop(kind, op1, op2, op3, op4);
183}
184
185/* Create an expression node for an 8-bit integer constant */
186static __inline__ IRExpr *
187mkU8(UInt value)
188{
189 vassert(value < 256);
190
191 return IRExpr_Const(IRConst_U8((UChar)value));
192}
193
194/* Create an expression node for a 16-bit integer constant */
195static __inline__ IRExpr *
196mkU16(UInt value)
197{
198 vassert(value < 65536);
199
200 return IRExpr_Const(IRConst_U16((UShort)value));
201}
202
203/* Create an expression node for a 32-bit integer constant */
204static __inline__ IRExpr *
205mkU32(UInt value)
206{
207 return IRExpr_Const(IRConst_U32(value));
208}
209
210/* Create an expression node for a 64-bit integer constant */
211static __inline__ IRExpr *
212mkU64(ULong value)
213{
214 return IRExpr_Const(IRConst_U64(value));
215}
216
217/* Create an expression node for a 32-bit floating point constant
218 whose value is given by a bit pattern. */
219static __inline__ IRExpr *
220mkF32i(UInt value)
221{
222 return IRExpr_Const(IRConst_F32i(value));
223}
224
225/* Create an expression node for a 32-bit floating point constant
226 whose value is given by a bit pattern. */
227static __inline__ IRExpr *
228mkF64i(ULong value)
229{
230 return IRExpr_Const(IRConst_F64i(value));
231}
232
233/* Little helper function for my sanity. ITE = if-then-else */
234static IRExpr *
235mkite(IRExpr *condition, IRExpr *iftrue, IRExpr *iffalse)
236{
237 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
238
239 return IRExpr_Mux0X(unop(Iop_1Uto8, condition), iffalse, iftrue);
240}
241
242/* Add a statement that stores DATA at ADDR. This is a big-endian machine. */
243static void __inline__
244store(IRExpr *addr, IRExpr *data)
245{
246 stmt(IRStmt_Store(Iend_BE, addr, data));
247}
248
249/* Create an expression that loads a TYPE sized value from ADDR.
250 This is a big-endian machine. */
251static __inline__ IRExpr *
252load(IRType type, IRExpr *addr)
253{
254 return IRExpr_Load(Iend_BE, type, addr);
255}
256
257/* Function call */
258static void
259call_function(IRExpr *callee_address)
260{
florian8844a632012-04-13 04:04:06 +0000261 put_IA(callee_address);
sewardj2019a972011-03-07 16:04:07 +0000262
florian8844a632012-04-13 04:04:06 +0000263 dis_res->whatNext = Dis_StopHere;
264 dis_res->jk_StopHere = Ijk_Call;
sewardj2019a972011-03-07 16:04:07 +0000265}
266
floriana64c2432011-07-16 02:11:50 +0000267/* Function call with known target. */
268static void
269call_function_and_chase(Addr64 callee_address)
270{
271 if (resteer_fn(resteer_data, callee_address)) {
272 dis_res->whatNext = Dis_ResteerU;
273 dis_res->continueAt = callee_address;
274 } else {
florian8844a632012-04-13 04:04:06 +0000275 put_IA(mkaddr_expr(callee_address));
276
floriana64c2432011-07-16 02:11:50 +0000277 dis_res->whatNext = Dis_StopHere;
florian8844a632012-04-13 04:04:06 +0000278 dis_res->jk_StopHere = Ijk_Call;
floriana64c2432011-07-16 02:11:50 +0000279 }
280}
281
sewardj2019a972011-03-07 16:04:07 +0000282/* Function return sequence */
283static void
284return_from_function(IRExpr *return_address)
285{
florian8844a632012-04-13 04:04:06 +0000286 put_IA(return_address);
sewardj2019a972011-03-07 16:04:07 +0000287
florian8844a632012-04-13 04:04:06 +0000288 dis_res->whatNext = Dis_StopHere;
289 dis_res->jk_StopHere = Ijk_Ret;
sewardj2019a972011-03-07 16:04:07 +0000290}
291
292/* A conditional branch whose target is not known at instrumentation time.
293
294 if (condition) goto computed_target;
295
296 Needs to be represented as:
297
298 if (! condition) goto next_instruction;
299 goto computed_target;
sewardj2019a972011-03-07 16:04:07 +0000300*/
301static void
florianf321da72012-07-21 20:32:57 +0000302if_condition_goto_computed(IRExpr *condition, IRExpr *target)
sewardj2019a972011-03-07 16:04:07 +0000303{
304 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
305
florianf321da72012-07-21 20:32:57 +0000306 condition = unop(Iop_Not1, condition);
307
florian8844a632012-04-13 04:04:06 +0000308 stmt(IRStmt_Exit(condition, Ijk_Boring, IRConst_U64(guest_IA_next_instr),
309 S390X_GUEST_OFFSET(guest_IA)));
sewardj2019a972011-03-07 16:04:07 +0000310
florian8844a632012-04-13 04:04:06 +0000311 put_IA(target);
sewardj2019a972011-03-07 16:04:07 +0000312
florian8844a632012-04-13 04:04:06 +0000313 dis_res->whatNext = Dis_StopHere;
314 dis_res->jk_StopHere = Ijk_Boring;
sewardj2019a972011-03-07 16:04:07 +0000315}
316
317/* A conditional branch whose target is known at instrumentation time. */
318static void
319if_condition_goto(IRExpr *condition, Addr64 target)
320{
321 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
322
florian8844a632012-04-13 04:04:06 +0000323 stmt(IRStmt_Exit(condition, Ijk_Boring, IRConst_U64(target),
324 S390X_GUEST_OFFSET(guest_IA)));
325
florian7346c7a2012-04-13 21:14:24 +0000326 put_IA(mkaddr_expr(guest_IA_next_instr));
florian8844a632012-04-13 04:04:06 +0000327
328 dis_res->whatNext = Dis_StopHere;
329 dis_res->jk_StopHere = Ijk_Boring;
sewardj2019a972011-03-07 16:04:07 +0000330}
331
332/* An unconditional branch. Target may or may not be known at instrumentation
333 time. */
334static void
335always_goto(IRExpr *target)
336{
florian8844a632012-04-13 04:04:06 +0000337 put_IA(target);
sewardj2019a972011-03-07 16:04:07 +0000338
florian8844a632012-04-13 04:04:06 +0000339 dis_res->whatNext = Dis_StopHere;
340 dis_res->jk_StopHere = Ijk_Boring;
sewardj2019a972011-03-07 16:04:07 +0000341}
342
florian8844a632012-04-13 04:04:06 +0000343
floriana64c2432011-07-16 02:11:50 +0000344/* An unconditional branch to a known target. */
345static void
346always_goto_and_chase(Addr64 target)
347{
348 if (resteer_fn(resteer_data, target)) {
florian8844a632012-04-13 04:04:06 +0000349 /* Follow into the target */
floriana64c2432011-07-16 02:11:50 +0000350 dis_res->whatNext = Dis_ResteerU;
351 dis_res->continueAt = target;
352 } else {
florian8844a632012-04-13 04:04:06 +0000353 put_IA(mkaddr_expr(target));
354
355 dis_res->whatNext = Dis_StopHere;
356 dis_res->jk_StopHere = Ijk_Boring;
floriana64c2432011-07-16 02:11:50 +0000357 }
358}
359
sewardj2019a972011-03-07 16:04:07 +0000360/* A system call */
361static void
362system_call(IRExpr *sysno)
363{
364 /* Store the system call number in the pseudo register. */
florian428dfdd2012-03-27 03:09:49 +0000365 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_SYSNO), sysno));
sewardj2019a972011-03-07 16:04:07 +0000366
sewardj69007022011-04-28 20:13:45 +0000367 /* Store the current IA into guest_IP_AT_SYSCALL. libvex_ir.h says so. */
florian428dfdd2012-03-27 03:09:49 +0000368 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_IP_AT_SYSCALL),
369 mkU64(guest_IA_curr_instr)));
sewardj2019a972011-03-07 16:04:07 +0000370
florian8844a632012-04-13 04:04:06 +0000371 put_IA(mkaddr_expr(guest_IA_next_instr));
372
sewardj2019a972011-03-07 16:04:07 +0000373 /* It's important that all ArchRegs carry their up-to-date value
374 at this point. So we declare an end-of-block here, which
375 forces any TempRegs caching ArchRegs to be flushed. */
florian8844a632012-04-13 04:04:06 +0000376 dis_res->whatNext = Dis_StopHere;
377 dis_res->jk_StopHere = Ijk_Sys_syscall;
sewardj2019a972011-03-07 16:04:07 +0000378}
379
florian6820ba52012-07-26 02:01:50 +0000380/* A side exit that branches back to the current insn if CONDITION is
381 true. Does not set DisResult. */
382static void
383iterate_if(IRExpr *condition)
384{
385 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
386
387 stmt(IRStmt_Exit(condition, Ijk_Boring, IRConst_U64(guest_IA_curr_instr),
388 S390X_GUEST_OFFSET(guest_IA)));
389}
390
391/* A side exit that branches back to the current insn.
392 Does not set DisResult. */
393static __inline__ void
394iterate(void)
395{
396 iterate_if(IRExpr_Const(IRConst_U1(True)));
397}
398
399/* A side exit that branches back to the insn immediately following the
400 current insn if CONDITION is true. Does not set DisResult. */
401static void
402next_insn_if(IRExpr *condition)
403{
404 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
405
406 stmt(IRStmt_Exit(condition, Ijk_Boring, IRConst_U64(guest_IA_next_instr),
407 S390X_GUEST_OFFSET(guest_IA)));
408}
409
410/* Convenience function to restart the current insn */
411static void
412restart_if(IRExpr *condition)
413{
414 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
415
416 stmt(IRStmt_Exit(condition, Ijk_TInval, IRConst_U64(guest_IA_curr_instr),
417 S390X_GUEST_OFFSET(guest_IA)));
418}
419
420/* Convenience function to yield to thread scheduler */
421static void
422yield_if(IRExpr *condition)
423{
424 stmt(IRStmt_Exit(condition, Ijk_Yield, IRConst_U64(guest_IA_next_instr),
425 S390X_GUEST_OFFSET(guest_IA)));
426}
427
sewardj2019a972011-03-07 16:04:07 +0000428static __inline__ IRExpr *get_fpr_dw0(UInt);
429static __inline__ void put_fpr_dw0(UInt, IRExpr *);
430
431/* Read a floating point register pair and combine their contents into a
432 128-bit value */
433static IRExpr *
434get_fpr_pair(UInt archreg)
435{
436 IRExpr *high = get_fpr_dw0(archreg);
437 IRExpr *low = get_fpr_dw0(archreg + 2);
438
439 return binop(Iop_F64HLtoF128, high, low);
440}
441
442/* Write a 128-bit floating point value into a register pair. */
443static void
444put_fpr_pair(UInt archreg, IRExpr *expr)
445{
446 IRExpr *high = unop(Iop_F128HItoF64, expr);
447 IRExpr *low = unop(Iop_F128LOtoF64, expr);
448
449 put_fpr_dw0(archreg, high);
450 put_fpr_dw0(archreg + 2, low);
451}
452
floriane75dafa2012-09-01 17:54:09 +0000453/* Terminate the current IRSB with an emulation failure. */
454static void
455emulation_failure(VexEmNote fail_kind)
456{
457 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_EMNOTE), mkU32(fail_kind)));
floriane75dafa2012-09-01 17:54:09 +0000458 dis_res->whatNext = Dis_StopHere;
459 dis_res->jk_StopHere = Ijk_EmFail;
460}
sewardj2019a972011-03-07 16:04:07 +0000461
florian4b8efad2012-09-02 18:07:08 +0000462/* Terminate the current IRSB with an emulation warning. */
463static void
464emulation_warning(VexEmNote warn_kind)
465{
466 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_EMNOTE), mkU32(warn_kind)));
467 dis_res->whatNext = Dis_StopHere;
468 dis_res->jk_StopHere = Ijk_EmWarn;
469}
470
sewardj2019a972011-03-07 16:04:07 +0000471/*------------------------------------------------------------*/
florianf3410f92012-08-03 18:41:58 +0000472/*--- IR Debugging aids. ---*/
473/*------------------------------------------------------------*/
474#if 0
475
476static ULong
477s390_do_print(HChar *text, ULong value)
478{
479 vex_printf("%s %llu\n", text, value);
480 return 0;
481}
482
483static void
484s390_print(HChar *text, IRExpr *value)
485{
486 IRDirty *d;
487
488 d = unsafeIRDirty_0_N(0 /* regparms */, "s390_do_print", &s390_do_print,
489 mkIRExprVec_2(mkU64((ULong)text), value));
490 stmt(IRStmt_Dirty(d));
491}
492#endif
493
494
495/*------------------------------------------------------------*/
sewardj2019a972011-03-07 16:04:07 +0000496/*--- Build the flags thunk. ---*/
497/*------------------------------------------------------------*/
498
499/* Completely fill the flags thunk. We're always filling all fields.
500 Apparently, that is better for redundant PUT elimination. */
501static void
502s390_cc_thunk_fill(IRExpr *op, IRExpr *dep1, IRExpr *dep2, IRExpr *ndep)
503{
504 UInt op_off, dep1_off, dep2_off, ndep_off;
505
florian428dfdd2012-03-27 03:09:49 +0000506 op_off = S390X_GUEST_OFFSET(guest_CC_OP);
507 dep1_off = S390X_GUEST_OFFSET(guest_CC_DEP1);
508 dep2_off = S390X_GUEST_OFFSET(guest_CC_DEP2);
509 ndep_off = S390X_GUEST_OFFSET(guest_CC_NDEP);
sewardj2019a972011-03-07 16:04:07 +0000510
511 stmt(IRStmt_Put(op_off, op));
512 stmt(IRStmt_Put(dep1_off, dep1));
513 stmt(IRStmt_Put(dep2_off, dep2));
514 stmt(IRStmt_Put(ndep_off, ndep));
515}
516
517
518/* Create an expression for V and widen the result to 64 bit. */
519static IRExpr *
520s390_cc_widen(IRTemp v, Bool sign_extend)
521{
522 IRExpr *expr;
523
524 expr = mkexpr(v);
525
526 switch (typeOfIRTemp(irsb->tyenv, v)) {
527 case Ity_I64:
528 break;
529 case Ity_I32:
530 expr = unop(sign_extend ? Iop_32Sto64 : Iop_32Uto64, expr);
531 break;
532 case Ity_I16:
533 expr = unop(sign_extend ? Iop_16Sto64 : Iop_16Uto64, expr);
534 break;
535 case Ity_I8:
536 expr = unop(sign_extend ? Iop_8Sto64 : Iop_8Uto64, expr);
537 break;
538 default:
539 vpanic("s390_cc_widen");
540 }
541
542 return expr;
543}
544
545static void
546s390_cc_thunk_put1(UInt opc, IRTemp d1, Bool sign_extend)
547{
548 IRExpr *op, *dep1, *dep2, *ndep;
549
550 op = mkU64(opc);
551 dep1 = s390_cc_widen(d1, sign_extend);
552 dep2 = mkU64(0);
553 ndep = mkU64(0);
554
555 s390_cc_thunk_fill(op, dep1, dep2, ndep);
556}
557
558
559static void
560s390_cc_thunk_put2(UInt opc, IRTemp d1, IRTemp d2, Bool sign_extend)
561{
562 IRExpr *op, *dep1, *dep2, *ndep;
563
564 op = mkU64(opc);
565 dep1 = s390_cc_widen(d1, sign_extend);
566 dep2 = s390_cc_widen(d2, sign_extend);
567 ndep = mkU64(0);
568
569 s390_cc_thunk_fill(op, dep1, dep2, ndep);
570}
571
572
573/* memcheck believes that the NDEP field in the flags thunk is always
574 defined. But for some flag computations (e.g. add with carry) that is
575 just not true. We therefore need to convey to memcheck that the value
576 of the ndep field does matter and therefore we make the DEP2 field
577 depend on it:
578
579 DEP2 = original_DEP2 ^ NDEP
580
581 In s390_calculate_cc we exploit that (a^b)^b == a
582 I.e. we xor the DEP2 value with the NDEP value to recover the
583 original_DEP2 value. */
584static void
585s390_cc_thunk_put3(UInt opc, IRTemp d1, IRTemp d2, IRTemp nd, Bool sign_extend)
586{
587 IRExpr *op, *dep1, *dep2, *ndep, *dep2x;
588
589 op = mkU64(opc);
590 dep1 = s390_cc_widen(d1, sign_extend);
591 dep2 = s390_cc_widen(d2, sign_extend);
592 ndep = s390_cc_widen(nd, sign_extend);
593
594 dep2x = binop(Iop_Xor64, dep2, ndep);
595
596 s390_cc_thunk_fill(op, dep1, dep2x, ndep);
597}
598
599
600/* Write one floating point value into the flags thunk */
601static void
602s390_cc_thunk_put1f(UInt opc, IRTemp d1)
603{
604 IRExpr *op, *dep1, *dep2, *ndep;
605
606 op = mkU64(opc);
607 dep1 = mkexpr(d1);
608 dep2 = mkU64(0);
609 ndep = mkU64(0);
610
611 s390_cc_thunk_fill(op, dep1, dep2, ndep);
612}
613
614
615/* Write a floating point value and an integer into the flags thunk. The
616 integer value is zero-extended first. */
617static void
618s390_cc_thunk_putFZ(UInt opc, IRTemp d1, IRTemp d2)
619{
620 IRExpr *op, *dep1, *dep2, *ndep;
621
622 op = mkU64(opc);
623 dep1 = mkexpr(d1);
624 dep2 = s390_cc_widen(d2, False);
625 ndep = mkU64(0);
626
627 s390_cc_thunk_fill(op, dep1, dep2, ndep);
628}
629
630
631/* Write a 128-bit floating point value into the flags thunk. This is
632 done by splitting the value into two 64-bits values. */
633static void
634s390_cc_thunk_put1f128(UInt opc, IRTemp d1)
635{
636 IRExpr *op, *hi, *lo, *ndep;
637
638 op = mkU64(opc);
639 hi = unop(Iop_F128HItoF64, mkexpr(d1));
640 lo = unop(Iop_F128LOtoF64, mkexpr(d1));
641 ndep = mkU64(0);
642
643 s390_cc_thunk_fill(op, hi, lo, ndep);
644}
645
646
647/* Write a 128-bit floating point value and an integer into the flags thunk.
648 The integer value is zero-extended first. */
649static void
650s390_cc_thunk_put1f128Z(UInt opc, IRTemp d1, IRTemp nd)
651{
652 IRExpr *op, *hi, *lo, *lox, *ndep;
653
654 op = mkU64(opc);
655 hi = unop(Iop_F128HItoF64, mkexpr(d1));
656 lo = unop(Iop_ReinterpF64asI64, unop(Iop_F128LOtoF64, mkexpr(d1)));
657 ndep = s390_cc_widen(nd, False);
658
659 lox = binop(Iop_Xor64, lo, ndep); /* convey dependency */
660
661 s390_cc_thunk_fill(op, hi, lox, ndep);
662}
663
664
665static void
666s390_cc_set(UInt val)
667{
668 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
669 mkU64(val), mkU64(0), mkU64(0));
670}
671
672/* Build IR to calculate the condition code from flags thunk.
673 Returns an expression of type Ity_I32 */
674static IRExpr *
675s390_call_calculate_cc(void)
676{
677 IRExpr **args, *call, *op, *dep1, *dep2, *ndep;
678
florian428dfdd2012-03-27 03:09:49 +0000679 op = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_OP), Ity_I64);
680 dep1 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP1), Ity_I64);
681 dep2 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP2), Ity_I64);
682 ndep = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_NDEP), Ity_I64);
sewardj2019a972011-03-07 16:04:07 +0000683
684 args = mkIRExprVec_4(op, dep1, dep2, ndep);
685 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
686 "s390_calculate_cc", &s390_calculate_cc, args);
687
688 /* Exclude OP and NDEP from definedness checking. We're only
689 interested in DEP1 and DEP2. */
690 call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<3);
691
692 return call;
693}
694
695/* Build IR to calculate the internal condition code for a "compare and branch"
696 insn. Returns an expression of type Ity_I32 */
697static IRExpr *
florianff9613f2012-05-12 15:26:44 +0000698s390_call_calculate_icc(UInt m, UInt opc, IRTemp op1, IRTemp op2)
sewardj2019a972011-03-07 16:04:07 +0000699{
florianff9613f2012-05-12 15:26:44 +0000700 IRExpr **args, *call, *op, *dep1, *dep2, *mask;
sewardj2019a972011-03-07 16:04:07 +0000701
florianff9613f2012-05-12 15:26:44 +0000702 switch (opc) {
703 case S390_CC_OP_SIGNED_COMPARE:
704 dep1 = s390_cc_widen(op1, True);
705 dep2 = s390_cc_widen(op2, True);
706 break;
707
708 case S390_CC_OP_UNSIGNED_COMPARE:
709 dep1 = s390_cc_widen(op1, False);
710 dep2 = s390_cc_widen(op2, False);
711 break;
712
713 default:
714 vpanic("s390_call_calculate_icc");
715 }
716
717 mask = mkU64(m);
sewardj2019a972011-03-07 16:04:07 +0000718 op = mkU64(opc);
sewardj2019a972011-03-07 16:04:07 +0000719
florianff9613f2012-05-12 15:26:44 +0000720 args = mkIRExprVec_5(mask, op, dep1, dep2, mkU64(0) /* unused */);
sewardj2019a972011-03-07 16:04:07 +0000721 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
florianff9613f2012-05-12 15:26:44 +0000722 "s390_calculate_cond", &s390_calculate_cond, args);
sewardj2019a972011-03-07 16:04:07 +0000723
florianff9613f2012-05-12 15:26:44 +0000724 /* Exclude the requested condition, OP and NDEP from definedness
725 checking. We're only interested in DEP1 and DEP2. */
726 call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<1) | (1<<4);
sewardj2019a972011-03-07 16:04:07 +0000727
728 return call;
729}
730
731/* Build IR to calculate the condition code from flags thunk.
732 Returns an expression of type Ity_I32 */
733static IRExpr *
734s390_call_calculate_cond(UInt m)
735{
736 IRExpr **args, *call, *op, *dep1, *dep2, *ndep, *mask;
737
738 mask = mkU64(m);
florian428dfdd2012-03-27 03:09:49 +0000739 op = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_OP), Ity_I64);
740 dep1 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP1), Ity_I64);
741 dep2 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP2), Ity_I64);
742 ndep = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_NDEP), Ity_I64);
sewardj2019a972011-03-07 16:04:07 +0000743
744 args = mkIRExprVec_5(mask, op, dep1, dep2, ndep);
745 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
746 "s390_calculate_cond", &s390_calculate_cond, args);
747
748 /* Exclude the requested condition, OP and NDEP from definedness
749 checking. We're only interested in DEP1 and DEP2. */
750 call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<1) | (1<<4);
751
752 return call;
753}
754
755#define s390_cc_thunk_putZ(op,dep1) s390_cc_thunk_put1(op,dep1,False)
756#define s390_cc_thunk_putS(op,dep1) s390_cc_thunk_put1(op,dep1,True)
757#define s390_cc_thunk_putF(op,dep1) s390_cc_thunk_put1f(op,dep1)
758#define s390_cc_thunk_putZZ(op,dep1,dep2) s390_cc_thunk_put2(op,dep1,dep2,False)
759#define s390_cc_thunk_putSS(op,dep1,dep2) s390_cc_thunk_put2(op,dep1,dep2,True)
760#define s390_cc_thunk_putFF(op,dep1,dep2) s390_cc_thunk_put2f(op,dep1,dep2)
761#define s390_cc_thunk_putZZZ(op,dep1,dep2,ndep) \
762 s390_cc_thunk_put3(op,dep1,dep2,ndep,False)
763#define s390_cc_thunk_putSSS(op,dep1,dep2,ndep) \
764 s390_cc_thunk_put3(op,dep1,dep2,ndep,True)
sewardj2019a972011-03-07 16:04:07 +0000765
766
sewardj2019a972011-03-07 16:04:07 +0000767
768
769/*------------------------------------------------------------*/
770/*--- Guest register access ---*/
771/*------------------------------------------------------------*/
772
773
774/*------------------------------------------------------------*/
775/*--- ar registers ---*/
776/*------------------------------------------------------------*/
777
778/* Return the guest state offset of a ar register. */
779static UInt
780ar_offset(UInt archreg)
781{
782 static const UInt offset[16] = {
floriane88b3c92011-07-05 02:48:39 +0000783 S390X_GUEST_OFFSET(guest_a0),
784 S390X_GUEST_OFFSET(guest_a1),
785 S390X_GUEST_OFFSET(guest_a2),
786 S390X_GUEST_OFFSET(guest_a3),
787 S390X_GUEST_OFFSET(guest_a4),
788 S390X_GUEST_OFFSET(guest_a5),
789 S390X_GUEST_OFFSET(guest_a6),
790 S390X_GUEST_OFFSET(guest_a7),
791 S390X_GUEST_OFFSET(guest_a8),
792 S390X_GUEST_OFFSET(guest_a9),
793 S390X_GUEST_OFFSET(guest_a10),
794 S390X_GUEST_OFFSET(guest_a11),
795 S390X_GUEST_OFFSET(guest_a12),
796 S390X_GUEST_OFFSET(guest_a13),
797 S390X_GUEST_OFFSET(guest_a14),
798 S390X_GUEST_OFFSET(guest_a15),
sewardj2019a972011-03-07 16:04:07 +0000799 };
800
801 vassert(archreg < 16);
802
803 return offset[archreg];
804}
805
806
807/* Return the guest state offset of word #0 of a ar register. */
808static __inline__ UInt
809ar_w0_offset(UInt archreg)
810{
811 return ar_offset(archreg) + 0;
812}
813
814/* Write word #0 of a ar to the guest state. */
815static __inline__ void
816put_ar_w0(UInt archreg, IRExpr *expr)
817{
818 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
819
820 stmt(IRStmt_Put(ar_w0_offset(archreg), expr));
821}
822
823/* Read word #0 of a ar register. */
824static __inline__ IRExpr *
825get_ar_w0(UInt archreg)
826{
827 return IRExpr_Get(ar_w0_offset(archreg), Ity_I32);
828}
829
830
831/*------------------------------------------------------------*/
832/*--- fpr registers ---*/
833/*------------------------------------------------------------*/
834
835/* Return the guest state offset of a fpr register. */
836static UInt
837fpr_offset(UInt archreg)
838{
839 static const UInt offset[16] = {
floriane88b3c92011-07-05 02:48:39 +0000840 S390X_GUEST_OFFSET(guest_f0),
841 S390X_GUEST_OFFSET(guest_f1),
842 S390X_GUEST_OFFSET(guest_f2),
843 S390X_GUEST_OFFSET(guest_f3),
844 S390X_GUEST_OFFSET(guest_f4),
845 S390X_GUEST_OFFSET(guest_f5),
846 S390X_GUEST_OFFSET(guest_f6),
847 S390X_GUEST_OFFSET(guest_f7),
848 S390X_GUEST_OFFSET(guest_f8),
849 S390X_GUEST_OFFSET(guest_f9),
850 S390X_GUEST_OFFSET(guest_f10),
851 S390X_GUEST_OFFSET(guest_f11),
852 S390X_GUEST_OFFSET(guest_f12),
853 S390X_GUEST_OFFSET(guest_f13),
854 S390X_GUEST_OFFSET(guest_f14),
855 S390X_GUEST_OFFSET(guest_f15),
sewardj2019a972011-03-07 16:04:07 +0000856 };
857
858 vassert(archreg < 16);
859
860 return offset[archreg];
861}
862
863
864/* Return the guest state offset of word #0 of a fpr register. */
865static __inline__ UInt
866fpr_w0_offset(UInt archreg)
867{
868 return fpr_offset(archreg) + 0;
869}
870
871/* Write word #0 of a fpr to the guest state. */
872static __inline__ void
873put_fpr_w0(UInt archreg, IRExpr *expr)
874{
875 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_F32);
876
877 stmt(IRStmt_Put(fpr_w0_offset(archreg), expr));
878}
879
880/* Read word #0 of a fpr register. */
881static __inline__ IRExpr *
882get_fpr_w0(UInt archreg)
883{
884 return IRExpr_Get(fpr_w0_offset(archreg), Ity_F32);
885}
886
887/* Return the guest state offset of double word #0 of a fpr register. */
888static __inline__ UInt
889fpr_dw0_offset(UInt archreg)
890{
891 return fpr_offset(archreg) + 0;
892}
893
894/* Write double word #0 of a fpr to the guest state. */
895static __inline__ void
896put_fpr_dw0(UInt archreg, IRExpr *expr)
897{
898 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_F64);
899
900 stmt(IRStmt_Put(fpr_dw0_offset(archreg), expr));
901}
902
903/* Read double word #0 of a fpr register. */
904static __inline__ IRExpr *
905get_fpr_dw0(UInt archreg)
906{
907 return IRExpr_Get(fpr_dw0_offset(archreg), Ity_F64);
908}
909
910
911/*------------------------------------------------------------*/
912/*--- gpr registers ---*/
913/*------------------------------------------------------------*/
914
915/* Return the guest state offset of a gpr register. */
916static UInt
917gpr_offset(UInt archreg)
918{
919 static const UInt offset[16] = {
floriane88b3c92011-07-05 02:48:39 +0000920 S390X_GUEST_OFFSET(guest_r0),
921 S390X_GUEST_OFFSET(guest_r1),
922 S390X_GUEST_OFFSET(guest_r2),
923 S390X_GUEST_OFFSET(guest_r3),
924 S390X_GUEST_OFFSET(guest_r4),
925 S390X_GUEST_OFFSET(guest_r5),
926 S390X_GUEST_OFFSET(guest_r6),
927 S390X_GUEST_OFFSET(guest_r7),
928 S390X_GUEST_OFFSET(guest_r8),
929 S390X_GUEST_OFFSET(guest_r9),
930 S390X_GUEST_OFFSET(guest_r10),
931 S390X_GUEST_OFFSET(guest_r11),
932 S390X_GUEST_OFFSET(guest_r12),
933 S390X_GUEST_OFFSET(guest_r13),
934 S390X_GUEST_OFFSET(guest_r14),
935 S390X_GUEST_OFFSET(guest_r15),
sewardj2019a972011-03-07 16:04:07 +0000936 };
937
938 vassert(archreg < 16);
939
940 return offset[archreg];
941}
942
943
944/* Return the guest state offset of word #0 of a gpr register. */
945static __inline__ UInt
946gpr_w0_offset(UInt archreg)
947{
948 return gpr_offset(archreg) + 0;
949}
950
951/* Write word #0 of a gpr to the guest state. */
952static __inline__ void
953put_gpr_w0(UInt archreg, IRExpr *expr)
954{
955 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
956
957 stmt(IRStmt_Put(gpr_w0_offset(archreg), expr));
958}
959
960/* Read word #0 of a gpr register. */
961static __inline__ IRExpr *
962get_gpr_w0(UInt archreg)
963{
964 return IRExpr_Get(gpr_w0_offset(archreg), Ity_I32);
965}
966
967/* Return the guest state offset of double word #0 of a gpr register. */
968static __inline__ UInt
969gpr_dw0_offset(UInt archreg)
970{
971 return gpr_offset(archreg) + 0;
972}
973
974/* Write double word #0 of a gpr to the guest state. */
975static __inline__ void
976put_gpr_dw0(UInt archreg, IRExpr *expr)
977{
978 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I64);
979
980 stmt(IRStmt_Put(gpr_dw0_offset(archreg), expr));
981}
982
983/* Read double word #0 of a gpr register. */
984static __inline__ IRExpr *
985get_gpr_dw0(UInt archreg)
986{
987 return IRExpr_Get(gpr_dw0_offset(archreg), Ity_I64);
988}
989
990/* Return the guest state offset of half word #1 of a gpr register. */
991static __inline__ UInt
992gpr_hw1_offset(UInt archreg)
993{
994 return gpr_offset(archreg) + 2;
995}
996
997/* Write half word #1 of a gpr to the guest state. */
998static __inline__ void
999put_gpr_hw1(UInt archreg, IRExpr *expr)
1000{
1001 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1002
1003 stmt(IRStmt_Put(gpr_hw1_offset(archreg), expr));
1004}
1005
1006/* Read half word #1 of a gpr register. */
1007static __inline__ IRExpr *
1008get_gpr_hw1(UInt archreg)
1009{
1010 return IRExpr_Get(gpr_hw1_offset(archreg), Ity_I16);
1011}
1012
1013/* Return the guest state offset of byte #6 of a gpr register. */
1014static __inline__ UInt
1015gpr_b6_offset(UInt archreg)
1016{
1017 return gpr_offset(archreg) + 6;
1018}
1019
1020/* Write byte #6 of a gpr to the guest state. */
1021static __inline__ void
1022put_gpr_b6(UInt archreg, IRExpr *expr)
1023{
1024 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1025
1026 stmt(IRStmt_Put(gpr_b6_offset(archreg), expr));
1027}
1028
1029/* Read byte #6 of a gpr register. */
1030static __inline__ IRExpr *
1031get_gpr_b6(UInt archreg)
1032{
1033 return IRExpr_Get(gpr_b6_offset(archreg), Ity_I8);
1034}
1035
1036/* Return the guest state offset of byte #3 of a gpr register. */
1037static __inline__ UInt
1038gpr_b3_offset(UInt archreg)
1039{
1040 return gpr_offset(archreg) + 3;
1041}
1042
1043/* Write byte #3 of a gpr to the guest state. */
1044static __inline__ void
1045put_gpr_b3(UInt archreg, IRExpr *expr)
1046{
1047 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1048
1049 stmt(IRStmt_Put(gpr_b3_offset(archreg), expr));
1050}
1051
1052/* Read byte #3 of a gpr register. */
1053static __inline__ IRExpr *
1054get_gpr_b3(UInt archreg)
1055{
1056 return IRExpr_Get(gpr_b3_offset(archreg), Ity_I8);
1057}
1058
1059/* Return the guest state offset of byte #0 of a gpr register. */
1060static __inline__ UInt
1061gpr_b0_offset(UInt archreg)
1062{
1063 return gpr_offset(archreg) + 0;
1064}
1065
1066/* Write byte #0 of a gpr to the guest state. */
1067static __inline__ void
1068put_gpr_b0(UInt archreg, IRExpr *expr)
1069{
1070 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1071
1072 stmt(IRStmt_Put(gpr_b0_offset(archreg), expr));
1073}
1074
1075/* Read byte #0 of a gpr register. */
1076static __inline__ IRExpr *
1077get_gpr_b0(UInt archreg)
1078{
1079 return IRExpr_Get(gpr_b0_offset(archreg), Ity_I8);
1080}
1081
1082/* Return the guest state offset of word #1 of a gpr register. */
1083static __inline__ UInt
1084gpr_w1_offset(UInt archreg)
1085{
1086 return gpr_offset(archreg) + 4;
1087}
1088
1089/* Write word #1 of a gpr to the guest state. */
1090static __inline__ void
1091put_gpr_w1(UInt archreg, IRExpr *expr)
1092{
1093 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1094
1095 stmt(IRStmt_Put(gpr_w1_offset(archreg), expr));
1096}
1097
1098/* Read word #1 of a gpr register. */
1099static __inline__ IRExpr *
1100get_gpr_w1(UInt archreg)
1101{
1102 return IRExpr_Get(gpr_w1_offset(archreg), Ity_I32);
1103}
1104
1105/* Return the guest state offset of half word #3 of a gpr register. */
1106static __inline__ UInt
1107gpr_hw3_offset(UInt archreg)
1108{
1109 return gpr_offset(archreg) + 6;
1110}
1111
1112/* Write half word #3 of a gpr to the guest state. */
1113static __inline__ void
1114put_gpr_hw3(UInt archreg, IRExpr *expr)
1115{
1116 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1117
1118 stmt(IRStmt_Put(gpr_hw3_offset(archreg), expr));
1119}
1120
1121/* Read half word #3 of a gpr register. */
1122static __inline__ IRExpr *
1123get_gpr_hw3(UInt archreg)
1124{
1125 return IRExpr_Get(gpr_hw3_offset(archreg), Ity_I16);
1126}
1127
1128/* Return the guest state offset of byte #7 of a gpr register. */
1129static __inline__ UInt
1130gpr_b7_offset(UInt archreg)
1131{
1132 return gpr_offset(archreg) + 7;
1133}
1134
1135/* Write byte #7 of a gpr to the guest state. */
1136static __inline__ void
1137put_gpr_b7(UInt archreg, IRExpr *expr)
1138{
1139 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1140
1141 stmt(IRStmt_Put(gpr_b7_offset(archreg), expr));
1142}
1143
1144/* Read byte #7 of a gpr register. */
1145static __inline__ IRExpr *
1146get_gpr_b7(UInt archreg)
1147{
1148 return IRExpr_Get(gpr_b7_offset(archreg), Ity_I8);
1149}
1150
1151/* Return the guest state offset of half word #0 of a gpr register. */
1152static __inline__ UInt
1153gpr_hw0_offset(UInt archreg)
1154{
1155 return gpr_offset(archreg) + 0;
1156}
1157
1158/* Write half word #0 of a gpr to the guest state. */
1159static __inline__ void
1160put_gpr_hw0(UInt archreg, IRExpr *expr)
1161{
1162 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1163
1164 stmt(IRStmt_Put(gpr_hw0_offset(archreg), expr));
1165}
1166
1167/* Read half word #0 of a gpr register. */
1168static __inline__ IRExpr *
1169get_gpr_hw0(UInt archreg)
1170{
1171 return IRExpr_Get(gpr_hw0_offset(archreg), Ity_I16);
1172}
1173
1174/* Return the guest state offset of byte #4 of a gpr register. */
1175static __inline__ UInt
1176gpr_b4_offset(UInt archreg)
1177{
1178 return gpr_offset(archreg) + 4;
1179}
1180
1181/* Write byte #4 of a gpr to the guest state. */
1182static __inline__ void
1183put_gpr_b4(UInt archreg, IRExpr *expr)
1184{
1185 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1186
1187 stmt(IRStmt_Put(gpr_b4_offset(archreg), expr));
1188}
1189
1190/* Read byte #4 of a gpr register. */
1191static __inline__ IRExpr *
1192get_gpr_b4(UInt archreg)
1193{
1194 return IRExpr_Get(gpr_b4_offset(archreg), Ity_I8);
1195}
1196
1197/* Return the guest state offset of byte #1 of a gpr register. */
1198static __inline__ UInt
1199gpr_b1_offset(UInt archreg)
1200{
1201 return gpr_offset(archreg) + 1;
1202}
1203
1204/* Write byte #1 of a gpr to the guest state. */
1205static __inline__ void
1206put_gpr_b1(UInt archreg, IRExpr *expr)
1207{
1208 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1209
1210 stmt(IRStmt_Put(gpr_b1_offset(archreg), expr));
1211}
1212
1213/* Read byte #1 of a gpr register. */
1214static __inline__ IRExpr *
1215get_gpr_b1(UInt archreg)
1216{
1217 return IRExpr_Get(gpr_b1_offset(archreg), Ity_I8);
1218}
1219
1220/* Return the guest state offset of half word #2 of a gpr register. */
1221static __inline__ UInt
1222gpr_hw2_offset(UInt archreg)
1223{
1224 return gpr_offset(archreg) + 4;
1225}
1226
1227/* Write half word #2 of a gpr to the guest state. */
1228static __inline__ void
1229put_gpr_hw2(UInt archreg, IRExpr *expr)
1230{
1231 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1232
1233 stmt(IRStmt_Put(gpr_hw2_offset(archreg), expr));
1234}
1235
1236/* Read half word #2 of a gpr register. */
1237static __inline__ IRExpr *
1238get_gpr_hw2(UInt archreg)
1239{
1240 return IRExpr_Get(gpr_hw2_offset(archreg), Ity_I16);
1241}
1242
1243/* Return the guest state offset of byte #5 of a gpr register. */
1244static __inline__ UInt
1245gpr_b5_offset(UInt archreg)
1246{
1247 return gpr_offset(archreg) + 5;
1248}
1249
1250/* Write byte #5 of a gpr to the guest state. */
1251static __inline__ void
1252put_gpr_b5(UInt archreg, IRExpr *expr)
1253{
1254 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1255
1256 stmt(IRStmt_Put(gpr_b5_offset(archreg), expr));
1257}
1258
1259/* Read byte #5 of a gpr register. */
1260static __inline__ IRExpr *
1261get_gpr_b5(UInt archreg)
1262{
1263 return IRExpr_Get(gpr_b5_offset(archreg), Ity_I8);
1264}
1265
1266/* Return the guest state offset of byte #2 of a gpr register. */
1267static __inline__ UInt
1268gpr_b2_offset(UInt archreg)
1269{
1270 return gpr_offset(archreg) + 2;
1271}
1272
1273/* Write byte #2 of a gpr to the guest state. */
1274static __inline__ void
1275put_gpr_b2(UInt archreg, IRExpr *expr)
1276{
1277 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1278
1279 stmt(IRStmt_Put(gpr_b2_offset(archreg), expr));
1280}
1281
1282/* Read byte #2 of a gpr register. */
1283static __inline__ IRExpr *
1284get_gpr_b2(UInt archreg)
1285{
1286 return IRExpr_Get(gpr_b2_offset(archreg), Ity_I8);
1287}
1288
1289/* Return the guest state offset of the counter register. */
1290static UInt
1291counter_offset(void)
1292{
floriane88b3c92011-07-05 02:48:39 +00001293 return S390X_GUEST_OFFSET(guest_counter);
sewardj2019a972011-03-07 16:04:07 +00001294}
1295
1296/* Return the guest state offset of double word #0 of the counter register. */
1297static __inline__ UInt
1298counter_dw0_offset(void)
1299{
1300 return counter_offset() + 0;
1301}
1302
1303/* Write double word #0 of the counter to the guest state. */
1304static __inline__ void
1305put_counter_dw0(IRExpr *expr)
1306{
1307 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I64);
1308
1309 stmt(IRStmt_Put(counter_dw0_offset(), expr));
1310}
1311
1312/* Read double word #0 of the counter register. */
1313static __inline__ IRExpr *
1314get_counter_dw0(void)
1315{
1316 return IRExpr_Get(counter_dw0_offset(), Ity_I64);
1317}
1318
1319/* Return the guest state offset of word #0 of the counter register. */
1320static __inline__ UInt
1321counter_w0_offset(void)
1322{
1323 return counter_offset() + 0;
1324}
1325
1326/* Return the guest state offset of word #1 of the counter register. */
1327static __inline__ UInt
1328counter_w1_offset(void)
1329{
1330 return counter_offset() + 4;
1331}
1332
1333/* Write word #0 of the counter to the guest state. */
1334static __inline__ void
1335put_counter_w0(IRExpr *expr)
1336{
1337 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1338
1339 stmt(IRStmt_Put(counter_w0_offset(), expr));
1340}
1341
1342/* Read word #0 of the counter register. */
1343static __inline__ IRExpr *
1344get_counter_w0(void)
1345{
1346 return IRExpr_Get(counter_w0_offset(), Ity_I32);
1347}
1348
1349/* Write word #1 of the counter to the guest state. */
1350static __inline__ void
1351put_counter_w1(IRExpr *expr)
1352{
1353 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1354
1355 stmt(IRStmt_Put(counter_w1_offset(), expr));
1356}
1357
1358/* Read word #1 of the counter register. */
1359static __inline__ IRExpr *
1360get_counter_w1(void)
1361{
1362 return IRExpr_Get(counter_w1_offset(), Ity_I32);
1363}
1364
1365/* Return the guest state offset of the fpc register. */
1366static UInt
1367fpc_offset(void)
1368{
floriane88b3c92011-07-05 02:48:39 +00001369 return S390X_GUEST_OFFSET(guest_fpc);
sewardj2019a972011-03-07 16:04:07 +00001370}
1371
1372/* Return the guest state offset of word #0 of the fpc register. */
1373static __inline__ UInt
1374fpc_w0_offset(void)
1375{
1376 return fpc_offset() + 0;
1377}
1378
1379/* Write word #0 of the fpc to the guest state. */
1380static __inline__ void
1381put_fpc_w0(IRExpr *expr)
1382{
1383 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1384
1385 stmt(IRStmt_Put(fpc_w0_offset(), expr));
1386}
1387
1388/* Read word #0 of the fpc register. */
1389static __inline__ IRExpr *
1390get_fpc_w0(void)
1391{
1392 return IRExpr_Get(fpc_w0_offset(), Ity_I32);
1393}
1394
1395
1396/*------------------------------------------------------------*/
florian2c74d242012-09-12 19:38:42 +00001397/*--- Rounding modes ---*/
1398/*------------------------------------------------------------*/
1399
florian125e20d2012-10-07 15:42:37 +00001400/* Extract the bfp rounding mode from the guest FPC reg and encode it as an
florian2c74d242012-09-12 19:38:42 +00001401 IRRoundingMode:
1402
1403 rounding mode | s390 | IR
1404 -------------------------
1405 to nearest | 00 | 00
1406 to zero | 01 | 11
1407 to +infinity | 10 | 10
1408 to -infinity | 11 | 01
1409
1410 So: IR = (4 - s390) & 3
1411*/
1412static IRExpr *
florian125e20d2012-10-07 15:42:37 +00001413get_bfp_rounding_mode_from_fpc(void)
florian2c74d242012-09-12 19:38:42 +00001414{
1415 IRTemp fpc_bits = newTemp(Ity_I32);
1416
1417 /* For z196 and later the bfp rounding mode is stored in bits [29:31].
1418 Prior to that bits [30:31] contained the bfp rounding mode with
1419 bit 29 being unused and having a value of 0. So we can always
1420 extract the least significant 3 bits. */
1421 assign(fpc_bits, binop(Iop_And32, get_fpc_w0(), mkU32(7)));
1422
1423 /* fixs390:
1424
1425
1426 if (! s390_host_has_fpext && rounding_mode > 3) {
1427 emulation warning @ runtime and
1428 set fpc to round nearest
1429 }
1430 */
1431
1432 /* For now silently adjust an unsupported rounding mode to "nearest" */
1433 IRExpr *rm_s390 = mkite(binop(Iop_CmpLE32S, mkexpr(fpc_bits), mkU32(3)),
1434 mkexpr(fpc_bits),
florian125e20d2012-10-07 15:42:37 +00001435 mkU32(S390_FPC_BFP_ROUND_NEAREST_EVEN));
florian2c74d242012-09-12 19:38:42 +00001436
1437 // rm_IR = (4 - rm_s390) & 3;
1438 return binop(Iop_And32, binop(Iop_Sub32, mkU32(4), rm_s390), mkU32(3));
1439}
1440
1441/* Encode the s390 rounding mode as it appears in the m3 field of certain
1442 instructions to VEX's IRRoundingMode. Rounding modes that cannot be
1443 represented in VEX are converted to Irrm_NEAREST. The rationale is, that
1444 Irrm_NEAREST refers to IEEE 754's roundTiesToEven which the standard
1445 considers the default rounding mode (4.3.3). */
1446static IRTemp
1447encode_bfp_rounding_mode(UChar mode)
1448{
1449 IRExpr *rm;
1450
1451 switch (mode) {
florian125e20d2012-10-07 15:42:37 +00001452 case S390_BFP_ROUND_PER_FPC:
1453 rm = get_bfp_rounding_mode_from_fpc();
1454 break;
1455 case S390_BFP_ROUND_NEAREST_AWAY: /* not supported */
1456 case S390_BFP_ROUND_PREPARE_SHORT: /* not supported */
1457 case S390_BFP_ROUND_NEAREST_EVEN: rm = mkU32(Irrm_NEAREST); break;
1458 case S390_BFP_ROUND_ZERO: rm = mkU32(Irrm_ZERO); break;
1459 case S390_BFP_ROUND_POSINF: rm = mkU32(Irrm_PosINF); break;
1460 case S390_BFP_ROUND_NEGINF: rm = mkU32(Irrm_NegINF); break;
florian2c74d242012-09-12 19:38:42 +00001461 default:
1462 vpanic("encode_bfp_rounding_mode");
1463 }
1464
1465 return mktemp(Ity_I32, rm);
1466}
1467
florianc8e4f562012-10-27 16:19:31 +00001468/* Extract the DFP rounding mode from the guest FPC reg and encode it as an
1469 IRRoundingMode:
1470
1471 rounding mode | s390 | IR
1472 ------------------------------------------------
1473 to nearest, ties to even | 000 | 000
1474 to zero | 001 | 011
1475 to +infinity | 010 | 010
1476 to -infinity | 011 | 001
1477 to nearest, ties away from 0 | 100 | 100
1478 to nearest, ties toward 0 | 101 | 111
1479 to away from 0 | 110 | 110
1480 to prepare for shorter precision | 111 | 101
1481
1482 So: IR = (s390 ^ ((s390 << 1) & 2))
1483*/
1484#if 0 // fixs390: avoid compiler warnings about unused function
1485static IRExpr *
1486get_dfp_rounding_mode_from_fpc(void)
1487{
1488 IRTemp fpc_bits = newTemp(Ity_I32);
1489
1490 /* The dfp rounding mode is stored in bits [25:27].
1491 extract the bits at 25:27 and right shift 4 times. */
1492 assign(fpc_bits, binop(Iop_Shr32,
1493 binop(Iop_And32, get_fpc_w0(), mkU32(0x70)),
1494 mkU8(4)));
1495
1496 IRExpr *rm_s390 = mkexpr(fpc_bits);
1497 // rm_IR = (rm_s390 ^ ((rm_s390 << 1) & 2));
1498
1499 return binop(Iop_Xor32, rm_s390,
1500 binop( Iop_And32,
1501 binop(Iop_Shl32, rm_s390, mkU8(1)),
1502 mkU32(2)));
1503}
1504
1505/* Encode the s390 rounding mode as it appears in the m3 field of certain
1506 instructions to VEX's IRRoundingMode. */
1507static IRTemp
1508encode_dfp_rounding_mode(UChar mode)
1509{
1510 IRExpr *rm;
1511
1512 switch (mode) {
1513 case S390_DFP_ROUND_PER_FPC_0:
1514 case S390_DFP_ROUND_PER_FPC_2:
1515 rm = get_dfp_rounding_mode_from_fpc(); break;
1516 case S390_DFP_ROUND_NEAREST_EVEN_4:
1517 case S390_DFP_ROUND_NEAREST_EVEN_8:
1518 rm = mkU32(Irrm_DFP_NEAREST); break;
1519 case S390_DFP_ROUND_NEAREST_TIE_AWAY_0_1:
1520 case S390_DFP_ROUND_NEAREST_TIE_AWAY_0_12:
1521 rm = mkU32(Irrm_DFP_NEAREST_TIE_AWAY_0); break;
1522 case S390_DFP_ROUND_PREPARE_SHORT_3:
1523 case S390_DFP_ROUND_PREPARE_SHORT_15:
1524 rm = mkU32(Irrm_DFP_PREPARE_SHORTER); break;
1525 case S390_DFP_ROUND_ZERO_5:
1526 case S390_DFP_ROUND_ZERO_9:
1527 rm = mkU32(Irrm_DFP_ZERO ); break;
1528 case S390_DFP_ROUND_POSINF_6:
1529 case S390_DFP_ROUND_POSINF_10:
1530 rm = mkU32(Irrm_DFP_PosINF); break;
1531 case S390_DFP_ROUND_NEGINF_7:
1532 case S390_DFP_ROUND_NEGINF_11:
1533 rm = mkU32(Irrm_DFP_NegINF); break;
1534 case S390_DFP_ROUND_NEAREST_TIE_TOWARD_0:
1535 rm = mkU32(Irrm_DFP_NEAREST_TIE_TOWARD_0); break;
1536 case S390_DFP_ROUND_AWAY_0:
1537 rm = mkU32(Irrm_DFP_AWAY_FROM_ZERO); break;
1538 default:
1539 vpanic("encode_dfp_rounding_mode");
1540 }
1541
1542 return mktemp(Ity_I32, rm);
1543}
1544#endif
1545
florian2c74d242012-09-12 19:38:42 +00001546/*------------------------------------------------------------*/
sewardj2019a972011-03-07 16:04:07 +00001547/*--- Build IR for formats ---*/
1548/*------------------------------------------------------------*/
1549static void
1550s390_format_I(HChar *(*irgen)(UChar i),
1551 UChar i)
1552{
1553 HChar *mnm = irgen(i);
1554
sewardj7ee97522011-05-09 21:45:04 +00001555 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001556 s390_disasm(ENC2(MNM, UINT), mnm, i);
1557}
1558
1559static void
1560s390_format_RI(HChar *(*irgen)(UChar r1, UShort i2),
1561 UChar r1, UShort i2)
1562{
1563 irgen(r1, i2);
1564}
1565
1566static void
1567s390_format_RI_RU(HChar *(*irgen)(UChar r1, UShort i2),
1568 UChar r1, UShort i2)
1569{
1570 HChar *mnm = irgen(r1, i2);
1571
sewardj7ee97522011-05-09 21:45:04 +00001572 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001573 s390_disasm(ENC3(MNM, GPR, UINT), mnm, r1, i2);
1574}
1575
1576static void
1577s390_format_RI_RI(HChar *(*irgen)(UChar r1, UShort i2),
1578 UChar r1, UShort i2)
1579{
1580 HChar *mnm = irgen(r1, i2);
1581
sewardj7ee97522011-05-09 21:45:04 +00001582 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001583 s390_disasm(ENC3(MNM, GPR, INT), mnm, r1, (Int)(Short)i2);
1584}
1585
1586static void
1587s390_format_RI_RP(HChar *(*irgen)(UChar r1, UShort i2),
1588 UChar r1, UShort i2)
1589{
1590 HChar *mnm = irgen(r1, i2);
1591
sewardj7ee97522011-05-09 21:45:04 +00001592 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001593 s390_disasm(ENC3(MNM, GPR, PCREL), mnm, r1, (Int)(Short)i2);
1594}
1595
1596static void
1597s390_format_RIE_RRP(HChar *(*irgen)(UChar r1, UChar r3, UShort i2),
1598 UChar r1, UChar r3, UShort i2)
1599{
1600 HChar *mnm = irgen(r1, r3, i2);
1601
sewardj7ee97522011-05-09 21:45:04 +00001602 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001603 s390_disasm(ENC4(MNM, GPR, GPR, PCREL), mnm, r1, r3, (Int)(Short)i2);
1604}
1605
1606static void
1607s390_format_RIE_RRI0(HChar *(*irgen)(UChar r1, UChar r3, UShort i2),
1608 UChar r1, UChar r3, UShort i2)
1609{
1610 HChar *mnm = irgen(r1, r3, i2);
1611
sewardj7ee97522011-05-09 21:45:04 +00001612 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001613 s390_disasm(ENC4(MNM, GPR, GPR, INT), mnm, r1, r3, (Int)(Short)i2);
1614}
1615
1616static void
1617s390_format_RIE_RRUUU(HChar *(*irgen)(UChar r1, UChar r2, UChar i3, UChar i4,
1618 UChar i5),
1619 UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
1620{
1621 HChar *mnm = irgen(r1, r2, i3, i4, i5);
1622
sewardj7ee97522011-05-09 21:45:04 +00001623 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001624 s390_disasm(ENC6(MNM, GPR, GPR, UINT, UINT, UINT), mnm, r1, r2, i3, i4,
1625 i5);
1626}
1627
1628static void
1629s390_format_RIE_RRPU(HChar *(*irgen)(UChar r1, UChar r2, UShort i4, UChar m3),
1630 UChar r1, UChar r2, UShort i4, UChar m3)
1631{
1632 HChar *mnm = irgen(r1, r2, i4, m3);
1633
sewardj7ee97522011-05-09 21:45:04 +00001634 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001635 s390_disasm(ENC5(XMNM, GPR, GPR, CABM, PCREL), S390_XMNM_CAB, mnm, m3, r1,
1636 r2, m3, (Int)(Short)i4);
1637}
1638
1639static void
1640s390_format_RIE_RUPU(HChar *(*irgen)(UChar r1, UChar m3, UShort i4, UChar i2),
1641 UChar r1, UChar m3, UShort i4, UChar i2)
1642{
1643 HChar *mnm = irgen(r1, m3, i4, i2);
1644
sewardj7ee97522011-05-09 21:45:04 +00001645 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001646 s390_disasm(ENC5(XMNM, GPR, UINT, CABM, PCREL), S390_XMNM_CAB, mnm, m3,
1647 r1, i2, m3, (Int)(Short)i4);
1648}
1649
1650static void
1651s390_format_RIE_RUPI(HChar *(*irgen)(UChar r1, UChar m3, UShort i4, UChar i2),
1652 UChar r1, UChar m3, UShort i4, UChar i2)
1653{
1654 HChar *mnm = irgen(r1, m3, i4, i2);
1655
sewardj7ee97522011-05-09 21:45:04 +00001656 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001657 s390_disasm(ENC5(XMNM, GPR, INT, CABM, PCREL), S390_XMNM_CAB, mnm, m3, r1,
1658 (Int)(Char)i2, m3, (Int)(Short)i4);
1659}
1660
1661static void
1662s390_format_RIL(HChar *(*irgen)(UChar r1, UInt i2),
1663 UChar r1, UInt i2)
1664{
1665 irgen(r1, i2);
1666}
1667
1668static void
1669s390_format_RIL_RU(HChar *(*irgen)(UChar r1, UInt i2),
1670 UChar r1, UInt i2)
1671{
1672 HChar *mnm = irgen(r1, i2);
1673
sewardj7ee97522011-05-09 21:45:04 +00001674 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001675 s390_disasm(ENC3(MNM, GPR, UINT), mnm, r1, i2);
1676}
1677
1678static void
1679s390_format_RIL_RI(HChar *(*irgen)(UChar r1, UInt i2),
1680 UChar r1, UInt i2)
1681{
1682 HChar *mnm = irgen(r1, i2);
1683
sewardj7ee97522011-05-09 21:45:04 +00001684 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001685 s390_disasm(ENC3(MNM, GPR, INT), mnm, r1, i2);
1686}
1687
1688static void
1689s390_format_RIL_RP(HChar *(*irgen)(UChar r1, UInt i2),
1690 UChar r1, UInt i2)
1691{
1692 HChar *mnm = irgen(r1, i2);
1693
sewardj7ee97522011-05-09 21:45:04 +00001694 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001695 s390_disasm(ENC3(MNM, GPR, PCREL), mnm, r1, i2);
1696}
1697
1698static void
1699s390_format_RIL_UP(HChar *(*irgen)(void),
1700 UChar r1, UInt i2)
1701{
1702 HChar *mnm = irgen();
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, UINT, PCREL), mnm, r1, i2);
1706}
1707
1708static void
1709s390_format_RIS_RURDI(HChar *(*irgen)(UChar r1, UChar m3, UChar i2,
1710 IRTemp op4addr),
1711 UChar r1, UChar m3, UChar b4, UShort d4, UChar i2)
1712{
1713 HChar *mnm;
1714 IRTemp op4addr = newTemp(Ity_I64);
1715
1716 assign(op4addr, binop(Iop_Add64, mkU64(d4), b4 != 0 ? get_gpr_dw0(b4) :
1717 mkU64(0)));
1718
1719 mnm = irgen(r1, m3, i2, op4addr);
1720
sewardj7ee97522011-05-09 21:45:04 +00001721 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001722 s390_disasm(ENC5(XMNM, GPR, INT, CABM, UDXB), S390_XMNM_CAB, mnm, m3, r1,
1723 (Int)(Char)i2, m3, d4, 0, b4);
1724}
1725
1726static void
1727s390_format_RIS_RURDU(HChar *(*irgen)(UChar r1, UChar m3, UChar i2,
1728 IRTemp op4addr),
1729 UChar r1, UChar m3, UChar b4, UShort d4, UChar i2)
1730{
1731 HChar *mnm;
1732 IRTemp op4addr = newTemp(Ity_I64);
1733
1734 assign(op4addr, binop(Iop_Add64, mkU64(d4), b4 != 0 ? get_gpr_dw0(b4) :
1735 mkU64(0)));
1736
1737 mnm = irgen(r1, m3, i2, op4addr);
1738
sewardj7ee97522011-05-09 21:45:04 +00001739 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001740 s390_disasm(ENC5(XMNM, GPR, UINT, CABM, UDXB), S390_XMNM_CAB, mnm, m3, r1,
1741 i2, m3, d4, 0, b4);
1742}
1743
1744static void
1745s390_format_RR(HChar *(*irgen)(UChar r1, UChar r2),
1746 UChar r1, UChar r2)
1747{
1748 irgen(r1, r2);
1749}
1750
1751static void
1752s390_format_RR_RR(HChar *(*irgen)(UChar r1, UChar r2),
1753 UChar r1, UChar r2)
1754{
1755 HChar *mnm = irgen(r1, r2);
1756
sewardj7ee97522011-05-09 21:45:04 +00001757 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001758 s390_disasm(ENC3(MNM, GPR, GPR), mnm, r1, r2);
1759}
1760
1761static void
1762s390_format_RR_FF(HChar *(*irgen)(UChar r1, UChar r2),
1763 UChar r1, UChar r2)
1764{
1765 HChar *mnm = irgen(r1, r2);
1766
sewardj7ee97522011-05-09 21:45:04 +00001767 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001768 s390_disasm(ENC3(MNM, FPR, FPR), mnm, r1, r2);
1769}
1770
1771static void
1772s390_format_RRE(HChar *(*irgen)(UChar r1, UChar r2),
1773 UChar r1, UChar r2)
1774{
1775 irgen(r1, r2);
1776}
1777
1778static void
1779s390_format_RRE_RR(HChar *(*irgen)(UChar r1, UChar r2),
1780 UChar r1, UChar r2)
1781{
1782 HChar *mnm = irgen(r1, r2);
1783
sewardj7ee97522011-05-09 21:45:04 +00001784 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001785 s390_disasm(ENC3(MNM, GPR, GPR), mnm, r1, r2);
1786}
1787
1788static void
1789s390_format_RRE_FF(HChar *(*irgen)(UChar r1, UChar r2),
1790 UChar r1, UChar r2)
1791{
1792 HChar *mnm = irgen(r1, r2);
1793
sewardj7ee97522011-05-09 21:45:04 +00001794 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001795 s390_disasm(ENC3(MNM, FPR, FPR), mnm, r1, r2);
1796}
1797
1798static void
1799s390_format_RRE_RF(HChar *(*irgen)(UChar, UChar),
1800 UChar r1, UChar r2)
1801{
1802 HChar *mnm = irgen(r1, r2);
1803
sewardj7ee97522011-05-09 21:45:04 +00001804 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001805 s390_disasm(ENC3(MNM, GPR, FPR), mnm, r1, r2);
1806}
1807
1808static void
1809s390_format_RRE_FR(HChar *(*irgen)(UChar r1, UChar r2),
1810 UChar r1, UChar r2)
1811{
1812 HChar *mnm = irgen(r1, r2);
1813
sewardj7ee97522011-05-09 21:45:04 +00001814 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001815 s390_disasm(ENC3(MNM, FPR, GPR), mnm, r1, r2);
1816}
1817
1818static void
1819s390_format_RRE_R0(HChar *(*irgen)(UChar r1),
1820 UChar r1)
1821{
1822 HChar *mnm = irgen(r1);
1823
sewardj7ee97522011-05-09 21:45:04 +00001824 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001825 s390_disasm(ENC2(MNM, GPR), mnm, r1);
1826}
1827
1828static void
1829s390_format_RRE_F0(HChar *(*irgen)(UChar r1),
1830 UChar r1)
1831{
1832 HChar *mnm = irgen(r1);
1833
sewardj7ee97522011-05-09 21:45:04 +00001834 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001835 s390_disasm(ENC2(MNM, FPR), mnm, r1);
1836}
1837
1838static void
florian9af37692012-01-15 21:01:16 +00001839s390_format_RRF_M0RERE(HChar *(*irgen)(UChar m3, UChar r1, UChar r2),
1840 UChar m3, UChar r1, UChar r2)
1841{
florianfed3ea32012-07-19 14:54:03 +00001842 HChar *mnm = irgen(m3, r1, r2);
florian9af37692012-01-15 21:01:16 +00001843
1844 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
florianfed3ea32012-07-19 14:54:03 +00001845 s390_disasm(ENC4(MNM, GPR, GPR, UINT), mnm, r1, r2, m3);
florian9af37692012-01-15 21:01:16 +00001846}
1847
1848static void
sewardj2019a972011-03-07 16:04:07 +00001849s390_format_RRF_F0FF(HChar *(*irgen)(UChar, UChar, UChar),
1850 UChar r1, UChar r3, UChar r2)
1851{
1852 HChar *mnm = irgen(r1, r3, r2);
1853
sewardj7ee97522011-05-09 21:45:04 +00001854 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001855 s390_disasm(ENC4(MNM, FPR, FPR, FPR), mnm, r1, r3, r2);
1856}
1857
1858static void
florian4b8efad2012-09-02 18:07:08 +00001859s390_format_RRF_UUFF(HChar *(*irgen)(UChar m3, UChar m4, UChar r1, UChar r2),
1860 UChar m3, UChar m4, UChar r1, UChar r2)
1861{
1862 HChar *mnm = irgen(m3, m4, r1, r2);
1863
1864 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
1865 s390_disasm(ENC5(MNM, FPR, UINT, FPR, UINT), mnm, r1, m3, r2, m4);
1866}
1867
1868static void
florian1c8f7ff2012-09-01 00:12:11 +00001869s390_format_RRF_UUFR(HChar *(*irgen)(UChar m3, UChar m4, UChar r1, UChar r2),
1870 UChar m3, UChar m4, UChar r1, UChar r2)
1871{
1872 HChar *mnm = irgen(m3, m4, r1, r2);
1873
1874 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
1875 s390_disasm(ENC5(MNM, FPR, UINT, GPR, UINT), mnm, r1, m3, r2, m4);
1876}
1877
1878static void
1879s390_format_RRF_UURF(HChar *(*irgen)(UChar m3, UChar m4, UChar r1, UChar r2),
1880 UChar m3, UChar m4, UChar r1, UChar r2)
1881{
1882 HChar *mnm = irgen(m3, m4, r1, r2);
1883
1884 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
1885 s390_disasm(ENC5(MNM, GPR, UINT, FPR, UINT), mnm, r1, m3, r2, m4);
1886}
1887
1888
1889static void
sewardjd7bde722011-04-05 13:19:33 +00001890s390_format_RRF_U0RR(HChar *(*irgen)(UChar m3, UChar r1, UChar r2),
1891 UChar m3, UChar r1, UChar r2, Int xmnm_kind)
1892{
1893 irgen(m3, r1, r2);
1894
sewardj7ee97522011-05-09 21:45:04 +00001895 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardjd7bde722011-04-05 13:19:33 +00001896 s390_disasm(ENC3(XMNM, GPR, GPR), xmnm_kind, m3, r1, r2);
1897}
1898
1899static void
sewardj2019a972011-03-07 16:04:07 +00001900s390_format_RRF_F0FF2(HChar *(*irgen)(UChar, UChar, UChar),
1901 UChar r3, UChar r1, UChar r2)
1902{
1903 HChar *mnm = irgen(r3, r1, r2);
1904
sewardj7ee97522011-05-09 21:45:04 +00001905 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001906 s390_disasm(ENC4(MNM, FPR, FPR, FPR), mnm, r1, r3, r2);
1907}
1908
1909static void
1910s390_format_RRF_R0RR2(HChar *(*irgen)(UChar r3, UChar r1, UChar r2),
1911 UChar r3, UChar r1, UChar r2)
1912{
1913 HChar *mnm = irgen(r3, r1, r2);
1914
sewardj7ee97522011-05-09 21:45:04 +00001915 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001916 s390_disasm(ENC4(MNM, GPR, GPR, GPR), mnm, r1, r2, r3);
1917}
1918
1919static void
1920s390_format_RRS(HChar *(*irgen)(UChar r1, UChar r2, UChar m3, IRTemp op4addr),
1921 UChar r1, UChar r2, UChar b4, UShort d4, UChar m3)
1922{
1923 HChar *mnm;
1924 IRTemp op4addr = newTemp(Ity_I64);
1925
1926 assign(op4addr, binop(Iop_Add64, mkU64(d4), b4 != 0 ? get_gpr_dw0(b4) :
1927 mkU64(0)));
1928
1929 mnm = irgen(r1, r2, m3, op4addr);
1930
sewardj7ee97522011-05-09 21:45:04 +00001931 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001932 s390_disasm(ENC5(XMNM, GPR, GPR, CABM, UDXB), S390_XMNM_CAB, mnm, m3, r1,
1933 r2, m3, d4, 0, b4);
1934}
1935
1936static void
1937s390_format_RS_R0RD(HChar *(*irgen)(UChar r1, IRTemp op2addr),
1938 UChar r1, UChar b2, UShort d2)
1939{
1940 HChar *mnm;
1941 IRTemp op2addr = newTemp(Ity_I64);
1942
1943 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
1944 mkU64(0)));
1945
1946 mnm = irgen(r1, op2addr);
1947
sewardj7ee97522011-05-09 21:45:04 +00001948 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001949 s390_disasm(ENC3(MNM, GPR, UDXB), mnm, r1, d2, 0, b2);
1950}
1951
1952static void
1953s390_format_RS_RRRD(HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
1954 UChar r1, UChar r3, UChar b2, UShort d2)
1955{
1956 HChar *mnm;
1957 IRTemp op2addr = newTemp(Ity_I64);
1958
1959 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
1960 mkU64(0)));
1961
1962 mnm = irgen(r1, r3, op2addr);
1963
sewardj7ee97522011-05-09 21:45:04 +00001964 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001965 s390_disasm(ENC4(MNM, GPR, GPR, UDXB), mnm, r1, r3, d2, 0, b2);
1966}
1967
1968static void
1969s390_format_RS_RURD(HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
1970 UChar r1, UChar r3, UChar b2, UShort d2)
1971{
1972 HChar *mnm;
1973 IRTemp op2addr = newTemp(Ity_I64);
1974
1975 assign(op2addr, binop(Iop_Add64, mkU64(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, UDXB), mnm, r1, r3, d2, 0, b2);
1982}
1983
1984static void
1985s390_format_RS_AARD(HChar *(*irgen)(UChar, UChar, IRTemp),
1986 UChar r1, UChar r3, UChar b2, UShort d2)
1987{
1988 HChar *mnm;
1989 IRTemp op2addr = newTemp(Ity_I64);
1990
1991 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
1992 mkU64(0)));
1993
1994 mnm = irgen(r1, r3, op2addr);
1995
sewardj7ee97522011-05-09 21:45:04 +00001996 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001997 s390_disasm(ENC4(MNM, AR, AR, UDXB), mnm, r1, r3, d2, 0, b2);
1998}
1999
2000static void
2001s390_format_RSI_RRP(HChar *(*irgen)(UChar r1, UChar r3, UShort i2),
2002 UChar r1, UChar r3, UShort i2)
2003{
2004 HChar *mnm = irgen(r1, r3, i2);
2005
sewardj7ee97522011-05-09 21:45:04 +00002006 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002007 s390_disasm(ENC4(MNM, GPR, GPR, PCREL), mnm, r1, r3, (Int)(Short)i2);
2008}
2009
2010static void
2011s390_format_RSY_RRRD(HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
2012 UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2)
2013{
2014 HChar *mnm;
2015 IRTemp op2addr = newTemp(Ity_I64);
2016 IRTemp d2 = newTemp(Ity_I64);
2017
2018 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2019 assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
2020 mkU64(0)));
2021
2022 mnm = irgen(r1, r3, op2addr);
2023
sewardj7ee97522011-05-09 21:45:04 +00002024 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002025 s390_disasm(ENC4(MNM, GPR, GPR, SDXB), mnm, r1, r3, dh2, dl2, 0, b2);
2026}
2027
2028static void
2029s390_format_RSY_AARD(HChar *(*irgen)(UChar, UChar, IRTemp),
2030 UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2)
2031{
2032 HChar *mnm;
2033 IRTemp op2addr = newTemp(Ity_I64);
2034 IRTemp d2 = newTemp(Ity_I64);
2035
2036 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2037 assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
2038 mkU64(0)));
2039
2040 mnm = irgen(r1, r3, op2addr);
2041
sewardj7ee97522011-05-09 21:45:04 +00002042 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002043 s390_disasm(ENC4(MNM, AR, AR, SDXB), mnm, r1, r3, dh2, dl2, 0, b2);
2044}
2045
2046static void
2047s390_format_RSY_RURD(HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
2048 UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2)
2049{
2050 HChar *mnm;
2051 IRTemp op2addr = newTemp(Ity_I64);
2052 IRTemp d2 = newTemp(Ity_I64);
2053
2054 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2055 assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
2056 mkU64(0)));
2057
2058 mnm = irgen(r1, r3, op2addr);
2059
sewardj7ee97522011-05-09 21:45:04 +00002060 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002061 s390_disasm(ENC4(MNM, GPR, UINT, SDXB), mnm, r1, r3, dh2, dl2, 0, b2);
2062}
2063
2064static void
sewardjd7bde722011-04-05 13:19:33 +00002065s390_format_RSY_RDRM(HChar *(*irgen)(UChar r1, IRTemp op2addr),
2066 UChar r1, UChar m3, UChar b2, UShort dl2, UChar dh2,
2067 Int xmnm_kind)
2068{
2069 IRTemp op2addr = newTemp(Ity_I64);
2070 IRTemp d2 = newTemp(Ity_I64);
2071
florian6820ba52012-07-26 02:01:50 +00002072 next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0)));
2073
sewardjd7bde722011-04-05 13:19:33 +00002074 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2075 assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
2076 mkU64(0)));
2077
2078 irgen(r1, op2addr);
florian6820ba52012-07-26 02:01:50 +00002079
2080 vassert(dis_res->whatNext == Dis_Continue);
sewardjd7bde722011-04-05 13:19:33 +00002081
sewardj7ee97522011-05-09 21:45:04 +00002082 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardjd7bde722011-04-05 13:19:33 +00002083 s390_disasm(ENC3(XMNM, GPR, SDXB), xmnm_kind, m3, r1, dh2, dl2, 0, b2);
2084}
2085
2086static void
sewardj2019a972011-03-07 16:04:07 +00002087s390_format_RX(HChar *(*irgen)(UChar r1, UChar x2, UChar b2, UShort d2,
2088 IRTemp op2addr),
2089 UChar r1, UChar x2, UChar b2, UShort d2)
2090{
2091 IRTemp op2addr = newTemp(Ity_I64);
2092
2093 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
2094 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2095 mkU64(0)));
2096
2097 irgen(r1, x2, b2, d2, op2addr);
2098}
2099
2100static void
2101s390_format_RX_RRRD(HChar *(*irgen)(UChar r1, IRTemp op2addr),
2102 UChar r1, UChar x2, UChar b2, UShort d2)
2103{
2104 HChar *mnm;
2105 IRTemp op2addr = newTemp(Ity_I64);
2106
2107 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
2108 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2109 mkU64(0)));
2110
2111 mnm = irgen(r1, op2addr);
2112
sewardj7ee97522011-05-09 21:45:04 +00002113 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002114 s390_disasm(ENC3(MNM, GPR, UDXB), mnm, r1, d2, x2, b2);
2115}
2116
2117static void
2118s390_format_RX_FRRD(HChar *(*irgen)(UChar r1, IRTemp op2addr),
2119 UChar r1, UChar x2, UChar b2, UShort d2)
2120{
2121 HChar *mnm;
2122 IRTemp op2addr = newTemp(Ity_I64);
2123
2124 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
2125 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2126 mkU64(0)));
2127
2128 mnm = irgen(r1, op2addr);
2129
sewardj7ee97522011-05-09 21:45:04 +00002130 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002131 s390_disasm(ENC3(MNM, FPR, UDXB), mnm, r1, d2, x2, b2);
2132}
2133
2134static void
2135s390_format_RXE_FRRD(HChar *(*irgen)(UChar r1, IRTemp op2addr),
2136 UChar r1, UChar x2, UChar b2, UShort d2)
2137{
2138 HChar *mnm;
2139 IRTemp op2addr = newTemp(Ity_I64);
2140
2141 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
2142 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2143 mkU64(0)));
2144
2145 mnm = irgen(r1, op2addr);
2146
sewardj7ee97522011-05-09 21:45:04 +00002147 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002148 s390_disasm(ENC3(MNM, FPR, UDXB), mnm, r1, d2, x2, b2);
2149}
2150
2151static void
2152s390_format_RXF_FRRDF(HChar *(*irgen)(UChar, IRTemp, UChar),
2153 UChar r3, UChar x2, UChar b2, UShort d2, UChar r1)
2154{
2155 HChar *mnm;
2156 IRTemp op2addr = newTemp(Ity_I64);
2157
2158 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
2159 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2160 mkU64(0)));
2161
2162 mnm = irgen(r3, op2addr, r1);
2163
sewardj7ee97522011-05-09 21:45:04 +00002164 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002165 s390_disasm(ENC4(MNM, FPR, FPR, UDXB), mnm, r1, r3, d2, x2, b2);
2166}
2167
2168static void
2169s390_format_RXY_RRRD(HChar *(*irgen)(UChar r1, IRTemp op2addr),
2170 UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
2171{
2172 HChar *mnm;
2173 IRTemp op2addr = newTemp(Ity_I64);
2174 IRTemp d2 = newTemp(Ity_I64);
2175
2176 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2177 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkexpr(d2),
2178 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2179 mkU64(0)));
2180
2181 mnm = irgen(r1, op2addr);
2182
sewardj7ee97522011-05-09 21:45:04 +00002183 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002184 s390_disasm(ENC3(MNM, GPR, SDXB), mnm, r1, dh2, dl2, x2, b2);
2185}
2186
2187static void
2188s390_format_RXY_FRRD(HChar *(*irgen)(UChar r1, IRTemp op2addr),
2189 UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
2190{
2191 HChar *mnm;
2192 IRTemp op2addr = newTemp(Ity_I64);
2193 IRTemp d2 = newTemp(Ity_I64);
2194
2195 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2196 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkexpr(d2),
2197 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2198 mkU64(0)));
2199
2200 mnm = irgen(r1, op2addr);
2201
sewardj7ee97522011-05-09 21:45:04 +00002202 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002203 s390_disasm(ENC3(MNM, FPR, SDXB), mnm, r1, dh2, dl2, x2, b2);
2204}
2205
2206static void
2207s390_format_RXY_URRD(HChar *(*irgen)(void),
2208 UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
2209{
2210 HChar *mnm;
2211 IRTemp op2addr = newTemp(Ity_I64);
2212 IRTemp d2 = newTemp(Ity_I64);
2213
2214 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2215 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkexpr(d2),
2216 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2217 mkU64(0)));
2218
2219 mnm = irgen();
2220
sewardj7ee97522011-05-09 21:45:04 +00002221 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002222 s390_disasm(ENC3(MNM, UINT, SDXB), mnm, r1, dh2, dl2, x2, b2);
2223}
2224
2225static void
2226s390_format_S_RD(HChar *(*irgen)(IRTemp op2addr),
2227 UChar b2, UShort d2)
2228{
2229 HChar *mnm;
2230 IRTemp op2addr = newTemp(Ity_I64);
2231
2232 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2233 mkU64(0)));
2234
2235 mnm = irgen(op2addr);
2236
sewardj7ee97522011-05-09 21:45:04 +00002237 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002238 s390_disasm(ENC2(MNM, UDXB), mnm, d2, 0, b2);
2239}
2240
2241static void
2242s390_format_SI_URD(HChar *(*irgen)(UChar i2, IRTemp op1addr),
2243 UChar i2, UChar b1, UShort d1)
2244{
2245 HChar *mnm;
2246 IRTemp op1addr = newTemp(Ity_I64);
2247
2248 assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
2249 mkU64(0)));
2250
2251 mnm = irgen(i2, op1addr);
2252
sewardj7ee97522011-05-09 21:45:04 +00002253 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002254 s390_disasm(ENC3(MNM, UDXB, UINT), mnm, d1, 0, b1, i2);
2255}
2256
2257static void
2258s390_format_SIY_URD(HChar *(*irgen)(UChar i2, IRTemp op1addr),
2259 UChar i2, UChar b1, UShort dl1, UChar dh1)
2260{
2261 HChar *mnm;
2262 IRTemp op1addr = newTemp(Ity_I64);
2263 IRTemp d1 = newTemp(Ity_I64);
2264
2265 assign(d1, mkU64(((ULong)(Long)(Char)dh1 << 12) | ((ULong)dl1)));
2266 assign(op1addr, binop(Iop_Add64, mkexpr(d1), b1 != 0 ? get_gpr_dw0(b1) :
2267 mkU64(0)));
2268
2269 mnm = irgen(i2, op1addr);
2270
sewardj7ee97522011-05-09 21:45:04 +00002271 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002272 s390_disasm(ENC3(MNM, SDXB, UINT), mnm, dh1, dl1, 0, b1, i2);
2273}
2274
2275static void
2276s390_format_SIY_IRD(HChar *(*irgen)(UChar i2, IRTemp op1addr),
2277 UChar i2, UChar b1, UShort dl1, UChar dh1)
2278{
2279 HChar *mnm;
2280 IRTemp op1addr = newTemp(Ity_I64);
2281 IRTemp d1 = newTemp(Ity_I64);
2282
2283 assign(d1, mkU64(((ULong)(Long)(Char)dh1 << 12) | ((ULong)dl1)));
2284 assign(op1addr, binop(Iop_Add64, mkexpr(d1), b1 != 0 ? get_gpr_dw0(b1) :
2285 mkU64(0)));
2286
2287 mnm = irgen(i2, op1addr);
2288
sewardj7ee97522011-05-09 21:45:04 +00002289 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002290 s390_disasm(ENC3(MNM, SDXB, INT), mnm, dh1, dl1, 0, b1, (Int)(Char)i2);
2291}
2292
2293static void
2294s390_format_SS_L0RDRD(HChar *(*irgen)(UChar, IRTemp, IRTemp),
2295 UChar l, UChar b1, UShort d1, UChar b2, UShort d2)
2296{
2297 HChar *mnm;
2298 IRTemp op1addr = newTemp(Ity_I64);
2299 IRTemp op2addr = newTemp(Ity_I64);
2300
2301 assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
2302 mkU64(0)));
2303 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2304 mkU64(0)));
2305
2306 mnm = irgen(l, op1addr, op2addr);
2307
sewardj7ee97522011-05-09 21:45:04 +00002308 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002309 s390_disasm(ENC3(MNM, UDLB, UDXB), mnm, d1, l, b1, d2, 0, b2);
2310}
2311
2312static void
2313s390_format_SIL_RDI(HChar *(*irgen)(UShort i2, IRTemp op1addr),
2314 UChar b1, UShort d1, UShort i2)
2315{
2316 HChar *mnm;
2317 IRTemp op1addr = newTemp(Ity_I64);
2318
2319 assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
2320 mkU64(0)));
2321
2322 mnm = irgen(i2, op1addr);
2323
sewardj7ee97522011-05-09 21:45:04 +00002324 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002325 s390_disasm(ENC3(MNM, UDXB, INT), mnm, d1, 0, b1, (Int)(Short)i2);
2326}
2327
2328static void
2329s390_format_SIL_RDU(HChar *(*irgen)(UShort i2, IRTemp op1addr),
2330 UChar b1, UShort d1, UShort i2)
2331{
2332 HChar *mnm;
2333 IRTemp op1addr = newTemp(Ity_I64);
2334
2335 assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
2336 mkU64(0)));
2337
2338 mnm = irgen(i2, op1addr);
2339
sewardj7ee97522011-05-09 21:45:04 +00002340 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002341 s390_disasm(ENC3(MNM, UDXB, UINT), mnm, d1, 0, b1, i2);
2342}
2343
2344
2345
2346/*------------------------------------------------------------*/
2347/*--- Build IR for opcodes ---*/
2348/*------------------------------------------------------------*/
2349
2350static HChar *
2351s390_irgen_AR(UChar r1, UChar r2)
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, get_gpr_w1(r2));
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 "ar";
2364}
2365
2366static HChar *
2367s390_irgen_AGR(UChar r1, UChar r2)
2368{
2369 IRTemp op1 = newTemp(Ity_I64);
2370 IRTemp op2 = newTemp(Ity_I64);
2371 IRTemp result = newTemp(Ity_I64);
2372
2373 assign(op1, get_gpr_dw0(r1));
2374 assign(op2, get_gpr_dw0(r2));
2375 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2376 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
2377 put_gpr_dw0(r1, mkexpr(result));
2378
2379 return "agr";
2380}
2381
2382static HChar *
2383s390_irgen_AGFR(UChar r1, UChar r2)
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, unop(Iop_32Sto64, get_gpr_w1(r2)));
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 "agfr";
2396}
2397
2398static HChar *
2399s390_irgen_ARK(UChar r3, UChar r1, UChar r2)
2400{
2401 IRTemp op2 = newTemp(Ity_I32);
2402 IRTemp op3 = newTemp(Ity_I32);
2403 IRTemp result = newTemp(Ity_I32);
2404
2405 assign(op2, get_gpr_w1(r2));
2406 assign(op3, get_gpr_w1(r3));
2407 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2408 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
2409 put_gpr_w1(r1, mkexpr(result));
2410
2411 return "ark";
2412}
2413
2414static HChar *
2415s390_irgen_AGRK(UChar r3, UChar r1, UChar r2)
2416{
2417 IRTemp op2 = newTemp(Ity_I64);
2418 IRTemp op3 = newTemp(Ity_I64);
2419 IRTemp result = newTemp(Ity_I64);
2420
2421 assign(op2, get_gpr_dw0(r2));
2422 assign(op3, get_gpr_dw0(r3));
2423 assign(result, binop(Iop_Add64, mkexpr(op2), mkexpr(op3)));
2424 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op2, op3);
2425 put_gpr_dw0(r1, mkexpr(result));
2426
2427 return "agrk";
2428}
2429
2430static HChar *
2431s390_irgen_A(UChar r1, IRTemp op2addr)
2432{
2433 IRTemp op1 = newTemp(Ity_I32);
2434 IRTemp op2 = newTemp(Ity_I32);
2435 IRTemp result = newTemp(Ity_I32);
2436
2437 assign(op1, get_gpr_w1(r1));
2438 assign(op2, load(Ity_I32, mkexpr(op2addr)));
2439 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2440 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2441 put_gpr_w1(r1, mkexpr(result));
2442
2443 return "a";
2444}
2445
2446static HChar *
2447s390_irgen_AY(UChar r1, IRTemp op2addr)
2448{
2449 IRTemp op1 = newTemp(Ity_I32);
2450 IRTemp op2 = newTemp(Ity_I32);
2451 IRTemp result = newTemp(Ity_I32);
2452
2453 assign(op1, get_gpr_w1(r1));
2454 assign(op2, load(Ity_I32, mkexpr(op2addr)));
2455 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2456 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2457 put_gpr_w1(r1, mkexpr(result));
2458
2459 return "ay";
2460}
2461
2462static HChar *
2463s390_irgen_AG(UChar r1, IRTemp op2addr)
2464{
2465 IRTemp op1 = newTemp(Ity_I64);
2466 IRTemp op2 = newTemp(Ity_I64);
2467 IRTemp result = newTemp(Ity_I64);
2468
2469 assign(op1, get_gpr_dw0(r1));
2470 assign(op2, load(Ity_I64, mkexpr(op2addr)));
2471 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2472 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
2473 put_gpr_dw0(r1, mkexpr(result));
2474
2475 return "ag";
2476}
2477
2478static HChar *
2479s390_irgen_AGF(UChar r1, IRTemp op2addr)
2480{
2481 IRTemp op1 = newTemp(Ity_I64);
2482 IRTemp op2 = newTemp(Ity_I64);
2483 IRTemp result = newTemp(Ity_I64);
2484
2485 assign(op1, get_gpr_dw0(r1));
2486 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
2487 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2488 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
2489 put_gpr_dw0(r1, mkexpr(result));
2490
2491 return "agf";
2492}
2493
2494static HChar *
2495s390_irgen_AFI(UChar r1, UInt i2)
2496{
2497 IRTemp op1 = newTemp(Ity_I32);
2498 Int op2;
2499 IRTemp result = newTemp(Ity_I32);
2500
2501 assign(op1, get_gpr_w1(r1));
2502 op2 = (Int)i2;
2503 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
2504 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
2505 mkU32((UInt)op2)));
2506 put_gpr_w1(r1, mkexpr(result));
2507
2508 return "afi";
2509}
2510
2511static HChar *
2512s390_irgen_AGFI(UChar r1, UInt i2)
2513{
2514 IRTemp op1 = newTemp(Ity_I64);
2515 Long op2;
2516 IRTemp result = newTemp(Ity_I64);
2517
2518 assign(op1, get_gpr_dw0(r1));
2519 op2 = (Long)(Int)i2;
2520 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64((ULong)op2)));
2521 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, mktemp(Ity_I64,
2522 mkU64((ULong)op2)));
2523 put_gpr_dw0(r1, mkexpr(result));
2524
2525 return "agfi";
2526}
2527
2528static HChar *
2529s390_irgen_AHIK(UChar r1, UChar r3, UShort i2)
2530{
2531 Int op2;
2532 IRTemp op3 = newTemp(Ity_I32);
2533 IRTemp result = newTemp(Ity_I32);
2534
2535 op2 = (Int)(Short)i2;
2536 assign(op3, get_gpr_w1(r3));
2537 assign(result, binop(Iop_Add32, mkU32((UInt)op2), mkexpr(op3)));
2538 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, mktemp(Ity_I32, mkU32((UInt)
2539 op2)), op3);
2540 put_gpr_w1(r1, mkexpr(result));
2541
2542 return "ahik";
2543}
2544
2545static HChar *
2546s390_irgen_AGHIK(UChar r1, UChar r3, UShort i2)
2547{
2548 Long op2;
2549 IRTemp op3 = newTemp(Ity_I64);
2550 IRTemp result = newTemp(Ity_I64);
2551
2552 op2 = (Long)(Short)i2;
2553 assign(op3, get_gpr_dw0(r3));
2554 assign(result, binop(Iop_Add64, mkU64((ULong)op2), mkexpr(op3)));
2555 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, mktemp(Ity_I64, mkU64((ULong)
2556 op2)), op3);
2557 put_gpr_dw0(r1, mkexpr(result));
2558
2559 return "aghik";
2560}
2561
2562static HChar *
2563s390_irgen_ASI(UChar i2, IRTemp op1addr)
2564{
2565 IRTemp op1 = newTemp(Ity_I32);
2566 Int op2;
2567 IRTemp result = newTemp(Ity_I32);
2568
2569 assign(op1, load(Ity_I32, mkexpr(op1addr)));
2570 op2 = (Int)(Char)i2;
2571 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
2572 store(mkexpr(op1addr), mkexpr(result));
2573 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
2574 mkU32((UInt)op2)));
2575
2576 return "asi";
2577}
2578
2579static HChar *
2580s390_irgen_AGSI(UChar i2, IRTemp op1addr)
2581{
2582 IRTemp op1 = newTemp(Ity_I64);
2583 Long op2;
2584 IRTemp result = newTemp(Ity_I64);
2585
2586 assign(op1, load(Ity_I64, mkexpr(op1addr)));
2587 op2 = (Long)(Char)i2;
2588 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64((ULong)op2)));
2589 store(mkexpr(op1addr), mkexpr(result));
2590 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, mktemp(Ity_I64,
2591 mkU64((ULong)op2)));
2592
2593 return "agsi";
2594}
2595
2596static HChar *
2597s390_irgen_AH(UChar r1, IRTemp op2addr)
2598{
2599 IRTemp op1 = newTemp(Ity_I32);
2600 IRTemp op2 = newTemp(Ity_I32);
2601 IRTemp result = newTemp(Ity_I32);
2602
2603 assign(op1, get_gpr_w1(r1));
2604 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
2605 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2606 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2607 put_gpr_w1(r1, mkexpr(result));
2608
2609 return "ah";
2610}
2611
2612static HChar *
2613s390_irgen_AHY(UChar r1, IRTemp op2addr)
2614{
2615 IRTemp op1 = newTemp(Ity_I32);
2616 IRTemp op2 = newTemp(Ity_I32);
2617 IRTemp result = newTemp(Ity_I32);
2618
2619 assign(op1, get_gpr_w1(r1));
2620 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
2621 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2622 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2623 put_gpr_w1(r1, mkexpr(result));
2624
2625 return "ahy";
2626}
2627
2628static HChar *
2629s390_irgen_AHI(UChar r1, UShort i2)
2630{
2631 IRTemp op1 = newTemp(Ity_I32);
2632 Int op2;
2633 IRTemp result = newTemp(Ity_I32);
2634
2635 assign(op1, get_gpr_w1(r1));
2636 op2 = (Int)(Short)i2;
2637 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
2638 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
2639 mkU32((UInt)op2)));
2640 put_gpr_w1(r1, mkexpr(result));
2641
2642 return "ahi";
2643}
2644
2645static HChar *
2646s390_irgen_AGHI(UChar r1, UShort i2)
2647{
2648 IRTemp op1 = newTemp(Ity_I64);
2649 Long op2;
2650 IRTemp result = newTemp(Ity_I64);
2651
2652 assign(op1, get_gpr_dw0(r1));
2653 op2 = (Long)(Short)i2;
2654 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64((ULong)op2)));
2655 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, mktemp(Ity_I64,
2656 mkU64((ULong)op2)));
2657 put_gpr_dw0(r1, mkexpr(result));
2658
2659 return "aghi";
2660}
2661
2662static HChar *
2663s390_irgen_AHHHR(UChar r3, UChar r1, UChar r2)
2664{
2665 IRTemp op2 = newTemp(Ity_I32);
2666 IRTemp op3 = newTemp(Ity_I32);
2667 IRTemp result = newTemp(Ity_I32);
2668
2669 assign(op2, get_gpr_w0(r2));
2670 assign(op3, get_gpr_w0(r3));
2671 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2672 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
2673 put_gpr_w0(r1, mkexpr(result));
2674
2675 return "ahhhr";
2676}
2677
2678static HChar *
2679s390_irgen_AHHLR(UChar r3, UChar r1, UChar r2)
2680{
2681 IRTemp op2 = newTemp(Ity_I32);
2682 IRTemp op3 = newTemp(Ity_I32);
2683 IRTemp result = newTemp(Ity_I32);
2684
2685 assign(op2, get_gpr_w0(r2));
2686 assign(op3, get_gpr_w1(r3));
2687 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2688 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
2689 put_gpr_w0(r1, mkexpr(result));
2690
2691 return "ahhlr";
2692}
2693
2694static HChar *
2695s390_irgen_AIH(UChar r1, UInt i2)
2696{
2697 IRTemp op1 = newTemp(Ity_I32);
2698 Int op2;
2699 IRTemp result = newTemp(Ity_I32);
2700
2701 assign(op1, get_gpr_w0(r1));
2702 op2 = (Int)i2;
2703 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
2704 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
2705 mkU32((UInt)op2)));
2706 put_gpr_w0(r1, mkexpr(result));
2707
2708 return "aih";
2709}
2710
2711static HChar *
2712s390_irgen_ALR(UChar r1, UChar r2)
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, get_gpr_w1(r2));
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 "alr";
2725}
2726
2727static HChar *
2728s390_irgen_ALGR(UChar r1, UChar r2)
2729{
2730 IRTemp op1 = newTemp(Ity_I64);
2731 IRTemp op2 = newTemp(Ity_I64);
2732 IRTemp result = newTemp(Ity_I64);
2733
2734 assign(op1, get_gpr_dw0(r1));
2735 assign(op2, get_gpr_dw0(r2));
2736 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2737 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
2738 put_gpr_dw0(r1, mkexpr(result));
2739
2740 return "algr";
2741}
2742
2743static HChar *
2744s390_irgen_ALGFR(UChar r1, UChar r2)
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, unop(Iop_32Uto64, get_gpr_w1(r2)));
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 "algfr";
2757}
2758
2759static HChar *
2760s390_irgen_ALRK(UChar r3, UChar r1, UChar r2)
2761{
2762 IRTemp op2 = newTemp(Ity_I32);
2763 IRTemp op3 = newTemp(Ity_I32);
2764 IRTemp result = newTemp(Ity_I32);
2765
2766 assign(op2, get_gpr_w1(r2));
2767 assign(op3, get_gpr_w1(r3));
2768 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2769 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
2770 put_gpr_w1(r1, mkexpr(result));
2771
2772 return "alrk";
2773}
2774
2775static HChar *
2776s390_irgen_ALGRK(UChar r3, UChar r1, UChar r2)
2777{
2778 IRTemp op2 = newTemp(Ity_I64);
2779 IRTemp op3 = newTemp(Ity_I64);
2780 IRTemp result = newTemp(Ity_I64);
2781
2782 assign(op2, get_gpr_dw0(r2));
2783 assign(op3, get_gpr_dw0(r3));
2784 assign(result, binop(Iop_Add64, mkexpr(op2), mkexpr(op3)));
2785 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op2, op3);
2786 put_gpr_dw0(r1, mkexpr(result));
2787
2788 return "algrk";
2789}
2790
2791static HChar *
2792s390_irgen_AL(UChar r1, IRTemp op2addr)
2793{
2794 IRTemp op1 = newTemp(Ity_I32);
2795 IRTemp op2 = newTemp(Ity_I32);
2796 IRTemp result = newTemp(Ity_I32);
2797
2798 assign(op1, get_gpr_w1(r1));
2799 assign(op2, load(Ity_I32, mkexpr(op2addr)));
2800 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2801 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, op2);
2802 put_gpr_w1(r1, mkexpr(result));
2803
2804 return "al";
2805}
2806
2807static HChar *
2808s390_irgen_ALY(UChar r1, IRTemp op2addr)
2809{
2810 IRTemp op1 = newTemp(Ity_I32);
2811 IRTemp op2 = newTemp(Ity_I32);
2812 IRTemp result = newTemp(Ity_I32);
2813
2814 assign(op1, get_gpr_w1(r1));
2815 assign(op2, load(Ity_I32, mkexpr(op2addr)));
2816 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2817 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, op2);
2818 put_gpr_w1(r1, mkexpr(result));
2819
2820 return "aly";
2821}
2822
2823static HChar *
2824s390_irgen_ALG(UChar r1, IRTemp op2addr)
2825{
2826 IRTemp op1 = newTemp(Ity_I64);
2827 IRTemp op2 = newTemp(Ity_I64);
2828 IRTemp result = newTemp(Ity_I64);
2829
2830 assign(op1, get_gpr_dw0(r1));
2831 assign(op2, load(Ity_I64, mkexpr(op2addr)));
2832 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2833 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
2834 put_gpr_dw0(r1, mkexpr(result));
2835
2836 return "alg";
2837}
2838
2839static HChar *
2840s390_irgen_ALGF(UChar r1, IRTemp op2addr)
2841{
2842 IRTemp op1 = newTemp(Ity_I64);
2843 IRTemp op2 = newTemp(Ity_I64);
2844 IRTemp result = newTemp(Ity_I64);
2845
2846 assign(op1, get_gpr_dw0(r1));
2847 assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
2848 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2849 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
2850 put_gpr_dw0(r1, mkexpr(result));
2851
2852 return "algf";
2853}
2854
2855static HChar *
2856s390_irgen_ALFI(UChar r1, UInt i2)
2857{
2858 IRTemp op1 = newTemp(Ity_I32);
2859 UInt op2;
2860 IRTemp result = newTemp(Ity_I32);
2861
2862 assign(op1, get_gpr_w1(r1));
2863 op2 = i2;
2864 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
2865 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, mktemp(Ity_I32,
2866 mkU32(op2)));
2867 put_gpr_w1(r1, mkexpr(result));
2868
2869 return "alfi";
2870}
2871
2872static HChar *
2873s390_irgen_ALGFI(UChar r1, UInt i2)
2874{
2875 IRTemp op1 = newTemp(Ity_I64);
2876 ULong op2;
2877 IRTemp result = newTemp(Ity_I64);
2878
2879 assign(op1, get_gpr_dw0(r1));
2880 op2 = (ULong)i2;
2881 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64(op2)));
2882 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, mktemp(Ity_I64,
2883 mkU64(op2)));
2884 put_gpr_dw0(r1, mkexpr(result));
2885
2886 return "algfi";
2887}
2888
2889static HChar *
2890s390_irgen_ALHHHR(UChar r3, UChar r1, UChar r2)
2891{
2892 IRTemp op2 = newTemp(Ity_I32);
2893 IRTemp op3 = newTemp(Ity_I32);
2894 IRTemp result = newTemp(Ity_I32);
2895
2896 assign(op2, get_gpr_w0(r2));
2897 assign(op3, get_gpr_w0(r3));
2898 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2899 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
2900 put_gpr_w0(r1, mkexpr(result));
2901
2902 return "alhhhr";
2903}
2904
2905static HChar *
2906s390_irgen_ALHHLR(UChar r3, UChar r1, UChar r2)
2907{
2908 IRTemp op2 = newTemp(Ity_I32);
2909 IRTemp op3 = newTemp(Ity_I32);
2910 IRTemp result = newTemp(Ity_I32);
2911
2912 assign(op2, get_gpr_w0(r2));
2913 assign(op3, get_gpr_w1(r3));
2914 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2915 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
2916 put_gpr_w0(r1, mkexpr(result));
2917
2918 return "alhhlr";
2919}
2920
2921static HChar *
2922s390_irgen_ALCR(UChar r1, UChar r2)
2923{
2924 IRTemp op1 = newTemp(Ity_I32);
2925 IRTemp op2 = newTemp(Ity_I32);
2926 IRTemp result = newTemp(Ity_I32);
2927 IRTemp carry_in = newTemp(Ity_I32);
2928
2929 assign(op1, get_gpr_w1(r1));
2930 assign(op2, get_gpr_w1(r2));
2931 assign(carry_in, binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)));
2932 assign(result, binop(Iop_Add32, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)),
2933 mkexpr(carry_in)));
2934 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_32, op1, op2, carry_in);
2935 put_gpr_w1(r1, mkexpr(result));
2936
2937 return "alcr";
2938}
2939
2940static HChar *
2941s390_irgen_ALCGR(UChar r1, UChar r2)
2942{
2943 IRTemp op1 = newTemp(Ity_I64);
2944 IRTemp op2 = newTemp(Ity_I64);
2945 IRTemp result = newTemp(Ity_I64);
2946 IRTemp carry_in = newTemp(Ity_I64);
2947
2948 assign(op1, get_gpr_dw0(r1));
2949 assign(op2, get_gpr_dw0(r2));
2950 assign(carry_in, unop(Iop_32Uto64, binop(Iop_Shr32, s390_call_calculate_cc(),
2951 mkU8(1))));
2952 assign(result, binop(Iop_Add64, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)),
2953 mkexpr(carry_in)));
2954 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_64, op1, op2, carry_in);
2955 put_gpr_dw0(r1, mkexpr(result));
2956
2957 return "alcgr";
2958}
2959
2960static HChar *
2961s390_irgen_ALC(UChar r1, IRTemp op2addr)
2962{
2963 IRTemp op1 = newTemp(Ity_I32);
2964 IRTemp op2 = newTemp(Ity_I32);
2965 IRTemp result = newTemp(Ity_I32);
2966 IRTemp carry_in = newTemp(Ity_I32);
2967
2968 assign(op1, get_gpr_w1(r1));
2969 assign(op2, load(Ity_I32, mkexpr(op2addr)));
2970 assign(carry_in, binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)));
2971 assign(result, binop(Iop_Add32, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)),
2972 mkexpr(carry_in)));
2973 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_32, op1, op2, carry_in);
2974 put_gpr_w1(r1, mkexpr(result));
2975
2976 return "alc";
2977}
2978
2979static HChar *
2980s390_irgen_ALCG(UChar r1, IRTemp op2addr)
2981{
2982 IRTemp op1 = newTemp(Ity_I64);
2983 IRTemp op2 = newTemp(Ity_I64);
2984 IRTemp result = newTemp(Ity_I64);
2985 IRTemp carry_in = newTemp(Ity_I64);
2986
2987 assign(op1, get_gpr_dw0(r1));
2988 assign(op2, load(Ity_I64, mkexpr(op2addr)));
2989 assign(carry_in, unop(Iop_32Uto64, binop(Iop_Shr32, s390_call_calculate_cc(),
2990 mkU8(1))));
2991 assign(result, binop(Iop_Add64, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)),
2992 mkexpr(carry_in)));
2993 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_64, op1, op2, carry_in);
2994 put_gpr_dw0(r1, mkexpr(result));
2995
2996 return "alcg";
2997}
2998
2999static HChar *
3000s390_irgen_ALSI(UChar i2, IRTemp op1addr)
3001{
3002 IRTemp op1 = newTemp(Ity_I32);
3003 UInt op2;
3004 IRTemp result = newTemp(Ity_I32);
3005
3006 assign(op1, load(Ity_I32, mkexpr(op1addr)));
3007 op2 = (UInt)(Int)(Char)i2;
3008 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
3009 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, mktemp(Ity_I32,
3010 mkU32(op2)));
3011 store(mkexpr(op1addr), mkexpr(result));
3012
3013 return "alsi";
3014}
3015
3016static HChar *
3017s390_irgen_ALGSI(UChar i2, IRTemp op1addr)
3018{
3019 IRTemp op1 = newTemp(Ity_I64);
3020 ULong op2;
3021 IRTemp result = newTemp(Ity_I64);
3022
3023 assign(op1, load(Ity_I64, mkexpr(op1addr)));
3024 op2 = (ULong)(Long)(Char)i2;
3025 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64(op2)));
3026 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, mktemp(Ity_I64,
3027 mkU64(op2)));
3028 store(mkexpr(op1addr), mkexpr(result));
3029
3030 return "algsi";
3031}
3032
3033static HChar *
3034s390_irgen_ALHSIK(UChar r1, UChar r3, UShort i2)
3035{
3036 UInt op2;
3037 IRTemp op3 = newTemp(Ity_I32);
3038 IRTemp result = newTemp(Ity_I32);
3039
3040 op2 = (UInt)(Int)(Short)i2;
3041 assign(op3, get_gpr_w1(r3));
3042 assign(result, binop(Iop_Add32, mkU32(op2), mkexpr(op3)));
3043 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, mktemp(Ity_I32, mkU32(op2)),
3044 op3);
3045 put_gpr_w1(r1, mkexpr(result));
3046
3047 return "alhsik";
3048}
3049
3050static HChar *
3051s390_irgen_ALGHSIK(UChar r1, UChar r3, UShort i2)
3052{
3053 ULong op2;
3054 IRTemp op3 = newTemp(Ity_I64);
3055 IRTemp result = newTemp(Ity_I64);
3056
3057 op2 = (ULong)(Long)(Short)i2;
3058 assign(op3, get_gpr_dw0(r3));
3059 assign(result, binop(Iop_Add64, mkU64(op2), mkexpr(op3)));
3060 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, mktemp(Ity_I64, mkU64(op2)),
3061 op3);
3062 put_gpr_dw0(r1, mkexpr(result));
3063
3064 return "alghsik";
3065}
3066
3067static HChar *
3068s390_irgen_ALSIH(UChar r1, UInt i2)
3069{
3070 IRTemp op1 = newTemp(Ity_I32);
3071 UInt op2;
3072 IRTemp result = newTemp(Ity_I32);
3073
3074 assign(op1, get_gpr_w0(r1));
3075 op2 = i2;
3076 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
3077 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, mktemp(Ity_I32,
3078 mkU32(op2)));
3079 put_gpr_w0(r1, mkexpr(result));
3080
3081 return "alsih";
3082}
3083
3084static HChar *
3085s390_irgen_ALSIHN(UChar r1, UInt i2)
3086{
3087 IRTemp op1 = newTemp(Ity_I32);
3088 UInt op2;
3089 IRTemp result = newTemp(Ity_I32);
3090
3091 assign(op1, get_gpr_w0(r1));
3092 op2 = i2;
3093 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
3094 put_gpr_w0(r1, mkexpr(result));
3095
3096 return "alsihn";
3097}
3098
3099static HChar *
3100s390_irgen_NR(UChar r1, UChar r2)
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, get_gpr_w1(r2));
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 "nr";
3113}
3114
3115static HChar *
3116s390_irgen_NGR(UChar r1, UChar r2)
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, get_gpr_dw0(r2));
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 "ngr";
3129}
3130
3131static HChar *
3132s390_irgen_NRK(UChar r3, UChar r1, UChar r2)
3133{
3134 IRTemp op2 = newTemp(Ity_I32);
3135 IRTemp op3 = newTemp(Ity_I32);
3136 IRTemp result = newTemp(Ity_I32);
3137
3138 assign(op2, get_gpr_w1(r2));
3139 assign(op3, get_gpr_w1(r3));
3140 assign(result, binop(Iop_And32, mkexpr(op2), mkexpr(op3)));
3141 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3142 put_gpr_w1(r1, mkexpr(result));
3143
3144 return "nrk";
3145}
3146
3147static HChar *
3148s390_irgen_NGRK(UChar r3, UChar r1, UChar r2)
3149{
3150 IRTemp op2 = newTemp(Ity_I64);
3151 IRTemp op3 = newTemp(Ity_I64);
3152 IRTemp result = newTemp(Ity_I64);
3153
3154 assign(op2, get_gpr_dw0(r2));
3155 assign(op3, get_gpr_dw0(r3));
3156 assign(result, binop(Iop_And64, mkexpr(op2), mkexpr(op3)));
3157 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3158 put_gpr_dw0(r1, mkexpr(result));
3159
3160 return "ngrk";
3161}
3162
3163static HChar *
3164s390_irgen_N(UChar r1, IRTemp op2addr)
3165{
3166 IRTemp op1 = newTemp(Ity_I32);
3167 IRTemp op2 = newTemp(Ity_I32);
3168 IRTemp result = newTemp(Ity_I32);
3169
3170 assign(op1, get_gpr_w1(r1));
3171 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3172 assign(result, binop(Iop_And32, mkexpr(op1), mkexpr(op2)));
3173 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3174 put_gpr_w1(r1, mkexpr(result));
3175
3176 return "n";
3177}
3178
3179static HChar *
3180s390_irgen_NY(UChar r1, IRTemp op2addr)
3181{
3182 IRTemp op1 = newTemp(Ity_I32);
3183 IRTemp op2 = newTemp(Ity_I32);
3184 IRTemp result = newTemp(Ity_I32);
3185
3186 assign(op1, get_gpr_w1(r1));
3187 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3188 assign(result, binop(Iop_And32, mkexpr(op1), mkexpr(op2)));
3189 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3190 put_gpr_w1(r1, mkexpr(result));
3191
3192 return "ny";
3193}
3194
3195static HChar *
3196s390_irgen_NG(UChar r1, IRTemp op2addr)
3197{
3198 IRTemp op1 = newTemp(Ity_I64);
3199 IRTemp op2 = newTemp(Ity_I64);
3200 IRTemp result = newTemp(Ity_I64);
3201
3202 assign(op1, get_gpr_dw0(r1));
3203 assign(op2, load(Ity_I64, mkexpr(op2addr)));
3204 assign(result, binop(Iop_And64, mkexpr(op1), mkexpr(op2)));
3205 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3206 put_gpr_dw0(r1, mkexpr(result));
3207
3208 return "ng";
3209}
3210
3211static HChar *
3212s390_irgen_NI(UChar i2, IRTemp op1addr)
3213{
3214 IRTemp op1 = newTemp(Ity_I8);
3215 UChar op2;
3216 IRTemp result = newTemp(Ity_I8);
3217
3218 assign(op1, load(Ity_I8, mkexpr(op1addr)));
3219 op2 = i2;
3220 assign(result, binop(Iop_And8, mkexpr(op1), mkU8(op2)));
3221 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3222 store(mkexpr(op1addr), mkexpr(result));
3223
3224 return "ni";
3225}
3226
3227static HChar *
3228s390_irgen_NIY(UChar i2, IRTemp op1addr)
3229{
3230 IRTemp op1 = newTemp(Ity_I8);
3231 UChar op2;
3232 IRTemp result = newTemp(Ity_I8);
3233
3234 assign(op1, load(Ity_I8, mkexpr(op1addr)));
3235 op2 = i2;
3236 assign(result, binop(Iop_And8, mkexpr(op1), mkU8(op2)));
3237 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3238 store(mkexpr(op1addr), mkexpr(result));
3239
3240 return "niy";
3241}
3242
3243static HChar *
3244s390_irgen_NIHF(UChar r1, UInt i2)
3245{
3246 IRTemp op1 = newTemp(Ity_I32);
3247 UInt op2;
3248 IRTemp result = newTemp(Ity_I32);
3249
3250 assign(op1, get_gpr_w0(r1));
3251 op2 = i2;
3252 assign(result, binop(Iop_And32, mkexpr(op1), mkU32(op2)));
3253 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3254 put_gpr_w0(r1, mkexpr(result));
3255
3256 return "nihf";
3257}
3258
3259static HChar *
3260s390_irgen_NIHH(UChar r1, UShort i2)
3261{
3262 IRTemp op1 = newTemp(Ity_I16);
3263 UShort op2;
3264 IRTemp result = newTemp(Ity_I16);
3265
3266 assign(op1, get_gpr_hw0(r1));
3267 op2 = i2;
3268 assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
3269 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3270 put_gpr_hw0(r1, mkexpr(result));
3271
3272 return "nihh";
3273}
3274
3275static HChar *
3276s390_irgen_NIHL(UChar r1, UShort i2)
3277{
3278 IRTemp op1 = newTemp(Ity_I16);
3279 UShort op2;
3280 IRTemp result = newTemp(Ity_I16);
3281
3282 assign(op1, get_gpr_hw1(r1));
3283 op2 = i2;
3284 assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
3285 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3286 put_gpr_hw1(r1, mkexpr(result));
3287
3288 return "nihl";
3289}
3290
3291static HChar *
3292s390_irgen_NILF(UChar r1, UInt i2)
3293{
3294 IRTemp op1 = newTemp(Ity_I32);
3295 UInt op2;
3296 IRTemp result = newTemp(Ity_I32);
3297
3298 assign(op1, get_gpr_w1(r1));
3299 op2 = i2;
3300 assign(result, binop(Iop_And32, mkexpr(op1), mkU32(op2)));
3301 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3302 put_gpr_w1(r1, mkexpr(result));
3303
3304 return "nilf";
3305}
3306
3307static HChar *
3308s390_irgen_NILH(UChar r1, UShort i2)
3309{
3310 IRTemp op1 = newTemp(Ity_I16);
3311 UShort op2;
3312 IRTemp result = newTemp(Ity_I16);
3313
3314 assign(op1, get_gpr_hw2(r1));
3315 op2 = i2;
3316 assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
3317 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3318 put_gpr_hw2(r1, mkexpr(result));
3319
3320 return "nilh";
3321}
3322
3323static HChar *
3324s390_irgen_NILL(UChar r1, UShort i2)
3325{
3326 IRTemp op1 = newTemp(Ity_I16);
3327 UShort op2;
3328 IRTemp result = newTemp(Ity_I16);
3329
3330 assign(op1, get_gpr_hw3(r1));
3331 op2 = i2;
3332 assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
3333 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3334 put_gpr_hw3(r1, mkexpr(result));
3335
3336 return "nill";
3337}
3338
3339static HChar *
3340s390_irgen_BASR(UChar r1, UChar r2)
3341{
3342 IRTemp target = newTemp(Ity_I64);
3343
3344 if (r2 == 0) {
3345 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 2ULL));
3346 } else {
3347 if (r1 != r2) {
3348 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 2ULL));
3349 call_function(get_gpr_dw0(r2));
3350 } else {
3351 assign(target, get_gpr_dw0(r2));
3352 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 2ULL));
3353 call_function(mkexpr(target));
3354 }
3355 }
3356
3357 return "basr";
3358}
3359
3360static HChar *
3361s390_irgen_BAS(UChar r1, IRTemp op2addr)
3362{
3363 IRTemp target = newTemp(Ity_I64);
3364
3365 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 4ULL));
3366 assign(target, mkexpr(op2addr));
3367 call_function(mkexpr(target));
3368
3369 return "bas";
3370}
3371
3372static HChar *
3373s390_irgen_BCR(UChar r1, UChar r2)
3374{
3375 IRTemp cond = newTemp(Ity_I32);
3376
sewardja52e37e2011-04-28 18:48:06 +00003377 if (r2 == 0 && (r1 >= 14)) { /* serialization */
3378 stmt(IRStmt_MBE(Imbe_Fence));
3379 }
3380
sewardj2019a972011-03-07 16:04:07 +00003381 if ((r2 == 0) || (r1 == 0)) {
3382 } else {
3383 if (r1 == 15) {
3384 return_from_function(get_gpr_dw0(r2));
3385 } else {
3386 assign(cond, s390_call_calculate_cond(r1));
florianf321da72012-07-21 20:32:57 +00003387 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3388 get_gpr_dw0(r2));
sewardj2019a972011-03-07 16:04:07 +00003389 }
3390 }
sewardj7ee97522011-05-09 21:45:04 +00003391 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00003392 s390_disasm(ENC2(XMNM, GPR), S390_XMNM_BCR, r1, r2);
3393
3394 return "bcr";
3395}
3396
3397static HChar *
3398s390_irgen_BC(UChar r1, UChar x2, UChar b2, UShort d2, IRTemp op2addr)
3399{
3400 IRTemp cond = newTemp(Ity_I32);
3401
3402 if (r1 == 0) {
3403 } else {
3404 if (r1 == 15) {
3405 always_goto(mkexpr(op2addr));
3406 } else {
3407 assign(cond, s390_call_calculate_cond(r1));
florianf321da72012-07-21 20:32:57 +00003408 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3409 mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003410 }
3411 }
sewardj7ee97522011-05-09 21:45:04 +00003412 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00003413 s390_disasm(ENC2(XMNM, UDXB), S390_XMNM_BC, r1, d2, x2, b2);
3414
3415 return "bc";
3416}
3417
3418static HChar *
3419s390_irgen_BCTR(UChar r1, UChar r2)
3420{
3421 put_gpr_w1(r1, binop(Iop_Sub32, get_gpr_w1(r1), mkU32(1)));
3422 if (r2 != 0) {
florianf321da72012-07-21 20:32:57 +00003423 if_condition_goto_computed(binop(Iop_CmpNE32, get_gpr_w1(r1), mkU32(0)),
3424 get_gpr_dw0(r2));
sewardj2019a972011-03-07 16:04:07 +00003425 }
3426
3427 return "bctr";
3428}
3429
3430static HChar *
3431s390_irgen_BCTGR(UChar r1, UChar r2)
3432{
3433 put_gpr_dw0(r1, binop(Iop_Sub64, get_gpr_dw0(r1), mkU64(1)));
3434 if (r2 != 0) {
florianf321da72012-07-21 20:32:57 +00003435 if_condition_goto_computed(binop(Iop_CmpNE64, get_gpr_dw0(r1), mkU64(0)),
3436 get_gpr_dw0(r2));
sewardj2019a972011-03-07 16:04:07 +00003437 }
3438
3439 return "bctgr";
3440}
3441
3442static HChar *
3443s390_irgen_BCT(UChar r1, IRTemp op2addr)
3444{
3445 put_gpr_w1(r1, binop(Iop_Sub32, get_gpr_w1(r1), mkU32(1)));
florianf321da72012-07-21 20:32:57 +00003446 if_condition_goto_computed(binop(Iop_CmpNE32, get_gpr_w1(r1), mkU32(0)),
3447 mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003448
3449 return "bct";
3450}
3451
3452static HChar *
3453s390_irgen_BCTG(UChar r1, IRTemp op2addr)
3454{
3455 put_gpr_dw0(r1, binop(Iop_Sub64, get_gpr_dw0(r1), mkU64(1)));
florianf321da72012-07-21 20:32:57 +00003456 if_condition_goto_computed(binop(Iop_CmpNE64, get_gpr_dw0(r1), mkU64(0)),
3457 mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003458
3459 return "bctg";
3460}
3461
3462static HChar *
3463s390_irgen_BXH(UChar r1, UChar r3, IRTemp op2addr)
3464{
3465 IRTemp value = newTemp(Ity_I32);
3466
3467 assign(value, get_gpr_w1(r3 | 1));
3468 put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
florianf321da72012-07-21 20:32:57 +00003469 if_condition_goto_computed(binop(Iop_CmpLT32S, mkexpr(value),
3470 get_gpr_w1(r1)), mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003471
3472 return "bxh";
3473}
3474
3475static HChar *
3476s390_irgen_BXHG(UChar r1, UChar r3, IRTemp op2addr)
3477{
3478 IRTemp value = newTemp(Ity_I64);
3479
3480 assign(value, get_gpr_dw0(r3 | 1));
3481 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
florianf321da72012-07-21 20:32:57 +00003482 if_condition_goto_computed(binop(Iop_CmpLT64S, mkexpr(value),
3483 get_gpr_dw0(r1)), mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003484
3485 return "bxhg";
3486}
3487
3488static HChar *
3489s390_irgen_BXLE(UChar r1, UChar r3, IRTemp op2addr)
3490{
3491 IRTemp value = newTemp(Ity_I32);
3492
3493 assign(value, get_gpr_w1(r3 | 1));
3494 put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
florianf321da72012-07-21 20:32:57 +00003495 if_condition_goto_computed(binop(Iop_CmpLE32S, get_gpr_w1(r1),
3496 mkexpr(value)), mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003497
3498 return "bxle";
3499}
3500
3501static HChar *
3502s390_irgen_BXLEG(UChar r1, UChar r3, IRTemp op2addr)
3503{
3504 IRTemp value = newTemp(Ity_I64);
3505
3506 assign(value, get_gpr_dw0(r3 | 1));
3507 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
florianf321da72012-07-21 20:32:57 +00003508 if_condition_goto_computed(binop(Iop_CmpLE64S, get_gpr_dw0(r1),
3509 mkexpr(value)), mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003510
3511 return "bxleg";
3512}
3513
3514static HChar *
3515s390_irgen_BRAS(UChar r1, UShort i2)
3516{
3517 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 4ULL));
floriana64c2432011-07-16 02:11:50 +00003518 call_function_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
sewardj2019a972011-03-07 16:04:07 +00003519
3520 return "bras";
3521}
3522
3523static HChar *
3524s390_irgen_BRASL(UChar r1, UInt i2)
3525{
3526 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 6ULL));
floriana64c2432011-07-16 02:11:50 +00003527 call_function_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1));
sewardj2019a972011-03-07 16:04:07 +00003528
3529 return "brasl";
3530}
3531
3532static HChar *
3533s390_irgen_BRC(UChar r1, UShort i2)
3534{
3535 IRTemp cond = newTemp(Ity_I32);
3536
3537 if (r1 == 0) {
3538 } else {
3539 if (r1 == 15) {
floriana64c2432011-07-16 02:11:50 +00003540 always_goto_and_chase(
3541 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
sewardj2019a972011-03-07 16:04:07 +00003542 } else {
3543 assign(cond, s390_call_calculate_cond(r1));
3544 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3545 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3546
3547 }
3548 }
sewardj7ee97522011-05-09 21:45:04 +00003549 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00003550 s390_disasm(ENC2(XMNM, PCREL), S390_XMNM_BRC, r1, (Int)(Short)i2);
3551
3552 return "brc";
3553}
3554
3555static HChar *
3556s390_irgen_BRCL(UChar r1, UInt i2)
3557{
3558 IRTemp cond = newTemp(Ity_I32);
3559
3560 if (r1 == 0) {
3561 } else {
3562 if (r1 == 15) {
floriana64c2432011-07-16 02:11:50 +00003563 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1));
sewardj2019a972011-03-07 16:04:07 +00003564 } else {
3565 assign(cond, s390_call_calculate_cond(r1));
3566 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3567 guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1));
3568 }
3569 }
sewardj7ee97522011-05-09 21:45:04 +00003570 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00003571 s390_disasm(ENC2(XMNM, PCREL), S390_XMNM_BRCL, r1, i2);
3572
3573 return "brcl";
3574}
3575
3576static HChar *
3577s390_irgen_BRCT(UChar r1, UShort i2)
3578{
3579 put_gpr_w1(r1, binop(Iop_Sub32, get_gpr_w1(r1), mkU32(1)));
3580 if_condition_goto(binop(Iop_CmpNE32, get_gpr_w1(r1), mkU32(0)),
3581 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3582
3583 return "brct";
3584}
3585
3586static HChar *
3587s390_irgen_BRCTG(UChar r1, UShort i2)
3588{
3589 put_gpr_dw0(r1, binop(Iop_Sub64, get_gpr_dw0(r1), mkU64(1)));
3590 if_condition_goto(binop(Iop_CmpNE64, get_gpr_dw0(r1), mkU64(0)),
3591 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3592
3593 return "brctg";
3594}
3595
3596static HChar *
3597s390_irgen_BRXH(UChar r1, UChar r3, UShort i2)
3598{
3599 IRTemp value = newTemp(Ity_I32);
3600
3601 assign(value, get_gpr_w1(r3 | 1));
3602 put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
3603 if_condition_goto(binop(Iop_CmpLT32S, mkexpr(value), get_gpr_w1(r1)),
3604 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3605
3606 return "brxh";
3607}
3608
3609static HChar *
3610s390_irgen_BRXHG(UChar r1, UChar r3, UShort i2)
3611{
3612 IRTemp value = newTemp(Ity_I64);
3613
3614 assign(value, get_gpr_dw0(r3 | 1));
3615 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
3616 if_condition_goto(binop(Iop_CmpLT64S, mkexpr(value), get_gpr_dw0(r1)),
3617 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3618
3619 return "brxhg";
3620}
3621
3622static HChar *
3623s390_irgen_BRXLE(UChar r1, UChar r3, UShort i2)
3624{
3625 IRTemp value = newTemp(Ity_I32);
3626
3627 assign(value, get_gpr_w1(r3 | 1));
3628 put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
3629 if_condition_goto(binop(Iop_CmpLE32S, get_gpr_w1(r1), mkexpr(value)),
3630 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3631
3632 return "brxle";
3633}
3634
3635static HChar *
3636s390_irgen_BRXLG(UChar r1, UChar r3, UShort i2)
3637{
3638 IRTemp value = newTemp(Ity_I64);
3639
3640 assign(value, get_gpr_dw0(r3 | 1));
3641 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
3642 if_condition_goto(binop(Iop_CmpLE64S, get_gpr_dw0(r1), mkexpr(value)),
3643 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3644
3645 return "brxlg";
3646}
3647
3648static HChar *
3649s390_irgen_CR(UChar r1, UChar r2)
3650{
3651 IRTemp op1 = newTemp(Ity_I32);
3652 IRTemp op2 = newTemp(Ity_I32);
3653
3654 assign(op1, get_gpr_w1(r1));
3655 assign(op2, get_gpr_w1(r2));
3656 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3657
3658 return "cr";
3659}
3660
3661static HChar *
3662s390_irgen_CGR(UChar r1, UChar r2)
3663{
3664 IRTemp op1 = newTemp(Ity_I64);
3665 IRTemp op2 = newTemp(Ity_I64);
3666
3667 assign(op1, get_gpr_dw0(r1));
3668 assign(op2, get_gpr_dw0(r2));
3669 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3670
3671 return "cgr";
3672}
3673
3674static HChar *
3675s390_irgen_CGFR(UChar r1, UChar r2)
3676{
3677 IRTemp op1 = newTemp(Ity_I64);
3678 IRTemp op2 = newTemp(Ity_I64);
3679
3680 assign(op1, get_gpr_dw0(r1));
3681 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
3682 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3683
3684 return "cgfr";
3685}
3686
3687static HChar *
3688s390_irgen_C(UChar r1, IRTemp op2addr)
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, mkexpr(op2addr)));
3695 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3696
3697 return "c";
3698}
3699
3700static HChar *
3701s390_irgen_CY(UChar r1, IRTemp op2addr)
3702{
3703 IRTemp op1 = newTemp(Ity_I32);
3704 IRTemp op2 = newTemp(Ity_I32);
3705
3706 assign(op1, get_gpr_w1(r1));
3707 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3708 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3709
3710 return "cy";
3711}
3712
3713static HChar *
3714s390_irgen_CG(UChar r1, IRTemp op2addr)
3715{
3716 IRTemp op1 = newTemp(Ity_I64);
3717 IRTemp op2 = newTemp(Ity_I64);
3718
3719 assign(op1, get_gpr_dw0(r1));
3720 assign(op2, load(Ity_I64, mkexpr(op2addr)));
3721 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3722
3723 return "cg";
3724}
3725
3726static HChar *
3727s390_irgen_CGF(UChar r1, IRTemp op2addr)
3728{
3729 IRTemp op1 = newTemp(Ity_I64);
3730 IRTemp op2 = newTemp(Ity_I64);
3731
3732 assign(op1, get_gpr_dw0(r1));
3733 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
3734 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3735
3736 return "cgf";
3737}
3738
3739static HChar *
3740s390_irgen_CFI(UChar r1, UInt i2)
3741{
3742 IRTemp op1 = newTemp(Ity_I32);
3743 Int op2;
3744
3745 assign(op1, get_gpr_w1(r1));
3746 op2 = (Int)i2;
3747 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
3748 mkU32((UInt)op2)));
3749
3750 return "cfi";
3751}
3752
3753static HChar *
3754s390_irgen_CGFI(UChar r1, UInt i2)
3755{
3756 IRTemp op1 = newTemp(Ity_I64);
3757 Long op2;
3758
3759 assign(op1, get_gpr_dw0(r1));
3760 op2 = (Long)(Int)i2;
3761 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I64,
3762 mkU64((ULong)op2)));
3763
3764 return "cgfi";
3765}
3766
3767static HChar *
3768s390_irgen_CRL(UChar r1, UInt i2)
3769{
3770 IRTemp op1 = newTemp(Ity_I32);
3771 IRTemp op2 = newTemp(Ity_I32);
3772
3773 assign(op1, get_gpr_w1(r1));
3774 assign(op2, load(Ity_I32, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
3775 i2 << 1))));
3776 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3777
3778 return "crl";
3779}
3780
3781static HChar *
3782s390_irgen_CGRL(UChar r1, UInt i2)
3783{
3784 IRTemp op1 = newTemp(Ity_I64);
3785 IRTemp op2 = newTemp(Ity_I64);
3786
3787 assign(op1, get_gpr_dw0(r1));
3788 assign(op2, load(Ity_I64, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
3789 i2 << 1))));
3790 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3791
3792 return "cgrl";
3793}
3794
3795static HChar *
3796s390_irgen_CGFRL(UChar r1, UInt i2)
3797{
3798 IRTemp op1 = newTemp(Ity_I64);
3799 IRTemp op2 = newTemp(Ity_I64);
3800
3801 assign(op1, get_gpr_dw0(r1));
3802 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
3803 ((ULong)(Long)(Int)i2 << 1)))));
3804 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3805
3806 return "cgfrl";
3807}
3808
3809static HChar *
3810s390_irgen_CRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
3811{
3812 IRTemp op1 = newTemp(Ity_I32);
3813 IRTemp op2 = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00003814 IRTemp cond = newTemp(Ity_I32);
3815
3816 if (m3 == 0) {
3817 } else {
3818 if (m3 == 14) {
3819 always_goto(mkexpr(op4addr));
3820 } else {
3821 assign(op1, get_gpr_w1(r1));
3822 assign(op2, get_gpr_w1(r2));
florianff9613f2012-05-12 15:26:44 +00003823 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
3824 op1, op2));
florianf321da72012-07-21 20:32:57 +00003825 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond),
3826 mkU32(0)), mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00003827 }
3828 }
3829
3830 return "crb";
3831}
3832
3833static HChar *
3834s390_irgen_CGRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
3835{
3836 IRTemp op1 = newTemp(Ity_I64);
3837 IRTemp op2 = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00003838 IRTemp cond = newTemp(Ity_I32);
3839
3840 if (m3 == 0) {
3841 } else {
3842 if (m3 == 14) {
3843 always_goto(mkexpr(op4addr));
3844 } else {
3845 assign(op1, get_gpr_dw0(r1));
3846 assign(op2, get_gpr_dw0(r2));
florianff9613f2012-05-12 15:26:44 +00003847 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
3848 op1, op2));
florianf321da72012-07-21 20:32:57 +00003849 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond),
3850 mkU32(0)), mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00003851 }
3852 }
3853
3854 return "cgrb";
3855}
3856
3857static HChar *
3858s390_irgen_CRJ(UChar r1, UChar r2, UShort i4, UChar m3)
3859{
3860 IRTemp op1 = newTemp(Ity_I32);
3861 IRTemp op2 = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00003862 IRTemp cond = newTemp(Ity_I32);
3863
3864 if (m3 == 0) {
3865 } else {
3866 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00003867 always_goto_and_chase(
3868 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00003869 } else {
3870 assign(op1, get_gpr_w1(r1));
3871 assign(op2, get_gpr_w1(r2));
florianff9613f2012-05-12 15:26:44 +00003872 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
3873 op1, op2));
sewardj2019a972011-03-07 16:04:07 +00003874 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3875 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
3876
3877 }
3878 }
3879
3880 return "crj";
3881}
3882
3883static HChar *
3884s390_irgen_CGRJ(UChar r1, UChar r2, UShort i4, UChar m3)
3885{
3886 IRTemp op1 = newTemp(Ity_I64);
3887 IRTemp op2 = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00003888 IRTemp cond = newTemp(Ity_I32);
3889
3890 if (m3 == 0) {
3891 } else {
3892 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00003893 always_goto_and_chase(
3894 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00003895 } else {
3896 assign(op1, get_gpr_dw0(r1));
3897 assign(op2, get_gpr_dw0(r2));
florianff9613f2012-05-12 15:26:44 +00003898 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
3899 op1, op2));
sewardj2019a972011-03-07 16:04:07 +00003900 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3901 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
3902
3903 }
3904 }
3905
3906 return "cgrj";
3907}
3908
3909static HChar *
3910s390_irgen_CIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
3911{
3912 IRTemp op1 = newTemp(Ity_I32);
3913 Int op2;
sewardj2019a972011-03-07 16:04:07 +00003914 IRTemp cond = newTemp(Ity_I32);
3915
3916 if (m3 == 0) {
3917 } else {
3918 if (m3 == 14) {
3919 always_goto(mkexpr(op4addr));
3920 } else {
3921 assign(op1, get_gpr_w1(r1));
3922 op2 = (Int)(Char)i2;
florianff9613f2012-05-12 15:26:44 +00003923 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
3924 mktemp(Ity_I32, mkU32((UInt)op2))));
florianf321da72012-07-21 20:32:57 +00003925 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3926 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00003927 }
3928 }
3929
3930 return "cib";
3931}
3932
3933static HChar *
3934s390_irgen_CGIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
3935{
3936 IRTemp op1 = newTemp(Ity_I64);
3937 Long op2;
sewardj2019a972011-03-07 16:04:07 +00003938 IRTemp cond = newTemp(Ity_I32);
3939
3940 if (m3 == 0) {
3941 } else {
3942 if (m3 == 14) {
3943 always_goto(mkexpr(op4addr));
3944 } else {
3945 assign(op1, get_gpr_dw0(r1));
3946 op2 = (Long)(Char)i2;
florianff9613f2012-05-12 15:26:44 +00003947 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
3948 mktemp(Ity_I64, mkU64((ULong)op2))));
florianf321da72012-07-21 20:32:57 +00003949 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3950 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00003951 }
3952 }
3953
3954 return "cgib";
3955}
3956
3957static HChar *
3958s390_irgen_CIJ(UChar r1, UChar m3, UShort i4, UChar i2)
3959{
3960 IRTemp op1 = newTemp(Ity_I32);
3961 Int op2;
sewardj2019a972011-03-07 16:04:07 +00003962 IRTemp cond = newTemp(Ity_I32);
3963
3964 if (m3 == 0) {
3965 } else {
3966 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00003967 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00003968 } else {
3969 assign(op1, get_gpr_w1(r1));
3970 op2 = (Int)(Char)i2;
florianff9613f2012-05-12 15:26:44 +00003971 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
3972 mktemp(Ity_I32, mkU32((UInt)op2))));
sewardj2019a972011-03-07 16:04:07 +00003973 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3974 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
3975
3976 }
3977 }
3978
3979 return "cij";
3980}
3981
3982static HChar *
3983s390_irgen_CGIJ(UChar r1, UChar m3, UShort i4, UChar i2)
3984{
3985 IRTemp op1 = newTemp(Ity_I64);
3986 Long op2;
sewardj2019a972011-03-07 16:04:07 +00003987 IRTemp cond = newTemp(Ity_I32);
3988
3989 if (m3 == 0) {
3990 } else {
3991 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00003992 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00003993 } else {
3994 assign(op1, get_gpr_dw0(r1));
3995 op2 = (Long)(Char)i2;
florianff9613f2012-05-12 15:26:44 +00003996 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
3997 mktemp(Ity_I64, mkU64((ULong)op2))));
sewardj2019a972011-03-07 16:04:07 +00003998 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3999 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4000
4001 }
4002 }
4003
4004 return "cgij";
4005}
4006
4007static HChar *
4008s390_irgen_CH(UChar r1, IRTemp op2addr)
4009{
4010 IRTemp op1 = newTemp(Ity_I32);
4011 IRTemp op2 = newTemp(Ity_I32);
4012
4013 assign(op1, get_gpr_w1(r1));
4014 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
4015 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4016
4017 return "ch";
4018}
4019
4020static HChar *
4021s390_irgen_CHY(UChar r1, IRTemp op2addr)
4022{
4023 IRTemp op1 = newTemp(Ity_I32);
4024 IRTemp op2 = newTemp(Ity_I32);
4025
4026 assign(op1, get_gpr_w1(r1));
4027 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
4028 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4029
4030 return "chy";
4031}
4032
4033static HChar *
4034s390_irgen_CGH(UChar r1, IRTemp op2addr)
4035{
4036 IRTemp op1 = newTemp(Ity_I64);
4037 IRTemp op2 = newTemp(Ity_I64);
4038
4039 assign(op1, get_gpr_dw0(r1));
4040 assign(op2, unop(Iop_16Sto64, load(Ity_I16, mkexpr(op2addr))));
4041 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4042
4043 return "cgh";
4044}
4045
4046static HChar *
4047s390_irgen_CHI(UChar r1, UShort i2)
4048{
4049 IRTemp op1 = newTemp(Ity_I32);
4050 Int op2;
4051
4052 assign(op1, get_gpr_w1(r1));
4053 op2 = (Int)(Short)i2;
4054 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
4055 mkU32((UInt)op2)));
4056
4057 return "chi";
4058}
4059
4060static HChar *
4061s390_irgen_CGHI(UChar r1, UShort i2)
4062{
4063 IRTemp op1 = newTemp(Ity_I64);
4064 Long op2;
4065
4066 assign(op1, get_gpr_dw0(r1));
4067 op2 = (Long)(Short)i2;
4068 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I64,
4069 mkU64((ULong)op2)));
4070
4071 return "cghi";
4072}
4073
4074static HChar *
4075s390_irgen_CHHSI(UShort i2, IRTemp op1addr)
4076{
4077 IRTemp op1 = newTemp(Ity_I16);
4078 Short op2;
4079
4080 assign(op1, load(Ity_I16, mkexpr(op1addr)));
4081 op2 = (Short)i2;
4082 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I16,
4083 mkU16((UShort)op2)));
4084
4085 return "chhsi";
4086}
4087
4088static HChar *
4089s390_irgen_CHSI(UShort i2, IRTemp op1addr)
4090{
4091 IRTemp op1 = newTemp(Ity_I32);
4092 Int op2;
4093
4094 assign(op1, load(Ity_I32, mkexpr(op1addr)));
4095 op2 = (Int)(Short)i2;
4096 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
4097 mkU32((UInt)op2)));
4098
4099 return "chsi";
4100}
4101
4102static HChar *
4103s390_irgen_CGHSI(UShort i2, IRTemp op1addr)
4104{
4105 IRTemp op1 = newTemp(Ity_I64);
4106 Long op2;
4107
4108 assign(op1, load(Ity_I64, mkexpr(op1addr)));
4109 op2 = (Long)(Short)i2;
4110 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I64,
4111 mkU64((ULong)op2)));
4112
4113 return "cghsi";
4114}
4115
4116static HChar *
4117s390_irgen_CHRL(UChar r1, UInt i2)
4118{
4119 IRTemp op1 = newTemp(Ity_I32);
4120 IRTemp op2 = newTemp(Ity_I32);
4121
4122 assign(op1, get_gpr_w1(r1));
4123 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
4124 ((ULong)(Long)(Int)i2 << 1)))));
4125 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4126
4127 return "chrl";
4128}
4129
4130static HChar *
4131s390_irgen_CGHRL(UChar r1, UInt i2)
4132{
4133 IRTemp op1 = newTemp(Ity_I64);
4134 IRTemp op2 = newTemp(Ity_I64);
4135
4136 assign(op1, get_gpr_dw0(r1));
4137 assign(op2, unop(Iop_16Sto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
4138 ((ULong)(Long)(Int)i2 << 1)))));
4139 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4140
4141 return "cghrl";
4142}
4143
4144static HChar *
4145s390_irgen_CHHR(UChar r1, UChar r2)
4146{
4147 IRTemp op1 = newTemp(Ity_I32);
4148 IRTemp op2 = newTemp(Ity_I32);
4149
4150 assign(op1, get_gpr_w0(r1));
4151 assign(op2, get_gpr_w0(r2));
4152 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4153
4154 return "chhr";
4155}
4156
4157static HChar *
4158s390_irgen_CHLR(UChar r1, UChar r2)
4159{
4160 IRTemp op1 = newTemp(Ity_I32);
4161 IRTemp op2 = newTemp(Ity_I32);
4162
4163 assign(op1, get_gpr_w0(r1));
4164 assign(op2, get_gpr_w1(r2));
4165 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4166
4167 return "chlr";
4168}
4169
4170static HChar *
4171s390_irgen_CHF(UChar r1, IRTemp op2addr)
4172{
4173 IRTemp op1 = newTemp(Ity_I32);
4174 IRTemp op2 = newTemp(Ity_I32);
4175
4176 assign(op1, get_gpr_w0(r1));
4177 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4178 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4179
4180 return "chf";
4181}
4182
4183static HChar *
4184s390_irgen_CIH(UChar r1, UInt i2)
4185{
4186 IRTemp op1 = newTemp(Ity_I32);
4187 Int op2;
4188
4189 assign(op1, get_gpr_w0(r1));
4190 op2 = (Int)i2;
4191 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
4192 mkU32((UInt)op2)));
4193
4194 return "cih";
4195}
4196
4197static HChar *
4198s390_irgen_CLR(UChar r1, UChar r2)
4199{
4200 IRTemp op1 = newTemp(Ity_I32);
4201 IRTemp op2 = newTemp(Ity_I32);
4202
4203 assign(op1, get_gpr_w1(r1));
4204 assign(op2, get_gpr_w1(r2));
4205 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4206
4207 return "clr";
4208}
4209
4210static HChar *
4211s390_irgen_CLGR(UChar r1, UChar r2)
4212{
4213 IRTemp op1 = newTemp(Ity_I64);
4214 IRTemp op2 = newTemp(Ity_I64);
4215
4216 assign(op1, get_gpr_dw0(r1));
4217 assign(op2, get_gpr_dw0(r2));
4218 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4219
4220 return "clgr";
4221}
4222
4223static HChar *
4224s390_irgen_CLGFR(UChar r1, UChar r2)
4225{
4226 IRTemp op1 = newTemp(Ity_I64);
4227 IRTemp op2 = newTemp(Ity_I64);
4228
4229 assign(op1, get_gpr_dw0(r1));
4230 assign(op2, unop(Iop_32Uto64, get_gpr_w1(r2)));
4231 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4232
4233 return "clgfr";
4234}
4235
4236static HChar *
4237s390_irgen_CL(UChar r1, IRTemp op2addr)
4238{
4239 IRTemp op1 = newTemp(Ity_I32);
4240 IRTemp op2 = newTemp(Ity_I32);
4241
4242 assign(op1, get_gpr_w1(r1));
4243 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4244 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4245
4246 return "cl";
4247}
4248
4249static HChar *
4250s390_irgen_CLY(UChar r1, IRTemp op2addr)
4251{
4252 IRTemp op1 = newTemp(Ity_I32);
4253 IRTemp op2 = newTemp(Ity_I32);
4254
4255 assign(op1, get_gpr_w1(r1));
4256 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4257 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4258
4259 return "cly";
4260}
4261
4262static HChar *
4263s390_irgen_CLG(UChar r1, IRTemp op2addr)
4264{
4265 IRTemp op1 = newTemp(Ity_I64);
4266 IRTemp op2 = newTemp(Ity_I64);
4267
4268 assign(op1, get_gpr_dw0(r1));
4269 assign(op2, load(Ity_I64, mkexpr(op2addr)));
4270 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4271
4272 return "clg";
4273}
4274
4275static HChar *
4276s390_irgen_CLGF(UChar r1, IRTemp op2addr)
4277{
4278 IRTemp op1 = newTemp(Ity_I64);
4279 IRTemp op2 = newTemp(Ity_I64);
4280
4281 assign(op1, get_gpr_dw0(r1));
4282 assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
4283 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4284
4285 return "clgf";
4286}
4287
4288static HChar *
4289s390_irgen_CLFI(UChar r1, UInt i2)
4290{
4291 IRTemp op1 = newTemp(Ity_I32);
4292 UInt op2;
4293
4294 assign(op1, get_gpr_w1(r1));
4295 op2 = i2;
4296 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I32,
4297 mkU32(op2)));
4298
4299 return "clfi";
4300}
4301
4302static HChar *
4303s390_irgen_CLGFI(UChar r1, UInt i2)
4304{
4305 IRTemp op1 = newTemp(Ity_I64);
4306 ULong op2;
4307
4308 assign(op1, get_gpr_dw0(r1));
4309 op2 = (ULong)i2;
4310 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I64,
4311 mkU64(op2)));
4312
4313 return "clgfi";
4314}
4315
4316static HChar *
4317s390_irgen_CLI(UChar i2, IRTemp op1addr)
4318{
4319 IRTemp op1 = newTemp(Ity_I8);
4320 UChar op2;
4321
4322 assign(op1, load(Ity_I8, mkexpr(op1addr)));
4323 op2 = i2;
4324 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I8,
4325 mkU8(op2)));
4326
4327 return "cli";
4328}
4329
4330static HChar *
4331s390_irgen_CLIY(UChar i2, IRTemp op1addr)
4332{
4333 IRTemp op1 = newTemp(Ity_I8);
4334 UChar op2;
4335
4336 assign(op1, load(Ity_I8, mkexpr(op1addr)));
4337 op2 = i2;
4338 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I8,
4339 mkU8(op2)));
4340
4341 return "cliy";
4342}
4343
4344static HChar *
4345s390_irgen_CLFHSI(UShort i2, IRTemp op1addr)
4346{
4347 IRTemp op1 = newTemp(Ity_I32);
4348 UInt op2;
4349
4350 assign(op1, load(Ity_I32, mkexpr(op1addr)));
4351 op2 = (UInt)i2;
4352 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I32,
4353 mkU32(op2)));
4354
4355 return "clfhsi";
4356}
4357
4358static HChar *
4359s390_irgen_CLGHSI(UShort i2, IRTemp op1addr)
4360{
4361 IRTemp op1 = newTemp(Ity_I64);
4362 ULong op2;
4363
4364 assign(op1, load(Ity_I64, mkexpr(op1addr)));
4365 op2 = (ULong)i2;
4366 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I64,
4367 mkU64(op2)));
4368
4369 return "clghsi";
4370}
4371
4372static HChar *
4373s390_irgen_CLHHSI(UShort i2, IRTemp op1addr)
4374{
4375 IRTemp op1 = newTemp(Ity_I16);
4376 UShort op2;
4377
4378 assign(op1, load(Ity_I16, mkexpr(op1addr)));
4379 op2 = i2;
4380 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I16,
4381 mkU16(op2)));
4382
4383 return "clhhsi";
4384}
4385
4386static HChar *
4387s390_irgen_CLRL(UChar r1, UInt i2)
4388{
4389 IRTemp op1 = newTemp(Ity_I32);
4390 IRTemp op2 = newTemp(Ity_I32);
4391
4392 assign(op1, get_gpr_w1(r1));
4393 assign(op2, load(Ity_I32, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
4394 i2 << 1))));
4395 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4396
4397 return "clrl";
4398}
4399
4400static HChar *
4401s390_irgen_CLGRL(UChar r1, UInt i2)
4402{
4403 IRTemp op1 = newTemp(Ity_I64);
4404 IRTemp op2 = newTemp(Ity_I64);
4405
4406 assign(op1, get_gpr_dw0(r1));
4407 assign(op2, load(Ity_I64, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
4408 i2 << 1))));
4409 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4410
4411 return "clgrl";
4412}
4413
4414static HChar *
4415s390_irgen_CLGFRL(UChar r1, UInt i2)
4416{
4417 IRTemp op1 = newTemp(Ity_I64);
4418 IRTemp op2 = newTemp(Ity_I64);
4419
4420 assign(op1, get_gpr_dw0(r1));
4421 assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
4422 ((ULong)(Long)(Int)i2 << 1)))));
4423 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4424
4425 return "clgfrl";
4426}
4427
4428static HChar *
4429s390_irgen_CLHRL(UChar r1, UInt i2)
4430{
4431 IRTemp op1 = newTemp(Ity_I32);
4432 IRTemp op2 = newTemp(Ity_I32);
4433
4434 assign(op1, get_gpr_w1(r1));
4435 assign(op2, unop(Iop_16Uto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
4436 ((ULong)(Long)(Int)i2 << 1)))));
4437 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4438
4439 return "clhrl";
4440}
4441
4442static HChar *
4443s390_irgen_CLGHRL(UChar r1, UInt i2)
4444{
4445 IRTemp op1 = newTemp(Ity_I64);
4446 IRTemp op2 = newTemp(Ity_I64);
4447
4448 assign(op1, get_gpr_dw0(r1));
4449 assign(op2, unop(Iop_16Uto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
4450 ((ULong)(Long)(Int)i2 << 1)))));
4451 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4452
4453 return "clghrl";
4454}
4455
4456static HChar *
4457s390_irgen_CLRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
4458{
4459 IRTemp op1 = newTemp(Ity_I32);
4460 IRTemp op2 = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00004461 IRTemp cond = newTemp(Ity_I32);
4462
4463 if (m3 == 0) {
4464 } else {
4465 if (m3 == 14) {
4466 always_goto(mkexpr(op4addr));
4467 } else {
4468 assign(op1, get_gpr_w1(r1));
4469 assign(op2, get_gpr_w1(r2));
florianff9613f2012-05-12 15:26:44 +00004470 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4471 op1, op2));
florianf321da72012-07-21 20:32:57 +00004472 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4473 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004474 }
4475 }
4476
4477 return "clrb";
4478}
4479
4480static HChar *
4481s390_irgen_CLGRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
4482{
4483 IRTemp op1 = newTemp(Ity_I64);
4484 IRTemp op2 = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00004485 IRTemp cond = newTemp(Ity_I32);
4486
4487 if (m3 == 0) {
4488 } else {
4489 if (m3 == 14) {
4490 always_goto(mkexpr(op4addr));
4491 } else {
4492 assign(op1, get_gpr_dw0(r1));
4493 assign(op2, get_gpr_dw0(r2));
florianff9613f2012-05-12 15:26:44 +00004494 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4495 op1, op2));
florianf321da72012-07-21 20:32:57 +00004496 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4497 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004498 }
4499 }
4500
4501 return "clgrb";
4502}
4503
4504static HChar *
4505s390_irgen_CLRJ(UChar r1, UChar r2, UShort i4, UChar m3)
4506{
4507 IRTemp op1 = newTemp(Ity_I32);
4508 IRTemp op2 = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00004509 IRTemp cond = newTemp(Ity_I32);
4510
4511 if (m3 == 0) {
4512 } else {
4513 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004514 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004515 } else {
4516 assign(op1, get_gpr_w1(r1));
4517 assign(op2, get_gpr_w1(r2));
florianff9613f2012-05-12 15:26:44 +00004518 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4519 op1, op2));
sewardj2019a972011-03-07 16:04:07 +00004520 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4521 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4522
4523 }
4524 }
4525
4526 return "clrj";
4527}
4528
4529static HChar *
4530s390_irgen_CLGRJ(UChar r1, UChar r2, UShort i4, UChar m3)
4531{
4532 IRTemp op1 = newTemp(Ity_I64);
4533 IRTemp op2 = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00004534 IRTemp cond = newTemp(Ity_I32);
4535
4536 if (m3 == 0) {
4537 } else {
4538 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004539 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004540 } else {
4541 assign(op1, get_gpr_dw0(r1));
4542 assign(op2, get_gpr_dw0(r2));
florianff9613f2012-05-12 15:26:44 +00004543 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4544 op1, op2));
sewardj2019a972011-03-07 16:04:07 +00004545 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4546 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4547
4548 }
4549 }
4550
4551 return "clgrj";
4552}
4553
4554static HChar *
4555s390_irgen_CLIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
4556{
4557 IRTemp op1 = newTemp(Ity_I32);
4558 UInt op2;
sewardj2019a972011-03-07 16:04:07 +00004559 IRTemp cond = newTemp(Ity_I32);
4560
4561 if (m3 == 0) {
4562 } else {
4563 if (m3 == 14) {
4564 always_goto(mkexpr(op4addr));
4565 } else {
4566 assign(op1, get_gpr_w1(r1));
4567 op2 = (UInt)i2;
florianff9613f2012-05-12 15:26:44 +00004568 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4569 mktemp(Ity_I32, mkU32(op2))));
florianf321da72012-07-21 20:32:57 +00004570 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4571 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004572 }
4573 }
4574
4575 return "clib";
4576}
4577
4578static HChar *
4579s390_irgen_CLGIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
4580{
4581 IRTemp op1 = newTemp(Ity_I64);
4582 ULong op2;
sewardj2019a972011-03-07 16:04:07 +00004583 IRTemp cond = newTemp(Ity_I32);
4584
4585 if (m3 == 0) {
4586 } else {
4587 if (m3 == 14) {
4588 always_goto(mkexpr(op4addr));
4589 } else {
4590 assign(op1, get_gpr_dw0(r1));
4591 op2 = (ULong)i2;
florianff9613f2012-05-12 15:26:44 +00004592 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4593 mktemp(Ity_I64, mkU64(op2))));
florianf321da72012-07-21 20:32:57 +00004594 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4595 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004596 }
4597 }
4598
4599 return "clgib";
4600}
4601
4602static HChar *
4603s390_irgen_CLIJ(UChar r1, UChar m3, UShort i4, UChar i2)
4604{
4605 IRTemp op1 = newTemp(Ity_I32);
4606 UInt op2;
sewardj2019a972011-03-07 16:04:07 +00004607 IRTemp cond = newTemp(Ity_I32);
4608
4609 if (m3 == 0) {
4610 } else {
4611 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004612 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004613 } else {
4614 assign(op1, get_gpr_w1(r1));
4615 op2 = (UInt)i2;
florianff9613f2012-05-12 15:26:44 +00004616 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4617 mktemp(Ity_I32, mkU32(op2))));
sewardj2019a972011-03-07 16:04:07 +00004618 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4619 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4620
4621 }
4622 }
4623
4624 return "clij";
4625}
4626
4627static HChar *
4628s390_irgen_CLGIJ(UChar r1, UChar m3, UShort i4, UChar i2)
4629{
4630 IRTemp op1 = newTemp(Ity_I64);
4631 ULong op2;
sewardj2019a972011-03-07 16:04:07 +00004632 IRTemp cond = newTemp(Ity_I32);
4633
4634 if (m3 == 0) {
4635 } else {
4636 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004637 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004638 } else {
4639 assign(op1, get_gpr_dw0(r1));
4640 op2 = (ULong)i2;
florianff9613f2012-05-12 15:26:44 +00004641 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4642 mktemp(Ity_I64, mkU64(op2))));
sewardj2019a972011-03-07 16:04:07 +00004643 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4644 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4645
4646 }
4647 }
4648
4649 return "clgij";
4650}
4651
4652static HChar *
4653s390_irgen_CLM(UChar r1, UChar r3, IRTemp op2addr)
4654{
4655 IRTemp op1 = newTemp(Ity_I32);
4656 IRTemp op2 = newTemp(Ity_I32);
4657 IRTemp b0 = newTemp(Ity_I32);
4658 IRTemp b1 = newTemp(Ity_I32);
4659 IRTemp b2 = newTemp(Ity_I32);
4660 IRTemp b3 = newTemp(Ity_I32);
4661 IRTemp c0 = newTemp(Ity_I32);
4662 IRTemp c1 = newTemp(Ity_I32);
4663 IRTemp c2 = newTemp(Ity_I32);
4664 IRTemp c3 = newTemp(Ity_I32);
4665 UChar n;
4666
4667 n = 0;
4668 if ((r3 & 8) != 0) {
4669 assign(b0, unop(Iop_8Uto32, get_gpr_b4(r1)));
4670 assign(c0, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
4671 n = n + 1;
4672 } else {
4673 assign(b0, mkU32(0));
4674 assign(c0, mkU32(0));
4675 }
4676 if ((r3 & 4) != 0) {
4677 assign(b1, unop(Iop_8Uto32, get_gpr_b5(r1)));
4678 assign(c1, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4679 mkU64(n)))));
4680 n = n + 1;
4681 } else {
4682 assign(b1, mkU32(0));
4683 assign(c1, mkU32(0));
4684 }
4685 if ((r3 & 2) != 0) {
4686 assign(b2, unop(Iop_8Uto32, get_gpr_b6(r1)));
4687 assign(c2, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4688 mkU64(n)))));
4689 n = n + 1;
4690 } else {
4691 assign(b2, mkU32(0));
4692 assign(c2, mkU32(0));
4693 }
4694 if ((r3 & 1) != 0) {
4695 assign(b3, unop(Iop_8Uto32, get_gpr_b7(r1)));
4696 assign(c3, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4697 mkU64(n)))));
4698 n = n + 1;
4699 } else {
4700 assign(b3, mkU32(0));
4701 assign(c3, mkU32(0));
4702 }
4703 assign(op1, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4704 mkexpr(b0), mkU8(24)), binop(Iop_Shl32, mkexpr(b1), mkU8(16))),
4705 binop(Iop_Shl32, mkexpr(b2), mkU8(8))), mkexpr(b3)));
4706 assign(op2, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4707 mkexpr(c0), mkU8(24)), binop(Iop_Shl32, mkexpr(c1), mkU8(16))),
4708 binop(Iop_Shl32, mkexpr(c2), mkU8(8))), mkexpr(c3)));
4709 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4710
4711 return "clm";
4712}
4713
4714static HChar *
4715s390_irgen_CLMY(UChar r1, UChar r3, IRTemp op2addr)
4716{
4717 IRTemp op1 = newTemp(Ity_I32);
4718 IRTemp op2 = newTemp(Ity_I32);
4719 IRTemp b0 = newTemp(Ity_I32);
4720 IRTemp b1 = newTemp(Ity_I32);
4721 IRTemp b2 = newTemp(Ity_I32);
4722 IRTemp b3 = newTemp(Ity_I32);
4723 IRTemp c0 = newTemp(Ity_I32);
4724 IRTemp c1 = newTemp(Ity_I32);
4725 IRTemp c2 = newTemp(Ity_I32);
4726 IRTemp c3 = newTemp(Ity_I32);
4727 UChar n;
4728
4729 n = 0;
4730 if ((r3 & 8) != 0) {
4731 assign(b0, unop(Iop_8Uto32, get_gpr_b4(r1)));
4732 assign(c0, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
4733 n = n + 1;
4734 } else {
4735 assign(b0, mkU32(0));
4736 assign(c0, mkU32(0));
4737 }
4738 if ((r3 & 4) != 0) {
4739 assign(b1, unop(Iop_8Uto32, get_gpr_b5(r1)));
4740 assign(c1, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4741 mkU64(n)))));
4742 n = n + 1;
4743 } else {
4744 assign(b1, mkU32(0));
4745 assign(c1, mkU32(0));
4746 }
4747 if ((r3 & 2) != 0) {
4748 assign(b2, unop(Iop_8Uto32, get_gpr_b6(r1)));
4749 assign(c2, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4750 mkU64(n)))));
4751 n = n + 1;
4752 } else {
4753 assign(b2, mkU32(0));
4754 assign(c2, mkU32(0));
4755 }
4756 if ((r3 & 1) != 0) {
4757 assign(b3, unop(Iop_8Uto32, get_gpr_b7(r1)));
4758 assign(c3, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4759 mkU64(n)))));
4760 n = n + 1;
4761 } else {
4762 assign(b3, mkU32(0));
4763 assign(c3, mkU32(0));
4764 }
4765 assign(op1, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4766 mkexpr(b0), mkU8(24)), binop(Iop_Shl32, mkexpr(b1), mkU8(16))),
4767 binop(Iop_Shl32, mkexpr(b2), mkU8(8))), mkexpr(b3)));
4768 assign(op2, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4769 mkexpr(c0), mkU8(24)), binop(Iop_Shl32, mkexpr(c1), mkU8(16))),
4770 binop(Iop_Shl32, mkexpr(c2), mkU8(8))), mkexpr(c3)));
4771 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4772
4773 return "clmy";
4774}
4775
4776static HChar *
4777s390_irgen_CLMH(UChar r1, UChar r3, IRTemp op2addr)
4778{
4779 IRTemp op1 = newTemp(Ity_I32);
4780 IRTemp op2 = newTemp(Ity_I32);
4781 IRTemp b0 = newTemp(Ity_I32);
4782 IRTemp b1 = newTemp(Ity_I32);
4783 IRTemp b2 = newTemp(Ity_I32);
4784 IRTemp b3 = newTemp(Ity_I32);
4785 IRTemp c0 = newTemp(Ity_I32);
4786 IRTemp c1 = newTemp(Ity_I32);
4787 IRTemp c2 = newTemp(Ity_I32);
4788 IRTemp c3 = newTemp(Ity_I32);
4789 UChar n;
4790
4791 n = 0;
4792 if ((r3 & 8) != 0) {
4793 assign(b0, unop(Iop_8Uto32, get_gpr_b0(r1)));
4794 assign(c0, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
4795 n = n + 1;
4796 } else {
4797 assign(b0, mkU32(0));
4798 assign(c0, mkU32(0));
4799 }
4800 if ((r3 & 4) != 0) {
4801 assign(b1, unop(Iop_8Uto32, get_gpr_b1(r1)));
4802 assign(c1, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4803 mkU64(n)))));
4804 n = n + 1;
4805 } else {
4806 assign(b1, mkU32(0));
4807 assign(c1, mkU32(0));
4808 }
4809 if ((r3 & 2) != 0) {
4810 assign(b2, unop(Iop_8Uto32, get_gpr_b2(r1)));
4811 assign(c2, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4812 mkU64(n)))));
4813 n = n + 1;
4814 } else {
4815 assign(b2, mkU32(0));
4816 assign(c2, mkU32(0));
4817 }
4818 if ((r3 & 1) != 0) {
4819 assign(b3, unop(Iop_8Uto32, get_gpr_b3(r1)));
4820 assign(c3, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4821 mkU64(n)))));
4822 n = n + 1;
4823 } else {
4824 assign(b3, mkU32(0));
4825 assign(c3, mkU32(0));
4826 }
4827 assign(op1, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4828 mkexpr(b0), mkU8(24)), binop(Iop_Shl32, mkexpr(b1), mkU8(16))),
4829 binop(Iop_Shl32, mkexpr(b2), mkU8(8))), mkexpr(b3)));
4830 assign(op2, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4831 mkexpr(c0), mkU8(24)), binop(Iop_Shl32, mkexpr(c1), mkU8(16))),
4832 binop(Iop_Shl32, mkexpr(c2), mkU8(8))), mkexpr(c3)));
4833 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4834
4835 return "clmh";
4836}
4837
4838static HChar *
4839s390_irgen_CLHHR(UChar r1, UChar r2)
4840{
4841 IRTemp op1 = newTemp(Ity_I32);
4842 IRTemp op2 = newTemp(Ity_I32);
4843
4844 assign(op1, get_gpr_w0(r1));
4845 assign(op2, get_gpr_w0(r2));
4846 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4847
4848 return "clhhr";
4849}
4850
4851static HChar *
4852s390_irgen_CLHLR(UChar r1, UChar r2)
4853{
4854 IRTemp op1 = newTemp(Ity_I32);
4855 IRTemp op2 = newTemp(Ity_I32);
4856
4857 assign(op1, get_gpr_w0(r1));
4858 assign(op2, get_gpr_w1(r2));
4859 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4860
4861 return "clhlr";
4862}
4863
4864static HChar *
4865s390_irgen_CLHF(UChar r1, IRTemp op2addr)
4866{
4867 IRTemp op1 = newTemp(Ity_I32);
4868 IRTemp op2 = newTemp(Ity_I32);
4869
4870 assign(op1, get_gpr_w0(r1));
4871 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4872 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4873
4874 return "clhf";
4875}
4876
4877static HChar *
4878s390_irgen_CLIH(UChar r1, UInt i2)
4879{
4880 IRTemp op1 = newTemp(Ity_I32);
4881 UInt op2;
4882
4883 assign(op1, get_gpr_w0(r1));
4884 op2 = i2;
4885 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I32,
4886 mkU32(op2)));
4887
4888 return "clih";
4889}
4890
4891static HChar *
4892s390_irgen_CPYA(UChar r1, UChar r2)
4893{
4894 put_ar_w0(r1, get_ar_w0(r2));
sewardj7ee97522011-05-09 21:45:04 +00004895 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00004896 s390_disasm(ENC3(MNM, AR, AR), "cpya", r1, r2);
4897
4898 return "cpya";
4899}
4900
4901static HChar *
4902s390_irgen_XR(UChar r1, UChar r2)
4903{
4904 IRTemp op1 = newTemp(Ity_I32);
4905 IRTemp op2 = newTemp(Ity_I32);
4906 IRTemp result = newTemp(Ity_I32);
4907
4908 if (r1 == r2) {
4909 assign(result, mkU32(0));
4910 } else {
4911 assign(op1, get_gpr_w1(r1));
4912 assign(op2, get_gpr_w1(r2));
4913 assign(result, binop(Iop_Xor32, mkexpr(op1), mkexpr(op2)));
4914 }
4915 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4916 put_gpr_w1(r1, mkexpr(result));
4917
4918 return "xr";
4919}
4920
4921static HChar *
4922s390_irgen_XGR(UChar r1, UChar r2)
4923{
4924 IRTemp op1 = newTemp(Ity_I64);
4925 IRTemp op2 = newTemp(Ity_I64);
4926 IRTemp result = newTemp(Ity_I64);
4927
4928 if (r1 == r2) {
4929 assign(result, mkU64(0));
4930 } else {
4931 assign(op1, get_gpr_dw0(r1));
4932 assign(op2, get_gpr_dw0(r2));
4933 assign(result, binop(Iop_Xor64, mkexpr(op1), mkexpr(op2)));
4934 }
4935 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4936 put_gpr_dw0(r1, mkexpr(result));
4937
4938 return "xgr";
4939}
4940
4941static HChar *
4942s390_irgen_XRK(UChar r3, UChar r1, UChar r2)
4943{
4944 IRTemp op2 = newTemp(Ity_I32);
4945 IRTemp op3 = newTemp(Ity_I32);
4946 IRTemp result = newTemp(Ity_I32);
4947
4948 assign(op2, get_gpr_w1(r2));
4949 assign(op3, get_gpr_w1(r3));
4950 assign(result, binop(Iop_Xor32, mkexpr(op2), mkexpr(op3)));
4951 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4952 put_gpr_w1(r1, mkexpr(result));
4953
4954 return "xrk";
4955}
4956
4957static HChar *
4958s390_irgen_XGRK(UChar r3, UChar r1, UChar r2)
4959{
4960 IRTemp op2 = newTemp(Ity_I64);
4961 IRTemp op3 = newTemp(Ity_I64);
4962 IRTemp result = newTemp(Ity_I64);
4963
4964 assign(op2, get_gpr_dw0(r2));
4965 assign(op3, get_gpr_dw0(r3));
4966 assign(result, binop(Iop_Xor64, mkexpr(op2), mkexpr(op3)));
4967 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4968 put_gpr_dw0(r1, mkexpr(result));
4969
4970 return "xgrk";
4971}
4972
4973static HChar *
4974s390_irgen_X(UChar r1, IRTemp op2addr)
4975{
4976 IRTemp op1 = newTemp(Ity_I32);
4977 IRTemp op2 = newTemp(Ity_I32);
4978 IRTemp result = newTemp(Ity_I32);
4979
4980 assign(op1, get_gpr_w1(r1));
4981 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4982 assign(result, binop(Iop_Xor32, mkexpr(op1), mkexpr(op2)));
4983 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4984 put_gpr_w1(r1, mkexpr(result));
4985
4986 return "x";
4987}
4988
4989static HChar *
4990s390_irgen_XY(UChar r1, IRTemp op2addr)
4991{
4992 IRTemp op1 = newTemp(Ity_I32);
4993 IRTemp op2 = newTemp(Ity_I32);
4994 IRTemp result = newTemp(Ity_I32);
4995
4996 assign(op1, get_gpr_w1(r1));
4997 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4998 assign(result, binop(Iop_Xor32, mkexpr(op1), mkexpr(op2)));
4999 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5000 put_gpr_w1(r1, mkexpr(result));
5001
5002 return "xy";
5003}
5004
5005static HChar *
5006s390_irgen_XG(UChar r1, IRTemp op2addr)
5007{
5008 IRTemp op1 = newTemp(Ity_I64);
5009 IRTemp op2 = newTemp(Ity_I64);
5010 IRTemp result = newTemp(Ity_I64);
5011
5012 assign(op1, get_gpr_dw0(r1));
5013 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5014 assign(result, binop(Iop_Xor64, mkexpr(op1), mkexpr(op2)));
5015 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5016 put_gpr_dw0(r1, mkexpr(result));
5017
5018 return "xg";
5019}
5020
5021static HChar *
5022s390_irgen_XI(UChar i2, IRTemp op1addr)
5023{
5024 IRTemp op1 = newTemp(Ity_I8);
5025 UChar op2;
5026 IRTemp result = newTemp(Ity_I8);
5027
5028 assign(op1, load(Ity_I8, mkexpr(op1addr)));
5029 op2 = i2;
5030 assign(result, binop(Iop_Xor8, mkexpr(op1), mkU8(op2)));
5031 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5032 store(mkexpr(op1addr), mkexpr(result));
5033
5034 return "xi";
5035}
5036
5037static HChar *
5038s390_irgen_XIY(UChar i2, IRTemp op1addr)
5039{
5040 IRTemp op1 = newTemp(Ity_I8);
5041 UChar op2;
5042 IRTemp result = newTemp(Ity_I8);
5043
5044 assign(op1, load(Ity_I8, mkexpr(op1addr)));
5045 op2 = i2;
5046 assign(result, binop(Iop_Xor8, mkexpr(op1), mkU8(op2)));
5047 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5048 store(mkexpr(op1addr), mkexpr(result));
5049
5050 return "xiy";
5051}
5052
5053static HChar *
5054s390_irgen_XIHF(UChar r1, UInt i2)
5055{
5056 IRTemp op1 = newTemp(Ity_I32);
5057 UInt op2;
5058 IRTemp result = newTemp(Ity_I32);
5059
5060 assign(op1, get_gpr_w0(r1));
5061 op2 = i2;
5062 assign(result, binop(Iop_Xor32, mkexpr(op1), mkU32(op2)));
5063 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5064 put_gpr_w0(r1, mkexpr(result));
5065
5066 return "xihf";
5067}
5068
5069static HChar *
5070s390_irgen_XILF(UChar r1, UInt i2)
5071{
5072 IRTemp op1 = newTemp(Ity_I32);
5073 UInt op2;
5074 IRTemp result = newTemp(Ity_I32);
5075
5076 assign(op1, get_gpr_w1(r1));
5077 op2 = i2;
5078 assign(result, binop(Iop_Xor32, mkexpr(op1), mkU32(op2)));
5079 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5080 put_gpr_w1(r1, mkexpr(result));
5081
5082 return "xilf";
5083}
5084
5085static HChar *
5086s390_irgen_EAR(UChar r1, UChar r2)
5087{
5088 put_gpr_w1(r1, get_ar_w0(r2));
sewardj7ee97522011-05-09 21:45:04 +00005089 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00005090 s390_disasm(ENC3(MNM, GPR, AR), "ear", r1, r2);
5091
5092 return "ear";
5093}
5094
5095static HChar *
5096s390_irgen_IC(UChar r1, IRTemp op2addr)
5097{
5098 put_gpr_b7(r1, load(Ity_I8, mkexpr(op2addr)));
5099
5100 return "ic";
5101}
5102
5103static HChar *
5104s390_irgen_ICY(UChar r1, IRTemp op2addr)
5105{
5106 put_gpr_b7(r1, load(Ity_I8, mkexpr(op2addr)));
5107
5108 return "icy";
5109}
5110
5111static HChar *
5112s390_irgen_ICM(UChar r1, UChar r3, IRTemp op2addr)
5113{
5114 UChar n;
5115 IRTemp result = newTemp(Ity_I32);
5116 UInt mask;
5117
5118 n = 0;
5119 mask = (UInt)r3;
5120 if ((mask & 8) != 0) {
5121 put_gpr_b4(r1, load(Ity_I8, mkexpr(op2addr)));
5122 n = n + 1;
5123 }
5124 if ((mask & 4) != 0) {
5125 put_gpr_b5(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5126
5127 n = n + 1;
5128 }
5129 if ((mask & 2) != 0) {
5130 put_gpr_b6(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5131
5132 n = n + 1;
5133 }
5134 if ((mask & 1) != 0) {
5135 put_gpr_b7(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5136
5137 n = n + 1;
5138 }
5139 assign(result, get_gpr_w1(r1));
5140 s390_cc_thunk_putZZ(S390_CC_OP_INSERT_CHAR_MASK_32, result, mktemp(Ity_I32,
5141 mkU32(mask)));
5142
5143 return "icm";
5144}
5145
5146static HChar *
5147s390_irgen_ICMY(UChar r1, UChar r3, IRTemp op2addr)
5148{
5149 UChar n;
5150 IRTemp result = newTemp(Ity_I32);
5151 UInt mask;
5152
5153 n = 0;
5154 mask = (UInt)r3;
5155 if ((mask & 8) != 0) {
5156 put_gpr_b4(r1, load(Ity_I8, mkexpr(op2addr)));
5157 n = n + 1;
5158 }
5159 if ((mask & 4) != 0) {
5160 put_gpr_b5(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5161
5162 n = n + 1;
5163 }
5164 if ((mask & 2) != 0) {
5165 put_gpr_b6(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5166
5167 n = n + 1;
5168 }
5169 if ((mask & 1) != 0) {
5170 put_gpr_b7(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5171
5172 n = n + 1;
5173 }
5174 assign(result, get_gpr_w1(r1));
5175 s390_cc_thunk_putZZ(S390_CC_OP_INSERT_CHAR_MASK_32, result, mktemp(Ity_I32,
5176 mkU32(mask)));
5177
5178 return "icmy";
5179}
5180
5181static HChar *
5182s390_irgen_ICMH(UChar r1, UChar r3, IRTemp op2addr)
5183{
5184 UChar n;
5185 IRTemp result = newTemp(Ity_I32);
5186 UInt mask;
5187
5188 n = 0;
5189 mask = (UInt)r3;
5190 if ((mask & 8) != 0) {
5191 put_gpr_b0(r1, load(Ity_I8, mkexpr(op2addr)));
5192 n = n + 1;
5193 }
5194 if ((mask & 4) != 0) {
5195 put_gpr_b1(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5196
5197 n = n + 1;
5198 }
5199 if ((mask & 2) != 0) {
5200 put_gpr_b2(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5201
5202 n = n + 1;
5203 }
5204 if ((mask & 1) != 0) {
5205 put_gpr_b3(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5206
5207 n = n + 1;
5208 }
5209 assign(result, get_gpr_w0(r1));
5210 s390_cc_thunk_putZZ(S390_CC_OP_INSERT_CHAR_MASK_32, result, mktemp(Ity_I32,
5211 mkU32(mask)));
5212
5213 return "icmh";
5214}
5215
5216static HChar *
5217s390_irgen_IIHF(UChar r1, UInt i2)
5218{
5219 put_gpr_w0(r1, mkU32(i2));
5220
5221 return "iihf";
5222}
5223
5224static HChar *
5225s390_irgen_IIHH(UChar r1, UShort i2)
5226{
5227 put_gpr_hw0(r1, mkU16(i2));
5228
5229 return "iihh";
5230}
5231
5232static HChar *
5233s390_irgen_IIHL(UChar r1, UShort i2)
5234{
5235 put_gpr_hw1(r1, mkU16(i2));
5236
5237 return "iihl";
5238}
5239
5240static HChar *
5241s390_irgen_IILF(UChar r1, UInt i2)
5242{
5243 put_gpr_w1(r1, mkU32(i2));
5244
5245 return "iilf";
5246}
5247
5248static HChar *
5249s390_irgen_IILH(UChar r1, UShort i2)
5250{
5251 put_gpr_hw2(r1, mkU16(i2));
5252
5253 return "iilh";
5254}
5255
5256static HChar *
5257s390_irgen_IILL(UChar r1, UShort i2)
5258{
5259 put_gpr_hw3(r1, mkU16(i2));
5260
5261 return "iill";
5262}
5263
5264static HChar *
5265s390_irgen_LR(UChar r1, UChar r2)
5266{
5267 put_gpr_w1(r1, get_gpr_w1(r2));
5268
5269 return "lr";
5270}
5271
5272static HChar *
5273s390_irgen_LGR(UChar r1, UChar r2)
5274{
5275 put_gpr_dw0(r1, get_gpr_dw0(r2));
5276
5277 return "lgr";
5278}
5279
5280static HChar *
5281s390_irgen_LGFR(UChar r1, UChar r2)
5282{
5283 put_gpr_dw0(r1, unop(Iop_32Sto64, get_gpr_w1(r2)));
5284
5285 return "lgfr";
5286}
5287
5288static HChar *
5289s390_irgen_L(UChar r1, IRTemp op2addr)
5290{
5291 put_gpr_w1(r1, load(Ity_I32, mkexpr(op2addr)));
5292
5293 return "l";
5294}
5295
5296static HChar *
5297s390_irgen_LY(UChar r1, IRTemp op2addr)
5298{
5299 put_gpr_w1(r1, load(Ity_I32, mkexpr(op2addr)));
5300
5301 return "ly";
5302}
5303
5304static HChar *
5305s390_irgen_LG(UChar r1, IRTemp op2addr)
5306{
5307 put_gpr_dw0(r1, load(Ity_I64, mkexpr(op2addr)));
5308
5309 return "lg";
5310}
5311
5312static HChar *
5313s390_irgen_LGF(UChar r1, IRTemp op2addr)
5314{
5315 put_gpr_dw0(r1, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
5316
5317 return "lgf";
5318}
5319
5320static HChar *
5321s390_irgen_LGFI(UChar r1, UInt i2)
5322{
5323 put_gpr_dw0(r1, mkU64((ULong)(Long)(Int)i2));
5324
5325 return "lgfi";
5326}
5327
5328static HChar *
5329s390_irgen_LRL(UChar r1, UInt i2)
5330{
5331 put_gpr_w1(r1, load(Ity_I32, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
5332 i2 << 1))));
5333
5334 return "lrl";
5335}
5336
5337static HChar *
5338s390_irgen_LGRL(UChar r1, UInt i2)
5339{
5340 put_gpr_dw0(r1, load(Ity_I64, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
5341 i2 << 1))));
5342
5343 return "lgrl";
5344}
5345
5346static HChar *
5347s390_irgen_LGFRL(UChar r1, UInt i2)
5348{
5349 put_gpr_dw0(r1, unop(Iop_32Sto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
5350 ((ULong)(Long)(Int)i2 << 1)))));
5351
5352 return "lgfrl";
5353}
5354
5355static HChar *
5356s390_irgen_LA(UChar r1, IRTemp op2addr)
5357{
5358 put_gpr_dw0(r1, mkexpr(op2addr));
5359
5360 return "la";
5361}
5362
5363static HChar *
5364s390_irgen_LAY(UChar r1, IRTemp op2addr)
5365{
5366 put_gpr_dw0(r1, mkexpr(op2addr));
5367
5368 return "lay";
5369}
5370
5371static HChar *
5372s390_irgen_LAE(UChar r1, IRTemp op2addr)
5373{
5374 put_gpr_dw0(r1, mkexpr(op2addr));
5375
5376 return "lae";
5377}
5378
5379static HChar *
5380s390_irgen_LAEY(UChar r1, IRTemp op2addr)
5381{
5382 put_gpr_dw0(r1, mkexpr(op2addr));
5383
5384 return "laey";
5385}
5386
5387static HChar *
5388s390_irgen_LARL(UChar r1, UInt i2)
5389{
5390 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)));
5391
5392 return "larl";
5393}
5394
5395static HChar *
5396s390_irgen_LAA(UChar r1, UChar r3, IRTemp op2addr)
5397{
5398 IRTemp op2 = newTemp(Ity_I32);
5399 IRTemp op3 = newTemp(Ity_I32);
5400 IRTemp result = newTemp(Ity_I32);
5401
5402 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5403 assign(op3, get_gpr_w1(r3));
5404 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
5405 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
5406 store(mkexpr(op2addr), mkexpr(result));
5407 put_gpr_w1(r1, mkexpr(op2));
5408
5409 return "laa";
5410}
5411
5412static HChar *
5413s390_irgen_LAAG(UChar r1, UChar r3, IRTemp op2addr)
5414{
5415 IRTemp op2 = newTemp(Ity_I64);
5416 IRTemp op3 = newTemp(Ity_I64);
5417 IRTemp result = newTemp(Ity_I64);
5418
5419 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5420 assign(op3, get_gpr_dw0(r3));
5421 assign(result, binop(Iop_Add64, mkexpr(op2), mkexpr(op3)));
5422 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op2, op3);
5423 store(mkexpr(op2addr), mkexpr(result));
5424 put_gpr_dw0(r1, mkexpr(op2));
5425
5426 return "laag";
5427}
5428
5429static HChar *
5430s390_irgen_LAAL(UChar r1, UChar r3, IRTemp op2addr)
5431{
5432 IRTemp op2 = newTemp(Ity_I32);
5433 IRTemp op3 = newTemp(Ity_I32);
5434 IRTemp result = newTemp(Ity_I32);
5435
5436 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5437 assign(op3, get_gpr_w1(r3));
5438 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
5439 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
5440 store(mkexpr(op2addr), mkexpr(result));
5441 put_gpr_w1(r1, mkexpr(op2));
5442
5443 return "laal";
5444}
5445
5446static HChar *
5447s390_irgen_LAALG(UChar r1, UChar r3, IRTemp op2addr)
5448{
5449 IRTemp op2 = newTemp(Ity_I64);
5450 IRTemp op3 = newTemp(Ity_I64);
5451 IRTemp result = newTemp(Ity_I64);
5452
5453 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5454 assign(op3, get_gpr_dw0(r3));
5455 assign(result, binop(Iop_Add64, mkexpr(op2), mkexpr(op3)));
5456 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op2, op3);
5457 store(mkexpr(op2addr), mkexpr(result));
5458 put_gpr_dw0(r1, mkexpr(op2));
5459
5460 return "laalg";
5461}
5462
5463static HChar *
5464s390_irgen_LAN(UChar r1, UChar r3, IRTemp op2addr)
5465{
5466 IRTemp op2 = newTemp(Ity_I32);
5467 IRTemp op3 = newTemp(Ity_I32);
5468 IRTemp result = newTemp(Ity_I32);
5469
5470 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5471 assign(op3, get_gpr_w1(r3));
5472 assign(result, binop(Iop_And32, mkexpr(op2), mkexpr(op3)));
5473 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5474 store(mkexpr(op2addr), mkexpr(result));
5475 put_gpr_w1(r1, mkexpr(op2));
5476
5477 return "lan";
5478}
5479
5480static HChar *
5481s390_irgen_LANG(UChar r1, UChar r3, IRTemp op2addr)
5482{
5483 IRTemp op2 = newTemp(Ity_I64);
5484 IRTemp op3 = newTemp(Ity_I64);
5485 IRTemp result = newTemp(Ity_I64);
5486
5487 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5488 assign(op3, get_gpr_dw0(r3));
5489 assign(result, binop(Iop_And64, mkexpr(op2), mkexpr(op3)));
5490 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5491 store(mkexpr(op2addr), mkexpr(result));
5492 put_gpr_dw0(r1, mkexpr(op2));
5493
5494 return "lang";
5495}
5496
5497static HChar *
5498s390_irgen_LAX(UChar r1, UChar r3, IRTemp op2addr)
5499{
5500 IRTemp op2 = newTemp(Ity_I32);
5501 IRTemp op3 = newTemp(Ity_I32);
5502 IRTemp result = newTemp(Ity_I32);
5503
5504 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5505 assign(op3, get_gpr_w1(r3));
5506 assign(result, binop(Iop_Xor32, mkexpr(op2), mkexpr(op3)));
5507 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5508 store(mkexpr(op2addr), mkexpr(result));
5509 put_gpr_w1(r1, mkexpr(op2));
5510
5511 return "lax";
5512}
5513
5514static HChar *
5515s390_irgen_LAXG(UChar r1, UChar r3, IRTemp op2addr)
5516{
5517 IRTemp op2 = newTemp(Ity_I64);
5518 IRTemp op3 = newTemp(Ity_I64);
5519 IRTemp result = newTemp(Ity_I64);
5520
5521 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5522 assign(op3, get_gpr_dw0(r3));
5523 assign(result, binop(Iop_Xor64, mkexpr(op2), mkexpr(op3)));
5524 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5525 store(mkexpr(op2addr), mkexpr(result));
5526 put_gpr_dw0(r1, mkexpr(op2));
5527
5528 return "laxg";
5529}
5530
5531static HChar *
5532s390_irgen_LAO(UChar r1, UChar r3, IRTemp op2addr)
5533{
5534 IRTemp op2 = newTemp(Ity_I32);
5535 IRTemp op3 = newTemp(Ity_I32);
5536 IRTemp result = newTemp(Ity_I32);
5537
5538 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5539 assign(op3, get_gpr_w1(r3));
5540 assign(result, binop(Iop_Or32, mkexpr(op2), mkexpr(op3)));
5541 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5542 store(mkexpr(op2addr), mkexpr(result));
5543 put_gpr_w1(r1, mkexpr(op2));
5544
5545 return "lao";
5546}
5547
5548static HChar *
5549s390_irgen_LAOG(UChar r1, UChar r3, IRTemp op2addr)
5550{
5551 IRTemp op2 = newTemp(Ity_I64);
5552 IRTemp op3 = newTemp(Ity_I64);
5553 IRTemp result = newTemp(Ity_I64);
5554
5555 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5556 assign(op3, get_gpr_dw0(r3));
5557 assign(result, binop(Iop_Or64, mkexpr(op2), mkexpr(op3)));
5558 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5559 store(mkexpr(op2addr), mkexpr(result));
5560 put_gpr_dw0(r1, mkexpr(op2));
5561
5562 return "laog";
5563}
5564
5565static HChar *
5566s390_irgen_LTR(UChar r1, UChar r2)
5567{
5568 IRTemp op2 = newTemp(Ity_I32);
5569
5570 assign(op2, get_gpr_w1(r2));
5571 put_gpr_w1(r1, mkexpr(op2));
5572 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5573
5574 return "ltr";
5575}
5576
5577static HChar *
5578s390_irgen_LTGR(UChar r1, UChar r2)
5579{
5580 IRTemp op2 = newTemp(Ity_I64);
5581
5582 assign(op2, get_gpr_dw0(r2));
5583 put_gpr_dw0(r1, mkexpr(op2));
5584 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5585
5586 return "ltgr";
5587}
5588
5589static HChar *
5590s390_irgen_LTGFR(UChar r1, UChar r2)
5591{
5592 IRTemp op2 = newTemp(Ity_I64);
5593
5594 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
5595 put_gpr_dw0(r1, mkexpr(op2));
5596 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5597
5598 return "ltgfr";
5599}
5600
5601static HChar *
5602s390_irgen_LT(UChar r1, IRTemp op2addr)
5603{
5604 IRTemp op2 = newTemp(Ity_I32);
5605
5606 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5607 put_gpr_w1(r1, mkexpr(op2));
5608 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5609
5610 return "lt";
5611}
5612
5613static HChar *
5614s390_irgen_LTG(UChar r1, IRTemp op2addr)
5615{
5616 IRTemp op2 = newTemp(Ity_I64);
5617
5618 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5619 put_gpr_dw0(r1, mkexpr(op2));
5620 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5621
5622 return "ltg";
5623}
5624
5625static HChar *
5626s390_irgen_LTGF(UChar r1, IRTemp op2addr)
5627{
5628 IRTemp op2 = newTemp(Ity_I64);
5629
5630 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
5631 put_gpr_dw0(r1, mkexpr(op2));
5632 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5633
5634 return "ltgf";
5635}
5636
5637static HChar *
5638s390_irgen_LBR(UChar r1, UChar r2)
5639{
5640 put_gpr_w1(r1, unop(Iop_8Sto32, get_gpr_b7(r2)));
5641
5642 return "lbr";
5643}
5644
5645static HChar *
5646s390_irgen_LGBR(UChar r1, UChar r2)
5647{
5648 put_gpr_dw0(r1, unop(Iop_8Sto64, get_gpr_b7(r2)));
5649
5650 return "lgbr";
5651}
5652
5653static HChar *
5654s390_irgen_LB(UChar r1, IRTemp op2addr)
5655{
5656 put_gpr_w1(r1, unop(Iop_8Sto32, load(Ity_I8, mkexpr(op2addr))));
5657
5658 return "lb";
5659}
5660
5661static HChar *
5662s390_irgen_LGB(UChar r1, IRTemp op2addr)
5663{
5664 put_gpr_dw0(r1, unop(Iop_8Sto64, load(Ity_I8, mkexpr(op2addr))));
5665
5666 return "lgb";
5667}
5668
5669static HChar *
5670s390_irgen_LBH(UChar r1, IRTemp op2addr)
5671{
5672 put_gpr_w0(r1, unop(Iop_8Sto32, load(Ity_I8, mkexpr(op2addr))));
5673
5674 return "lbh";
5675}
5676
5677static HChar *
5678s390_irgen_LCR(UChar r1, UChar r2)
5679{
5680 Int op1;
5681 IRTemp op2 = newTemp(Ity_I32);
5682 IRTemp result = newTemp(Ity_I32);
5683
5684 op1 = 0;
5685 assign(op2, get_gpr_w1(r2));
5686 assign(result, binop(Iop_Sub32, mkU32((UInt)op1), mkexpr(op2)));
5687 put_gpr_w1(r1, mkexpr(result));
5688 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, mktemp(Ity_I32, mkU32((UInt)
5689 op1)), op2);
5690
5691 return "lcr";
5692}
5693
5694static HChar *
5695s390_irgen_LCGR(UChar r1, UChar r2)
5696{
5697 Long op1;
5698 IRTemp op2 = newTemp(Ity_I64);
5699 IRTemp result = newTemp(Ity_I64);
5700
5701 op1 = 0ULL;
5702 assign(op2, get_gpr_dw0(r2));
5703 assign(result, binop(Iop_Sub64, mkU64((ULong)op1), mkexpr(op2)));
5704 put_gpr_dw0(r1, mkexpr(result));
5705 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, mktemp(Ity_I64, mkU64((ULong)
5706 op1)), op2);
5707
5708 return "lcgr";
5709}
5710
5711static HChar *
5712s390_irgen_LCGFR(UChar r1, UChar r2)
5713{
5714 Long op1;
5715 IRTemp op2 = newTemp(Ity_I64);
5716 IRTemp result = newTemp(Ity_I64);
5717
5718 op1 = 0ULL;
5719 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
5720 assign(result, binop(Iop_Sub64, mkU64((ULong)op1), mkexpr(op2)));
5721 put_gpr_dw0(r1, mkexpr(result));
5722 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, mktemp(Ity_I64, mkU64((ULong)
5723 op1)), op2);
5724
5725 return "lcgfr";
5726}
5727
5728static HChar *
5729s390_irgen_LHR(UChar r1, UChar r2)
5730{
5731 put_gpr_w1(r1, unop(Iop_16Sto32, get_gpr_hw3(r2)));
5732
5733 return "lhr";
5734}
5735
5736static HChar *
5737s390_irgen_LGHR(UChar r1, UChar r2)
5738{
5739 put_gpr_dw0(r1, unop(Iop_16Sto64, get_gpr_hw3(r2)));
5740
5741 return "lghr";
5742}
5743
5744static HChar *
5745s390_irgen_LH(UChar r1, IRTemp op2addr)
5746{
5747 put_gpr_w1(r1, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
5748
5749 return "lh";
5750}
5751
5752static HChar *
5753s390_irgen_LHY(UChar r1, IRTemp op2addr)
5754{
5755 put_gpr_w1(r1, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
5756
5757 return "lhy";
5758}
5759
5760static HChar *
5761s390_irgen_LGH(UChar r1, IRTemp op2addr)
5762{
5763 put_gpr_dw0(r1, unop(Iop_16Sto64, load(Ity_I16, mkexpr(op2addr))));
5764
5765 return "lgh";
5766}
5767
5768static HChar *
5769s390_irgen_LHI(UChar r1, UShort i2)
5770{
5771 put_gpr_w1(r1, mkU32((UInt)(Int)(Short)i2));
5772
5773 return "lhi";
5774}
5775
5776static HChar *
5777s390_irgen_LGHI(UChar r1, UShort i2)
5778{
5779 put_gpr_dw0(r1, mkU64((ULong)(Long)(Short)i2));
5780
5781 return "lghi";
5782}
5783
5784static HChar *
5785s390_irgen_LHRL(UChar r1, UInt i2)
5786{
5787 put_gpr_w1(r1, unop(Iop_16Sto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
5788 ((ULong)(Long)(Int)i2 << 1)))));
5789
5790 return "lhrl";
5791}
5792
5793static HChar *
5794s390_irgen_LGHRL(UChar r1, UInt i2)
5795{
5796 put_gpr_dw0(r1, unop(Iop_16Sto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
5797 ((ULong)(Long)(Int)i2 << 1)))));
5798
5799 return "lghrl";
5800}
5801
5802static HChar *
5803s390_irgen_LHH(UChar r1, IRTemp op2addr)
5804{
5805 put_gpr_w0(r1, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
5806
5807 return "lhh";
5808}
5809
5810static HChar *
5811s390_irgen_LFH(UChar r1, IRTemp op2addr)
5812{
5813 put_gpr_w0(r1, load(Ity_I32, mkexpr(op2addr)));
5814
5815 return "lfh";
5816}
5817
5818static HChar *
5819s390_irgen_LLGFR(UChar r1, UChar r2)
5820{
5821 put_gpr_dw0(r1, unop(Iop_32Uto64, get_gpr_w1(r2)));
5822
5823 return "llgfr";
5824}
5825
5826static HChar *
5827s390_irgen_LLGF(UChar r1, IRTemp op2addr)
5828{
5829 put_gpr_dw0(r1, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
5830
5831 return "llgf";
5832}
5833
5834static HChar *
5835s390_irgen_LLGFRL(UChar r1, UInt i2)
5836{
5837 put_gpr_dw0(r1, unop(Iop_32Uto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
5838 ((ULong)(Long)(Int)i2 << 1)))));
5839
5840 return "llgfrl";
5841}
5842
5843static HChar *
5844s390_irgen_LLCR(UChar r1, UChar r2)
5845{
5846 put_gpr_w1(r1, unop(Iop_8Uto32, get_gpr_b7(r2)));
5847
5848 return "llcr";
5849}
5850
5851static HChar *
5852s390_irgen_LLGCR(UChar r1, UChar r2)
5853{
5854 put_gpr_dw0(r1, unop(Iop_8Uto64, get_gpr_b7(r2)));
5855
5856 return "llgcr";
5857}
5858
5859static HChar *
5860s390_irgen_LLC(UChar r1, IRTemp op2addr)
5861{
5862 put_gpr_w1(r1, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
5863
5864 return "llc";
5865}
5866
5867static HChar *
5868s390_irgen_LLGC(UChar r1, IRTemp op2addr)
5869{
5870 put_gpr_dw0(r1, unop(Iop_8Uto64, load(Ity_I8, mkexpr(op2addr))));
5871
5872 return "llgc";
5873}
5874
5875static HChar *
5876s390_irgen_LLCH(UChar r1, IRTemp op2addr)
5877{
5878 put_gpr_w0(r1, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
5879
5880 return "llch";
5881}
5882
5883static HChar *
5884s390_irgen_LLHR(UChar r1, UChar r2)
5885{
5886 put_gpr_w1(r1, unop(Iop_16Uto32, get_gpr_hw3(r2)));
5887
5888 return "llhr";
5889}
5890
5891static HChar *
5892s390_irgen_LLGHR(UChar r1, UChar r2)
5893{
5894 put_gpr_dw0(r1, unop(Iop_16Uto64, get_gpr_hw3(r2)));
5895
5896 return "llghr";
5897}
5898
5899static HChar *
5900s390_irgen_LLH(UChar r1, IRTemp op2addr)
5901{
5902 put_gpr_w1(r1, unop(Iop_16Uto32, load(Ity_I16, mkexpr(op2addr))));
5903
5904 return "llh";
5905}
5906
5907static HChar *
5908s390_irgen_LLGH(UChar r1, IRTemp op2addr)
5909{
5910 put_gpr_dw0(r1, unop(Iop_16Uto64, load(Ity_I16, mkexpr(op2addr))));
5911
5912 return "llgh";
5913}
5914
5915static HChar *
5916s390_irgen_LLHRL(UChar r1, UInt i2)
5917{
5918 put_gpr_w1(r1, unop(Iop_16Uto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
5919 ((ULong)(Long)(Int)i2 << 1)))));
5920
5921 return "llhrl";
5922}
5923
5924static HChar *
5925s390_irgen_LLGHRL(UChar r1, UInt i2)
5926{
5927 put_gpr_dw0(r1, unop(Iop_16Uto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
5928 ((ULong)(Long)(Int)i2 << 1)))));
5929
5930 return "llghrl";
5931}
5932
5933static HChar *
5934s390_irgen_LLHH(UChar r1, IRTemp op2addr)
5935{
5936 put_gpr_w0(r1, unop(Iop_16Uto32, load(Ity_I16, mkexpr(op2addr))));
5937
5938 return "llhh";
5939}
5940
5941static HChar *
5942s390_irgen_LLIHF(UChar r1, UInt i2)
5943{
5944 put_gpr_dw0(r1, mkU64(((ULong)i2) << 32));
5945
5946 return "llihf";
5947}
5948
5949static HChar *
5950s390_irgen_LLIHH(UChar r1, UShort i2)
5951{
5952 put_gpr_dw0(r1, mkU64(((ULong)i2) << 48));
5953
5954 return "llihh";
5955}
5956
5957static HChar *
5958s390_irgen_LLIHL(UChar r1, UShort i2)
5959{
5960 put_gpr_dw0(r1, mkU64(((ULong)i2) << 32));
5961
5962 return "llihl";
5963}
5964
5965static HChar *
5966s390_irgen_LLILF(UChar r1, UInt i2)
5967{
5968 put_gpr_dw0(r1, mkU64(i2));
5969
5970 return "llilf";
5971}
5972
5973static HChar *
5974s390_irgen_LLILH(UChar r1, UShort i2)
5975{
5976 put_gpr_dw0(r1, mkU64(((ULong)i2) << 16));
5977
5978 return "llilh";
5979}
5980
5981static HChar *
5982s390_irgen_LLILL(UChar r1, UShort i2)
5983{
5984 put_gpr_dw0(r1, mkU64(i2));
5985
5986 return "llill";
5987}
5988
5989static HChar *
5990s390_irgen_LLGTR(UChar r1, UChar r2)
5991{
5992 put_gpr_dw0(r1, unop(Iop_32Uto64, binop(Iop_And32, get_gpr_w1(r2),
5993 mkU32(2147483647))));
5994
5995 return "llgtr";
5996}
5997
5998static HChar *
5999s390_irgen_LLGT(UChar r1, IRTemp op2addr)
6000{
6001 put_gpr_dw0(r1, unop(Iop_32Uto64, binop(Iop_And32, load(Ity_I32,
6002 mkexpr(op2addr)), mkU32(2147483647))));
6003
6004 return "llgt";
6005}
6006
6007static HChar *
6008s390_irgen_LNR(UChar r1, UChar r2)
6009{
6010 IRTemp op2 = newTemp(Ity_I32);
6011 IRTemp result = newTemp(Ity_I32);
6012
6013 assign(op2, get_gpr_w1(r2));
6014 assign(result, mkite(binop(Iop_CmpLE32S, mkexpr(op2), mkU32(0)), mkexpr(op2),
6015 binop(Iop_Sub32, mkU32(0), mkexpr(op2))));
6016 put_gpr_w1(r1, mkexpr(result));
6017 s390_cc_thunk_putS(S390_CC_OP_BITWISE, result);
6018
6019 return "lnr";
6020}
6021
6022static HChar *
6023s390_irgen_LNGR(UChar r1, UChar r2)
6024{
6025 IRTemp op2 = newTemp(Ity_I64);
6026 IRTemp result = newTemp(Ity_I64);
6027
6028 assign(op2, get_gpr_dw0(r2));
6029 assign(result, mkite(binop(Iop_CmpLE64S, mkexpr(op2), mkU64(0)), mkexpr(op2),
6030 binop(Iop_Sub64, mkU64(0), mkexpr(op2))));
6031 put_gpr_dw0(r1, mkexpr(result));
6032 s390_cc_thunk_putS(S390_CC_OP_BITWISE, result);
6033
6034 return "lngr";
6035}
6036
6037static HChar *
6038s390_irgen_LNGFR(UChar r1, UChar r2 __attribute__((unused)))
6039{
6040 IRTemp op2 = newTemp(Ity_I64);
6041 IRTemp result = newTemp(Ity_I64);
6042
6043 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r1)));
6044 assign(result, mkite(binop(Iop_CmpLE64S, mkexpr(op2), mkU64(0)), mkexpr(op2),
6045 binop(Iop_Sub64, mkU64(0), mkexpr(op2))));
6046 put_gpr_dw0(r1, mkexpr(result));
6047 s390_cc_thunk_putS(S390_CC_OP_BITWISE, result);
6048
6049 return "lngfr";
6050}
6051
6052static HChar *
sewardjd7bde722011-04-05 13:19:33 +00006053s390_irgen_LOCR(UChar m3, UChar r1, UChar r2)
6054{
florian6820ba52012-07-26 02:01:50 +00006055 next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0)));
sewardjd7bde722011-04-05 13:19:33 +00006056 put_gpr_w1(r1, get_gpr_w1(r2));
6057
6058 return "locr";
6059}
6060
6061static HChar *
6062s390_irgen_LOCGR(UChar m3, UChar r1, UChar r2)
6063{
florian6820ba52012-07-26 02:01:50 +00006064 next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0)));
sewardjd7bde722011-04-05 13:19:33 +00006065 put_gpr_dw0(r1, get_gpr_dw0(r2));
6066
6067 return "locgr";
6068}
6069
6070static HChar *
6071s390_irgen_LOC(UChar r1, IRTemp op2addr)
6072{
6073 /* condition is checked in format handler */
6074 put_gpr_w1(r1, load(Ity_I32, mkexpr(op2addr)));
6075
6076 return "loc";
6077}
6078
6079static HChar *
6080s390_irgen_LOCG(UChar r1, IRTemp op2addr)
6081{
6082 /* condition is checked in format handler */
6083 put_gpr_dw0(r1, load(Ity_I64, mkexpr(op2addr)));
6084
6085 return "locg";
6086}
6087
6088static HChar *
sewardj2019a972011-03-07 16:04:07 +00006089s390_irgen_LPQ(UChar r1, IRTemp op2addr)
6090{
6091 put_gpr_dw0(r1, load(Ity_I64, mkexpr(op2addr)));
6092 put_gpr_dw0(r1 + 1, load(Ity_I64, binop(Iop_Add64, mkexpr(op2addr), mkU64(8))
6093 ));
6094
6095 return "lpq";
6096}
6097
6098static HChar *
6099s390_irgen_LPR(UChar r1, UChar r2)
6100{
6101 IRTemp op2 = newTemp(Ity_I32);
6102 IRTemp result = newTemp(Ity_I32);
6103
6104 assign(op2, get_gpr_w1(r2));
6105 assign(result, mkite(binop(Iop_CmpLT32S, mkexpr(op2), mkU32(0)),
6106 binop(Iop_Sub32, mkU32(0), mkexpr(op2)), mkexpr(op2)));
6107 put_gpr_w1(r1, mkexpr(result));
6108 s390_cc_thunk_putS(S390_CC_OP_LOAD_POSITIVE_32, op2);
6109
6110 return "lpr";
6111}
6112
6113static HChar *
6114s390_irgen_LPGR(UChar r1, UChar r2)
6115{
6116 IRTemp op2 = newTemp(Ity_I64);
6117 IRTemp result = newTemp(Ity_I64);
6118
6119 assign(op2, get_gpr_dw0(r2));
6120 assign(result, mkite(binop(Iop_CmpLT64S, mkexpr(op2), mkU64(0)),
6121 binop(Iop_Sub64, mkU64(0), mkexpr(op2)), mkexpr(op2)));
6122 put_gpr_dw0(r1, mkexpr(result));
6123 s390_cc_thunk_putS(S390_CC_OP_LOAD_POSITIVE_64, op2);
6124
6125 return "lpgr";
6126}
6127
6128static HChar *
6129s390_irgen_LPGFR(UChar r1, UChar r2)
6130{
6131 IRTemp op2 = newTemp(Ity_I64);
6132 IRTemp result = newTemp(Ity_I64);
6133
6134 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
6135 assign(result, mkite(binop(Iop_CmpLT64S, mkexpr(op2), mkU64(0)),
6136 binop(Iop_Sub64, mkU64(0), mkexpr(op2)), mkexpr(op2)));
6137 put_gpr_dw0(r1, mkexpr(result));
6138 s390_cc_thunk_putS(S390_CC_OP_LOAD_POSITIVE_64, op2);
6139
6140 return "lpgfr";
6141}
6142
6143static HChar *
6144s390_irgen_LRVR(UChar r1, UChar r2)
6145{
6146 IRTemp b0 = newTemp(Ity_I8);
6147 IRTemp b1 = newTemp(Ity_I8);
6148 IRTemp b2 = newTemp(Ity_I8);
6149 IRTemp b3 = newTemp(Ity_I8);
6150
6151 assign(b3, get_gpr_b7(r2));
6152 assign(b2, get_gpr_b6(r2));
6153 assign(b1, get_gpr_b5(r2));
6154 assign(b0, get_gpr_b4(r2));
6155 put_gpr_b4(r1, mkexpr(b3));
6156 put_gpr_b5(r1, mkexpr(b2));
6157 put_gpr_b6(r1, mkexpr(b1));
6158 put_gpr_b7(r1, mkexpr(b0));
6159
6160 return "lrvr";
6161}
6162
6163static HChar *
6164s390_irgen_LRVGR(UChar r1, UChar r2)
6165{
6166 IRTemp b0 = newTemp(Ity_I8);
6167 IRTemp b1 = newTemp(Ity_I8);
6168 IRTemp b2 = newTemp(Ity_I8);
6169 IRTemp b3 = newTemp(Ity_I8);
6170 IRTemp b4 = newTemp(Ity_I8);
6171 IRTemp b5 = newTemp(Ity_I8);
6172 IRTemp b6 = newTemp(Ity_I8);
6173 IRTemp b7 = newTemp(Ity_I8);
6174
6175 assign(b7, get_gpr_b7(r2));
6176 assign(b6, get_gpr_b6(r2));
6177 assign(b5, get_gpr_b5(r2));
6178 assign(b4, get_gpr_b4(r2));
6179 assign(b3, get_gpr_b3(r2));
6180 assign(b2, get_gpr_b2(r2));
6181 assign(b1, get_gpr_b1(r2));
6182 assign(b0, get_gpr_b0(r2));
6183 put_gpr_b0(r1, mkexpr(b7));
6184 put_gpr_b1(r1, mkexpr(b6));
6185 put_gpr_b2(r1, mkexpr(b5));
6186 put_gpr_b3(r1, mkexpr(b4));
6187 put_gpr_b4(r1, mkexpr(b3));
6188 put_gpr_b5(r1, mkexpr(b2));
6189 put_gpr_b6(r1, mkexpr(b1));
6190 put_gpr_b7(r1, mkexpr(b0));
6191
6192 return "lrvgr";
6193}
6194
6195static HChar *
6196s390_irgen_LRVH(UChar r1, IRTemp op2addr)
6197{
6198 IRTemp op2 = newTemp(Ity_I16);
6199
6200 assign(op2, load(Ity_I16, mkexpr(op2addr)));
6201 put_gpr_b6(r1, unop(Iop_16to8, mkexpr(op2)));
6202 put_gpr_b7(r1, unop(Iop_16HIto8, mkexpr(op2)));
6203
6204 return "lrvh";
6205}
6206
6207static HChar *
6208s390_irgen_LRV(UChar r1, IRTemp op2addr)
6209{
6210 IRTemp op2 = newTemp(Ity_I32);
6211
6212 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6213 put_gpr_b4(r1, unop(Iop_32to8, binop(Iop_And32, mkexpr(op2), mkU32(255))));
6214 put_gpr_b5(r1, unop(Iop_32to8, binop(Iop_And32, binop(Iop_Shr32, mkexpr(op2),
6215 mkU8(8)), mkU32(255))));
6216 put_gpr_b6(r1, unop(Iop_32to8, binop(Iop_And32, binop(Iop_Shr32, mkexpr(op2),
6217 mkU8(16)), mkU32(255))));
6218 put_gpr_b7(r1, unop(Iop_32to8, binop(Iop_And32, binop(Iop_Shr32, mkexpr(op2),
6219 mkU8(24)), mkU32(255))));
6220
6221 return "lrv";
6222}
6223
6224static HChar *
6225s390_irgen_LRVG(UChar r1, IRTemp op2addr)
6226{
6227 IRTemp op2 = newTemp(Ity_I64);
6228
6229 assign(op2, load(Ity_I64, mkexpr(op2addr)));
6230 put_gpr_b0(r1, unop(Iop_64to8, binop(Iop_And64, mkexpr(op2), mkU64(255))));
6231 put_gpr_b1(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6232 mkU8(8)), mkU64(255))));
6233 put_gpr_b2(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6234 mkU8(16)), mkU64(255))));
6235 put_gpr_b3(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6236 mkU8(24)), mkU64(255))));
6237 put_gpr_b4(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6238 mkU8(32)), mkU64(255))));
6239 put_gpr_b5(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6240 mkU8(40)), mkU64(255))));
6241 put_gpr_b6(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6242 mkU8(48)), mkU64(255))));
6243 put_gpr_b7(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6244 mkU8(56)), mkU64(255))));
6245
6246 return "lrvg";
6247}
6248
6249static HChar *
6250s390_irgen_MVHHI(UShort i2, IRTemp op1addr)
6251{
6252 store(mkexpr(op1addr), mkU16(i2));
6253
6254 return "mvhhi";
6255}
6256
6257static HChar *
6258s390_irgen_MVHI(UShort i2, IRTemp op1addr)
6259{
6260 store(mkexpr(op1addr), mkU32((UInt)(Int)(Short)i2));
6261
6262 return "mvhi";
6263}
6264
6265static HChar *
6266s390_irgen_MVGHI(UShort i2, IRTemp op1addr)
6267{
6268 store(mkexpr(op1addr), mkU64((ULong)(Long)(Short)i2));
6269
6270 return "mvghi";
6271}
6272
6273static HChar *
6274s390_irgen_MVI(UChar i2, IRTemp op1addr)
6275{
6276 store(mkexpr(op1addr), mkU8(i2));
6277
6278 return "mvi";
6279}
6280
6281static HChar *
6282s390_irgen_MVIY(UChar i2, IRTemp op1addr)
6283{
6284 store(mkexpr(op1addr), mkU8(i2));
6285
6286 return "mviy";
6287}
6288
6289static HChar *
6290s390_irgen_MR(UChar r1, UChar r2)
6291{
6292 IRTemp op1 = newTemp(Ity_I32);
6293 IRTemp op2 = newTemp(Ity_I32);
6294 IRTemp result = newTemp(Ity_I64);
6295
6296 assign(op1, get_gpr_w1(r1 + 1));
6297 assign(op2, get_gpr_w1(r2));
6298 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6299 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6300 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6301
6302 return "mr";
6303}
6304
6305static HChar *
6306s390_irgen_M(UChar r1, IRTemp op2addr)
6307{
6308 IRTemp op1 = newTemp(Ity_I32);
6309 IRTemp op2 = newTemp(Ity_I32);
6310 IRTemp result = newTemp(Ity_I64);
6311
6312 assign(op1, get_gpr_w1(r1 + 1));
6313 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6314 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6315 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6316 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6317
6318 return "m";
6319}
6320
6321static HChar *
6322s390_irgen_MFY(UChar r1, IRTemp op2addr)
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, load(Ity_I32, mkexpr(op2addr)));
6330 assign(result, binop(Iop_MullS32, 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 "mfy";
6335}
6336
6337static HChar *
6338s390_irgen_MH(UChar r1, IRTemp op2addr)
6339{
6340 IRTemp op1 = newTemp(Ity_I32);
6341 IRTemp op2 = newTemp(Ity_I16);
6342 IRTemp result = newTemp(Ity_I64);
6343
6344 assign(op1, get_gpr_w1(r1));
6345 assign(op2, load(Ity_I16, mkexpr(op2addr)));
6346 assign(result, binop(Iop_MullS32, mkexpr(op1), unop(Iop_16Sto32, mkexpr(op2))
6347 ));
6348 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6349
6350 return "mh";
6351}
6352
6353static HChar *
6354s390_irgen_MHY(UChar r1, IRTemp op2addr)
6355{
6356 IRTemp op1 = newTemp(Ity_I32);
6357 IRTemp op2 = newTemp(Ity_I16);
6358 IRTemp result = newTemp(Ity_I64);
6359
6360 assign(op1, get_gpr_w1(r1));
6361 assign(op2, load(Ity_I16, mkexpr(op2addr)));
6362 assign(result, binop(Iop_MullS32, mkexpr(op1), unop(Iop_16Sto32, mkexpr(op2))
6363 ));
6364 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6365
6366 return "mhy";
6367}
6368
6369static HChar *
6370s390_irgen_MHI(UChar r1, UShort i2)
6371{
6372 IRTemp op1 = newTemp(Ity_I32);
6373 Short op2;
6374 IRTemp result = newTemp(Ity_I64);
6375
6376 assign(op1, get_gpr_w1(r1));
6377 op2 = (Short)i2;
6378 assign(result, binop(Iop_MullS32, mkexpr(op1), unop(Iop_16Sto32,
6379 mkU16((UShort)op2))));
6380 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6381
6382 return "mhi";
6383}
6384
6385static HChar *
6386s390_irgen_MGHI(UChar r1, UShort i2)
6387{
6388 IRTemp op1 = newTemp(Ity_I64);
6389 Short op2;
6390 IRTemp result = newTemp(Ity_I128);
6391
6392 assign(op1, get_gpr_dw0(r1));
6393 op2 = (Short)i2;
6394 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_16Sto64,
6395 mkU16((UShort)op2))));
6396 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6397
6398 return "mghi";
6399}
6400
6401static HChar *
6402s390_irgen_MLR(UChar r1, UChar r2)
6403{
6404 IRTemp op1 = newTemp(Ity_I32);
6405 IRTemp op2 = newTemp(Ity_I32);
6406 IRTemp result = newTemp(Ity_I64);
6407
6408 assign(op1, get_gpr_w1(r1 + 1));
6409 assign(op2, get_gpr_w1(r2));
6410 assign(result, binop(Iop_MullU32, mkexpr(op1), mkexpr(op2)));
6411 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6412 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6413
6414 return "mlr";
6415}
6416
6417static HChar *
6418s390_irgen_MLGR(UChar r1, UChar r2)
6419{
6420 IRTemp op1 = newTemp(Ity_I64);
6421 IRTemp op2 = newTemp(Ity_I64);
6422 IRTemp result = newTemp(Ity_I128);
6423
6424 assign(op1, get_gpr_dw0(r1 + 1));
6425 assign(op2, get_gpr_dw0(r2));
6426 assign(result, binop(Iop_MullU64, mkexpr(op1), mkexpr(op2)));
6427 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result)));
6428 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result)));
6429
6430 return "mlgr";
6431}
6432
6433static HChar *
6434s390_irgen_ML(UChar r1, IRTemp op2addr)
6435{
6436 IRTemp op1 = newTemp(Ity_I32);
6437 IRTemp op2 = newTemp(Ity_I32);
6438 IRTemp result = newTemp(Ity_I64);
6439
6440 assign(op1, get_gpr_w1(r1 + 1));
6441 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6442 assign(result, binop(Iop_MullU32, mkexpr(op1), mkexpr(op2)));
6443 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6444 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6445
6446 return "ml";
6447}
6448
6449static HChar *
6450s390_irgen_MLG(UChar r1, IRTemp op2addr)
6451{
6452 IRTemp op1 = newTemp(Ity_I64);
6453 IRTemp op2 = newTemp(Ity_I64);
6454 IRTemp result = newTemp(Ity_I128);
6455
6456 assign(op1, get_gpr_dw0(r1 + 1));
6457 assign(op2, load(Ity_I64, mkexpr(op2addr)));
6458 assign(result, binop(Iop_MullU64, mkexpr(op1), mkexpr(op2)));
6459 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result)));
6460 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result)));
6461
6462 return "mlg";
6463}
6464
6465static HChar *
6466s390_irgen_MSR(UChar r1, UChar r2)
6467{
6468 IRTemp op1 = newTemp(Ity_I32);
6469 IRTemp op2 = newTemp(Ity_I32);
6470 IRTemp result = newTemp(Ity_I64);
6471
6472 assign(op1, get_gpr_w1(r1));
6473 assign(op2, get_gpr_w1(r2));
6474 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6475 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6476
6477 return "msr";
6478}
6479
6480static HChar *
6481s390_irgen_MSGR(UChar r1, UChar r2)
6482{
6483 IRTemp op1 = newTemp(Ity_I64);
6484 IRTemp op2 = newTemp(Ity_I64);
6485 IRTemp result = newTemp(Ity_I128);
6486
6487 assign(op1, get_gpr_dw0(r1));
6488 assign(op2, get_gpr_dw0(r2));
6489 assign(result, binop(Iop_MullS64, mkexpr(op1), mkexpr(op2)));
6490 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6491
6492 return "msgr";
6493}
6494
6495static HChar *
6496s390_irgen_MSGFR(UChar r1, UChar r2)
6497{
6498 IRTemp op1 = newTemp(Ity_I64);
6499 IRTemp op2 = newTemp(Ity_I32);
6500 IRTemp result = newTemp(Ity_I128);
6501
6502 assign(op1, get_gpr_dw0(r1));
6503 assign(op2, get_gpr_w1(r2));
6504 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_32Sto64, mkexpr(op2))
6505 ));
6506 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6507
6508 return "msgfr";
6509}
6510
6511static HChar *
6512s390_irgen_MS(UChar r1, IRTemp op2addr)
6513{
6514 IRTemp op1 = newTemp(Ity_I32);
6515 IRTemp op2 = newTemp(Ity_I32);
6516 IRTemp result = newTemp(Ity_I64);
6517
6518 assign(op1, get_gpr_w1(r1));
6519 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6520 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6521 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6522
6523 return "ms";
6524}
6525
6526static HChar *
6527s390_irgen_MSY(UChar r1, IRTemp op2addr)
6528{
6529 IRTemp op1 = newTemp(Ity_I32);
6530 IRTemp op2 = newTemp(Ity_I32);
6531 IRTemp result = newTemp(Ity_I64);
6532
6533 assign(op1, get_gpr_w1(r1));
6534 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6535 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6536 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6537
6538 return "msy";
6539}
6540
6541static HChar *
6542s390_irgen_MSG(UChar r1, IRTemp op2addr)
6543{
6544 IRTemp op1 = newTemp(Ity_I64);
6545 IRTemp op2 = newTemp(Ity_I64);
6546 IRTemp result = newTemp(Ity_I128);
6547
6548 assign(op1, get_gpr_dw0(r1));
6549 assign(op2, load(Ity_I64, mkexpr(op2addr)));
6550 assign(result, binop(Iop_MullS64, mkexpr(op1), mkexpr(op2)));
6551 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6552
6553 return "msg";
6554}
6555
6556static HChar *
6557s390_irgen_MSGF(UChar r1, IRTemp op2addr)
6558{
6559 IRTemp op1 = newTemp(Ity_I64);
6560 IRTemp op2 = newTemp(Ity_I32);
6561 IRTemp result = newTemp(Ity_I128);
6562
6563 assign(op1, get_gpr_dw0(r1));
6564 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6565 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_32Sto64, mkexpr(op2))
6566 ));
6567 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6568
6569 return "msgf";
6570}
6571
6572static HChar *
6573s390_irgen_MSFI(UChar r1, UInt i2)
6574{
6575 IRTemp op1 = newTemp(Ity_I32);
6576 Int op2;
6577 IRTemp result = newTemp(Ity_I64);
6578
6579 assign(op1, get_gpr_w1(r1));
6580 op2 = (Int)i2;
6581 assign(result, binop(Iop_MullS32, mkexpr(op1), mkU32((UInt)op2)));
6582 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6583
6584 return "msfi";
6585}
6586
6587static HChar *
6588s390_irgen_MSGFI(UChar r1, UInt i2)
6589{
6590 IRTemp op1 = newTemp(Ity_I64);
6591 Int op2;
6592 IRTemp result = newTemp(Ity_I128);
6593
6594 assign(op1, get_gpr_dw0(r1));
6595 op2 = (Int)i2;
6596 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_32Sto64, mkU32((UInt)
6597 op2))));
6598 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6599
6600 return "msgfi";
6601}
6602
6603static HChar *
6604s390_irgen_OR(UChar r1, UChar r2)
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, get_gpr_w1(r2));
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 "or";
6617}
6618
6619static HChar *
6620s390_irgen_OGR(UChar r1, UChar r2)
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, get_gpr_dw0(r2));
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 "ogr";
6633}
6634
6635static HChar *
6636s390_irgen_ORK(UChar r3, UChar r1, UChar r2)
6637{
6638 IRTemp op2 = newTemp(Ity_I32);
6639 IRTemp op3 = newTemp(Ity_I32);
6640 IRTemp result = newTemp(Ity_I32);
6641
6642 assign(op2, get_gpr_w1(r2));
6643 assign(op3, get_gpr_w1(r3));
6644 assign(result, binop(Iop_Or32, mkexpr(op2), mkexpr(op3)));
6645 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6646 put_gpr_w1(r1, mkexpr(result));
6647
6648 return "ork";
6649}
6650
6651static HChar *
6652s390_irgen_OGRK(UChar r3, UChar r1, UChar r2)
6653{
6654 IRTemp op2 = newTemp(Ity_I64);
6655 IRTemp op3 = newTemp(Ity_I64);
6656 IRTemp result = newTemp(Ity_I64);
6657
6658 assign(op2, get_gpr_dw0(r2));
6659 assign(op3, get_gpr_dw0(r3));
6660 assign(result, binop(Iop_Or64, mkexpr(op2), mkexpr(op3)));
6661 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6662 put_gpr_dw0(r1, mkexpr(result));
6663
6664 return "ogrk";
6665}
6666
6667static HChar *
6668s390_irgen_O(UChar r1, IRTemp op2addr)
6669{
6670 IRTemp op1 = newTemp(Ity_I32);
6671 IRTemp op2 = newTemp(Ity_I32);
6672 IRTemp result = newTemp(Ity_I32);
6673
6674 assign(op1, get_gpr_w1(r1));
6675 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6676 assign(result, binop(Iop_Or32, mkexpr(op1), mkexpr(op2)));
6677 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6678 put_gpr_w1(r1, mkexpr(result));
6679
6680 return "o";
6681}
6682
6683static HChar *
6684s390_irgen_OY(UChar r1, IRTemp op2addr)
6685{
6686 IRTemp op1 = newTemp(Ity_I32);
6687 IRTemp op2 = newTemp(Ity_I32);
6688 IRTemp result = newTemp(Ity_I32);
6689
6690 assign(op1, get_gpr_w1(r1));
6691 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6692 assign(result, binop(Iop_Or32, mkexpr(op1), mkexpr(op2)));
6693 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6694 put_gpr_w1(r1, mkexpr(result));
6695
6696 return "oy";
6697}
6698
6699static HChar *
6700s390_irgen_OG(UChar r1, IRTemp op2addr)
6701{
6702 IRTemp op1 = newTemp(Ity_I64);
6703 IRTemp op2 = newTemp(Ity_I64);
6704 IRTemp result = newTemp(Ity_I64);
6705
6706 assign(op1, get_gpr_dw0(r1));
6707 assign(op2, load(Ity_I64, mkexpr(op2addr)));
6708 assign(result, binop(Iop_Or64, mkexpr(op1), mkexpr(op2)));
6709 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6710 put_gpr_dw0(r1, mkexpr(result));
6711
6712 return "og";
6713}
6714
6715static HChar *
6716s390_irgen_OI(UChar i2, IRTemp op1addr)
6717{
6718 IRTemp op1 = newTemp(Ity_I8);
6719 UChar op2;
6720 IRTemp result = newTemp(Ity_I8);
6721
6722 assign(op1, load(Ity_I8, mkexpr(op1addr)));
6723 op2 = i2;
6724 assign(result, binop(Iop_Or8, mkexpr(op1), mkU8(op2)));
6725 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6726 store(mkexpr(op1addr), mkexpr(result));
6727
6728 return "oi";
6729}
6730
6731static HChar *
6732s390_irgen_OIY(UChar i2, IRTemp op1addr)
6733{
6734 IRTemp op1 = newTemp(Ity_I8);
6735 UChar op2;
6736 IRTemp result = newTemp(Ity_I8);
6737
6738 assign(op1, load(Ity_I8, mkexpr(op1addr)));
6739 op2 = i2;
6740 assign(result, binop(Iop_Or8, mkexpr(op1), mkU8(op2)));
6741 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6742 store(mkexpr(op1addr), mkexpr(result));
6743
6744 return "oiy";
6745}
6746
6747static HChar *
6748s390_irgen_OIHF(UChar r1, UInt i2)
6749{
6750 IRTemp op1 = newTemp(Ity_I32);
6751 UInt op2;
6752 IRTemp result = newTemp(Ity_I32);
6753
6754 assign(op1, get_gpr_w0(r1));
6755 op2 = i2;
6756 assign(result, binop(Iop_Or32, mkexpr(op1), mkU32(op2)));
6757 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6758 put_gpr_w0(r1, mkexpr(result));
6759
6760 return "oihf";
6761}
6762
6763static HChar *
6764s390_irgen_OIHH(UChar r1, UShort i2)
6765{
6766 IRTemp op1 = newTemp(Ity_I16);
6767 UShort op2;
6768 IRTemp result = newTemp(Ity_I16);
6769
6770 assign(op1, get_gpr_hw0(r1));
6771 op2 = i2;
6772 assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
6773 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6774 put_gpr_hw0(r1, mkexpr(result));
6775
6776 return "oihh";
6777}
6778
6779static HChar *
6780s390_irgen_OIHL(UChar r1, UShort i2)
6781{
6782 IRTemp op1 = newTemp(Ity_I16);
6783 UShort op2;
6784 IRTemp result = newTemp(Ity_I16);
6785
6786 assign(op1, get_gpr_hw1(r1));
6787 op2 = i2;
6788 assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
6789 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6790 put_gpr_hw1(r1, mkexpr(result));
6791
6792 return "oihl";
6793}
6794
6795static HChar *
6796s390_irgen_OILF(UChar r1, UInt i2)
6797{
6798 IRTemp op1 = newTemp(Ity_I32);
6799 UInt op2;
6800 IRTemp result = newTemp(Ity_I32);
6801
6802 assign(op1, get_gpr_w1(r1));
6803 op2 = i2;
6804 assign(result, binop(Iop_Or32, mkexpr(op1), mkU32(op2)));
6805 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6806 put_gpr_w1(r1, mkexpr(result));
6807
6808 return "oilf";
6809}
6810
6811static HChar *
6812s390_irgen_OILH(UChar r1, UShort i2)
6813{
6814 IRTemp op1 = newTemp(Ity_I16);
6815 UShort op2;
6816 IRTemp result = newTemp(Ity_I16);
6817
6818 assign(op1, get_gpr_hw2(r1));
6819 op2 = i2;
6820 assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
6821 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6822 put_gpr_hw2(r1, mkexpr(result));
6823
6824 return "oilh";
6825}
6826
6827static HChar *
6828s390_irgen_OILL(UChar r1, UShort i2)
6829{
6830 IRTemp op1 = newTemp(Ity_I16);
6831 UShort op2;
6832 IRTemp result = newTemp(Ity_I16);
6833
6834 assign(op1, get_gpr_hw3(r1));
6835 op2 = i2;
6836 assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
6837 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6838 put_gpr_hw3(r1, mkexpr(result));
6839
6840 return "oill";
6841}
6842
6843static HChar *
6844s390_irgen_PFD(void)
6845{
6846
6847 return "pfd";
6848}
6849
6850static HChar *
6851s390_irgen_PFDRL(void)
6852{
6853
6854 return "pfdrl";
6855}
6856
6857static HChar *
6858s390_irgen_RLL(UChar r1, UChar r3, IRTemp op2addr)
6859{
6860 IRTemp amount = newTemp(Ity_I64);
6861 IRTemp op = newTemp(Ity_I32);
6862
6863 assign(amount, binop(Iop_And64, mkexpr(op2addr), mkU64(31)));
6864 assign(op, get_gpr_w1(r3));
6865 put_gpr_w1(r1, binop(Iop_Or32, binop(Iop_Shl32, mkexpr(op), unop(Iop_64to8,
6866 mkexpr(amount))), binop(Iop_Shr32, mkexpr(op), unop(Iop_64to8,
6867 binop(Iop_Sub64, mkU64(32), mkexpr(amount))))));
6868
6869 return "rll";
6870}
6871
6872static HChar *
6873s390_irgen_RLLG(UChar r1, UChar r3, IRTemp op2addr)
6874{
6875 IRTemp amount = newTemp(Ity_I64);
6876 IRTemp op = newTemp(Ity_I64);
6877
6878 assign(amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
6879 assign(op, get_gpr_dw0(r3));
6880 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(op), unop(Iop_64to8,
6881 mkexpr(amount))), binop(Iop_Shr64, mkexpr(op), unop(Iop_64to8,
6882 binop(Iop_Sub64, mkU64(64), mkexpr(amount))))));
6883
6884 return "rllg";
6885}
6886
6887static HChar *
6888s390_irgen_RNSBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
6889{
6890 UChar from;
6891 UChar to;
6892 UChar rot;
6893 UChar t_bit;
6894 ULong mask;
6895 ULong maskc;
6896 IRTemp result = newTemp(Ity_I64);
6897 IRTemp op2 = newTemp(Ity_I64);
6898
6899 from = i3 & 63;
6900 to = i4 & 63;
6901 rot = i5 & 63;
6902 t_bit = i3 & 128;
6903 assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
6904 get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
6905 mkU8(64 - rot))));
6906 if (from <= to) {
6907 mask = ~0ULL;
6908 mask = (mask >> from) & (mask << (63 - to));
6909 maskc = ~mask;
6910 } else {
6911 maskc = ~0ULL;
6912 maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
6913 mask = ~maskc;
6914 }
6915 assign(result, binop(Iop_And64, binop(Iop_And64, get_gpr_dw0(r1), mkexpr(op2)
6916 ), mkU64(mask)));
6917 if (t_bit == 0) {
6918 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
6919 mkU64(maskc)), mkexpr(result)));
6920 }
6921 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6922
6923 return "rnsbg";
6924}
6925
6926static HChar *
6927s390_irgen_RXSBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
6928{
6929 UChar from;
6930 UChar to;
6931 UChar rot;
6932 UChar t_bit;
6933 ULong mask;
6934 ULong maskc;
6935 IRTemp result = newTemp(Ity_I64);
6936 IRTemp op2 = newTemp(Ity_I64);
6937
6938 from = i3 & 63;
6939 to = i4 & 63;
6940 rot = i5 & 63;
6941 t_bit = i3 & 128;
6942 assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
6943 get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
6944 mkU8(64 - rot))));
6945 if (from <= to) {
6946 mask = ~0ULL;
6947 mask = (mask >> from) & (mask << (63 - to));
6948 maskc = ~mask;
6949 } else {
6950 maskc = ~0ULL;
6951 maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
6952 mask = ~maskc;
6953 }
6954 assign(result, binop(Iop_And64, binop(Iop_Xor64, get_gpr_dw0(r1), mkexpr(op2)
6955 ), mkU64(mask)));
6956 if (t_bit == 0) {
6957 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
6958 mkU64(maskc)), mkexpr(result)));
6959 }
6960 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6961
6962 return "rxsbg";
6963}
6964
6965static HChar *
6966s390_irgen_ROSBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
6967{
6968 UChar from;
6969 UChar to;
6970 UChar rot;
6971 UChar t_bit;
6972 ULong mask;
6973 ULong maskc;
6974 IRTemp result = newTemp(Ity_I64);
6975 IRTemp op2 = newTemp(Ity_I64);
6976
6977 from = i3 & 63;
6978 to = i4 & 63;
6979 rot = i5 & 63;
6980 t_bit = i3 & 128;
6981 assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
6982 get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
6983 mkU8(64 - rot))));
6984 if (from <= to) {
6985 mask = ~0ULL;
6986 mask = (mask >> from) & (mask << (63 - to));
6987 maskc = ~mask;
6988 } else {
6989 maskc = ~0ULL;
6990 maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
6991 mask = ~maskc;
6992 }
6993 assign(result, binop(Iop_And64, binop(Iop_Or64, get_gpr_dw0(r1), mkexpr(op2)
6994 ), mkU64(mask)));
6995 if (t_bit == 0) {
6996 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
6997 mkU64(maskc)), mkexpr(result)));
6998 }
6999 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7000
7001 return "rosbg";
7002}
7003
7004static HChar *
7005s390_irgen_RISBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
7006{
7007 UChar from;
7008 UChar to;
7009 UChar rot;
7010 UChar z_bit;
7011 ULong mask;
7012 ULong maskc;
7013 IRTemp op2 = newTemp(Ity_I64);
7014 IRTemp result = newTemp(Ity_I64);
7015
7016 from = i3 & 63;
7017 to = i4 & 63;
7018 rot = i5 & 63;
7019 z_bit = i4 & 128;
7020 assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
7021 get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
7022 mkU8(64 - rot))));
7023 if (from <= to) {
7024 mask = ~0ULL;
7025 mask = (mask >> from) & (mask << (63 - to));
7026 maskc = ~mask;
7027 } else {
7028 maskc = ~0ULL;
7029 maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
7030 mask = ~maskc;
7031 }
7032 if (z_bit == 0) {
7033 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
7034 mkU64(maskc)), binop(Iop_And64, mkexpr(op2), mkU64(mask))));
7035 } else {
7036 put_gpr_dw0(r1, binop(Iop_And64, mkexpr(op2), mkU64(mask)));
7037 }
7038 assign(result, get_gpr_dw0(r1));
7039 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
7040
7041 return "risbg";
7042}
7043
7044static HChar *
7045s390_irgen_SAR(UChar r1, UChar r2)
7046{
7047 put_ar_w0(r1, get_gpr_w1(r2));
sewardj7ee97522011-05-09 21:45:04 +00007048 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00007049 s390_disasm(ENC3(MNM, AR, GPR), "sar", r1, r2);
7050
7051 return "sar";
7052}
7053
7054static HChar *
7055s390_irgen_SLDA(UChar r1, IRTemp op2addr)
7056{
7057 IRTemp p1 = newTemp(Ity_I64);
7058 IRTemp p2 = newTemp(Ity_I64);
7059 IRTemp op = newTemp(Ity_I64);
7060 IRTemp result = newTemp(Ity_I64);
florian417b22d2012-07-13 13:41:41 +00007061 ULong sign_mask;
sewardj2019a972011-03-07 16:04:07 +00007062 IRTemp shift_amount = newTemp(Ity_I64);
7063
7064 assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
7065 assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
7066 assign(op, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1), mkU8(32)), mkexpr(p2)
7067 ));
7068 sign_mask = 1ULL << 63;
7069 assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7070 assign(result, binop(Iop_Or64, binop(Iop_And64, binop(Iop_Shl64, mkexpr(op),
florian417b22d2012-07-13 13:41:41 +00007071 unop(Iop_64to8, mkexpr(shift_amount))), mkU64(~sign_mask)),
7072 binop(Iop_And64, mkexpr(op), mkU64(sign_mask))));
sewardj2019a972011-03-07 16:04:07 +00007073 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
7074 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
7075 s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_64, op, shift_amount);
7076
7077 return "slda";
7078}
7079
7080static HChar *
7081s390_irgen_SLDL(UChar r1, IRTemp op2addr)
7082{
7083 IRTemp p1 = newTemp(Ity_I64);
7084 IRTemp p2 = newTemp(Ity_I64);
7085 IRTemp result = newTemp(Ity_I64);
7086
7087 assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
7088 assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
7089 assign(result, binop(Iop_Shl64, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1),
7090 mkU8(32)), mkexpr(p2)), unop(Iop_64to8, binop(Iop_And64,
7091 mkexpr(op2addr), mkU64(63)))));
7092 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
7093 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
7094
7095 return "sldl";
7096}
7097
7098static HChar *
7099s390_irgen_SLA(UChar r1, IRTemp op2addr)
7100{
7101 IRTemp uop = newTemp(Ity_I32);
7102 IRTemp result = newTemp(Ity_I32);
7103 UInt sign_mask;
7104 IRTemp shift_amount = newTemp(Ity_I64);
7105 IRTemp op = newTemp(Ity_I32);
7106
7107 assign(op, get_gpr_w1(r1));
7108 assign(uop, get_gpr_w1(r1));
7109 sign_mask = 2147483648U;
7110 assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7111 assign(result, binop(Iop_Or32, binop(Iop_And32, binop(Iop_Shl32, mkexpr(uop),
7112 unop(Iop_64to8, mkexpr(shift_amount))), mkU32(~sign_mask)),
7113 binop(Iop_And32, mkexpr(uop), mkU32(sign_mask))));
7114 put_gpr_w1(r1, mkexpr(result));
7115 s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_32, op, shift_amount);
7116
7117 return "sla";
7118}
7119
7120static HChar *
7121s390_irgen_SLAK(UChar r1, UChar r3, IRTemp op2addr)
7122{
7123 IRTemp uop = newTemp(Ity_I32);
7124 IRTemp result = newTemp(Ity_I32);
7125 UInt sign_mask;
7126 IRTemp shift_amount = newTemp(Ity_I64);
7127 IRTemp op = newTemp(Ity_I32);
7128
7129 assign(op, get_gpr_w1(r3));
7130 assign(uop, get_gpr_w1(r3));
7131 sign_mask = 2147483648U;
7132 assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7133 assign(result, binop(Iop_Or32, binop(Iop_And32, binop(Iop_Shl32, mkexpr(uop),
7134 unop(Iop_64to8, mkexpr(shift_amount))), mkU32(~sign_mask)),
7135 binop(Iop_And32, mkexpr(uop), mkU32(sign_mask))));
7136 put_gpr_w1(r1, mkexpr(result));
7137 s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_32, op, shift_amount);
7138
7139 return "slak";
7140}
7141
7142static HChar *
7143s390_irgen_SLAG(UChar r1, UChar r3, IRTemp op2addr)
7144{
7145 IRTemp uop = newTemp(Ity_I64);
7146 IRTemp result = newTemp(Ity_I64);
7147 ULong sign_mask;
7148 IRTemp shift_amount = newTemp(Ity_I64);
7149 IRTemp op = newTemp(Ity_I64);
7150
7151 assign(op, get_gpr_dw0(r3));
7152 assign(uop, get_gpr_dw0(r3));
7153 sign_mask = 9223372036854775808ULL;
7154 assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7155 assign(result, binop(Iop_Or64, binop(Iop_And64, binop(Iop_Shl64, mkexpr(uop),
7156 unop(Iop_64to8, mkexpr(shift_amount))), mkU64(~sign_mask)),
7157 binop(Iop_And64, mkexpr(uop), mkU64(sign_mask))));
7158 put_gpr_dw0(r1, mkexpr(result));
7159 s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_64, op, shift_amount);
7160
7161 return "slag";
7162}
7163
7164static HChar *
7165s390_irgen_SLL(UChar r1, IRTemp op2addr)
7166{
7167 put_gpr_w1(r1, binop(Iop_Shl32, get_gpr_w1(r1), unop(Iop_64to8,
7168 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
7169
7170 return "sll";
7171}
7172
7173static HChar *
7174s390_irgen_SLLK(UChar r1, UChar r3, IRTemp op2addr)
7175{
7176 put_gpr_w1(r1, binop(Iop_Shl32, get_gpr_w1(r3), unop(Iop_64to8,
7177 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
7178
7179 return "sllk";
7180}
7181
7182static HChar *
7183s390_irgen_SLLG(UChar r1, UChar r3, IRTemp op2addr)
7184{
7185 put_gpr_dw0(r1, binop(Iop_Shl64, get_gpr_dw0(r3), unop(Iop_64to8,
7186 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
7187
7188 return "sllg";
7189}
7190
7191static HChar *
7192s390_irgen_SRDA(UChar r1, IRTemp op2addr)
7193{
7194 IRTemp p1 = newTemp(Ity_I64);
7195 IRTemp p2 = newTemp(Ity_I64);
7196 IRTemp result = newTemp(Ity_I64);
7197
7198 assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
7199 assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
7200 assign(result, binop(Iop_Sar64, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1),
7201 mkU8(32)), mkexpr(p2)), unop(Iop_64to8, binop(Iop_And64,
7202 mkexpr(op2addr), mkU64(63)))));
7203 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
7204 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
7205 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7206
7207 return "srda";
7208}
7209
7210static HChar *
7211s390_irgen_SRDL(UChar r1, IRTemp op2addr)
7212{
7213 IRTemp p1 = newTemp(Ity_I64);
7214 IRTemp p2 = newTemp(Ity_I64);
7215 IRTemp result = newTemp(Ity_I64);
7216
7217 assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
7218 assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
7219 assign(result, binop(Iop_Shr64, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1),
7220 mkU8(32)), mkexpr(p2)), unop(Iop_64to8, binop(Iop_And64,
7221 mkexpr(op2addr), mkU64(63)))));
7222 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
7223 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
7224
7225 return "srdl";
7226}
7227
7228static HChar *
7229s390_irgen_SRA(UChar r1, IRTemp op2addr)
7230{
7231 IRTemp result = newTemp(Ity_I32);
7232 IRTemp op = newTemp(Ity_I32);
7233
7234 assign(op, get_gpr_w1(r1));
7235 assign(result, binop(Iop_Sar32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7236 mkexpr(op2addr), mkU64(63)))));
7237 put_gpr_w1(r1, mkexpr(result));
7238 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7239
7240 return "sra";
7241}
7242
7243static HChar *
7244s390_irgen_SRAK(UChar r1, UChar r3, IRTemp op2addr)
7245{
7246 IRTemp result = newTemp(Ity_I32);
7247 IRTemp op = newTemp(Ity_I32);
7248
7249 assign(op, get_gpr_w1(r3));
7250 assign(result, binop(Iop_Sar32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7251 mkexpr(op2addr), mkU64(63)))));
7252 put_gpr_w1(r1, mkexpr(result));
7253 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7254
7255 return "srak";
7256}
7257
7258static HChar *
7259s390_irgen_SRAG(UChar r1, UChar r3, IRTemp op2addr)
7260{
7261 IRTemp result = newTemp(Ity_I64);
7262 IRTemp op = newTemp(Ity_I64);
7263
7264 assign(op, get_gpr_dw0(r3));
7265 assign(result, binop(Iop_Sar64, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7266 mkexpr(op2addr), mkU64(63)))));
7267 put_gpr_dw0(r1, mkexpr(result));
7268 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7269
7270 return "srag";
7271}
7272
7273static HChar *
7274s390_irgen_SRL(UChar r1, IRTemp op2addr)
7275{
7276 IRTemp op = newTemp(Ity_I32);
7277
7278 assign(op, get_gpr_w1(r1));
7279 put_gpr_w1(r1, binop(Iop_Shr32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7280 mkexpr(op2addr), mkU64(63)))));
7281
7282 return "srl";
7283}
7284
7285static HChar *
7286s390_irgen_SRLK(UChar r1, UChar r3, IRTemp op2addr)
7287{
7288 IRTemp op = newTemp(Ity_I32);
7289
7290 assign(op, get_gpr_w1(r3));
7291 put_gpr_w1(r1, binop(Iop_Shr32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7292 mkexpr(op2addr), mkU64(63)))));
7293
7294 return "srlk";
7295}
7296
7297static HChar *
7298s390_irgen_SRLG(UChar r1, UChar r3, IRTemp op2addr)
7299{
7300 IRTemp op = newTemp(Ity_I64);
7301
7302 assign(op, get_gpr_dw0(r3));
7303 put_gpr_dw0(r1, binop(Iop_Shr64, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7304 mkexpr(op2addr), mkU64(63)))));
7305
7306 return "srlg";
7307}
7308
7309static HChar *
7310s390_irgen_ST(UChar r1, IRTemp op2addr)
7311{
7312 store(mkexpr(op2addr), get_gpr_w1(r1));
7313
7314 return "st";
7315}
7316
7317static HChar *
7318s390_irgen_STY(UChar r1, IRTemp op2addr)
7319{
7320 store(mkexpr(op2addr), get_gpr_w1(r1));
7321
7322 return "sty";
7323}
7324
7325static HChar *
7326s390_irgen_STG(UChar r1, IRTemp op2addr)
7327{
7328 store(mkexpr(op2addr), get_gpr_dw0(r1));
7329
7330 return "stg";
7331}
7332
7333static HChar *
7334s390_irgen_STRL(UChar r1, UInt i2)
7335{
7336 store(mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)),
7337 get_gpr_w1(r1));
7338
7339 return "strl";
7340}
7341
7342static HChar *
7343s390_irgen_STGRL(UChar r1, UInt i2)
7344{
7345 store(mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)),
7346 get_gpr_dw0(r1));
7347
7348 return "stgrl";
7349}
7350
7351static HChar *
7352s390_irgen_STC(UChar r1, IRTemp op2addr)
7353{
7354 store(mkexpr(op2addr), get_gpr_b7(r1));
7355
7356 return "stc";
7357}
7358
7359static HChar *
7360s390_irgen_STCY(UChar r1, IRTemp op2addr)
7361{
7362 store(mkexpr(op2addr), get_gpr_b7(r1));
7363
7364 return "stcy";
7365}
7366
7367static HChar *
7368s390_irgen_STCH(UChar r1, IRTemp op2addr)
7369{
7370 store(mkexpr(op2addr), get_gpr_b3(r1));
7371
7372 return "stch";
7373}
7374
7375static HChar *
7376s390_irgen_STCM(UChar r1, UChar r3, IRTemp op2addr)
7377{
7378 UChar mask;
7379 UChar n;
7380
7381 mask = (UChar)r3;
7382 n = 0;
7383 if ((mask & 8) != 0) {
7384 store(mkexpr(op2addr), get_gpr_b4(r1));
7385 n = n + 1;
7386 }
7387 if ((mask & 4) != 0) {
7388 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b5(r1));
7389 n = n + 1;
7390 }
7391 if ((mask & 2) != 0) {
7392 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b6(r1));
7393 n = n + 1;
7394 }
7395 if ((mask & 1) != 0) {
7396 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b7(r1));
7397 }
7398
7399 return "stcm";
7400}
7401
7402static HChar *
7403s390_irgen_STCMY(UChar r1, UChar r3, IRTemp op2addr)
7404{
7405 UChar mask;
7406 UChar n;
7407
7408 mask = (UChar)r3;
7409 n = 0;
7410 if ((mask & 8) != 0) {
7411 store(mkexpr(op2addr), get_gpr_b4(r1));
7412 n = n + 1;
7413 }
7414 if ((mask & 4) != 0) {
7415 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b5(r1));
7416 n = n + 1;
7417 }
7418 if ((mask & 2) != 0) {
7419 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b6(r1));
7420 n = n + 1;
7421 }
7422 if ((mask & 1) != 0) {
7423 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b7(r1));
7424 }
7425
7426 return "stcmy";
7427}
7428
7429static HChar *
7430s390_irgen_STCMH(UChar r1, UChar r3, IRTemp op2addr)
7431{
7432 UChar mask;
7433 UChar n;
7434
7435 mask = (UChar)r3;
7436 n = 0;
7437 if ((mask & 8) != 0) {
7438 store(mkexpr(op2addr), get_gpr_b0(r1));
7439 n = n + 1;
7440 }
7441 if ((mask & 4) != 0) {
7442 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b1(r1));
7443 n = n + 1;
7444 }
7445 if ((mask & 2) != 0) {
7446 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b2(r1));
7447 n = n + 1;
7448 }
7449 if ((mask & 1) != 0) {
7450 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b3(r1));
7451 }
7452
7453 return "stcmh";
7454}
7455
7456static HChar *
7457s390_irgen_STH(UChar r1, IRTemp op2addr)
7458{
7459 store(mkexpr(op2addr), get_gpr_hw3(r1));
7460
7461 return "sth";
7462}
7463
7464static HChar *
7465s390_irgen_STHY(UChar r1, IRTemp op2addr)
7466{
7467 store(mkexpr(op2addr), get_gpr_hw3(r1));
7468
7469 return "sthy";
7470}
7471
7472static HChar *
7473s390_irgen_STHRL(UChar r1, UInt i2)
7474{
7475 store(mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)),
7476 get_gpr_hw3(r1));
7477
7478 return "sthrl";
7479}
7480
7481static HChar *
7482s390_irgen_STHH(UChar r1, IRTemp op2addr)
7483{
7484 store(mkexpr(op2addr), get_gpr_hw1(r1));
7485
7486 return "sthh";
7487}
7488
7489static HChar *
7490s390_irgen_STFH(UChar r1, IRTemp op2addr)
7491{
7492 store(mkexpr(op2addr), get_gpr_w0(r1));
7493
7494 return "stfh";
7495}
7496
7497static HChar *
sewardjd7bde722011-04-05 13:19:33 +00007498s390_irgen_STOC(UChar r1, IRTemp op2addr)
7499{
7500 /* condition is checked in format handler */
7501 store(mkexpr(op2addr), get_gpr_w1(r1));
7502
7503 return "stoc";
7504}
7505
7506static HChar *
7507s390_irgen_STOCG(UChar r1, IRTemp op2addr)
7508{
7509 /* condition is checked in format handler */
7510 store(mkexpr(op2addr), get_gpr_dw0(r1));
7511
7512 return "stocg";
7513}
7514
7515static HChar *
sewardj2019a972011-03-07 16:04:07 +00007516s390_irgen_STPQ(UChar r1, IRTemp op2addr)
7517{
7518 store(mkexpr(op2addr), get_gpr_dw0(r1));
7519 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(8)), get_gpr_dw0(r1 + 1));
7520
7521 return "stpq";
7522}
7523
7524static HChar *
7525s390_irgen_STRVH(UChar r1, IRTemp op2addr)
7526{
7527 store(mkexpr(op2addr), get_gpr_b7(r1));
7528 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(1)), get_gpr_b6(r1));
7529
7530 return "strvh";
7531}
7532
7533static HChar *
7534s390_irgen_STRV(UChar r1, IRTemp op2addr)
7535{
7536 store(mkexpr(op2addr), get_gpr_b7(r1));
7537 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(1)), get_gpr_b6(r1));
7538 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(2)), get_gpr_b5(r1));
7539 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(3)), get_gpr_b4(r1));
7540
7541 return "strv";
7542}
7543
7544static HChar *
7545s390_irgen_STRVG(UChar r1, IRTemp op2addr)
7546{
7547 store(mkexpr(op2addr), get_gpr_b7(r1));
7548 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(1)), get_gpr_b6(r1));
7549 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(2)), get_gpr_b5(r1));
7550 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(3)), get_gpr_b4(r1));
7551 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(4)), get_gpr_b3(r1));
7552 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(5)), get_gpr_b2(r1));
7553 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(6)), get_gpr_b1(r1));
7554 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(7)), get_gpr_b0(r1));
7555
7556 return "strvg";
7557}
7558
7559static HChar *
7560s390_irgen_SR(UChar r1, UChar r2)
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, get_gpr_w1(r2));
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 "sr";
7573}
7574
7575static HChar *
7576s390_irgen_SGR(UChar r1, UChar r2)
7577{
7578 IRTemp op1 = newTemp(Ity_I64);
7579 IRTemp op2 = newTemp(Ity_I64);
7580 IRTemp result = newTemp(Ity_I64);
7581
7582 assign(op1, get_gpr_dw0(r1));
7583 assign(op2, get_gpr_dw0(r2));
7584 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7585 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
7586 put_gpr_dw0(r1, mkexpr(result));
7587
7588 return "sgr";
7589}
7590
7591static HChar *
7592s390_irgen_SGFR(UChar r1, UChar r2)
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, unop(Iop_32Sto64, get_gpr_w1(r2)));
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 "sgfr";
7605}
7606
7607static HChar *
7608s390_irgen_SRK(UChar r3, UChar r1, UChar r2)
7609{
7610 IRTemp op2 = newTemp(Ity_I32);
7611 IRTemp op3 = newTemp(Ity_I32);
7612 IRTemp result = newTemp(Ity_I32);
7613
7614 assign(op2, get_gpr_w1(r2));
7615 assign(op3, get_gpr_w1(r3));
7616 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
7617 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op2, op3);
7618 put_gpr_w1(r1, mkexpr(result));
7619
7620 return "srk";
7621}
7622
7623static HChar *
7624s390_irgen_SGRK(UChar r3, UChar r1, UChar r2)
7625{
7626 IRTemp op2 = newTemp(Ity_I64);
7627 IRTemp op3 = newTemp(Ity_I64);
7628 IRTemp result = newTemp(Ity_I64);
7629
7630 assign(op2, get_gpr_dw0(r2));
7631 assign(op3, get_gpr_dw0(r3));
7632 assign(result, binop(Iop_Sub64, mkexpr(op2), mkexpr(op3)));
7633 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op2, op3);
7634 put_gpr_dw0(r1, mkexpr(result));
7635
7636 return "sgrk";
7637}
7638
7639static HChar *
7640s390_irgen_S(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, load(Ity_I32, 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 "s";
7653}
7654
7655static HChar *
7656s390_irgen_SY(UChar r1, IRTemp op2addr)
7657{
7658 IRTemp op1 = newTemp(Ity_I32);
7659 IRTemp op2 = newTemp(Ity_I32);
7660 IRTemp result = newTemp(Ity_I32);
7661
7662 assign(op1, get_gpr_w1(r1));
7663 assign(op2, load(Ity_I32, mkexpr(op2addr)));
7664 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7665 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
7666 put_gpr_w1(r1, mkexpr(result));
7667
7668 return "sy";
7669}
7670
7671static HChar *
7672s390_irgen_SG(UChar r1, IRTemp op2addr)
7673{
7674 IRTemp op1 = newTemp(Ity_I64);
7675 IRTemp op2 = newTemp(Ity_I64);
7676 IRTemp result = newTemp(Ity_I64);
7677
7678 assign(op1, get_gpr_dw0(r1));
7679 assign(op2, load(Ity_I64, mkexpr(op2addr)));
7680 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7681 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
7682 put_gpr_dw0(r1, mkexpr(result));
7683
7684 return "sg";
7685}
7686
7687static HChar *
7688s390_irgen_SGF(UChar r1, IRTemp op2addr)
7689{
7690 IRTemp op1 = newTemp(Ity_I64);
7691 IRTemp op2 = newTemp(Ity_I64);
7692 IRTemp result = newTemp(Ity_I64);
7693
7694 assign(op1, get_gpr_dw0(r1));
7695 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
7696 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7697 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
7698 put_gpr_dw0(r1, mkexpr(result));
7699
7700 return "sgf";
7701}
7702
7703static HChar *
7704s390_irgen_SH(UChar r1, IRTemp op2addr)
7705{
7706 IRTemp op1 = newTemp(Ity_I32);
7707 IRTemp op2 = newTemp(Ity_I32);
7708 IRTemp result = newTemp(Ity_I32);
7709
7710 assign(op1, get_gpr_w1(r1));
7711 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
7712 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7713 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
7714 put_gpr_w1(r1, mkexpr(result));
7715
7716 return "sh";
7717}
7718
7719static HChar *
7720s390_irgen_SHY(UChar r1, IRTemp op2addr)
7721{
7722 IRTemp op1 = newTemp(Ity_I32);
7723 IRTemp op2 = newTemp(Ity_I32);
7724 IRTemp result = newTemp(Ity_I32);
7725
7726 assign(op1, get_gpr_w1(r1));
7727 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
7728 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7729 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
7730 put_gpr_w1(r1, mkexpr(result));
7731
7732 return "shy";
7733}
7734
7735static HChar *
7736s390_irgen_SHHHR(UChar r3 __attribute__((unused)), 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_w0(r1));
7743 assign(op3, get_gpr_w0(r2));
7744 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
7745 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op2, op3);
7746 put_gpr_w0(r1, mkexpr(result));
7747
7748 return "shhhr";
7749}
7750
7751static HChar *
7752s390_irgen_SHHLR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
7753{
7754 IRTemp op2 = newTemp(Ity_I32);
7755 IRTemp op3 = newTemp(Ity_I32);
7756 IRTemp result = newTemp(Ity_I32);
7757
7758 assign(op2, get_gpr_w0(r1));
7759 assign(op3, get_gpr_w1(r2));
7760 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
7761 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op2, op3);
7762 put_gpr_w0(r1, mkexpr(result));
7763
7764 return "shhlr";
7765}
7766
7767static HChar *
7768s390_irgen_SLR(UChar r1, UChar r2)
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, get_gpr_w1(r2));
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 "slr";
7781}
7782
7783static HChar *
7784s390_irgen_SLGR(UChar r1, UChar r2)
7785{
7786 IRTemp op1 = newTemp(Ity_I64);
7787 IRTemp op2 = newTemp(Ity_I64);
7788 IRTemp result = newTemp(Ity_I64);
7789
7790 assign(op1, get_gpr_dw0(r1));
7791 assign(op2, get_gpr_dw0(r2));
7792 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7793 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
7794 put_gpr_dw0(r1, mkexpr(result));
7795
7796 return "slgr";
7797}
7798
7799static HChar *
7800s390_irgen_SLGFR(UChar r1, UChar r2)
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, unop(Iop_32Uto64, get_gpr_w1(r2)));
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 "slgfr";
7813}
7814
7815static HChar *
7816s390_irgen_SLRK(UChar r3, UChar r1, UChar r2)
7817{
7818 IRTemp op2 = newTemp(Ity_I32);
7819 IRTemp op3 = newTemp(Ity_I32);
7820 IRTemp result = newTemp(Ity_I32);
7821
7822 assign(op2, get_gpr_w1(r2));
7823 assign(op3, get_gpr_w1(r3));
7824 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
7825 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op2, op3);
7826 put_gpr_w1(r1, mkexpr(result));
7827
7828 return "slrk";
7829}
7830
7831static HChar *
7832s390_irgen_SLGRK(UChar r3, UChar r1, UChar r2)
7833{
7834 IRTemp op2 = newTemp(Ity_I64);
7835 IRTemp op3 = newTemp(Ity_I64);
7836 IRTemp result = newTemp(Ity_I64);
7837
7838 assign(op2, get_gpr_dw0(r2));
7839 assign(op3, get_gpr_dw0(r3));
7840 assign(result, binop(Iop_Sub64, mkexpr(op2), mkexpr(op3)));
7841 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op2, op3);
7842 put_gpr_dw0(r1, mkexpr(result));
7843
7844 return "slgrk";
7845}
7846
7847static HChar *
7848s390_irgen_SL(UChar r1, IRTemp op2addr)
7849{
7850 IRTemp op1 = newTemp(Ity_I32);
7851 IRTemp op2 = newTemp(Ity_I32);
7852 IRTemp result = newTemp(Ity_I32);
7853
7854 assign(op1, get_gpr_w1(r1));
7855 assign(op2, load(Ity_I32, mkexpr(op2addr)));
7856 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7857 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, op2);
7858 put_gpr_w1(r1, mkexpr(result));
7859
7860 return "sl";
7861}
7862
7863static HChar *
7864s390_irgen_SLY(UChar r1, IRTemp op2addr)
7865{
7866 IRTemp op1 = newTemp(Ity_I32);
7867 IRTemp op2 = newTemp(Ity_I32);
7868 IRTemp result = newTemp(Ity_I32);
7869
7870 assign(op1, get_gpr_w1(r1));
7871 assign(op2, load(Ity_I32, mkexpr(op2addr)));
7872 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7873 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, op2);
7874 put_gpr_w1(r1, mkexpr(result));
7875
7876 return "sly";
7877}
7878
7879static HChar *
7880s390_irgen_SLG(UChar r1, IRTemp op2addr)
7881{
7882 IRTemp op1 = newTemp(Ity_I64);
7883 IRTemp op2 = newTemp(Ity_I64);
7884 IRTemp result = newTemp(Ity_I64);
7885
7886 assign(op1, get_gpr_dw0(r1));
7887 assign(op2, load(Ity_I64, mkexpr(op2addr)));
7888 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7889 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
7890 put_gpr_dw0(r1, mkexpr(result));
7891
7892 return "slg";
7893}
7894
7895static HChar *
7896s390_irgen_SLGF(UChar r1, IRTemp op2addr)
7897{
7898 IRTemp op1 = newTemp(Ity_I64);
7899 IRTemp op2 = newTemp(Ity_I64);
7900 IRTemp result = newTemp(Ity_I64);
7901
7902 assign(op1, get_gpr_dw0(r1));
7903 assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
7904 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7905 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
7906 put_gpr_dw0(r1, mkexpr(result));
7907
7908 return "slgf";
7909}
7910
7911static HChar *
7912s390_irgen_SLFI(UChar r1, UInt i2)
7913{
7914 IRTemp op1 = newTemp(Ity_I32);
7915 UInt op2;
7916 IRTemp result = newTemp(Ity_I32);
7917
7918 assign(op1, get_gpr_w1(r1));
7919 op2 = i2;
7920 assign(result, binop(Iop_Sub32, mkexpr(op1), mkU32(op2)));
7921 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, mktemp(Ity_I32,
7922 mkU32(op2)));
7923 put_gpr_w1(r1, mkexpr(result));
7924
7925 return "slfi";
7926}
7927
7928static HChar *
7929s390_irgen_SLGFI(UChar r1, UInt i2)
7930{
7931 IRTemp op1 = newTemp(Ity_I64);
7932 ULong op2;
7933 IRTemp result = newTemp(Ity_I64);
7934
7935 assign(op1, get_gpr_dw0(r1));
7936 op2 = (ULong)i2;
7937 assign(result, binop(Iop_Sub64, mkexpr(op1), mkU64(op2)));
7938 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, mktemp(Ity_I64,
7939 mkU64(op2)));
7940 put_gpr_dw0(r1, mkexpr(result));
7941
7942 return "slgfi";
7943}
7944
7945static HChar *
7946s390_irgen_SLHHHR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
7947{
7948 IRTemp op2 = newTemp(Ity_I32);
7949 IRTemp op3 = newTemp(Ity_I32);
7950 IRTemp result = newTemp(Ity_I32);
7951
7952 assign(op2, get_gpr_w0(r1));
7953 assign(op3, get_gpr_w0(r2));
7954 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
7955 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op2, op3);
7956 put_gpr_w0(r1, mkexpr(result));
7957
7958 return "slhhhr";
7959}
7960
7961static HChar *
7962s390_irgen_SLHHLR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
7963{
7964 IRTemp op2 = newTemp(Ity_I32);
7965 IRTemp op3 = newTemp(Ity_I32);
7966 IRTemp result = newTemp(Ity_I32);
7967
7968 assign(op2, get_gpr_w0(r1));
7969 assign(op3, get_gpr_w1(r2));
7970 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
7971 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op2, op3);
7972 put_gpr_w0(r1, mkexpr(result));
7973
7974 return "slhhlr";
7975}
7976
7977static HChar *
7978s390_irgen_SLBR(UChar r1, UChar r2)
7979{
7980 IRTemp op1 = newTemp(Ity_I32);
7981 IRTemp op2 = newTemp(Ity_I32);
7982 IRTemp result = newTemp(Ity_I32);
7983 IRTemp borrow_in = newTemp(Ity_I32);
7984
7985 assign(op1, get_gpr_w1(r1));
7986 assign(op2, get_gpr_w1(r2));
7987 assign(borrow_in, binop(Iop_Sub32, mkU32(1), binop(Iop_Shr32,
7988 s390_call_calculate_cc(), mkU8(1))));
7989 assign(result, binop(Iop_Sub32, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)),
7990 mkexpr(borrow_in)));
7991 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_32, op1, op2, borrow_in);
7992 put_gpr_w1(r1, mkexpr(result));
7993
7994 return "slbr";
7995}
7996
7997static HChar *
7998s390_irgen_SLBGR(UChar r1, UChar r2)
7999{
8000 IRTemp op1 = newTemp(Ity_I64);
8001 IRTemp op2 = newTemp(Ity_I64);
8002 IRTemp result = newTemp(Ity_I64);
8003 IRTemp borrow_in = newTemp(Ity_I64);
8004
8005 assign(op1, get_gpr_dw0(r1));
8006 assign(op2, get_gpr_dw0(r2));
8007 assign(borrow_in, unop(Iop_32Uto64, binop(Iop_Sub32, mkU32(1),
8008 binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)))));
8009 assign(result, binop(Iop_Sub64, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)),
8010 mkexpr(borrow_in)));
8011 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_64, op1, op2, borrow_in);
8012 put_gpr_dw0(r1, mkexpr(result));
8013
8014 return "slbgr";
8015}
8016
8017static HChar *
8018s390_irgen_SLB(UChar r1, IRTemp op2addr)
8019{
8020 IRTemp op1 = newTemp(Ity_I32);
8021 IRTemp op2 = newTemp(Ity_I32);
8022 IRTemp result = newTemp(Ity_I32);
8023 IRTemp borrow_in = newTemp(Ity_I32);
8024
8025 assign(op1, get_gpr_w1(r1));
8026 assign(op2, load(Ity_I32, mkexpr(op2addr)));
8027 assign(borrow_in, binop(Iop_Sub32, mkU32(1), binop(Iop_Shr32,
8028 s390_call_calculate_cc(), mkU8(1))));
8029 assign(result, binop(Iop_Sub32, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)),
8030 mkexpr(borrow_in)));
8031 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_32, op1, op2, borrow_in);
8032 put_gpr_w1(r1, mkexpr(result));
8033
8034 return "slb";
8035}
8036
8037static HChar *
8038s390_irgen_SLBG(UChar r1, IRTemp op2addr)
8039{
8040 IRTemp op1 = newTemp(Ity_I64);
8041 IRTemp op2 = newTemp(Ity_I64);
8042 IRTemp result = newTemp(Ity_I64);
8043 IRTemp borrow_in = newTemp(Ity_I64);
8044
8045 assign(op1, get_gpr_dw0(r1));
8046 assign(op2, load(Ity_I64, mkexpr(op2addr)));
8047 assign(borrow_in, unop(Iop_32Uto64, binop(Iop_Sub32, mkU32(1),
8048 binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)))));
8049 assign(result, binop(Iop_Sub64, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)),
8050 mkexpr(borrow_in)));
8051 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_64, op1, op2, borrow_in);
8052 put_gpr_dw0(r1, mkexpr(result));
8053
8054 return "slbg";
8055}
8056
8057static HChar *
8058s390_irgen_SVC(UChar i)
8059{
8060 IRTemp sysno = newTemp(Ity_I64);
8061
8062 if (i != 0) {
8063 assign(sysno, mkU64(i));
8064 } else {
8065 assign(sysno, unop(Iop_32Uto64, get_gpr_w1(1)));
8066 }
8067 system_call(mkexpr(sysno));
8068
8069 return "svc";
8070}
8071
8072static HChar *
sewardj2019a972011-03-07 16:04:07 +00008073s390_irgen_TM(UChar i2, IRTemp op1addr)
8074{
8075 UChar mask;
8076 IRTemp value = newTemp(Ity_I8);
8077
8078 mask = i2;
8079 assign(value, load(Ity_I8, mkexpr(op1addr)));
8080 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_8, value, mktemp(Ity_I8,
8081 mkU8(mask)));
8082
8083 return "tm";
8084}
8085
8086static HChar *
8087s390_irgen_TMY(UChar i2, IRTemp op1addr)
8088{
8089 UChar mask;
8090 IRTemp value = newTemp(Ity_I8);
8091
8092 mask = i2;
8093 assign(value, load(Ity_I8, mkexpr(op1addr)));
8094 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_8, value, mktemp(Ity_I8,
8095 mkU8(mask)));
8096
8097 return "tmy";
8098}
8099
8100static HChar *
8101s390_irgen_TMHH(UChar r1, UShort i2)
8102{
8103 UShort mask;
8104 IRTemp value = newTemp(Ity_I16);
8105
8106 mask = i2;
8107 assign(value, get_gpr_hw0(r1));
8108 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
8109 mkU16(mask)));
8110
8111 return "tmhh";
8112}
8113
8114static HChar *
8115s390_irgen_TMHL(UChar r1, UShort i2)
8116{
8117 UShort mask;
8118 IRTemp value = newTemp(Ity_I16);
8119
8120 mask = i2;
8121 assign(value, get_gpr_hw1(r1));
8122 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
8123 mkU16(mask)));
8124
8125 return "tmhl";
8126}
8127
8128static HChar *
8129s390_irgen_TMLH(UChar r1, UShort i2)
8130{
8131 UShort mask;
8132 IRTemp value = newTemp(Ity_I16);
8133
8134 mask = i2;
8135 assign(value, get_gpr_hw2(r1));
8136 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
8137 mkU16(mask)));
8138
8139 return "tmlh";
8140}
8141
8142static HChar *
8143s390_irgen_TMLL(UChar r1, UShort i2)
8144{
8145 UShort mask;
8146 IRTemp value = newTemp(Ity_I16);
8147
8148 mask = i2;
8149 assign(value, get_gpr_hw3(r1));
8150 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
8151 mkU16(mask)));
8152
8153 return "tmll";
8154}
8155
8156static HChar *
8157s390_irgen_EFPC(UChar r1)
8158{
8159 put_gpr_w1(r1, get_fpc_w0());
8160
8161 return "efpc";
8162}
8163
8164static HChar *
8165s390_irgen_LER(UChar r1, UChar r2)
8166{
8167 put_fpr_w0(r1, get_fpr_w0(r2));
8168
8169 return "ler";
8170}
8171
8172static HChar *
8173s390_irgen_LDR(UChar r1, UChar r2)
8174{
8175 put_fpr_dw0(r1, get_fpr_dw0(r2));
8176
8177 return "ldr";
8178}
8179
8180static HChar *
8181s390_irgen_LXR(UChar r1, UChar r2)
8182{
8183 put_fpr_dw0(r1, get_fpr_dw0(r2));
8184 put_fpr_dw0(r1 + 2, get_fpr_dw0(r2 + 2));
8185
8186 return "lxr";
8187}
8188
8189static HChar *
8190s390_irgen_LE(UChar r1, IRTemp op2addr)
8191{
8192 put_fpr_w0(r1, load(Ity_F32, mkexpr(op2addr)));
8193
8194 return "le";
8195}
8196
8197static HChar *
8198s390_irgen_LD(UChar r1, IRTemp op2addr)
8199{
8200 put_fpr_dw0(r1, load(Ity_F64, mkexpr(op2addr)));
8201
8202 return "ld";
8203}
8204
8205static HChar *
8206s390_irgen_LEY(UChar r1, IRTemp op2addr)
8207{
8208 put_fpr_w0(r1, load(Ity_F32, mkexpr(op2addr)));
8209
8210 return "ley";
8211}
8212
8213static HChar *
8214s390_irgen_LDY(UChar r1, IRTemp op2addr)
8215{
8216 put_fpr_dw0(r1, load(Ity_F64, mkexpr(op2addr)));
8217
8218 return "ldy";
8219}
8220
8221static HChar *
8222s390_irgen_LFPC(IRTemp op2addr)
8223{
8224 put_fpc_w0(load(Ity_I32, mkexpr(op2addr)));
8225
8226 return "lfpc";
8227}
8228
8229static HChar *
8230s390_irgen_LZER(UChar r1)
8231{
8232 put_fpr_w0(r1, mkF32i(0x0));
8233
8234 return "lzer";
8235}
8236
8237static HChar *
8238s390_irgen_LZDR(UChar r1)
8239{
8240 put_fpr_dw0(r1, mkF64i(0x0));
8241
8242 return "lzdr";
8243}
8244
8245static HChar *
8246s390_irgen_LZXR(UChar r1)
8247{
8248 put_fpr_dw0(r1, mkF64i(0x0));
8249 put_fpr_dw0(r1 + 2, mkF64i(0x0));
8250
8251 return "lzxr";
8252}
8253
8254static HChar *
8255s390_irgen_SRNM(IRTemp op2addr)
8256{
florianf0fa1be2012-09-18 20:24:38 +00008257 UInt input_mask, fpc_mask;
sewardj2019a972011-03-07 16:04:07 +00008258
florianf0fa1be2012-09-18 20:24:38 +00008259 input_mask = 3;
8260 fpc_mask = s390_host_has_fpext ? 7 : 3;
sewardj2019a972011-03-07 16:04:07 +00008261
florianf0fa1be2012-09-18 20:24:38 +00008262 put_fpc_w0(binop(Iop_Or32,
8263 binop(Iop_And32, get_fpc_w0(), mkU32(~fpc_mask)),
8264 binop(Iop_And32, unop(Iop_64to32, mkexpr(op2addr)),
8265 mkU32(input_mask))));
sewardj2019a972011-03-07 16:04:07 +00008266 return "srnm";
8267}
8268
8269static HChar *
florianf0fa1be2012-09-18 20:24:38 +00008270s390_irgen_SRNMB(IRTemp op2addr)
8271{
8272 UInt input_mask, fpc_mask;
8273
8274 input_mask = 7;
8275 fpc_mask = 7;
8276
8277 put_fpc_w0(binop(Iop_Or32,
8278 binop(Iop_And32, get_fpc_w0(), mkU32(~fpc_mask)),
8279 binop(Iop_And32, unop(Iop_64to32, mkexpr(op2addr)),
8280 mkU32(input_mask))));
8281 return "srnmb";
8282}
8283
florian81a4bfe2012-09-20 01:25:28 +00008284static void
florianf0fa1be2012-09-18 20:24:38 +00008285s390_irgen_srnmb_wrapper(UChar b2, UShort d2)
8286{
8287 if (b2 == 0) { /* This is the typical case */
8288 if (d2 > 3) {
8289 if (s390_host_has_fpext && d2 == 7) {
8290 /* ok */
8291 } else {
8292 emulation_warning(EmWarn_S390X_invalid_rounding);
florian125e20d2012-10-07 15:42:37 +00008293 d2 = S390_FPC_BFP_ROUND_NEAREST_EVEN;
florianf0fa1be2012-09-18 20:24:38 +00008294 }
8295 }
8296 }
8297
8298 s390_format_S_RD(s390_irgen_SRNMB, b2, d2);
8299}
8300
8301
8302static HChar *
sewardj2019a972011-03-07 16:04:07 +00008303s390_irgen_SFPC(UChar r1)
8304{
8305 put_fpc_w0(get_gpr_w1(r1));
8306
8307 return "sfpc";
8308}
8309
8310static HChar *
8311s390_irgen_STE(UChar r1, IRTemp op2addr)
8312{
8313 store(mkexpr(op2addr), get_fpr_w0(r1));
8314
8315 return "ste";
8316}
8317
8318static HChar *
8319s390_irgen_STD(UChar r1, IRTemp op2addr)
8320{
8321 store(mkexpr(op2addr), get_fpr_dw0(r1));
8322
8323 return "std";
8324}
8325
8326static HChar *
8327s390_irgen_STEY(UChar r1, IRTemp op2addr)
8328{
8329 store(mkexpr(op2addr), get_fpr_w0(r1));
8330
8331 return "stey";
8332}
8333
8334static HChar *
8335s390_irgen_STDY(UChar r1, IRTemp op2addr)
8336{
8337 store(mkexpr(op2addr), get_fpr_dw0(r1));
8338
8339 return "stdy";
8340}
8341
8342static HChar *
8343s390_irgen_STFPC(IRTemp op2addr)
8344{
8345 store(mkexpr(op2addr), get_fpc_w0());
8346
8347 return "stfpc";
8348}
8349
8350static HChar *
8351s390_irgen_AEBR(UChar r1, UChar r2)
8352{
8353 IRTemp op1 = newTemp(Ity_F32);
8354 IRTemp op2 = newTemp(Ity_F32);
8355 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00008356 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008357
8358 assign(op1, get_fpr_w0(r1));
8359 assign(op2, get_fpr_w0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008360 assign(result, triop(Iop_AddF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008361 mkexpr(op2)));
8362 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
8363 put_fpr_w0(r1, mkexpr(result));
8364
8365 return "aebr";
8366}
8367
8368static HChar *
8369s390_irgen_ADBR(UChar r1, UChar r2)
8370{
8371 IRTemp op1 = newTemp(Ity_F64);
8372 IRTemp op2 = newTemp(Ity_F64);
8373 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00008374 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008375
8376 assign(op1, get_fpr_dw0(r1));
8377 assign(op2, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008378 assign(result, triop(Iop_AddF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008379 mkexpr(op2)));
8380 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
8381 put_fpr_dw0(r1, mkexpr(result));
8382
8383 return "adbr";
8384}
8385
8386static HChar *
8387s390_irgen_AEB(UChar r1, IRTemp op2addr)
8388{
8389 IRTemp op1 = newTemp(Ity_F32);
8390 IRTemp op2 = newTemp(Ity_F32);
8391 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00008392 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008393
8394 assign(op1, get_fpr_w0(r1));
8395 assign(op2, load(Ity_F32, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00008396 assign(result, triop(Iop_AddF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008397 mkexpr(op2)));
8398 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
8399 put_fpr_w0(r1, mkexpr(result));
8400
8401 return "aeb";
8402}
8403
8404static HChar *
8405s390_irgen_ADB(UChar r1, IRTemp op2addr)
8406{
8407 IRTemp op1 = newTemp(Ity_F64);
8408 IRTemp op2 = newTemp(Ity_F64);
8409 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00008410 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008411
8412 assign(op1, get_fpr_dw0(r1));
8413 assign(op2, load(Ity_F64, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00008414 assign(result, triop(Iop_AddF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008415 mkexpr(op2)));
8416 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
8417 put_fpr_dw0(r1, mkexpr(result));
8418
8419 return "adb";
8420}
8421
8422static HChar *
florian4b8efad2012-09-02 18:07:08 +00008423s390_irgen_CEFBR(UChar m3, UChar m4 __attribute__((unused)),
8424 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008425{
florian125e20d2012-10-07 15:42:37 +00008426 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian4b8efad2012-09-02 18:07:08 +00008427 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +00008428 m3 = S390_BFP_ROUND_PER_FPC;
florian4b8efad2012-09-02 18:07:08 +00008429 }
sewardj2019a972011-03-07 16:04:07 +00008430 IRTemp op2 = newTemp(Ity_I32);
8431
8432 assign(op2, get_gpr_w1(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008433 put_fpr_w0(r1, binop(Iop_I32StoF32, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +00008434 mkexpr(op2)));
sewardj2019a972011-03-07 16:04:07 +00008435
8436 return "cefbr";
8437}
8438
8439static HChar *
florian4b8efad2012-09-02 18:07:08 +00008440s390_irgen_CDFBR(UChar m3 __attribute__((unused)),
8441 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008442{
8443 IRTemp op2 = newTemp(Ity_I32);
8444
8445 assign(op2, get_gpr_w1(r2));
8446 put_fpr_dw0(r1, unop(Iop_I32StoF64, mkexpr(op2)));
8447
8448 return "cdfbr";
8449}
8450
8451static HChar *
florian4b8efad2012-09-02 18:07:08 +00008452s390_irgen_CEGBR(UChar m3, UChar m4 __attribute__((unused)),
8453 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008454{
florian125e20d2012-10-07 15:42:37 +00008455 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian4b8efad2012-09-02 18:07:08 +00008456 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +00008457 m3 = S390_BFP_ROUND_PER_FPC;
florian4b8efad2012-09-02 18:07:08 +00008458 }
sewardj2019a972011-03-07 16:04:07 +00008459 IRTemp op2 = newTemp(Ity_I64);
8460
8461 assign(op2, get_gpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008462 put_fpr_w0(r1, binop(Iop_I64StoF32, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +00008463 mkexpr(op2)));
sewardj2019a972011-03-07 16:04:07 +00008464
8465 return "cegbr";
8466}
8467
8468static HChar *
florian4b8efad2012-09-02 18:07:08 +00008469s390_irgen_CDGBR(UChar m3, UChar m4 __attribute__((unused)),
8470 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008471{
florian125e20d2012-10-07 15:42:37 +00008472 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian4b8efad2012-09-02 18:07:08 +00008473 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +00008474 m3 = S390_BFP_ROUND_PER_FPC;
florian4b8efad2012-09-02 18:07:08 +00008475 }
sewardj2019a972011-03-07 16:04:07 +00008476 IRTemp op2 = newTemp(Ity_I64);
8477
8478 assign(op2, get_gpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008479 put_fpr_dw0(r1, binop(Iop_I64StoF64, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +00008480 mkexpr(op2)));
sewardj2019a972011-03-07 16:04:07 +00008481
8482 return "cdgbr";
8483}
8484
8485static HChar *
florian1c8f7ff2012-09-01 00:12:11 +00008486s390_irgen_CELFBR(UChar m3, UChar m4 __attribute__((unused)),
8487 UChar r1, UChar r2)
8488{
floriane75dafa2012-09-01 17:54:09 +00008489 if (! s390_host_has_fpext) {
8490 emulation_failure(EmFail_S390X_fpext);
8491 } else {
8492 IRTemp op2 = newTemp(Ity_I32);
florian1c8f7ff2012-09-01 00:12:11 +00008493
floriane75dafa2012-09-01 17:54:09 +00008494 assign(op2, get_gpr_w1(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008495 put_fpr_w0(r1, binop(Iop_I32UtoF32, mkexpr(encode_bfp_rounding_mode(m3)),
floriane75dafa2012-09-01 17:54:09 +00008496 mkexpr(op2)));
8497 }
florian1c8f7ff2012-09-01 00:12:11 +00008498 return "celfbr";
8499}
8500
8501static HChar *
floriand2129202012-09-01 20:01:39 +00008502s390_irgen_CDLFBR(UChar m3 __attribute__((unused)),
8503 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
florian1c8f7ff2012-09-01 00:12:11 +00008504{
floriane75dafa2012-09-01 17:54:09 +00008505 if (! s390_host_has_fpext) {
8506 emulation_failure(EmFail_S390X_fpext);
8507 } else {
8508 IRTemp op2 = newTemp(Ity_I32);
florian1c8f7ff2012-09-01 00:12:11 +00008509
floriane75dafa2012-09-01 17:54:09 +00008510 assign(op2, get_gpr_w1(r2));
8511 put_fpr_dw0(r1, unop(Iop_I32UtoF64, mkexpr(op2)));
8512 }
florian1c8f7ff2012-09-01 00:12:11 +00008513 return "cdlfbr";
8514}
8515
8516static HChar *
8517s390_irgen_CELGBR(UChar m3, UChar m4 __attribute__((unused)),
8518 UChar r1, UChar r2)
8519{
floriane75dafa2012-09-01 17:54:09 +00008520 if (! s390_host_has_fpext) {
8521 emulation_failure(EmFail_S390X_fpext);
8522 } else {
8523 IRTemp op2 = newTemp(Ity_I64);
florian1c8f7ff2012-09-01 00:12:11 +00008524
floriane75dafa2012-09-01 17:54:09 +00008525 assign(op2, get_gpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008526 put_fpr_w0(r1, binop(Iop_I64UtoF32, mkexpr(encode_bfp_rounding_mode(m3)),
floriane75dafa2012-09-01 17:54:09 +00008527 mkexpr(op2)));
8528 }
florian1c8f7ff2012-09-01 00:12:11 +00008529 return "celgbr";
8530}
8531
8532static HChar *
8533s390_irgen_CDLGBR(UChar m3, UChar m4 __attribute__((unused)),
8534 UChar r1, UChar r2)
8535{
floriane75dafa2012-09-01 17:54:09 +00008536 if (! s390_host_has_fpext) {
8537 emulation_failure(EmFail_S390X_fpext);
8538 } else {
8539 IRTemp op2 = newTemp(Ity_I64);
florian1c8f7ff2012-09-01 00:12:11 +00008540
floriane75dafa2012-09-01 17:54:09 +00008541 assign(op2, get_gpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008542 put_fpr_dw0(r1, binop(Iop_I64UtoF64,
8543 mkexpr(encode_bfp_rounding_mode(m3)),
floriane75dafa2012-09-01 17:54:09 +00008544 mkexpr(op2)));
8545 }
florian1c8f7ff2012-09-01 00:12:11 +00008546 return "cdlgbr";
8547}
8548
8549static HChar *
8550s390_irgen_CLFEBR(UChar m3, UChar m4 __attribute__((unused)),
8551 UChar r1, UChar r2)
8552{
floriane75dafa2012-09-01 17:54:09 +00008553 if (! s390_host_has_fpext) {
8554 emulation_failure(EmFail_S390X_fpext);
8555 } else {
8556 IRTemp op = newTemp(Ity_F32);
8557 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +00008558 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +00008559
floriane75dafa2012-09-01 17:54:09 +00008560 assign(op, get_fpr_w0(r2));
florian19e00772012-09-06 03:13:22 +00008561 assign(result, binop(Iop_F32toI32U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +00008562 mkexpr(op)));
8563 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008564 s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_UINT_32, op, rounding_mode);
floriane75dafa2012-09-01 17:54:09 +00008565 }
florian1c8f7ff2012-09-01 00:12:11 +00008566 return "clfebr";
8567}
8568
8569static HChar *
8570s390_irgen_CLFDBR(UChar m3, UChar m4 __attribute__((unused)),
8571 UChar r1, UChar r2)
8572{
floriane75dafa2012-09-01 17:54:09 +00008573 if (! s390_host_has_fpext) {
8574 emulation_failure(EmFail_S390X_fpext);
8575 } else {
8576 IRTemp op = newTemp(Ity_F64);
8577 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +00008578 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +00008579
floriane75dafa2012-09-01 17:54:09 +00008580 assign(op, get_fpr_dw0(r2));
florian19e00772012-09-06 03:13:22 +00008581 assign(result, binop(Iop_F64toI32U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +00008582 mkexpr(op)));
8583 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008584 s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_UINT_32, op, rounding_mode);
floriane75dafa2012-09-01 17:54:09 +00008585 }
florian1c8f7ff2012-09-01 00:12:11 +00008586 return "clfdbr";
8587}
8588
8589static HChar *
8590s390_irgen_CLGEBR(UChar m3, UChar m4 __attribute__((unused)),
8591 UChar r1, UChar r2)
8592{
floriane75dafa2012-09-01 17:54:09 +00008593 if (! s390_host_has_fpext) {
8594 emulation_failure(EmFail_S390X_fpext);
8595 } else {
8596 IRTemp op = newTemp(Ity_F32);
8597 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +00008598 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +00008599
floriane75dafa2012-09-01 17:54:09 +00008600 assign(op, get_fpr_w0(r2));
florian19e00772012-09-06 03:13:22 +00008601 assign(result, binop(Iop_F32toI64U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +00008602 mkexpr(op)));
8603 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008604 s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_UINT_64, op, rounding_mode);
floriane75dafa2012-09-01 17:54:09 +00008605 }
florian1c8f7ff2012-09-01 00:12:11 +00008606 return "clgebr";
8607}
8608
8609static HChar *
8610s390_irgen_CLGDBR(UChar m3, UChar m4 __attribute__((unused)),
8611 UChar r1, UChar r2)
8612{
floriane75dafa2012-09-01 17:54:09 +00008613 if (! s390_host_has_fpext) {
8614 emulation_failure(EmFail_S390X_fpext);
8615 } else {
8616 IRTemp op = newTemp(Ity_F64);
8617 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +00008618 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +00008619
floriane75dafa2012-09-01 17:54:09 +00008620 assign(op, get_fpr_dw0(r2));
florian19e00772012-09-06 03:13:22 +00008621 assign(result, binop(Iop_F64toI64U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +00008622 mkexpr(op)));
8623 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008624 s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_UINT_64, op, rounding_mode);
floriane75dafa2012-09-01 17:54:09 +00008625 }
florian1c8f7ff2012-09-01 00:12:11 +00008626 return "clgdbr";
8627}
8628
8629static HChar *
florian4b8efad2012-09-02 18:07:08 +00008630s390_irgen_CFEBR(UChar m3, UChar m4 __attribute__((unused)),
8631 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008632{
8633 IRTemp op = newTemp(Ity_F32);
8634 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +00008635 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +00008636
8637 assign(op, get_fpr_w0(r2));
florian19e00772012-09-06 03:13:22 +00008638 assign(result, binop(Iop_F32toI32S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +00008639 mkexpr(op)));
8640 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008641 s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_INT_32, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +00008642
8643 return "cfebr";
8644}
8645
8646static HChar *
florian4b8efad2012-09-02 18:07:08 +00008647s390_irgen_CFDBR(UChar m3, UChar m4 __attribute__((unused)),
8648 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008649{
8650 IRTemp op = newTemp(Ity_F64);
8651 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +00008652 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +00008653
8654 assign(op, get_fpr_dw0(r2));
florian19e00772012-09-06 03:13:22 +00008655 assign(result, binop(Iop_F64toI32S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +00008656 mkexpr(op)));
8657 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008658 s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_INT_32, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +00008659
8660 return "cfdbr";
8661}
8662
8663static HChar *
florian4b8efad2012-09-02 18:07:08 +00008664s390_irgen_CGEBR(UChar m3, UChar m4 __attribute__((unused)),
8665 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008666{
8667 IRTemp op = newTemp(Ity_F32);
8668 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +00008669 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +00008670
8671 assign(op, get_fpr_w0(r2));
florian19e00772012-09-06 03:13:22 +00008672 assign(result, binop(Iop_F32toI64S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +00008673 mkexpr(op)));
8674 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008675 s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_INT_64, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +00008676
8677 return "cgebr";
8678}
8679
8680static HChar *
florian4b8efad2012-09-02 18:07:08 +00008681s390_irgen_CGDBR(UChar m3, UChar m4 __attribute__((unused)),
8682 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008683{
8684 IRTemp op = newTemp(Ity_F64);
8685 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +00008686 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +00008687
8688 assign(op, get_fpr_dw0(r2));
florian19e00772012-09-06 03:13:22 +00008689 assign(result, binop(Iop_F64toI64S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +00008690 mkexpr(op)));
8691 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008692 s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_INT_64, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +00008693
8694 return "cgdbr";
8695}
8696
8697static HChar *
8698s390_irgen_DEBR(UChar r1, UChar r2)
8699{
8700 IRTemp op1 = newTemp(Ity_F32);
8701 IRTemp op2 = newTemp(Ity_F32);
8702 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00008703 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008704
8705 assign(op1, get_fpr_w0(r1));
8706 assign(op2, get_fpr_w0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008707 assign(result, triop(Iop_DivF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008708 mkexpr(op2)));
8709 put_fpr_w0(r1, mkexpr(result));
8710
8711 return "debr";
8712}
8713
8714static HChar *
8715s390_irgen_DDBR(UChar r1, UChar r2)
8716{
8717 IRTemp op1 = newTemp(Ity_F64);
8718 IRTemp op2 = newTemp(Ity_F64);
8719 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00008720 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008721
8722 assign(op1, get_fpr_dw0(r1));
8723 assign(op2, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008724 assign(result, triop(Iop_DivF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008725 mkexpr(op2)));
8726 put_fpr_dw0(r1, mkexpr(result));
8727
8728 return "ddbr";
8729}
8730
8731static HChar *
8732s390_irgen_DEB(UChar r1, IRTemp op2addr)
8733{
8734 IRTemp op1 = newTemp(Ity_F32);
8735 IRTemp op2 = newTemp(Ity_F32);
8736 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00008737 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008738
8739 assign(op1, get_fpr_w0(r1));
8740 assign(op2, load(Ity_F32, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00008741 assign(result, triop(Iop_DivF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008742 mkexpr(op2)));
8743 put_fpr_w0(r1, mkexpr(result));
8744
8745 return "deb";
8746}
8747
8748static HChar *
8749s390_irgen_DDB(UChar r1, IRTemp op2addr)
8750{
8751 IRTemp op1 = newTemp(Ity_F64);
8752 IRTemp op2 = newTemp(Ity_F64);
8753 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00008754 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008755
8756 assign(op1, get_fpr_dw0(r1));
8757 assign(op2, load(Ity_F64, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00008758 assign(result, triop(Iop_DivF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008759 mkexpr(op2)));
8760 put_fpr_dw0(r1, mkexpr(result));
8761
8762 return "ddb";
8763}
8764
8765static HChar *
8766s390_irgen_LTEBR(UChar r1, UChar r2)
8767{
8768 IRTemp result = newTemp(Ity_F32);
8769
8770 assign(result, get_fpr_w0(r2));
8771 put_fpr_w0(r1, mkexpr(result));
8772 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
8773
8774 return "ltebr";
8775}
8776
8777static HChar *
8778s390_irgen_LTDBR(UChar r1, UChar r2)
8779{
8780 IRTemp result = newTemp(Ity_F64);
8781
8782 assign(result, get_fpr_dw0(r2));
8783 put_fpr_dw0(r1, mkexpr(result));
8784 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
8785
8786 return "ltdbr";
8787}
8788
8789static HChar *
8790s390_irgen_LCEBR(UChar r1, UChar r2)
8791{
8792 IRTemp result = newTemp(Ity_F32);
8793
8794 assign(result, unop(Iop_NegF32, get_fpr_w0(r2)));
8795 put_fpr_w0(r1, mkexpr(result));
8796 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
8797
8798 return "lcebr";
8799}
8800
8801static HChar *
8802s390_irgen_LCDBR(UChar r1, UChar r2)
8803{
8804 IRTemp result = newTemp(Ity_F64);
8805
8806 assign(result, unop(Iop_NegF64, get_fpr_dw0(r2)));
8807 put_fpr_dw0(r1, mkexpr(result));
8808 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
8809
8810 return "lcdbr";
8811}
8812
8813static HChar *
8814s390_irgen_LDEBR(UChar r1, UChar r2)
8815{
8816 IRTemp op = newTemp(Ity_F32);
8817
8818 assign(op, get_fpr_w0(r2));
8819 put_fpr_dw0(r1, unop(Iop_F32toF64, mkexpr(op)));
8820
8821 return "ldebr";
8822}
8823
8824static HChar *
8825s390_irgen_LDEB(UChar r1, IRTemp op2addr)
8826{
8827 IRTemp op = newTemp(Ity_F32);
8828
8829 assign(op, load(Ity_F32, mkexpr(op2addr)));
8830 put_fpr_dw0(r1, unop(Iop_F32toF64, mkexpr(op)));
8831
8832 return "ldeb";
8833}
8834
8835static HChar *
florian4b8efad2012-09-02 18:07:08 +00008836s390_irgen_LEDBR(UChar m3, UChar m4 __attribute__((unused)),
8837 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008838{
florian125e20d2012-10-07 15:42:37 +00008839 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian12b0bca2012-09-05 20:05:20 +00008840 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +00008841 m3 = S390_BFP_ROUND_PER_FPC;
florian12b0bca2012-09-05 20:05:20 +00008842 }
sewardj2019a972011-03-07 16:04:07 +00008843 IRTemp op = newTemp(Ity_F64);
8844
8845 assign(op, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008846 put_fpr_w0(r1, binop(Iop_F64toF32, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +00008847 mkexpr(op)));
sewardj2019a972011-03-07 16:04:07 +00008848
8849 return "ledbr";
8850}
8851
8852static HChar *
8853s390_irgen_MEEBR(UChar r1, UChar r2)
8854{
8855 IRTemp op1 = newTemp(Ity_F32);
8856 IRTemp op2 = newTemp(Ity_F32);
8857 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00008858 IRRoundingMode rounding_mode =
8859 encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008860
8861 assign(op1, get_fpr_w0(r1));
8862 assign(op2, get_fpr_w0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008863 assign(result, triop(Iop_MulF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008864 mkexpr(op2)));
8865 put_fpr_w0(r1, mkexpr(result));
8866
8867 return "meebr";
8868}
8869
8870static HChar *
8871s390_irgen_MDBR(UChar r1, UChar r2)
8872{
8873 IRTemp op1 = newTemp(Ity_F64);
8874 IRTemp op2 = newTemp(Ity_F64);
8875 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00008876 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008877
8878 assign(op1, get_fpr_dw0(r1));
8879 assign(op2, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008880 assign(result, triop(Iop_MulF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008881 mkexpr(op2)));
8882 put_fpr_dw0(r1, mkexpr(result));
8883
8884 return "mdbr";
8885}
8886
8887static HChar *
8888s390_irgen_MEEB(UChar r1, IRTemp op2addr)
8889{
8890 IRTemp op1 = newTemp(Ity_F32);
8891 IRTemp op2 = newTemp(Ity_F32);
8892 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00008893 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008894
8895 assign(op1, get_fpr_w0(r1));
8896 assign(op2, load(Ity_F32, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00008897 assign(result, triop(Iop_MulF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008898 mkexpr(op2)));
8899 put_fpr_w0(r1, mkexpr(result));
8900
8901 return "meeb";
8902}
8903
8904static HChar *
8905s390_irgen_MDB(UChar r1, IRTemp op2addr)
8906{
8907 IRTemp op1 = newTemp(Ity_F64);
8908 IRTemp op2 = newTemp(Ity_F64);
8909 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00008910 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008911
8912 assign(op1, get_fpr_dw0(r1));
8913 assign(op2, load(Ity_F64, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00008914 assign(result, triop(Iop_MulF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008915 mkexpr(op2)));
8916 put_fpr_dw0(r1, mkexpr(result));
8917
8918 return "mdb";
8919}
8920
8921static HChar *
8922s390_irgen_SEBR(UChar r1, UChar r2)
8923{
8924 IRTemp op1 = newTemp(Ity_F32);
8925 IRTemp op2 = newTemp(Ity_F32);
8926 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00008927 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008928
8929 assign(op1, get_fpr_w0(r1));
8930 assign(op2, get_fpr_w0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008931 assign(result, triop(Iop_SubF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008932 mkexpr(op2)));
8933 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
8934 put_fpr_w0(r1, mkexpr(result));
8935
8936 return "sebr";
8937}
8938
8939static HChar *
8940s390_irgen_SDBR(UChar r1, UChar r2)
8941{
8942 IRTemp op1 = newTemp(Ity_F64);
8943 IRTemp op2 = newTemp(Ity_F64);
8944 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00008945 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008946
8947 assign(op1, get_fpr_dw0(r1));
8948 assign(op2, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008949 assign(result, triop(Iop_SubF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008950 mkexpr(op2)));
8951 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
8952 put_fpr_dw0(r1, mkexpr(result));
8953
8954 return "sdbr";
8955}
8956
8957static HChar *
8958s390_irgen_SEB(UChar r1, IRTemp op2addr)
8959{
8960 IRTemp op1 = newTemp(Ity_F32);
8961 IRTemp op2 = newTemp(Ity_F32);
8962 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00008963 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008964
8965 assign(op1, get_fpr_w0(r1));
8966 assign(op2, load(Ity_F32, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00008967 assign(result, triop(Iop_SubF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008968 mkexpr(op2)));
8969 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
8970 put_fpr_w0(r1, mkexpr(result));
8971
8972 return "seb";
8973}
8974
8975static HChar *
8976s390_irgen_SDB(UChar r1, IRTemp op2addr)
8977{
8978 IRTemp op1 = newTemp(Ity_F64);
8979 IRTemp op2 = newTemp(Ity_F64);
8980 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00008981 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008982
8983 assign(op1, get_fpr_dw0(r1));
8984 assign(op2, load(Ity_F64, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00008985 assign(result, triop(Iop_SubF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008986 mkexpr(op2)));
8987 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
8988 put_fpr_dw0(r1, mkexpr(result));
8989
8990 return "sdb";
8991}
8992
8993
8994static HChar *
8995s390_irgen_CLC(UChar length, IRTemp start1, IRTemp start2)
8996{
florian79e839e2012-05-05 02:20:30 +00008997 IRTemp len = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00008998
florian79e839e2012-05-05 02:20:30 +00008999 assign(len, mkU64(length));
9000 s390_irgen_CLC_EX(len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +00009001
9002 return "clc";
9003}
9004
9005static HChar *
florianb0c9a132011-09-08 15:37:39 +00009006s390_irgen_CLCL(UChar r1, UChar r2)
9007{
9008 IRTemp addr1 = newTemp(Ity_I64);
9009 IRTemp addr2 = newTemp(Ity_I64);
9010 IRTemp addr1_load = newTemp(Ity_I64);
9011 IRTemp addr2_load = newTemp(Ity_I64);
9012 IRTemp len1 = newTemp(Ity_I32);
9013 IRTemp len2 = newTemp(Ity_I32);
9014 IRTemp r1p1 = newTemp(Ity_I32); /* contents of r1 + 1 */
9015 IRTemp r2p1 = newTemp(Ity_I32); /* contents of r2 + 1 */
9016 IRTemp single1 = newTemp(Ity_I8);
9017 IRTemp single2 = newTemp(Ity_I8);
9018 IRTemp pad = newTemp(Ity_I8);
9019
9020 assign(addr1, get_gpr_dw0(r1));
9021 assign(r1p1, get_gpr_w1(r1 + 1));
9022 assign(len1, binop(Iop_And32, mkexpr(r1p1), mkU32(0x00ffffff)));
9023 assign(addr2, get_gpr_dw0(r2));
9024 assign(r2p1, get_gpr_w1(r2 + 1));
9025 assign(len2, binop(Iop_And32, mkexpr(r2p1), mkU32(0x00ffffff)));
9026 assign(pad, get_gpr_b4(r2 + 1));
9027
9028 /* len1 == 0 and len2 == 0? Exit */
9029 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +00009030 next_insn_if(binop(Iop_CmpEQ32, binop(Iop_Or32, mkexpr(len1),
9031 mkexpr(len2)), mkU32(0)));
florianb0c9a132011-09-08 15:37:39 +00009032
9033 /* Because mkite evaluates both the then-clause and the else-clause
9034 we cannot load directly from addr1 here. If len1 is 0, then adddr1
9035 may be NULL and loading from there would segfault. So we provide a
9036 valid dummy address in that case. Loading from there does no harm and
9037 the value will be discarded at runtime. */
9038 assign(addr1_load,
9039 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
9040 mkU64(guest_IA_curr_instr), mkexpr(addr1)));
9041 assign(single1,
9042 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
9043 mkexpr(pad), load(Ity_I8, mkexpr(addr1_load))));
9044
9045 assign(addr2_load,
9046 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
9047 mkU64(guest_IA_curr_instr), mkexpr(addr2)));
9048 assign(single2,
9049 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
9050 mkexpr(pad), load(Ity_I8, mkexpr(addr2_load))));
9051
9052 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, single1, single2, False);
9053 /* Fields differ ? */
florian6820ba52012-07-26 02:01:50 +00009054 next_insn_if(binop(Iop_CmpNE8, mkexpr(single1), mkexpr(single2)));
florianb0c9a132011-09-08 15:37:39 +00009055
9056 /* Update len1 and addr1, unless len1 == 0. */
9057 put_gpr_dw0(r1,
9058 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
9059 mkexpr(addr1),
9060 binop(Iop_Add64, mkexpr(addr1), mkU64(1))));
9061
9062 /* When updating len1 we must not modify bits (r1+1)[0:39] */
9063 put_gpr_w1(r1 + 1,
9064 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
9065 binop(Iop_And32, mkexpr(r1p1), mkU32(0xFF000000u)),
9066 binop(Iop_Sub32, mkexpr(r1p1), mkU32(1))));
9067
9068 /* Update len2 and addr2, unless len2 == 0. */
9069 put_gpr_dw0(r2,
9070 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
9071 mkexpr(addr2),
9072 binop(Iop_Add64, mkexpr(addr2), mkU64(1))));
9073
9074 /* When updating len2 we must not modify bits (r2+1)[0:39] */
9075 put_gpr_w1(r2 + 1,
9076 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
9077 binop(Iop_And32, mkexpr(r2p1), mkU32(0xFF000000u)),
9078 binop(Iop_Sub32, mkexpr(r2p1), mkU32(1))));
9079
florian6820ba52012-07-26 02:01:50 +00009080 iterate();
florianb0c9a132011-09-08 15:37:39 +00009081
9082 return "clcl";
9083}
9084
9085static HChar *
sewardj2019a972011-03-07 16:04:07 +00009086s390_irgen_CLCLE(UChar r1, UChar r3, IRTemp pad2)
9087{
9088 IRTemp addr1, addr3, addr1_load, addr3_load, len1, len3, single1, single3;
9089
9090 addr1 = newTemp(Ity_I64);
9091 addr3 = newTemp(Ity_I64);
9092 addr1_load = newTemp(Ity_I64);
9093 addr3_load = newTemp(Ity_I64);
9094 len1 = newTemp(Ity_I64);
9095 len3 = newTemp(Ity_I64);
9096 single1 = newTemp(Ity_I8);
9097 single3 = newTemp(Ity_I8);
9098
9099 assign(addr1, get_gpr_dw0(r1));
9100 assign(len1, get_gpr_dw0(r1 + 1));
9101 assign(addr3, get_gpr_dw0(r3));
9102 assign(len3, get_gpr_dw0(r3 + 1));
9103
9104 /* len1 == 0 and len3 == 0? Exit */
9105 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +00009106 next_insn_if(binop(Iop_CmpEQ64,binop(Iop_Or64, mkexpr(len1),
9107 mkexpr(len3)), mkU64(0)));
sewardj2019a972011-03-07 16:04:07 +00009108
9109 /* A mux requires both ways to be possible. This is a way to prevent clcle
9110 from reading from addr1 if it should read from the pad. Since the pad
9111 has no address, just read from the instruction, we discard that anyway */
9112 assign(addr1_load,
florian6ad49522011-09-09 02:38:55 +00009113 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
9114 mkU64(guest_IA_curr_instr), mkexpr(addr1)));
sewardj2019a972011-03-07 16:04:07 +00009115
9116 /* same for addr3 */
9117 assign(addr3_load,
florian6ad49522011-09-09 02:38:55 +00009118 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
9119 mkU64(guest_IA_curr_instr), mkexpr(addr3)));
sewardj2019a972011-03-07 16:04:07 +00009120
9121 assign(single1,
florian6ad49522011-09-09 02:38:55 +00009122 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
9123 unop(Iop_64to8, mkexpr(pad2)),
9124 load(Ity_I8, mkexpr(addr1_load))));
sewardj2019a972011-03-07 16:04:07 +00009125
9126 assign(single3,
florian6ad49522011-09-09 02:38:55 +00009127 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
9128 unop(Iop_64to8, mkexpr(pad2)),
9129 load(Ity_I8, mkexpr(addr3_load))));
sewardj2019a972011-03-07 16:04:07 +00009130
9131 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, single1, single3, False);
9132 /* Both fields differ ? */
florian6820ba52012-07-26 02:01:50 +00009133 next_insn_if(binop(Iop_CmpNE8, mkexpr(single1), mkexpr(single3)));
sewardj2019a972011-03-07 16:04:07 +00009134
9135 /* If a length in 0 we must not change this length and the address */
9136 put_gpr_dw0(r1,
florian6ad49522011-09-09 02:38:55 +00009137 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
9138 mkexpr(addr1),
9139 binop(Iop_Add64, mkexpr(addr1), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +00009140
9141 put_gpr_dw0(r1 + 1,
florian6ad49522011-09-09 02:38:55 +00009142 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
9143 mkU64(0), binop(Iop_Sub64, mkexpr(len1), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +00009144
9145 put_gpr_dw0(r3,
florian6ad49522011-09-09 02:38:55 +00009146 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
9147 mkexpr(addr3),
9148 binop(Iop_Add64, mkexpr(addr3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +00009149
9150 put_gpr_dw0(r3 + 1,
florian6ad49522011-09-09 02:38:55 +00009151 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
9152 mkU64(0), binop(Iop_Sub64, mkexpr(len3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +00009153
florian6820ba52012-07-26 02:01:50 +00009154 iterate();
sewardj2019a972011-03-07 16:04:07 +00009155
9156 return "clcle";
9157}
floriana64c2432011-07-16 02:11:50 +00009158
florianb0bf6602012-05-05 00:01:16 +00009159
sewardj2019a972011-03-07 16:04:07 +00009160static void
9161s390_irgen_XC_EX(IRTemp length, IRTemp start1, IRTemp start2)
9162{
florianb0bf6602012-05-05 00:01:16 +00009163 s390_irgen_xonc(Iop_Xor8, length, start1, start2);
9164}
sewardj2019a972011-03-07 16:04:07 +00009165
sewardj2019a972011-03-07 16:04:07 +00009166
florianb0bf6602012-05-05 00:01:16 +00009167static void
9168s390_irgen_NC_EX(IRTemp length, IRTemp start1, IRTemp start2)
9169{
9170 s390_irgen_xonc(Iop_And8, length, start1, start2);
9171}
sewardj2019a972011-03-07 16:04:07 +00009172
sewardj2019a972011-03-07 16:04:07 +00009173
florianb0bf6602012-05-05 00:01:16 +00009174static void
9175s390_irgen_OC_EX(IRTemp length, IRTemp start1, IRTemp start2)
9176{
9177 s390_irgen_xonc(Iop_Or8, length, start1, start2);
sewardj2019a972011-03-07 16:04:07 +00009178}
9179
9180
9181static void
9182s390_irgen_CLC_EX(IRTemp length, IRTemp start1, IRTemp start2)
9183{
9184 IRTemp current1 = newTemp(Ity_I8);
9185 IRTemp current2 = newTemp(Ity_I8);
9186 IRTemp counter = newTemp(Ity_I64);
9187
9188 assign(counter, get_counter_dw0());
9189 put_counter_dw0(mkU64(0));
9190
9191 assign(current1, load(Ity_I8, binop(Iop_Add64, mkexpr(start1),
9192 mkexpr(counter))));
9193 assign(current2, load(Ity_I8, binop(Iop_Add64, mkexpr(start2),
9194 mkexpr(counter))));
9195 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, current1, current2,
9196 False);
9197
9198 /* Both fields differ ? */
florian6820ba52012-07-26 02:01:50 +00009199 next_insn_if(binop(Iop_CmpNE8, mkexpr(current1), mkexpr(current2)));
sewardj2019a972011-03-07 16:04:07 +00009200
9201 /* Check for end of field */
9202 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
florian6820ba52012-07-26 02:01:50 +00009203 iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)));
sewardj2019a972011-03-07 16:04:07 +00009204 put_counter_dw0(mkU64(0));
9205}
9206
9207static void
9208s390_irgen_MVC_EX(IRTemp length, IRTemp start1, IRTemp start2)
9209{
9210 IRTemp counter = newTemp(Ity_I64);
9211
9212 assign(counter, get_counter_dw0());
9213
9214 store(binop(Iop_Add64, mkexpr(start1), mkexpr(counter)),
9215 load(Ity_I8, binop(Iop_Add64, mkexpr(start2), mkexpr(counter))));
9216
9217 /* Check for end of field */
9218 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
florian6820ba52012-07-26 02:01:50 +00009219 iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)));
sewardj2019a972011-03-07 16:04:07 +00009220 put_counter_dw0(mkU64(0));
9221}
9222
florianf87d4fb2012-05-05 02:55:24 +00009223static void
9224s390_irgen_TR_EX(IRTemp length, IRTemp start1, IRTemp start2)
9225{
9226 IRTemp op = newTemp(Ity_I8);
9227 IRTemp op1 = newTemp(Ity_I8);
9228 IRTemp result = newTemp(Ity_I64);
9229 IRTemp counter = newTemp(Ity_I64);
9230
9231 assign(counter, get_counter_dw0());
9232
9233 assign(op, load(Ity_I8, binop(Iop_Add64, mkexpr(start1), mkexpr(counter))));
9234
9235 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)), mkexpr(start2)));
9236
9237 assign(op1, load(Ity_I8, mkexpr(result)));
9238 store(binop(Iop_Add64, mkexpr(start1), mkexpr(counter)), mkexpr(op1));
9239
9240 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
florian6820ba52012-07-26 02:01:50 +00009241 iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)));
florianf87d4fb2012-05-05 02:55:24 +00009242 put_counter_dw0(mkU64(0));
9243}
sewardj2019a972011-03-07 16:04:07 +00009244
9245
9246static void
9247s390_irgen_EX_SS(UChar r, IRTemp addr2,
florian6820ba52012-07-26 02:01:50 +00009248 void (*irgen)(IRTemp length, IRTemp start1, IRTemp start2),
9249 int lensize)
sewardj2019a972011-03-07 16:04:07 +00009250{
9251 struct SS {
9252 unsigned int op : 8;
9253 unsigned int l : 8;
9254 unsigned int b1 : 4;
9255 unsigned int d1 : 12;
9256 unsigned int b2 : 4;
9257 unsigned int d2 : 12;
9258 };
9259 union {
9260 struct SS dec;
9261 unsigned long bytes;
9262 } ss;
9263 IRTemp cond;
9264 IRDirty *d;
9265 IRTemp torun;
9266
9267 IRTemp start1 = newTemp(Ity_I64);
9268 IRTemp start2 = newTemp(Ity_I64);
9269 IRTemp len = newTemp(lensize == 64 ? Ity_I64 : Ity_I32);
9270 cond = newTemp(Ity_I1);
9271 torun = newTemp(Ity_I64);
9272
9273 assign(torun, load(Ity_I64, mkexpr(addr2)));
9274 /* Start with a check that the saved code is still correct */
9275 assign(cond, binop(Iop_CmpNE64, mkexpr(torun), mkU64(last_execute_target)));
9276 /* If not, save the new value */
9277 d = unsafeIRDirty_0_N (0, "s390x_dirtyhelper_EX", &s390x_dirtyhelper_EX,
9278 mkIRExprVec_1(mkexpr(torun)));
9279 d->guard = mkexpr(cond);
9280 stmt(IRStmt_Dirty(d));
9281
9282 /* and restart */
florian428dfdd2012-03-27 03:09:49 +00009283 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TISTART),
9284 mkU64(guest_IA_curr_instr)));
9285 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TILEN), mkU64(4)));
florian6820ba52012-07-26 02:01:50 +00009286 restart_if(mkexpr(cond));
sewardj2019a972011-03-07 16:04:07 +00009287
9288 ss.bytes = last_execute_target;
9289 assign(start1, binop(Iop_Add64, mkU64(ss.dec.d1),
9290 ss.dec.b1 != 0 ? get_gpr_dw0(ss.dec.b1) : mkU64(0)));
9291 assign(start2, binop(Iop_Add64, mkU64(ss.dec.d2),
9292 ss.dec.b2 != 0 ? get_gpr_dw0(ss.dec.b2) : mkU64(0)));
9293 assign(len, unop(lensize == 64 ? Iop_8Uto64 : Iop_8Uto32, binop(Iop_Or8,
9294 r != 0 ? get_gpr_b7(r): mkU8(0), mkU8(ss.dec.l))));
9295 irgen(len, start1, start2);
florian8844a632012-04-13 04:04:06 +00009296
sewardj2019a972011-03-07 16:04:07 +00009297 last_execute_target = 0;
9298}
9299
9300static HChar *
9301s390_irgen_EX(UChar r1, IRTemp addr2)
9302{
9303 switch(last_execute_target & 0xff00000000000000ULL) {
9304 case 0:
9305 {
9306 /* no code information yet */
9307 IRDirty *d;
9308
9309 /* so safe the code... */
9310 d = unsafeIRDirty_0_N (0, "s390x_dirtyhelper_EX", &s390x_dirtyhelper_EX,
9311 mkIRExprVec_1(load(Ity_I64, mkexpr(addr2))));
9312 stmt(IRStmt_Dirty(d));
9313 /* and restart */
florian428dfdd2012-03-27 03:09:49 +00009314 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TISTART),
9315 mkU64(guest_IA_curr_instr)));
9316 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TILEN), mkU64(4)));
florian6820ba52012-07-26 02:01:50 +00009317 restart_if(IRExpr_Const(IRConst_U1(True)));
9318
sewardj2019a972011-03-07 16:04:07 +00009319 /* we know that this will be invalidated */
florianf9e1ed72012-04-17 02:41:56 +00009320 put_IA(mkaddr_expr(guest_IA_next_instr));
sewardj2019a972011-03-07 16:04:07 +00009321 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +00009322 dis_res->jk_StopHere = Ijk_TInval;
sewardj2019a972011-03-07 16:04:07 +00009323 break;
9324 }
9325
9326 case 0xd200000000000000ULL:
9327 /* special case MVC */
9328 s390_irgen_EX_SS(r1, addr2, s390_irgen_MVC_EX, 64);
9329 return "mvc via ex";
9330
9331 case 0xd500000000000000ULL:
9332 /* special case CLC */
9333 s390_irgen_EX_SS(r1, addr2, s390_irgen_CLC_EX, 64);
9334 return "clc via ex";
9335
9336 case 0xd700000000000000ULL:
9337 /* special case XC */
9338 s390_irgen_EX_SS(r1, addr2, s390_irgen_XC_EX, 32);
9339 return "xc via ex";
9340
florianb0bf6602012-05-05 00:01:16 +00009341 case 0xd600000000000000ULL:
9342 /* special case OC */
9343 s390_irgen_EX_SS(r1, addr2, s390_irgen_OC_EX, 32);
9344 return "oc via ex";
9345
9346 case 0xd400000000000000ULL:
9347 /* special case NC */
9348 s390_irgen_EX_SS(r1, addr2, s390_irgen_NC_EX, 32);
9349 return "nc via ex";
sewardj2019a972011-03-07 16:04:07 +00009350
florianf87d4fb2012-05-05 02:55:24 +00009351 case 0xdc00000000000000ULL:
9352 /* special case TR */
9353 s390_irgen_EX_SS(r1, addr2, s390_irgen_TR_EX, 64);
9354 return "tr via ex";
9355
sewardj2019a972011-03-07 16:04:07 +00009356 default:
9357 {
9358 /* everything else will get a self checking prefix that also checks the
9359 register content */
9360 IRDirty *d;
9361 UChar *bytes;
9362 IRTemp cond;
9363 IRTemp orperand;
9364 IRTemp torun;
9365
9366 cond = newTemp(Ity_I1);
9367 orperand = newTemp(Ity_I64);
9368 torun = newTemp(Ity_I64);
9369
9370 if (r1 == 0)
9371 assign(orperand, mkU64(0));
9372 else
9373 assign(orperand, unop(Iop_8Uto64,get_gpr_b7(r1)));
9374 /* This code is going to be translated */
9375 assign(torun, binop(Iop_Or64, load(Ity_I64, mkexpr(addr2)),
9376 binop(Iop_Shl64, mkexpr(orperand), mkU8(48))));
9377
9378 /* Start with a check that saved code is still correct */
9379 assign(cond, binop(Iop_CmpNE64, mkexpr(torun),
9380 mkU64(last_execute_target)));
9381 /* If not, save the new value */
9382 d = unsafeIRDirty_0_N (0, "s390x_dirtyhelper_EX", &s390x_dirtyhelper_EX,
9383 mkIRExprVec_1(mkexpr(torun)));
9384 d->guard = mkexpr(cond);
9385 stmt(IRStmt_Dirty(d));
9386
9387 /* and restart */
florian428dfdd2012-03-27 03:09:49 +00009388 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TISTART), mkU64(guest_IA_curr_instr)));
9389 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TILEN), mkU64(4)));
florian6820ba52012-07-26 02:01:50 +00009390 restart_if(mkexpr(cond));
sewardj2019a972011-03-07 16:04:07 +00009391
9392 /* Now comes the actual translation */
9393 bytes = (UChar *) &last_execute_target;
9394 s390_decode_and_irgen(bytes, ((((bytes[0] >> 6) + 1) >> 1) + 1) << 1,
9395 dis_res);
sewardj7ee97522011-05-09 21:45:04 +00009396 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00009397 vex_printf(" which was executed by\n");
9398 /* dont make useless translations in the next execute */
9399 last_execute_target = 0;
9400 }
9401 }
9402 return "ex";
9403}
9404
9405static HChar *
9406s390_irgen_EXRL(UChar r1, UInt offset)
9407{
9408 IRTemp addr = newTemp(Ity_I64);
9409 /* we might save one round trip because we know the target */
9410 if (!last_execute_target)
9411 last_execute_target = *(ULong *)(HWord)
9412 (guest_IA_curr_instr + offset * 2UL);
9413 assign(addr, mkU64(guest_IA_curr_instr + offset * 2UL));
9414 s390_irgen_EX(r1, addr);
9415 return "exrl";
9416}
9417
9418static HChar *
9419s390_irgen_IPM(UChar r1)
9420{
9421 // As long as we dont support SPM, lets just assume 0 as program mask
9422 put_gpr_b4(r1, unop(Iop_32to8, binop(Iop_Or32, mkU32(0 /* program mask */),
9423 binop(Iop_Shl32, s390_call_calculate_cc(), mkU8(4)))));
9424
9425 return "ipm";
9426}
9427
9428
9429static HChar *
9430s390_irgen_SRST(UChar r1, UChar r2)
9431{
9432 IRTemp address = newTemp(Ity_I64);
9433 IRTemp next = newTemp(Ity_I64);
9434 IRTemp delim = newTemp(Ity_I8);
9435 IRTemp counter = newTemp(Ity_I64);
9436 IRTemp byte = newTemp(Ity_I8);
9437
9438 assign(address, get_gpr_dw0(r2));
9439 assign(next, get_gpr_dw0(r1));
9440
9441 assign(counter, get_counter_dw0());
9442 put_counter_dw0(mkU64(0));
9443
9444 // start = next? CC=2 and out r1 and r2 unchanged
9445 s390_cc_set(2);
9446 put_gpr_dw0(r2, binop(Iop_Sub64, mkexpr(address), mkexpr(counter)));
florian6820ba52012-07-26 02:01:50 +00009447 next_insn_if(binop(Iop_CmpEQ64, mkexpr(address), mkexpr(next)));
sewardj2019a972011-03-07 16:04:07 +00009448
9449 assign(byte, load(Ity_I8, mkexpr(address)));
9450 assign(delim, get_gpr_b7(0));
9451
9452 // byte = delim? CC=1, R1=address
9453 s390_cc_set(1);
9454 put_gpr_dw0(r1, mkexpr(address));
florian6820ba52012-07-26 02:01:50 +00009455 next_insn_if(binop(Iop_CmpEQ8, mkexpr(delim), mkexpr(byte)));
sewardj2019a972011-03-07 16:04:07 +00009456
9457 // else: all equal, no end yet, loop
9458 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
9459 put_gpr_dw0(r1, mkexpr(next));
9460 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(address), mkU64(1)));
floriancf87c942012-07-25 00:52:21 +00009461
florian6820ba52012-07-26 02:01:50 +00009462 iterate();
sewardj2019a972011-03-07 16:04:07 +00009463
9464 return "srst";
9465}
9466
9467static HChar *
9468s390_irgen_CLST(UChar r1, UChar r2)
9469{
9470 IRTemp address1 = newTemp(Ity_I64);
9471 IRTemp address2 = newTemp(Ity_I64);
9472 IRTemp end = newTemp(Ity_I8);
9473 IRTemp counter = newTemp(Ity_I64);
9474 IRTemp byte1 = newTemp(Ity_I8);
9475 IRTemp byte2 = newTemp(Ity_I8);
9476
9477 assign(address1, get_gpr_dw0(r1));
9478 assign(address2, get_gpr_dw0(r2));
9479 assign(end, get_gpr_b7(0));
9480 assign(counter, get_counter_dw0());
9481 put_counter_dw0(mkU64(0));
9482 assign(byte1, load(Ity_I8, mkexpr(address1)));
9483 assign(byte2, load(Ity_I8, mkexpr(address2)));
9484
9485 // end in both? all equal, reset r1 and r2 to start values
9486 s390_cc_set(0);
9487 put_gpr_dw0(r1, binop(Iop_Sub64, mkexpr(address1), mkexpr(counter)));
9488 put_gpr_dw0(r2, binop(Iop_Sub64, mkexpr(address2), mkexpr(counter)));
florian6820ba52012-07-26 02:01:50 +00009489 next_insn_if(binop(Iop_CmpEQ8, mkU8(0),
9490 binop(Iop_Or8,
9491 binop(Iop_Xor8, mkexpr(byte1), mkexpr(end)),
9492 binop(Iop_Xor8, mkexpr(byte2), mkexpr(end)))));
sewardj2019a972011-03-07 16:04:07 +00009493
9494 put_gpr_dw0(r1, mkexpr(address1));
9495 put_gpr_dw0(r2, mkexpr(address2));
9496
9497 // End found in string1
9498 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +00009499 next_insn_if(binop(Iop_CmpEQ8, mkexpr(end), mkexpr(byte1)));
sewardj2019a972011-03-07 16:04:07 +00009500
9501 // End found in string2
9502 s390_cc_set(2);
florian6820ba52012-07-26 02:01:50 +00009503 next_insn_if(binop(Iop_CmpEQ8, mkexpr(end), mkexpr(byte2)));
sewardj2019a972011-03-07 16:04:07 +00009504
9505 // string1 < string2
9506 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +00009507 next_insn_if(binop(Iop_CmpLT32U, unop(Iop_8Uto32, mkexpr(byte1)),
9508 unop(Iop_8Uto32, mkexpr(byte2))));
sewardj2019a972011-03-07 16:04:07 +00009509
9510 // string2 < string1
9511 s390_cc_set(2);
florian6820ba52012-07-26 02:01:50 +00009512 next_insn_if(binop(Iop_CmpLT32U, unop(Iop_8Uto32, mkexpr(byte2)),
9513 unop(Iop_8Uto32, mkexpr(byte1))));
sewardj2019a972011-03-07 16:04:07 +00009514
9515 // else: all equal, no end yet, loop
9516 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
9517 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), mkU64(1)));
9518 put_gpr_dw0(r2, binop(Iop_Add64, get_gpr_dw0(r2), mkU64(1)));
floriancf87c942012-07-25 00:52:21 +00009519
florian6820ba52012-07-26 02:01:50 +00009520 iterate();
sewardj2019a972011-03-07 16:04:07 +00009521
9522 return "clst";
9523}
9524
9525static void
9526s390_irgen_load_multiple_32bit(UChar r1, UChar r3, IRTemp op2addr)
9527{
9528 UChar reg;
9529 IRTemp addr = newTemp(Ity_I64);
9530
9531 assign(addr, mkexpr(op2addr));
9532 reg = r1;
9533 do {
9534 IRTemp old = addr;
9535
9536 reg %= 16;
9537 put_gpr_w1(reg, load(Ity_I32, mkexpr(addr)));
9538 addr = newTemp(Ity_I64);
9539 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
9540 reg++;
9541 } while (reg != (r3 + 1));
9542}
9543
9544static HChar *
9545s390_irgen_LM(UChar r1, UChar r3, IRTemp op2addr)
9546{
9547 s390_irgen_load_multiple_32bit(r1, r3, op2addr);
9548
9549 return "lm";
9550}
9551
9552static HChar *
9553s390_irgen_LMY(UChar r1, UChar r3, IRTemp op2addr)
9554{
9555 s390_irgen_load_multiple_32bit(r1, r3, op2addr);
9556
9557 return "lmy";
9558}
9559
9560static HChar *
9561s390_irgen_LMH(UChar r1, UChar r3, IRTemp op2addr)
9562{
9563 UChar reg;
9564 IRTemp addr = newTemp(Ity_I64);
9565
9566 assign(addr, mkexpr(op2addr));
9567 reg = r1;
9568 do {
9569 IRTemp old = addr;
9570
9571 reg %= 16;
9572 put_gpr_w0(reg, load(Ity_I32, mkexpr(addr)));
9573 addr = newTemp(Ity_I64);
9574 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
9575 reg++;
9576 } while (reg != (r3 + 1));
9577
9578 return "lmh";
9579}
9580
9581static HChar *
9582s390_irgen_LMG(UChar r1, UChar r3, IRTemp op2addr)
9583{
9584 UChar reg;
9585 IRTemp addr = newTemp(Ity_I64);
9586
9587 assign(addr, mkexpr(op2addr));
9588 reg = r1;
9589 do {
9590 IRTemp old = addr;
9591
9592 reg %= 16;
9593 put_gpr_dw0(reg, load(Ity_I64, mkexpr(addr)));
9594 addr = newTemp(Ity_I64);
9595 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(8)));
9596 reg++;
9597 } while (reg != (r3 + 1));
9598
9599 return "lmg";
9600}
9601
9602static void
9603s390_irgen_store_multiple_32bit(UChar r1, UChar r3, IRTemp op2addr)
9604{
9605 UChar reg;
9606 IRTemp addr = newTemp(Ity_I64);
9607
9608 assign(addr, mkexpr(op2addr));
9609 reg = r1;
9610 do {
9611 IRTemp old = addr;
9612
9613 reg %= 16;
9614 store(mkexpr(addr), get_gpr_w1(reg));
9615 addr = newTemp(Ity_I64);
9616 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
9617 reg++;
9618 } while( reg != (r3 + 1));
9619}
9620
9621static HChar *
9622s390_irgen_STM(UChar r1, UChar r3, IRTemp op2addr)
9623{
9624 s390_irgen_store_multiple_32bit(r1, r3, op2addr);
9625
9626 return "stm";
9627}
9628
9629static HChar *
9630s390_irgen_STMY(UChar r1, UChar r3, IRTemp op2addr)
9631{
9632 s390_irgen_store_multiple_32bit(r1, r3, op2addr);
9633
9634 return "stmy";
9635}
9636
9637static HChar *
9638s390_irgen_STMH(UChar r1, UChar r3, IRTemp op2addr)
9639{
9640 UChar reg;
9641 IRTemp addr = newTemp(Ity_I64);
9642
9643 assign(addr, mkexpr(op2addr));
9644 reg = r1;
9645 do {
9646 IRTemp old = addr;
9647
9648 reg %= 16;
9649 store(mkexpr(addr), get_gpr_w0(reg));
9650 addr = newTemp(Ity_I64);
9651 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
9652 reg++;
9653 } while( reg != (r3 + 1));
9654
9655 return "stmh";
9656}
9657
9658static HChar *
9659s390_irgen_STMG(UChar r1, UChar r3, IRTemp op2addr)
9660{
9661 UChar reg;
9662 IRTemp addr = newTemp(Ity_I64);
9663
9664 assign(addr, mkexpr(op2addr));
9665 reg = r1;
9666 do {
9667 IRTemp old = addr;
9668
9669 reg %= 16;
9670 store(mkexpr(addr), get_gpr_dw0(reg));
9671 addr = newTemp(Ity_I64);
9672 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(8)));
9673 reg++;
9674 } while( reg != (r3 + 1));
9675
9676 return "stmg";
9677}
9678
9679static void
florianb0bf6602012-05-05 00:01:16 +00009680s390_irgen_xonc(IROp op, IRTemp length, IRTemp start1, IRTemp start2)
sewardj2019a972011-03-07 16:04:07 +00009681{
9682 IRTemp old1 = newTemp(Ity_I8);
9683 IRTemp old2 = newTemp(Ity_I8);
9684 IRTemp new1 = newTemp(Ity_I8);
9685 IRTemp counter = newTemp(Ity_I32);
9686 IRTemp addr1 = newTemp(Ity_I64);
9687
9688 assign(counter, get_counter_w0());
9689
9690 assign(addr1, binop(Iop_Add64, mkexpr(start1),
9691 unop(Iop_32Uto64, mkexpr(counter))));
9692
9693 assign(old1, load(Ity_I8, mkexpr(addr1)));
9694 assign(old2, load(Ity_I8, binop(Iop_Add64, mkexpr(start2),
9695 unop(Iop_32Uto64,mkexpr(counter)))));
9696 assign(new1, binop(op, mkexpr(old1), mkexpr(old2)));
9697
9698 /* Special case: xc is used to zero memory */
sewardj2019a972011-03-07 16:04:07 +00009699 if (op == Iop_Xor8) {
9700 store(mkexpr(addr1),
florian6ad49522011-09-09 02:38:55 +00009701 mkite(binop(Iop_CmpEQ64, mkexpr(start1), mkexpr(start2)),
9702 mkU8(0), mkexpr(new1)));
sewardj2019a972011-03-07 16:04:07 +00009703 } else
9704 store(mkexpr(addr1), mkexpr(new1));
9705 put_counter_w1(binop(Iop_Or32, unop(Iop_8Uto32, mkexpr(new1)),
9706 get_counter_w1()));
9707
9708 /* Check for end of field */
9709 put_counter_w0(binop(Iop_Add32, mkexpr(counter), mkU32(1)));
florian6820ba52012-07-26 02:01:50 +00009710 iterate_if(binop(Iop_CmpNE32, mkexpr(counter), mkexpr(length)));
sewardj2019a972011-03-07 16:04:07 +00009711 s390_cc_thunk_put1(S390_CC_OP_BITWISE, mktemp(Ity_I32, get_counter_w1()),
9712 False);
9713 put_counter_dw0(mkU64(0));
9714}
9715
9716static HChar *
9717s390_irgen_XC(UChar length, IRTemp start1, IRTemp start2)
9718{
florianb0bf6602012-05-05 00:01:16 +00009719 IRTemp len = newTemp(Ity_I32);
9720
9721 assign(len, mkU32(length));
9722 s390_irgen_xonc(Iop_Xor8, len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +00009723
9724 return "xc";
9725}
9726
sewardjb63967e2011-03-24 08:50:04 +00009727static void
9728s390_irgen_XC_sameloc(UChar length, UChar b, UShort d)
9729{
9730 IRTemp counter = newTemp(Ity_I32);
9731 IRTemp start = newTemp(Ity_I64);
9732 IRTemp addr = newTemp(Ity_I64);
9733
9734 assign(start,
9735 binop(Iop_Add64, mkU64(d), b != 0 ? get_gpr_dw0(b) : mkU64(0)));
9736
9737 if (length < 8) {
9738 UInt i;
9739
9740 for (i = 0; i <= length; ++i) {
9741 store(binop(Iop_Add64, mkexpr(start), mkU64(i)), mkU8(0));
9742 }
9743 } else {
9744 assign(counter, get_counter_w0());
9745
9746 assign(addr, binop(Iop_Add64, mkexpr(start),
9747 unop(Iop_32Uto64, mkexpr(counter))));
9748
9749 store(mkexpr(addr), mkU8(0));
9750
9751 /* Check for end of field */
9752 put_counter_w0(binop(Iop_Add32, mkexpr(counter), mkU32(1)));
florian6820ba52012-07-26 02:01:50 +00009753 iterate_if(binop(Iop_CmpNE32, mkexpr(counter), mkU32(length)));
sewardjb63967e2011-03-24 08:50:04 +00009754
9755 /* Reset counter */
9756 put_counter_dw0(mkU64(0));
9757 }
9758
9759 s390_cc_thunk_put1(S390_CC_OP_BITWISE, mktemp(Ity_I32, mkU32(0)), False);
9760
sewardj7ee97522011-05-09 21:45:04 +00009761 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardjb63967e2011-03-24 08:50:04 +00009762 s390_disasm(ENC3(MNM, UDLB, UDXB), "xc", d, length, b, d, 0, b);
9763}
9764
sewardj2019a972011-03-07 16:04:07 +00009765static HChar *
9766s390_irgen_NC(UChar length, IRTemp start1, IRTemp start2)
9767{
florianb0bf6602012-05-05 00:01:16 +00009768 IRTemp len = newTemp(Ity_I32);
9769
9770 assign(len, mkU32(length));
9771 s390_irgen_xonc(Iop_And8, len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +00009772
9773 return "nc";
9774}
9775
9776static HChar *
9777s390_irgen_OC(UChar length, IRTemp start1, IRTemp start2)
9778{
florianb0bf6602012-05-05 00:01:16 +00009779 IRTemp len = newTemp(Ity_I32);
9780
9781 assign(len, mkU32(length));
9782 s390_irgen_xonc(Iop_Or8, len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +00009783
9784 return "oc";
9785}
9786
9787
9788static HChar *
9789s390_irgen_MVC(UChar length, IRTemp start1, IRTemp start2)
9790{
florian79e839e2012-05-05 02:20:30 +00009791 IRTemp len = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00009792
florian79e839e2012-05-05 02:20:30 +00009793 assign(len, mkU64(length));
9794 s390_irgen_MVC_EX(len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +00009795
9796 return "mvc";
9797}
9798
9799static HChar *
florianb0c9a132011-09-08 15:37:39 +00009800s390_irgen_MVCL(UChar r1, UChar r2)
9801{
9802 IRTemp addr1 = newTemp(Ity_I64);
9803 IRTemp addr2 = newTemp(Ity_I64);
9804 IRTemp addr2_load = newTemp(Ity_I64);
9805 IRTemp r1p1 = newTemp(Ity_I32); /* contents of r1 + 1 */
9806 IRTemp r2p1 = newTemp(Ity_I32); /* contents of r2 + 1 */
9807 IRTemp len1 = newTemp(Ity_I32);
9808 IRTemp len2 = newTemp(Ity_I32);
9809 IRTemp pad = newTemp(Ity_I8);
9810 IRTemp single = newTemp(Ity_I8);
9811
9812 assign(addr1, get_gpr_dw0(r1));
9813 assign(r1p1, get_gpr_w1(r1 + 1));
9814 assign(len1, binop(Iop_And32, mkexpr(r1p1), mkU32(0x00ffffff)));
9815 assign(addr2, get_gpr_dw0(r2));
9816 assign(r2p1, get_gpr_w1(r2 + 1));
9817 assign(len2, binop(Iop_And32, mkexpr(r2p1), mkU32(0x00ffffff)));
9818 assign(pad, get_gpr_b4(r2 + 1));
9819
9820 /* len1 == 0 ? */
9821 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len2, False);
florian6820ba52012-07-26 02:01:50 +00009822 next_insn_if(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)));
florianb0c9a132011-09-08 15:37:39 +00009823
9824 /* Check for destructive overlap:
9825 addr1 > addr2 && addr2 + len1 > addr1 && (addr2 + len2) > addr1 */
9826 s390_cc_set(3);
9827 IRTemp cond1 = newTemp(Ity_I32);
9828 assign(cond1, unop(Iop_1Uto32,
9829 binop(Iop_CmpLT64U, mkexpr(addr2), mkexpr(addr1))));
9830 IRTemp cond2 = newTemp(Ity_I32);
9831 assign(cond2, unop(Iop_1Uto32,
9832 binop(Iop_CmpLT64U, mkexpr(addr1),
9833 binop(Iop_Add64, mkexpr(addr2),
9834 unop(Iop_32Uto64, mkexpr(len1))))));
9835 IRTemp cond3 = newTemp(Ity_I32);
9836 assign(cond3, unop(Iop_1Uto32,
9837 binop(Iop_CmpLT64U,
9838 mkexpr(addr1),
9839 binop(Iop_Add64, mkexpr(addr2),
9840 unop(Iop_32Uto64, mkexpr(len2))))));
9841
florian6820ba52012-07-26 02:01:50 +00009842 next_insn_if(binop(Iop_CmpEQ32,
9843 binop(Iop_And32,
9844 binop(Iop_And32, mkexpr(cond1), mkexpr(cond2)),
9845 mkexpr(cond3)),
9846 mkU32(1)));
florianb0c9a132011-09-08 15:37:39 +00009847
9848 /* See s390_irgen_CLCL for explanation why we cannot load directly
9849 and need two steps. */
9850 assign(addr2_load,
9851 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
9852 mkU64(guest_IA_curr_instr), mkexpr(addr2)));
9853 assign(single,
9854 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
9855 mkexpr(pad), load(Ity_I8, mkexpr(addr2_load))));
9856
9857 store(mkexpr(addr1), mkexpr(single));
9858
9859 /* Update addr1 and len1 */
9860 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkU64(1)));
9861 put_gpr_w1(r1 + 1, binop(Iop_Sub32, mkexpr(r1p1), mkU32(1)));
9862
9863 /* Update addr2 and len2 */
9864 put_gpr_dw0(r2,
9865 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
9866 mkexpr(addr2),
9867 binop(Iop_Add64, mkexpr(addr2), mkU64(1))));
9868
9869 /* When updating len2 we must not modify bits (r2+1)[0:39] */
9870 put_gpr_w1(r2 + 1,
9871 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
9872 binop(Iop_And32, mkexpr(r2p1), mkU32(0xFF000000u)),
9873 binop(Iop_Sub32, mkexpr(r2p1), mkU32(1))));
9874
9875 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len2, False);
florian6820ba52012-07-26 02:01:50 +00009876 iterate_if(binop(Iop_CmpNE32, mkexpr(len1), mkU32(1)));
florianb0c9a132011-09-08 15:37:39 +00009877
9878 return "mvcl";
9879}
9880
9881
9882static HChar *
sewardj2019a972011-03-07 16:04:07 +00009883s390_irgen_MVCLE(UChar r1, UChar r3, IRTemp pad2)
9884{
9885 IRTemp addr1, addr3, addr3_load, len1, len3, single;
9886
9887 addr1 = newTemp(Ity_I64);
9888 addr3 = newTemp(Ity_I64);
9889 addr3_load = newTemp(Ity_I64);
9890 len1 = newTemp(Ity_I64);
9891 len3 = newTemp(Ity_I64);
9892 single = newTemp(Ity_I8);
9893
9894 assign(addr1, get_gpr_dw0(r1));
9895 assign(len1, get_gpr_dw0(r1 + 1));
9896 assign(addr3, get_gpr_dw0(r3));
9897 assign(len3, get_gpr_dw0(r3 + 1));
9898
9899 // len1 == 0 ?
9900 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len3, False);
florian6820ba52012-07-26 02:01:50 +00009901 next_insn_if(binop(Iop_CmpEQ64,mkexpr(len1), mkU64(0)));
sewardj2019a972011-03-07 16:04:07 +00009902
9903 /* This is a hack to prevent mvcle from reading from addr3 if it
9904 should read from the pad. Since the pad has no address, just
9905 read from the instruction, we discard that anyway */
9906 assign(addr3_load,
florian6ad49522011-09-09 02:38:55 +00009907 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
9908 mkU64(guest_IA_curr_instr), mkexpr(addr3)));
sewardj2019a972011-03-07 16:04:07 +00009909
9910 assign(single,
florian6ad49522011-09-09 02:38:55 +00009911 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
9912 unop(Iop_64to8, mkexpr(pad2)),
9913 load(Ity_I8, mkexpr(addr3_load))));
sewardj2019a972011-03-07 16:04:07 +00009914 store(mkexpr(addr1), mkexpr(single));
9915
9916 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkU64(1)));
9917
9918 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkU64(1)));
9919
9920 put_gpr_dw0(r3,
florian6ad49522011-09-09 02:38:55 +00009921 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
9922 mkexpr(addr3),
9923 binop(Iop_Add64, mkexpr(addr3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +00009924
9925 put_gpr_dw0(r3 + 1,
florian6ad49522011-09-09 02:38:55 +00009926 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
9927 mkU64(0), binop(Iop_Sub64, mkexpr(len3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +00009928
sewardj2019a972011-03-07 16:04:07 +00009929 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len3, False);
florian6820ba52012-07-26 02:01:50 +00009930 iterate_if(binop(Iop_CmpNE64, mkexpr(len1), mkU64(1)));
sewardj2019a972011-03-07 16:04:07 +00009931
9932 return "mvcle";
9933}
9934
9935static HChar *
9936s390_irgen_MVST(UChar r1, UChar r2)
9937{
9938 IRTemp addr1 = newTemp(Ity_I64);
9939 IRTemp addr2 = newTemp(Ity_I64);
9940 IRTemp end = newTemp(Ity_I8);
9941 IRTemp byte = newTemp(Ity_I8);
9942 IRTemp counter = newTemp(Ity_I64);
9943
9944 assign(addr1, get_gpr_dw0(r1));
9945 assign(addr2, get_gpr_dw0(r2));
9946 assign(counter, get_counter_dw0());
9947 assign(end, get_gpr_b7(0));
9948 assign(byte, load(Ity_I8, binop(Iop_Add64, mkexpr(addr2),mkexpr(counter))));
9949 store(binop(Iop_Add64,mkexpr(addr1),mkexpr(counter)), mkexpr(byte));
9950
9951 // We use unlimited as cpu-determined number
9952 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
florian6820ba52012-07-26 02:01:50 +00009953 iterate_if(binop(Iop_CmpNE8, mkexpr(end), mkexpr(byte)));
sewardj2019a972011-03-07 16:04:07 +00009954
9955 // and always set cc=1 at the end + update r1
9956 s390_cc_set(1);
9957 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(counter)));
9958 put_counter_dw0(mkU64(0));
9959
9960 return "mvst";
9961}
9962
9963static void
9964s390_irgen_divide_64to32(IROp op, UChar r1, IRTemp op2)
9965{
9966 IRTemp op1 = newTemp(Ity_I64);
9967 IRTemp result = newTemp(Ity_I64);
9968
9969 assign(op1, binop(Iop_32HLto64,
9970 get_gpr_w1(r1), // high 32 bits
9971 get_gpr_w1(r1 + 1))); // low 32 bits
9972 assign(result, binop(op, mkexpr(op1), mkexpr(op2)));
9973 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result))); // remainder
9974 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result))); // quotient
9975}
9976
9977static void
9978s390_irgen_divide_128to64(IROp op, UChar r1, IRTemp op2)
9979{
9980 IRTemp op1 = newTemp(Ity_I128);
9981 IRTemp result = newTemp(Ity_I128);
9982
9983 assign(op1, binop(Iop_64HLto128,
9984 get_gpr_dw0(r1), // high 64 bits
9985 get_gpr_dw0(r1 + 1))); // low 64 bits
9986 assign(result, binop(op, mkexpr(op1), mkexpr(op2)));
9987 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result))); // remainder
9988 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result))); // quotient
9989}
9990
9991static void
9992s390_irgen_divide_64to64(IROp op, UChar r1, IRTemp op2)
9993{
9994 IRTemp op1 = newTemp(Ity_I64);
9995 IRTemp result = newTemp(Ity_I128);
9996
9997 assign(op1, get_gpr_dw0(r1 + 1));
9998 assign(result, binop(op, mkexpr(op1), mkexpr(op2)));
9999 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result))); // remainder
10000 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result))); // quotient
10001}
10002
10003static HChar *
10004s390_irgen_DR(UChar r1, UChar r2)
10005{
10006 IRTemp op2 = newTemp(Ity_I32);
10007
10008 assign(op2, get_gpr_w1(r2));
10009
10010 s390_irgen_divide_64to32(Iop_DivModS64to32, r1, op2);
10011
10012 return "dr";
10013}
10014
10015static HChar *
10016s390_irgen_D(UChar r1, IRTemp op2addr)
10017{
10018 IRTemp op2 = newTemp(Ity_I32);
10019
10020 assign(op2, load(Ity_I32, mkexpr(op2addr)));
10021
10022 s390_irgen_divide_64to32(Iop_DivModS64to32, r1, op2);
10023
10024 return "d";
10025}
10026
10027static HChar *
10028s390_irgen_DLR(UChar r1, UChar r2)
10029{
10030 IRTemp op2 = newTemp(Ity_I32);
10031
10032 assign(op2, get_gpr_w1(r2));
10033
10034 s390_irgen_divide_64to32(Iop_DivModU64to32, r1, op2);
10035
florian7cd1cde2012-08-16 23:57:43 +000010036 return "dlr";
sewardj2019a972011-03-07 16:04:07 +000010037}
10038
10039static HChar *
10040s390_irgen_DL(UChar r1, IRTemp op2addr)
10041{
10042 IRTemp op2 = newTemp(Ity_I32);
10043
10044 assign(op2, load(Ity_I32, mkexpr(op2addr)));
10045
10046 s390_irgen_divide_64to32(Iop_DivModU64to32, r1, op2);
10047
10048 return "dl";
10049}
10050
10051static HChar *
10052s390_irgen_DLG(UChar r1, IRTemp op2addr)
10053{
10054 IRTemp op2 = newTemp(Ity_I64);
10055
10056 assign(op2, load(Ity_I64, mkexpr(op2addr)));
10057
10058 s390_irgen_divide_128to64(Iop_DivModU128to64, r1, op2);
10059
10060 return "dlg";
10061}
10062
10063static HChar *
10064s390_irgen_DLGR(UChar r1, UChar r2)
10065{
10066 IRTemp op2 = newTemp(Ity_I64);
10067
10068 assign(op2, get_gpr_dw0(r2));
10069
10070 s390_irgen_divide_128to64(Iop_DivModU128to64, r1, op2);
10071
10072 return "dlgr";
10073}
10074
10075static HChar *
10076s390_irgen_DSGR(UChar r1, UChar r2)
10077{
10078 IRTemp op2 = newTemp(Ity_I64);
10079
10080 assign(op2, get_gpr_dw0(r2));
10081
10082 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
10083
10084 return "dsgr";
10085}
10086
10087static HChar *
10088s390_irgen_DSG(UChar r1, IRTemp op2addr)
10089{
10090 IRTemp op2 = newTemp(Ity_I64);
10091
10092 assign(op2, load(Ity_I64, mkexpr(op2addr)));
10093
10094 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
10095
10096 return "dsg";
10097}
10098
10099static HChar *
10100s390_irgen_DSGFR(UChar r1, UChar r2)
10101{
10102 IRTemp op2 = newTemp(Ity_I64);
10103
10104 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
10105
10106 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
10107
10108 return "dsgfr";
10109}
10110
10111static HChar *
10112s390_irgen_DSGF(UChar r1, IRTemp op2addr)
10113{
10114 IRTemp op2 = newTemp(Ity_I64);
10115
10116 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
10117
10118 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
10119
10120 return "dsgf";
10121}
10122
10123static void
10124s390_irgen_load_ar_multiple(UChar r1, UChar r3, IRTemp op2addr)
10125{
10126 UChar reg;
10127 IRTemp addr = newTemp(Ity_I64);
10128
10129 assign(addr, mkexpr(op2addr));
10130 reg = r1;
10131 do {
10132 IRTemp old = addr;
10133
10134 reg %= 16;
10135 put_ar_w0(reg, load(Ity_I32, mkexpr(addr)));
10136 addr = newTemp(Ity_I64);
10137 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
10138 reg++;
10139 } while (reg != (r3 + 1));
10140}
10141
10142static HChar *
10143s390_irgen_LAM(UChar r1, UChar r3, IRTemp op2addr)
10144{
10145 s390_irgen_load_ar_multiple(r1, r3, op2addr);
10146
10147 return "lam";
10148}
10149
10150static HChar *
10151s390_irgen_LAMY(UChar r1, UChar r3, IRTemp op2addr)
10152{
10153 s390_irgen_load_ar_multiple(r1, r3, op2addr);
10154
10155 return "lamy";
10156}
10157
10158static void
10159s390_irgen_store_ar_multiple(UChar r1, UChar r3, IRTemp op2addr)
10160{
10161 UChar reg;
10162 IRTemp addr = newTemp(Ity_I64);
10163
10164 assign(addr, mkexpr(op2addr));
10165 reg = r1;
10166 do {
10167 IRTemp old = addr;
10168
10169 reg %= 16;
10170 store(mkexpr(addr), get_ar_w0(reg));
10171 addr = newTemp(Ity_I64);
10172 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
10173 reg++;
10174 } while (reg != (r3 + 1));
10175}
10176
10177static HChar *
10178s390_irgen_STAM(UChar r1, UChar r3, IRTemp op2addr)
10179{
10180 s390_irgen_store_ar_multiple(r1, r3, op2addr);
10181
10182 return "stam";
10183}
10184
10185static HChar *
10186s390_irgen_STAMY(UChar r1, UChar r3, IRTemp op2addr)
10187{
10188 s390_irgen_store_ar_multiple(r1, r3, op2addr);
10189
10190 return "stamy";
10191}
10192
10193
10194/* Implementation for 32-bit compare-and-swap */
10195static void
10196s390_irgen_cas_32(UChar r1, UChar r3, IRTemp op2addr)
10197{
10198 IRCAS *cas;
10199 IRTemp op1 = newTemp(Ity_I32);
10200 IRTemp old_mem = newTemp(Ity_I32);
10201 IRTemp op3 = newTemp(Ity_I32);
10202 IRTemp result = newTemp(Ity_I32);
10203 IRTemp nequal = newTemp(Ity_I1);
10204
10205 assign(op1, get_gpr_w1(r1));
10206 assign(op3, get_gpr_w1(r3));
10207
10208 /* The first and second operands are compared. If they are equal,
10209 the third operand is stored at the second- operand location. */
10210 cas = mkIRCAS(IRTemp_INVALID, old_mem,
10211 Iend_BE, mkexpr(op2addr),
10212 NULL, mkexpr(op1), /* expected value */
10213 NULL, mkexpr(op3) /* new value */);
10214 stmt(IRStmt_CAS(cas));
10215
10216 /* Set CC. Operands compared equal -> 0, else 1. */
10217 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(old_mem)));
10218 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
10219
10220 /* If operands were equal (cc == 0) just store the old value op1 in r1.
10221 Otherwise, store the old_value from memory in r1 and yield. */
10222 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
10223 put_gpr_w1(r1, mkite(mkexpr(nequal), mkexpr(old_mem), mkexpr(op1)));
florian6820ba52012-07-26 02:01:50 +000010224 yield_if(mkexpr(nequal));
sewardj2019a972011-03-07 16:04:07 +000010225}
10226
10227static HChar *
10228s390_irgen_CS(UChar r1, UChar r3, IRTemp op2addr)
10229{
10230 s390_irgen_cas_32(r1, r3, op2addr);
10231
10232 return "cs";
10233}
10234
10235static HChar *
10236s390_irgen_CSY(UChar r1, UChar r3, IRTemp op2addr)
10237{
10238 s390_irgen_cas_32(r1, r3, op2addr);
10239
10240 return "csy";
10241}
10242
10243static HChar *
10244s390_irgen_CSG(UChar r1, UChar r3, IRTemp op2addr)
10245{
10246 IRCAS *cas;
10247 IRTemp op1 = newTemp(Ity_I64);
10248 IRTemp old_mem = newTemp(Ity_I64);
10249 IRTemp op3 = newTemp(Ity_I64);
10250 IRTemp result = newTemp(Ity_I64);
10251 IRTemp nequal = newTemp(Ity_I1);
10252
10253 assign(op1, get_gpr_dw0(r1));
10254 assign(op3, get_gpr_dw0(r3));
10255
10256 /* The first and second operands are compared. If they are equal,
10257 the third operand is stored at the second- operand location. */
10258 cas = mkIRCAS(IRTemp_INVALID, old_mem,
10259 Iend_BE, mkexpr(op2addr),
10260 NULL, mkexpr(op1), /* expected value */
10261 NULL, mkexpr(op3) /* new value */);
10262 stmt(IRStmt_CAS(cas));
10263
10264 /* Set CC. Operands compared equal -> 0, else 1. */
10265 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(old_mem)));
10266 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
10267
10268 /* If operands were equal (cc == 0) just store the old value op1 in r1.
10269 Otherwise, store the old_value from memory in r1 and yield. */
10270 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
10271 put_gpr_dw0(r1, mkite(mkexpr(nequal), mkexpr(old_mem), mkexpr(op1)));
florian6820ba52012-07-26 02:01:50 +000010272 yield_if(mkexpr(nequal));
sewardj2019a972011-03-07 16:04:07 +000010273
10274 return "csg";
10275}
10276
florian448cbba2012-06-06 02:26:01 +000010277/* Implementation for 32-bit compare-double-and-swap */
10278static void
10279s390_irgen_cdas_32(UChar r1, UChar r3, IRTemp op2addr)
10280{
10281 IRCAS *cas;
10282 IRTemp op1_high = newTemp(Ity_I32);
10283 IRTemp op1_low = newTemp(Ity_I32);
10284 IRTemp old_mem_high = newTemp(Ity_I32);
10285 IRTemp old_mem_low = newTemp(Ity_I32);
10286 IRTemp op3_high = newTemp(Ity_I32);
10287 IRTemp op3_low = newTemp(Ity_I32);
10288 IRTemp result = newTemp(Ity_I32);
10289 IRTemp nequal = newTemp(Ity_I1);
10290
10291 assign(op1_high, get_gpr_w1(r1));
10292 assign(op1_low, get_gpr_w1(r1+1));
10293 assign(op3_high, get_gpr_w1(r3));
10294 assign(op3_low, get_gpr_w1(r3+1));
10295
10296 /* The first and second operands are compared. If they are equal,
10297 the third operand is stored at the second-operand location. */
10298 cas = mkIRCAS(old_mem_high, old_mem_low,
10299 Iend_BE, mkexpr(op2addr),
10300 mkexpr(op1_high), mkexpr(op1_low), /* expected value */
10301 mkexpr(op3_high), mkexpr(op3_low) /* new value */);
10302 stmt(IRStmt_CAS(cas));
10303
10304 /* Set CC. Operands compared equal -> 0, else 1. */
10305 assign(result, unop(Iop_1Uto32,
10306 binop(Iop_CmpNE32,
10307 binop(Iop_Or32,
10308 binop(Iop_Xor32, mkexpr(op1_high), mkexpr(old_mem_high)),
10309 binop(Iop_Xor32, mkexpr(op1_low), mkexpr(old_mem_low))),
10310 mkU32(0))));
10311
10312 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
10313
10314 /* If operands were equal (cc == 0) just store the old value op1 in r1.
10315 Otherwise, store the old_value from memory in r1 and yield. */
10316 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
10317 put_gpr_w1(r1, mkite(mkexpr(nequal), mkexpr(old_mem_high), mkexpr(op1_high)));
10318 put_gpr_w1(r1+1, mkite(mkexpr(nequal), mkexpr(old_mem_low), mkexpr(op1_low)));
florian6820ba52012-07-26 02:01:50 +000010319 yield_if(mkexpr(nequal));
florian448cbba2012-06-06 02:26:01 +000010320}
10321
10322static HChar *
10323s390_irgen_CDS(UChar r1, UChar r3, IRTemp op2addr)
10324{
10325 s390_irgen_cdas_32(r1, r3, op2addr);
10326
10327 return "cds";
10328}
10329
10330static HChar *
10331s390_irgen_CDSY(UChar r1, UChar r3, IRTemp op2addr)
10332{
10333 s390_irgen_cdas_32(r1, r3, op2addr);
10334
10335 return "cdsy";
10336}
10337
10338static HChar *
10339s390_irgen_CDSG(UChar r1, UChar r3, IRTemp op2addr)
10340{
10341 IRCAS *cas;
10342 IRTemp op1_high = newTemp(Ity_I64);
10343 IRTemp op1_low = newTemp(Ity_I64);
10344 IRTemp old_mem_high = newTemp(Ity_I64);
10345 IRTemp old_mem_low = newTemp(Ity_I64);
10346 IRTemp op3_high = newTemp(Ity_I64);
10347 IRTemp op3_low = newTemp(Ity_I64);
10348 IRTemp result = newTemp(Ity_I64);
10349 IRTemp nequal = newTemp(Ity_I1);
10350
10351 assign(op1_high, get_gpr_dw0(r1));
10352 assign(op1_low, get_gpr_dw0(r1+1));
10353 assign(op3_high, get_gpr_dw0(r3));
10354 assign(op3_low, get_gpr_dw0(r3+1));
10355
10356 /* The first and second operands are compared. If they are equal,
10357 the third operand is stored at the second-operand location. */
10358 cas = mkIRCAS(old_mem_high, old_mem_low,
10359 Iend_BE, mkexpr(op2addr),
10360 mkexpr(op1_high), mkexpr(op1_low), /* expected value */
10361 mkexpr(op3_high), mkexpr(op3_low) /* new value */);
10362 stmt(IRStmt_CAS(cas));
10363
10364 /* Set CC. Operands compared equal -> 0, else 1. */
10365 assign(result, unop(Iop_1Uto64,
10366 binop(Iop_CmpNE64,
10367 binop(Iop_Or64,
10368 binop(Iop_Xor64, mkexpr(op1_high), mkexpr(old_mem_high)),
10369 binop(Iop_Xor64, mkexpr(op1_low), mkexpr(old_mem_low))),
10370 mkU64(0))));
10371
10372 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
10373
10374 /* If operands were equal (cc == 0) just store the old value op1 in r1.
10375 Otherwise, store the old_value from memory in r1 and yield. */
10376 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
10377 put_gpr_dw0(r1, mkite(mkexpr(nequal), mkexpr(old_mem_high), mkexpr(op1_high)));
10378 put_gpr_dw0(r1+1, mkite(mkexpr(nequal), mkexpr(old_mem_low), mkexpr(op1_low)));
florian6820ba52012-07-26 02:01:50 +000010379 yield_if(mkexpr(nequal));
10380
florian448cbba2012-06-06 02:26:01 +000010381 return "cdsg";
10382}
10383
sewardj2019a972011-03-07 16:04:07 +000010384
10385/* Binary floating point */
10386
10387static HChar *
10388s390_irgen_AXBR(UChar r1, UChar r2)
10389{
10390 IRTemp op1 = newTemp(Ity_F128);
10391 IRTemp op2 = newTemp(Ity_F128);
10392 IRTemp result = newTemp(Ity_F128);
florian125e20d2012-10-07 15:42:37 +000010393 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000010394
10395 assign(op1, get_fpr_pair(r1));
10396 assign(op2, get_fpr_pair(r2));
floriandb4fcaa2012-09-05 19:54:08 +000010397 assign(result, triop(Iop_AddF128, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +000010398 mkexpr(op2)));
10399 put_fpr_pair(r1, mkexpr(result));
10400
10401 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
10402
10403 return "axbr";
10404}
10405
10406/* The result of a Iop_CmdFxx operation is a condition code. It is
10407 encoded using the values defined in type IRCmpFxxResult.
10408 Before we can store the condition code into the guest state (or do
10409 anything else with it for that matter) we need to convert it to
10410 the encoding that s390 uses. This is what this function does.
10411
10412 s390 VEX b6 b2 b0 cc.1 cc.0
10413 0 0x40 EQ 1 0 0 0 0
10414 1 0x01 LT 0 0 1 0 1
10415 2 0x00 GT 0 0 0 1 0
10416 3 0x45 Unordered 1 1 1 1 1
10417
10418 The following bits from the VEX encoding are interesting:
10419 b0, b2, b6 with b0 being the LSB. We observe:
10420
10421 cc.0 = b0;
10422 cc.1 = b2 | (~b0 & ~b6)
10423
10424 with cc being the s390 condition code.
10425*/
10426static IRExpr *
10427convert_vex_fpcc_to_s390(IRTemp vex_cc)
10428{
10429 IRTemp cc0 = newTemp(Ity_I32);
10430 IRTemp cc1 = newTemp(Ity_I32);
10431 IRTemp b0 = newTemp(Ity_I32);
10432 IRTemp b2 = newTemp(Ity_I32);
10433 IRTemp b6 = newTemp(Ity_I32);
10434
10435 assign(b0, binop(Iop_And32, mkexpr(vex_cc), mkU32(1)));
10436 assign(b2, binop(Iop_And32, binop(Iop_Shr32, mkexpr(vex_cc), mkU8(2)),
10437 mkU32(1)));
10438 assign(b6, binop(Iop_And32, binop(Iop_Shr32, mkexpr(vex_cc), mkU8(6)),
10439 mkU32(1)));
10440
10441 assign(cc0, mkexpr(b0));
10442 assign(cc1, binop(Iop_Or32, mkexpr(b2),
10443 binop(Iop_And32,
10444 binop(Iop_Sub32, mkU32(1), mkexpr(b0)), /* ~b0 */
10445 binop(Iop_Sub32, mkU32(1), mkexpr(b6)) /* ~b6 */
10446 )));
10447
10448 return binop(Iop_Or32, mkexpr(cc0), binop(Iop_Shl32, mkexpr(cc1), mkU8(1)));
10449}
10450
10451static HChar *
10452s390_irgen_CEBR(UChar r1, UChar r2)
10453{
10454 IRTemp op1 = newTemp(Ity_F32);
10455 IRTemp op2 = newTemp(Ity_F32);
10456 IRTemp cc_vex = newTemp(Ity_I32);
10457 IRTemp cc_s390 = newTemp(Ity_I32);
10458
10459 assign(op1, get_fpr_w0(r1));
10460 assign(op2, get_fpr_w0(r2));
10461 assign(cc_vex, binop(Iop_CmpF32, mkexpr(op1), mkexpr(op2)));
10462
10463 assign(cc_s390, convert_vex_fpcc_to_s390(cc_vex));
10464 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
10465
10466 return "cebr";
10467}
10468
10469static HChar *
10470s390_irgen_CDBR(UChar r1, UChar r2)
10471{
10472 IRTemp op1 = newTemp(Ity_F64);
10473 IRTemp op2 = newTemp(Ity_F64);
10474 IRTemp cc_vex = newTemp(Ity_I32);
10475 IRTemp cc_s390 = newTemp(Ity_I32);
10476
10477 assign(op1, get_fpr_dw0(r1));
10478 assign(op2, get_fpr_dw0(r2));
10479 assign(cc_vex, binop(Iop_CmpF64, mkexpr(op1), mkexpr(op2)));
10480
10481 assign(cc_s390, convert_vex_fpcc_to_s390(cc_vex));
10482 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
10483
10484 return "cdbr";
10485}
10486
10487static HChar *
10488s390_irgen_CXBR(UChar r1, UChar r2)
10489{
10490 IRTemp op1 = newTemp(Ity_F128);
10491 IRTemp op2 = newTemp(Ity_F128);
10492 IRTemp cc_vex = newTemp(Ity_I32);
10493 IRTemp cc_s390 = newTemp(Ity_I32);
10494
10495 assign(op1, get_fpr_pair(r1));
10496 assign(op2, get_fpr_pair(r2));
10497 assign(cc_vex, binop(Iop_CmpF128, mkexpr(op1), mkexpr(op2)));
10498
10499 assign(cc_s390, convert_vex_fpcc_to_s390(cc_vex));
10500 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
10501
10502 return "cxbr";
10503}
10504
10505static HChar *
10506s390_irgen_CEB(UChar r1, IRTemp op2addr)
10507{
10508 IRTemp op1 = newTemp(Ity_F32);
10509 IRTemp op2 = newTemp(Ity_F32);
10510 IRTemp cc_vex = newTemp(Ity_I32);
10511 IRTemp cc_s390 = newTemp(Ity_I32);
10512
10513 assign(op1, get_fpr_w0(r1));
10514 assign(op2, load(Ity_F32, mkexpr(op2addr)));
10515 assign(cc_vex, binop(Iop_CmpF32, mkexpr(op1), mkexpr(op2)));
10516
10517 assign(cc_s390, convert_vex_fpcc_to_s390(cc_vex));
10518 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
10519
10520 return "ceb";
10521}
10522
10523static HChar *
10524s390_irgen_CDB(UChar r1, IRTemp op2addr)
10525{
10526 IRTemp op1 = newTemp(Ity_F64);
10527 IRTemp op2 = newTemp(Ity_F64);
10528 IRTemp cc_vex = newTemp(Ity_I32);
10529 IRTemp cc_s390 = newTemp(Ity_I32);
10530
10531 assign(op1, get_fpr_dw0(r1));
10532 assign(op2, load(Ity_F64, mkexpr(op2addr)));
10533 assign(cc_vex, binop(Iop_CmpF64, mkexpr(op1), mkexpr(op2)));
10534
10535 assign(cc_s390, convert_vex_fpcc_to_s390(cc_vex));
10536 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
10537
10538 return "cdb";
10539}
10540
10541static HChar *
florian4b8efad2012-09-02 18:07:08 +000010542s390_irgen_CXFBR(UChar m3 __attribute__((unused)),
10543 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000010544{
10545 IRTemp op2 = newTemp(Ity_I32);
10546
10547 assign(op2, get_gpr_w1(r2));
10548 put_fpr_pair(r1, unop(Iop_I32StoF128, mkexpr(op2)));
10549
10550 return "cxfbr";
10551}
10552
10553static HChar *
floriand2129202012-09-01 20:01:39 +000010554s390_irgen_CXLFBR(UChar m3 __attribute__((unused)),
10555 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
florian1c8f7ff2012-09-01 00:12:11 +000010556{
floriane75dafa2012-09-01 17:54:09 +000010557 if (! s390_host_has_fpext) {
10558 emulation_failure(EmFail_S390X_fpext);
10559 } else {
10560 IRTemp op2 = newTemp(Ity_I32);
florian1c8f7ff2012-09-01 00:12:11 +000010561
floriane75dafa2012-09-01 17:54:09 +000010562 assign(op2, get_gpr_w1(r2));
10563 put_fpr_pair(r1, unop(Iop_I32UtoF128, mkexpr(op2)));
10564 }
florian1c8f7ff2012-09-01 00:12:11 +000010565 return "cxlfbr";
10566}
10567
10568
10569static HChar *
florian4b8efad2012-09-02 18:07:08 +000010570s390_irgen_CXGBR(UChar m3 __attribute__((unused)),
10571 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000010572{
10573 IRTemp op2 = newTemp(Ity_I64);
10574
10575 assign(op2, get_gpr_dw0(r2));
10576 put_fpr_pair(r1, unop(Iop_I64StoF128, mkexpr(op2)));
10577
10578 return "cxgbr";
10579}
10580
10581static HChar *
floriand2129202012-09-01 20:01:39 +000010582s390_irgen_CXLGBR(UChar m3 __attribute__((unused)),
10583 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
florian1c8f7ff2012-09-01 00:12:11 +000010584{
floriane75dafa2012-09-01 17:54:09 +000010585 if (! s390_host_has_fpext) {
10586 emulation_failure(EmFail_S390X_fpext);
10587 } else {
10588 IRTemp op2 = newTemp(Ity_I64);
florian1c8f7ff2012-09-01 00:12:11 +000010589
floriane75dafa2012-09-01 17:54:09 +000010590 assign(op2, get_gpr_dw0(r2));
10591 put_fpr_pair(r1, unop(Iop_I64UtoF128, mkexpr(op2)));
10592 }
florian1c8f7ff2012-09-01 00:12:11 +000010593 return "cxlgbr";
10594}
10595
10596static HChar *
florian4b8efad2012-09-02 18:07:08 +000010597s390_irgen_CFXBR(UChar m3, UChar m4 __attribute__((unused)),
10598 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000010599{
10600 IRTemp op = newTemp(Ity_F128);
10601 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +000010602 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +000010603
10604 assign(op, get_fpr_pair(r2));
florian19e00772012-09-06 03:13:22 +000010605 assign(result, binop(Iop_F128toI32S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +000010606 mkexpr(op)));
10607 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +000010608 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_INT_32, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +000010609
10610 return "cfxbr";
10611}
10612
10613static HChar *
florian1c8f7ff2012-09-01 00:12:11 +000010614s390_irgen_CLFXBR(UChar m3, UChar m4 __attribute__((unused)),
10615 UChar r1, UChar r2)
10616{
floriane75dafa2012-09-01 17:54:09 +000010617 if (! s390_host_has_fpext) {
10618 emulation_failure(EmFail_S390X_fpext);
10619 } else {
10620 IRTemp op = newTemp(Ity_F128);
10621 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +000010622 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +000010623
floriane75dafa2012-09-01 17:54:09 +000010624 assign(op, get_fpr_pair(r2));
florian19e00772012-09-06 03:13:22 +000010625 assign(result, binop(Iop_F128toI32U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +000010626 mkexpr(op)));
10627 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +000010628 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_UINT_32, op, rounding_mode);
floriane75dafa2012-09-01 17:54:09 +000010629 }
florian1c8f7ff2012-09-01 00:12:11 +000010630 return "clfxbr";
10631}
10632
10633
10634static HChar *
florian4b8efad2012-09-02 18:07:08 +000010635s390_irgen_CGXBR(UChar m3, UChar m4 __attribute__((unused)),
10636 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000010637{
10638 IRTemp op = newTemp(Ity_F128);
10639 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +000010640 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +000010641
10642 assign(op, get_fpr_pair(r2));
florian19e00772012-09-06 03:13:22 +000010643 assign(result, binop(Iop_F128toI64S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +000010644 mkexpr(op)));
10645 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +000010646 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_INT_64, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +000010647
10648 return "cgxbr";
10649}
10650
10651static HChar *
florian1c8f7ff2012-09-01 00:12:11 +000010652s390_irgen_CLGXBR(UChar m3, UChar m4 __attribute__((unused)),
10653 UChar r1, UChar r2)
10654{
floriane75dafa2012-09-01 17:54:09 +000010655 if (! s390_host_has_fpext) {
10656 emulation_failure(EmFail_S390X_fpext);
10657 } else {
10658 IRTemp op = newTemp(Ity_F128);
10659 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +000010660 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +000010661
floriane75dafa2012-09-01 17:54:09 +000010662 assign(op, get_fpr_pair(r2));
florian19e00772012-09-06 03:13:22 +000010663 assign(result, binop(Iop_F128toI64U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +000010664 mkexpr(op)));
10665 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +000010666 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_UINT_64, op,
10667 rounding_mode);
floriane75dafa2012-09-01 17:54:09 +000010668 }
florian1c8f7ff2012-09-01 00:12:11 +000010669 return "clgxbr";
10670}
10671
10672static HChar *
sewardj2019a972011-03-07 16:04:07 +000010673s390_irgen_DXBR(UChar r1, UChar r2)
10674{
10675 IRTemp op1 = newTemp(Ity_F128);
10676 IRTemp op2 = newTemp(Ity_F128);
10677 IRTemp result = newTemp(Ity_F128);
florian125e20d2012-10-07 15:42:37 +000010678 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000010679
10680 assign(op1, get_fpr_pair(r1));
10681 assign(op2, get_fpr_pair(r2));
floriandb4fcaa2012-09-05 19:54:08 +000010682 assign(result, triop(Iop_DivF128, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +000010683 mkexpr(op2)));
10684 put_fpr_pair(r1, mkexpr(result));
10685
10686 return "dxbr";
10687}
10688
10689static HChar *
10690s390_irgen_LTXBR(UChar r1, UChar r2)
10691{
10692 IRTemp result = newTemp(Ity_F128);
10693
10694 assign(result, get_fpr_pair(r2));
10695 put_fpr_pair(r1, mkexpr(result));
10696 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
10697
10698 return "ltxbr";
10699}
10700
10701static HChar *
10702s390_irgen_LCXBR(UChar r1, UChar r2)
10703{
10704 IRTemp result = newTemp(Ity_F128);
10705
10706 assign(result, unop(Iop_NegF128, get_fpr_pair(r2)));
10707 put_fpr_pair(r1, mkexpr(result));
10708 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
10709
10710 return "lcxbr";
10711}
10712
10713static HChar *
10714s390_irgen_LXDBR(UChar r1, UChar r2)
10715{
10716 IRTemp op = newTemp(Ity_F64);
10717
10718 assign(op, get_fpr_dw0(r2));
10719 put_fpr_pair(r1, unop(Iop_F64toF128, mkexpr(op)));
10720
10721 return "lxdbr";
10722}
10723
10724static HChar *
10725s390_irgen_LXEBR(UChar r1, UChar r2)
10726{
10727 IRTemp op = newTemp(Ity_F32);
10728
10729 assign(op, get_fpr_w0(r2));
10730 put_fpr_pair(r1, unop(Iop_F32toF128, mkexpr(op)));
10731
10732 return "lxebr";
10733}
10734
10735static HChar *
10736s390_irgen_LXDB(UChar r1, IRTemp op2addr)
10737{
10738 IRTemp op = newTemp(Ity_F64);
10739
10740 assign(op, load(Ity_F64, mkexpr(op2addr)));
10741 put_fpr_pair(r1, unop(Iop_F64toF128, mkexpr(op)));
10742
10743 return "lxdb";
10744}
10745
10746static HChar *
10747s390_irgen_LXEB(UChar r1, IRTemp op2addr)
10748{
10749 IRTemp op = newTemp(Ity_F32);
10750
10751 assign(op, load(Ity_F32, mkexpr(op2addr)));
10752 put_fpr_pair(r1, unop(Iop_F32toF128, mkexpr(op)));
10753
10754 return "lxeb";
10755}
10756
10757static HChar *
10758s390_irgen_LNEBR(UChar r1, UChar r2)
10759{
10760 IRTemp result = newTemp(Ity_F32);
10761
10762 assign(result, unop(Iop_NegF32, unop(Iop_AbsF32, get_fpr_w0(r2))));
10763 put_fpr_w0(r1, mkexpr(result));
10764 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_32, result);
10765
10766 return "lnebr";
10767}
10768
10769static HChar *
10770s390_irgen_LNDBR(UChar r1, UChar r2)
10771{
10772 IRTemp result = newTemp(Ity_F64);
10773
10774 assign(result, unop(Iop_NegF64, unop(Iop_AbsF64, get_fpr_dw0(r2))));
10775 put_fpr_dw0(r1, mkexpr(result));
10776 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_64, result);
10777
10778 return "lndbr";
10779}
10780
10781static HChar *
10782s390_irgen_LNXBR(UChar r1, UChar r2)
10783{
10784 IRTemp result = newTemp(Ity_F128);
10785
10786 assign(result, unop(Iop_NegF128, unop(Iop_AbsF128, get_fpr_pair(r2))));
10787 put_fpr_pair(r1, mkexpr(result));
10788 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
10789
10790 return "lnxbr";
10791}
10792
10793static HChar *
10794s390_irgen_LPEBR(UChar r1, UChar r2)
10795{
10796 IRTemp result = newTemp(Ity_F32);
10797
10798 assign(result, unop(Iop_AbsF32, get_fpr_w0(r2)));
10799 put_fpr_w0(r1, mkexpr(result));
10800 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_32, result);
10801
10802 return "lpebr";
10803}
10804
10805static HChar *
10806s390_irgen_LPDBR(UChar r1, UChar r2)
10807{
10808 IRTemp result = newTemp(Ity_F64);
10809
10810 assign(result, unop(Iop_AbsF64, get_fpr_dw0(r2)));
10811 put_fpr_dw0(r1, mkexpr(result));
10812 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_64, result);
10813
10814 return "lpdbr";
10815}
10816
10817static HChar *
10818s390_irgen_LPXBR(UChar r1, UChar r2)
10819{
10820 IRTemp result = newTemp(Ity_F128);
10821
10822 assign(result, unop(Iop_AbsF128, get_fpr_pair(r2)));
10823 put_fpr_pair(r1, mkexpr(result));
10824 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
10825
10826 return "lpxbr";
10827}
10828
10829static HChar *
florian4b8efad2012-09-02 18:07:08 +000010830s390_irgen_LDXBR(UChar m3, UChar m4 __attribute__((unused)),
10831 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000010832{
florian125e20d2012-10-07 15:42:37 +000010833 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian12b0bca2012-09-05 20:05:20 +000010834 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +000010835 m3 = S390_BFP_ROUND_PER_FPC;
florian12b0bca2012-09-05 20:05:20 +000010836 }
sewardj2019a972011-03-07 16:04:07 +000010837 IRTemp result = newTemp(Ity_F64);
10838
floriandb4fcaa2012-09-05 19:54:08 +000010839 assign(result, binop(Iop_F128toF64, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +000010840 get_fpr_pair(r2)));
sewardj2019a972011-03-07 16:04:07 +000010841 put_fpr_dw0(r1, mkexpr(result));
10842
10843 return "ldxbr";
10844}
10845
10846static HChar *
florian4b8efad2012-09-02 18:07:08 +000010847s390_irgen_LEXBR(UChar m3, UChar m4 __attribute__((unused)),
10848 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000010849{
florian125e20d2012-10-07 15:42:37 +000010850 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian12b0bca2012-09-05 20:05:20 +000010851 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +000010852 m3 = S390_BFP_ROUND_PER_FPC;
florian12b0bca2012-09-05 20:05:20 +000010853 }
sewardj2019a972011-03-07 16:04:07 +000010854 IRTemp result = newTemp(Ity_F32);
10855
floriandb4fcaa2012-09-05 19:54:08 +000010856 assign(result, binop(Iop_F128toF32, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +000010857 get_fpr_pair(r2)));
sewardj2019a972011-03-07 16:04:07 +000010858 put_fpr_w0(r1, mkexpr(result));
10859
10860 return "lexbr";
10861}
10862
10863static HChar *
10864s390_irgen_MXBR(UChar r1, UChar r2)
10865{
10866 IRTemp op1 = newTemp(Ity_F128);
10867 IRTemp op2 = newTemp(Ity_F128);
10868 IRTemp result = newTemp(Ity_F128);
florian125e20d2012-10-07 15:42:37 +000010869 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000010870
10871 assign(op1, get_fpr_pair(r1));
10872 assign(op2, get_fpr_pair(r2));
floriandb4fcaa2012-09-05 19:54:08 +000010873 assign(result, triop(Iop_MulF128, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +000010874 mkexpr(op2)));
10875 put_fpr_pair(r1, mkexpr(result));
10876
10877 return "mxbr";
10878}
10879
10880static HChar *
10881s390_irgen_MAEBR(UChar r1, UChar r3, UChar r2)
10882{
florian125e20d2012-10-07 15:42:37 +000010883 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
florian847684d2012-09-05 04:19:09 +000010884
floriandb4fcaa2012-09-05 19:54:08 +000010885 put_fpr_w0(r1, qop(Iop_MAddF32, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000010886 get_fpr_w0(r3), get_fpr_w0(r2), get_fpr_w0(r1)));
sewardj2019a972011-03-07 16:04:07 +000010887
10888 return "maebr";
10889}
10890
10891static HChar *
10892s390_irgen_MADBR(UChar r1, UChar r3, UChar r2)
10893{
florian125e20d2012-10-07 15:42:37 +000010894 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
florian847684d2012-09-05 04:19:09 +000010895
floriandb4fcaa2012-09-05 19:54:08 +000010896 put_fpr_dw0(r1, qop(Iop_MAddF64, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000010897 get_fpr_dw0(r3), get_fpr_dw0(r2), get_fpr_dw0(r1)));
sewardj2019a972011-03-07 16:04:07 +000010898
10899 return "madbr";
10900}
10901
10902static HChar *
10903s390_irgen_MAEB(UChar r3, IRTemp op2addr, UChar r1)
10904{
10905 IRExpr *op2 = load(Ity_F32, mkexpr(op2addr));
florian125e20d2012-10-07 15:42:37 +000010906 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000010907
floriandb4fcaa2012-09-05 19:54:08 +000010908 put_fpr_w0(r1, qop(Iop_MAddF32, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000010909 get_fpr_w0(r3), op2, get_fpr_w0(r1)));
sewardj2019a972011-03-07 16:04:07 +000010910
10911 return "maeb";
10912}
10913
10914static HChar *
10915s390_irgen_MADB(UChar r3, IRTemp op2addr, UChar r1)
10916{
10917 IRExpr *op2 = load(Ity_F64, mkexpr(op2addr));
florian125e20d2012-10-07 15:42:37 +000010918 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000010919
floriandb4fcaa2012-09-05 19:54:08 +000010920 put_fpr_dw0(r1, qop(Iop_MAddF64, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000010921 get_fpr_dw0(r3), op2, get_fpr_dw0(r1)));
sewardj2019a972011-03-07 16:04:07 +000010922
10923 return "madb";
10924}
10925
10926static HChar *
10927s390_irgen_MSEBR(UChar r1, UChar r3, UChar r2)
10928{
florian125e20d2012-10-07 15:42:37 +000010929 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
florian847684d2012-09-05 04:19:09 +000010930
floriandb4fcaa2012-09-05 19:54:08 +000010931 put_fpr_w0(r1, qop(Iop_MSubF32, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000010932 get_fpr_w0(r3), get_fpr_w0(r2), get_fpr_w0(r1)));
sewardj2019a972011-03-07 16:04:07 +000010933
10934 return "msebr";
10935}
10936
10937static HChar *
10938s390_irgen_MSDBR(UChar r1, UChar r3, UChar r2)
10939{
florian125e20d2012-10-07 15:42:37 +000010940 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
florian847684d2012-09-05 04:19:09 +000010941
floriandb4fcaa2012-09-05 19:54:08 +000010942 put_fpr_dw0(r1, qop(Iop_MSubF64, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000010943 get_fpr_dw0(r3), get_fpr_dw0(r2), get_fpr_dw0(r1)));
sewardj2019a972011-03-07 16:04:07 +000010944
10945 return "msdbr";
10946}
10947
10948static HChar *
10949s390_irgen_MSEB(UChar r3, IRTemp op2addr, UChar r1)
10950{
10951 IRExpr *op2 = load(Ity_F32, mkexpr(op2addr));
florian125e20d2012-10-07 15:42:37 +000010952 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000010953
floriandb4fcaa2012-09-05 19:54:08 +000010954 put_fpr_w0(r1, qop(Iop_MSubF32, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000010955 get_fpr_w0(r3), op2, get_fpr_w0(r1)));
sewardj2019a972011-03-07 16:04:07 +000010956
10957 return "mseb";
10958}
10959
10960static HChar *
10961s390_irgen_MSDB(UChar r3, IRTemp op2addr, UChar r1)
10962{
10963 IRExpr *op2 = load(Ity_F64, mkexpr(op2addr));
florian125e20d2012-10-07 15:42:37 +000010964 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000010965
floriandb4fcaa2012-09-05 19:54:08 +000010966 put_fpr_dw0(r1, qop(Iop_MSubF64, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000010967 get_fpr_dw0(r3), op2, get_fpr_dw0(r1)));
sewardj2019a972011-03-07 16:04:07 +000010968
10969 return "msdb";
10970}
10971
10972static HChar *
10973s390_irgen_SQEBR(UChar r1, UChar r2)
10974{
10975 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +000010976 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000010977
floriandb4fcaa2012-09-05 19:54:08 +000010978 assign(result, binop(Iop_SqrtF32, mkexpr(rounding_mode), get_fpr_w0(r2)));
sewardj2019a972011-03-07 16:04:07 +000010979 put_fpr_w0(r1, mkexpr(result));
10980
10981 return "sqebr";
10982}
10983
10984static HChar *
10985s390_irgen_SQDBR(UChar r1, UChar r2)
10986{
10987 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +000010988 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000010989
floriandb4fcaa2012-09-05 19:54:08 +000010990 assign(result, binop(Iop_SqrtF64, mkexpr(rounding_mode), get_fpr_dw0(r2)));
sewardj2019a972011-03-07 16:04:07 +000010991 put_fpr_dw0(r1, mkexpr(result));
10992
10993 return "sqdbr";
10994}
10995
10996static HChar *
10997s390_irgen_SQXBR(UChar r1, UChar r2)
10998{
10999 IRTemp result = newTemp(Ity_F128);
florian125e20d2012-10-07 15:42:37 +000011000 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011001
floriandb4fcaa2012-09-05 19:54:08 +000011002 assign(result, binop(Iop_SqrtF128, mkexpr(rounding_mode),
11003 get_fpr_pair(r2)));
sewardj2019a972011-03-07 16:04:07 +000011004 put_fpr_pair(r1, mkexpr(result));
11005
11006 return "sqxbr";
11007}
11008
11009static HChar *
11010s390_irgen_SQEB(UChar r1, IRTemp op2addr)
11011{
11012 IRTemp op = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +000011013 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011014
11015 assign(op, load(Ity_F32, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +000011016 put_fpr_w0(r1, binop(Iop_SqrtF32, mkexpr(rounding_mode), mkexpr(op)));
sewardj2019a972011-03-07 16:04:07 +000011017
11018 return "sqeb";
11019}
11020
11021static HChar *
11022s390_irgen_SQDB(UChar r1, IRTemp op2addr)
11023{
11024 IRTemp op = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +000011025 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011026
11027 assign(op, load(Ity_F64, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +000011028 put_fpr_dw0(r1, binop(Iop_SqrtF64, mkexpr(rounding_mode), mkexpr(op)));
sewardj2019a972011-03-07 16:04:07 +000011029
11030 return "sqdb";
11031}
11032
11033static HChar *
11034s390_irgen_SXBR(UChar r1, UChar r2)
11035{
11036 IRTemp op1 = newTemp(Ity_F128);
11037 IRTemp op2 = newTemp(Ity_F128);
11038 IRTemp result = newTemp(Ity_F128);
florian125e20d2012-10-07 15:42:37 +000011039 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011040
11041 assign(op1, get_fpr_pair(r1));
11042 assign(op2, get_fpr_pair(r2));
floriandb4fcaa2012-09-05 19:54:08 +000011043 assign(result, triop(Iop_SubF128, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +000011044 mkexpr(op2)));
11045 put_fpr_pair(r1, mkexpr(result));
11046 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
11047
11048 return "sxbr";
11049}
11050
11051static HChar *
11052s390_irgen_TCEB(UChar r1, IRTemp op2addr)
11053{
11054 IRTemp value = newTemp(Ity_F32);
11055
11056 assign(value, get_fpr_w0(r1));
11057
11058 s390_cc_thunk_putFZ(S390_CC_OP_BFP_TDC_32, value, op2addr);
11059
11060 return "tceb";
11061}
11062
11063static HChar *
11064s390_irgen_TCDB(UChar r1, IRTemp op2addr)
11065{
11066 IRTemp value = newTemp(Ity_F64);
11067
11068 assign(value, get_fpr_dw0(r1));
11069
11070 s390_cc_thunk_putFZ(S390_CC_OP_BFP_TDC_64, value, op2addr);
11071
11072 return "tcdb";
11073}
11074
11075static HChar *
11076s390_irgen_TCXB(UChar r1, IRTemp op2addr)
11077{
11078 IRTemp value = newTemp(Ity_F128);
11079
11080 assign(value, get_fpr_pair(r1));
11081
11082 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_TDC_128, value, op2addr);
11083
11084 return "tcxb";
11085}
11086
11087static HChar *
11088s390_irgen_LCDFR(UChar r1, UChar r2)
11089{
11090 IRTemp result = newTemp(Ity_F64);
11091
11092 assign(result, unop(Iop_NegF64, get_fpr_dw0(r2)));
11093 put_fpr_dw0(r1, mkexpr(result));
11094
11095 return "lcdfr";
11096}
11097
11098static HChar *
11099s390_irgen_LNDFR(UChar r1, UChar r2)
11100{
11101 IRTemp result = newTemp(Ity_F64);
11102
11103 assign(result, unop(Iop_NegF64, unop(Iop_AbsF64, get_fpr_dw0(r2))));
11104 put_fpr_dw0(r1, mkexpr(result));
11105
11106 return "lndfr";
11107}
11108
11109static HChar *
11110s390_irgen_LPDFR(UChar r1, UChar r2)
11111{
11112 IRTemp result = newTemp(Ity_F64);
11113
11114 assign(result, unop(Iop_AbsF64, get_fpr_dw0(r2)));
11115 put_fpr_dw0(r1, mkexpr(result));
11116
11117 return "lpdfr";
11118}
11119
11120static HChar *
11121s390_irgen_LDGR(UChar r1, UChar r2)
11122{
11123 put_fpr_dw0(r1, unop(Iop_ReinterpI64asF64, get_gpr_dw0(r2)));
11124
11125 return "ldgr";
11126}
11127
11128static HChar *
11129s390_irgen_LGDR(UChar r1, UChar r2)
11130{
11131 put_gpr_dw0(r1, unop(Iop_ReinterpF64asI64, get_fpr_dw0(r2)));
11132
11133 return "lgdr";
11134}
11135
11136
11137static HChar *
11138s390_irgen_CPSDR(UChar r3, UChar r1, UChar r2)
11139{
11140 IRTemp sign = newTemp(Ity_I64);
11141 IRTemp value = newTemp(Ity_I64);
11142
11143 assign(sign, binop(Iop_And64, unop(Iop_ReinterpF64asI64, get_fpr_dw0(r3)),
11144 mkU64(1ULL << 63)));
11145 assign(value, binop(Iop_And64, unop(Iop_ReinterpF64asI64, get_fpr_dw0(r2)),
11146 mkU64((1ULL << 63) - 1)));
11147 put_fpr_dw0(r1, unop(Iop_ReinterpI64asF64, binop(Iop_Or64, mkexpr(value),
11148 mkexpr(sign))));
11149
11150 return "cpsdr";
11151}
11152
11153
sewardj2019a972011-03-07 16:04:07 +000011154static IRExpr *
11155s390_call_cvb(IRExpr *in)
11156{
11157 IRExpr **args, *call;
11158
11159 args = mkIRExprVec_1(in);
11160 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
11161 "s390_do_cvb", &s390_do_cvb, args);
11162
11163 /* Nothing is excluded from definedness checking. */
11164 call->Iex.CCall.cee->mcx_mask = 0;
11165
11166 return call;
11167}
11168
11169static HChar *
11170s390_irgen_CVB(UChar r1, IRTemp op2addr)
11171{
11172 put_gpr_w1(r1, s390_call_cvb(load(Ity_I64, mkexpr(op2addr))));
11173
11174 return "cvb";
11175}
11176
11177static HChar *
11178s390_irgen_CVBY(UChar r1, IRTemp op2addr)
11179{
11180 put_gpr_w1(r1, s390_call_cvb(load(Ity_I64, mkexpr(op2addr))));
11181
11182 return "cvby";
11183}
11184
11185
sewardj2019a972011-03-07 16:04:07 +000011186static IRExpr *
11187s390_call_cvd(IRExpr *in)
11188{
11189 IRExpr **args, *call;
11190
11191 args = mkIRExprVec_1(in);
11192 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
11193 "s390_do_cvd", &s390_do_cvd, args);
11194
11195 /* Nothing is excluded from definedness checking. */
11196 call->Iex.CCall.cee->mcx_mask = 0;
11197
11198 return call;
11199}
11200
11201static HChar *
11202s390_irgen_CVD(UChar r1, IRTemp op2addr)
11203{
florian11b8ee82012-08-06 13:35:33 +000011204 store(mkexpr(op2addr), s390_call_cvd(unop(Iop_32Uto64, get_gpr_w1(r1))));
sewardj2019a972011-03-07 16:04:07 +000011205
11206 return "cvd";
11207}
11208
11209static HChar *
11210s390_irgen_CVDY(UChar r1, IRTemp op2addr)
11211{
11212 store(mkexpr(op2addr), s390_call_cvd(get_gpr_w1(r1)));
11213
11214 return "cvdy";
11215}
11216
11217static HChar *
11218s390_irgen_FLOGR(UChar r1, UChar r2)
11219{
11220 IRTemp input = newTemp(Ity_I64);
11221 IRTemp not_zero = newTemp(Ity_I64);
11222 IRTemp tmpnum = newTemp(Ity_I64);
11223 IRTemp num = newTemp(Ity_I64);
11224 IRTemp shift_amount = newTemp(Ity_I8);
11225
11226 /* We use the "count leading zeroes" operator because the number of
11227 leading zeroes is identical with the bit position of the first '1' bit.
11228 However, that operator does not work when the input value is zero.
11229 Therefore, we set the LSB of the input value to 1 and use Clz64 on
11230 the modified value. If input == 0, then the result is 64. Otherwise,
11231 the result of Clz64 is what we want. */
11232
11233 assign(input, get_gpr_dw0(r2));
11234 assign(not_zero, binop(Iop_Or64, mkexpr(input), mkU64(1)));
11235 assign(tmpnum, unop(Iop_Clz64, mkexpr(not_zero)));
11236
11237 /* num = (input == 0) ? 64 : tmpnum */
11238 assign(num, mkite(binop(Iop_CmpEQ64, mkexpr(input), mkU64(0)),
11239 /* == 0 */ mkU64(64),
11240 /* != 0 */ mkexpr(tmpnum)));
11241
11242 put_gpr_dw0(r1, mkexpr(num));
11243
11244 /* Set the leftmost '1' bit of the input value to zero. The general scheme
11245 is to first shift the input value by NUM + 1 bits to the left which
11246 causes the leftmost '1' bit to disappear. Then we shift logically to
11247 the right by NUM + 1 bits. Because the semantics of Iop_Shl64 and
11248 Iop_Shr64 are undefined if the shift-amount is greater than or equal to
11249 the width of the value-to-be-shifted, we need to special case
11250 NUM + 1 >= 64. This is equivalent to INPUT != 0 && INPUT != 1.
11251 For both such INPUT values the result will be 0. */
11252
11253 assign(shift_amount, unop(Iop_64to8, binop(Iop_Add64, mkexpr(num),
11254 mkU64(1))));
11255
11256 put_gpr_dw0(r1 + 1,
florian6ad49522011-09-09 02:38:55 +000011257 mkite(binop(Iop_CmpLE64U, mkexpr(input), mkU64(1)),
11258 /* == 0 || == 1*/ mkU64(0),
11259 /* otherwise */
11260 binop(Iop_Shr64,
11261 binop(Iop_Shl64, mkexpr(input),
11262 mkexpr(shift_amount)),
11263 mkexpr(shift_amount))));
sewardj2019a972011-03-07 16:04:07 +000011264
11265 /* Compare the original value as an unsigned integer with 0. */
11266 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, input,
11267 mktemp(Ity_I64, mkU64(0)), False);
11268
11269 return "flogr";
11270}
11271
sewardj1e5fea62011-05-17 16:18:36 +000011272static HChar *
11273s390_irgen_STCK(IRTemp op2addr)
11274{
11275 IRDirty *d;
11276 IRTemp cc = newTemp(Ity_I64);
11277
11278 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STCK",
11279 &s390x_dirtyhelper_STCK,
11280 mkIRExprVec_1(mkexpr(op2addr)));
11281 d->mFx = Ifx_Write;
11282 d->mAddr = mkexpr(op2addr);
11283 d->mSize = 8;
11284 stmt(IRStmt_Dirty(d));
11285 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
11286 mkexpr(cc), mkU64(0), mkU64(0));
11287 return "stck";
11288}
11289
11290static HChar *
11291s390_irgen_STCKF(IRTemp op2addr)
11292{
florianc5c669b2012-08-26 14:32:28 +000011293 if (! s390_host_has_stckf) {
floriane75dafa2012-09-01 17:54:09 +000011294 emulation_failure(EmFail_S390X_stckf);
florianc5c669b2012-08-26 14:32:28 +000011295 } else {
11296 IRTemp cc = newTemp(Ity_I64);
sewardj1e5fea62011-05-17 16:18:36 +000011297
florianc5c669b2012-08-26 14:32:28 +000011298 IRDirty *d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STCKF",
11299 &s390x_dirtyhelper_STCKF,
11300 mkIRExprVec_1(mkexpr(op2addr)));
11301 d->mFx = Ifx_Write;
11302 d->mAddr = mkexpr(op2addr);
11303 d->mSize = 8;
11304 stmt(IRStmt_Dirty(d));
11305 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
11306 mkexpr(cc), mkU64(0), mkU64(0));
11307 }
sewardj1e5fea62011-05-17 16:18:36 +000011308 return "stckf";
11309}
11310
11311static HChar *
11312s390_irgen_STCKE(IRTemp op2addr)
11313{
11314 IRDirty *d;
11315 IRTemp cc = newTemp(Ity_I64);
11316
11317 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STCKE",
11318 &s390x_dirtyhelper_STCKE,
11319 mkIRExprVec_1(mkexpr(op2addr)));
11320 d->mFx = Ifx_Write;
11321 d->mAddr = mkexpr(op2addr);
11322 d->mSize = 16;
11323 stmt(IRStmt_Dirty(d));
11324 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
11325 mkexpr(cc), mkU64(0), mkU64(0));
11326 return "stcke";
11327}
11328
florian933065d2011-07-11 01:48:02 +000011329static HChar *
11330s390_irgen_STFLE(IRTemp op2addr)
11331{
florian4e0083e2012-08-26 03:41:56 +000011332 if (! s390_host_has_stfle) {
floriane75dafa2012-09-01 17:54:09 +000011333 emulation_failure(EmFail_S390X_stfle);
florian4e0083e2012-08-26 03:41:56 +000011334 return "stfle";
11335 }
11336
florian933065d2011-07-11 01:48:02 +000011337 IRDirty *d;
11338 IRTemp cc = newTemp(Ity_I64);
11339
11340 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STFLE",
11341 &s390x_dirtyhelper_STFLE,
11342 mkIRExprVec_1(mkexpr(op2addr)));
11343
11344 d->needsBBP = 1; /* Need to pass pointer to guest state to helper */
11345
sewardjc9069f22012-06-01 16:09:50 +000011346 d->nFxState = 1;
11347 vex_bzero(&d->fxState, sizeof(d->fxState));
11348
florian933065d2011-07-11 01:48:02 +000011349 d->fxState[0].fx = Ifx_Modify; /* read then write */
11350 d->fxState[0].offset = S390X_GUEST_OFFSET(guest_r0);
11351 d->fxState[0].size = sizeof(ULong);
florian933065d2011-07-11 01:48:02 +000011352
11353 d->mAddr = mkexpr(op2addr);
11354 /* Pretend all double words are written */
11355 d->mSize = S390_NUM_FACILITY_DW * sizeof(ULong);
11356 d->mFx = Ifx_Write;
11357
11358 stmt(IRStmt_Dirty(d));
11359
11360 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET), mkexpr(cc), mkU64(0), mkU64(0));
11361
11362 return "stfle";
11363}
11364
floriana4384a32011-08-11 16:58:45 +000011365static HChar *
11366s390_irgen_CKSM(UChar r1,UChar r2)
11367{
11368 IRTemp addr = newTemp(Ity_I64);
11369 IRTemp op = newTemp(Ity_I32);
11370 IRTemp len = newTemp(Ity_I64);
11371 IRTemp oldval = newTemp(Ity_I32);
11372 IRTemp mask = newTemp(Ity_I32);
11373 IRTemp newop = newTemp(Ity_I32);
11374 IRTemp result = newTemp(Ity_I32);
11375 IRTemp result1 = newTemp(Ity_I32);
11376 IRTemp inc = newTemp(Ity_I64);
11377
11378 assign(oldval, get_gpr_w1(r1));
11379 assign(addr, get_gpr_dw0(r2));
11380 assign(len, get_gpr_dw0(r2+1));
11381
11382 /* Condition code is always zero. */
11383 s390_cc_set(0);
11384
11385 /* If length is zero, there is no need to calculate the checksum */
florian6820ba52012-07-26 02:01:50 +000011386 next_insn_if(binop(Iop_CmpEQ64, mkexpr(len), mkU64(0)));
floriana4384a32011-08-11 16:58:45 +000011387
11388 /* Assiging the increment variable to adjust address and length
11389 later on. */
11390 assign(inc, mkite(binop(Iop_CmpLT64U, mkexpr(len), mkU64(4)),
11391 mkexpr(len), mkU64(4)));
11392
11393 /* If length < 4 the final 4-byte 2nd operand value is computed by
11394 appending the remaining bytes to the right with 0. This is done
11395 by AND'ing the 4 bytes loaded from memory with an appropriate
11396 mask. If length >= 4, that mask is simply 0xffffffff. */
11397
11398 assign(mask, mkite(binop(Iop_CmpLT64U, mkexpr(len), mkU64(4)),
11399 /* Mask computation when len < 4:
11400 0xffffffff << (32 - (len % 4)*8) */
11401 binop(Iop_Shl32, mkU32(0xffffffff),
11402 unop(Iop_32to8,
11403 binop(Iop_Sub32, mkU32(32),
11404 binop(Iop_Shl32,
11405 unop(Iop_64to32,
11406 binop(Iop_And64,
11407 mkexpr(len), mkU64(3))),
11408 mkU8(3))))),
11409 mkU32(0xffffffff)));
11410
11411 assign(op, load(Ity_I32, mkexpr(addr)));
11412 assign(newop, binop(Iop_And32, mkexpr(op), mkexpr(mask)));
11413 assign(result, binop(Iop_Add32, mkexpr(newop), mkexpr(oldval)));
11414
11415 /* Checking for carry */
11416 assign(result1, mkite(binop(Iop_CmpLT32U, mkexpr(result), mkexpr(newop)),
11417 binop(Iop_Add32, mkexpr(result), mkU32(1)),
11418 mkexpr(result)));
11419
11420 put_gpr_w1(r1, mkexpr(result1));
11421 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr), mkexpr(inc)));
11422 put_gpr_dw0(r2+1, binop(Iop_Sub64, mkexpr(len), mkexpr(inc)));
11423
florian6820ba52012-07-26 02:01:50 +000011424 iterate_if(binop(Iop_CmpNE64, mkexpr(len), mkU64(0)));
floriana4384a32011-08-11 16:58:45 +000011425
11426 return "cksm";
11427}
11428
florian9af37692012-01-15 21:01:16 +000011429static HChar *
11430s390_irgen_TROO(UChar m3, UChar r1, UChar r2)
11431{
11432 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
11433 src_addr = newTemp(Ity_I64);
11434 des_addr = newTemp(Ity_I64);
11435 tab_addr = newTemp(Ity_I64);
11436 test_byte = newTemp(Ity_I8);
11437 src_len = newTemp(Ity_I64);
11438
11439 assign(src_addr, get_gpr_dw0(r2));
11440 assign(des_addr, get_gpr_dw0(r1));
11441 assign(tab_addr, get_gpr_dw0(1));
florian53518532012-01-18 14:00:31 +000011442 assign(src_len, get_gpr_dw0(r1+1));
florian9af37692012-01-15 21:01:16 +000011443 assign(test_byte, get_gpr_b7(0));
11444
11445 IRTemp op = newTemp(Ity_I8);
11446 IRTemp op1 = newTemp(Ity_I8);
11447 IRTemp result = newTemp(Ity_I64);
11448
11449 /* End of source string? We're done; proceed to next insn */
11450 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000011451 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian9af37692012-01-15 21:01:16 +000011452
11453 /* Load character from source string, index translation table and
11454 store translated character in op1. */
11455 assign(op, load(Ity_I8, mkexpr(src_addr)));
11456
11457 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)),
11458 mkexpr(tab_addr)));
11459 assign(op1, load(Ity_I8, mkexpr(result)));
11460
11461 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
11462 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000011463 next_insn_if(binop(Iop_CmpEQ8, mkexpr(op1), mkexpr(test_byte)));
florian9af37692012-01-15 21:01:16 +000011464 }
11465 store(get_gpr_dw0(r1), mkexpr(op1));
11466
11467 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(1)));
11468 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(1)));
11469 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(1)));
11470
florian6820ba52012-07-26 02:01:50 +000011471 iterate();
florian9af37692012-01-15 21:01:16 +000011472
11473 return "troo";
11474}
11475
florian730448f2012-02-04 17:07:07 +000011476static HChar *
11477s390_irgen_TRTO(UChar m3, UChar r1, UChar r2)
11478{
11479 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
11480 src_addr = newTemp(Ity_I64);
11481 des_addr = newTemp(Ity_I64);
11482 tab_addr = newTemp(Ity_I64);
11483 test_byte = newTemp(Ity_I8);
11484 src_len = newTemp(Ity_I64);
11485
11486 assign(src_addr, get_gpr_dw0(r2));
11487 assign(des_addr, get_gpr_dw0(r1));
11488 assign(tab_addr, get_gpr_dw0(1));
11489 assign(src_len, get_gpr_dw0(r1+1));
11490 assign(test_byte, get_gpr_b7(0));
11491
11492 IRTemp op = newTemp(Ity_I16);
11493 IRTemp op1 = newTemp(Ity_I8);
11494 IRTemp result = newTemp(Ity_I64);
11495
11496 /* End of source string? We're done; proceed to next insn */
11497 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000011498 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian730448f2012-02-04 17:07:07 +000011499
11500 /* Load character from source string, index translation table and
11501 store translated character in op1. */
11502 assign(op, load(Ity_I16, mkexpr(src_addr)));
11503
11504 assign(result, binop(Iop_Add64, unop(Iop_16Uto64, mkexpr(op)),
11505 mkexpr(tab_addr)));
11506
11507 assign(op1, load(Ity_I8, mkexpr(result)));
11508
11509 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
11510 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000011511 next_insn_if(binop(Iop_CmpEQ8, mkexpr(op1), mkexpr(test_byte)));
florian730448f2012-02-04 17:07:07 +000011512 }
11513 store(get_gpr_dw0(r1), mkexpr(op1));
11514
11515 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(2)));
11516 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(1)));
11517 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(2)));
11518
florian6820ba52012-07-26 02:01:50 +000011519 iterate();
florian730448f2012-02-04 17:07:07 +000011520
11521 return "trto";
11522}
11523
11524static HChar *
11525s390_irgen_TROT(UChar m3, UChar r1, UChar r2)
11526{
11527 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
11528 src_addr = newTemp(Ity_I64);
11529 des_addr = newTemp(Ity_I64);
11530 tab_addr = newTemp(Ity_I64);
11531 test_byte = newTemp(Ity_I16);
11532 src_len = newTemp(Ity_I64);
11533
11534 assign(src_addr, get_gpr_dw0(r2));
11535 assign(des_addr, get_gpr_dw0(r1));
11536 assign(tab_addr, get_gpr_dw0(1));
11537 assign(src_len, get_gpr_dw0(r1+1));
11538 assign(test_byte, get_gpr_hw3(0));
11539
11540 IRTemp op = newTemp(Ity_I8);
11541 IRTemp op1 = newTemp(Ity_I16);
11542 IRTemp result = newTemp(Ity_I64);
11543
11544 /* End of source string? We're done; proceed to next insn */
11545 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000011546 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian730448f2012-02-04 17:07:07 +000011547
11548 /* Load character from source string, index translation table and
11549 store translated character in op1. */
11550 assign(op, binop(Iop_Shl8, load(Ity_I8, mkexpr(src_addr)), mkU8(1)));
11551
11552 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)),
11553 mkexpr(tab_addr)));
11554 assign(op1, load(Ity_I16, mkexpr(result)));
11555
11556 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
11557 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000011558 next_insn_if(binop(Iop_CmpEQ16, mkexpr(op1), mkexpr(test_byte)));
florian730448f2012-02-04 17:07:07 +000011559 }
11560 store(get_gpr_dw0(r1), mkexpr(op1));
11561
11562 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(1)));
11563 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(2)));
11564 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(1)));
11565
florian6820ba52012-07-26 02:01:50 +000011566 iterate();
florian730448f2012-02-04 17:07:07 +000011567
11568 return "trot";
11569}
11570
11571static HChar *
11572s390_irgen_TRTT(UChar m3, UChar r1, UChar r2)
11573{
11574 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
11575 src_addr = newTemp(Ity_I64);
11576 des_addr = newTemp(Ity_I64);
11577 tab_addr = newTemp(Ity_I64);
11578 test_byte = newTemp(Ity_I16);
11579 src_len = newTemp(Ity_I64);
11580
11581 assign(src_addr, get_gpr_dw0(r2));
11582 assign(des_addr, get_gpr_dw0(r1));
11583 assign(tab_addr, get_gpr_dw0(1));
11584 assign(src_len, get_gpr_dw0(r1+1));
11585 assign(test_byte, get_gpr_hw3(0));
11586
11587 IRTemp op = newTemp(Ity_I16);
11588 IRTemp op1 = newTemp(Ity_I16);
11589 IRTemp result = newTemp(Ity_I64);
11590
11591 /* End of source string? We're done; proceed to next insn */
11592 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000011593 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian730448f2012-02-04 17:07:07 +000011594
11595 /* Load character from source string, index translation table and
11596 store translated character in op1. */
11597 assign(op, binop(Iop_Shl16, load(Ity_I16, mkexpr(src_addr)), mkU8(1)));
11598
11599 assign(result, binop(Iop_Add64, unop(Iop_16Uto64, mkexpr(op)),
11600 mkexpr(tab_addr)));
11601 assign(op1, load(Ity_I16, mkexpr(result)));
11602
11603 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
11604 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000011605 next_insn_if(binop(Iop_CmpEQ16, mkexpr(op1), mkexpr(test_byte)));
florian730448f2012-02-04 17:07:07 +000011606 }
11607
11608 store(get_gpr_dw0(r1), mkexpr(op1));
11609
11610 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(2)));
11611 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(2)));
11612 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(2)));
11613
florian6820ba52012-07-26 02:01:50 +000011614 iterate();
florian730448f2012-02-04 17:07:07 +000011615
11616 return "trtt";
11617}
11618
11619static HChar *
11620s390_irgen_TR(UChar length, IRTemp start1, IRTemp start2)
11621{
florianf87d4fb2012-05-05 02:55:24 +000011622 IRTemp len = newTemp(Ity_I64);
florian730448f2012-02-04 17:07:07 +000011623
florianf87d4fb2012-05-05 02:55:24 +000011624 assign(len, mkU64(length));
11625 s390_irgen_TR_EX(len, start1, start2);
florian730448f2012-02-04 17:07:07 +000011626
11627 return "tr";
11628}
11629
11630static HChar *
11631s390_irgen_TRE(UChar r1,UChar r2)
11632{
11633 IRTemp src_addr, tab_addr, src_len, test_byte;
11634 src_addr = newTemp(Ity_I64);
11635 tab_addr = newTemp(Ity_I64);
11636 src_len = newTemp(Ity_I64);
11637 test_byte = newTemp(Ity_I8);
11638
11639 assign(src_addr, get_gpr_dw0(r1));
11640 assign(src_len, get_gpr_dw0(r1+1));
11641 assign(tab_addr, get_gpr_dw0(r2));
11642 assign(test_byte, get_gpr_b7(0));
11643
11644 IRTemp op = newTemp(Ity_I8);
11645 IRTemp op1 = newTemp(Ity_I8);
11646 IRTemp result = newTemp(Ity_I64);
11647
11648 /* End of source string? We're done; proceed to next insn */
11649 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000011650 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian730448f2012-02-04 17:07:07 +000011651
11652 /* Load character from source string and compare with test byte */
11653 assign(op, load(Ity_I8, mkexpr(src_addr)));
11654
11655 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000011656 next_insn_if(binop(Iop_CmpEQ8, mkexpr(op), mkexpr(test_byte)));
florian730448f2012-02-04 17:07:07 +000011657
11658 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)),
11659 mkexpr(tab_addr)));
11660
11661 assign(op1, load(Ity_I8, mkexpr(result)));
11662
11663 store(get_gpr_dw0(r1), mkexpr(op1));
11664 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(src_addr), mkU64(1)));
11665 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(1)));
11666
florian6820ba52012-07-26 02:01:50 +000011667 iterate();
florian730448f2012-02-04 17:07:07 +000011668
11669 return "tre";
11670}
11671
floriana0100c92012-07-20 00:06:35 +000011672static IRExpr *
11673s390_call_cu21(IRExpr *srcval, IRExpr *low_surrogate)
11674{
11675 IRExpr **args, *call;
11676 args = mkIRExprVec_2(srcval, low_surrogate);
11677 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
11678 "s390_do_cu21", &s390_do_cu21, args);
11679
11680 /* Nothing is excluded from definedness checking. */
11681 call->Iex.CCall.cee->mcx_mask = 0;
11682
11683 return call;
11684}
11685
11686static HChar *
11687s390_irgen_CU21(UChar m3, UChar r1, UChar r2)
11688{
11689 IRTemp addr1 = newTemp(Ity_I64);
11690 IRTemp addr2 = newTemp(Ity_I64);
11691 IRTemp len1 = newTemp(Ity_I64);
11692 IRTemp len2 = newTemp(Ity_I64);
11693
11694 assign(addr1, get_gpr_dw0(r1));
11695 assign(addr2, get_gpr_dw0(r2));
11696 assign(len1, get_gpr_dw0(r1 + 1));
11697 assign(len2, get_gpr_dw0(r2 + 1));
11698
11699 /* We're processing the 2nd operand 2 bytes at a time. Therefore, if
11700 there are less than 2 bytes left, then the 2nd operand is exhausted
11701 and we're done here. cc = 0 */
11702 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000011703 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(2)));
floriana0100c92012-07-20 00:06:35 +000011704
11705 /* There are at least two bytes there. Read them. */
11706 IRTemp srcval = newTemp(Ity_I32);
11707 assign(srcval, unop(Iop_16Uto32, load(Ity_I16, mkexpr(addr2))));
11708
11709 /* Find out whether this is a high surrogate. I.e. SRCVAL lies
11710 inside the interval [0xd800 - 0xdbff] */
11711 IRTemp is_high_surrogate = newTemp(Ity_I32);
11712 IRExpr *flag1 = mkite(binop(Iop_CmpLE32U, mkU32(0xd800), mkexpr(srcval)),
11713 mkU32(1), mkU32(0));
11714 IRExpr *flag2 = mkite(binop(Iop_CmpLE32U, mkexpr(srcval), mkU32(0xdbff)),
11715 mkU32(1), mkU32(0));
11716 assign(is_high_surrogate, binop(Iop_And32, flag1, flag2));
11717
11718 /* If SRCVAL is a high surrogate and there are less than 4 bytes left,
11719 then the 2nd operand is exhausted and we're done here. cc = 0 */
11720 IRExpr *not_enough_bytes =
11721 mkite(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)), mkU32(1), mkU32(0));
11722
florian6820ba52012-07-26 02:01:50 +000011723 next_insn_if(binop(Iop_CmpEQ32,
11724 binop(Iop_And32, mkexpr(is_high_surrogate),
11725 not_enough_bytes), mkU32(1)));
floriana0100c92012-07-20 00:06:35 +000011726
11727 /* The 2nd operand is not exhausted. If the first 2 bytes are a high
11728 surrogate, read the next two bytes (low surrogate). */
11729 IRTemp low_surrogate = newTemp(Ity_I32);
11730 IRExpr *low_surrogate_addr = binop(Iop_Add64, mkexpr(addr2), mkU64(2));
11731
11732 assign(low_surrogate,
11733 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
11734 unop(Iop_16Uto32, load(Ity_I16, low_surrogate_addr)),
11735 mkU32(0))); // any value is fine; it will not be used
11736
11737 /* Call the helper */
11738 IRTemp retval = newTemp(Ity_I64);
florian11b8ee82012-08-06 13:35:33 +000011739 assign(retval, s390_call_cu21(unop(Iop_32Uto64, mkexpr(srcval)),
11740 unop(Iop_32Uto64, mkexpr(low_surrogate))));
floriana0100c92012-07-20 00:06:35 +000011741
11742 /* Before we can test whether the 1st operand is exhausted we need to
11743 test for an invalid low surrogate. Because cc=2 outranks cc=1. */
11744 if (s390_host_has_etf3 && (m3 & 0x1) == 1) {
11745 IRExpr *invalid_low_surrogate =
11746 binop(Iop_And64, mkexpr(retval), mkU64(0xff));
11747
11748 s390_cc_set(2);
florian6820ba52012-07-26 02:01:50 +000011749 next_insn_if(binop(Iop_CmpEQ64, invalid_low_surrogate, mkU64(1)));
floriana0100c92012-07-20 00:06:35 +000011750 }
11751
11752 /* Now test whether the 1st operand is exhausted */
11753 IRTemp num_bytes = newTemp(Ity_I64);
11754 assign(num_bytes, binop(Iop_And64,
11755 binop(Iop_Shr64, mkexpr(retval), mkU8(8)),
11756 mkU64(0xff)));
11757 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000011758 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
floriana0100c92012-07-20 00:06:35 +000011759
11760 /* Extract the bytes to be stored at addr1 */
11761 IRTemp data = newTemp(Ity_I64);
11762 assign(data, binop(Iop_Shr64, mkexpr(retval), mkU8(16)));
11763
11764 /* To store the bytes construct 4 dirty helper calls. The helper calls
11765 are guarded (num_bytes == 1, num_bytes == 2, etc) such that only
11766 one of them will be called at runtime. */
11767 int i;
11768 for (i = 1; i <= 4; ++i) {
11769 IRDirty *d;
11770
11771 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
11772 &s390x_dirtyhelper_CUxy,
11773 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
11774 mkexpr(num_bytes)));
11775 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
11776 d->mFx = Ifx_Write;
11777 d->mAddr = mkexpr(addr1);
11778 d->mSize = i;
11779 stmt(IRStmt_Dirty(d));
11780 }
11781
11782 /* Update source address and length */
11783 IRTemp num_src_bytes = newTemp(Ity_I64);
11784 assign(num_src_bytes,
11785 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
11786 mkU64(4), mkU64(2)));
11787 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkexpr(num_src_bytes)));
11788 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkexpr(num_src_bytes)));
11789
11790 /* Update destination address and length */
11791 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
11792 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
11793
florian6820ba52012-07-26 02:01:50 +000011794 iterate();
floriana0100c92012-07-20 00:06:35 +000011795
11796 return "cu21";
11797}
11798
florian2a415a12012-07-21 17:41:36 +000011799static IRExpr *
11800s390_call_cu24(IRExpr *srcval, IRExpr *low_surrogate)
11801{
11802 IRExpr **args, *call;
11803 args = mkIRExprVec_2(srcval, low_surrogate);
11804 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
11805 "s390_do_cu24", &s390_do_cu24, args);
11806
11807 /* Nothing is excluded from definedness checking. */
11808 call->Iex.CCall.cee->mcx_mask = 0;
11809
11810 return call;
11811}
11812
11813static HChar *
11814s390_irgen_CU24(UChar m3, UChar r1, UChar r2)
11815{
11816 IRTemp addr1 = newTemp(Ity_I64);
11817 IRTemp addr2 = newTemp(Ity_I64);
11818 IRTemp len1 = newTemp(Ity_I64);
11819 IRTemp len2 = newTemp(Ity_I64);
11820
11821 assign(addr1, get_gpr_dw0(r1));
11822 assign(addr2, get_gpr_dw0(r2));
11823 assign(len1, get_gpr_dw0(r1 + 1));
11824 assign(len2, get_gpr_dw0(r2 + 1));
11825
11826 /* We're processing the 2nd operand 2 bytes at a time. Therefore, if
11827 there are less than 2 bytes left, then the 2nd operand is exhausted
11828 and we're done here. cc = 0 */
11829 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000011830 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(2)));
florian2a415a12012-07-21 17:41:36 +000011831
11832 /* There are at least two bytes there. Read them. */
11833 IRTemp srcval = newTemp(Ity_I32);
11834 assign(srcval, unop(Iop_16Uto32, load(Ity_I16, mkexpr(addr2))));
11835
11836 /* Find out whether this is a high surrogate. I.e. SRCVAL lies
11837 inside the interval [0xd800 - 0xdbff] */
11838 IRTemp is_high_surrogate = newTemp(Ity_I32);
11839 IRExpr *flag1 = mkite(binop(Iop_CmpLE32U, mkU32(0xd800), mkexpr(srcval)),
11840 mkU32(1), mkU32(0));
11841 IRExpr *flag2 = mkite(binop(Iop_CmpLE32U, mkexpr(srcval), mkU32(0xdbff)),
11842 mkU32(1), mkU32(0));
11843 assign(is_high_surrogate, binop(Iop_And32, flag1, flag2));
11844
11845 /* If SRCVAL is a high surrogate and there are less than 4 bytes left,
11846 then the 2nd operand is exhausted and we're done here. cc = 0 */
11847 IRExpr *not_enough_bytes =
11848 mkite(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)), mkU32(1), mkU32(0));
11849
florian6820ba52012-07-26 02:01:50 +000011850 next_insn_if(binop(Iop_CmpEQ32,
11851 binop(Iop_And32, mkexpr(is_high_surrogate),
11852 not_enough_bytes),
11853 mkU32(1)));
florian2a415a12012-07-21 17:41:36 +000011854
11855 /* The 2nd operand is not exhausted. If the first 2 bytes are a high
11856 surrogate, read the next two bytes (low surrogate). */
11857 IRTemp low_surrogate = newTemp(Ity_I32);
11858 IRExpr *low_surrogate_addr = binop(Iop_Add64, mkexpr(addr2), mkU64(2));
11859
11860 assign(low_surrogate,
11861 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
11862 unop(Iop_16Uto32, load(Ity_I16, low_surrogate_addr)),
11863 mkU32(0))); // any value is fine; it will not be used
11864
11865 /* Call the helper */
11866 IRTemp retval = newTemp(Ity_I64);
florian11b8ee82012-08-06 13:35:33 +000011867 assign(retval, s390_call_cu24(unop(Iop_32Uto64, mkexpr(srcval)),
11868 unop(Iop_32Uto64, mkexpr(low_surrogate))));
florian2a415a12012-07-21 17:41:36 +000011869
11870 /* Before we can test whether the 1st operand is exhausted we need to
11871 test for an invalid low surrogate. Because cc=2 outranks cc=1. */
11872 if (s390_host_has_etf3 && (m3 & 0x1) == 1) {
11873 IRExpr *invalid_low_surrogate =
11874 binop(Iop_And64, mkexpr(retval), mkU64(0xff));
11875
11876 s390_cc_set(2);
florian6820ba52012-07-26 02:01:50 +000011877 next_insn_if(binop(Iop_CmpEQ64, invalid_low_surrogate, mkU64(1)));
florian2a415a12012-07-21 17:41:36 +000011878 }
11879
11880 /* Now test whether the 1st operand is exhausted */
11881 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000011882 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkU64(4)));
florian2a415a12012-07-21 17:41:36 +000011883
11884 /* Extract the bytes to be stored at addr1 */
11885 IRExpr *data = unop(Iop_64to32, binop(Iop_Shr64, mkexpr(retval), mkU8(8)));
11886
11887 store(mkexpr(addr1), data);
11888
11889 /* Update source address and length */
11890 IRTemp num_src_bytes = newTemp(Ity_I64);
11891 assign(num_src_bytes,
11892 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
11893 mkU64(4), mkU64(2)));
11894 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkexpr(num_src_bytes)));
11895 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkexpr(num_src_bytes)));
11896
11897 /* Update destination address and length */
11898 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkU64(4)));
11899 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkU64(4)));
11900
florian6820ba52012-07-26 02:01:50 +000011901 iterate();
florian2a415a12012-07-21 17:41:36 +000011902
11903 return "cu24";
11904}
floriana4384a32011-08-11 16:58:45 +000011905
florian956194b2012-07-28 22:18:32 +000011906static IRExpr *
11907s390_call_cu42(IRExpr *srcval)
11908{
11909 IRExpr **args, *call;
11910 args = mkIRExprVec_1(srcval);
11911 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
11912 "s390_do_cu42", &s390_do_cu42, args);
11913
11914 /* Nothing is excluded from definedness checking. */
11915 call->Iex.CCall.cee->mcx_mask = 0;
11916
11917 return call;
11918}
11919
11920static HChar *
11921s390_irgen_CU42(UChar r1, UChar r2)
11922{
11923 IRTemp addr1 = newTemp(Ity_I64);
11924 IRTemp addr2 = newTemp(Ity_I64);
11925 IRTemp len1 = newTemp(Ity_I64);
11926 IRTemp len2 = newTemp(Ity_I64);
11927
11928 assign(addr1, get_gpr_dw0(r1));
11929 assign(addr2, get_gpr_dw0(r2));
11930 assign(len1, get_gpr_dw0(r1 + 1));
11931 assign(len2, get_gpr_dw0(r2 + 1));
11932
11933 /* We're processing the 2nd operand 4 bytes at a time. Therefore, if
11934 there are less than 4 bytes left, then the 2nd operand is exhausted
11935 and we're done here. cc = 0 */
11936 s390_cc_set(0);
11937 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)));
11938
11939 /* Read the 2nd operand. */
11940 IRTemp srcval = newTemp(Ity_I32);
11941 assign(srcval, load(Ity_I32, mkexpr(addr2)));
11942
11943 /* Call the helper */
11944 IRTemp retval = newTemp(Ity_I64);
florian11b8ee82012-08-06 13:35:33 +000011945 assign(retval, s390_call_cu42(unop(Iop_32Uto64, mkexpr(srcval))));
florian956194b2012-07-28 22:18:32 +000011946
11947 /* If the UTF-32 character was invalid, set cc=2 and we're done.
11948 cc=2 outranks cc=1 (1st operand exhausted) */
11949 IRExpr *invalid_character = binop(Iop_And64, mkexpr(retval), mkU64(0xff));
11950
11951 s390_cc_set(2);
11952 next_insn_if(binop(Iop_CmpEQ64, invalid_character, mkU64(1)));
11953
11954 /* Now test whether the 1st operand is exhausted */
11955 IRTemp num_bytes = newTemp(Ity_I64);
11956 assign(num_bytes, binop(Iop_And64,
11957 binop(Iop_Shr64, mkexpr(retval), mkU8(8)),
11958 mkU64(0xff)));
11959 s390_cc_set(1);
11960 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
11961
11962 /* Extract the bytes to be stored at addr1 */
11963 IRTemp data = newTemp(Ity_I64);
11964 assign(data, binop(Iop_Shr64, mkexpr(retval), mkU8(16)));
11965
11966 /* To store the bytes construct 2 dirty helper calls. The helper calls
11967 are guarded (num_bytes == 2 and num_bytes == 4, respectively) such
11968 that only one of them will be called at runtime. */
11969
11970 Int i;
11971 for (i = 2; i <= 4; ++i) {
11972 IRDirty *d;
11973
11974 if (i == 3) continue; // skip this one
11975
11976 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
11977 &s390x_dirtyhelper_CUxy,
11978 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
11979 mkexpr(num_bytes)));
11980 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
11981 d->mFx = Ifx_Write;
11982 d->mAddr = mkexpr(addr1);
11983 d->mSize = i;
11984 stmt(IRStmt_Dirty(d));
11985 }
11986
11987 /* Update source address and length */
11988 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkU64(4)));
11989 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkU64(4)));
11990
11991 /* Update destination address and length */
11992 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
11993 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
11994
11995 iterate();
11996
11997 return "cu42";
11998}
11999
florian6d9b9b22012-08-03 18:35:39 +000012000static IRExpr *
florianaf2194f2012-08-06 00:07:54 +000012001s390_call_cu41(IRExpr *srcval)
12002{
12003 IRExpr **args, *call;
12004 args = mkIRExprVec_1(srcval);
12005 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
12006 "s390_do_cu41", &s390_do_cu41, args);
12007
12008 /* Nothing is excluded from definedness checking. */
12009 call->Iex.CCall.cee->mcx_mask = 0;
12010
12011 return call;
12012}
12013
12014static HChar *
12015s390_irgen_CU41(UChar r1, UChar r2)
12016{
12017 IRTemp addr1 = newTemp(Ity_I64);
12018 IRTemp addr2 = newTemp(Ity_I64);
12019 IRTemp len1 = newTemp(Ity_I64);
12020 IRTemp len2 = newTemp(Ity_I64);
12021
12022 assign(addr1, get_gpr_dw0(r1));
12023 assign(addr2, get_gpr_dw0(r2));
12024 assign(len1, get_gpr_dw0(r1 + 1));
12025 assign(len2, get_gpr_dw0(r2 + 1));
12026
12027 /* We're processing the 2nd operand 4 bytes at a time. Therefore, if
12028 there are less than 4 bytes left, then the 2nd operand is exhausted
12029 and we're done here. cc = 0 */
12030 s390_cc_set(0);
12031 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)));
12032
12033 /* Read the 2nd operand. */
12034 IRTemp srcval = newTemp(Ity_I32);
12035 assign(srcval, load(Ity_I32, mkexpr(addr2)));
12036
12037 /* Call the helper */
12038 IRTemp retval = newTemp(Ity_I64);
florian11b8ee82012-08-06 13:35:33 +000012039 assign(retval, s390_call_cu41(unop(Iop_32Uto64, mkexpr(srcval))));
florianaf2194f2012-08-06 00:07:54 +000012040
12041 /* If the UTF-32 character was invalid, set cc=2 and we're done.
12042 cc=2 outranks cc=1 (1st operand exhausted) */
12043 IRExpr *invalid_character = binop(Iop_And64, mkexpr(retval), mkU64(0xff));
12044
12045 s390_cc_set(2);
12046 next_insn_if(binop(Iop_CmpEQ64, invalid_character, mkU64(1)));
12047
12048 /* Now test whether the 1st operand is exhausted */
12049 IRTemp num_bytes = newTemp(Ity_I64);
12050 assign(num_bytes, binop(Iop_And64,
12051 binop(Iop_Shr64, mkexpr(retval), mkU8(8)),
12052 mkU64(0xff)));
12053 s390_cc_set(1);
12054 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
12055
12056 /* Extract the bytes to be stored at addr1 */
12057 IRTemp data = newTemp(Ity_I64);
12058 assign(data, binop(Iop_Shr64, mkexpr(retval), mkU8(16)));
12059
12060 /* To store the bytes construct 4 dirty helper calls. The helper calls
12061 are guarded (num_bytes == 1, num_bytes == 2, etc) such that only
12062 one of them will be called at runtime. */
12063 int i;
12064 for (i = 1; i <= 4; ++i) {
12065 IRDirty *d;
12066
12067 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
12068 &s390x_dirtyhelper_CUxy,
12069 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
12070 mkexpr(num_bytes)));
12071 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
12072 d->mFx = Ifx_Write;
12073 d->mAddr = mkexpr(addr1);
12074 d->mSize = i;
12075 stmt(IRStmt_Dirty(d));
12076 }
12077
12078 /* Update source address and length */
12079 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkU64(4)));
12080 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkU64(4)));
12081
12082 /* Update destination address and length */
12083 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
12084 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
12085
12086 iterate();
12087
12088 return "cu41";
12089}
12090
12091static IRExpr *
florian3f8a96a2012-08-05 02:59:55 +000012092s390_call_cu12_cu14_helper1(IRExpr *byte1, IRExpr *etf3_and_m3_is_1)
florian6d9b9b22012-08-03 18:35:39 +000012093{
12094 IRExpr **args, *call;
12095 args = mkIRExprVec_2(byte1, etf3_and_m3_is_1);
florian3f8a96a2012-08-05 02:59:55 +000012096 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/, "s390_do_cu12_cu14_helper1",
12097 &s390_do_cu12_cu14_helper1, args);
florian6d9b9b22012-08-03 18:35:39 +000012098
12099 /* Nothing is excluded from definedness checking. */
12100 call->Iex.CCall.cee->mcx_mask = 0;
12101
12102 return call;
12103}
12104
12105static IRExpr *
12106s390_call_cu12_helper2(IRExpr *byte1, IRExpr *byte2, IRExpr *byte3,
12107 IRExpr *byte4, IRExpr *stuff)
12108{
12109 IRExpr **args, *call;
12110 args = mkIRExprVec_5(byte1, byte2, byte3, byte4, stuff);
12111 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
12112 "s390_do_cu12_helper2", &s390_do_cu12_helper2, args);
12113
12114 /* Nothing is excluded from definedness checking. */
12115 call->Iex.CCall.cee->mcx_mask = 0;
12116
12117 return call;
12118}
12119
florian3f8a96a2012-08-05 02:59:55 +000012120static IRExpr *
12121s390_call_cu14_helper2(IRExpr *byte1, IRExpr *byte2, IRExpr *byte3,
12122 IRExpr *byte4, IRExpr *stuff)
12123{
12124 IRExpr **args, *call;
12125 args = mkIRExprVec_5(byte1, byte2, byte3, byte4, stuff);
12126 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
12127 "s390_do_cu14_helper2", &s390_do_cu14_helper2, args);
12128
12129 /* Nothing is excluded from definedness checking. */
12130 call->Iex.CCall.cee->mcx_mask = 0;
12131
12132 return call;
12133}
12134
12135static void
12136s390_irgen_cu12_cu14(UChar m3, UChar r1, UChar r2, Bool is_cu12)
florian6d9b9b22012-08-03 18:35:39 +000012137{
12138 IRTemp addr1 = newTemp(Ity_I64);
12139 IRTemp addr2 = newTemp(Ity_I64);
12140 IRTemp len1 = newTemp(Ity_I64);
12141 IRTemp len2 = newTemp(Ity_I64);
12142
12143 assign(addr1, get_gpr_dw0(r1));
12144 assign(addr2, get_gpr_dw0(r2));
12145 assign(len1, get_gpr_dw0(r1 + 1));
12146 assign(len2, get_gpr_dw0(r2 + 1));
12147
12148 UInt extended_checking = s390_host_has_etf3 && (m3 & 0x1) == 1;
12149
12150 /* We're processing the 2nd operand 1 byte at a time. Therefore, if
12151 there is less than 1 byte left, then the 2nd operand is exhausted
12152 and we're done here. cc = 0 */
12153 s390_cc_set(0);
12154 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(1)));
12155
12156 /* There is at least one byte there. Read it. */
florian11b8ee82012-08-06 13:35:33 +000012157 IRTemp byte1 = newTemp(Ity_I64);
12158 assign(byte1, unop(Iop_8Uto64, load(Ity_I8, mkexpr(addr2))));
florian6d9b9b22012-08-03 18:35:39 +000012159
12160 /* Call the helper to get number of bytes and invalid byte indicator */
12161 IRTemp retval1 = newTemp(Ity_I64);
florian3f8a96a2012-08-05 02:59:55 +000012162 assign(retval1, s390_call_cu12_cu14_helper1(mkexpr(byte1),
florian11b8ee82012-08-06 13:35:33 +000012163 mkU64(extended_checking)));
florian6d9b9b22012-08-03 18:35:39 +000012164
12165 /* Check for invalid 1st byte */
12166 IRExpr *is_invalid = unop(Iop_64to1, mkexpr(retval1));
12167 s390_cc_set(2);
12168 next_insn_if(is_invalid);
12169
12170 /* How many bytes do we have to read? */
12171 IRTemp num_src_bytes = newTemp(Ity_I64);
12172 assign(num_src_bytes, binop(Iop_Shr64, mkexpr(retval1), mkU8(8)));
12173
12174 /* Now test whether the 2nd operand is exhausted */
12175 s390_cc_set(0);
12176 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkexpr(num_src_bytes)));
12177
12178 /* Read the remaining bytes */
12179 IRExpr *cond, *addr, *byte2, *byte3, *byte4;
12180
12181 cond = binop(Iop_CmpLE64U, mkU64(2), mkexpr(num_src_bytes));
12182 addr = binop(Iop_Add64, mkexpr(addr2), mkU64(1));
florian11b8ee82012-08-06 13:35:33 +000012183 byte2 = mkite(cond, unop(Iop_8Uto64, load(Ity_I8, addr)), mkU64(0));
florian6d9b9b22012-08-03 18:35:39 +000012184 cond = binop(Iop_CmpLE64U, mkU64(3), mkexpr(num_src_bytes));
12185 addr = binop(Iop_Add64, mkexpr(addr2), mkU64(2));
florian11b8ee82012-08-06 13:35:33 +000012186 byte3 = mkite(cond, unop(Iop_8Uto64, load(Ity_I8, addr)), mkU64(0));
florian6d9b9b22012-08-03 18:35:39 +000012187 cond = binop(Iop_CmpLE64U, mkU64(4), mkexpr(num_src_bytes));
12188 addr = binop(Iop_Add64, mkexpr(addr2), mkU64(3));
florian11b8ee82012-08-06 13:35:33 +000012189 byte4 = mkite(cond, unop(Iop_8Uto64, load(Ity_I8, addr)), mkU64(0));
florian6d9b9b22012-08-03 18:35:39 +000012190
12191 /* Call the helper to get the converted value and invalid byte indicator.
12192 We can pass at most 5 arguments; therefore some encoding is needed
12193 here */
12194 IRExpr *stuff = binop(Iop_Or64,
12195 binop(Iop_Shl64, mkexpr(num_src_bytes), mkU8(1)),
12196 mkU64(extended_checking));
12197 IRTemp retval2 = newTemp(Ity_I64);
florian3f8a96a2012-08-05 02:59:55 +000012198
12199 if (is_cu12) {
12200 assign(retval2, s390_call_cu12_helper2(mkexpr(byte1), byte2, byte3,
12201 byte4, stuff));
12202 } else {
12203 assign(retval2, s390_call_cu14_helper2(mkexpr(byte1), byte2, byte3,
12204 byte4, stuff));
12205 }
florian6d9b9b22012-08-03 18:35:39 +000012206
12207 /* Check for invalid character */
12208 s390_cc_set(2);
12209 is_invalid = unop(Iop_64to1, mkexpr(retval2));
12210 next_insn_if(is_invalid);
12211
12212 /* Now test whether the 1st operand is exhausted */
12213 IRTemp num_bytes = newTemp(Ity_I64);
12214 assign(num_bytes, binop(Iop_And64,
12215 binop(Iop_Shr64, mkexpr(retval2), mkU8(8)),
12216 mkU64(0xff)));
12217 s390_cc_set(1);
12218 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
12219
12220 /* Extract the bytes to be stored at addr1 */
12221 IRTemp data = newTemp(Ity_I64);
12222 assign(data, binop(Iop_Shr64, mkexpr(retval2), mkU8(16)));
12223
florian3f8a96a2012-08-05 02:59:55 +000012224 if (is_cu12) {
12225 /* To store the bytes construct 2 dirty helper calls. The helper calls
12226 are guarded (num_bytes == 2 and num_bytes == 4, respectively) such
12227 that only one of them will be called at runtime. */
florian6d9b9b22012-08-03 18:35:39 +000012228
florian3f8a96a2012-08-05 02:59:55 +000012229 Int i;
12230 for (i = 2; i <= 4; ++i) {
12231 IRDirty *d;
florian6d9b9b22012-08-03 18:35:39 +000012232
florian3f8a96a2012-08-05 02:59:55 +000012233 if (i == 3) continue; // skip this one
florian6d9b9b22012-08-03 18:35:39 +000012234
florian3f8a96a2012-08-05 02:59:55 +000012235 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
12236 &s390x_dirtyhelper_CUxy,
12237 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
12238 mkexpr(num_bytes)));
12239 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
12240 d->mFx = Ifx_Write;
12241 d->mAddr = mkexpr(addr1);
12242 d->mSize = i;
12243 stmt(IRStmt_Dirty(d));
12244 }
12245 } else {
12246 // cu14
12247 store(mkexpr(addr1), unop(Iop_64to32, mkexpr(data)));
florian6d9b9b22012-08-03 18:35:39 +000012248 }
12249
12250 /* Update source address and length */
12251 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkexpr(num_src_bytes)));
12252 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkexpr(num_src_bytes)));
12253
12254 /* Update destination address and length */
12255 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
12256 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
12257
12258 iterate();
florian3f8a96a2012-08-05 02:59:55 +000012259}
12260
12261static HChar *
12262s390_irgen_CU12(UChar m3, UChar r1, UChar r2)
12263{
12264 s390_irgen_cu12_cu14(m3, r1, r2, /* is_cu12 = */ 1);
florian6d9b9b22012-08-03 18:35:39 +000012265
12266 return "cu12";
12267}
12268
florian3f8a96a2012-08-05 02:59:55 +000012269static HChar *
12270s390_irgen_CU14(UChar m3, UChar r1, UChar r2)
12271{
12272 s390_irgen_cu12_cu14(m3, r1, r2, /* is_cu12 = */ 0);
12273
12274 return "cu14";
12275}
12276
florian8c88cb62012-08-26 18:58:13 +000012277static IRExpr *
12278s390_call_ecag(IRExpr *op2addr)
12279{
12280 IRExpr **args, *call;
12281
12282 args = mkIRExprVec_1(op2addr);
12283 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
12284 "s390_do_ecag", &s390_do_ecag, args);
12285
12286 /* Nothing is excluded from definedness checking. */
12287 call->Iex.CCall.cee->mcx_mask = 0;
12288
12289 return call;
12290}
12291
12292static HChar *
floriand2129202012-09-01 20:01:39 +000012293s390_irgen_ECAG(UChar r1, UChar r3 __attribute__((unused)), IRTemp op2addr)
florian8c88cb62012-08-26 18:58:13 +000012294{
12295 if (! s390_host_has_gie) {
floriane75dafa2012-09-01 17:54:09 +000012296 emulation_failure(EmFail_S390X_ecag);
florian8c88cb62012-08-26 18:58:13 +000012297 } else {
12298 put_gpr_dw0(r1, s390_call_ecag(mkexpr(op2addr)));
12299 }
12300
12301 return "ecag";
12302}
12303
12304
sewardj2019a972011-03-07 16:04:07 +000012305/*------------------------------------------------------------*/
12306/*--- Build IR for special instructions ---*/
12307/*------------------------------------------------------------*/
12308
florianb4df7682011-07-05 02:09:01 +000012309static void
sewardj2019a972011-03-07 16:04:07 +000012310s390_irgen_client_request(void)
12311{
12312 if (0)
12313 vex_printf("%%R3 = client_request ( %%R2 )\n");
12314
florianf9e1ed72012-04-17 02:41:56 +000012315 Addr64 next = guest_IA_curr_instr + S390_SPECIAL_OP_PREAMBLE_SIZE
12316 + S390_SPECIAL_OP_SIZE;
sewardj2019a972011-03-07 16:04:07 +000012317
florianf9e1ed72012-04-17 02:41:56 +000012318 dis_res->jk_StopHere = Ijk_ClientReq;
sewardj2019a972011-03-07 16:04:07 +000012319 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +000012320
12321 put_IA(mkaddr_expr(next));
sewardj2019a972011-03-07 16:04:07 +000012322}
12323
florianb4df7682011-07-05 02:09:01 +000012324static void
sewardj2019a972011-03-07 16:04:07 +000012325s390_irgen_guest_NRADDR(void)
12326{
12327 if (0)
12328 vex_printf("%%R3 = guest_NRADDR\n");
12329
floriane88b3c92011-07-05 02:48:39 +000012330 put_gpr_dw0(3, IRExpr_Get(S390X_GUEST_OFFSET(guest_NRADDR), Ity_I64));
sewardj2019a972011-03-07 16:04:07 +000012331}
12332
florianb4df7682011-07-05 02:09:01 +000012333static void
sewardj2019a972011-03-07 16:04:07 +000012334s390_irgen_call_noredir(void)
12335{
florianf9e1ed72012-04-17 02:41:56 +000012336 Addr64 next = guest_IA_curr_instr + S390_SPECIAL_OP_PREAMBLE_SIZE
12337 + S390_SPECIAL_OP_SIZE;
12338
sewardj2019a972011-03-07 16:04:07 +000012339 /* Continue after special op */
florianf9e1ed72012-04-17 02:41:56 +000012340 put_gpr_dw0(14, mkaddr_expr(next));
sewardj2019a972011-03-07 16:04:07 +000012341
12342 /* The address is in REG1, all parameters are in the right (guest) places */
florianf9e1ed72012-04-17 02:41:56 +000012343 put_IA(get_gpr_dw0(1));
sewardj2019a972011-03-07 16:04:07 +000012344
12345 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +000012346 dis_res->jk_StopHere = Ijk_NoRedir;
sewardj2019a972011-03-07 16:04:07 +000012347}
12348
12349/* Force proper alignment for the structures below. */
12350#pragma pack(1)
12351
12352
12353static s390_decode_t
12354s390_decode_2byte_and_irgen(UChar *bytes)
12355{
12356 typedef union {
12357 struct {
12358 unsigned int op : 16;
12359 } E;
12360 struct {
12361 unsigned int op : 8;
12362 unsigned int i : 8;
12363 } I;
12364 struct {
12365 unsigned int op : 8;
12366 unsigned int r1 : 4;
12367 unsigned int r2 : 4;
12368 } RR;
12369 } formats;
12370 union {
12371 formats fmt;
12372 UShort value;
12373 } ovl;
12374
12375 vassert(sizeof(formats) == 2);
12376
12377 ((char *)(&ovl.value))[0] = bytes[0];
12378 ((char *)(&ovl.value))[1] = bytes[1];
12379
12380 switch (ovl.value & 0xffff) {
12381 case 0x0101: /* PR */ goto unimplemented;
12382 case 0x0102: /* UPT */ goto unimplemented;
12383 case 0x0104: /* PTFF */ goto unimplemented;
12384 case 0x0107: /* SCKPF */ goto unimplemented;
12385 case 0x010a: /* PFPO */ goto unimplemented;
12386 case 0x010b: /* TAM */ goto unimplemented;
12387 case 0x010c: /* SAM24 */ goto unimplemented;
12388 case 0x010d: /* SAM31 */ goto unimplemented;
12389 case 0x010e: /* SAM64 */ goto unimplemented;
12390 case 0x01ff: /* TRAP2 */ goto unimplemented;
12391 }
12392
12393 switch ((ovl.value & 0xff00) >> 8) {
12394 case 0x04: /* SPM */ goto unimplemented;
12395 case 0x05: /* BALR */ goto unimplemented;
12396 case 0x06: s390_format_RR_RR(s390_irgen_BCTR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12397 goto ok;
12398 case 0x07: s390_format_RR(s390_irgen_BCR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12399 goto ok;
12400 case 0x0a: s390_format_I(s390_irgen_SVC, ovl.fmt.I.i); goto ok;
12401 case 0x0b: /* BSM */ goto unimplemented;
12402 case 0x0c: /* BASSM */ goto unimplemented;
12403 case 0x0d: s390_format_RR_RR(s390_irgen_BASR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12404 goto ok;
florianb0c9a132011-09-08 15:37:39 +000012405 case 0x0e: s390_format_RR(s390_irgen_MVCL, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12406 goto ok;
12407 case 0x0f: s390_format_RR(s390_irgen_CLCL, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12408 goto ok;
sewardj2019a972011-03-07 16:04:07 +000012409 case 0x10: s390_format_RR_RR(s390_irgen_LPR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12410 goto ok;
12411 case 0x11: s390_format_RR_RR(s390_irgen_LNR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12412 goto ok;
12413 case 0x12: s390_format_RR_RR(s390_irgen_LTR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12414 goto ok;
12415 case 0x13: s390_format_RR_RR(s390_irgen_LCR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12416 goto ok;
12417 case 0x14: s390_format_RR_RR(s390_irgen_NR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12418 goto ok;
12419 case 0x15: s390_format_RR_RR(s390_irgen_CLR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12420 goto ok;
12421 case 0x16: s390_format_RR_RR(s390_irgen_OR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12422 goto ok;
12423 case 0x17: s390_format_RR_RR(s390_irgen_XR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12424 goto ok;
12425 case 0x18: s390_format_RR_RR(s390_irgen_LR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12426 goto ok;
12427 case 0x19: s390_format_RR_RR(s390_irgen_CR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12428 goto ok;
12429 case 0x1a: s390_format_RR_RR(s390_irgen_AR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12430 goto ok;
12431 case 0x1b: s390_format_RR_RR(s390_irgen_SR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12432 goto ok;
12433 case 0x1c: s390_format_RR_RR(s390_irgen_MR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12434 goto ok;
12435 case 0x1d: s390_format_RR_RR(s390_irgen_DR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12436 goto ok;
12437 case 0x1e: s390_format_RR_RR(s390_irgen_ALR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12438 goto ok;
12439 case 0x1f: s390_format_RR_RR(s390_irgen_SLR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12440 goto ok;
12441 case 0x20: /* LPDR */ goto unimplemented;
12442 case 0x21: /* LNDR */ goto unimplemented;
12443 case 0x22: /* LTDR */ goto unimplemented;
12444 case 0x23: /* LCDR */ goto unimplemented;
12445 case 0x24: /* HDR */ goto unimplemented;
12446 case 0x25: /* LDXR */ goto unimplemented;
12447 case 0x26: /* MXR */ goto unimplemented;
12448 case 0x27: /* MXDR */ goto unimplemented;
12449 case 0x28: s390_format_RR_FF(s390_irgen_LDR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12450 goto ok;
12451 case 0x29: /* CDR */ goto unimplemented;
12452 case 0x2a: /* ADR */ goto unimplemented;
12453 case 0x2b: /* SDR */ goto unimplemented;
12454 case 0x2c: /* MDR */ goto unimplemented;
12455 case 0x2d: /* DDR */ goto unimplemented;
12456 case 0x2e: /* AWR */ goto unimplemented;
12457 case 0x2f: /* SWR */ goto unimplemented;
12458 case 0x30: /* LPER */ goto unimplemented;
12459 case 0x31: /* LNER */ goto unimplemented;
12460 case 0x32: /* LTER */ goto unimplemented;
12461 case 0x33: /* LCER */ goto unimplemented;
12462 case 0x34: /* HER */ goto unimplemented;
12463 case 0x35: /* LEDR */ goto unimplemented;
12464 case 0x36: /* AXR */ goto unimplemented;
12465 case 0x37: /* SXR */ goto unimplemented;
12466 case 0x38: s390_format_RR_FF(s390_irgen_LER, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12467 goto ok;
12468 case 0x39: /* CER */ goto unimplemented;
12469 case 0x3a: /* AER */ goto unimplemented;
12470 case 0x3b: /* SER */ goto unimplemented;
12471 case 0x3c: /* MDER */ goto unimplemented;
12472 case 0x3d: /* DER */ goto unimplemented;
12473 case 0x3e: /* AUR */ goto unimplemented;
12474 case 0x3f: /* SUR */ goto unimplemented;
12475 }
12476
12477 return S390_DECODE_UNKNOWN_INSN;
12478
12479ok:
12480 return S390_DECODE_OK;
12481
12482unimplemented:
12483 return S390_DECODE_UNIMPLEMENTED_INSN;
12484}
12485
12486static s390_decode_t
12487s390_decode_4byte_and_irgen(UChar *bytes)
12488{
12489 typedef union {
12490 struct {
12491 unsigned int op1 : 8;
12492 unsigned int r1 : 4;
12493 unsigned int op2 : 4;
12494 unsigned int i2 : 16;
12495 } RI;
12496 struct {
12497 unsigned int op : 16;
12498 unsigned int : 8;
12499 unsigned int r1 : 4;
12500 unsigned int r2 : 4;
12501 } RRE;
12502 struct {
12503 unsigned int op : 16;
12504 unsigned int r1 : 4;
12505 unsigned int : 4;
12506 unsigned int r3 : 4;
12507 unsigned int r2 : 4;
12508 } RRF;
12509 struct {
12510 unsigned int op : 16;
florian1c8f7ff2012-09-01 00:12:11 +000012511 unsigned int m3 : 4;
sewardj2019a972011-03-07 16:04:07 +000012512 unsigned int m4 : 4;
12513 unsigned int r1 : 4;
12514 unsigned int r2 : 4;
12515 } RRF2;
12516 struct {
12517 unsigned int op : 16;
12518 unsigned int r3 : 4;
12519 unsigned int : 4;
12520 unsigned int r1 : 4;
12521 unsigned int r2 : 4;
12522 } RRF3;
12523 struct {
12524 unsigned int op : 16;
12525 unsigned int r3 : 4;
12526 unsigned int : 4;
12527 unsigned int r1 : 4;
12528 unsigned int r2 : 4;
12529 } RRR;
12530 struct {
12531 unsigned int op : 16;
12532 unsigned int r3 : 4;
12533 unsigned int : 4;
12534 unsigned int r1 : 4;
12535 unsigned int r2 : 4;
12536 } RRF4;
12537 struct {
12538 unsigned int op : 8;
12539 unsigned int r1 : 4;
12540 unsigned int r3 : 4;
12541 unsigned int b2 : 4;
12542 unsigned int d2 : 12;
12543 } RS;
12544 struct {
12545 unsigned int op : 8;
12546 unsigned int r1 : 4;
12547 unsigned int r3 : 4;
12548 unsigned int i2 : 16;
12549 } RSI;
12550 struct {
12551 unsigned int op : 8;
12552 unsigned int r1 : 4;
12553 unsigned int x2 : 4;
12554 unsigned int b2 : 4;
12555 unsigned int d2 : 12;
12556 } RX;
12557 struct {
12558 unsigned int op : 16;
12559 unsigned int b2 : 4;
12560 unsigned int d2 : 12;
12561 } S;
12562 struct {
12563 unsigned int op : 8;
12564 unsigned int i2 : 8;
12565 unsigned int b1 : 4;
12566 unsigned int d1 : 12;
12567 } SI;
12568 } formats;
12569 union {
12570 formats fmt;
12571 UInt value;
12572 } ovl;
12573
12574 vassert(sizeof(formats) == 4);
12575
12576 ((char *)(&ovl.value))[0] = bytes[0];
12577 ((char *)(&ovl.value))[1] = bytes[1];
12578 ((char *)(&ovl.value))[2] = bytes[2];
12579 ((char *)(&ovl.value))[3] = bytes[3];
12580
12581 switch ((ovl.value & 0xff0f0000) >> 16) {
12582 case 0xa500: s390_format_RI_RU(s390_irgen_IIHH, ovl.fmt.RI.r1,
12583 ovl.fmt.RI.i2); goto ok;
12584 case 0xa501: s390_format_RI_RU(s390_irgen_IIHL, ovl.fmt.RI.r1,
12585 ovl.fmt.RI.i2); goto ok;
12586 case 0xa502: s390_format_RI_RU(s390_irgen_IILH, ovl.fmt.RI.r1,
12587 ovl.fmt.RI.i2); goto ok;
12588 case 0xa503: s390_format_RI_RU(s390_irgen_IILL, ovl.fmt.RI.r1,
12589 ovl.fmt.RI.i2); goto ok;
12590 case 0xa504: s390_format_RI_RU(s390_irgen_NIHH, ovl.fmt.RI.r1,
12591 ovl.fmt.RI.i2); goto ok;
12592 case 0xa505: s390_format_RI_RU(s390_irgen_NIHL, ovl.fmt.RI.r1,
12593 ovl.fmt.RI.i2); goto ok;
12594 case 0xa506: s390_format_RI_RU(s390_irgen_NILH, ovl.fmt.RI.r1,
12595 ovl.fmt.RI.i2); goto ok;
12596 case 0xa507: s390_format_RI_RU(s390_irgen_NILL, ovl.fmt.RI.r1,
12597 ovl.fmt.RI.i2); goto ok;
12598 case 0xa508: s390_format_RI_RU(s390_irgen_OIHH, ovl.fmt.RI.r1,
12599 ovl.fmt.RI.i2); goto ok;
12600 case 0xa509: s390_format_RI_RU(s390_irgen_OIHL, ovl.fmt.RI.r1,
12601 ovl.fmt.RI.i2); goto ok;
12602 case 0xa50a: s390_format_RI_RU(s390_irgen_OILH, ovl.fmt.RI.r1,
12603 ovl.fmt.RI.i2); goto ok;
12604 case 0xa50b: s390_format_RI_RU(s390_irgen_OILL, ovl.fmt.RI.r1,
12605 ovl.fmt.RI.i2); goto ok;
12606 case 0xa50c: s390_format_RI_RU(s390_irgen_LLIHH, ovl.fmt.RI.r1,
12607 ovl.fmt.RI.i2); goto ok;
12608 case 0xa50d: s390_format_RI_RU(s390_irgen_LLIHL, ovl.fmt.RI.r1,
12609 ovl.fmt.RI.i2); goto ok;
12610 case 0xa50e: s390_format_RI_RU(s390_irgen_LLILH, ovl.fmt.RI.r1,
12611 ovl.fmt.RI.i2); goto ok;
12612 case 0xa50f: s390_format_RI_RU(s390_irgen_LLILL, ovl.fmt.RI.r1,
12613 ovl.fmt.RI.i2); goto ok;
12614 case 0xa700: s390_format_RI_RU(s390_irgen_TMLH, ovl.fmt.RI.r1,
12615 ovl.fmt.RI.i2); goto ok;
12616 case 0xa701: s390_format_RI_RU(s390_irgen_TMLL, ovl.fmt.RI.r1,
12617 ovl.fmt.RI.i2); goto ok;
12618 case 0xa702: s390_format_RI_RU(s390_irgen_TMHH, ovl.fmt.RI.r1,
12619 ovl.fmt.RI.i2); goto ok;
12620 case 0xa703: s390_format_RI_RU(s390_irgen_TMHL, ovl.fmt.RI.r1,
12621 ovl.fmt.RI.i2); goto ok;
12622 case 0xa704: s390_format_RI(s390_irgen_BRC, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
12623 goto ok;
12624 case 0xa705: s390_format_RI_RP(s390_irgen_BRAS, ovl.fmt.RI.r1,
12625 ovl.fmt.RI.i2); goto ok;
12626 case 0xa706: s390_format_RI_RP(s390_irgen_BRCT, ovl.fmt.RI.r1,
12627 ovl.fmt.RI.i2); goto ok;
12628 case 0xa707: s390_format_RI_RP(s390_irgen_BRCTG, ovl.fmt.RI.r1,
12629 ovl.fmt.RI.i2); goto ok;
12630 case 0xa708: s390_format_RI_RI(s390_irgen_LHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
12631 goto ok;
12632 case 0xa709: s390_format_RI_RI(s390_irgen_LGHI, ovl.fmt.RI.r1,
12633 ovl.fmt.RI.i2); goto ok;
12634 case 0xa70a: s390_format_RI_RI(s390_irgen_AHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
12635 goto ok;
12636 case 0xa70b: s390_format_RI_RI(s390_irgen_AGHI, ovl.fmt.RI.r1,
12637 ovl.fmt.RI.i2); goto ok;
12638 case 0xa70c: s390_format_RI_RI(s390_irgen_MHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
12639 goto ok;
12640 case 0xa70d: s390_format_RI_RI(s390_irgen_MGHI, ovl.fmt.RI.r1,
12641 ovl.fmt.RI.i2); goto ok;
12642 case 0xa70e: s390_format_RI_RI(s390_irgen_CHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
12643 goto ok;
12644 case 0xa70f: s390_format_RI_RI(s390_irgen_CGHI, ovl.fmt.RI.r1,
12645 ovl.fmt.RI.i2); goto ok;
12646 }
12647
12648 switch ((ovl.value & 0xffff0000) >> 16) {
12649 case 0x8000: /* SSM */ goto unimplemented;
12650 case 0x8200: /* LPSW */ goto unimplemented;
florian7700fc92012-01-16 17:25:55 +000012651 case 0x9300: /* TS */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000012652 case 0xb202: /* STIDP */ goto unimplemented;
12653 case 0xb204: /* SCK */ goto unimplemented;
florian7700fc92012-01-16 17:25:55 +000012654 case 0xb205: s390_format_S_RD(s390_irgen_STCK, ovl.fmt.S.b2, ovl.fmt.S.d2);
12655 goto ok;
sewardj2019a972011-03-07 16:04:07 +000012656 case 0xb206: /* SCKC */ goto unimplemented;
12657 case 0xb207: /* STCKC */ goto unimplemented;
12658 case 0xb208: /* SPT */ goto unimplemented;
12659 case 0xb209: /* STPT */ goto unimplemented;
12660 case 0xb20a: /* SPKA */ goto unimplemented;
12661 case 0xb20b: /* IPK */ goto unimplemented;
12662 case 0xb20d: /* PTLB */ goto unimplemented;
12663 case 0xb210: /* SPX */ goto unimplemented;
12664 case 0xb211: /* STPX */ goto unimplemented;
12665 case 0xb212: /* STAP */ goto unimplemented;
12666 case 0xb214: /* SIE */ goto unimplemented;
12667 case 0xb218: /* PC */ goto unimplemented;
12668 case 0xb219: /* SAC */ goto unimplemented;
12669 case 0xb21a: /* CFC */ goto unimplemented;
12670 case 0xb221: /* IPTE */ goto unimplemented;
12671 case 0xb222: s390_format_RRE_R0(s390_irgen_IPM, ovl.fmt.RRE.r1); goto ok;
12672 case 0xb223: /* IVSK */ goto unimplemented;
12673 case 0xb224: /* IAC */ goto unimplemented;
12674 case 0xb225: /* SSAR */ goto unimplemented;
12675 case 0xb226: /* EPAR */ goto unimplemented;
12676 case 0xb227: /* ESAR */ goto unimplemented;
12677 case 0xb228: /* PT */ goto unimplemented;
12678 case 0xb229: /* ISKE */ goto unimplemented;
12679 case 0xb22a: /* RRBE */ goto unimplemented;
12680 case 0xb22b: /* SSKE */ goto unimplemented;
12681 case 0xb22c: /* TB */ goto unimplemented;
12682 case 0xb22d: /* DXR */ goto unimplemented;
12683 case 0xb22e: /* PGIN */ goto unimplemented;
12684 case 0xb22f: /* PGOUT */ goto unimplemented;
12685 case 0xb230: /* CSCH */ goto unimplemented;
12686 case 0xb231: /* HSCH */ goto unimplemented;
12687 case 0xb232: /* MSCH */ goto unimplemented;
12688 case 0xb233: /* SSCH */ goto unimplemented;
12689 case 0xb234: /* STSCH */ goto unimplemented;
12690 case 0xb235: /* TSCH */ goto unimplemented;
12691 case 0xb236: /* TPI */ goto unimplemented;
12692 case 0xb237: /* SAL */ goto unimplemented;
12693 case 0xb238: /* RSCH */ goto unimplemented;
12694 case 0xb239: /* STCRW */ goto unimplemented;
12695 case 0xb23a: /* STCPS */ goto unimplemented;
12696 case 0xb23b: /* RCHP */ goto unimplemented;
12697 case 0xb23c: /* SCHM */ goto unimplemented;
12698 case 0xb240: /* BAKR */ goto unimplemented;
floriana4384a32011-08-11 16:58:45 +000012699 case 0xb241: s390_format_RRE(s390_irgen_CKSM, ovl.fmt.RRE.r1,
12700 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000012701 case 0xb244: /* SQDR */ goto unimplemented;
12702 case 0xb245: /* SQER */ goto unimplemented;
12703 case 0xb246: /* STURA */ goto unimplemented;
12704 case 0xb247: /* MSTA */ goto unimplemented;
12705 case 0xb248: /* PALB */ goto unimplemented;
12706 case 0xb249: /* EREG */ goto unimplemented;
12707 case 0xb24a: /* ESTA */ goto unimplemented;
12708 case 0xb24b: /* LURA */ goto unimplemented;
12709 case 0xb24c: /* TAR */ goto unimplemented;
12710 case 0xb24d: s390_format_RRE(s390_irgen_CPYA, ovl.fmt.RRE.r1,
12711 ovl.fmt.RRE.r2); goto ok;
12712 case 0xb24e: s390_format_RRE(s390_irgen_SAR, ovl.fmt.RRE.r1, ovl.fmt.RRE.r2);
12713 goto ok;
12714 case 0xb24f: s390_format_RRE(s390_irgen_EAR, ovl.fmt.RRE.r1, ovl.fmt.RRE.r2);
12715 goto ok;
12716 case 0xb250: /* CSP */ goto unimplemented;
12717 case 0xb252: s390_format_RRE_RR(s390_irgen_MSR, ovl.fmt.RRE.r1,
12718 ovl.fmt.RRE.r2); goto ok;
12719 case 0xb254: /* MVPG */ goto unimplemented;
12720 case 0xb255: s390_format_RRE_RR(s390_irgen_MVST, ovl.fmt.RRE.r1,
12721 ovl.fmt.RRE.r2); goto ok;
12722 case 0xb257: /* CUSE */ goto unimplemented;
12723 case 0xb258: /* BSG */ goto unimplemented;
12724 case 0xb25a: /* BSA */ goto unimplemented;
12725 case 0xb25d: s390_format_RRE_RR(s390_irgen_CLST, ovl.fmt.RRE.r1,
12726 ovl.fmt.RRE.r2); goto ok;
12727 case 0xb25e: s390_format_RRE_RR(s390_irgen_SRST, ovl.fmt.RRE.r1,
12728 ovl.fmt.RRE.r2); goto ok;
12729 case 0xb263: /* CMPSC */ goto unimplemented;
12730 case 0xb274: /* SIGA */ goto unimplemented;
12731 case 0xb276: /* XSCH */ goto unimplemented;
12732 case 0xb277: /* RP */ goto unimplemented;
sewardj1e5fea62011-05-17 16:18:36 +000012733 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 +000012734 case 0xb279: /* SACF */ goto unimplemented;
sewardj1e5fea62011-05-17 16:18:36 +000012735 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 +000012736 case 0xb27d: /* STSI */ goto unimplemented;
12737 case 0xb299: s390_format_S_RD(s390_irgen_SRNM, ovl.fmt.S.b2, ovl.fmt.S.d2);
12738 goto ok;
12739 case 0xb29c: s390_format_S_RD(s390_irgen_STFPC, ovl.fmt.S.b2, ovl.fmt.S.d2);
12740 goto ok;
12741 case 0xb29d: s390_format_S_RD(s390_irgen_LFPC, ovl.fmt.S.b2, ovl.fmt.S.d2);
12742 goto ok;
florian730448f2012-02-04 17:07:07 +000012743 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 +000012744 case 0xb2a6: s390_format_RRF_M0RERE(s390_irgen_CU21, ovl.fmt.RRF3.r3,
12745 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
12746 goto ok;
florian6d9b9b22012-08-03 18:35:39 +000012747 case 0xb2a7: s390_format_RRF_M0RERE(s390_irgen_CU12, ovl.fmt.RRF3.r3,
12748 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
12749 goto ok;
florian933065d2011-07-11 01:48:02 +000012750 case 0xb2b0: s390_format_S_RD(s390_irgen_STFLE, ovl.fmt.S.b2, ovl.fmt.S.d2);
12751 goto ok;
sewardj2019a972011-03-07 16:04:07 +000012752 case 0xb2b1: /* STFL */ goto unimplemented;
12753 case 0xb2b2: /* LPSWE */ goto unimplemented;
florianf0fa1be2012-09-18 20:24:38 +000012754 case 0xb2b8: s390_irgen_srnmb_wrapper(ovl.fmt.S.b2, ovl.fmt.S.d2);
12755 goto ok;
sewardj2019a972011-03-07 16:04:07 +000012756 case 0xb2b9: /* SRNMT */ goto unimplemented;
12757 case 0xb2bd: /* LFAS */ goto unimplemented;
12758 case 0xb2ff: /* TRAP4 */ goto unimplemented;
12759 case 0xb300: s390_format_RRE_FF(s390_irgen_LPEBR, ovl.fmt.RRE.r1,
12760 ovl.fmt.RRE.r2); goto ok;
12761 case 0xb301: s390_format_RRE_FF(s390_irgen_LNEBR, ovl.fmt.RRE.r1,
12762 ovl.fmt.RRE.r2); goto ok;
12763 case 0xb302: s390_format_RRE_FF(s390_irgen_LTEBR, ovl.fmt.RRE.r1,
12764 ovl.fmt.RRE.r2); goto ok;
12765 case 0xb303: s390_format_RRE_FF(s390_irgen_LCEBR, ovl.fmt.RRE.r1,
12766 ovl.fmt.RRE.r2); goto ok;
12767 case 0xb304: s390_format_RRE_FF(s390_irgen_LDEBR, ovl.fmt.RRE.r1,
12768 ovl.fmt.RRE.r2); goto ok;
12769 case 0xb305: s390_format_RRE_FF(s390_irgen_LXDBR, ovl.fmt.RRE.r1,
12770 ovl.fmt.RRE.r2); goto ok;
12771 case 0xb306: s390_format_RRE_FF(s390_irgen_LXEBR, ovl.fmt.RRE.r1,
12772 ovl.fmt.RRE.r2); goto ok;
12773 case 0xb307: /* MXDBR */ goto unimplemented;
12774 case 0xb308: /* KEBR */ goto unimplemented;
12775 case 0xb309: s390_format_RRE_FF(s390_irgen_CEBR, ovl.fmt.RRE.r1,
12776 ovl.fmt.RRE.r2); goto ok;
12777 case 0xb30a: s390_format_RRE_FF(s390_irgen_AEBR, ovl.fmt.RRE.r1,
12778 ovl.fmt.RRE.r2); goto ok;
12779 case 0xb30b: s390_format_RRE_FF(s390_irgen_SEBR, ovl.fmt.RRE.r1,
12780 ovl.fmt.RRE.r2); goto ok;
12781 case 0xb30c: /* MDEBR */ goto unimplemented;
12782 case 0xb30d: s390_format_RRE_FF(s390_irgen_DEBR, ovl.fmt.RRE.r1,
12783 ovl.fmt.RRE.r2); goto ok;
12784 case 0xb30e: s390_format_RRF_F0FF(s390_irgen_MAEBR, ovl.fmt.RRF.r1,
12785 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
12786 case 0xb30f: s390_format_RRF_F0FF(s390_irgen_MSEBR, ovl.fmt.RRF.r1,
12787 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
12788 case 0xb310: s390_format_RRE_FF(s390_irgen_LPDBR, ovl.fmt.RRE.r1,
12789 ovl.fmt.RRE.r2); goto ok;
12790 case 0xb311: s390_format_RRE_FF(s390_irgen_LNDBR, ovl.fmt.RRE.r1,
12791 ovl.fmt.RRE.r2); goto ok;
12792 case 0xb312: s390_format_RRE_FF(s390_irgen_LTDBR, ovl.fmt.RRE.r1,
12793 ovl.fmt.RRE.r2); goto ok;
12794 case 0xb313: s390_format_RRE_FF(s390_irgen_LCDBR, ovl.fmt.RRE.r1,
12795 ovl.fmt.RRE.r2); goto ok;
12796 case 0xb314: s390_format_RRE_FF(s390_irgen_SQEBR, ovl.fmt.RRE.r1,
12797 ovl.fmt.RRE.r2); goto ok;
12798 case 0xb315: s390_format_RRE_FF(s390_irgen_SQDBR, ovl.fmt.RRE.r1,
12799 ovl.fmt.RRE.r2); goto ok;
12800 case 0xb316: s390_format_RRE_FF(s390_irgen_SQXBR, ovl.fmt.RRE.r1,
12801 ovl.fmt.RRE.r2); goto ok;
12802 case 0xb317: s390_format_RRE_FF(s390_irgen_MEEBR, ovl.fmt.RRE.r1,
12803 ovl.fmt.RRE.r2); goto ok;
12804 case 0xb318: /* KDBR */ goto unimplemented;
12805 case 0xb319: s390_format_RRE_FF(s390_irgen_CDBR, ovl.fmt.RRE.r1,
12806 ovl.fmt.RRE.r2); goto ok;
12807 case 0xb31a: s390_format_RRE_FF(s390_irgen_ADBR, ovl.fmt.RRE.r1,
12808 ovl.fmt.RRE.r2); goto ok;
12809 case 0xb31b: s390_format_RRE_FF(s390_irgen_SDBR, ovl.fmt.RRE.r1,
12810 ovl.fmt.RRE.r2); goto ok;
12811 case 0xb31c: s390_format_RRE_FF(s390_irgen_MDBR, ovl.fmt.RRE.r1,
12812 ovl.fmt.RRE.r2); goto ok;
12813 case 0xb31d: s390_format_RRE_FF(s390_irgen_DDBR, ovl.fmt.RRE.r1,
12814 ovl.fmt.RRE.r2); goto ok;
12815 case 0xb31e: s390_format_RRF_F0FF(s390_irgen_MADBR, ovl.fmt.RRF.r1,
12816 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
12817 case 0xb31f: s390_format_RRF_F0FF(s390_irgen_MSDBR, ovl.fmt.RRF.r1,
12818 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
12819 case 0xb324: /* LDER */ goto unimplemented;
12820 case 0xb325: /* LXDR */ goto unimplemented;
12821 case 0xb326: /* LXER */ goto unimplemented;
12822 case 0xb32e: /* MAER */ goto unimplemented;
12823 case 0xb32f: /* MSER */ goto unimplemented;
12824 case 0xb336: /* SQXR */ goto unimplemented;
12825 case 0xb337: /* MEER */ goto unimplemented;
12826 case 0xb338: /* MAYLR */ goto unimplemented;
12827 case 0xb339: /* MYLR */ goto unimplemented;
12828 case 0xb33a: /* MAYR */ goto unimplemented;
12829 case 0xb33b: /* MYR */ goto unimplemented;
12830 case 0xb33c: /* MAYHR */ goto unimplemented;
12831 case 0xb33d: /* MYHR */ goto unimplemented;
12832 case 0xb33e: /* MADR */ goto unimplemented;
12833 case 0xb33f: /* MSDR */ goto unimplemented;
12834 case 0xb340: s390_format_RRE_FF(s390_irgen_LPXBR, ovl.fmt.RRE.r1,
12835 ovl.fmt.RRE.r2); goto ok;
12836 case 0xb341: s390_format_RRE_FF(s390_irgen_LNXBR, ovl.fmt.RRE.r1,
12837 ovl.fmt.RRE.r2); goto ok;
12838 case 0xb342: s390_format_RRE_FF(s390_irgen_LTXBR, ovl.fmt.RRE.r1,
12839 ovl.fmt.RRE.r2); goto ok;
12840 case 0xb343: s390_format_RRE_FF(s390_irgen_LCXBR, ovl.fmt.RRE.r1,
12841 ovl.fmt.RRE.r2); goto ok;
florian4b8efad2012-09-02 18:07:08 +000012842 case 0xb344: s390_format_RRF_UUFF(s390_irgen_LEDBR, ovl.fmt.RRF2.m3,
12843 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12844 ovl.fmt.RRF2.r2); goto ok;
12845 case 0xb345: s390_format_RRF_UUFF(s390_irgen_LDXBR, ovl.fmt.RRF2.m3,
12846 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12847 ovl.fmt.RRF2.r2); goto ok;
12848 case 0xb346: s390_format_RRF_UUFF(s390_irgen_LEXBR, ovl.fmt.RRF2.m3,
12849 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12850 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000012851 case 0xb347: /* FIXBR */ goto unimplemented;
12852 case 0xb348: /* KXBR */ goto unimplemented;
12853 case 0xb349: s390_format_RRE_FF(s390_irgen_CXBR, ovl.fmt.RRE.r1,
12854 ovl.fmt.RRE.r2); goto ok;
12855 case 0xb34a: s390_format_RRE_FF(s390_irgen_AXBR, ovl.fmt.RRE.r1,
12856 ovl.fmt.RRE.r2); goto ok;
12857 case 0xb34b: s390_format_RRE_FF(s390_irgen_SXBR, ovl.fmt.RRE.r1,
12858 ovl.fmt.RRE.r2); goto ok;
12859 case 0xb34c: s390_format_RRE_FF(s390_irgen_MXBR, ovl.fmt.RRE.r1,
12860 ovl.fmt.RRE.r2); goto ok;
12861 case 0xb34d: s390_format_RRE_FF(s390_irgen_DXBR, ovl.fmt.RRE.r1,
12862 ovl.fmt.RRE.r2); goto ok;
12863 case 0xb350: /* TBEDR */ goto unimplemented;
12864 case 0xb351: /* TBDR */ goto unimplemented;
12865 case 0xb353: /* DIEBR */ goto unimplemented;
12866 case 0xb357: /* FIEBR */ goto unimplemented;
12867 case 0xb358: /* THDER */ goto unimplemented;
12868 case 0xb359: /* THDR */ goto unimplemented;
12869 case 0xb35b: /* DIDBR */ goto unimplemented;
12870 case 0xb35f: /* FIDBR */ goto unimplemented;
12871 case 0xb360: /* LPXR */ goto unimplemented;
12872 case 0xb361: /* LNXR */ goto unimplemented;
12873 case 0xb362: /* LTXR */ goto unimplemented;
12874 case 0xb363: /* LCXR */ goto unimplemented;
12875 case 0xb365: s390_format_RRE_FF(s390_irgen_LXR, ovl.fmt.RRE.r1,
12876 ovl.fmt.RRE.r2); goto ok;
12877 case 0xb366: /* LEXR */ goto unimplemented;
12878 case 0xb367: /* FIXR */ goto unimplemented;
12879 case 0xb369: /* CXR */ goto unimplemented;
12880 case 0xb370: s390_format_RRE_FF(s390_irgen_LPDFR, ovl.fmt.RRE.r1,
12881 ovl.fmt.RRE.r2); goto ok;
12882 case 0xb371: s390_format_RRE_FF(s390_irgen_LNDFR, ovl.fmt.RRE.r1,
12883 ovl.fmt.RRE.r2); goto ok;
12884 case 0xb372: s390_format_RRF_F0FF2(s390_irgen_CPSDR, ovl.fmt.RRF3.r3,
12885 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
12886 goto ok;
12887 case 0xb373: s390_format_RRE_FF(s390_irgen_LCDFR, ovl.fmt.RRE.r1,
12888 ovl.fmt.RRE.r2); goto ok;
12889 case 0xb374: s390_format_RRE_F0(s390_irgen_LZER, ovl.fmt.RRE.r1); goto ok;
12890 case 0xb375: s390_format_RRE_F0(s390_irgen_LZDR, ovl.fmt.RRE.r1); goto ok;
12891 case 0xb376: s390_format_RRE_F0(s390_irgen_LZXR, ovl.fmt.RRE.r1); goto ok;
12892 case 0xb377: /* FIER */ goto unimplemented;
12893 case 0xb37f: /* FIDR */ goto unimplemented;
12894 case 0xb384: s390_format_RRE_R0(s390_irgen_SFPC, ovl.fmt.RRE.r1); goto ok;
12895 case 0xb385: /* SFASR */ goto unimplemented;
12896 case 0xb38c: s390_format_RRE_R0(s390_irgen_EFPC, ovl.fmt.RRE.r1); goto ok;
florian1c8f7ff2012-09-01 00:12:11 +000012897 case 0xb390: s390_format_RRF_UUFR(s390_irgen_CELFBR, ovl.fmt.RRF2.m3,
12898 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12899 ovl.fmt.RRF2.r2); goto ok;
12900 case 0xb391: s390_format_RRF_UUFR(s390_irgen_CDLFBR, ovl.fmt.RRF2.m3,
12901 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12902 ovl.fmt.RRF2.r2); goto ok;
12903 case 0xb392: s390_format_RRF_UUFR(s390_irgen_CXLFBR, ovl.fmt.RRF2.m3,
12904 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12905 ovl.fmt.RRF2.r2); goto ok;
florian4b8efad2012-09-02 18:07:08 +000012906 case 0xb394: s390_format_RRF_UUFR(s390_irgen_CEFBR, ovl.fmt.RRF2.m3,
12907 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12908 ovl.fmt.RRF2.r2); goto ok;
12909 case 0xb395: s390_format_RRF_UUFR(s390_irgen_CDFBR, ovl.fmt.RRF2.m3,
12910 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12911 ovl.fmt.RRF2.r2); goto ok;
12912 case 0xb396: s390_format_RRF_UUFR(s390_irgen_CXFBR, ovl.fmt.RRF2.m3,
12913 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12914 ovl.fmt.RRF2.r2); goto ok;
12915 case 0xb398: s390_format_RRF_UURF(s390_irgen_CFEBR, ovl.fmt.RRF2.m3,
12916 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12917 ovl.fmt.RRF2.r2); goto ok;
12918 case 0xb399: s390_format_RRF_UURF(s390_irgen_CFDBR, ovl.fmt.RRF2.m3,
12919 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12920 ovl.fmt.RRF2.r2); goto ok;
12921 case 0xb39a: s390_format_RRF_UURF(s390_irgen_CFXBR, ovl.fmt.RRF2.m3,
12922 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12923 ovl.fmt.RRF2.r2); goto ok;
florian1c8f7ff2012-09-01 00:12:11 +000012924 case 0xb39c: s390_format_RRF_UURF(s390_irgen_CLFEBR, ovl.fmt.RRF2.m3,
12925 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12926 ovl.fmt.RRF2.r2); goto ok;
12927 case 0xb39d: s390_format_RRF_UURF(s390_irgen_CLFDBR, ovl.fmt.RRF2.m3,
12928 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12929 ovl.fmt.RRF2.r2); goto ok;
12930 case 0xb39e: s390_format_RRF_UURF(s390_irgen_CLFXBR, ovl.fmt.RRF2.m3,
12931 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12932 ovl.fmt.RRF2.r2); goto ok;
12933 case 0xb3a0: s390_format_RRF_UUFR(s390_irgen_CELGBR, ovl.fmt.RRF2.m3,
12934 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12935 ovl.fmt.RRF2.r2); goto ok;
12936 case 0xb3a1: s390_format_RRF_UUFR(s390_irgen_CDLGBR, ovl.fmt.RRF2.m3,
12937 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12938 ovl.fmt.RRF2.r2); goto ok;
12939 case 0xb3a2: s390_format_RRF_UUFR(s390_irgen_CXLGBR, ovl.fmt.RRF2.m3,
12940 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12941 ovl.fmt.RRF2.r2); goto ok;
florian4b8efad2012-09-02 18:07:08 +000012942 case 0xb3a4: s390_format_RRF_UUFR(s390_irgen_CEGBR, ovl.fmt.RRF2.m3,
12943 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12944 ovl.fmt.RRF2.r2); goto ok;
12945 case 0xb3a5: s390_format_RRF_UUFR(s390_irgen_CDGBR, ovl.fmt.RRF2.m3,
12946 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12947 ovl.fmt.RRF2.r2); goto ok;
12948 case 0xb3a6: s390_format_RRF_UUFR(s390_irgen_CXGBR, ovl.fmt.RRF2.m3,
12949 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12950 ovl.fmt.RRF2.r2); goto ok;
12951 case 0xb3a8: s390_format_RRF_UURF(s390_irgen_CGEBR, ovl.fmt.RRF2.m3,
12952 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12953 ovl.fmt.RRF2.r2); goto ok;
12954 case 0xb3a9: s390_format_RRF_UURF(s390_irgen_CGDBR, ovl.fmt.RRF2.m3,
12955 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12956 ovl.fmt.RRF2.r2); goto ok;
12957 case 0xb3aa: s390_format_RRF_UURF(s390_irgen_CGXBR, ovl.fmt.RRF2.m3,
12958 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12959 ovl.fmt.RRF2.r2); goto ok;
florian1c8f7ff2012-09-01 00:12:11 +000012960 case 0xb3ac: s390_format_RRF_UURF(s390_irgen_CLGEBR, ovl.fmt.RRF2.m3,
12961 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12962 ovl.fmt.RRF2.r2); goto ok;
12963 case 0xb3ad: s390_format_RRF_UURF(s390_irgen_CLGDBR, ovl.fmt.RRF2.m3,
12964 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12965 ovl.fmt.RRF2.r2); goto ok;
12966 case 0xb3ae: s390_format_RRF_UURF(s390_irgen_CLGXBR, ovl.fmt.RRF2.m3,
12967 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
12968 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000012969 case 0xb3b4: /* CEFR */ goto unimplemented;
12970 case 0xb3b5: /* CDFR */ goto unimplemented;
12971 case 0xb3b6: /* CXFR */ goto unimplemented;
12972 case 0xb3b8: /* CFER */ goto unimplemented;
12973 case 0xb3b9: /* CFDR */ goto unimplemented;
12974 case 0xb3ba: /* CFXR */ goto unimplemented;
12975 case 0xb3c1: s390_format_RRE_FR(s390_irgen_LDGR, ovl.fmt.RRE.r1,
12976 ovl.fmt.RRE.r2); goto ok;
12977 case 0xb3c4: /* CEGR */ goto unimplemented;
12978 case 0xb3c5: /* CDGR */ goto unimplemented;
12979 case 0xb3c6: /* CXGR */ goto unimplemented;
12980 case 0xb3c8: /* CGER */ goto unimplemented;
12981 case 0xb3c9: /* CGDR */ goto unimplemented;
12982 case 0xb3ca: /* CGXR */ goto unimplemented;
12983 case 0xb3cd: s390_format_RRE_RF(s390_irgen_LGDR, ovl.fmt.RRE.r1,
12984 ovl.fmt.RRE.r2); goto ok;
12985 case 0xb3d0: /* MDTR */ goto unimplemented;
12986 case 0xb3d1: /* DDTR */ goto unimplemented;
12987 case 0xb3d2: /* ADTR */ goto unimplemented;
12988 case 0xb3d3: /* SDTR */ goto unimplemented;
12989 case 0xb3d4: /* LDETR */ goto unimplemented;
12990 case 0xb3d5: /* LEDTR */ goto unimplemented;
12991 case 0xb3d6: /* LTDTR */ goto unimplemented;
12992 case 0xb3d7: /* FIDTR */ goto unimplemented;
12993 case 0xb3d8: /* MXTR */ goto unimplemented;
12994 case 0xb3d9: /* DXTR */ goto unimplemented;
12995 case 0xb3da: /* AXTR */ goto unimplemented;
12996 case 0xb3db: /* SXTR */ goto unimplemented;
12997 case 0xb3dc: /* LXDTR */ goto unimplemented;
12998 case 0xb3dd: /* LDXTR */ goto unimplemented;
12999 case 0xb3de: /* LTXTR */ goto unimplemented;
13000 case 0xb3df: /* FIXTR */ goto unimplemented;
13001 case 0xb3e0: /* KDTR */ goto unimplemented;
13002 case 0xb3e1: /* CGDTR */ goto unimplemented;
13003 case 0xb3e2: /* CUDTR */ goto unimplemented;
13004 case 0xb3e3: /* CSDTR */ goto unimplemented;
13005 case 0xb3e4: /* CDTR */ goto unimplemented;
13006 case 0xb3e5: /* EEDTR */ goto unimplemented;
13007 case 0xb3e7: /* ESDTR */ goto unimplemented;
13008 case 0xb3e8: /* KXTR */ goto unimplemented;
13009 case 0xb3e9: /* CGXTR */ goto unimplemented;
13010 case 0xb3ea: /* CUXTR */ goto unimplemented;
13011 case 0xb3eb: /* CSXTR */ goto unimplemented;
13012 case 0xb3ec: /* CXTR */ goto unimplemented;
13013 case 0xb3ed: /* EEXTR */ goto unimplemented;
13014 case 0xb3ef: /* ESXTR */ goto unimplemented;
13015 case 0xb3f1: /* CDGTR */ goto unimplemented;
13016 case 0xb3f2: /* CDUTR */ goto unimplemented;
13017 case 0xb3f3: /* CDSTR */ goto unimplemented;
13018 case 0xb3f4: /* CEDTR */ goto unimplemented;
13019 case 0xb3f5: /* QADTR */ goto unimplemented;
13020 case 0xb3f6: /* IEDTR */ goto unimplemented;
13021 case 0xb3f7: /* RRDTR */ goto unimplemented;
13022 case 0xb3f9: /* CXGTR */ goto unimplemented;
13023 case 0xb3fa: /* CXUTR */ goto unimplemented;
13024 case 0xb3fb: /* CXSTR */ goto unimplemented;
13025 case 0xb3fc: /* CEXTR */ goto unimplemented;
13026 case 0xb3fd: /* QAXTR */ goto unimplemented;
13027 case 0xb3fe: /* IEXTR */ goto unimplemented;
13028 case 0xb3ff: /* RRXTR */ goto unimplemented;
13029 case 0xb900: s390_format_RRE_RR(s390_irgen_LPGR, ovl.fmt.RRE.r1,
13030 ovl.fmt.RRE.r2); goto ok;
13031 case 0xb901: s390_format_RRE_RR(s390_irgen_LNGR, ovl.fmt.RRE.r1,
13032 ovl.fmt.RRE.r2); goto ok;
13033 case 0xb902: s390_format_RRE_RR(s390_irgen_LTGR, ovl.fmt.RRE.r1,
13034 ovl.fmt.RRE.r2); goto ok;
13035 case 0xb903: s390_format_RRE_RR(s390_irgen_LCGR, ovl.fmt.RRE.r1,
13036 ovl.fmt.RRE.r2); goto ok;
13037 case 0xb904: s390_format_RRE_RR(s390_irgen_LGR, ovl.fmt.RRE.r1,
13038 ovl.fmt.RRE.r2); goto ok;
13039 case 0xb905: /* LURAG */ goto unimplemented;
13040 case 0xb906: s390_format_RRE_RR(s390_irgen_LGBR, ovl.fmt.RRE.r1,
13041 ovl.fmt.RRE.r2); goto ok;
13042 case 0xb907: s390_format_RRE_RR(s390_irgen_LGHR, ovl.fmt.RRE.r1,
13043 ovl.fmt.RRE.r2); goto ok;
13044 case 0xb908: s390_format_RRE_RR(s390_irgen_AGR, ovl.fmt.RRE.r1,
13045 ovl.fmt.RRE.r2); goto ok;
13046 case 0xb909: s390_format_RRE_RR(s390_irgen_SGR, ovl.fmt.RRE.r1,
13047 ovl.fmt.RRE.r2); goto ok;
13048 case 0xb90a: s390_format_RRE_RR(s390_irgen_ALGR, ovl.fmt.RRE.r1,
13049 ovl.fmt.RRE.r2); goto ok;
13050 case 0xb90b: s390_format_RRE_RR(s390_irgen_SLGR, ovl.fmt.RRE.r1,
13051 ovl.fmt.RRE.r2); goto ok;
13052 case 0xb90c: s390_format_RRE_RR(s390_irgen_MSGR, ovl.fmt.RRE.r1,
13053 ovl.fmt.RRE.r2); goto ok;
13054 case 0xb90d: s390_format_RRE_RR(s390_irgen_DSGR, ovl.fmt.RRE.r1,
13055 ovl.fmt.RRE.r2); goto ok;
13056 case 0xb90e: /* EREGG */ goto unimplemented;
13057 case 0xb90f: s390_format_RRE_RR(s390_irgen_LRVGR, ovl.fmt.RRE.r1,
13058 ovl.fmt.RRE.r2); goto ok;
13059 case 0xb910: s390_format_RRE_RR(s390_irgen_LPGFR, ovl.fmt.RRE.r1,
13060 ovl.fmt.RRE.r2); goto ok;
13061 case 0xb911: s390_format_RRE_RR(s390_irgen_LNGFR, ovl.fmt.RRE.r1,
13062 ovl.fmt.RRE.r2); goto ok;
13063 case 0xb912: s390_format_RRE_RR(s390_irgen_LTGFR, ovl.fmt.RRE.r1,
13064 ovl.fmt.RRE.r2); goto ok;
13065 case 0xb913: s390_format_RRE_RR(s390_irgen_LCGFR, ovl.fmt.RRE.r1,
13066 ovl.fmt.RRE.r2); goto ok;
13067 case 0xb914: s390_format_RRE_RR(s390_irgen_LGFR, ovl.fmt.RRE.r1,
13068 ovl.fmt.RRE.r2); goto ok;
13069 case 0xb916: s390_format_RRE_RR(s390_irgen_LLGFR, ovl.fmt.RRE.r1,
13070 ovl.fmt.RRE.r2); goto ok;
13071 case 0xb917: s390_format_RRE_RR(s390_irgen_LLGTR, ovl.fmt.RRE.r1,
13072 ovl.fmt.RRE.r2); goto ok;
13073 case 0xb918: s390_format_RRE_RR(s390_irgen_AGFR, ovl.fmt.RRE.r1,
13074 ovl.fmt.RRE.r2); goto ok;
13075 case 0xb919: s390_format_RRE_RR(s390_irgen_SGFR, ovl.fmt.RRE.r1,
13076 ovl.fmt.RRE.r2); goto ok;
13077 case 0xb91a: s390_format_RRE_RR(s390_irgen_ALGFR, ovl.fmt.RRE.r1,
13078 ovl.fmt.RRE.r2); goto ok;
13079 case 0xb91b: s390_format_RRE_RR(s390_irgen_SLGFR, ovl.fmt.RRE.r1,
13080 ovl.fmt.RRE.r2); goto ok;
13081 case 0xb91c: s390_format_RRE_RR(s390_irgen_MSGFR, ovl.fmt.RRE.r1,
13082 ovl.fmt.RRE.r2); goto ok;
13083 case 0xb91d: s390_format_RRE_RR(s390_irgen_DSGFR, ovl.fmt.RRE.r1,
13084 ovl.fmt.RRE.r2); goto ok;
13085 case 0xb91e: /* KMAC */ goto unimplemented;
13086 case 0xb91f: s390_format_RRE_RR(s390_irgen_LRVR, ovl.fmt.RRE.r1,
13087 ovl.fmt.RRE.r2); goto ok;
13088 case 0xb920: s390_format_RRE_RR(s390_irgen_CGR, ovl.fmt.RRE.r1,
13089 ovl.fmt.RRE.r2); goto ok;
13090 case 0xb921: s390_format_RRE_RR(s390_irgen_CLGR, ovl.fmt.RRE.r1,
13091 ovl.fmt.RRE.r2); goto ok;
13092 case 0xb925: /* STURG */ goto unimplemented;
13093 case 0xb926: s390_format_RRE_RR(s390_irgen_LBR, ovl.fmt.RRE.r1,
13094 ovl.fmt.RRE.r2); goto ok;
13095 case 0xb927: s390_format_RRE_RR(s390_irgen_LHR, ovl.fmt.RRE.r1,
13096 ovl.fmt.RRE.r2); goto ok;
13097 case 0xb928: /* PCKMO */ goto unimplemented;
13098 case 0xb92b: /* KMO */ goto unimplemented;
13099 case 0xb92c: /* PCC */ goto unimplemented;
13100 case 0xb92d: /* KMCTR */ goto unimplemented;
13101 case 0xb92e: /* KM */ goto unimplemented;
13102 case 0xb92f: /* KMC */ goto unimplemented;
13103 case 0xb930: s390_format_RRE_RR(s390_irgen_CGFR, ovl.fmt.RRE.r1,
13104 ovl.fmt.RRE.r2); goto ok;
13105 case 0xb931: s390_format_RRE_RR(s390_irgen_CLGFR, ovl.fmt.RRE.r1,
13106 ovl.fmt.RRE.r2); goto ok;
13107 case 0xb93e: /* KIMD */ goto unimplemented;
13108 case 0xb93f: /* KLMD */ goto unimplemented;
13109 case 0xb941: /* CFDTR */ goto unimplemented;
13110 case 0xb942: /* CLGDTR */ goto unimplemented;
13111 case 0xb943: /* CLFDTR */ goto unimplemented;
13112 case 0xb946: s390_format_RRE_RR(s390_irgen_BCTGR, ovl.fmt.RRE.r1,
13113 ovl.fmt.RRE.r2); goto ok;
13114 case 0xb949: /* CFXTR */ goto unimplemented;
13115 case 0xb94a: /* CLGXTR */ goto unimplemented;
13116 case 0xb94b: /* CLFXTR */ goto unimplemented;
13117 case 0xb951: /* CDFTR */ goto unimplemented;
13118 case 0xb952: /* CDLGTR */ goto unimplemented;
13119 case 0xb953: /* CDLFTR */ goto unimplemented;
13120 case 0xb959: /* CXFTR */ goto unimplemented;
13121 case 0xb95a: /* CXLGTR */ goto unimplemented;
13122 case 0xb95b: /* CXLFTR */ goto unimplemented;
13123 case 0xb960: /* CGRT */ goto unimplemented;
13124 case 0xb961: /* CLGRT */ goto unimplemented;
13125 case 0xb972: /* CRT */ goto unimplemented;
13126 case 0xb973: /* CLRT */ goto unimplemented;
13127 case 0xb980: s390_format_RRE_RR(s390_irgen_NGR, ovl.fmt.RRE.r1,
13128 ovl.fmt.RRE.r2); goto ok;
13129 case 0xb981: s390_format_RRE_RR(s390_irgen_OGR, ovl.fmt.RRE.r1,
13130 ovl.fmt.RRE.r2); goto ok;
13131 case 0xb982: s390_format_RRE_RR(s390_irgen_XGR, ovl.fmt.RRE.r1,
13132 ovl.fmt.RRE.r2); goto ok;
13133 case 0xb983: s390_format_RRE_RR(s390_irgen_FLOGR, ovl.fmt.RRE.r1,
13134 ovl.fmt.RRE.r2); goto ok;
13135 case 0xb984: s390_format_RRE_RR(s390_irgen_LLGCR, ovl.fmt.RRE.r1,
13136 ovl.fmt.RRE.r2); goto ok;
13137 case 0xb985: s390_format_RRE_RR(s390_irgen_LLGHR, ovl.fmt.RRE.r1,
13138 ovl.fmt.RRE.r2); goto ok;
13139 case 0xb986: s390_format_RRE_RR(s390_irgen_MLGR, ovl.fmt.RRE.r1,
13140 ovl.fmt.RRE.r2); goto ok;
13141 case 0xb987: s390_format_RRE_RR(s390_irgen_DLGR, ovl.fmt.RRE.r1,
13142 ovl.fmt.RRE.r2); goto ok;
13143 case 0xb988: s390_format_RRE_RR(s390_irgen_ALCGR, ovl.fmt.RRE.r1,
13144 ovl.fmt.RRE.r2); goto ok;
13145 case 0xb989: s390_format_RRE_RR(s390_irgen_SLBGR, ovl.fmt.RRE.r1,
13146 ovl.fmt.RRE.r2); goto ok;
13147 case 0xb98a: /* CSPG */ goto unimplemented;
13148 case 0xb98d: /* EPSW */ goto unimplemented;
13149 case 0xb98e: /* IDTE */ goto unimplemented;
florian730448f2012-02-04 17:07:07 +000013150 case 0xb990: s390_format_RRF_M0RERE(s390_irgen_TRTT, ovl.fmt.RRF3.r3,
13151 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
13152 case 0xb991: s390_format_RRF_M0RERE(s390_irgen_TRTO, ovl.fmt.RRF3.r3,
13153 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
13154 case 0xb992: s390_format_RRF_M0RERE(s390_irgen_TROT, ovl.fmt.RRF3.r3,
13155 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
florian9af37692012-01-15 21:01:16 +000013156 case 0xb993: s390_format_RRF_M0RERE(s390_irgen_TROO, ovl.fmt.RRF3.r3,
13157 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013158 case 0xb994: s390_format_RRE_RR(s390_irgen_LLCR, ovl.fmt.RRE.r1,
13159 ovl.fmt.RRE.r2); goto ok;
13160 case 0xb995: s390_format_RRE_RR(s390_irgen_LLHR, ovl.fmt.RRE.r1,
13161 ovl.fmt.RRE.r2); goto ok;
13162 case 0xb996: s390_format_RRE_RR(s390_irgen_MLR, ovl.fmt.RRE.r1,
13163 ovl.fmt.RRE.r2); goto ok;
13164 case 0xb997: s390_format_RRE_RR(s390_irgen_DLR, ovl.fmt.RRE.r1,
13165 ovl.fmt.RRE.r2); goto ok;
13166 case 0xb998: s390_format_RRE_RR(s390_irgen_ALCR, ovl.fmt.RRE.r1,
13167 ovl.fmt.RRE.r2); goto ok;
13168 case 0xb999: s390_format_RRE_RR(s390_irgen_SLBR, ovl.fmt.RRE.r1,
13169 ovl.fmt.RRE.r2); goto ok;
13170 case 0xb99a: /* EPAIR */ goto unimplemented;
13171 case 0xb99b: /* ESAIR */ goto unimplemented;
13172 case 0xb99d: /* ESEA */ goto unimplemented;
13173 case 0xb99e: /* PTI */ goto unimplemented;
13174 case 0xb99f: /* SSAIR */ goto unimplemented;
13175 case 0xb9a2: /* PTF */ goto unimplemented;
13176 case 0xb9aa: /* LPTEA */ goto unimplemented;
13177 case 0xb9ae: /* RRBM */ goto unimplemented;
13178 case 0xb9af: /* PFMF */ goto unimplemented;
florian3f8a96a2012-08-05 02:59:55 +000013179 case 0xb9b0: s390_format_RRF_M0RERE(s390_irgen_CU14, ovl.fmt.RRF3.r3,
13180 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
13181 goto ok;
florian2a415a12012-07-21 17:41:36 +000013182 case 0xb9b1: s390_format_RRF_M0RERE(s390_irgen_CU24, ovl.fmt.RRF3.r3,
13183 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
13184 goto ok;
florianaf2194f2012-08-06 00:07:54 +000013185 case 0xb9b2: s390_format_RRE_RR(s390_irgen_CU41, ovl.fmt.RRE.r1,
13186 ovl.fmt.RRE.r2); goto ok;
florian956194b2012-07-28 22:18:32 +000013187 case 0xb9b3: s390_format_RRE_RR(s390_irgen_CU42, ovl.fmt.RRE.r1,
13188 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013189 case 0xb9bd: /* TRTRE */ goto unimplemented;
13190 case 0xb9be: /* SRSTU */ goto unimplemented;
13191 case 0xb9bf: /* TRTE */ goto unimplemented;
13192 case 0xb9c8: s390_format_RRF_R0RR2(s390_irgen_AHHHR, ovl.fmt.RRF4.r3,
13193 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13194 goto ok;
13195 case 0xb9c9: s390_format_RRF_R0RR2(s390_irgen_SHHHR, ovl.fmt.RRF4.r3,
13196 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13197 goto ok;
13198 case 0xb9ca: s390_format_RRF_R0RR2(s390_irgen_ALHHHR, ovl.fmt.RRF4.r3,
13199 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13200 goto ok;
13201 case 0xb9cb: s390_format_RRF_R0RR2(s390_irgen_SLHHHR, ovl.fmt.RRF4.r3,
13202 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13203 goto ok;
13204 case 0xb9cd: s390_format_RRE_RR(s390_irgen_CHHR, ovl.fmt.RRE.r1,
13205 ovl.fmt.RRE.r2); goto ok;
13206 case 0xb9cf: s390_format_RRE_RR(s390_irgen_CLHHR, ovl.fmt.RRE.r1,
13207 ovl.fmt.RRE.r2); goto ok;
13208 case 0xb9d8: s390_format_RRF_R0RR2(s390_irgen_AHHLR, ovl.fmt.RRF4.r3,
13209 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13210 goto ok;
13211 case 0xb9d9: s390_format_RRF_R0RR2(s390_irgen_SHHLR, ovl.fmt.RRF4.r3,
13212 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13213 goto ok;
13214 case 0xb9da: s390_format_RRF_R0RR2(s390_irgen_ALHHLR, ovl.fmt.RRF4.r3,
13215 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13216 goto ok;
13217 case 0xb9db: s390_format_RRF_R0RR2(s390_irgen_SLHHLR, ovl.fmt.RRF4.r3,
13218 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13219 goto ok;
13220 case 0xb9dd: s390_format_RRE_RR(s390_irgen_CHLR, ovl.fmt.RRE.r1,
13221 ovl.fmt.RRE.r2); goto ok;
13222 case 0xb9df: s390_format_RRE_RR(s390_irgen_CLHLR, ovl.fmt.RRE.r1,
13223 ovl.fmt.RRE.r2); goto ok;
13224 case 0xb9e1: /* POPCNT */ goto unimplemented;
sewardjd7bde722011-04-05 13:19:33 +000013225 case 0xb9e2: s390_format_RRF_U0RR(s390_irgen_LOCGR, ovl.fmt.RRF3.r3,
13226 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2,
13227 S390_XMNM_LOCGR); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013228 case 0xb9e4: s390_format_RRF_R0RR2(s390_irgen_NGRK, ovl.fmt.RRF4.r3,
13229 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13230 goto ok;
13231 case 0xb9e6: s390_format_RRF_R0RR2(s390_irgen_OGRK, ovl.fmt.RRF4.r3,
13232 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13233 goto ok;
13234 case 0xb9e7: s390_format_RRF_R0RR2(s390_irgen_XGRK, ovl.fmt.RRF4.r3,
13235 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13236 goto ok;
13237 case 0xb9e8: s390_format_RRF_R0RR2(s390_irgen_AGRK, ovl.fmt.RRF4.r3,
13238 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13239 goto ok;
13240 case 0xb9e9: s390_format_RRF_R0RR2(s390_irgen_SGRK, ovl.fmt.RRF4.r3,
13241 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13242 goto ok;
13243 case 0xb9ea: s390_format_RRF_R0RR2(s390_irgen_ALGRK, ovl.fmt.RRF4.r3,
13244 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13245 goto ok;
13246 case 0xb9eb: s390_format_RRF_R0RR2(s390_irgen_SLGRK, ovl.fmt.RRF4.r3,
13247 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13248 goto ok;
sewardjd7bde722011-04-05 13:19:33 +000013249 case 0xb9f2: s390_format_RRF_U0RR(s390_irgen_LOCR, ovl.fmt.RRF3.r3,
13250 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2,
13251 S390_XMNM_LOCR); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013252 case 0xb9f4: s390_format_RRF_R0RR2(s390_irgen_NRK, ovl.fmt.RRF4.r3,
13253 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13254 goto ok;
13255 case 0xb9f6: s390_format_RRF_R0RR2(s390_irgen_ORK, ovl.fmt.RRF4.r3,
13256 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13257 goto ok;
13258 case 0xb9f7: s390_format_RRF_R0RR2(s390_irgen_XRK, ovl.fmt.RRF4.r3,
13259 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13260 goto ok;
13261 case 0xb9f8: s390_format_RRF_R0RR2(s390_irgen_ARK, ovl.fmt.RRF4.r3,
13262 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13263 goto ok;
13264 case 0xb9f9: s390_format_RRF_R0RR2(s390_irgen_SRK, ovl.fmt.RRF4.r3,
13265 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13266 goto ok;
13267 case 0xb9fa: s390_format_RRF_R0RR2(s390_irgen_ALRK, ovl.fmt.RRF4.r3,
13268 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13269 goto ok;
13270 case 0xb9fb: s390_format_RRF_R0RR2(s390_irgen_SLRK, ovl.fmt.RRF4.r3,
13271 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13272 goto ok;
13273 }
13274
13275 switch ((ovl.value & 0xff000000) >> 24) {
13276 case 0x40: s390_format_RX_RRRD(s390_irgen_STH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13277 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13278 case 0x41: s390_format_RX_RRRD(s390_irgen_LA, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13279 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13280 case 0x42: s390_format_RX_RRRD(s390_irgen_STC, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13281 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13282 case 0x43: s390_format_RX_RRRD(s390_irgen_IC, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13283 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13284 case 0x44: s390_format_RX_RRRD(s390_irgen_EX, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13285 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13286 case 0x45: /* BAL */ goto unimplemented;
13287 case 0x46: s390_format_RX_RRRD(s390_irgen_BCT, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13288 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13289 case 0x47: s390_format_RX(s390_irgen_BC, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13290 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13291 case 0x48: s390_format_RX_RRRD(s390_irgen_LH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13292 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13293 case 0x49: s390_format_RX_RRRD(s390_irgen_CH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13294 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13295 case 0x4a: s390_format_RX_RRRD(s390_irgen_AH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13296 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13297 case 0x4b: s390_format_RX_RRRD(s390_irgen_SH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13298 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13299 case 0x4c: s390_format_RX_RRRD(s390_irgen_MH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13300 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13301 case 0x4d: s390_format_RX_RRRD(s390_irgen_BAS, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13302 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13303 case 0x4e: s390_format_RX_RRRD(s390_irgen_CVD, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13304 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13305 case 0x4f: s390_format_RX_RRRD(s390_irgen_CVB, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13306 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13307 case 0x50: s390_format_RX_RRRD(s390_irgen_ST, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13308 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13309 case 0x51: s390_format_RX_RRRD(s390_irgen_LAE, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13310 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13311 case 0x54: s390_format_RX_RRRD(s390_irgen_N, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13312 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13313 case 0x55: s390_format_RX_RRRD(s390_irgen_CL, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13314 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13315 case 0x56: s390_format_RX_RRRD(s390_irgen_O, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13316 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13317 case 0x57: s390_format_RX_RRRD(s390_irgen_X, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13318 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13319 case 0x58: s390_format_RX_RRRD(s390_irgen_L, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13320 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13321 case 0x59: s390_format_RX_RRRD(s390_irgen_C, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13322 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13323 case 0x5a: s390_format_RX_RRRD(s390_irgen_A, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13324 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13325 case 0x5b: s390_format_RX_RRRD(s390_irgen_S, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13326 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13327 case 0x5c: s390_format_RX_RRRD(s390_irgen_M, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13328 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13329 case 0x5d: s390_format_RX_RRRD(s390_irgen_D, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13330 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13331 case 0x5e: s390_format_RX_RRRD(s390_irgen_AL, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13332 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13333 case 0x5f: s390_format_RX_RRRD(s390_irgen_SL, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13334 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13335 case 0x60: s390_format_RX_FRRD(s390_irgen_STD, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13336 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13337 case 0x67: /* MXD */ goto unimplemented;
13338 case 0x68: s390_format_RX_FRRD(s390_irgen_LD, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13339 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13340 case 0x69: /* CD */ goto unimplemented;
13341 case 0x6a: /* AD */ goto unimplemented;
13342 case 0x6b: /* SD */ goto unimplemented;
13343 case 0x6c: /* MD */ goto unimplemented;
13344 case 0x6d: /* DD */ goto unimplemented;
13345 case 0x6e: /* AW */ goto unimplemented;
13346 case 0x6f: /* SW */ goto unimplemented;
13347 case 0x70: s390_format_RX_FRRD(s390_irgen_STE, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13348 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13349 case 0x71: s390_format_RX_RRRD(s390_irgen_MS, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13350 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13351 case 0x78: s390_format_RX_FRRD(s390_irgen_LE, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13352 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13353 case 0x79: /* CE */ goto unimplemented;
13354 case 0x7a: /* AE */ goto unimplemented;
13355 case 0x7b: /* SE */ goto unimplemented;
13356 case 0x7c: /* MDE */ goto unimplemented;
13357 case 0x7d: /* DE */ goto unimplemented;
13358 case 0x7e: /* AU */ goto unimplemented;
13359 case 0x7f: /* SU */ goto unimplemented;
13360 case 0x83: /* DIAG */ goto unimplemented;
13361 case 0x84: s390_format_RSI_RRP(s390_irgen_BRXH, ovl.fmt.RSI.r1,
13362 ovl.fmt.RSI.r3, ovl.fmt.RSI.i2); goto ok;
13363 case 0x85: s390_format_RSI_RRP(s390_irgen_BRXLE, ovl.fmt.RSI.r1,
13364 ovl.fmt.RSI.r3, ovl.fmt.RSI.i2); goto ok;
13365 case 0x86: s390_format_RS_RRRD(s390_irgen_BXH, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13366 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13367 case 0x87: s390_format_RS_RRRD(s390_irgen_BXLE, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13368 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13369 case 0x88: s390_format_RS_R0RD(s390_irgen_SRL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
13370 ovl.fmt.RS.d2); goto ok;
13371 case 0x89: s390_format_RS_R0RD(s390_irgen_SLL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
13372 ovl.fmt.RS.d2); goto ok;
13373 case 0x8a: s390_format_RS_R0RD(s390_irgen_SRA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
13374 ovl.fmt.RS.d2); goto ok;
13375 case 0x8b: s390_format_RS_R0RD(s390_irgen_SLA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
13376 ovl.fmt.RS.d2); goto ok;
13377 case 0x8c: s390_format_RS_R0RD(s390_irgen_SRDL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
13378 ovl.fmt.RS.d2); goto ok;
13379 case 0x8d: s390_format_RS_R0RD(s390_irgen_SLDL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
13380 ovl.fmt.RS.d2); goto ok;
13381 case 0x8e: s390_format_RS_R0RD(s390_irgen_SRDA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
13382 ovl.fmt.RS.d2); goto ok;
13383 case 0x8f: s390_format_RS_R0RD(s390_irgen_SLDA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
13384 ovl.fmt.RS.d2); goto ok;
13385 case 0x90: s390_format_RS_RRRD(s390_irgen_STM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13386 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13387 case 0x91: s390_format_SI_URD(s390_irgen_TM, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
13388 ovl.fmt.SI.d1); goto ok;
13389 case 0x92: s390_format_SI_URD(s390_irgen_MVI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
13390 ovl.fmt.SI.d1); goto ok;
13391 case 0x94: s390_format_SI_URD(s390_irgen_NI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
13392 ovl.fmt.SI.d1); goto ok;
13393 case 0x95: s390_format_SI_URD(s390_irgen_CLI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
13394 ovl.fmt.SI.d1); goto ok;
13395 case 0x96: s390_format_SI_URD(s390_irgen_OI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
13396 ovl.fmt.SI.d1); goto ok;
13397 case 0x97: s390_format_SI_URD(s390_irgen_XI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
13398 ovl.fmt.SI.d1); goto ok;
13399 case 0x98: s390_format_RS_RRRD(s390_irgen_LM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13400 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13401 case 0x99: /* TRACE */ goto unimplemented;
13402 case 0x9a: s390_format_RS_AARD(s390_irgen_LAM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13403 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13404 case 0x9b: s390_format_RS_AARD(s390_irgen_STAM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13405 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13406 case 0xa8: s390_format_RS_RRRD(s390_irgen_MVCLE, ovl.fmt.RS.r1,
13407 ovl.fmt.RS.r3, ovl.fmt.RS.b2, ovl.fmt.RS.d2);
13408 goto ok;
13409 case 0xa9: s390_format_RS_RRRD(s390_irgen_CLCLE, ovl.fmt.RS.r1,
13410 ovl.fmt.RS.r3, ovl.fmt.RS.b2, ovl.fmt.RS.d2);
13411 goto ok;
13412 case 0xac: /* STNSM */ goto unimplemented;
13413 case 0xad: /* STOSM */ goto unimplemented;
13414 case 0xae: /* SIGP */ goto unimplemented;
13415 case 0xaf: /* MC */ goto unimplemented;
13416 case 0xb1: /* LRA */ goto unimplemented;
13417 case 0xb6: /* STCTL */ goto unimplemented;
13418 case 0xb7: /* LCTL */ goto unimplemented;
13419 case 0xba: s390_format_RS_RRRD(s390_irgen_CS, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13420 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
florian448cbba2012-06-06 02:26:01 +000013421 case 0xbb: s390_format_RS_RRRD(s390_irgen_CDS, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13422 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013423 case 0xbd: s390_format_RS_RURD(s390_irgen_CLM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13424 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13425 case 0xbe: s390_format_RS_RURD(s390_irgen_STCM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13426 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13427 case 0xbf: s390_format_RS_RURD(s390_irgen_ICM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13428 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13429 }
13430
13431 return S390_DECODE_UNKNOWN_INSN;
13432
13433ok:
13434 return S390_DECODE_OK;
13435
13436unimplemented:
13437 return S390_DECODE_UNIMPLEMENTED_INSN;
13438}
13439
13440static s390_decode_t
13441s390_decode_6byte_and_irgen(UChar *bytes)
13442{
13443 typedef union {
13444 struct {
13445 unsigned int op1 : 8;
13446 unsigned int r1 : 4;
13447 unsigned int r3 : 4;
13448 unsigned int i2 : 16;
13449 unsigned int : 8;
13450 unsigned int op2 : 8;
13451 } RIE;
13452 struct {
13453 unsigned int op1 : 8;
13454 unsigned int r1 : 4;
13455 unsigned int r2 : 4;
13456 unsigned int i3 : 8;
13457 unsigned int i4 : 8;
13458 unsigned int i5 : 8;
13459 unsigned int op2 : 8;
13460 } RIE_RRUUU;
13461 struct {
13462 unsigned int op1 : 8;
13463 unsigned int r1 : 4;
13464 unsigned int : 4;
13465 unsigned int i2 : 16;
13466 unsigned int m3 : 4;
13467 unsigned int : 4;
13468 unsigned int op2 : 8;
13469 } RIEv1;
13470 struct {
13471 unsigned int op1 : 8;
13472 unsigned int r1 : 4;
13473 unsigned int r2 : 4;
13474 unsigned int i4 : 16;
13475 unsigned int m3 : 4;
13476 unsigned int : 4;
13477 unsigned int op2 : 8;
13478 } RIE_RRPU;
13479 struct {
13480 unsigned int op1 : 8;
13481 unsigned int r1 : 4;
13482 unsigned int m3 : 4;
13483 unsigned int i4 : 16;
13484 unsigned int i2 : 8;
13485 unsigned int op2 : 8;
13486 } RIEv3;
13487 struct {
13488 unsigned int op1 : 8;
13489 unsigned int r1 : 4;
13490 unsigned int op2 : 4;
13491 unsigned int i2 : 32;
13492 } RIL;
13493 struct {
13494 unsigned int op1 : 8;
13495 unsigned int r1 : 4;
13496 unsigned int m3 : 4;
13497 unsigned int b4 : 4;
13498 unsigned int d4 : 12;
13499 unsigned int i2 : 8;
13500 unsigned int op2 : 8;
13501 } RIS;
13502 struct {
13503 unsigned int op1 : 8;
13504 unsigned int r1 : 4;
13505 unsigned int r2 : 4;
13506 unsigned int b4 : 4;
13507 unsigned int d4 : 12;
13508 unsigned int m3 : 4;
13509 unsigned int : 4;
13510 unsigned int op2 : 8;
13511 } RRS;
13512 struct {
13513 unsigned int op1 : 8;
13514 unsigned int l1 : 4;
13515 unsigned int : 4;
13516 unsigned int b1 : 4;
13517 unsigned int d1 : 12;
13518 unsigned int : 8;
13519 unsigned int op2 : 8;
13520 } RSL;
13521 struct {
13522 unsigned int op1 : 8;
13523 unsigned int r1 : 4;
13524 unsigned int r3 : 4;
13525 unsigned int b2 : 4;
13526 unsigned int dl2 : 12;
13527 unsigned int dh2 : 8;
13528 unsigned int op2 : 8;
13529 } RSY;
13530 struct {
13531 unsigned int op1 : 8;
13532 unsigned int r1 : 4;
13533 unsigned int x2 : 4;
13534 unsigned int b2 : 4;
13535 unsigned int d2 : 12;
13536 unsigned int : 8;
13537 unsigned int op2 : 8;
13538 } RXE;
13539 struct {
13540 unsigned int op1 : 8;
13541 unsigned int r3 : 4;
13542 unsigned int x2 : 4;
13543 unsigned int b2 : 4;
13544 unsigned int d2 : 12;
13545 unsigned int r1 : 4;
13546 unsigned int : 4;
13547 unsigned int op2 : 8;
13548 } RXF;
13549 struct {
13550 unsigned int op1 : 8;
13551 unsigned int r1 : 4;
13552 unsigned int x2 : 4;
13553 unsigned int b2 : 4;
13554 unsigned int dl2 : 12;
13555 unsigned int dh2 : 8;
13556 unsigned int op2 : 8;
13557 } RXY;
13558 struct {
13559 unsigned int op1 : 8;
13560 unsigned int i2 : 8;
13561 unsigned int b1 : 4;
13562 unsigned int dl1 : 12;
13563 unsigned int dh1 : 8;
13564 unsigned int op2 : 8;
13565 } SIY;
13566 struct {
13567 unsigned int op : 8;
13568 unsigned int l : 8;
13569 unsigned int b1 : 4;
13570 unsigned int d1 : 12;
13571 unsigned int b2 : 4;
13572 unsigned int d2 : 12;
13573 } SS;
13574 struct {
13575 unsigned int op : 8;
13576 unsigned int l1 : 4;
13577 unsigned int l2 : 4;
13578 unsigned int b1 : 4;
13579 unsigned int d1 : 12;
13580 unsigned int b2 : 4;
13581 unsigned int d2 : 12;
13582 } SS_LLRDRD;
13583 struct {
13584 unsigned int op : 8;
13585 unsigned int r1 : 4;
13586 unsigned int r3 : 4;
13587 unsigned int b2 : 4;
13588 unsigned int d2 : 12;
13589 unsigned int b4 : 4;
13590 unsigned int d4 : 12;
13591 } SS_RRRDRD2;
13592 struct {
13593 unsigned int op : 16;
13594 unsigned int b1 : 4;
13595 unsigned int d1 : 12;
13596 unsigned int b2 : 4;
13597 unsigned int d2 : 12;
13598 } SSE;
13599 struct {
13600 unsigned int op1 : 8;
13601 unsigned int r3 : 4;
13602 unsigned int op2 : 4;
13603 unsigned int b1 : 4;
13604 unsigned int d1 : 12;
13605 unsigned int b2 : 4;
13606 unsigned int d2 : 12;
13607 } SSF;
13608 struct {
13609 unsigned int op : 16;
13610 unsigned int b1 : 4;
13611 unsigned int d1 : 12;
13612 unsigned int i2 : 16;
13613 } SIL;
13614 } formats;
13615 union {
13616 formats fmt;
13617 ULong value;
13618 } ovl;
13619
13620 vassert(sizeof(formats) == 6);
13621
13622 ((char *)(&ovl.value))[0] = bytes[0];
13623 ((char *)(&ovl.value))[1] = bytes[1];
13624 ((char *)(&ovl.value))[2] = bytes[2];
13625 ((char *)(&ovl.value))[3] = bytes[3];
13626 ((char *)(&ovl.value))[4] = bytes[4];
13627 ((char *)(&ovl.value))[5] = bytes[5];
13628 ((char *)(&ovl.value))[6] = 0x0;
13629 ((char *)(&ovl.value))[7] = 0x0;
13630
13631 switch ((ovl.value >> 16) & 0xff00000000ffULL) {
13632 case 0xe30000000002ULL: s390_format_RXY_RRRD(s390_irgen_LTG, ovl.fmt.RXY.r1,
13633 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13634 ovl.fmt.RXY.dl2,
13635 ovl.fmt.RXY.dh2); goto ok;
13636 case 0xe30000000003ULL: /* LRAG */ goto unimplemented;
13637 case 0xe30000000004ULL: s390_format_RXY_RRRD(s390_irgen_LG, ovl.fmt.RXY.r1,
13638 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13639 ovl.fmt.RXY.dl2,
13640 ovl.fmt.RXY.dh2); goto ok;
13641 case 0xe30000000006ULL: s390_format_RXY_RRRD(s390_irgen_CVBY, ovl.fmt.RXY.r1,
13642 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13643 ovl.fmt.RXY.dl2,
13644 ovl.fmt.RXY.dh2); goto ok;
13645 case 0xe30000000008ULL: s390_format_RXY_RRRD(s390_irgen_AG, ovl.fmt.RXY.r1,
13646 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13647 ovl.fmt.RXY.dl2,
13648 ovl.fmt.RXY.dh2); goto ok;
13649 case 0xe30000000009ULL: s390_format_RXY_RRRD(s390_irgen_SG, ovl.fmt.RXY.r1,
13650 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13651 ovl.fmt.RXY.dl2,
13652 ovl.fmt.RXY.dh2); goto ok;
13653 case 0xe3000000000aULL: s390_format_RXY_RRRD(s390_irgen_ALG, ovl.fmt.RXY.r1,
13654 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13655 ovl.fmt.RXY.dl2,
13656 ovl.fmt.RXY.dh2); goto ok;
13657 case 0xe3000000000bULL: s390_format_RXY_RRRD(s390_irgen_SLG, ovl.fmt.RXY.r1,
13658 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13659 ovl.fmt.RXY.dl2,
13660 ovl.fmt.RXY.dh2); goto ok;
13661 case 0xe3000000000cULL: s390_format_RXY_RRRD(s390_irgen_MSG, ovl.fmt.RXY.r1,
13662 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13663 ovl.fmt.RXY.dl2,
13664 ovl.fmt.RXY.dh2); goto ok;
13665 case 0xe3000000000dULL: s390_format_RXY_RRRD(s390_irgen_DSG, ovl.fmt.RXY.r1,
13666 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13667 ovl.fmt.RXY.dl2,
13668 ovl.fmt.RXY.dh2); goto ok;
13669 case 0xe3000000000eULL: /* CVBG */ goto unimplemented;
13670 case 0xe3000000000fULL: s390_format_RXY_RRRD(s390_irgen_LRVG, ovl.fmt.RXY.r1,
13671 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13672 ovl.fmt.RXY.dl2,
13673 ovl.fmt.RXY.dh2); goto ok;
13674 case 0xe30000000012ULL: s390_format_RXY_RRRD(s390_irgen_LT, ovl.fmt.RXY.r1,
13675 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13676 ovl.fmt.RXY.dl2,
13677 ovl.fmt.RXY.dh2); goto ok;
13678 case 0xe30000000013ULL: /* LRAY */ goto unimplemented;
13679 case 0xe30000000014ULL: s390_format_RXY_RRRD(s390_irgen_LGF, 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 0xe30000000015ULL: s390_format_RXY_RRRD(s390_irgen_LGH, 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 0xe30000000016ULL: s390_format_RXY_RRRD(s390_irgen_LLGF, 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 0xe30000000017ULL: s390_format_RXY_RRRD(s390_irgen_LLGT, ovl.fmt.RXY.r1,
13692 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13693 ovl.fmt.RXY.dl2,
13694 ovl.fmt.RXY.dh2); goto ok;
13695 case 0xe30000000018ULL: s390_format_RXY_RRRD(s390_irgen_AGF, 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 0xe30000000019ULL: s390_format_RXY_RRRD(s390_irgen_SGF, 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 0xe3000000001aULL: s390_format_RXY_RRRD(s390_irgen_ALGF, 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 0xe3000000001bULL: s390_format_RXY_RRRD(s390_irgen_SLGF, 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 0xe3000000001cULL: s390_format_RXY_RRRD(s390_irgen_MSGF, 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 0xe3000000001dULL: s390_format_RXY_RRRD(s390_irgen_DSGF, 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 0xe3000000001eULL: s390_format_RXY_RRRD(s390_irgen_LRV, 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 0xe3000000001fULL: s390_format_RXY_RRRD(s390_irgen_LRVH, 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 0xe30000000020ULL: s390_format_RXY_RRRD(s390_irgen_CG, 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 0xe30000000021ULL: s390_format_RXY_RRRD(s390_irgen_CLG, 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 0xe30000000024ULL: s390_format_RXY_RRRD(s390_irgen_STG, 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 0xe30000000026ULL: s390_format_RXY_RRRD(s390_irgen_CVDY, 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 0xe3000000002eULL: /* CVDG */ goto unimplemented;
13744 case 0xe3000000002fULL: s390_format_RXY_RRRD(s390_irgen_STRVG,
13745 ovl.fmt.RXY.r1, ovl.fmt.RXY.x2,
13746 ovl.fmt.RXY.b2, ovl.fmt.RXY.dl2,
13747 ovl.fmt.RXY.dh2); goto ok;
13748 case 0xe30000000030ULL: s390_format_RXY_RRRD(s390_irgen_CGF, ovl.fmt.RXY.r1,
13749 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13750 ovl.fmt.RXY.dl2,
13751 ovl.fmt.RXY.dh2); goto ok;
13752 case 0xe30000000031ULL: s390_format_RXY_RRRD(s390_irgen_CLGF, ovl.fmt.RXY.r1,
13753 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13754 ovl.fmt.RXY.dl2,
13755 ovl.fmt.RXY.dh2); goto ok;
13756 case 0xe30000000032ULL: s390_format_RXY_RRRD(s390_irgen_LTGF, ovl.fmt.RXY.r1,
13757 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13758 ovl.fmt.RXY.dl2,
13759 ovl.fmt.RXY.dh2); goto ok;
13760 case 0xe30000000034ULL: s390_format_RXY_RRRD(s390_irgen_CGH, ovl.fmt.RXY.r1,
13761 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13762 ovl.fmt.RXY.dl2,
13763 ovl.fmt.RXY.dh2); goto ok;
13764 case 0xe30000000036ULL: s390_format_RXY_URRD(s390_irgen_PFD, ovl.fmt.RXY.r1,
13765 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13766 ovl.fmt.RXY.dl2,
13767 ovl.fmt.RXY.dh2); goto ok;
13768 case 0xe3000000003eULL: s390_format_RXY_RRRD(s390_irgen_STRV, ovl.fmt.RXY.r1,
13769 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13770 ovl.fmt.RXY.dl2,
13771 ovl.fmt.RXY.dh2); goto ok;
13772 case 0xe3000000003fULL: s390_format_RXY_RRRD(s390_irgen_STRVH,
13773 ovl.fmt.RXY.r1, ovl.fmt.RXY.x2,
13774 ovl.fmt.RXY.b2, ovl.fmt.RXY.dl2,
13775 ovl.fmt.RXY.dh2); goto ok;
13776 case 0xe30000000046ULL: s390_format_RXY_RRRD(s390_irgen_BCTG, ovl.fmt.RXY.r1,
13777 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13778 ovl.fmt.RXY.dl2,
13779 ovl.fmt.RXY.dh2); goto ok;
13780 case 0xe30000000050ULL: s390_format_RXY_RRRD(s390_irgen_STY, ovl.fmt.RXY.r1,
13781 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13782 ovl.fmt.RXY.dl2,
13783 ovl.fmt.RXY.dh2); goto ok;
13784 case 0xe30000000051ULL: s390_format_RXY_RRRD(s390_irgen_MSY, ovl.fmt.RXY.r1,
13785 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13786 ovl.fmt.RXY.dl2,
13787 ovl.fmt.RXY.dh2); goto ok;
13788 case 0xe30000000054ULL: s390_format_RXY_RRRD(s390_irgen_NY, ovl.fmt.RXY.r1,
13789 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13790 ovl.fmt.RXY.dl2,
13791 ovl.fmt.RXY.dh2); goto ok;
13792 case 0xe30000000055ULL: s390_format_RXY_RRRD(s390_irgen_CLY, ovl.fmt.RXY.r1,
13793 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13794 ovl.fmt.RXY.dl2,
13795 ovl.fmt.RXY.dh2); goto ok;
13796 case 0xe30000000056ULL: s390_format_RXY_RRRD(s390_irgen_OY, ovl.fmt.RXY.r1,
13797 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13798 ovl.fmt.RXY.dl2,
13799 ovl.fmt.RXY.dh2); goto ok;
13800 case 0xe30000000057ULL: s390_format_RXY_RRRD(s390_irgen_XY, ovl.fmt.RXY.r1,
13801 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13802 ovl.fmt.RXY.dl2,
13803 ovl.fmt.RXY.dh2); goto ok;
13804 case 0xe30000000058ULL: s390_format_RXY_RRRD(s390_irgen_LY, ovl.fmt.RXY.r1,
13805 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13806 ovl.fmt.RXY.dl2,
13807 ovl.fmt.RXY.dh2); goto ok;
13808 case 0xe30000000059ULL: s390_format_RXY_RRRD(s390_irgen_CY, ovl.fmt.RXY.r1,
13809 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13810 ovl.fmt.RXY.dl2,
13811 ovl.fmt.RXY.dh2); goto ok;
13812 case 0xe3000000005aULL: s390_format_RXY_RRRD(s390_irgen_AY, ovl.fmt.RXY.r1,
13813 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13814 ovl.fmt.RXY.dl2,
13815 ovl.fmt.RXY.dh2); goto ok;
13816 case 0xe3000000005bULL: s390_format_RXY_RRRD(s390_irgen_SY, ovl.fmt.RXY.r1,
13817 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13818 ovl.fmt.RXY.dl2,
13819 ovl.fmt.RXY.dh2); goto ok;
13820 case 0xe3000000005cULL: s390_format_RXY_RRRD(s390_irgen_MFY, ovl.fmt.RXY.r1,
13821 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13822 ovl.fmt.RXY.dl2,
13823 ovl.fmt.RXY.dh2); goto ok;
13824 case 0xe3000000005eULL: s390_format_RXY_RRRD(s390_irgen_ALY, ovl.fmt.RXY.r1,
13825 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13826 ovl.fmt.RXY.dl2,
13827 ovl.fmt.RXY.dh2); goto ok;
13828 case 0xe3000000005fULL: s390_format_RXY_RRRD(s390_irgen_SLY, ovl.fmt.RXY.r1,
13829 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13830 ovl.fmt.RXY.dl2,
13831 ovl.fmt.RXY.dh2); goto ok;
13832 case 0xe30000000070ULL: s390_format_RXY_RRRD(s390_irgen_STHY, ovl.fmt.RXY.r1,
13833 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13834 ovl.fmt.RXY.dl2,
13835 ovl.fmt.RXY.dh2); goto ok;
13836 case 0xe30000000071ULL: s390_format_RXY_RRRD(s390_irgen_LAY, ovl.fmt.RXY.r1,
13837 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13838 ovl.fmt.RXY.dl2,
13839 ovl.fmt.RXY.dh2); goto ok;
13840 case 0xe30000000072ULL: s390_format_RXY_RRRD(s390_irgen_STCY, ovl.fmt.RXY.r1,
13841 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13842 ovl.fmt.RXY.dl2,
13843 ovl.fmt.RXY.dh2); goto ok;
13844 case 0xe30000000073ULL: s390_format_RXY_RRRD(s390_irgen_ICY, ovl.fmt.RXY.r1,
13845 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13846 ovl.fmt.RXY.dl2,
13847 ovl.fmt.RXY.dh2); goto ok;
13848 case 0xe30000000075ULL: s390_format_RXY_RRRD(s390_irgen_LAEY, ovl.fmt.RXY.r1,
13849 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13850 ovl.fmt.RXY.dl2,
13851 ovl.fmt.RXY.dh2); goto ok;
13852 case 0xe30000000076ULL: s390_format_RXY_RRRD(s390_irgen_LB, ovl.fmt.RXY.r1,
13853 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13854 ovl.fmt.RXY.dl2,
13855 ovl.fmt.RXY.dh2); goto ok;
13856 case 0xe30000000077ULL: s390_format_RXY_RRRD(s390_irgen_LGB, ovl.fmt.RXY.r1,
13857 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13858 ovl.fmt.RXY.dl2,
13859 ovl.fmt.RXY.dh2); goto ok;
13860 case 0xe30000000078ULL: s390_format_RXY_RRRD(s390_irgen_LHY, ovl.fmt.RXY.r1,
13861 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13862 ovl.fmt.RXY.dl2,
13863 ovl.fmt.RXY.dh2); goto ok;
13864 case 0xe30000000079ULL: s390_format_RXY_RRRD(s390_irgen_CHY, ovl.fmt.RXY.r1,
13865 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13866 ovl.fmt.RXY.dl2,
13867 ovl.fmt.RXY.dh2); goto ok;
13868 case 0xe3000000007aULL: s390_format_RXY_RRRD(s390_irgen_AHY, ovl.fmt.RXY.r1,
13869 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13870 ovl.fmt.RXY.dl2,
13871 ovl.fmt.RXY.dh2); goto ok;
13872 case 0xe3000000007bULL: s390_format_RXY_RRRD(s390_irgen_SHY, ovl.fmt.RXY.r1,
13873 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13874 ovl.fmt.RXY.dl2,
13875 ovl.fmt.RXY.dh2); goto ok;
13876 case 0xe3000000007cULL: s390_format_RXY_RRRD(s390_irgen_MHY, ovl.fmt.RXY.r1,
13877 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13878 ovl.fmt.RXY.dl2,
13879 ovl.fmt.RXY.dh2); goto ok;
13880 case 0xe30000000080ULL: s390_format_RXY_RRRD(s390_irgen_NG, ovl.fmt.RXY.r1,
13881 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13882 ovl.fmt.RXY.dl2,
13883 ovl.fmt.RXY.dh2); goto ok;
13884 case 0xe30000000081ULL: s390_format_RXY_RRRD(s390_irgen_OG, ovl.fmt.RXY.r1,
13885 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13886 ovl.fmt.RXY.dl2,
13887 ovl.fmt.RXY.dh2); goto ok;
13888 case 0xe30000000082ULL: s390_format_RXY_RRRD(s390_irgen_XG, ovl.fmt.RXY.r1,
13889 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13890 ovl.fmt.RXY.dl2,
13891 ovl.fmt.RXY.dh2); goto ok;
13892 case 0xe30000000086ULL: s390_format_RXY_RRRD(s390_irgen_MLG, ovl.fmt.RXY.r1,
13893 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13894 ovl.fmt.RXY.dl2,
13895 ovl.fmt.RXY.dh2); goto ok;
13896 case 0xe30000000087ULL: s390_format_RXY_RRRD(s390_irgen_DLG, ovl.fmt.RXY.r1,
13897 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13898 ovl.fmt.RXY.dl2,
13899 ovl.fmt.RXY.dh2); goto ok;
13900 case 0xe30000000088ULL: s390_format_RXY_RRRD(s390_irgen_ALCG, ovl.fmt.RXY.r1,
13901 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13902 ovl.fmt.RXY.dl2,
13903 ovl.fmt.RXY.dh2); goto ok;
13904 case 0xe30000000089ULL: s390_format_RXY_RRRD(s390_irgen_SLBG, ovl.fmt.RXY.r1,
13905 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13906 ovl.fmt.RXY.dl2,
13907 ovl.fmt.RXY.dh2); goto ok;
13908 case 0xe3000000008eULL: s390_format_RXY_RRRD(s390_irgen_STPQ, ovl.fmt.RXY.r1,
13909 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13910 ovl.fmt.RXY.dl2,
13911 ovl.fmt.RXY.dh2); goto ok;
13912 case 0xe3000000008fULL: s390_format_RXY_RRRD(s390_irgen_LPQ, ovl.fmt.RXY.r1,
13913 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13914 ovl.fmt.RXY.dl2,
13915 ovl.fmt.RXY.dh2); goto ok;
13916 case 0xe30000000090ULL: s390_format_RXY_RRRD(s390_irgen_LLGC, ovl.fmt.RXY.r1,
13917 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13918 ovl.fmt.RXY.dl2,
13919 ovl.fmt.RXY.dh2); goto ok;
13920 case 0xe30000000091ULL: s390_format_RXY_RRRD(s390_irgen_LLGH, ovl.fmt.RXY.r1,
13921 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13922 ovl.fmt.RXY.dl2,
13923 ovl.fmt.RXY.dh2); goto ok;
13924 case 0xe30000000094ULL: s390_format_RXY_RRRD(s390_irgen_LLC, ovl.fmt.RXY.r1,
13925 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13926 ovl.fmt.RXY.dl2,
13927 ovl.fmt.RXY.dh2); goto ok;
13928 case 0xe30000000095ULL: s390_format_RXY_RRRD(s390_irgen_LLH, ovl.fmt.RXY.r1,
13929 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13930 ovl.fmt.RXY.dl2,
13931 ovl.fmt.RXY.dh2); goto ok;
13932 case 0xe30000000096ULL: s390_format_RXY_RRRD(s390_irgen_ML, ovl.fmt.RXY.r1,
13933 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13934 ovl.fmt.RXY.dl2,
13935 ovl.fmt.RXY.dh2); goto ok;
13936 case 0xe30000000097ULL: s390_format_RXY_RRRD(s390_irgen_DL, ovl.fmt.RXY.r1,
13937 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13938 ovl.fmt.RXY.dl2,
13939 ovl.fmt.RXY.dh2); goto ok;
13940 case 0xe30000000098ULL: s390_format_RXY_RRRD(s390_irgen_ALC, ovl.fmt.RXY.r1,
13941 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13942 ovl.fmt.RXY.dl2,
13943 ovl.fmt.RXY.dh2); goto ok;
13944 case 0xe30000000099ULL: s390_format_RXY_RRRD(s390_irgen_SLB, ovl.fmt.RXY.r1,
13945 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13946 ovl.fmt.RXY.dl2,
13947 ovl.fmt.RXY.dh2); goto ok;
13948 case 0xe300000000c0ULL: s390_format_RXY_RRRD(s390_irgen_LBH, ovl.fmt.RXY.r1,
13949 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13950 ovl.fmt.RXY.dl2,
13951 ovl.fmt.RXY.dh2); goto ok;
13952 case 0xe300000000c2ULL: s390_format_RXY_RRRD(s390_irgen_LLCH, ovl.fmt.RXY.r1,
13953 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13954 ovl.fmt.RXY.dl2,
13955 ovl.fmt.RXY.dh2); goto ok;
13956 case 0xe300000000c3ULL: s390_format_RXY_RRRD(s390_irgen_STCH, ovl.fmt.RXY.r1,
13957 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13958 ovl.fmt.RXY.dl2,
13959 ovl.fmt.RXY.dh2); goto ok;
13960 case 0xe300000000c4ULL: s390_format_RXY_RRRD(s390_irgen_LHH, ovl.fmt.RXY.r1,
13961 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13962 ovl.fmt.RXY.dl2,
13963 ovl.fmt.RXY.dh2); goto ok;
13964 case 0xe300000000c6ULL: s390_format_RXY_RRRD(s390_irgen_LLHH, ovl.fmt.RXY.r1,
13965 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13966 ovl.fmt.RXY.dl2,
13967 ovl.fmt.RXY.dh2); goto ok;
13968 case 0xe300000000c7ULL: s390_format_RXY_RRRD(s390_irgen_STHH, ovl.fmt.RXY.r1,
13969 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13970 ovl.fmt.RXY.dl2,
13971 ovl.fmt.RXY.dh2); goto ok;
13972 case 0xe300000000caULL: s390_format_RXY_RRRD(s390_irgen_LFH, ovl.fmt.RXY.r1,
13973 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13974 ovl.fmt.RXY.dl2,
13975 ovl.fmt.RXY.dh2); goto ok;
13976 case 0xe300000000cbULL: s390_format_RXY_RRRD(s390_irgen_STFH, ovl.fmt.RXY.r1,
13977 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13978 ovl.fmt.RXY.dl2,
13979 ovl.fmt.RXY.dh2); goto ok;
13980 case 0xe300000000cdULL: s390_format_RXY_RRRD(s390_irgen_CHF, ovl.fmt.RXY.r1,
13981 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13982 ovl.fmt.RXY.dl2,
13983 ovl.fmt.RXY.dh2); goto ok;
13984 case 0xe300000000cfULL: s390_format_RXY_RRRD(s390_irgen_CLHF, ovl.fmt.RXY.r1,
13985 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13986 ovl.fmt.RXY.dl2,
13987 ovl.fmt.RXY.dh2); goto ok;
13988 case 0xeb0000000004ULL: s390_format_RSY_RRRD(s390_irgen_LMG, ovl.fmt.RSY.r1,
13989 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13990 ovl.fmt.RSY.dl2,
13991 ovl.fmt.RSY.dh2); goto ok;
13992 case 0xeb000000000aULL: s390_format_RSY_RRRD(s390_irgen_SRAG, ovl.fmt.RSY.r1,
13993 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13994 ovl.fmt.RSY.dl2,
13995 ovl.fmt.RSY.dh2); goto ok;
13996 case 0xeb000000000bULL: s390_format_RSY_RRRD(s390_irgen_SLAG, ovl.fmt.RSY.r1,
13997 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
13998 ovl.fmt.RSY.dl2,
13999 ovl.fmt.RSY.dh2); goto ok;
14000 case 0xeb000000000cULL: s390_format_RSY_RRRD(s390_irgen_SRLG, ovl.fmt.RSY.r1,
14001 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14002 ovl.fmt.RSY.dl2,
14003 ovl.fmt.RSY.dh2); goto ok;
14004 case 0xeb000000000dULL: s390_format_RSY_RRRD(s390_irgen_SLLG, ovl.fmt.RSY.r1,
14005 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14006 ovl.fmt.RSY.dl2,
14007 ovl.fmt.RSY.dh2); goto ok;
14008 case 0xeb000000000fULL: /* TRACG */ goto unimplemented;
14009 case 0xeb0000000014ULL: s390_format_RSY_RRRD(s390_irgen_CSY, ovl.fmt.RSY.r1,
14010 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14011 ovl.fmt.RSY.dl2,
14012 ovl.fmt.RSY.dh2); goto ok;
14013 case 0xeb000000001cULL: s390_format_RSY_RRRD(s390_irgen_RLLG, ovl.fmt.RSY.r1,
14014 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14015 ovl.fmt.RSY.dl2,
14016 ovl.fmt.RSY.dh2); goto ok;
14017 case 0xeb000000001dULL: s390_format_RSY_RRRD(s390_irgen_RLL, ovl.fmt.RSY.r1,
14018 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14019 ovl.fmt.RSY.dl2,
14020 ovl.fmt.RSY.dh2); goto ok;
14021 case 0xeb0000000020ULL: s390_format_RSY_RURD(s390_irgen_CLMH, ovl.fmt.RSY.r1,
14022 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14023 ovl.fmt.RSY.dl2,
14024 ovl.fmt.RSY.dh2); goto ok;
14025 case 0xeb0000000021ULL: s390_format_RSY_RURD(s390_irgen_CLMY, ovl.fmt.RSY.r1,
14026 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14027 ovl.fmt.RSY.dl2,
14028 ovl.fmt.RSY.dh2); goto ok;
14029 case 0xeb0000000024ULL: s390_format_RSY_RRRD(s390_irgen_STMG, ovl.fmt.RSY.r1,
14030 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14031 ovl.fmt.RSY.dl2,
14032 ovl.fmt.RSY.dh2); goto ok;
14033 case 0xeb0000000025ULL: /* STCTG */ goto unimplemented;
14034 case 0xeb0000000026ULL: s390_format_RSY_RRRD(s390_irgen_STMH, 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 0xeb000000002cULL: s390_format_RSY_RURD(s390_irgen_STCMH,
14039 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
14040 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
14041 ovl.fmt.RSY.dh2); goto ok;
14042 case 0xeb000000002dULL: s390_format_RSY_RURD(s390_irgen_STCMY,
14043 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
14044 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
14045 ovl.fmt.RSY.dh2); goto ok;
14046 case 0xeb000000002fULL: /* LCTLG */ goto unimplemented;
14047 case 0xeb0000000030ULL: s390_format_RSY_RRRD(s390_irgen_CSG, ovl.fmt.RSY.r1,
14048 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14049 ovl.fmt.RSY.dl2,
14050 ovl.fmt.RSY.dh2); goto ok;
florian448cbba2012-06-06 02:26:01 +000014051 case 0xeb0000000031ULL: s390_format_RSY_RRRD(s390_irgen_CDSY, 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 0xeb000000003eULL: s390_format_RSY_RRRD(s390_irgen_CDSG, 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;
sewardj2019a972011-03-07 16:04:07 +000014059 case 0xeb0000000044ULL: s390_format_RSY_RRRD(s390_irgen_BXHG, 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 0xeb0000000045ULL: s390_format_RSY_RRRD(s390_irgen_BXLEG,
14064 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
14065 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
14066 ovl.fmt.RSY.dh2); goto ok;
florian8c88cb62012-08-26 18:58:13 +000014067 case 0xeb000000004cULL: s390_format_RSY_RRRD(s390_irgen_ECAG, ovl.fmt.RSY.r1,
14068 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14069 ovl.fmt.RSY.dl2,
14070 ovl.fmt.RSY.dh2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014071 case 0xeb0000000051ULL: s390_format_SIY_URD(s390_irgen_TMY, ovl.fmt.SIY.i2,
14072 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
14073 ovl.fmt.SIY.dh1); goto ok;
14074 case 0xeb0000000052ULL: s390_format_SIY_URD(s390_irgen_MVIY, ovl.fmt.SIY.i2,
14075 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
14076 ovl.fmt.SIY.dh1); goto ok;
14077 case 0xeb0000000054ULL: s390_format_SIY_URD(s390_irgen_NIY, ovl.fmt.SIY.i2,
14078 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
14079 ovl.fmt.SIY.dh1); goto ok;
14080 case 0xeb0000000055ULL: s390_format_SIY_URD(s390_irgen_CLIY, ovl.fmt.SIY.i2,
14081 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
14082 ovl.fmt.SIY.dh1); goto ok;
14083 case 0xeb0000000056ULL: s390_format_SIY_URD(s390_irgen_OIY, ovl.fmt.SIY.i2,
14084 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
14085 ovl.fmt.SIY.dh1); goto ok;
14086 case 0xeb0000000057ULL: s390_format_SIY_URD(s390_irgen_XIY, ovl.fmt.SIY.i2,
14087 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
14088 ovl.fmt.SIY.dh1); goto ok;
14089 case 0xeb000000006aULL: s390_format_SIY_IRD(s390_irgen_ASI, ovl.fmt.SIY.i2,
14090 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
14091 ovl.fmt.SIY.dh1); goto ok;
14092 case 0xeb000000006eULL: s390_format_SIY_IRD(s390_irgen_ALSI, ovl.fmt.SIY.i2,
14093 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
14094 ovl.fmt.SIY.dh1); goto ok;
14095 case 0xeb000000007aULL: s390_format_SIY_IRD(s390_irgen_AGSI, ovl.fmt.SIY.i2,
14096 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
14097 ovl.fmt.SIY.dh1); goto ok;
14098 case 0xeb000000007eULL: s390_format_SIY_IRD(s390_irgen_ALGSI, ovl.fmt.SIY.i2,
14099 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
14100 ovl.fmt.SIY.dh1); goto ok;
14101 case 0xeb0000000080ULL: s390_format_RSY_RURD(s390_irgen_ICMH, ovl.fmt.RSY.r1,
14102 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14103 ovl.fmt.RSY.dl2,
14104 ovl.fmt.RSY.dh2); goto ok;
14105 case 0xeb0000000081ULL: s390_format_RSY_RURD(s390_irgen_ICMY, ovl.fmt.RSY.r1,
14106 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14107 ovl.fmt.RSY.dl2,
14108 ovl.fmt.RSY.dh2); goto ok;
14109 case 0xeb000000008eULL: /* MVCLU */ goto unimplemented;
14110 case 0xeb000000008fULL: /* CLCLU */ goto unimplemented;
14111 case 0xeb0000000090ULL: s390_format_RSY_RRRD(s390_irgen_STMY, 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 0xeb0000000096ULL: s390_format_RSY_RRRD(s390_irgen_LMH, 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 0xeb0000000098ULL: s390_format_RSY_RRRD(s390_irgen_LMY, 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 0xeb000000009aULL: s390_format_RSY_AARD(s390_irgen_LAMY, 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 0xeb000000009bULL: s390_format_RSY_AARD(s390_irgen_STAMY,
14128 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
14129 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
14130 ovl.fmt.RSY.dh2); goto ok;
14131 case 0xeb00000000c0ULL: /* TP */ goto unimplemented;
14132 case 0xeb00000000dcULL: s390_format_RSY_RRRD(s390_irgen_SRAK, ovl.fmt.RSY.r1,
14133 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14134 ovl.fmt.RSY.dl2,
14135 ovl.fmt.RSY.dh2); goto ok;
14136 case 0xeb00000000ddULL: s390_format_RSY_RRRD(s390_irgen_SLAK, ovl.fmt.RSY.r1,
14137 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14138 ovl.fmt.RSY.dl2,
14139 ovl.fmt.RSY.dh2); goto ok;
14140 case 0xeb00000000deULL: s390_format_RSY_RRRD(s390_irgen_SRLK, ovl.fmt.RSY.r1,
14141 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14142 ovl.fmt.RSY.dl2,
14143 ovl.fmt.RSY.dh2); goto ok;
14144 case 0xeb00000000dfULL: s390_format_RSY_RRRD(s390_irgen_SLLK, ovl.fmt.RSY.r1,
14145 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14146 ovl.fmt.RSY.dl2,
14147 ovl.fmt.RSY.dh2); goto ok;
sewardjd7bde722011-04-05 13:19:33 +000014148 case 0xeb00000000e2ULL: s390_format_RSY_RDRM(s390_irgen_LOCG, ovl.fmt.RSY.r1,
14149 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14150 ovl.fmt.RSY.dl2,
14151 ovl.fmt.RSY.dh2,
14152 S390_XMNM_LOCG); goto ok;
14153 case 0xeb00000000e3ULL: s390_format_RSY_RDRM(s390_irgen_STOCG,
14154 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
14155 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
14156 ovl.fmt.RSY.dh2,
14157 S390_XMNM_STOCG); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014158 case 0xeb00000000e4ULL: s390_format_RSY_RRRD(s390_irgen_LANG, ovl.fmt.RSY.r1,
14159 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14160 ovl.fmt.RSY.dl2,
14161 ovl.fmt.RSY.dh2); goto ok;
14162 case 0xeb00000000e6ULL: s390_format_RSY_RRRD(s390_irgen_LAOG, ovl.fmt.RSY.r1,
14163 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14164 ovl.fmt.RSY.dl2,
14165 ovl.fmt.RSY.dh2); goto ok;
14166 case 0xeb00000000e7ULL: s390_format_RSY_RRRD(s390_irgen_LAXG, ovl.fmt.RSY.r1,
14167 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14168 ovl.fmt.RSY.dl2,
14169 ovl.fmt.RSY.dh2); goto ok;
14170 case 0xeb00000000e8ULL: s390_format_RSY_RRRD(s390_irgen_LAAG, ovl.fmt.RSY.r1,
14171 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14172 ovl.fmt.RSY.dl2,
14173 ovl.fmt.RSY.dh2); goto ok;
14174 case 0xeb00000000eaULL: s390_format_RSY_RRRD(s390_irgen_LAALG,
14175 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
14176 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
14177 ovl.fmt.RSY.dh2); goto ok;
sewardjd7bde722011-04-05 13:19:33 +000014178 case 0xeb00000000f2ULL: s390_format_RSY_RDRM(s390_irgen_LOC, ovl.fmt.RSY.r1,
14179 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14180 ovl.fmt.RSY.dl2,
14181 ovl.fmt.RSY.dh2, S390_XMNM_LOC);
14182 goto ok;
14183 case 0xeb00000000f3ULL: s390_format_RSY_RDRM(s390_irgen_STOC, ovl.fmt.RSY.r1,
14184 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14185 ovl.fmt.RSY.dl2,
14186 ovl.fmt.RSY.dh2,
14187 S390_XMNM_STOC); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014188 case 0xeb00000000f4ULL: s390_format_RSY_RRRD(s390_irgen_LAN, ovl.fmt.RSY.r1,
14189 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14190 ovl.fmt.RSY.dl2,
14191 ovl.fmt.RSY.dh2); goto ok;
14192 case 0xeb00000000f6ULL: s390_format_RSY_RRRD(s390_irgen_LAO, ovl.fmt.RSY.r1,
14193 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14194 ovl.fmt.RSY.dl2,
14195 ovl.fmt.RSY.dh2); goto ok;
14196 case 0xeb00000000f7ULL: s390_format_RSY_RRRD(s390_irgen_LAX, ovl.fmt.RSY.r1,
14197 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14198 ovl.fmt.RSY.dl2,
14199 ovl.fmt.RSY.dh2); goto ok;
14200 case 0xeb00000000f8ULL: s390_format_RSY_RRRD(s390_irgen_LAA, ovl.fmt.RSY.r1,
14201 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14202 ovl.fmt.RSY.dl2,
14203 ovl.fmt.RSY.dh2); goto ok;
14204 case 0xeb00000000faULL: s390_format_RSY_RRRD(s390_irgen_LAAL, ovl.fmt.RSY.r1,
14205 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14206 ovl.fmt.RSY.dl2,
14207 ovl.fmt.RSY.dh2); goto ok;
14208 case 0xec0000000044ULL: s390_format_RIE_RRP(s390_irgen_BRXHG, ovl.fmt.RIE.r1,
14209 ovl.fmt.RIE.r3, ovl.fmt.RIE.i2);
14210 goto ok;
14211 case 0xec0000000045ULL: s390_format_RIE_RRP(s390_irgen_BRXLG, ovl.fmt.RIE.r1,
14212 ovl.fmt.RIE.r3, ovl.fmt.RIE.i2);
14213 goto ok;
14214 case 0xec0000000051ULL: /* RISBLG */ goto unimplemented;
14215 case 0xec0000000054ULL: s390_format_RIE_RRUUU(s390_irgen_RNSBG,
14216 ovl.fmt.RIE_RRUUU.r1,
14217 ovl.fmt.RIE_RRUUU.r2,
14218 ovl.fmt.RIE_RRUUU.i3,
14219 ovl.fmt.RIE_RRUUU.i4,
14220 ovl.fmt.RIE_RRUUU.i5);
14221 goto ok;
14222 case 0xec0000000055ULL: s390_format_RIE_RRUUU(s390_irgen_RISBG,
14223 ovl.fmt.RIE_RRUUU.r1,
14224 ovl.fmt.RIE_RRUUU.r2,
14225 ovl.fmt.RIE_RRUUU.i3,
14226 ovl.fmt.RIE_RRUUU.i4,
14227 ovl.fmt.RIE_RRUUU.i5);
14228 goto ok;
14229 case 0xec0000000056ULL: s390_format_RIE_RRUUU(s390_irgen_ROSBG,
14230 ovl.fmt.RIE_RRUUU.r1,
14231 ovl.fmt.RIE_RRUUU.r2,
14232 ovl.fmt.RIE_RRUUU.i3,
14233 ovl.fmt.RIE_RRUUU.i4,
14234 ovl.fmt.RIE_RRUUU.i5);
14235 goto ok;
14236 case 0xec0000000057ULL: s390_format_RIE_RRUUU(s390_irgen_RXSBG,
14237 ovl.fmt.RIE_RRUUU.r1,
14238 ovl.fmt.RIE_RRUUU.r2,
14239 ovl.fmt.RIE_RRUUU.i3,
14240 ovl.fmt.RIE_RRUUU.i4,
14241 ovl.fmt.RIE_RRUUU.i5);
14242 goto ok;
14243 case 0xec000000005dULL: /* RISBHG */ goto unimplemented;
14244 case 0xec0000000064ULL: s390_format_RIE_RRPU(s390_irgen_CGRJ,
14245 ovl.fmt.RIE_RRPU.r1,
14246 ovl.fmt.RIE_RRPU.r2,
14247 ovl.fmt.RIE_RRPU.i4,
14248 ovl.fmt.RIE_RRPU.m3); goto ok;
14249 case 0xec0000000065ULL: s390_format_RIE_RRPU(s390_irgen_CLGRJ,
14250 ovl.fmt.RIE_RRPU.r1,
14251 ovl.fmt.RIE_RRPU.r2,
14252 ovl.fmt.RIE_RRPU.i4,
14253 ovl.fmt.RIE_RRPU.m3); goto ok;
14254 case 0xec0000000070ULL: /* CGIT */ goto unimplemented;
14255 case 0xec0000000071ULL: /* CLGIT */ goto unimplemented;
14256 case 0xec0000000072ULL: /* CIT */ goto unimplemented;
14257 case 0xec0000000073ULL: /* CLFIT */ goto unimplemented;
14258 case 0xec0000000076ULL: s390_format_RIE_RRPU(s390_irgen_CRJ,
14259 ovl.fmt.RIE_RRPU.r1,
14260 ovl.fmt.RIE_RRPU.r2,
14261 ovl.fmt.RIE_RRPU.i4,
14262 ovl.fmt.RIE_RRPU.m3); goto ok;
14263 case 0xec0000000077ULL: s390_format_RIE_RRPU(s390_irgen_CLRJ,
14264 ovl.fmt.RIE_RRPU.r1,
14265 ovl.fmt.RIE_RRPU.r2,
14266 ovl.fmt.RIE_RRPU.i4,
14267 ovl.fmt.RIE_RRPU.m3); goto ok;
14268 case 0xec000000007cULL: s390_format_RIE_RUPI(s390_irgen_CGIJ,
14269 ovl.fmt.RIEv3.r1,
14270 ovl.fmt.RIEv3.m3,
14271 ovl.fmt.RIEv3.i4,
14272 ovl.fmt.RIEv3.i2); goto ok;
14273 case 0xec000000007dULL: s390_format_RIE_RUPU(s390_irgen_CLGIJ,
14274 ovl.fmt.RIEv3.r1,
14275 ovl.fmt.RIEv3.m3,
14276 ovl.fmt.RIEv3.i4,
14277 ovl.fmt.RIEv3.i2); goto ok;
14278 case 0xec000000007eULL: s390_format_RIE_RUPI(s390_irgen_CIJ,
14279 ovl.fmt.RIEv3.r1,
14280 ovl.fmt.RIEv3.m3,
14281 ovl.fmt.RIEv3.i4,
14282 ovl.fmt.RIEv3.i2); goto ok;
14283 case 0xec000000007fULL: s390_format_RIE_RUPU(s390_irgen_CLIJ,
14284 ovl.fmt.RIEv3.r1,
14285 ovl.fmt.RIEv3.m3,
14286 ovl.fmt.RIEv3.i4,
14287 ovl.fmt.RIEv3.i2); goto ok;
14288 case 0xec00000000d8ULL: s390_format_RIE_RRI0(s390_irgen_AHIK, ovl.fmt.RIE.r1,
14289 ovl.fmt.RIE.r3, ovl.fmt.RIE.i2);
14290 goto ok;
14291 case 0xec00000000d9ULL: s390_format_RIE_RRI0(s390_irgen_AGHIK,
14292 ovl.fmt.RIE.r1, ovl.fmt.RIE.r3,
14293 ovl.fmt.RIE.i2); goto ok;
14294 case 0xec00000000daULL: s390_format_RIE_RRI0(s390_irgen_ALHSIK,
14295 ovl.fmt.RIE.r1, ovl.fmt.RIE.r3,
14296 ovl.fmt.RIE.i2); goto ok;
14297 case 0xec00000000dbULL: s390_format_RIE_RRI0(s390_irgen_ALGHSIK,
14298 ovl.fmt.RIE.r1, ovl.fmt.RIE.r3,
14299 ovl.fmt.RIE.i2); goto ok;
14300 case 0xec00000000e4ULL: s390_format_RRS(s390_irgen_CGRB, ovl.fmt.RRS.r1,
14301 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
14302 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
14303 goto ok;
14304 case 0xec00000000e5ULL: s390_format_RRS(s390_irgen_CLGRB, ovl.fmt.RRS.r1,
14305 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
14306 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
14307 goto ok;
14308 case 0xec00000000f6ULL: s390_format_RRS(s390_irgen_CRB, ovl.fmt.RRS.r1,
14309 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
14310 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
14311 goto ok;
14312 case 0xec00000000f7ULL: s390_format_RRS(s390_irgen_CLRB, ovl.fmt.RRS.r1,
14313 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
14314 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
14315 goto ok;
14316 case 0xec00000000fcULL: s390_format_RIS_RURDI(s390_irgen_CGIB,
14317 ovl.fmt.RIS.r1, ovl.fmt.RIS.m3,
14318 ovl.fmt.RIS.b4, ovl.fmt.RIS.d4,
14319 ovl.fmt.RIS.i2); goto ok;
14320 case 0xec00000000fdULL: s390_format_RIS_RURDU(s390_irgen_CLGIB,
14321 ovl.fmt.RIS.r1, ovl.fmt.RIS.m3,
14322 ovl.fmt.RIS.b4, ovl.fmt.RIS.d4,
14323 ovl.fmt.RIS.i2); goto ok;
14324 case 0xec00000000feULL: s390_format_RIS_RURDI(s390_irgen_CIB, ovl.fmt.RIS.r1,
14325 ovl.fmt.RIS.m3, ovl.fmt.RIS.b4,
14326 ovl.fmt.RIS.d4,
14327 ovl.fmt.RIS.i2); goto ok;
14328 case 0xec00000000ffULL: s390_format_RIS_RURDU(s390_irgen_CLIB,
14329 ovl.fmt.RIS.r1, ovl.fmt.RIS.m3,
14330 ovl.fmt.RIS.b4, ovl.fmt.RIS.d4,
14331 ovl.fmt.RIS.i2); goto ok;
14332 case 0xed0000000004ULL: s390_format_RXE_FRRD(s390_irgen_LDEB, ovl.fmt.RXE.r1,
14333 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14334 ovl.fmt.RXE.d2); goto ok;
14335 case 0xed0000000005ULL: s390_format_RXE_FRRD(s390_irgen_LXDB, ovl.fmt.RXE.r1,
14336 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14337 ovl.fmt.RXE.d2); goto ok;
14338 case 0xed0000000006ULL: s390_format_RXE_FRRD(s390_irgen_LXEB, ovl.fmt.RXE.r1,
14339 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14340 ovl.fmt.RXE.d2); goto ok;
14341 case 0xed0000000007ULL: /* MXDB */ goto unimplemented;
14342 case 0xed0000000008ULL: /* KEB */ goto unimplemented;
14343 case 0xed0000000009ULL: s390_format_RXE_FRRD(s390_irgen_CEB, ovl.fmt.RXE.r1,
14344 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14345 ovl.fmt.RXE.d2); goto ok;
14346 case 0xed000000000aULL: s390_format_RXE_FRRD(s390_irgen_AEB, ovl.fmt.RXE.r1,
14347 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14348 ovl.fmt.RXE.d2); goto ok;
14349 case 0xed000000000bULL: s390_format_RXE_FRRD(s390_irgen_SEB, ovl.fmt.RXE.r1,
14350 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14351 ovl.fmt.RXE.d2); goto ok;
14352 case 0xed000000000cULL: /* MDEB */ goto unimplemented;
14353 case 0xed000000000dULL: s390_format_RXE_FRRD(s390_irgen_DEB, ovl.fmt.RXE.r1,
14354 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14355 ovl.fmt.RXE.d2); goto ok;
14356 case 0xed000000000eULL: s390_format_RXF_FRRDF(s390_irgen_MAEB,
14357 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
14358 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
14359 ovl.fmt.RXF.r1); goto ok;
14360 case 0xed000000000fULL: s390_format_RXF_FRRDF(s390_irgen_MSEB,
14361 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
14362 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
14363 ovl.fmt.RXF.r1); goto ok;
14364 case 0xed0000000010ULL: s390_format_RXE_FRRD(s390_irgen_TCEB, ovl.fmt.RXE.r1,
14365 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14366 ovl.fmt.RXE.d2); goto ok;
14367 case 0xed0000000011ULL: s390_format_RXE_FRRD(s390_irgen_TCDB, ovl.fmt.RXE.r1,
14368 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14369 ovl.fmt.RXE.d2); goto ok;
14370 case 0xed0000000012ULL: s390_format_RXE_FRRD(s390_irgen_TCXB, ovl.fmt.RXE.r1,
14371 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14372 ovl.fmt.RXE.d2); goto ok;
14373 case 0xed0000000014ULL: s390_format_RXE_FRRD(s390_irgen_SQEB, ovl.fmt.RXE.r1,
14374 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14375 ovl.fmt.RXE.d2); goto ok;
14376 case 0xed0000000015ULL: s390_format_RXE_FRRD(s390_irgen_SQDB, ovl.fmt.RXE.r1,
14377 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14378 ovl.fmt.RXE.d2); goto ok;
14379 case 0xed0000000017ULL: s390_format_RXE_FRRD(s390_irgen_MEEB, ovl.fmt.RXE.r1,
14380 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14381 ovl.fmt.RXE.d2); goto ok;
14382 case 0xed0000000018ULL: /* KDB */ goto unimplemented;
14383 case 0xed0000000019ULL: s390_format_RXE_FRRD(s390_irgen_CDB, ovl.fmt.RXE.r1,
14384 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14385 ovl.fmt.RXE.d2); goto ok;
14386 case 0xed000000001aULL: s390_format_RXE_FRRD(s390_irgen_ADB, ovl.fmt.RXE.r1,
14387 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14388 ovl.fmt.RXE.d2); goto ok;
14389 case 0xed000000001bULL: s390_format_RXE_FRRD(s390_irgen_SDB, ovl.fmt.RXE.r1,
14390 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14391 ovl.fmt.RXE.d2); goto ok;
14392 case 0xed000000001cULL: s390_format_RXE_FRRD(s390_irgen_MDB, ovl.fmt.RXE.r1,
14393 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14394 ovl.fmt.RXE.d2); goto ok;
14395 case 0xed000000001dULL: s390_format_RXE_FRRD(s390_irgen_DDB, ovl.fmt.RXE.r1,
14396 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14397 ovl.fmt.RXE.d2); goto ok;
14398 case 0xed000000001eULL: s390_format_RXF_FRRDF(s390_irgen_MADB,
14399 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
14400 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
14401 ovl.fmt.RXF.r1); goto ok;
14402 case 0xed000000001fULL: s390_format_RXF_FRRDF(s390_irgen_MSDB,
14403 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
14404 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
14405 ovl.fmt.RXF.r1); goto ok;
14406 case 0xed0000000024ULL: /* LDE */ goto unimplemented;
14407 case 0xed0000000025ULL: /* LXD */ goto unimplemented;
14408 case 0xed0000000026ULL: /* LXE */ goto unimplemented;
14409 case 0xed000000002eULL: /* MAE */ goto unimplemented;
14410 case 0xed000000002fULL: /* MSE */ goto unimplemented;
14411 case 0xed0000000034ULL: /* SQE */ goto unimplemented;
14412 case 0xed0000000035ULL: /* SQD */ goto unimplemented;
14413 case 0xed0000000037ULL: /* MEE */ goto unimplemented;
14414 case 0xed0000000038ULL: /* MAYL */ goto unimplemented;
14415 case 0xed0000000039ULL: /* MYL */ goto unimplemented;
14416 case 0xed000000003aULL: /* MAY */ goto unimplemented;
14417 case 0xed000000003bULL: /* MY */ goto unimplemented;
14418 case 0xed000000003cULL: /* MAYH */ goto unimplemented;
14419 case 0xed000000003dULL: /* MYH */ goto unimplemented;
14420 case 0xed000000003eULL: /* MAD */ goto unimplemented;
14421 case 0xed000000003fULL: /* MSD */ goto unimplemented;
14422 case 0xed0000000040ULL: /* SLDT */ goto unimplemented;
14423 case 0xed0000000041ULL: /* SRDT */ goto unimplemented;
14424 case 0xed0000000048ULL: /* SLXT */ goto unimplemented;
14425 case 0xed0000000049ULL: /* SRXT */ goto unimplemented;
14426 case 0xed0000000050ULL: /* TDCET */ goto unimplemented;
14427 case 0xed0000000051ULL: /* TDGET */ goto unimplemented;
14428 case 0xed0000000054ULL: /* TDCDT */ goto unimplemented;
14429 case 0xed0000000055ULL: /* TDGDT */ goto unimplemented;
14430 case 0xed0000000058ULL: /* TDCXT */ goto unimplemented;
14431 case 0xed0000000059ULL: /* TDGXT */ goto unimplemented;
14432 case 0xed0000000064ULL: s390_format_RXY_FRRD(s390_irgen_LEY, ovl.fmt.RXY.r1,
14433 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14434 ovl.fmt.RXY.dl2,
14435 ovl.fmt.RXY.dh2); goto ok;
14436 case 0xed0000000065ULL: s390_format_RXY_FRRD(s390_irgen_LDY, ovl.fmt.RXY.r1,
14437 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14438 ovl.fmt.RXY.dl2,
14439 ovl.fmt.RXY.dh2); goto ok;
14440 case 0xed0000000066ULL: s390_format_RXY_FRRD(s390_irgen_STEY, ovl.fmt.RXY.r1,
14441 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14442 ovl.fmt.RXY.dl2,
14443 ovl.fmt.RXY.dh2); goto ok;
14444 case 0xed0000000067ULL: s390_format_RXY_FRRD(s390_irgen_STDY, ovl.fmt.RXY.r1,
14445 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14446 ovl.fmt.RXY.dl2,
14447 ovl.fmt.RXY.dh2); goto ok;
14448 }
14449
14450 switch (((ovl.value >> 16) & 0xff0f00000000ULL) >> 32) {
14451 case 0xc000ULL: s390_format_RIL_RP(s390_irgen_LARL, ovl.fmt.RIL.r1,
14452 ovl.fmt.RIL.i2); goto ok;
14453 case 0xc001ULL: s390_format_RIL_RI(s390_irgen_LGFI, ovl.fmt.RIL.r1,
14454 ovl.fmt.RIL.i2); goto ok;
14455 case 0xc004ULL: s390_format_RIL(s390_irgen_BRCL, ovl.fmt.RIL.r1,
14456 ovl.fmt.RIL.i2); goto ok;
14457 case 0xc005ULL: s390_format_RIL_RP(s390_irgen_BRASL, ovl.fmt.RIL.r1,
14458 ovl.fmt.RIL.i2); goto ok;
14459 case 0xc006ULL: s390_format_RIL_RU(s390_irgen_XIHF, ovl.fmt.RIL.r1,
14460 ovl.fmt.RIL.i2); goto ok;
14461 case 0xc007ULL: s390_format_RIL_RU(s390_irgen_XILF, ovl.fmt.RIL.r1,
14462 ovl.fmt.RIL.i2); goto ok;
14463 case 0xc008ULL: s390_format_RIL_RU(s390_irgen_IIHF, ovl.fmt.RIL.r1,
14464 ovl.fmt.RIL.i2); goto ok;
14465 case 0xc009ULL: s390_format_RIL_RU(s390_irgen_IILF, ovl.fmt.RIL.r1,
14466 ovl.fmt.RIL.i2); goto ok;
14467 case 0xc00aULL: s390_format_RIL_RU(s390_irgen_NIHF, ovl.fmt.RIL.r1,
14468 ovl.fmt.RIL.i2); goto ok;
14469 case 0xc00bULL: s390_format_RIL_RU(s390_irgen_NILF, ovl.fmt.RIL.r1,
14470 ovl.fmt.RIL.i2); goto ok;
14471 case 0xc00cULL: s390_format_RIL_RU(s390_irgen_OIHF, ovl.fmt.RIL.r1,
14472 ovl.fmt.RIL.i2); goto ok;
14473 case 0xc00dULL: s390_format_RIL_RU(s390_irgen_OILF, ovl.fmt.RIL.r1,
14474 ovl.fmt.RIL.i2); goto ok;
14475 case 0xc00eULL: s390_format_RIL_RU(s390_irgen_LLIHF, ovl.fmt.RIL.r1,
14476 ovl.fmt.RIL.i2); goto ok;
14477 case 0xc00fULL: s390_format_RIL_RU(s390_irgen_LLILF, ovl.fmt.RIL.r1,
14478 ovl.fmt.RIL.i2); goto ok;
14479 case 0xc200ULL: s390_format_RIL_RI(s390_irgen_MSGFI, ovl.fmt.RIL.r1,
14480 ovl.fmt.RIL.i2); goto ok;
14481 case 0xc201ULL: s390_format_RIL_RI(s390_irgen_MSFI, ovl.fmt.RIL.r1,
14482 ovl.fmt.RIL.i2); goto ok;
14483 case 0xc204ULL: s390_format_RIL_RU(s390_irgen_SLGFI, ovl.fmt.RIL.r1,
14484 ovl.fmt.RIL.i2); goto ok;
14485 case 0xc205ULL: s390_format_RIL_RU(s390_irgen_SLFI, ovl.fmt.RIL.r1,
14486 ovl.fmt.RIL.i2); goto ok;
14487 case 0xc208ULL: s390_format_RIL_RI(s390_irgen_AGFI, ovl.fmt.RIL.r1,
14488 ovl.fmt.RIL.i2); goto ok;
14489 case 0xc209ULL: s390_format_RIL_RI(s390_irgen_AFI, ovl.fmt.RIL.r1,
14490 ovl.fmt.RIL.i2); goto ok;
14491 case 0xc20aULL: s390_format_RIL_RU(s390_irgen_ALGFI, ovl.fmt.RIL.r1,
14492 ovl.fmt.RIL.i2); goto ok;
14493 case 0xc20bULL: s390_format_RIL_RU(s390_irgen_ALFI, ovl.fmt.RIL.r1,
14494 ovl.fmt.RIL.i2); goto ok;
14495 case 0xc20cULL: s390_format_RIL_RI(s390_irgen_CGFI, ovl.fmt.RIL.r1,
14496 ovl.fmt.RIL.i2); goto ok;
14497 case 0xc20dULL: s390_format_RIL_RI(s390_irgen_CFI, ovl.fmt.RIL.r1,
14498 ovl.fmt.RIL.i2); goto ok;
14499 case 0xc20eULL: s390_format_RIL_RU(s390_irgen_CLGFI, ovl.fmt.RIL.r1,
14500 ovl.fmt.RIL.i2); goto ok;
14501 case 0xc20fULL: s390_format_RIL_RU(s390_irgen_CLFI, ovl.fmt.RIL.r1,
14502 ovl.fmt.RIL.i2); goto ok;
14503 case 0xc402ULL: s390_format_RIL_RP(s390_irgen_LLHRL, ovl.fmt.RIL.r1,
14504 ovl.fmt.RIL.i2); goto ok;
14505 case 0xc404ULL: s390_format_RIL_RP(s390_irgen_LGHRL, ovl.fmt.RIL.r1,
14506 ovl.fmt.RIL.i2); goto ok;
14507 case 0xc405ULL: s390_format_RIL_RP(s390_irgen_LHRL, ovl.fmt.RIL.r1,
14508 ovl.fmt.RIL.i2); goto ok;
14509 case 0xc406ULL: s390_format_RIL_RP(s390_irgen_LLGHRL, ovl.fmt.RIL.r1,
14510 ovl.fmt.RIL.i2); goto ok;
14511 case 0xc407ULL: s390_format_RIL_RP(s390_irgen_STHRL, ovl.fmt.RIL.r1,
14512 ovl.fmt.RIL.i2); goto ok;
14513 case 0xc408ULL: s390_format_RIL_RP(s390_irgen_LGRL, ovl.fmt.RIL.r1,
14514 ovl.fmt.RIL.i2); goto ok;
14515 case 0xc40bULL: s390_format_RIL_RP(s390_irgen_STGRL, ovl.fmt.RIL.r1,
14516 ovl.fmt.RIL.i2); goto ok;
14517 case 0xc40cULL: s390_format_RIL_RP(s390_irgen_LGFRL, ovl.fmt.RIL.r1,
14518 ovl.fmt.RIL.i2); goto ok;
14519 case 0xc40dULL: s390_format_RIL_RP(s390_irgen_LRL, ovl.fmt.RIL.r1,
14520 ovl.fmt.RIL.i2); goto ok;
14521 case 0xc40eULL: s390_format_RIL_RP(s390_irgen_LLGFRL, ovl.fmt.RIL.r1,
14522 ovl.fmt.RIL.i2); goto ok;
14523 case 0xc40fULL: s390_format_RIL_RP(s390_irgen_STRL, ovl.fmt.RIL.r1,
14524 ovl.fmt.RIL.i2); goto ok;
14525 case 0xc600ULL: s390_format_RIL_RP(s390_irgen_EXRL, ovl.fmt.RIL.r1,
14526 ovl.fmt.RIL.i2); goto ok;
14527 case 0xc602ULL: s390_format_RIL_UP(s390_irgen_PFDRL, ovl.fmt.RIL.r1,
14528 ovl.fmt.RIL.i2); goto ok;
14529 case 0xc604ULL: s390_format_RIL_RP(s390_irgen_CGHRL, ovl.fmt.RIL.r1,
14530 ovl.fmt.RIL.i2); goto ok;
14531 case 0xc605ULL: s390_format_RIL_RP(s390_irgen_CHRL, ovl.fmt.RIL.r1,
14532 ovl.fmt.RIL.i2); goto ok;
14533 case 0xc606ULL: s390_format_RIL_RP(s390_irgen_CLGHRL, ovl.fmt.RIL.r1,
14534 ovl.fmt.RIL.i2); goto ok;
14535 case 0xc607ULL: s390_format_RIL_RP(s390_irgen_CLHRL, ovl.fmt.RIL.r1,
14536 ovl.fmt.RIL.i2); goto ok;
14537 case 0xc608ULL: s390_format_RIL_RP(s390_irgen_CGRL, ovl.fmt.RIL.r1,
14538 ovl.fmt.RIL.i2); goto ok;
14539 case 0xc60aULL: s390_format_RIL_RP(s390_irgen_CLGRL, ovl.fmt.RIL.r1,
14540 ovl.fmt.RIL.i2); goto ok;
14541 case 0xc60cULL: s390_format_RIL_RP(s390_irgen_CGFRL, ovl.fmt.RIL.r1,
14542 ovl.fmt.RIL.i2); goto ok;
14543 case 0xc60dULL: s390_format_RIL_RP(s390_irgen_CRL, ovl.fmt.RIL.r1,
14544 ovl.fmt.RIL.i2); goto ok;
14545 case 0xc60eULL: s390_format_RIL_RP(s390_irgen_CLGFRL, ovl.fmt.RIL.r1,
14546 ovl.fmt.RIL.i2); goto ok;
14547 case 0xc60fULL: s390_format_RIL_RP(s390_irgen_CLRL, ovl.fmt.RIL.r1,
14548 ovl.fmt.RIL.i2); goto ok;
14549 case 0xc800ULL: /* MVCOS */ goto unimplemented;
14550 case 0xc801ULL: /* ECTG */ goto unimplemented;
14551 case 0xc802ULL: /* CSST */ goto unimplemented;
14552 case 0xc804ULL: /* LPD */ goto unimplemented;
14553 case 0xc805ULL: /* LPDG */ goto unimplemented;
14554 case 0xcc06ULL: /* BRCTH */ goto unimplemented;
14555 case 0xcc08ULL: s390_format_RIL_RI(s390_irgen_AIH, ovl.fmt.RIL.r1,
14556 ovl.fmt.RIL.i2); goto ok;
14557 case 0xcc0aULL: s390_format_RIL_RI(s390_irgen_ALSIH, ovl.fmt.RIL.r1,
14558 ovl.fmt.RIL.i2); goto ok;
14559 case 0xcc0bULL: s390_format_RIL_RI(s390_irgen_ALSIHN, ovl.fmt.RIL.r1,
14560 ovl.fmt.RIL.i2); goto ok;
14561 case 0xcc0dULL: s390_format_RIL_RI(s390_irgen_CIH, ovl.fmt.RIL.r1,
14562 ovl.fmt.RIL.i2); goto ok;
14563 case 0xcc0fULL: s390_format_RIL_RU(s390_irgen_CLIH, ovl.fmt.RIL.r1,
14564 ovl.fmt.RIL.i2); goto ok;
14565 }
14566
14567 switch (((ovl.value >> 16) & 0xff0000000000ULL) >> 40) {
14568 case 0xd0ULL: /* TRTR */ goto unimplemented;
14569 case 0xd1ULL: /* MVN */ goto unimplemented;
14570 case 0xd2ULL: s390_format_SS_L0RDRD(s390_irgen_MVC, ovl.fmt.SS.l,
14571 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
14572 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
14573 case 0xd3ULL: /* MVZ */ goto unimplemented;
14574 case 0xd4ULL: s390_format_SS_L0RDRD(s390_irgen_NC, ovl.fmt.SS.l,
14575 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
14576 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
14577 case 0xd5ULL: s390_format_SS_L0RDRD(s390_irgen_CLC, ovl.fmt.SS.l,
14578 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
14579 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
14580 case 0xd6ULL: s390_format_SS_L0RDRD(s390_irgen_OC, ovl.fmt.SS.l,
14581 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
14582 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
sewardjb63967e2011-03-24 08:50:04 +000014583 case 0xd7ULL:
14584 if (ovl.fmt.SS.b1 == ovl.fmt.SS.b2 && ovl.fmt.SS.d1 == ovl.fmt.SS.d2)
14585 s390_irgen_XC_sameloc(ovl.fmt.SS.l, ovl.fmt.SS.b1, ovl.fmt.SS.d1);
14586 else
14587 s390_format_SS_L0RDRD(s390_irgen_XC, ovl.fmt.SS.l,
14588 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
14589 ovl.fmt.SS.b2, ovl.fmt.SS.d2);
14590 goto ok;
sewardj2019a972011-03-07 16:04:07 +000014591 case 0xd9ULL: /* MVCK */ goto unimplemented;
14592 case 0xdaULL: /* MVCP */ goto unimplemented;
14593 case 0xdbULL: /* MVCS */ goto unimplemented;
florian730448f2012-02-04 17:07:07 +000014594 case 0xdcULL: s390_format_SS_L0RDRD(s390_irgen_TR, ovl.fmt.SS.l,
14595 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
14596 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014597 case 0xddULL: /* TRT */ goto unimplemented;
14598 case 0xdeULL: /* ED */ goto unimplemented;
14599 case 0xdfULL: /* EDMK */ goto unimplemented;
14600 case 0xe1ULL: /* PKU */ goto unimplemented;
14601 case 0xe2ULL: /* UNPKU */ goto unimplemented;
14602 case 0xe8ULL: /* MVCIN */ goto unimplemented;
14603 case 0xe9ULL: /* PKA */ goto unimplemented;
14604 case 0xeaULL: /* UNPKA */ goto unimplemented;
14605 case 0xeeULL: /* PLO */ goto unimplemented;
14606 case 0xefULL: /* LMD */ goto unimplemented;
14607 case 0xf0ULL: /* SRP */ goto unimplemented;
14608 case 0xf1ULL: /* MVO */ goto unimplemented;
14609 case 0xf2ULL: /* PACK */ goto unimplemented;
14610 case 0xf3ULL: /* UNPK */ goto unimplemented;
14611 case 0xf8ULL: /* ZAP */ goto unimplemented;
14612 case 0xf9ULL: /* CP */ goto unimplemented;
14613 case 0xfaULL: /* AP */ goto unimplemented;
14614 case 0xfbULL: /* SP */ goto unimplemented;
14615 case 0xfcULL: /* MP */ goto unimplemented;
14616 case 0xfdULL: /* DP */ goto unimplemented;
14617 }
14618
14619 switch (((ovl.value >> 16) & 0xffff00000000ULL) >> 32) {
14620 case 0xe500ULL: /* LASP */ goto unimplemented;
14621 case 0xe501ULL: /* TPROT */ goto unimplemented;
14622 case 0xe502ULL: /* STRAG */ goto unimplemented;
14623 case 0xe50eULL: /* MVCSK */ goto unimplemented;
14624 case 0xe50fULL: /* MVCDK */ goto unimplemented;
14625 case 0xe544ULL: s390_format_SIL_RDI(s390_irgen_MVHHI, ovl.fmt.SIL.b1,
14626 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14627 goto ok;
14628 case 0xe548ULL: s390_format_SIL_RDI(s390_irgen_MVGHI, ovl.fmt.SIL.b1,
14629 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14630 goto ok;
14631 case 0xe54cULL: s390_format_SIL_RDI(s390_irgen_MVHI, ovl.fmt.SIL.b1,
14632 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14633 goto ok;
14634 case 0xe554ULL: s390_format_SIL_RDI(s390_irgen_CHHSI, ovl.fmt.SIL.b1,
14635 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14636 goto ok;
14637 case 0xe555ULL: s390_format_SIL_RDU(s390_irgen_CLHHSI, ovl.fmt.SIL.b1,
14638 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14639 goto ok;
14640 case 0xe558ULL: s390_format_SIL_RDI(s390_irgen_CGHSI, ovl.fmt.SIL.b1,
14641 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14642 goto ok;
14643 case 0xe559ULL: s390_format_SIL_RDU(s390_irgen_CLGHSI, ovl.fmt.SIL.b1,
14644 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14645 goto ok;
14646 case 0xe55cULL: s390_format_SIL_RDI(s390_irgen_CHSI, ovl.fmt.SIL.b1,
14647 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14648 goto ok;
14649 case 0xe55dULL: s390_format_SIL_RDU(s390_irgen_CLFHSI, ovl.fmt.SIL.b1,
14650 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14651 goto ok;
14652 }
14653
14654 return S390_DECODE_UNKNOWN_INSN;
14655
14656ok:
14657 return S390_DECODE_OK;
14658
14659unimplemented:
14660 return S390_DECODE_UNIMPLEMENTED_INSN;
14661}
14662
14663/* Handle "special" instructions. */
14664static s390_decode_t
14665s390_decode_special_and_irgen(UChar *bytes)
14666{
14667 s390_decode_t status = S390_DECODE_OK;
14668
14669 /* Got a "Special" instruction preamble. Which one is it? */
14670 if (bytes[0] == 0x18 && bytes[1] == 0x22 /* lr %r2, %r2 */) {
14671 s390_irgen_client_request();
14672 } else if (bytes[0] == 0x18 && bytes[1] == 0x33 /* lr %r3, %r3 */) {
14673 s390_irgen_guest_NRADDR();
14674 } else if (bytes[0] == 0x18 && bytes[1] == 0x44 /* lr %r4, %r4 */) {
14675 s390_irgen_call_noredir();
florian2245ce92012-08-28 16:49:30 +000014676 } else if (bytes[0] == 0x18 && bytes[1] == 0x55 /* lr %r5, %r5 */) {
14677 vex_inject_ir(irsb, Iend_BE);
14678
14679 /* Invalidate the current insn. The reason is that the IRop we're
14680 injecting here can change. In which case the translation has to
14681 be redone. For ease of handling, we simply invalidate all the
14682 time. */
14683 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TISTART),
14684 mkU64(guest_IA_curr_instr)));
14685 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TILEN),
14686 mkU64(guest_IA_next_instr - guest_IA_curr_instr)));
14687 vassert(guest_IA_next_instr - guest_IA_curr_instr ==
14688 S390_SPECIAL_OP_PREAMBLE_SIZE + S390_SPECIAL_OP_SIZE);
14689
14690 put_IA(mkaddr_expr(guest_IA_next_instr));
14691 dis_res->whatNext = Dis_StopHere;
14692 dis_res->jk_StopHere = Ijk_TInval;
sewardj2019a972011-03-07 16:04:07 +000014693 } else {
14694 /* We don't know what it is. */
14695 return S390_DECODE_UNKNOWN_SPECIAL_INSN;
14696 }
14697
14698 dis_res->len = S390_SPECIAL_OP_PREAMBLE_SIZE + S390_SPECIAL_OP_SIZE;
14699
14700 return status;
14701}
14702
14703
14704/* Function returns # bytes that were decoded or 0 in case of failure */
florianb4df7682011-07-05 02:09:01 +000014705static UInt
sewardj2019a972011-03-07 16:04:07 +000014706s390_decode_and_irgen(UChar *bytes, UInt insn_length, DisResult *dres)
14707{
14708 s390_decode_t status;
14709
14710 dis_res = dres;
14711
14712 /* Spot the 8-byte preamble: 18ff lr r15,r15
14713 1811 lr r1,r1
14714 1822 lr r2,r2
14715 1833 lr r3,r3 */
14716 if (bytes[ 0] == 0x18 && bytes[ 1] == 0xff && bytes[ 2] == 0x18 &&
14717 bytes[ 3] == 0x11 && bytes[ 4] == 0x18 && bytes[ 5] == 0x22 &&
14718 bytes[ 6] == 0x18 && bytes[ 7] == 0x33) {
14719
14720 /* Handle special instruction that follows that preamble. */
14721 if (0) vex_printf("special function handling...\n");
florian2c8ed942011-08-01 22:07:51 +000014722
14723 insn_length = S390_SPECIAL_OP_PREAMBLE_SIZE + S390_SPECIAL_OP_SIZE;
14724 guest_IA_next_instr = guest_IA_curr_instr + insn_length;
14725
14726 status =
14727 s390_decode_special_and_irgen(bytes + S390_SPECIAL_OP_PREAMBLE_SIZE);
sewardj2019a972011-03-07 16:04:07 +000014728 } else {
14729 /* Handle normal instructions. */
14730 switch (insn_length) {
14731 case 2:
14732 status = s390_decode_2byte_and_irgen(bytes);
14733 break;
14734
14735 case 4:
14736 status = s390_decode_4byte_and_irgen(bytes);
14737 break;
14738
14739 case 6:
14740 status = s390_decode_6byte_and_irgen(bytes);
14741 break;
14742
14743 default:
14744 status = S390_DECODE_ERROR;
14745 break;
14746 }
14747 }
florian5fcbba22011-07-27 20:40:22 +000014748 /* If next instruction is execute, stop here */
florianf9e1ed72012-04-17 02:41:56 +000014749 if (dis_res->whatNext == Dis_Continue && bytes[insn_length] == 0x44) {
14750 put_IA(mkaddr_expr(guest_IA_next_instr));
sewardj2019a972011-03-07 16:04:07 +000014751 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +000014752 dis_res->jk_StopHere = Ijk_Boring;
sewardj2019a972011-03-07 16:04:07 +000014753 }
14754
14755 if (status == S390_DECODE_OK) return insn_length; /* OK */
14756
14757 /* Decoding failed somehow */
14758 vex_printf("vex s390->IR: ");
14759 switch (status) {
14760 case S390_DECODE_UNKNOWN_INSN:
14761 vex_printf("unknown insn: ");
14762 break;
14763
14764 case S390_DECODE_UNIMPLEMENTED_INSN:
14765 vex_printf("unimplemented insn: ");
14766 break;
14767
14768 case S390_DECODE_UNKNOWN_SPECIAL_INSN:
14769 vex_printf("unimplemented special insn: ");
14770 break;
14771
14772 default:
14773 case S390_DECODE_ERROR:
14774 vex_printf("decoding error: ");
14775 break;
14776 }
14777
14778 vex_printf("%02x%02x", bytes[0], bytes[1]);
14779 if (insn_length > 2) {
14780 vex_printf(" %02x%02x", bytes[2], bytes[3]);
14781 }
14782 if (insn_length > 4) {
14783 vex_printf(" %02x%02x", bytes[4], bytes[5]);
14784 }
14785 vex_printf("\n");
14786
14787 return 0; /* Failed */
14788}
14789
14790
sewardj2019a972011-03-07 16:04:07 +000014791/* Disassemble a single instruction INSN into IR. */
14792static DisResult
florian420c5012011-07-22 02:12:28 +000014793disInstr_S390_WRK(UChar *insn)
sewardj2019a972011-03-07 16:04:07 +000014794{
14795 UChar byte;
14796 UInt insn_length;
14797 DisResult dres;
14798
14799 /* ---------------------------------------------------- */
14800 /* --- Compute instruction length -- */
14801 /* ---------------------------------------------------- */
14802
14803 /* Get the first byte of the insn. */
14804 byte = insn[0];
14805
14806 /* The leftmost two bits (0:1) encode the length of the insn in bytes.
14807 00 -> 2 bytes, 01 -> 4 bytes, 10 -> 4 bytes, 11 -> 6 bytes. */
14808 insn_length = ((((byte >> 6) + 1) >> 1) + 1) << 1;
14809
14810 guest_IA_next_instr = guest_IA_curr_instr + insn_length;
14811
14812 /* ---------------------------------------------------- */
14813 /* --- Initialise the DisResult data -- */
14814 /* ---------------------------------------------------- */
14815 dres.whatNext = Dis_Continue;
14816 dres.len = insn_length;
14817 dres.continueAt = 0;
florian8844a632012-04-13 04:04:06 +000014818 dres.jk_StopHere = Ijk_INVALID;
sewardj2019a972011-03-07 16:04:07 +000014819
floriana99f20e2011-07-17 14:16:41 +000014820 /* fixs390: consider chasing of conditional jumps */
14821
sewardj2019a972011-03-07 16:04:07 +000014822 /* Normal and special instruction handling starts here. */
14823 if (s390_decode_and_irgen(insn, insn_length, &dres) == 0) {
14824 /* All decode failures end up here. The decoder has already issued an
14825 error message.
14826 Tell the dispatcher that this insn cannot be decoded, and so has
florian342e01a2012-07-26 02:37:49 +000014827 not been executed, and (is currently) the next to be executed.
14828 The insn address in the guest state needs to be set to
14829 guest_IA_curr_instr, otherwise the complaint will report an
14830 incorrect address. */
14831 put_IA(mkaddr_expr(guest_IA_curr_instr));
sewardj2019a972011-03-07 16:04:07 +000014832
florian8844a632012-04-13 04:04:06 +000014833 dres.whatNext = Dis_StopHere;
14834 dres.jk_StopHere = Ijk_NoDecode;
14835 dres.continueAt = 0;
14836 dres.len = 0;
14837 } else {
14838 /* Decode success */
14839 switch (dres.whatNext) {
14840 case Dis_Continue:
florian8559e412012-04-19 14:23:48 +000014841 put_IA(mkaddr_expr(guest_IA_next_instr));
florian8844a632012-04-13 04:04:06 +000014842 break;
14843 case Dis_ResteerU:
14844 case Dis_ResteerC:
14845 put_IA(mkaddr_expr(dres.continueAt));
14846 break;
14847 case Dis_StopHere:
florian4b8efad2012-09-02 18:07:08 +000014848 if (dres.jk_StopHere == Ijk_EmWarn ||
14849 dres.jk_StopHere == Ijk_EmFail) {
14850 /* We assume here, that emulation warnings are not given for
14851 insns that transfer control. There is no good way to
14852 do that. */
14853 put_IA(mkaddr_expr(guest_IA_next_instr));
14854 }
florian8844a632012-04-13 04:04:06 +000014855 break;
14856 default:
14857 vassert(0);
14858 }
sewardj2019a972011-03-07 16:04:07 +000014859 }
14860
14861 return dres;
14862}
14863
14864
14865/*------------------------------------------------------------*/
14866/*--- Top-level fn ---*/
14867/*------------------------------------------------------------*/
14868
14869/* Disassemble a single instruction into IR. The instruction
14870 is located in host memory at &guest_code[delta]. */
14871
14872DisResult
14873disInstr_S390(IRSB *irsb_IN,
sewardj2019a972011-03-07 16:04:07 +000014874 Bool (*resteerOkFn)(void *, Addr64),
14875 Bool resteerCisOk,
14876 void *callback_opaque,
14877 UChar *guest_code,
14878 Long delta,
14879 Addr64 guest_IP,
14880 VexArch guest_arch,
14881 VexArchInfo *archinfo,
14882 VexAbiInfo *abiinfo,
14883 Bool host_bigendian)
14884{
14885 vassert(guest_arch == VexArchS390X);
14886
14887 /* The instruction decoder requires a big-endian machine. */
14888 vassert(host_bigendian == True);
14889
14890 /* Set globals (see top of this file) */
14891 guest_IA_curr_instr = guest_IP;
sewardj2019a972011-03-07 16:04:07 +000014892 irsb = irsb_IN;
florian420c5012011-07-22 02:12:28 +000014893 resteer_fn = resteerOkFn;
14894 resteer_data = callback_opaque;
sewardj2019a972011-03-07 16:04:07 +000014895
florian420c5012011-07-22 02:12:28 +000014896 return disInstr_S390_WRK(guest_code + delta);
sewardj2019a972011-03-07 16:04:07 +000014897}
14898
14899/*---------------------------------------------------------------*/
14900/*--- end guest_s390_toIR.c ---*/
14901/*---------------------------------------------------------------*/