blob: 68bad92d956cacf5b3f83f5b5b6dabb7916bd974 [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
sewardj442e51a2012-12-06 18:08:04 +000076/* Whether to print diagnostics for illegal instructions. */
77static Bool sigill_diag;
78
sewardj2019a972011-03-07 16:04:07 +000079/* The last seen execute target instruction */
80ULong last_execute_target;
81
82/* The possible outcomes of a decoding operation */
83typedef enum {
84 S390_DECODE_OK,
85 S390_DECODE_UNKNOWN_INSN,
86 S390_DECODE_UNIMPLEMENTED_INSN,
87 S390_DECODE_UNKNOWN_SPECIAL_INSN,
88 S390_DECODE_ERROR
89} s390_decode_t;
90
florian428dfdd2012-03-27 03:09:49 +000091
sewardj2019a972011-03-07 16:04:07 +000092/*------------------------------------------------------------*/
93/*--- Helpers for constructing IR. ---*/
94/*------------------------------------------------------------*/
95
96/* Sign extend a value with the given number of bits. This is a
97 macro because it allows us to overload the type of the value.
98 Note that VALUE must have a signed type! */
99#undef sign_extend
100#define sign_extend(value,num_bits) \
101(((value) << (sizeof(__typeof__(value)) * 8 - (num_bits))) >> \
102 (sizeof(__typeof__(value)) * 8 - (num_bits)))
103
104
105/* Add a statement to the current irsb. */
106static __inline__ void
107stmt(IRStmt *st)
108{
109 addStmtToIRSB(irsb, st);
110}
111
112/* Allocate a new temporary of the given type. */
113static __inline__ IRTemp
114newTemp(IRType type)
115{
116 vassert(isPlausibleIRType(type));
117
118 return newIRTemp(irsb->tyenv, type);
119}
120
121/* Create an expression node for a temporary */
122static __inline__ IRExpr *
123mkexpr(IRTemp tmp)
124{
125 return IRExpr_RdTmp(tmp);
126}
127
florian8844a632012-04-13 04:04:06 +0000128/* Generate an expression node for an address. */
129static __inline__ IRExpr *
130mkaddr_expr(Addr64 addr)
131{
132 return IRExpr_Const(IRConst_U64(addr));
133}
134
sewardj2019a972011-03-07 16:04:07 +0000135/* Add a statement that assigns to a temporary */
136static __inline__ void
137assign(IRTemp dst, IRExpr *expr)
138{
139 stmt(IRStmt_WrTmp(dst, expr));
140}
141
florian8844a632012-04-13 04:04:06 +0000142/* Write an address into the guest_IA */
143static __inline__ void
144put_IA(IRExpr *address)
145{
146 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_IA), address));
147}
148
sewardj2019a972011-03-07 16:04:07 +0000149/* Create a temporary of the given type and assign the expression to it */
150static __inline__ IRTemp
151mktemp(IRType type, IRExpr *expr)
152{
153 IRTemp temp = newTemp(type);
154
155 assign(temp, expr);
156
157 return temp;
158}
159
160/* Create a unary expression */
161static __inline__ IRExpr *
162unop(IROp kind, IRExpr *op)
163{
164 return IRExpr_Unop(kind, op);
165}
166
167/* Create a binary expression */
168static __inline__ IRExpr *
169binop(IROp kind, IRExpr *op1, IRExpr *op2)
170{
171 return IRExpr_Binop(kind, op1, op2);
172}
173
174/* Create a ternary expression */
175static __inline__ IRExpr *
176triop(IROp kind, IRExpr *op1, IRExpr *op2, IRExpr *op3)
177{
178 return IRExpr_Triop(kind, op1, op2, op3);
179}
180
181/* Create a quaternary expression */
182static __inline__ IRExpr *
183qop(IROp kind, IRExpr *op1, IRExpr *op2, IRExpr *op3, IRExpr *op4)
184{
185 return IRExpr_Qop(kind, op1, op2, op3, op4);
186}
187
188/* Create an expression node for an 8-bit integer constant */
189static __inline__ IRExpr *
190mkU8(UInt value)
191{
192 vassert(value < 256);
193
194 return IRExpr_Const(IRConst_U8((UChar)value));
195}
196
197/* Create an expression node for a 16-bit integer constant */
198static __inline__ IRExpr *
199mkU16(UInt value)
200{
201 vassert(value < 65536);
202
203 return IRExpr_Const(IRConst_U16((UShort)value));
204}
205
206/* Create an expression node for a 32-bit integer constant */
207static __inline__ IRExpr *
208mkU32(UInt value)
209{
210 return IRExpr_Const(IRConst_U32(value));
211}
212
213/* Create an expression node for a 64-bit integer constant */
214static __inline__ IRExpr *
215mkU64(ULong value)
216{
217 return IRExpr_Const(IRConst_U64(value));
218}
219
220/* Create an expression node for a 32-bit floating point constant
221 whose value is given by a bit pattern. */
222static __inline__ IRExpr *
223mkF32i(UInt value)
224{
225 return IRExpr_Const(IRConst_F32i(value));
226}
227
228/* Create an expression node for a 32-bit floating point constant
229 whose value is given by a bit pattern. */
230static __inline__ IRExpr *
231mkF64i(ULong value)
232{
233 return IRExpr_Const(IRConst_F64i(value));
234}
235
236/* Little helper function for my sanity. ITE = if-then-else */
237static IRExpr *
238mkite(IRExpr *condition, IRExpr *iftrue, IRExpr *iffalse)
239{
240 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
241
242 return IRExpr_Mux0X(unop(Iop_1Uto8, condition), iffalse, iftrue);
243}
244
245/* Add a statement that stores DATA at ADDR. This is a big-endian machine. */
246static void __inline__
247store(IRExpr *addr, IRExpr *data)
248{
249 stmt(IRStmt_Store(Iend_BE, addr, data));
250}
251
252/* Create an expression that loads a TYPE sized value from ADDR.
253 This is a big-endian machine. */
254static __inline__ IRExpr *
255load(IRType type, IRExpr *addr)
256{
257 return IRExpr_Load(Iend_BE, type, addr);
258}
259
260/* Function call */
261static void
262call_function(IRExpr *callee_address)
263{
florian8844a632012-04-13 04:04:06 +0000264 put_IA(callee_address);
sewardj2019a972011-03-07 16:04:07 +0000265
florian8844a632012-04-13 04:04:06 +0000266 dis_res->whatNext = Dis_StopHere;
267 dis_res->jk_StopHere = Ijk_Call;
sewardj2019a972011-03-07 16:04:07 +0000268}
269
floriana64c2432011-07-16 02:11:50 +0000270/* Function call with known target. */
271static void
272call_function_and_chase(Addr64 callee_address)
273{
274 if (resteer_fn(resteer_data, callee_address)) {
275 dis_res->whatNext = Dis_ResteerU;
276 dis_res->continueAt = callee_address;
277 } else {
florian8844a632012-04-13 04:04:06 +0000278 put_IA(mkaddr_expr(callee_address));
279
floriana64c2432011-07-16 02:11:50 +0000280 dis_res->whatNext = Dis_StopHere;
florian8844a632012-04-13 04:04:06 +0000281 dis_res->jk_StopHere = Ijk_Call;
floriana64c2432011-07-16 02:11:50 +0000282 }
283}
284
sewardj2019a972011-03-07 16:04:07 +0000285/* Function return sequence */
286static void
287return_from_function(IRExpr *return_address)
288{
florian8844a632012-04-13 04:04:06 +0000289 put_IA(return_address);
sewardj2019a972011-03-07 16:04:07 +0000290
florian8844a632012-04-13 04:04:06 +0000291 dis_res->whatNext = Dis_StopHere;
292 dis_res->jk_StopHere = Ijk_Ret;
sewardj2019a972011-03-07 16:04:07 +0000293}
294
295/* A conditional branch whose target is not known at instrumentation time.
296
297 if (condition) goto computed_target;
298
299 Needs to be represented as:
300
301 if (! condition) goto next_instruction;
302 goto computed_target;
sewardj2019a972011-03-07 16:04:07 +0000303*/
304static void
florianf321da72012-07-21 20:32:57 +0000305if_condition_goto_computed(IRExpr *condition, IRExpr *target)
sewardj2019a972011-03-07 16:04:07 +0000306{
307 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
308
florianf321da72012-07-21 20:32:57 +0000309 condition = unop(Iop_Not1, condition);
310
florian8844a632012-04-13 04:04:06 +0000311 stmt(IRStmt_Exit(condition, Ijk_Boring, IRConst_U64(guest_IA_next_instr),
312 S390X_GUEST_OFFSET(guest_IA)));
sewardj2019a972011-03-07 16:04:07 +0000313
florian8844a632012-04-13 04:04:06 +0000314 put_IA(target);
sewardj2019a972011-03-07 16:04:07 +0000315
florian8844a632012-04-13 04:04:06 +0000316 dis_res->whatNext = Dis_StopHere;
317 dis_res->jk_StopHere = Ijk_Boring;
sewardj2019a972011-03-07 16:04:07 +0000318}
319
320/* A conditional branch whose target is known at instrumentation time. */
321static void
322if_condition_goto(IRExpr *condition, Addr64 target)
323{
324 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
325
florian8844a632012-04-13 04:04:06 +0000326 stmt(IRStmt_Exit(condition, Ijk_Boring, IRConst_U64(target),
327 S390X_GUEST_OFFSET(guest_IA)));
328
florian7346c7a2012-04-13 21:14:24 +0000329 put_IA(mkaddr_expr(guest_IA_next_instr));
florian8844a632012-04-13 04:04:06 +0000330
331 dis_res->whatNext = Dis_StopHere;
332 dis_res->jk_StopHere = Ijk_Boring;
sewardj2019a972011-03-07 16:04:07 +0000333}
334
335/* An unconditional branch. Target may or may not be known at instrumentation
336 time. */
337static void
338always_goto(IRExpr *target)
339{
florian8844a632012-04-13 04:04:06 +0000340 put_IA(target);
sewardj2019a972011-03-07 16:04:07 +0000341
florian8844a632012-04-13 04:04:06 +0000342 dis_res->whatNext = Dis_StopHere;
343 dis_res->jk_StopHere = Ijk_Boring;
sewardj2019a972011-03-07 16:04:07 +0000344}
345
florian8844a632012-04-13 04:04:06 +0000346
floriana64c2432011-07-16 02:11:50 +0000347/* An unconditional branch to a known target. */
348static void
349always_goto_and_chase(Addr64 target)
350{
351 if (resteer_fn(resteer_data, target)) {
florian8844a632012-04-13 04:04:06 +0000352 /* Follow into the target */
floriana64c2432011-07-16 02:11:50 +0000353 dis_res->whatNext = Dis_ResteerU;
354 dis_res->continueAt = target;
355 } else {
florian8844a632012-04-13 04:04:06 +0000356 put_IA(mkaddr_expr(target));
357
358 dis_res->whatNext = Dis_StopHere;
359 dis_res->jk_StopHere = Ijk_Boring;
floriana64c2432011-07-16 02:11:50 +0000360 }
361}
362
sewardj2019a972011-03-07 16:04:07 +0000363/* A system call */
364static void
365system_call(IRExpr *sysno)
366{
367 /* Store the system call number in the pseudo register. */
florian428dfdd2012-03-27 03:09:49 +0000368 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_SYSNO), sysno));
sewardj2019a972011-03-07 16:04:07 +0000369
sewardj69007022011-04-28 20:13:45 +0000370 /* Store the current IA into guest_IP_AT_SYSCALL. libvex_ir.h says so. */
florian428dfdd2012-03-27 03:09:49 +0000371 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_IP_AT_SYSCALL),
372 mkU64(guest_IA_curr_instr)));
sewardj2019a972011-03-07 16:04:07 +0000373
florian8844a632012-04-13 04:04:06 +0000374 put_IA(mkaddr_expr(guest_IA_next_instr));
375
sewardj2019a972011-03-07 16:04:07 +0000376 /* It's important that all ArchRegs carry their up-to-date value
377 at this point. So we declare an end-of-block here, which
378 forces any TempRegs caching ArchRegs to be flushed. */
florian8844a632012-04-13 04:04:06 +0000379 dis_res->whatNext = Dis_StopHere;
380 dis_res->jk_StopHere = Ijk_Sys_syscall;
sewardj2019a972011-03-07 16:04:07 +0000381}
382
florian6820ba52012-07-26 02:01:50 +0000383/* A side exit that branches back to the current insn if CONDITION is
384 true. Does not set DisResult. */
385static void
386iterate_if(IRExpr *condition)
387{
388 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
389
390 stmt(IRStmt_Exit(condition, Ijk_Boring, IRConst_U64(guest_IA_curr_instr),
391 S390X_GUEST_OFFSET(guest_IA)));
392}
393
394/* A side exit that branches back to the current insn.
395 Does not set DisResult. */
396static __inline__ void
397iterate(void)
398{
399 iterate_if(IRExpr_Const(IRConst_U1(True)));
400}
401
402/* A side exit that branches back to the insn immediately following the
403 current insn if CONDITION is true. Does not set DisResult. */
404static void
405next_insn_if(IRExpr *condition)
406{
407 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
408
409 stmt(IRStmt_Exit(condition, Ijk_Boring, IRConst_U64(guest_IA_next_instr),
410 S390X_GUEST_OFFSET(guest_IA)));
411}
412
413/* Convenience function to restart the current insn */
414static void
415restart_if(IRExpr *condition)
416{
417 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
418
419 stmt(IRStmt_Exit(condition, Ijk_TInval, IRConst_U64(guest_IA_curr_instr),
420 S390X_GUEST_OFFSET(guest_IA)));
421}
422
423/* Convenience function to yield to thread scheduler */
424static void
425yield_if(IRExpr *condition)
426{
427 stmt(IRStmt_Exit(condition, Ijk_Yield, IRConst_U64(guest_IA_next_instr),
428 S390X_GUEST_OFFSET(guest_IA)));
429}
430
sewardj2019a972011-03-07 16:04:07 +0000431static __inline__ IRExpr *get_fpr_dw0(UInt);
432static __inline__ void put_fpr_dw0(UInt, IRExpr *);
florian12390202012-11-10 22:34:14 +0000433static __inline__ IRExpr *get_dpr_dw0(UInt);
434static __inline__ void put_dpr_dw0(UInt, IRExpr *);
sewardj2019a972011-03-07 16:04:07 +0000435
436/* Read a floating point register pair and combine their contents into a
437 128-bit value */
438static IRExpr *
439get_fpr_pair(UInt archreg)
440{
441 IRExpr *high = get_fpr_dw0(archreg);
442 IRExpr *low = get_fpr_dw0(archreg + 2);
443
444 return binop(Iop_F64HLtoF128, high, low);
445}
446
447/* Write a 128-bit floating point value into a register pair. */
448static void
449put_fpr_pair(UInt archreg, IRExpr *expr)
450{
451 IRExpr *high = unop(Iop_F128HItoF64, expr);
452 IRExpr *low = unop(Iop_F128LOtoF64, expr);
453
454 put_fpr_dw0(archreg, high);
455 put_fpr_dw0(archreg + 2, low);
456}
457
floriane75dafa2012-09-01 17:54:09 +0000458/* Terminate the current IRSB with an emulation failure. */
459static void
460emulation_failure(VexEmNote fail_kind)
461{
462 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_EMNOTE), mkU32(fail_kind)));
floriane75dafa2012-09-01 17:54:09 +0000463 dis_res->whatNext = Dis_StopHere;
464 dis_res->jk_StopHere = Ijk_EmFail;
465}
sewardj2019a972011-03-07 16:04:07 +0000466
florian4b8efad2012-09-02 18:07:08 +0000467/* Terminate the current IRSB with an emulation warning. */
468static void
469emulation_warning(VexEmNote warn_kind)
470{
471 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_EMNOTE), mkU32(warn_kind)));
472 dis_res->whatNext = Dis_StopHere;
473 dis_res->jk_StopHere = Ijk_EmWarn;
474}
475
sewardj2019a972011-03-07 16:04:07 +0000476/*------------------------------------------------------------*/
florianf3410f92012-08-03 18:41:58 +0000477/*--- IR Debugging aids. ---*/
478/*------------------------------------------------------------*/
479#if 0
480
481static ULong
482s390_do_print(HChar *text, ULong value)
483{
484 vex_printf("%s %llu\n", text, value);
485 return 0;
486}
487
488static void
489s390_print(HChar *text, IRExpr *value)
490{
491 IRDirty *d;
492
493 d = unsafeIRDirty_0_N(0 /* regparms */, "s390_do_print", &s390_do_print,
494 mkIRExprVec_2(mkU64((ULong)text), value));
495 stmt(IRStmt_Dirty(d));
496}
497#endif
498
499
500/*------------------------------------------------------------*/
sewardj2019a972011-03-07 16:04:07 +0000501/*--- Build the flags thunk. ---*/
502/*------------------------------------------------------------*/
503
504/* Completely fill the flags thunk. We're always filling all fields.
505 Apparently, that is better for redundant PUT elimination. */
506static void
507s390_cc_thunk_fill(IRExpr *op, IRExpr *dep1, IRExpr *dep2, IRExpr *ndep)
508{
509 UInt op_off, dep1_off, dep2_off, ndep_off;
510
florian428dfdd2012-03-27 03:09:49 +0000511 op_off = S390X_GUEST_OFFSET(guest_CC_OP);
512 dep1_off = S390X_GUEST_OFFSET(guest_CC_DEP1);
513 dep2_off = S390X_GUEST_OFFSET(guest_CC_DEP2);
514 ndep_off = S390X_GUEST_OFFSET(guest_CC_NDEP);
sewardj2019a972011-03-07 16:04:07 +0000515
516 stmt(IRStmt_Put(op_off, op));
517 stmt(IRStmt_Put(dep1_off, dep1));
518 stmt(IRStmt_Put(dep2_off, dep2));
519 stmt(IRStmt_Put(ndep_off, ndep));
520}
521
522
523/* Create an expression for V and widen the result to 64 bit. */
524static IRExpr *
525s390_cc_widen(IRTemp v, Bool sign_extend)
526{
527 IRExpr *expr;
528
529 expr = mkexpr(v);
530
531 switch (typeOfIRTemp(irsb->tyenv, v)) {
532 case Ity_I64:
533 break;
534 case Ity_I32:
535 expr = unop(sign_extend ? Iop_32Sto64 : Iop_32Uto64, expr);
536 break;
537 case Ity_I16:
538 expr = unop(sign_extend ? Iop_16Sto64 : Iop_16Uto64, expr);
539 break;
540 case Ity_I8:
541 expr = unop(sign_extend ? Iop_8Sto64 : Iop_8Uto64, expr);
542 break;
543 default:
544 vpanic("s390_cc_widen");
545 }
546
547 return expr;
548}
549
550static void
551s390_cc_thunk_put1(UInt opc, IRTemp d1, Bool sign_extend)
552{
553 IRExpr *op, *dep1, *dep2, *ndep;
554
555 op = mkU64(opc);
556 dep1 = s390_cc_widen(d1, sign_extend);
557 dep2 = mkU64(0);
558 ndep = mkU64(0);
559
560 s390_cc_thunk_fill(op, dep1, dep2, ndep);
561}
562
563
564static void
565s390_cc_thunk_put2(UInt opc, IRTemp d1, IRTemp d2, Bool sign_extend)
566{
567 IRExpr *op, *dep1, *dep2, *ndep;
568
569 op = mkU64(opc);
570 dep1 = s390_cc_widen(d1, sign_extend);
571 dep2 = s390_cc_widen(d2, sign_extend);
572 ndep = mkU64(0);
573
574 s390_cc_thunk_fill(op, dep1, dep2, ndep);
575}
576
577
578/* memcheck believes that the NDEP field in the flags thunk is always
579 defined. But for some flag computations (e.g. add with carry) that is
580 just not true. We therefore need to convey to memcheck that the value
581 of the ndep field does matter and therefore we make the DEP2 field
582 depend on it:
583
584 DEP2 = original_DEP2 ^ NDEP
585
586 In s390_calculate_cc we exploit that (a^b)^b == a
587 I.e. we xor the DEP2 value with the NDEP value to recover the
588 original_DEP2 value. */
589static void
590s390_cc_thunk_put3(UInt opc, IRTemp d1, IRTemp d2, IRTemp nd, Bool sign_extend)
591{
592 IRExpr *op, *dep1, *dep2, *ndep, *dep2x;
593
594 op = mkU64(opc);
595 dep1 = s390_cc_widen(d1, sign_extend);
596 dep2 = s390_cc_widen(d2, sign_extend);
597 ndep = s390_cc_widen(nd, sign_extend);
598
599 dep2x = binop(Iop_Xor64, dep2, ndep);
600
601 s390_cc_thunk_fill(op, dep1, dep2x, ndep);
602}
603
604
605/* Write one floating point value into the flags thunk */
606static void
607s390_cc_thunk_put1f(UInt opc, IRTemp d1)
608{
609 IRExpr *op, *dep1, *dep2, *ndep;
610
611 op = mkU64(opc);
612 dep1 = mkexpr(d1);
613 dep2 = mkU64(0);
614 ndep = mkU64(0);
615
616 s390_cc_thunk_fill(op, dep1, dep2, ndep);
617}
618
619
620/* Write a floating point value and an integer into the flags thunk. The
621 integer value is zero-extended first. */
622static void
623s390_cc_thunk_putFZ(UInt opc, IRTemp d1, IRTemp d2)
624{
625 IRExpr *op, *dep1, *dep2, *ndep;
626
627 op = mkU64(opc);
628 dep1 = mkexpr(d1);
629 dep2 = s390_cc_widen(d2, False);
630 ndep = mkU64(0);
631
632 s390_cc_thunk_fill(op, dep1, dep2, ndep);
633}
634
635
636/* Write a 128-bit floating point value into the flags thunk. This is
637 done by splitting the value into two 64-bits values. */
638static void
639s390_cc_thunk_put1f128(UInt opc, IRTemp d1)
640{
641 IRExpr *op, *hi, *lo, *ndep;
642
643 op = mkU64(opc);
644 hi = unop(Iop_F128HItoF64, mkexpr(d1));
645 lo = unop(Iop_F128LOtoF64, mkexpr(d1));
646 ndep = mkU64(0);
647
648 s390_cc_thunk_fill(op, hi, lo, ndep);
649}
650
651
652/* Write a 128-bit floating point value and an integer into the flags thunk.
653 The integer value is zero-extended first. */
654static void
655s390_cc_thunk_put1f128Z(UInt opc, IRTemp d1, IRTemp nd)
656{
657 IRExpr *op, *hi, *lo, *lox, *ndep;
658
659 op = mkU64(opc);
660 hi = unop(Iop_F128HItoF64, mkexpr(d1));
661 lo = unop(Iop_ReinterpF64asI64, unop(Iop_F128LOtoF64, mkexpr(d1)));
662 ndep = s390_cc_widen(nd, False);
663
664 lox = binop(Iop_Xor64, lo, ndep); /* convey dependency */
665
666 s390_cc_thunk_fill(op, hi, lox, ndep);
667}
668
669
670static void
671s390_cc_set(UInt val)
672{
673 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
674 mkU64(val), mkU64(0), mkU64(0));
675}
676
677/* Build IR to calculate the condition code from flags thunk.
678 Returns an expression of type Ity_I32 */
679static IRExpr *
680s390_call_calculate_cc(void)
681{
682 IRExpr **args, *call, *op, *dep1, *dep2, *ndep;
683
florian428dfdd2012-03-27 03:09:49 +0000684 op = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_OP), Ity_I64);
685 dep1 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP1), Ity_I64);
686 dep2 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP2), Ity_I64);
687 ndep = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_NDEP), Ity_I64);
sewardj2019a972011-03-07 16:04:07 +0000688
689 args = mkIRExprVec_4(op, dep1, dep2, ndep);
690 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
691 "s390_calculate_cc", &s390_calculate_cc, args);
692
693 /* Exclude OP and NDEP from definedness checking. We're only
694 interested in DEP1 and DEP2. */
695 call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<3);
696
697 return call;
698}
699
700/* Build IR to calculate the internal condition code for a "compare and branch"
701 insn. Returns an expression of type Ity_I32 */
702static IRExpr *
florianff9613f2012-05-12 15:26:44 +0000703s390_call_calculate_icc(UInt m, UInt opc, IRTemp op1, IRTemp op2)
sewardj2019a972011-03-07 16:04:07 +0000704{
florianff9613f2012-05-12 15:26:44 +0000705 IRExpr **args, *call, *op, *dep1, *dep2, *mask;
sewardj2019a972011-03-07 16:04:07 +0000706
florianff9613f2012-05-12 15:26:44 +0000707 switch (opc) {
708 case S390_CC_OP_SIGNED_COMPARE:
709 dep1 = s390_cc_widen(op1, True);
710 dep2 = s390_cc_widen(op2, True);
711 break;
712
713 case S390_CC_OP_UNSIGNED_COMPARE:
714 dep1 = s390_cc_widen(op1, False);
715 dep2 = s390_cc_widen(op2, False);
716 break;
717
718 default:
719 vpanic("s390_call_calculate_icc");
720 }
721
722 mask = mkU64(m);
sewardj2019a972011-03-07 16:04:07 +0000723 op = mkU64(opc);
sewardj2019a972011-03-07 16:04:07 +0000724
florianff9613f2012-05-12 15:26:44 +0000725 args = mkIRExprVec_5(mask, op, dep1, dep2, mkU64(0) /* unused */);
sewardj2019a972011-03-07 16:04:07 +0000726 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
florianff9613f2012-05-12 15:26:44 +0000727 "s390_calculate_cond", &s390_calculate_cond, args);
sewardj2019a972011-03-07 16:04:07 +0000728
florianff9613f2012-05-12 15:26:44 +0000729 /* Exclude the requested condition, OP and NDEP from definedness
730 checking. We're only interested in DEP1 and DEP2. */
731 call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<1) | (1<<4);
sewardj2019a972011-03-07 16:04:07 +0000732
733 return call;
734}
735
736/* Build IR to calculate the condition code from flags thunk.
737 Returns an expression of type Ity_I32 */
738static IRExpr *
739s390_call_calculate_cond(UInt m)
740{
741 IRExpr **args, *call, *op, *dep1, *dep2, *ndep, *mask;
742
743 mask = mkU64(m);
florian428dfdd2012-03-27 03:09:49 +0000744 op = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_OP), Ity_I64);
745 dep1 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP1), Ity_I64);
746 dep2 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP2), Ity_I64);
747 ndep = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_NDEP), Ity_I64);
sewardj2019a972011-03-07 16:04:07 +0000748
749 args = mkIRExprVec_5(mask, op, dep1, dep2, ndep);
750 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
751 "s390_calculate_cond", &s390_calculate_cond, args);
752
753 /* Exclude the requested condition, OP and NDEP from definedness
754 checking. We're only interested in DEP1 and DEP2. */
755 call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<1) | (1<<4);
756
757 return call;
758}
759
760#define s390_cc_thunk_putZ(op,dep1) s390_cc_thunk_put1(op,dep1,False)
761#define s390_cc_thunk_putS(op,dep1) s390_cc_thunk_put1(op,dep1,True)
762#define s390_cc_thunk_putF(op,dep1) s390_cc_thunk_put1f(op,dep1)
763#define s390_cc_thunk_putZZ(op,dep1,dep2) s390_cc_thunk_put2(op,dep1,dep2,False)
764#define s390_cc_thunk_putSS(op,dep1,dep2) s390_cc_thunk_put2(op,dep1,dep2,True)
765#define s390_cc_thunk_putFF(op,dep1,dep2) s390_cc_thunk_put2f(op,dep1,dep2)
766#define s390_cc_thunk_putZZZ(op,dep1,dep2,ndep) \
767 s390_cc_thunk_put3(op,dep1,dep2,ndep,False)
768#define s390_cc_thunk_putSSS(op,dep1,dep2,ndep) \
769 s390_cc_thunk_put3(op,dep1,dep2,ndep,True)
sewardj2019a972011-03-07 16:04:07 +0000770
771
sewardj2019a972011-03-07 16:04:07 +0000772
773
774/*------------------------------------------------------------*/
775/*--- Guest register access ---*/
776/*------------------------------------------------------------*/
777
778
779/*------------------------------------------------------------*/
780/*--- ar registers ---*/
781/*------------------------------------------------------------*/
782
783/* Return the guest state offset of a ar register. */
784static UInt
785ar_offset(UInt archreg)
786{
787 static const UInt offset[16] = {
floriane88b3c92011-07-05 02:48:39 +0000788 S390X_GUEST_OFFSET(guest_a0),
789 S390X_GUEST_OFFSET(guest_a1),
790 S390X_GUEST_OFFSET(guest_a2),
791 S390X_GUEST_OFFSET(guest_a3),
792 S390X_GUEST_OFFSET(guest_a4),
793 S390X_GUEST_OFFSET(guest_a5),
794 S390X_GUEST_OFFSET(guest_a6),
795 S390X_GUEST_OFFSET(guest_a7),
796 S390X_GUEST_OFFSET(guest_a8),
797 S390X_GUEST_OFFSET(guest_a9),
798 S390X_GUEST_OFFSET(guest_a10),
799 S390X_GUEST_OFFSET(guest_a11),
800 S390X_GUEST_OFFSET(guest_a12),
801 S390X_GUEST_OFFSET(guest_a13),
802 S390X_GUEST_OFFSET(guest_a14),
803 S390X_GUEST_OFFSET(guest_a15),
sewardj2019a972011-03-07 16:04:07 +0000804 };
805
806 vassert(archreg < 16);
807
808 return offset[archreg];
809}
810
811
812/* Return the guest state offset of word #0 of a ar register. */
813static __inline__ UInt
814ar_w0_offset(UInt archreg)
815{
816 return ar_offset(archreg) + 0;
817}
818
819/* Write word #0 of a ar to the guest state. */
820static __inline__ void
821put_ar_w0(UInt archreg, IRExpr *expr)
822{
823 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
824
825 stmt(IRStmt_Put(ar_w0_offset(archreg), expr));
826}
827
828/* Read word #0 of a ar register. */
829static __inline__ IRExpr *
830get_ar_w0(UInt archreg)
831{
832 return IRExpr_Get(ar_w0_offset(archreg), Ity_I32);
833}
834
835
836/*------------------------------------------------------------*/
837/*--- fpr registers ---*/
838/*------------------------------------------------------------*/
839
840/* Return the guest state offset of a fpr register. */
841static UInt
842fpr_offset(UInt archreg)
843{
844 static const UInt offset[16] = {
floriane88b3c92011-07-05 02:48:39 +0000845 S390X_GUEST_OFFSET(guest_f0),
846 S390X_GUEST_OFFSET(guest_f1),
847 S390X_GUEST_OFFSET(guest_f2),
848 S390X_GUEST_OFFSET(guest_f3),
849 S390X_GUEST_OFFSET(guest_f4),
850 S390X_GUEST_OFFSET(guest_f5),
851 S390X_GUEST_OFFSET(guest_f6),
852 S390X_GUEST_OFFSET(guest_f7),
853 S390X_GUEST_OFFSET(guest_f8),
854 S390X_GUEST_OFFSET(guest_f9),
855 S390X_GUEST_OFFSET(guest_f10),
856 S390X_GUEST_OFFSET(guest_f11),
857 S390X_GUEST_OFFSET(guest_f12),
858 S390X_GUEST_OFFSET(guest_f13),
859 S390X_GUEST_OFFSET(guest_f14),
860 S390X_GUEST_OFFSET(guest_f15),
sewardj2019a972011-03-07 16:04:07 +0000861 };
862
863 vassert(archreg < 16);
864
865 return offset[archreg];
866}
867
868
869/* Return the guest state offset of word #0 of a fpr register. */
870static __inline__ UInt
871fpr_w0_offset(UInt archreg)
872{
873 return fpr_offset(archreg) + 0;
874}
875
876/* Write word #0 of a fpr to the guest state. */
877static __inline__ void
878put_fpr_w0(UInt archreg, IRExpr *expr)
879{
880 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_F32);
881
882 stmt(IRStmt_Put(fpr_w0_offset(archreg), expr));
883}
884
885/* Read word #0 of a fpr register. */
886static __inline__ IRExpr *
887get_fpr_w0(UInt archreg)
888{
889 return IRExpr_Get(fpr_w0_offset(archreg), Ity_F32);
890}
891
892/* Return the guest state offset of double word #0 of a fpr register. */
893static __inline__ UInt
894fpr_dw0_offset(UInt archreg)
895{
896 return fpr_offset(archreg) + 0;
897}
898
899/* Write double word #0 of a fpr to the guest state. */
900static __inline__ void
901put_fpr_dw0(UInt archreg, IRExpr *expr)
902{
903 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_F64);
904
905 stmt(IRStmt_Put(fpr_dw0_offset(archreg), expr));
906}
907
908/* Read double word #0 of a fpr register. */
909static __inline__ IRExpr *
910get_fpr_dw0(UInt archreg)
911{
912 return IRExpr_Get(fpr_dw0_offset(archreg), Ity_F64);
913}
914
florian12390202012-11-10 22:34:14 +0000915/* Write double word #0 of a fpr containg DFP value to the guest state. */
916static __inline__ void
917put_dpr_dw0(UInt archreg, IRExpr *expr)
918{
919 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_D64);
920
921 stmt(IRStmt_Put(fpr_dw0_offset(archreg), expr));
922}
923
924/* Read double word #0 of a fpr register containing DFP value. */
925static __inline__ IRExpr *
926get_dpr_dw0(UInt archreg)
927{
928 return IRExpr_Get(fpr_dw0_offset(archreg), Ity_D64);
929}
sewardj2019a972011-03-07 16:04:07 +0000930
931/*------------------------------------------------------------*/
932/*--- gpr registers ---*/
933/*------------------------------------------------------------*/
934
935/* Return the guest state offset of a gpr register. */
936static UInt
937gpr_offset(UInt archreg)
938{
939 static const UInt offset[16] = {
floriane88b3c92011-07-05 02:48:39 +0000940 S390X_GUEST_OFFSET(guest_r0),
941 S390X_GUEST_OFFSET(guest_r1),
942 S390X_GUEST_OFFSET(guest_r2),
943 S390X_GUEST_OFFSET(guest_r3),
944 S390X_GUEST_OFFSET(guest_r4),
945 S390X_GUEST_OFFSET(guest_r5),
946 S390X_GUEST_OFFSET(guest_r6),
947 S390X_GUEST_OFFSET(guest_r7),
948 S390X_GUEST_OFFSET(guest_r8),
949 S390X_GUEST_OFFSET(guest_r9),
950 S390X_GUEST_OFFSET(guest_r10),
951 S390X_GUEST_OFFSET(guest_r11),
952 S390X_GUEST_OFFSET(guest_r12),
953 S390X_GUEST_OFFSET(guest_r13),
954 S390X_GUEST_OFFSET(guest_r14),
955 S390X_GUEST_OFFSET(guest_r15),
sewardj2019a972011-03-07 16:04:07 +0000956 };
957
958 vassert(archreg < 16);
959
960 return offset[archreg];
961}
962
963
964/* Return the guest state offset of word #0 of a gpr register. */
965static __inline__ UInt
966gpr_w0_offset(UInt archreg)
967{
968 return gpr_offset(archreg) + 0;
969}
970
971/* Write word #0 of a gpr to the guest state. */
972static __inline__ void
973put_gpr_w0(UInt archreg, IRExpr *expr)
974{
975 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
976
977 stmt(IRStmt_Put(gpr_w0_offset(archreg), expr));
978}
979
980/* Read word #0 of a gpr register. */
981static __inline__ IRExpr *
982get_gpr_w0(UInt archreg)
983{
984 return IRExpr_Get(gpr_w0_offset(archreg), Ity_I32);
985}
986
987/* Return the guest state offset of double word #0 of a gpr register. */
988static __inline__ UInt
989gpr_dw0_offset(UInt archreg)
990{
991 return gpr_offset(archreg) + 0;
992}
993
994/* Write double word #0 of a gpr to the guest state. */
995static __inline__ void
996put_gpr_dw0(UInt archreg, IRExpr *expr)
997{
998 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I64);
999
1000 stmt(IRStmt_Put(gpr_dw0_offset(archreg), expr));
1001}
1002
1003/* Read double word #0 of a gpr register. */
1004static __inline__ IRExpr *
1005get_gpr_dw0(UInt archreg)
1006{
1007 return IRExpr_Get(gpr_dw0_offset(archreg), Ity_I64);
1008}
1009
1010/* Return the guest state offset of half word #1 of a gpr register. */
1011static __inline__ UInt
1012gpr_hw1_offset(UInt archreg)
1013{
1014 return gpr_offset(archreg) + 2;
1015}
1016
1017/* Write half word #1 of a gpr to the guest state. */
1018static __inline__ void
1019put_gpr_hw1(UInt archreg, IRExpr *expr)
1020{
1021 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1022
1023 stmt(IRStmt_Put(gpr_hw1_offset(archreg), expr));
1024}
1025
1026/* Read half word #1 of a gpr register. */
1027static __inline__ IRExpr *
1028get_gpr_hw1(UInt archreg)
1029{
1030 return IRExpr_Get(gpr_hw1_offset(archreg), Ity_I16);
1031}
1032
1033/* Return the guest state offset of byte #6 of a gpr register. */
1034static __inline__ UInt
1035gpr_b6_offset(UInt archreg)
1036{
1037 return gpr_offset(archreg) + 6;
1038}
1039
1040/* Write byte #6 of a gpr to the guest state. */
1041static __inline__ void
1042put_gpr_b6(UInt archreg, IRExpr *expr)
1043{
1044 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1045
1046 stmt(IRStmt_Put(gpr_b6_offset(archreg), expr));
1047}
1048
1049/* Read byte #6 of a gpr register. */
1050static __inline__ IRExpr *
1051get_gpr_b6(UInt archreg)
1052{
1053 return IRExpr_Get(gpr_b6_offset(archreg), Ity_I8);
1054}
1055
1056/* Return the guest state offset of byte #3 of a gpr register. */
1057static __inline__ UInt
1058gpr_b3_offset(UInt archreg)
1059{
1060 return gpr_offset(archreg) + 3;
1061}
1062
1063/* Write byte #3 of a gpr to the guest state. */
1064static __inline__ void
1065put_gpr_b3(UInt archreg, IRExpr *expr)
1066{
1067 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1068
1069 stmt(IRStmt_Put(gpr_b3_offset(archreg), expr));
1070}
1071
1072/* Read byte #3 of a gpr register. */
1073static __inline__ IRExpr *
1074get_gpr_b3(UInt archreg)
1075{
1076 return IRExpr_Get(gpr_b3_offset(archreg), Ity_I8);
1077}
1078
1079/* Return the guest state offset of byte #0 of a gpr register. */
1080static __inline__ UInt
1081gpr_b0_offset(UInt archreg)
1082{
1083 return gpr_offset(archreg) + 0;
1084}
1085
1086/* Write byte #0 of a gpr to the guest state. */
1087static __inline__ void
1088put_gpr_b0(UInt archreg, IRExpr *expr)
1089{
1090 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1091
1092 stmt(IRStmt_Put(gpr_b0_offset(archreg), expr));
1093}
1094
1095/* Read byte #0 of a gpr register. */
1096static __inline__ IRExpr *
1097get_gpr_b0(UInt archreg)
1098{
1099 return IRExpr_Get(gpr_b0_offset(archreg), Ity_I8);
1100}
1101
1102/* Return the guest state offset of word #1 of a gpr register. */
1103static __inline__ UInt
1104gpr_w1_offset(UInt archreg)
1105{
1106 return gpr_offset(archreg) + 4;
1107}
1108
1109/* Write word #1 of a gpr to the guest state. */
1110static __inline__ void
1111put_gpr_w1(UInt archreg, IRExpr *expr)
1112{
1113 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1114
1115 stmt(IRStmt_Put(gpr_w1_offset(archreg), expr));
1116}
1117
1118/* Read word #1 of a gpr register. */
1119static __inline__ IRExpr *
1120get_gpr_w1(UInt archreg)
1121{
1122 return IRExpr_Get(gpr_w1_offset(archreg), Ity_I32);
1123}
1124
1125/* Return the guest state offset of half word #3 of a gpr register. */
1126static __inline__ UInt
1127gpr_hw3_offset(UInt archreg)
1128{
1129 return gpr_offset(archreg) + 6;
1130}
1131
1132/* Write half word #3 of a gpr to the guest state. */
1133static __inline__ void
1134put_gpr_hw3(UInt archreg, IRExpr *expr)
1135{
1136 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1137
1138 stmt(IRStmt_Put(gpr_hw3_offset(archreg), expr));
1139}
1140
1141/* Read half word #3 of a gpr register. */
1142static __inline__ IRExpr *
1143get_gpr_hw3(UInt archreg)
1144{
1145 return IRExpr_Get(gpr_hw3_offset(archreg), Ity_I16);
1146}
1147
1148/* Return the guest state offset of byte #7 of a gpr register. */
1149static __inline__ UInt
1150gpr_b7_offset(UInt archreg)
1151{
1152 return gpr_offset(archreg) + 7;
1153}
1154
1155/* Write byte #7 of a gpr to the guest state. */
1156static __inline__ void
1157put_gpr_b7(UInt archreg, IRExpr *expr)
1158{
1159 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1160
1161 stmt(IRStmt_Put(gpr_b7_offset(archreg), expr));
1162}
1163
1164/* Read byte #7 of a gpr register. */
1165static __inline__ IRExpr *
1166get_gpr_b7(UInt archreg)
1167{
1168 return IRExpr_Get(gpr_b7_offset(archreg), Ity_I8);
1169}
1170
1171/* Return the guest state offset of half word #0 of a gpr register. */
1172static __inline__ UInt
1173gpr_hw0_offset(UInt archreg)
1174{
1175 return gpr_offset(archreg) + 0;
1176}
1177
1178/* Write half word #0 of a gpr to the guest state. */
1179static __inline__ void
1180put_gpr_hw0(UInt archreg, IRExpr *expr)
1181{
1182 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1183
1184 stmt(IRStmt_Put(gpr_hw0_offset(archreg), expr));
1185}
1186
1187/* Read half word #0 of a gpr register. */
1188static __inline__ IRExpr *
1189get_gpr_hw0(UInt archreg)
1190{
1191 return IRExpr_Get(gpr_hw0_offset(archreg), Ity_I16);
1192}
1193
1194/* Return the guest state offset of byte #4 of a gpr register. */
1195static __inline__ UInt
1196gpr_b4_offset(UInt archreg)
1197{
1198 return gpr_offset(archreg) + 4;
1199}
1200
1201/* Write byte #4 of a gpr to the guest state. */
1202static __inline__ void
1203put_gpr_b4(UInt archreg, IRExpr *expr)
1204{
1205 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1206
1207 stmt(IRStmt_Put(gpr_b4_offset(archreg), expr));
1208}
1209
1210/* Read byte #4 of a gpr register. */
1211static __inline__ IRExpr *
1212get_gpr_b4(UInt archreg)
1213{
1214 return IRExpr_Get(gpr_b4_offset(archreg), Ity_I8);
1215}
1216
1217/* Return the guest state offset of byte #1 of a gpr register. */
1218static __inline__ UInt
1219gpr_b1_offset(UInt archreg)
1220{
1221 return gpr_offset(archreg) + 1;
1222}
1223
1224/* Write byte #1 of a gpr to the guest state. */
1225static __inline__ void
1226put_gpr_b1(UInt archreg, IRExpr *expr)
1227{
1228 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1229
1230 stmt(IRStmt_Put(gpr_b1_offset(archreg), expr));
1231}
1232
1233/* Read byte #1 of a gpr register. */
1234static __inline__ IRExpr *
1235get_gpr_b1(UInt archreg)
1236{
1237 return IRExpr_Get(gpr_b1_offset(archreg), Ity_I8);
1238}
1239
1240/* Return the guest state offset of half word #2 of a gpr register. */
1241static __inline__ UInt
1242gpr_hw2_offset(UInt archreg)
1243{
1244 return gpr_offset(archreg) + 4;
1245}
1246
1247/* Write half word #2 of a gpr to the guest state. */
1248static __inline__ void
1249put_gpr_hw2(UInt archreg, IRExpr *expr)
1250{
1251 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1252
1253 stmt(IRStmt_Put(gpr_hw2_offset(archreg), expr));
1254}
1255
1256/* Read half word #2 of a gpr register. */
1257static __inline__ IRExpr *
1258get_gpr_hw2(UInt archreg)
1259{
1260 return IRExpr_Get(gpr_hw2_offset(archreg), Ity_I16);
1261}
1262
1263/* Return the guest state offset of byte #5 of a gpr register. */
1264static __inline__ UInt
1265gpr_b5_offset(UInt archreg)
1266{
1267 return gpr_offset(archreg) + 5;
1268}
1269
1270/* Write byte #5 of a gpr to the guest state. */
1271static __inline__ void
1272put_gpr_b5(UInt archreg, IRExpr *expr)
1273{
1274 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1275
1276 stmt(IRStmt_Put(gpr_b5_offset(archreg), expr));
1277}
1278
1279/* Read byte #5 of a gpr register. */
1280static __inline__ IRExpr *
1281get_gpr_b5(UInt archreg)
1282{
1283 return IRExpr_Get(gpr_b5_offset(archreg), Ity_I8);
1284}
1285
1286/* Return the guest state offset of byte #2 of a gpr register. */
1287static __inline__ UInt
1288gpr_b2_offset(UInt archreg)
1289{
1290 return gpr_offset(archreg) + 2;
1291}
1292
1293/* Write byte #2 of a gpr to the guest state. */
1294static __inline__ void
1295put_gpr_b2(UInt archreg, IRExpr *expr)
1296{
1297 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1298
1299 stmt(IRStmt_Put(gpr_b2_offset(archreg), expr));
1300}
1301
1302/* Read byte #2 of a gpr register. */
1303static __inline__ IRExpr *
1304get_gpr_b2(UInt archreg)
1305{
1306 return IRExpr_Get(gpr_b2_offset(archreg), Ity_I8);
1307}
1308
1309/* Return the guest state offset of the counter register. */
1310static UInt
1311counter_offset(void)
1312{
floriane88b3c92011-07-05 02:48:39 +00001313 return S390X_GUEST_OFFSET(guest_counter);
sewardj2019a972011-03-07 16:04:07 +00001314}
1315
1316/* Return the guest state offset of double word #0 of the counter register. */
1317static __inline__ UInt
1318counter_dw0_offset(void)
1319{
1320 return counter_offset() + 0;
1321}
1322
1323/* Write double word #0 of the counter to the guest state. */
1324static __inline__ void
1325put_counter_dw0(IRExpr *expr)
1326{
1327 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I64);
1328
1329 stmt(IRStmt_Put(counter_dw0_offset(), expr));
1330}
1331
1332/* Read double word #0 of the counter register. */
1333static __inline__ IRExpr *
1334get_counter_dw0(void)
1335{
1336 return IRExpr_Get(counter_dw0_offset(), Ity_I64);
1337}
1338
1339/* Return the guest state offset of word #0 of the counter register. */
1340static __inline__ UInt
1341counter_w0_offset(void)
1342{
1343 return counter_offset() + 0;
1344}
1345
1346/* Return the guest state offset of word #1 of the counter register. */
1347static __inline__ UInt
1348counter_w1_offset(void)
1349{
1350 return counter_offset() + 4;
1351}
1352
1353/* Write word #0 of the counter to the guest state. */
1354static __inline__ void
1355put_counter_w0(IRExpr *expr)
1356{
1357 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1358
1359 stmt(IRStmt_Put(counter_w0_offset(), expr));
1360}
1361
1362/* Read word #0 of the counter register. */
1363static __inline__ IRExpr *
1364get_counter_w0(void)
1365{
1366 return IRExpr_Get(counter_w0_offset(), Ity_I32);
1367}
1368
1369/* Write word #1 of the counter to the guest state. */
1370static __inline__ void
1371put_counter_w1(IRExpr *expr)
1372{
1373 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1374
1375 stmt(IRStmt_Put(counter_w1_offset(), expr));
1376}
1377
1378/* Read word #1 of the counter register. */
1379static __inline__ IRExpr *
1380get_counter_w1(void)
1381{
1382 return IRExpr_Get(counter_w1_offset(), Ity_I32);
1383}
1384
1385/* Return the guest state offset of the fpc register. */
1386static UInt
1387fpc_offset(void)
1388{
floriane88b3c92011-07-05 02:48:39 +00001389 return S390X_GUEST_OFFSET(guest_fpc);
sewardj2019a972011-03-07 16:04:07 +00001390}
1391
1392/* Return the guest state offset of word #0 of the fpc register. */
1393static __inline__ UInt
1394fpc_w0_offset(void)
1395{
1396 return fpc_offset() + 0;
1397}
1398
1399/* Write word #0 of the fpc to the guest state. */
1400static __inline__ void
1401put_fpc_w0(IRExpr *expr)
1402{
1403 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1404
1405 stmt(IRStmt_Put(fpc_w0_offset(), expr));
1406}
1407
1408/* Read word #0 of the fpc register. */
1409static __inline__ IRExpr *
1410get_fpc_w0(void)
1411{
1412 return IRExpr_Get(fpc_w0_offset(), Ity_I32);
1413}
1414
1415
1416/*------------------------------------------------------------*/
florian2c74d242012-09-12 19:38:42 +00001417/*--- Rounding modes ---*/
1418/*------------------------------------------------------------*/
1419
florian125e20d2012-10-07 15:42:37 +00001420/* Extract the bfp rounding mode from the guest FPC reg and encode it as an
florian2c74d242012-09-12 19:38:42 +00001421 IRRoundingMode:
1422
1423 rounding mode | s390 | IR
1424 -------------------------
1425 to nearest | 00 | 00
1426 to zero | 01 | 11
1427 to +infinity | 10 | 10
1428 to -infinity | 11 | 01
1429
1430 So: IR = (4 - s390) & 3
1431*/
1432static IRExpr *
florian125e20d2012-10-07 15:42:37 +00001433get_bfp_rounding_mode_from_fpc(void)
florian2c74d242012-09-12 19:38:42 +00001434{
1435 IRTemp fpc_bits = newTemp(Ity_I32);
1436
1437 /* For z196 and later the bfp rounding mode is stored in bits [29:31].
1438 Prior to that bits [30:31] contained the bfp rounding mode with
1439 bit 29 being unused and having a value of 0. So we can always
1440 extract the least significant 3 bits. */
1441 assign(fpc_bits, binop(Iop_And32, get_fpc_w0(), mkU32(7)));
1442
1443 /* fixs390:
1444
1445
1446 if (! s390_host_has_fpext && rounding_mode > 3) {
1447 emulation warning @ runtime and
1448 set fpc to round nearest
1449 }
1450 */
1451
1452 /* For now silently adjust an unsupported rounding mode to "nearest" */
1453 IRExpr *rm_s390 = mkite(binop(Iop_CmpLE32S, mkexpr(fpc_bits), mkU32(3)),
1454 mkexpr(fpc_bits),
florian125e20d2012-10-07 15:42:37 +00001455 mkU32(S390_FPC_BFP_ROUND_NEAREST_EVEN));
florian2c74d242012-09-12 19:38:42 +00001456
1457 // rm_IR = (4 - rm_s390) & 3;
1458 return binop(Iop_And32, binop(Iop_Sub32, mkU32(4), rm_s390), mkU32(3));
1459}
1460
1461/* Encode the s390 rounding mode as it appears in the m3 field of certain
1462 instructions to VEX's IRRoundingMode. Rounding modes that cannot be
1463 represented in VEX are converted to Irrm_NEAREST. The rationale is, that
1464 Irrm_NEAREST refers to IEEE 754's roundTiesToEven which the standard
1465 considers the default rounding mode (4.3.3). */
1466static IRTemp
1467encode_bfp_rounding_mode(UChar mode)
1468{
1469 IRExpr *rm;
1470
1471 switch (mode) {
florian125e20d2012-10-07 15:42:37 +00001472 case S390_BFP_ROUND_PER_FPC:
1473 rm = get_bfp_rounding_mode_from_fpc();
1474 break;
1475 case S390_BFP_ROUND_NEAREST_AWAY: /* not supported */
1476 case S390_BFP_ROUND_PREPARE_SHORT: /* not supported */
1477 case S390_BFP_ROUND_NEAREST_EVEN: rm = mkU32(Irrm_NEAREST); break;
1478 case S390_BFP_ROUND_ZERO: rm = mkU32(Irrm_ZERO); break;
1479 case S390_BFP_ROUND_POSINF: rm = mkU32(Irrm_PosINF); break;
1480 case S390_BFP_ROUND_NEGINF: rm = mkU32(Irrm_NegINF); break;
florian2c74d242012-09-12 19:38:42 +00001481 default:
1482 vpanic("encode_bfp_rounding_mode");
1483 }
1484
1485 return mktemp(Ity_I32, rm);
1486}
1487
florianc8e4f562012-10-27 16:19:31 +00001488/* Extract the DFP rounding mode from the guest FPC reg and encode it as an
1489 IRRoundingMode:
1490
1491 rounding mode | s390 | IR
1492 ------------------------------------------------
1493 to nearest, ties to even | 000 | 000
1494 to zero | 001 | 011
1495 to +infinity | 010 | 010
1496 to -infinity | 011 | 001
1497 to nearest, ties away from 0 | 100 | 100
1498 to nearest, ties toward 0 | 101 | 111
1499 to away from 0 | 110 | 110
1500 to prepare for shorter precision | 111 | 101
1501
1502 So: IR = (s390 ^ ((s390 << 1) & 2))
1503*/
florianc8e4f562012-10-27 16:19:31 +00001504static IRExpr *
1505get_dfp_rounding_mode_from_fpc(void)
1506{
1507 IRTemp fpc_bits = newTemp(Ity_I32);
1508
1509 /* The dfp rounding mode is stored in bits [25:27].
1510 extract the bits at 25:27 and right shift 4 times. */
1511 assign(fpc_bits, binop(Iop_Shr32,
1512 binop(Iop_And32, get_fpc_w0(), mkU32(0x70)),
1513 mkU8(4)));
1514
1515 IRExpr *rm_s390 = mkexpr(fpc_bits);
1516 // rm_IR = (rm_s390 ^ ((rm_s390 << 1) & 2));
1517
1518 return binop(Iop_Xor32, rm_s390,
1519 binop( Iop_And32,
1520 binop(Iop_Shl32, rm_s390, mkU8(1)),
1521 mkU32(2)));
1522}
1523
1524/* Encode the s390 rounding mode as it appears in the m3 field of certain
1525 instructions to VEX's IRRoundingMode. */
1526static IRTemp
1527encode_dfp_rounding_mode(UChar mode)
1528{
1529 IRExpr *rm;
1530
1531 switch (mode) {
1532 case S390_DFP_ROUND_PER_FPC_0:
1533 case S390_DFP_ROUND_PER_FPC_2:
1534 rm = get_dfp_rounding_mode_from_fpc(); break;
1535 case S390_DFP_ROUND_NEAREST_EVEN_4:
1536 case S390_DFP_ROUND_NEAREST_EVEN_8:
1537 rm = mkU32(Irrm_DFP_NEAREST); break;
1538 case S390_DFP_ROUND_NEAREST_TIE_AWAY_0_1:
1539 case S390_DFP_ROUND_NEAREST_TIE_AWAY_0_12:
1540 rm = mkU32(Irrm_DFP_NEAREST_TIE_AWAY_0); break;
1541 case S390_DFP_ROUND_PREPARE_SHORT_3:
1542 case S390_DFP_ROUND_PREPARE_SHORT_15:
1543 rm = mkU32(Irrm_DFP_PREPARE_SHORTER); break;
1544 case S390_DFP_ROUND_ZERO_5:
1545 case S390_DFP_ROUND_ZERO_9:
1546 rm = mkU32(Irrm_DFP_ZERO ); break;
1547 case S390_DFP_ROUND_POSINF_6:
1548 case S390_DFP_ROUND_POSINF_10:
1549 rm = mkU32(Irrm_DFP_PosINF); break;
1550 case S390_DFP_ROUND_NEGINF_7:
1551 case S390_DFP_ROUND_NEGINF_11:
1552 rm = mkU32(Irrm_DFP_NegINF); break;
1553 case S390_DFP_ROUND_NEAREST_TIE_TOWARD_0:
1554 rm = mkU32(Irrm_DFP_NEAREST_TIE_TOWARD_0); break;
1555 case S390_DFP_ROUND_AWAY_0:
1556 rm = mkU32(Irrm_DFP_AWAY_FROM_ZERO); break;
1557 default:
1558 vpanic("encode_dfp_rounding_mode");
1559 }
1560
1561 return mktemp(Ity_I32, rm);
1562}
florian12390202012-11-10 22:34:14 +00001563
florianc8e4f562012-10-27 16:19:31 +00001564
florian2c74d242012-09-12 19:38:42 +00001565/*------------------------------------------------------------*/
sewardj2019a972011-03-07 16:04:07 +00001566/*--- Build IR for formats ---*/
1567/*------------------------------------------------------------*/
1568static void
florian55085f82012-11-21 00:36:55 +00001569s390_format_I(const HChar *(*irgen)(UChar i),
sewardj2019a972011-03-07 16:04:07 +00001570 UChar i)
1571{
florian55085f82012-11-21 00:36:55 +00001572 const HChar *mnm = irgen(i);
sewardj2019a972011-03-07 16:04:07 +00001573
sewardj7ee97522011-05-09 21:45:04 +00001574 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001575 s390_disasm(ENC2(MNM, UINT), mnm, i);
1576}
1577
1578static void
florian55085f82012-11-21 00:36:55 +00001579s390_format_RI(const HChar *(*irgen)(UChar r1, UShort i2),
sewardj2019a972011-03-07 16:04:07 +00001580 UChar r1, UShort i2)
1581{
1582 irgen(r1, i2);
1583}
1584
1585static void
florian55085f82012-11-21 00:36:55 +00001586s390_format_RI_RU(const HChar *(*irgen)(UChar r1, UShort i2),
sewardj2019a972011-03-07 16:04:07 +00001587 UChar r1, UShort i2)
1588{
florian55085f82012-11-21 00:36:55 +00001589 const HChar *mnm = irgen(r1, i2);
sewardj2019a972011-03-07 16:04:07 +00001590
sewardj7ee97522011-05-09 21:45:04 +00001591 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001592 s390_disasm(ENC3(MNM, GPR, UINT), mnm, r1, i2);
1593}
1594
1595static void
florian55085f82012-11-21 00:36:55 +00001596s390_format_RI_RI(const HChar *(*irgen)(UChar r1, UShort i2),
sewardj2019a972011-03-07 16:04:07 +00001597 UChar r1, UShort i2)
1598{
florian55085f82012-11-21 00:36:55 +00001599 const HChar *mnm = irgen(r1, i2);
sewardj2019a972011-03-07 16:04:07 +00001600
sewardj7ee97522011-05-09 21:45:04 +00001601 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001602 s390_disasm(ENC3(MNM, GPR, INT), mnm, r1, (Int)(Short)i2);
1603}
1604
1605static void
florian55085f82012-11-21 00:36:55 +00001606s390_format_RI_RP(const HChar *(*irgen)(UChar r1, UShort i2),
sewardj2019a972011-03-07 16:04:07 +00001607 UChar r1, UShort i2)
1608{
florian55085f82012-11-21 00:36:55 +00001609 const HChar *mnm = irgen(r1, i2);
sewardj2019a972011-03-07 16:04:07 +00001610
sewardj7ee97522011-05-09 21:45:04 +00001611 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001612 s390_disasm(ENC3(MNM, GPR, PCREL), mnm, r1, (Int)(Short)i2);
1613}
1614
1615static void
florian55085f82012-11-21 00:36:55 +00001616s390_format_RIE_RRP(const HChar *(*irgen)(UChar r1, UChar r3, UShort i2),
sewardj2019a972011-03-07 16:04:07 +00001617 UChar r1, UChar r3, UShort i2)
1618{
florian55085f82012-11-21 00:36:55 +00001619 const HChar *mnm = irgen(r1, r3, i2);
sewardj2019a972011-03-07 16:04:07 +00001620
sewardj7ee97522011-05-09 21:45:04 +00001621 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001622 s390_disasm(ENC4(MNM, GPR, GPR, PCREL), mnm, r1, r3, (Int)(Short)i2);
1623}
1624
1625static void
florian55085f82012-11-21 00:36:55 +00001626s390_format_RIE_RRI0(const HChar *(*irgen)(UChar r1, UChar r3, UShort i2),
sewardj2019a972011-03-07 16:04:07 +00001627 UChar r1, UChar r3, UShort i2)
1628{
florian55085f82012-11-21 00:36:55 +00001629 const HChar *mnm = irgen(r1, r3, i2);
sewardj2019a972011-03-07 16:04:07 +00001630
sewardj7ee97522011-05-09 21:45:04 +00001631 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001632 s390_disasm(ENC4(MNM, GPR, GPR, INT), mnm, r1, r3, (Int)(Short)i2);
1633}
1634
1635static void
florian55085f82012-11-21 00:36:55 +00001636s390_format_RIE_RRUUU(const HChar *(*irgen)(UChar r1, UChar r2, UChar i3,
1637 UChar i4, UChar i5),
sewardj2019a972011-03-07 16:04:07 +00001638 UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
1639{
florian55085f82012-11-21 00:36:55 +00001640 const HChar *mnm = irgen(r1, r2, i3, i4, i5);
sewardj2019a972011-03-07 16:04:07 +00001641
sewardj7ee97522011-05-09 21:45:04 +00001642 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001643 s390_disasm(ENC6(MNM, GPR, GPR, UINT, UINT, UINT), mnm, r1, r2, i3, i4,
1644 i5);
1645}
1646
1647static void
florian55085f82012-11-21 00:36:55 +00001648s390_format_RIE_RRPU(const HChar *(*irgen)(UChar r1, UChar r2, UShort i4,
1649 UChar m3),
sewardj2019a972011-03-07 16:04:07 +00001650 UChar r1, UChar r2, UShort i4, UChar m3)
1651{
florian55085f82012-11-21 00:36:55 +00001652 const HChar *mnm = irgen(r1, r2, i4, m3);
sewardj2019a972011-03-07 16:04:07 +00001653
sewardj7ee97522011-05-09 21:45:04 +00001654 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001655 s390_disasm(ENC5(XMNM, GPR, GPR, CABM, PCREL), S390_XMNM_CAB, mnm, m3, r1,
1656 r2, m3, (Int)(Short)i4);
1657}
1658
1659static void
florian55085f82012-11-21 00:36:55 +00001660s390_format_RIE_RUPU(const HChar *(*irgen)(UChar r1, UChar m3, UShort i4,
1661 UChar i2),
sewardj2019a972011-03-07 16:04:07 +00001662 UChar r1, UChar m3, UShort i4, UChar i2)
1663{
florian55085f82012-11-21 00:36:55 +00001664 const HChar *mnm = irgen(r1, m3, i4, i2);
sewardj2019a972011-03-07 16:04:07 +00001665
sewardj7ee97522011-05-09 21:45:04 +00001666 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001667 s390_disasm(ENC5(XMNM, GPR, UINT, CABM, PCREL), S390_XMNM_CAB, mnm, m3,
1668 r1, i2, m3, (Int)(Short)i4);
1669}
1670
1671static void
florian55085f82012-11-21 00:36:55 +00001672s390_format_RIE_RUPI(const HChar *(*irgen)(UChar r1, UChar m3, UShort i4,
1673 UChar i2),
sewardj2019a972011-03-07 16:04:07 +00001674 UChar r1, UChar m3, UShort i4, UChar i2)
1675{
florian55085f82012-11-21 00:36:55 +00001676 const HChar *mnm = irgen(r1, m3, i4, i2);
sewardj2019a972011-03-07 16:04:07 +00001677
sewardj7ee97522011-05-09 21:45:04 +00001678 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001679 s390_disasm(ENC5(XMNM, GPR, INT, CABM, PCREL), S390_XMNM_CAB, mnm, m3, r1,
1680 (Int)(Char)i2, m3, (Int)(Short)i4);
1681}
1682
1683static void
florian55085f82012-11-21 00:36:55 +00001684s390_format_RIL(const HChar *(*irgen)(UChar r1, UInt i2),
sewardj2019a972011-03-07 16:04:07 +00001685 UChar r1, UInt i2)
1686{
1687 irgen(r1, i2);
1688}
1689
1690static void
florian55085f82012-11-21 00:36:55 +00001691s390_format_RIL_RU(const HChar *(*irgen)(UChar r1, UInt i2),
sewardj2019a972011-03-07 16:04:07 +00001692 UChar r1, UInt i2)
1693{
florian55085f82012-11-21 00:36:55 +00001694 const HChar *mnm = irgen(r1, i2);
sewardj2019a972011-03-07 16:04:07 +00001695
sewardj7ee97522011-05-09 21:45:04 +00001696 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001697 s390_disasm(ENC3(MNM, GPR, UINT), mnm, r1, i2);
1698}
1699
1700static void
florian55085f82012-11-21 00:36:55 +00001701s390_format_RIL_RI(const HChar *(*irgen)(UChar r1, UInt i2),
sewardj2019a972011-03-07 16:04:07 +00001702 UChar r1, UInt i2)
1703{
florian55085f82012-11-21 00:36:55 +00001704 const HChar *mnm = irgen(r1, i2);
sewardj2019a972011-03-07 16:04:07 +00001705
sewardj7ee97522011-05-09 21:45:04 +00001706 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001707 s390_disasm(ENC3(MNM, GPR, INT), mnm, r1, i2);
1708}
1709
1710static void
florian55085f82012-11-21 00:36:55 +00001711s390_format_RIL_RP(const HChar *(*irgen)(UChar r1, UInt i2),
sewardj2019a972011-03-07 16:04:07 +00001712 UChar r1, UInt i2)
1713{
florian55085f82012-11-21 00:36:55 +00001714 const HChar *mnm = irgen(r1, i2);
sewardj2019a972011-03-07 16:04:07 +00001715
sewardj7ee97522011-05-09 21:45:04 +00001716 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001717 s390_disasm(ENC3(MNM, GPR, PCREL), mnm, r1, i2);
1718}
1719
1720static void
florian55085f82012-11-21 00:36:55 +00001721s390_format_RIL_UP(const HChar *(*irgen)(void),
sewardj2019a972011-03-07 16:04:07 +00001722 UChar r1, UInt i2)
1723{
florian55085f82012-11-21 00:36:55 +00001724 const HChar *mnm = irgen();
sewardj2019a972011-03-07 16:04:07 +00001725
sewardj7ee97522011-05-09 21:45:04 +00001726 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001727 s390_disasm(ENC3(MNM, UINT, PCREL), mnm, r1, i2);
1728}
1729
1730static void
florian55085f82012-11-21 00:36:55 +00001731s390_format_RIS_RURDI(const HChar *(*irgen)(UChar r1, UChar m3, UChar i2,
sewardj2019a972011-03-07 16:04:07 +00001732 IRTemp op4addr),
1733 UChar r1, UChar m3, UChar b4, UShort d4, UChar i2)
1734{
florian55085f82012-11-21 00:36:55 +00001735 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00001736 IRTemp op4addr = newTemp(Ity_I64);
1737
1738 assign(op4addr, binop(Iop_Add64, mkU64(d4), b4 != 0 ? get_gpr_dw0(b4) :
1739 mkU64(0)));
1740
1741 mnm = irgen(r1, m3, i2, op4addr);
1742
sewardj7ee97522011-05-09 21:45:04 +00001743 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001744 s390_disasm(ENC5(XMNM, GPR, INT, CABM, UDXB), S390_XMNM_CAB, mnm, m3, r1,
1745 (Int)(Char)i2, m3, d4, 0, b4);
1746}
1747
1748static void
florian55085f82012-11-21 00:36:55 +00001749s390_format_RIS_RURDU(const HChar *(*irgen)(UChar r1, UChar m3, UChar i2,
sewardj2019a972011-03-07 16:04:07 +00001750 IRTemp op4addr),
1751 UChar r1, UChar m3, UChar b4, UShort d4, UChar i2)
1752{
florian55085f82012-11-21 00:36:55 +00001753 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00001754 IRTemp op4addr = newTemp(Ity_I64);
1755
1756 assign(op4addr, binop(Iop_Add64, mkU64(d4), b4 != 0 ? get_gpr_dw0(b4) :
1757 mkU64(0)));
1758
1759 mnm = irgen(r1, m3, i2, op4addr);
1760
sewardj7ee97522011-05-09 21:45:04 +00001761 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001762 s390_disasm(ENC5(XMNM, GPR, UINT, CABM, UDXB), S390_XMNM_CAB, mnm, m3, r1,
1763 i2, m3, d4, 0, b4);
1764}
1765
1766static void
florian55085f82012-11-21 00:36:55 +00001767s390_format_RR(const HChar *(*irgen)(UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00001768 UChar r1, UChar r2)
1769{
1770 irgen(r1, r2);
1771}
1772
1773static void
florian55085f82012-11-21 00:36:55 +00001774s390_format_RR_RR(const HChar *(*irgen)(UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00001775 UChar r1, UChar r2)
1776{
florian55085f82012-11-21 00:36:55 +00001777 const HChar *mnm = irgen(r1, r2);
sewardj2019a972011-03-07 16:04:07 +00001778
sewardj7ee97522011-05-09 21:45:04 +00001779 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001780 s390_disasm(ENC3(MNM, GPR, GPR), mnm, r1, r2);
1781}
1782
1783static void
florian55085f82012-11-21 00:36:55 +00001784s390_format_RR_FF(const HChar *(*irgen)(UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00001785 UChar r1, UChar r2)
1786{
florian55085f82012-11-21 00:36:55 +00001787 const HChar *mnm = irgen(r1, r2);
sewardj2019a972011-03-07 16:04:07 +00001788
sewardj7ee97522011-05-09 21:45:04 +00001789 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001790 s390_disasm(ENC3(MNM, FPR, FPR), mnm, r1, r2);
1791}
1792
1793static void
florian55085f82012-11-21 00:36:55 +00001794s390_format_RRE(const HChar *(*irgen)(UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00001795 UChar r1, UChar r2)
1796{
1797 irgen(r1, r2);
1798}
1799
1800static void
florian55085f82012-11-21 00:36:55 +00001801s390_format_RRE_RR(const HChar *(*irgen)(UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00001802 UChar r1, UChar r2)
1803{
florian55085f82012-11-21 00:36:55 +00001804 const HChar *mnm = irgen(r1, r2);
sewardj2019a972011-03-07 16:04:07 +00001805
sewardj7ee97522011-05-09 21:45:04 +00001806 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001807 s390_disasm(ENC3(MNM, GPR, GPR), mnm, r1, r2);
1808}
1809
1810static void
florian55085f82012-11-21 00:36:55 +00001811s390_format_RRE_FF(const HChar *(*irgen)(UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00001812 UChar r1, UChar r2)
1813{
florian55085f82012-11-21 00:36:55 +00001814 const HChar *mnm = irgen(r1, r2);
sewardj2019a972011-03-07 16:04:07 +00001815
sewardj7ee97522011-05-09 21:45:04 +00001816 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001817 s390_disasm(ENC3(MNM, FPR, FPR), mnm, r1, r2);
1818}
1819
1820static void
florian55085f82012-11-21 00:36:55 +00001821s390_format_RRE_RF(const HChar *(*irgen)(UChar, UChar),
sewardj2019a972011-03-07 16:04:07 +00001822 UChar r1, UChar r2)
1823{
florian55085f82012-11-21 00:36:55 +00001824 const HChar *mnm = irgen(r1, r2);
sewardj2019a972011-03-07 16:04:07 +00001825
sewardj7ee97522011-05-09 21:45:04 +00001826 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001827 s390_disasm(ENC3(MNM, GPR, FPR), mnm, r1, r2);
1828}
1829
1830static void
florian55085f82012-11-21 00:36:55 +00001831s390_format_RRE_FR(const HChar *(*irgen)(UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00001832 UChar r1, UChar r2)
1833{
florian55085f82012-11-21 00:36:55 +00001834 const HChar *mnm = irgen(r1, r2);
sewardj2019a972011-03-07 16:04:07 +00001835
sewardj7ee97522011-05-09 21:45:04 +00001836 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001837 s390_disasm(ENC3(MNM, FPR, GPR), mnm, r1, r2);
1838}
1839
1840static void
florian55085f82012-11-21 00:36:55 +00001841s390_format_RRE_R0(const HChar *(*irgen)(UChar r1),
sewardj2019a972011-03-07 16:04:07 +00001842 UChar r1)
1843{
florian55085f82012-11-21 00:36:55 +00001844 const HChar *mnm = irgen(r1);
sewardj2019a972011-03-07 16:04:07 +00001845
sewardj7ee97522011-05-09 21:45:04 +00001846 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001847 s390_disasm(ENC2(MNM, GPR), mnm, r1);
1848}
1849
1850static void
florian55085f82012-11-21 00:36:55 +00001851s390_format_RRE_F0(const HChar *(*irgen)(UChar r1),
sewardj2019a972011-03-07 16:04:07 +00001852 UChar r1)
1853{
florian55085f82012-11-21 00:36:55 +00001854 const HChar *mnm = irgen(r1);
sewardj2019a972011-03-07 16:04:07 +00001855
sewardj7ee97522011-05-09 21:45:04 +00001856 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001857 s390_disasm(ENC2(MNM, FPR), mnm, r1);
1858}
1859
1860static void
florian55085f82012-11-21 00:36:55 +00001861s390_format_RRF_M0RERE(const HChar *(*irgen)(UChar m3, UChar r1, UChar r2),
florian9af37692012-01-15 21:01:16 +00001862 UChar m3, UChar r1, UChar r2)
1863{
florian55085f82012-11-21 00:36:55 +00001864 const HChar *mnm = irgen(m3, r1, r2);
florian9af37692012-01-15 21:01:16 +00001865
1866 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
florianfed3ea32012-07-19 14:54:03 +00001867 s390_disasm(ENC4(MNM, GPR, GPR, UINT), mnm, r1, r2, m3);
florian9af37692012-01-15 21:01:16 +00001868}
1869
1870static void
florian55085f82012-11-21 00:36:55 +00001871s390_format_RRF_F0FF(const HChar *(*irgen)(UChar, UChar, UChar),
sewardj2019a972011-03-07 16:04:07 +00001872 UChar r1, UChar r3, UChar r2)
1873{
florian55085f82012-11-21 00:36:55 +00001874 const HChar *mnm = irgen(r1, r3, r2);
sewardj2019a972011-03-07 16:04:07 +00001875
sewardj7ee97522011-05-09 21:45:04 +00001876 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001877 s390_disasm(ENC4(MNM, FPR, FPR, FPR), mnm, r1, r3, r2);
1878}
1879
1880static void
florian55085f82012-11-21 00:36:55 +00001881s390_format_RRF_UUFF(const HChar *(*irgen)(UChar m3, UChar m4, UChar r1,
1882 UChar r2),
florian4b8efad2012-09-02 18:07:08 +00001883 UChar m3, UChar m4, UChar r1, UChar r2)
1884{
florian55085f82012-11-21 00:36:55 +00001885 const HChar *mnm = irgen(m3, m4, r1, r2);
florian4b8efad2012-09-02 18:07:08 +00001886
1887 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
1888 s390_disasm(ENC5(MNM, FPR, UINT, FPR, UINT), mnm, r1, m3, r2, m4);
1889}
1890
1891static void
florian55085f82012-11-21 00:36:55 +00001892s390_format_RRF_UUFR(const HChar *(*irgen)(UChar m3, UChar m4, UChar r1,
1893 UChar r2),
florian1c8f7ff2012-09-01 00:12:11 +00001894 UChar m3, UChar m4, UChar r1, UChar r2)
1895{
florian55085f82012-11-21 00:36:55 +00001896 const HChar *mnm = irgen(m3, m4, r1, r2);
florian1c8f7ff2012-09-01 00:12:11 +00001897
1898 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
1899 s390_disasm(ENC5(MNM, FPR, UINT, GPR, UINT), mnm, r1, m3, r2, m4);
1900}
1901
1902static void
florian55085f82012-11-21 00:36:55 +00001903s390_format_RRF_UURF(const HChar *(*irgen)(UChar m3, UChar m4, UChar r1,
1904 UChar r2),
florian1c8f7ff2012-09-01 00:12:11 +00001905 UChar m3, UChar m4, UChar r1, UChar r2)
1906{
florian55085f82012-11-21 00:36:55 +00001907 const HChar *mnm = irgen(m3, m4, r1, r2);
florian1c8f7ff2012-09-01 00:12:11 +00001908
1909 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
1910 s390_disasm(ENC5(MNM, GPR, UINT, FPR, UINT), mnm, r1, m3, r2, m4);
1911}
1912
1913
1914static void
florian55085f82012-11-21 00:36:55 +00001915s390_format_RRF_U0RR(const HChar *(*irgen)(UChar m3, UChar r1, UChar r2),
sewardjd7bde722011-04-05 13:19:33 +00001916 UChar m3, UChar r1, UChar r2, Int xmnm_kind)
1917{
1918 irgen(m3, r1, r2);
1919
sewardj7ee97522011-05-09 21:45:04 +00001920 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardjd7bde722011-04-05 13:19:33 +00001921 s390_disasm(ENC3(XMNM, GPR, GPR), xmnm_kind, m3, r1, r2);
1922}
1923
1924static void
florian55085f82012-11-21 00:36:55 +00001925s390_format_RRF_F0FF2(const HChar *(*irgen)(UChar, UChar, UChar),
sewardj2019a972011-03-07 16:04:07 +00001926 UChar r3, UChar r1, UChar r2)
1927{
florian55085f82012-11-21 00:36:55 +00001928 const HChar *mnm = irgen(r3, r1, r2);
sewardj2019a972011-03-07 16:04:07 +00001929
sewardj7ee97522011-05-09 21:45:04 +00001930 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001931 s390_disasm(ENC4(MNM, FPR, FPR, FPR), mnm, r1, r3, r2);
1932}
1933
1934static void
florian55085f82012-11-21 00:36:55 +00001935s390_format_RRF_FUFF2(const HChar *(*irgen)(UChar, UChar, UChar, UChar),
florian12390202012-11-10 22:34:14 +00001936 UChar r3, UChar m4, UChar r1, UChar r2)
1937{
florian55085f82012-11-21 00:36:55 +00001938 const HChar *mnm = irgen(r3, m4, r1, r2);
florian12390202012-11-10 22:34:14 +00001939
1940 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
1941 s390_disasm(ENC5(MNM, FPR, FPR, FPR, UINT), mnm, r1, r2, r3, m4);
1942}
1943
1944static void
florian55085f82012-11-21 00:36:55 +00001945s390_format_RRF_R0RR2(const HChar *(*irgen)(UChar r3, UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00001946 UChar r3, UChar r1, UChar r2)
1947{
florian55085f82012-11-21 00:36:55 +00001948 const HChar *mnm = irgen(r3, r1, r2);
sewardj2019a972011-03-07 16:04:07 +00001949
sewardj7ee97522011-05-09 21:45:04 +00001950 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001951 s390_disasm(ENC4(MNM, GPR, GPR, GPR), mnm, r1, r2, r3);
1952}
1953
1954static void
florian55085f82012-11-21 00:36:55 +00001955s390_format_RRS(const HChar *(*irgen)(UChar r1, UChar r2, UChar m3,
1956 IRTemp op4addr),
sewardj2019a972011-03-07 16:04:07 +00001957 UChar r1, UChar r2, UChar b4, UShort d4, UChar m3)
1958{
florian55085f82012-11-21 00:36:55 +00001959 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00001960 IRTemp op4addr = newTemp(Ity_I64);
1961
1962 assign(op4addr, binop(Iop_Add64, mkU64(d4), b4 != 0 ? get_gpr_dw0(b4) :
1963 mkU64(0)));
1964
1965 mnm = irgen(r1, r2, m3, op4addr);
1966
sewardj7ee97522011-05-09 21:45:04 +00001967 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001968 s390_disasm(ENC5(XMNM, GPR, GPR, CABM, UDXB), S390_XMNM_CAB, mnm, m3, r1,
1969 r2, m3, d4, 0, b4);
1970}
1971
1972static void
florian55085f82012-11-21 00:36:55 +00001973s390_format_RS_R0RD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00001974 UChar r1, UChar b2, UShort d2)
1975{
florian55085f82012-11-21 00:36:55 +00001976 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00001977 IRTemp op2addr = newTemp(Ity_I64);
1978
1979 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
1980 mkU64(0)));
1981
1982 mnm = irgen(r1, op2addr);
1983
sewardj7ee97522011-05-09 21:45:04 +00001984 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001985 s390_disasm(ENC3(MNM, GPR, UDXB), mnm, r1, d2, 0, b2);
1986}
1987
1988static void
florian55085f82012-11-21 00:36:55 +00001989s390_format_RS_RRRD(const HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00001990 UChar r1, UChar r3, UChar b2, UShort d2)
1991{
florian55085f82012-11-21 00:36:55 +00001992 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00001993 IRTemp op2addr = newTemp(Ity_I64);
1994
1995 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
1996 mkU64(0)));
1997
1998 mnm = irgen(r1, r3, op2addr);
1999
sewardj7ee97522011-05-09 21:45:04 +00002000 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002001 s390_disasm(ENC4(MNM, GPR, GPR, UDXB), mnm, r1, r3, d2, 0, b2);
2002}
2003
2004static void
florian55085f82012-11-21 00:36:55 +00002005s390_format_RS_RURD(const HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002006 UChar r1, UChar r3, UChar b2, UShort d2)
2007{
florian55085f82012-11-21 00:36:55 +00002008 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002009 IRTemp op2addr = newTemp(Ity_I64);
2010
2011 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2012 mkU64(0)));
2013
2014 mnm = irgen(r1, r3, op2addr);
2015
sewardj7ee97522011-05-09 21:45:04 +00002016 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002017 s390_disasm(ENC4(MNM, GPR, UINT, UDXB), mnm, r1, r3, d2, 0, b2);
2018}
2019
2020static void
florian55085f82012-11-21 00:36:55 +00002021s390_format_RS_AARD(const HChar *(*irgen)(UChar, UChar, IRTemp),
sewardj2019a972011-03-07 16:04:07 +00002022 UChar r1, UChar r3, UChar b2, UShort d2)
2023{
florian55085f82012-11-21 00:36:55 +00002024 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002025 IRTemp op2addr = newTemp(Ity_I64);
2026
2027 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2028 mkU64(0)));
2029
2030 mnm = irgen(r1, r3, op2addr);
2031
sewardj7ee97522011-05-09 21:45:04 +00002032 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002033 s390_disasm(ENC4(MNM, AR, AR, UDXB), mnm, r1, r3, d2, 0, b2);
2034}
2035
2036static void
florian55085f82012-11-21 00:36:55 +00002037s390_format_RSI_RRP(const HChar *(*irgen)(UChar r1, UChar r3, UShort i2),
sewardj2019a972011-03-07 16:04:07 +00002038 UChar r1, UChar r3, UShort i2)
2039{
florian55085f82012-11-21 00:36:55 +00002040 const HChar *mnm = irgen(r1, r3, i2);
sewardj2019a972011-03-07 16:04:07 +00002041
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, GPR, GPR, PCREL), mnm, r1, r3, (Int)(Short)i2);
2044}
2045
2046static void
florian55085f82012-11-21 00:36:55 +00002047s390_format_RSY_RRRD(const HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002048 UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2)
2049{
florian55085f82012-11-21 00:36:55 +00002050 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002051 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, GPR, SDXB), mnm, r1, r3, dh2, dl2, 0, b2);
2062}
2063
2064static void
florian55085f82012-11-21 00:36:55 +00002065s390_format_RSY_AARD(const HChar *(*irgen)(UChar, UChar, IRTemp),
sewardj2019a972011-03-07 16:04:07 +00002066 UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2)
2067{
florian55085f82012-11-21 00:36:55 +00002068 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002069 IRTemp op2addr = newTemp(Ity_I64);
2070 IRTemp d2 = newTemp(Ity_I64);
2071
2072 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2073 assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
2074 mkU64(0)));
2075
2076 mnm = irgen(r1, r3, op2addr);
2077
sewardj7ee97522011-05-09 21:45:04 +00002078 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002079 s390_disasm(ENC4(MNM, AR, AR, SDXB), mnm, r1, r3, dh2, dl2, 0, b2);
2080}
2081
2082static void
florian55085f82012-11-21 00:36:55 +00002083s390_format_RSY_RURD(const HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002084 UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2)
2085{
florian55085f82012-11-21 00:36:55 +00002086 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002087 IRTemp op2addr = newTemp(Ity_I64);
2088 IRTemp d2 = newTemp(Ity_I64);
2089
2090 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2091 assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
2092 mkU64(0)));
2093
2094 mnm = irgen(r1, r3, op2addr);
2095
sewardj7ee97522011-05-09 21:45:04 +00002096 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002097 s390_disasm(ENC4(MNM, GPR, UINT, SDXB), mnm, r1, r3, dh2, dl2, 0, b2);
2098}
2099
2100static void
florian55085f82012-11-21 00:36:55 +00002101s390_format_RSY_RDRM(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
sewardjd7bde722011-04-05 13:19:33 +00002102 UChar r1, UChar m3, UChar b2, UShort dl2, UChar dh2,
2103 Int xmnm_kind)
2104{
2105 IRTemp op2addr = newTemp(Ity_I64);
2106 IRTemp d2 = newTemp(Ity_I64);
2107
florian6820ba52012-07-26 02:01:50 +00002108 next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0)));
2109
sewardjd7bde722011-04-05 13:19:33 +00002110 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2111 assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
2112 mkU64(0)));
2113
2114 irgen(r1, op2addr);
florian6820ba52012-07-26 02:01:50 +00002115
2116 vassert(dis_res->whatNext == Dis_Continue);
sewardjd7bde722011-04-05 13:19:33 +00002117
sewardj7ee97522011-05-09 21:45:04 +00002118 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardjd7bde722011-04-05 13:19:33 +00002119 s390_disasm(ENC3(XMNM, GPR, SDXB), xmnm_kind, m3, r1, dh2, dl2, 0, b2);
2120}
2121
2122static void
florian55085f82012-11-21 00:36:55 +00002123s390_format_RX(const HChar *(*irgen)(UChar r1, UChar x2, UChar b2, UShort d2,
sewardj2019a972011-03-07 16:04:07 +00002124 IRTemp op2addr),
2125 UChar r1, UChar x2, UChar b2, UShort d2)
2126{
2127 IRTemp op2addr = newTemp(Ity_I64);
2128
2129 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
2130 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2131 mkU64(0)));
2132
2133 irgen(r1, x2, b2, d2, op2addr);
2134}
2135
2136static void
florian55085f82012-11-21 00:36:55 +00002137s390_format_RX_RRRD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002138 UChar r1, UChar x2, UChar b2, UShort d2)
2139{
florian55085f82012-11-21 00:36:55 +00002140 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002141 IRTemp op2addr = newTemp(Ity_I64);
2142
2143 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
2144 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2145 mkU64(0)));
2146
2147 mnm = irgen(r1, op2addr);
2148
sewardj7ee97522011-05-09 21:45:04 +00002149 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002150 s390_disasm(ENC3(MNM, GPR, UDXB), mnm, r1, d2, x2, b2);
2151}
2152
2153static void
florian55085f82012-11-21 00:36:55 +00002154s390_format_RX_FRRD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002155 UChar r1, UChar x2, UChar b2, UShort d2)
2156{
florian55085f82012-11-21 00:36:55 +00002157 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002158 IRTemp op2addr = newTemp(Ity_I64);
2159
2160 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
2161 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2162 mkU64(0)));
2163
2164 mnm = irgen(r1, op2addr);
2165
sewardj7ee97522011-05-09 21:45:04 +00002166 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002167 s390_disasm(ENC3(MNM, FPR, UDXB), mnm, r1, d2, x2, b2);
2168}
2169
2170static void
florian55085f82012-11-21 00:36:55 +00002171s390_format_RXE_FRRD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002172 UChar r1, UChar x2, UChar b2, UShort d2)
2173{
florian55085f82012-11-21 00:36:55 +00002174 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002175 IRTemp op2addr = newTemp(Ity_I64);
2176
2177 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(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, FPR, UDXB), mnm, r1, d2, x2, b2);
2185}
2186
2187static void
florian55085f82012-11-21 00:36:55 +00002188s390_format_RXF_FRRDF(const HChar *(*irgen)(UChar, IRTemp, UChar),
sewardj2019a972011-03-07 16:04:07 +00002189 UChar r3, UChar x2, UChar b2, UShort d2, UChar r1)
2190{
florian55085f82012-11-21 00:36:55 +00002191 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002192 IRTemp op2addr = newTemp(Ity_I64);
2193
2194 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
2195 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2196 mkU64(0)));
2197
2198 mnm = irgen(r3, op2addr, r1);
2199
sewardj7ee97522011-05-09 21:45:04 +00002200 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002201 s390_disasm(ENC4(MNM, FPR, FPR, UDXB), mnm, r1, r3, d2, x2, b2);
2202}
2203
2204static void
florian55085f82012-11-21 00:36:55 +00002205s390_format_RXY_RRRD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002206 UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
2207{
florian55085f82012-11-21 00:36:55 +00002208 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002209 IRTemp op2addr = newTemp(Ity_I64);
2210 IRTemp d2 = newTemp(Ity_I64);
2211
2212 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2213 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkexpr(d2),
2214 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2215 mkU64(0)));
2216
2217 mnm = irgen(r1, op2addr);
2218
sewardj7ee97522011-05-09 21:45:04 +00002219 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002220 s390_disasm(ENC3(MNM, GPR, SDXB), mnm, r1, dh2, dl2, x2, b2);
2221}
2222
2223static void
florian55085f82012-11-21 00:36:55 +00002224s390_format_RXY_FRRD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002225 UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
2226{
florian55085f82012-11-21 00:36:55 +00002227 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002228 IRTemp op2addr = newTemp(Ity_I64);
2229 IRTemp d2 = newTemp(Ity_I64);
2230
2231 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2232 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkexpr(d2),
2233 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2234 mkU64(0)));
2235
2236 mnm = irgen(r1, op2addr);
2237
sewardj7ee97522011-05-09 21:45:04 +00002238 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002239 s390_disasm(ENC3(MNM, FPR, SDXB), mnm, r1, dh2, dl2, x2, b2);
2240}
2241
2242static void
florian55085f82012-11-21 00:36:55 +00002243s390_format_RXY_URRD(const HChar *(*irgen)(void),
sewardj2019a972011-03-07 16:04:07 +00002244 UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
2245{
florian55085f82012-11-21 00:36:55 +00002246 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002247 IRTemp op2addr = newTemp(Ity_I64);
2248 IRTemp d2 = newTemp(Ity_I64);
2249
2250 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2251 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkexpr(d2),
2252 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2253 mkU64(0)));
2254
2255 mnm = irgen();
2256
sewardj7ee97522011-05-09 21:45:04 +00002257 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002258 s390_disasm(ENC3(MNM, UINT, SDXB), mnm, r1, dh2, dl2, x2, b2);
2259}
2260
2261static void
florian55085f82012-11-21 00:36:55 +00002262s390_format_S_RD(const HChar *(*irgen)(IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002263 UChar b2, UShort d2)
2264{
florian55085f82012-11-21 00:36:55 +00002265 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002266 IRTemp op2addr = newTemp(Ity_I64);
2267
2268 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2269 mkU64(0)));
2270
2271 mnm = irgen(op2addr);
2272
sewardj7ee97522011-05-09 21:45:04 +00002273 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002274 s390_disasm(ENC2(MNM, UDXB), mnm, d2, 0, b2);
2275}
2276
2277static void
florian55085f82012-11-21 00:36:55 +00002278s390_format_SI_URD(const HChar *(*irgen)(UChar i2, IRTemp op1addr),
sewardj2019a972011-03-07 16:04:07 +00002279 UChar i2, UChar b1, UShort d1)
2280{
florian55085f82012-11-21 00:36:55 +00002281 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002282 IRTemp op1addr = newTemp(Ity_I64);
2283
2284 assign(op1addr, binop(Iop_Add64, mkU64(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, UDXB, UINT), mnm, d1, 0, b1, i2);
2291}
2292
2293static void
florian55085f82012-11-21 00:36:55 +00002294s390_format_SIY_URD(const HChar *(*irgen)(UChar i2, IRTemp op1addr),
sewardj2019a972011-03-07 16:04:07 +00002295 UChar i2, UChar b1, UShort dl1, UChar dh1)
2296{
florian55085f82012-11-21 00:36:55 +00002297 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002298 IRTemp op1addr = newTemp(Ity_I64);
2299 IRTemp d1 = newTemp(Ity_I64);
2300
2301 assign(d1, mkU64(((ULong)(Long)(Char)dh1 << 12) | ((ULong)dl1)));
2302 assign(op1addr, binop(Iop_Add64, mkexpr(d1), b1 != 0 ? get_gpr_dw0(b1) :
2303 mkU64(0)));
2304
2305 mnm = irgen(i2, op1addr);
2306
sewardj7ee97522011-05-09 21:45:04 +00002307 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002308 s390_disasm(ENC3(MNM, SDXB, UINT), mnm, dh1, dl1, 0, b1, i2);
2309}
2310
2311static void
florian55085f82012-11-21 00:36:55 +00002312s390_format_SIY_IRD(const HChar *(*irgen)(UChar i2, IRTemp op1addr),
sewardj2019a972011-03-07 16:04:07 +00002313 UChar i2, UChar b1, UShort dl1, UChar dh1)
2314{
florian55085f82012-11-21 00:36:55 +00002315 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002316 IRTemp op1addr = newTemp(Ity_I64);
2317 IRTemp d1 = newTemp(Ity_I64);
2318
2319 assign(d1, mkU64(((ULong)(Long)(Char)dh1 << 12) | ((ULong)dl1)));
2320 assign(op1addr, binop(Iop_Add64, mkexpr(d1), b1 != 0 ? get_gpr_dw0(b1) :
2321 mkU64(0)));
2322
2323 mnm = irgen(i2, op1addr);
2324
sewardj7ee97522011-05-09 21:45:04 +00002325 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002326 s390_disasm(ENC3(MNM, SDXB, INT), mnm, dh1, dl1, 0, b1, (Int)(Char)i2);
2327}
2328
2329static void
florian55085f82012-11-21 00:36:55 +00002330s390_format_SS_L0RDRD(const HChar *(*irgen)(UChar, IRTemp, IRTemp),
sewardj2019a972011-03-07 16:04:07 +00002331 UChar l, UChar b1, UShort d1, UChar b2, UShort d2)
2332{
florian55085f82012-11-21 00:36:55 +00002333 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002334 IRTemp op1addr = newTemp(Ity_I64);
2335 IRTemp op2addr = newTemp(Ity_I64);
2336
2337 assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
2338 mkU64(0)));
2339 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2340 mkU64(0)));
2341
2342 mnm = irgen(l, op1addr, op2addr);
2343
sewardj7ee97522011-05-09 21:45:04 +00002344 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002345 s390_disasm(ENC3(MNM, UDLB, UDXB), mnm, d1, l, b1, d2, 0, b2);
2346}
2347
2348static void
florian55085f82012-11-21 00:36:55 +00002349s390_format_SIL_RDI(const HChar *(*irgen)(UShort i2, IRTemp op1addr),
sewardj2019a972011-03-07 16:04:07 +00002350 UChar b1, UShort d1, UShort i2)
2351{
florian55085f82012-11-21 00:36:55 +00002352 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002353 IRTemp op1addr = newTemp(Ity_I64);
2354
2355 assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
2356 mkU64(0)));
2357
2358 mnm = irgen(i2, op1addr);
2359
sewardj7ee97522011-05-09 21:45:04 +00002360 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002361 s390_disasm(ENC3(MNM, UDXB, INT), mnm, d1, 0, b1, (Int)(Short)i2);
2362}
2363
2364static void
florian55085f82012-11-21 00:36:55 +00002365s390_format_SIL_RDU(const HChar *(*irgen)(UShort i2, IRTemp op1addr),
sewardj2019a972011-03-07 16:04:07 +00002366 UChar b1, UShort d1, UShort i2)
2367{
florian55085f82012-11-21 00:36:55 +00002368 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002369 IRTemp op1addr = newTemp(Ity_I64);
2370
2371 assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
2372 mkU64(0)));
2373
2374 mnm = irgen(i2, op1addr);
2375
sewardj7ee97522011-05-09 21:45:04 +00002376 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002377 s390_disasm(ENC3(MNM, UDXB, UINT), mnm, d1, 0, b1, i2);
2378}
2379
2380
2381
2382/*------------------------------------------------------------*/
2383/*--- Build IR for opcodes ---*/
2384/*------------------------------------------------------------*/
2385
florian55085f82012-11-21 00:36:55 +00002386static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002387s390_irgen_AR(UChar r1, UChar r2)
2388{
2389 IRTemp op1 = newTemp(Ity_I32);
2390 IRTemp op2 = newTemp(Ity_I32);
2391 IRTemp result = newTemp(Ity_I32);
2392
2393 assign(op1, get_gpr_w1(r1));
2394 assign(op2, get_gpr_w1(r2));
2395 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2396 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2397 put_gpr_w1(r1, mkexpr(result));
2398
2399 return "ar";
2400}
2401
florian55085f82012-11-21 00:36:55 +00002402static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002403s390_irgen_AGR(UChar r1, UChar r2)
2404{
2405 IRTemp op1 = newTemp(Ity_I64);
2406 IRTemp op2 = newTemp(Ity_I64);
2407 IRTemp result = newTemp(Ity_I64);
2408
2409 assign(op1, get_gpr_dw0(r1));
2410 assign(op2, get_gpr_dw0(r2));
2411 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2412 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
2413 put_gpr_dw0(r1, mkexpr(result));
2414
2415 return "agr";
2416}
2417
florian55085f82012-11-21 00:36:55 +00002418static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002419s390_irgen_AGFR(UChar r1, UChar r2)
2420{
2421 IRTemp op1 = newTemp(Ity_I64);
2422 IRTemp op2 = newTemp(Ity_I64);
2423 IRTemp result = newTemp(Ity_I64);
2424
2425 assign(op1, get_gpr_dw0(r1));
2426 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
2427 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2428 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
2429 put_gpr_dw0(r1, mkexpr(result));
2430
2431 return "agfr";
2432}
2433
florian55085f82012-11-21 00:36:55 +00002434static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002435s390_irgen_ARK(UChar r3, UChar r1, UChar r2)
2436{
2437 IRTemp op2 = newTemp(Ity_I32);
2438 IRTemp op3 = newTemp(Ity_I32);
2439 IRTemp result = newTemp(Ity_I32);
2440
2441 assign(op2, get_gpr_w1(r2));
2442 assign(op3, get_gpr_w1(r3));
2443 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2444 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
2445 put_gpr_w1(r1, mkexpr(result));
2446
2447 return "ark";
2448}
2449
florian55085f82012-11-21 00:36:55 +00002450static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002451s390_irgen_AGRK(UChar r3, UChar r1, UChar r2)
2452{
2453 IRTemp op2 = newTemp(Ity_I64);
2454 IRTemp op3 = newTemp(Ity_I64);
2455 IRTemp result = newTemp(Ity_I64);
2456
2457 assign(op2, get_gpr_dw0(r2));
2458 assign(op3, get_gpr_dw0(r3));
2459 assign(result, binop(Iop_Add64, mkexpr(op2), mkexpr(op3)));
2460 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op2, op3);
2461 put_gpr_dw0(r1, mkexpr(result));
2462
2463 return "agrk";
2464}
2465
florian55085f82012-11-21 00:36:55 +00002466static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002467s390_irgen_A(UChar r1, IRTemp op2addr)
2468{
2469 IRTemp op1 = newTemp(Ity_I32);
2470 IRTemp op2 = newTemp(Ity_I32);
2471 IRTemp result = newTemp(Ity_I32);
2472
2473 assign(op1, get_gpr_w1(r1));
2474 assign(op2, load(Ity_I32, mkexpr(op2addr)));
2475 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2476 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2477 put_gpr_w1(r1, mkexpr(result));
2478
2479 return "a";
2480}
2481
florian55085f82012-11-21 00:36:55 +00002482static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002483s390_irgen_AY(UChar r1, IRTemp op2addr)
2484{
2485 IRTemp op1 = newTemp(Ity_I32);
2486 IRTemp op2 = newTemp(Ity_I32);
2487 IRTemp result = newTemp(Ity_I32);
2488
2489 assign(op1, get_gpr_w1(r1));
2490 assign(op2, load(Ity_I32, mkexpr(op2addr)));
2491 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2492 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2493 put_gpr_w1(r1, mkexpr(result));
2494
2495 return "ay";
2496}
2497
florian55085f82012-11-21 00:36:55 +00002498static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002499s390_irgen_AG(UChar r1, IRTemp op2addr)
2500{
2501 IRTemp op1 = newTemp(Ity_I64);
2502 IRTemp op2 = newTemp(Ity_I64);
2503 IRTemp result = newTemp(Ity_I64);
2504
2505 assign(op1, get_gpr_dw0(r1));
2506 assign(op2, load(Ity_I64, mkexpr(op2addr)));
2507 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2508 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
2509 put_gpr_dw0(r1, mkexpr(result));
2510
2511 return "ag";
2512}
2513
florian55085f82012-11-21 00:36:55 +00002514static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002515s390_irgen_AGF(UChar r1, IRTemp op2addr)
2516{
2517 IRTemp op1 = newTemp(Ity_I64);
2518 IRTemp op2 = newTemp(Ity_I64);
2519 IRTemp result = newTemp(Ity_I64);
2520
2521 assign(op1, get_gpr_dw0(r1));
2522 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
2523 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2524 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
2525 put_gpr_dw0(r1, mkexpr(result));
2526
2527 return "agf";
2528}
2529
florian55085f82012-11-21 00:36:55 +00002530static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002531s390_irgen_AFI(UChar r1, UInt i2)
2532{
2533 IRTemp op1 = newTemp(Ity_I32);
2534 Int op2;
2535 IRTemp result = newTemp(Ity_I32);
2536
2537 assign(op1, get_gpr_w1(r1));
2538 op2 = (Int)i2;
2539 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
2540 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
2541 mkU32((UInt)op2)));
2542 put_gpr_w1(r1, mkexpr(result));
2543
2544 return "afi";
2545}
2546
florian55085f82012-11-21 00:36:55 +00002547static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002548s390_irgen_AGFI(UChar r1, UInt i2)
2549{
2550 IRTemp op1 = newTemp(Ity_I64);
2551 Long op2;
2552 IRTemp result = newTemp(Ity_I64);
2553
2554 assign(op1, get_gpr_dw0(r1));
2555 op2 = (Long)(Int)i2;
2556 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64((ULong)op2)));
2557 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, mktemp(Ity_I64,
2558 mkU64((ULong)op2)));
2559 put_gpr_dw0(r1, mkexpr(result));
2560
2561 return "agfi";
2562}
2563
florian55085f82012-11-21 00:36:55 +00002564static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002565s390_irgen_AHIK(UChar r1, UChar r3, UShort i2)
2566{
2567 Int op2;
2568 IRTemp op3 = newTemp(Ity_I32);
2569 IRTemp result = newTemp(Ity_I32);
2570
2571 op2 = (Int)(Short)i2;
2572 assign(op3, get_gpr_w1(r3));
2573 assign(result, binop(Iop_Add32, mkU32((UInt)op2), mkexpr(op3)));
2574 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, mktemp(Ity_I32, mkU32((UInt)
2575 op2)), op3);
2576 put_gpr_w1(r1, mkexpr(result));
2577
2578 return "ahik";
2579}
2580
florian55085f82012-11-21 00:36:55 +00002581static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002582s390_irgen_AGHIK(UChar r1, UChar r3, UShort i2)
2583{
2584 Long op2;
2585 IRTemp op3 = newTemp(Ity_I64);
2586 IRTemp result = newTemp(Ity_I64);
2587
2588 op2 = (Long)(Short)i2;
2589 assign(op3, get_gpr_dw0(r3));
2590 assign(result, binop(Iop_Add64, mkU64((ULong)op2), mkexpr(op3)));
2591 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, mktemp(Ity_I64, mkU64((ULong)
2592 op2)), op3);
2593 put_gpr_dw0(r1, mkexpr(result));
2594
2595 return "aghik";
2596}
2597
florian55085f82012-11-21 00:36:55 +00002598static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002599s390_irgen_ASI(UChar i2, IRTemp op1addr)
2600{
2601 IRTemp op1 = newTemp(Ity_I32);
2602 Int op2;
2603 IRTemp result = newTemp(Ity_I32);
2604
2605 assign(op1, load(Ity_I32, mkexpr(op1addr)));
2606 op2 = (Int)(Char)i2;
2607 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
2608 store(mkexpr(op1addr), mkexpr(result));
2609 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
2610 mkU32((UInt)op2)));
2611
2612 return "asi";
2613}
2614
florian55085f82012-11-21 00:36:55 +00002615static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002616s390_irgen_AGSI(UChar i2, IRTemp op1addr)
2617{
2618 IRTemp op1 = newTemp(Ity_I64);
2619 Long op2;
2620 IRTemp result = newTemp(Ity_I64);
2621
2622 assign(op1, load(Ity_I64, mkexpr(op1addr)));
2623 op2 = (Long)(Char)i2;
2624 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64((ULong)op2)));
2625 store(mkexpr(op1addr), mkexpr(result));
2626 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, mktemp(Ity_I64,
2627 mkU64((ULong)op2)));
2628
2629 return "agsi";
2630}
2631
florian55085f82012-11-21 00:36:55 +00002632static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002633s390_irgen_AH(UChar r1, IRTemp op2addr)
2634{
2635 IRTemp op1 = newTemp(Ity_I32);
2636 IRTemp op2 = newTemp(Ity_I32);
2637 IRTemp result = newTemp(Ity_I32);
2638
2639 assign(op1, get_gpr_w1(r1));
2640 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
2641 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2642 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2643 put_gpr_w1(r1, mkexpr(result));
2644
2645 return "ah";
2646}
2647
florian55085f82012-11-21 00:36:55 +00002648static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002649s390_irgen_AHY(UChar r1, IRTemp op2addr)
2650{
2651 IRTemp op1 = newTemp(Ity_I32);
2652 IRTemp op2 = newTemp(Ity_I32);
2653 IRTemp result = newTemp(Ity_I32);
2654
2655 assign(op1, get_gpr_w1(r1));
2656 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
2657 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2658 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2659 put_gpr_w1(r1, mkexpr(result));
2660
2661 return "ahy";
2662}
2663
florian55085f82012-11-21 00:36:55 +00002664static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002665s390_irgen_AHI(UChar r1, UShort i2)
2666{
2667 IRTemp op1 = newTemp(Ity_I32);
2668 Int op2;
2669 IRTemp result = newTemp(Ity_I32);
2670
2671 assign(op1, get_gpr_w1(r1));
2672 op2 = (Int)(Short)i2;
2673 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
2674 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
2675 mkU32((UInt)op2)));
2676 put_gpr_w1(r1, mkexpr(result));
2677
2678 return "ahi";
2679}
2680
florian55085f82012-11-21 00:36:55 +00002681static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002682s390_irgen_AGHI(UChar r1, UShort i2)
2683{
2684 IRTemp op1 = newTemp(Ity_I64);
2685 Long op2;
2686 IRTemp result = newTemp(Ity_I64);
2687
2688 assign(op1, get_gpr_dw0(r1));
2689 op2 = (Long)(Short)i2;
2690 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64((ULong)op2)));
2691 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, mktemp(Ity_I64,
2692 mkU64((ULong)op2)));
2693 put_gpr_dw0(r1, mkexpr(result));
2694
2695 return "aghi";
2696}
2697
florian55085f82012-11-21 00:36:55 +00002698static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002699s390_irgen_AHHHR(UChar r3, UChar r1, UChar r2)
2700{
2701 IRTemp op2 = newTemp(Ity_I32);
2702 IRTemp op3 = newTemp(Ity_I32);
2703 IRTemp result = newTemp(Ity_I32);
2704
2705 assign(op2, get_gpr_w0(r2));
2706 assign(op3, get_gpr_w0(r3));
2707 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2708 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
2709 put_gpr_w0(r1, mkexpr(result));
2710
2711 return "ahhhr";
2712}
2713
florian55085f82012-11-21 00:36:55 +00002714static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002715s390_irgen_AHHLR(UChar r3, UChar r1, UChar r2)
2716{
2717 IRTemp op2 = newTemp(Ity_I32);
2718 IRTemp op3 = newTemp(Ity_I32);
2719 IRTemp result = newTemp(Ity_I32);
2720
2721 assign(op2, get_gpr_w0(r2));
2722 assign(op3, get_gpr_w1(r3));
2723 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2724 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
2725 put_gpr_w0(r1, mkexpr(result));
2726
2727 return "ahhlr";
2728}
2729
florian55085f82012-11-21 00:36:55 +00002730static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002731s390_irgen_AIH(UChar r1, UInt i2)
2732{
2733 IRTemp op1 = newTemp(Ity_I32);
2734 Int op2;
2735 IRTemp result = newTemp(Ity_I32);
2736
2737 assign(op1, get_gpr_w0(r1));
2738 op2 = (Int)i2;
2739 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
2740 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
2741 mkU32((UInt)op2)));
2742 put_gpr_w0(r1, mkexpr(result));
2743
2744 return "aih";
2745}
2746
florian55085f82012-11-21 00:36:55 +00002747static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002748s390_irgen_ALR(UChar r1, UChar r2)
2749{
2750 IRTemp op1 = newTemp(Ity_I32);
2751 IRTemp op2 = newTemp(Ity_I32);
2752 IRTemp result = newTemp(Ity_I32);
2753
2754 assign(op1, get_gpr_w1(r1));
2755 assign(op2, get_gpr_w1(r2));
2756 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2757 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, op2);
2758 put_gpr_w1(r1, mkexpr(result));
2759
2760 return "alr";
2761}
2762
florian55085f82012-11-21 00:36:55 +00002763static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002764s390_irgen_ALGR(UChar r1, UChar r2)
2765{
2766 IRTemp op1 = newTemp(Ity_I64);
2767 IRTemp op2 = newTemp(Ity_I64);
2768 IRTemp result = newTemp(Ity_I64);
2769
2770 assign(op1, get_gpr_dw0(r1));
2771 assign(op2, get_gpr_dw0(r2));
2772 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2773 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
2774 put_gpr_dw0(r1, mkexpr(result));
2775
2776 return "algr";
2777}
2778
florian55085f82012-11-21 00:36:55 +00002779static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002780s390_irgen_ALGFR(UChar r1, UChar r2)
2781{
2782 IRTemp op1 = newTemp(Ity_I64);
2783 IRTemp op2 = newTemp(Ity_I64);
2784 IRTemp result = newTemp(Ity_I64);
2785
2786 assign(op1, get_gpr_dw0(r1));
2787 assign(op2, unop(Iop_32Uto64, get_gpr_w1(r2)));
2788 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2789 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
2790 put_gpr_dw0(r1, mkexpr(result));
2791
2792 return "algfr";
2793}
2794
florian55085f82012-11-21 00:36:55 +00002795static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002796s390_irgen_ALRK(UChar r3, UChar r1, UChar r2)
2797{
2798 IRTemp op2 = newTemp(Ity_I32);
2799 IRTemp op3 = newTemp(Ity_I32);
2800 IRTemp result = newTemp(Ity_I32);
2801
2802 assign(op2, get_gpr_w1(r2));
2803 assign(op3, get_gpr_w1(r3));
2804 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2805 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
2806 put_gpr_w1(r1, mkexpr(result));
2807
2808 return "alrk";
2809}
2810
florian55085f82012-11-21 00:36:55 +00002811static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002812s390_irgen_ALGRK(UChar r3, UChar r1, UChar r2)
2813{
2814 IRTemp op2 = newTemp(Ity_I64);
2815 IRTemp op3 = newTemp(Ity_I64);
2816 IRTemp result = newTemp(Ity_I64);
2817
2818 assign(op2, get_gpr_dw0(r2));
2819 assign(op3, get_gpr_dw0(r3));
2820 assign(result, binop(Iop_Add64, mkexpr(op2), mkexpr(op3)));
2821 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op2, op3);
2822 put_gpr_dw0(r1, mkexpr(result));
2823
2824 return "algrk";
2825}
2826
florian55085f82012-11-21 00:36:55 +00002827static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002828s390_irgen_AL(UChar r1, IRTemp op2addr)
2829{
2830 IRTemp op1 = newTemp(Ity_I32);
2831 IRTemp op2 = newTemp(Ity_I32);
2832 IRTemp result = newTemp(Ity_I32);
2833
2834 assign(op1, get_gpr_w1(r1));
2835 assign(op2, load(Ity_I32, mkexpr(op2addr)));
2836 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2837 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, op2);
2838 put_gpr_w1(r1, mkexpr(result));
2839
2840 return "al";
2841}
2842
florian55085f82012-11-21 00:36:55 +00002843static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002844s390_irgen_ALY(UChar r1, IRTemp op2addr)
2845{
2846 IRTemp op1 = newTemp(Ity_I32);
2847 IRTemp op2 = newTemp(Ity_I32);
2848 IRTemp result = newTemp(Ity_I32);
2849
2850 assign(op1, get_gpr_w1(r1));
2851 assign(op2, load(Ity_I32, mkexpr(op2addr)));
2852 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2853 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, op2);
2854 put_gpr_w1(r1, mkexpr(result));
2855
2856 return "aly";
2857}
2858
florian55085f82012-11-21 00:36:55 +00002859static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002860s390_irgen_ALG(UChar r1, IRTemp op2addr)
2861{
2862 IRTemp op1 = newTemp(Ity_I64);
2863 IRTemp op2 = newTemp(Ity_I64);
2864 IRTemp result = newTemp(Ity_I64);
2865
2866 assign(op1, get_gpr_dw0(r1));
2867 assign(op2, load(Ity_I64, mkexpr(op2addr)));
2868 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2869 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
2870 put_gpr_dw0(r1, mkexpr(result));
2871
2872 return "alg";
2873}
2874
florian55085f82012-11-21 00:36:55 +00002875static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002876s390_irgen_ALGF(UChar r1, IRTemp op2addr)
2877{
2878 IRTemp op1 = newTemp(Ity_I64);
2879 IRTemp op2 = newTemp(Ity_I64);
2880 IRTemp result = newTemp(Ity_I64);
2881
2882 assign(op1, get_gpr_dw0(r1));
2883 assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
2884 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2885 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
2886 put_gpr_dw0(r1, mkexpr(result));
2887
2888 return "algf";
2889}
2890
florian55085f82012-11-21 00:36:55 +00002891static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002892s390_irgen_ALFI(UChar r1, UInt i2)
2893{
2894 IRTemp op1 = newTemp(Ity_I32);
2895 UInt op2;
2896 IRTemp result = newTemp(Ity_I32);
2897
2898 assign(op1, get_gpr_w1(r1));
2899 op2 = i2;
2900 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
2901 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, mktemp(Ity_I32,
2902 mkU32(op2)));
2903 put_gpr_w1(r1, mkexpr(result));
2904
2905 return "alfi";
2906}
2907
florian55085f82012-11-21 00:36:55 +00002908static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002909s390_irgen_ALGFI(UChar r1, UInt i2)
2910{
2911 IRTemp op1 = newTemp(Ity_I64);
2912 ULong op2;
2913 IRTemp result = newTemp(Ity_I64);
2914
2915 assign(op1, get_gpr_dw0(r1));
2916 op2 = (ULong)i2;
2917 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64(op2)));
2918 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, mktemp(Ity_I64,
2919 mkU64(op2)));
2920 put_gpr_dw0(r1, mkexpr(result));
2921
2922 return "algfi";
2923}
2924
florian55085f82012-11-21 00:36:55 +00002925static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002926s390_irgen_ALHHHR(UChar r3, UChar r1, UChar r2)
2927{
2928 IRTemp op2 = newTemp(Ity_I32);
2929 IRTemp op3 = newTemp(Ity_I32);
2930 IRTemp result = newTemp(Ity_I32);
2931
2932 assign(op2, get_gpr_w0(r2));
2933 assign(op3, get_gpr_w0(r3));
2934 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2935 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
2936 put_gpr_w0(r1, mkexpr(result));
2937
2938 return "alhhhr";
2939}
2940
florian55085f82012-11-21 00:36:55 +00002941static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002942s390_irgen_ALHHLR(UChar r3, UChar r1, UChar r2)
2943{
2944 IRTemp op2 = newTemp(Ity_I32);
2945 IRTemp op3 = newTemp(Ity_I32);
2946 IRTemp result = newTemp(Ity_I32);
2947
2948 assign(op2, get_gpr_w0(r2));
2949 assign(op3, get_gpr_w1(r3));
2950 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2951 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
2952 put_gpr_w0(r1, mkexpr(result));
2953
2954 return "alhhlr";
2955}
2956
florian55085f82012-11-21 00:36:55 +00002957static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002958s390_irgen_ALCR(UChar r1, UChar r2)
2959{
2960 IRTemp op1 = newTemp(Ity_I32);
2961 IRTemp op2 = newTemp(Ity_I32);
2962 IRTemp result = newTemp(Ity_I32);
2963 IRTemp carry_in = newTemp(Ity_I32);
2964
2965 assign(op1, get_gpr_w1(r1));
2966 assign(op2, get_gpr_w1(r2));
2967 assign(carry_in, binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)));
2968 assign(result, binop(Iop_Add32, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)),
2969 mkexpr(carry_in)));
2970 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_32, op1, op2, carry_in);
2971 put_gpr_w1(r1, mkexpr(result));
2972
2973 return "alcr";
2974}
2975
florian55085f82012-11-21 00:36:55 +00002976static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002977s390_irgen_ALCGR(UChar r1, UChar r2)
2978{
2979 IRTemp op1 = newTemp(Ity_I64);
2980 IRTemp op2 = newTemp(Ity_I64);
2981 IRTemp result = newTemp(Ity_I64);
2982 IRTemp carry_in = newTemp(Ity_I64);
2983
2984 assign(op1, get_gpr_dw0(r1));
2985 assign(op2, get_gpr_dw0(r2));
2986 assign(carry_in, unop(Iop_32Uto64, binop(Iop_Shr32, s390_call_calculate_cc(),
2987 mkU8(1))));
2988 assign(result, binop(Iop_Add64, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)),
2989 mkexpr(carry_in)));
2990 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_64, op1, op2, carry_in);
2991 put_gpr_dw0(r1, mkexpr(result));
2992
2993 return "alcgr";
2994}
2995
florian55085f82012-11-21 00:36:55 +00002996static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002997s390_irgen_ALC(UChar r1, IRTemp op2addr)
2998{
2999 IRTemp op1 = newTemp(Ity_I32);
3000 IRTemp op2 = newTemp(Ity_I32);
3001 IRTemp result = newTemp(Ity_I32);
3002 IRTemp carry_in = newTemp(Ity_I32);
3003
3004 assign(op1, get_gpr_w1(r1));
3005 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3006 assign(carry_in, binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)));
3007 assign(result, binop(Iop_Add32, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)),
3008 mkexpr(carry_in)));
3009 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_32, op1, op2, carry_in);
3010 put_gpr_w1(r1, mkexpr(result));
3011
3012 return "alc";
3013}
3014
florian55085f82012-11-21 00:36:55 +00003015static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003016s390_irgen_ALCG(UChar r1, IRTemp op2addr)
3017{
3018 IRTemp op1 = newTemp(Ity_I64);
3019 IRTemp op2 = newTemp(Ity_I64);
3020 IRTemp result = newTemp(Ity_I64);
3021 IRTemp carry_in = newTemp(Ity_I64);
3022
3023 assign(op1, get_gpr_dw0(r1));
3024 assign(op2, load(Ity_I64, mkexpr(op2addr)));
3025 assign(carry_in, unop(Iop_32Uto64, binop(Iop_Shr32, s390_call_calculate_cc(),
3026 mkU8(1))));
3027 assign(result, binop(Iop_Add64, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)),
3028 mkexpr(carry_in)));
3029 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_64, op1, op2, carry_in);
3030 put_gpr_dw0(r1, mkexpr(result));
3031
3032 return "alcg";
3033}
3034
florian55085f82012-11-21 00:36:55 +00003035static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003036s390_irgen_ALSI(UChar i2, IRTemp op1addr)
3037{
3038 IRTemp op1 = newTemp(Ity_I32);
3039 UInt op2;
3040 IRTemp result = newTemp(Ity_I32);
3041
3042 assign(op1, load(Ity_I32, mkexpr(op1addr)));
3043 op2 = (UInt)(Int)(Char)i2;
3044 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
3045 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, mktemp(Ity_I32,
3046 mkU32(op2)));
3047 store(mkexpr(op1addr), mkexpr(result));
3048
3049 return "alsi";
3050}
3051
florian55085f82012-11-21 00:36:55 +00003052static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003053s390_irgen_ALGSI(UChar i2, IRTemp op1addr)
3054{
3055 IRTemp op1 = newTemp(Ity_I64);
3056 ULong op2;
3057 IRTemp result = newTemp(Ity_I64);
3058
3059 assign(op1, load(Ity_I64, mkexpr(op1addr)));
3060 op2 = (ULong)(Long)(Char)i2;
3061 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64(op2)));
3062 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, mktemp(Ity_I64,
3063 mkU64(op2)));
3064 store(mkexpr(op1addr), mkexpr(result));
3065
3066 return "algsi";
3067}
3068
florian55085f82012-11-21 00:36:55 +00003069static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003070s390_irgen_ALHSIK(UChar r1, UChar r3, UShort i2)
3071{
3072 UInt op2;
3073 IRTemp op3 = newTemp(Ity_I32);
3074 IRTemp result = newTemp(Ity_I32);
3075
3076 op2 = (UInt)(Int)(Short)i2;
3077 assign(op3, get_gpr_w1(r3));
3078 assign(result, binop(Iop_Add32, mkU32(op2), mkexpr(op3)));
3079 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, mktemp(Ity_I32, mkU32(op2)),
3080 op3);
3081 put_gpr_w1(r1, mkexpr(result));
3082
3083 return "alhsik";
3084}
3085
florian55085f82012-11-21 00:36:55 +00003086static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003087s390_irgen_ALGHSIK(UChar r1, UChar r3, UShort i2)
3088{
3089 ULong op2;
3090 IRTemp op3 = newTemp(Ity_I64);
3091 IRTemp result = newTemp(Ity_I64);
3092
3093 op2 = (ULong)(Long)(Short)i2;
3094 assign(op3, get_gpr_dw0(r3));
3095 assign(result, binop(Iop_Add64, mkU64(op2), mkexpr(op3)));
3096 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, mktemp(Ity_I64, mkU64(op2)),
3097 op3);
3098 put_gpr_dw0(r1, mkexpr(result));
3099
3100 return "alghsik";
3101}
3102
florian55085f82012-11-21 00:36:55 +00003103static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003104s390_irgen_ALSIH(UChar r1, UInt i2)
3105{
3106 IRTemp op1 = newTemp(Ity_I32);
3107 UInt op2;
3108 IRTemp result = newTemp(Ity_I32);
3109
3110 assign(op1, get_gpr_w0(r1));
3111 op2 = i2;
3112 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
3113 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, mktemp(Ity_I32,
3114 mkU32(op2)));
3115 put_gpr_w0(r1, mkexpr(result));
3116
3117 return "alsih";
3118}
3119
florian55085f82012-11-21 00:36:55 +00003120static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003121s390_irgen_ALSIHN(UChar r1, UInt i2)
3122{
3123 IRTemp op1 = newTemp(Ity_I32);
3124 UInt op2;
3125 IRTemp result = newTemp(Ity_I32);
3126
3127 assign(op1, get_gpr_w0(r1));
3128 op2 = i2;
3129 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
3130 put_gpr_w0(r1, mkexpr(result));
3131
3132 return "alsihn";
3133}
3134
florian55085f82012-11-21 00:36:55 +00003135static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003136s390_irgen_NR(UChar r1, UChar r2)
3137{
3138 IRTemp op1 = newTemp(Ity_I32);
3139 IRTemp op2 = newTemp(Ity_I32);
3140 IRTemp result = newTemp(Ity_I32);
3141
3142 assign(op1, get_gpr_w1(r1));
3143 assign(op2, get_gpr_w1(r2));
3144 assign(result, binop(Iop_And32, mkexpr(op1), mkexpr(op2)));
3145 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3146 put_gpr_w1(r1, mkexpr(result));
3147
3148 return "nr";
3149}
3150
florian55085f82012-11-21 00:36:55 +00003151static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003152s390_irgen_NGR(UChar r1, UChar r2)
3153{
3154 IRTemp op1 = newTemp(Ity_I64);
3155 IRTemp op2 = newTemp(Ity_I64);
3156 IRTemp result = newTemp(Ity_I64);
3157
3158 assign(op1, get_gpr_dw0(r1));
3159 assign(op2, get_gpr_dw0(r2));
3160 assign(result, binop(Iop_And64, mkexpr(op1), mkexpr(op2)));
3161 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3162 put_gpr_dw0(r1, mkexpr(result));
3163
3164 return "ngr";
3165}
3166
florian55085f82012-11-21 00:36:55 +00003167static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003168s390_irgen_NRK(UChar r3, UChar r1, UChar r2)
3169{
3170 IRTemp op2 = newTemp(Ity_I32);
3171 IRTemp op3 = newTemp(Ity_I32);
3172 IRTemp result = newTemp(Ity_I32);
3173
3174 assign(op2, get_gpr_w1(r2));
3175 assign(op3, get_gpr_w1(r3));
3176 assign(result, binop(Iop_And32, mkexpr(op2), mkexpr(op3)));
3177 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3178 put_gpr_w1(r1, mkexpr(result));
3179
3180 return "nrk";
3181}
3182
florian55085f82012-11-21 00:36:55 +00003183static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003184s390_irgen_NGRK(UChar r3, UChar r1, UChar r2)
3185{
3186 IRTemp op2 = newTemp(Ity_I64);
3187 IRTemp op3 = newTemp(Ity_I64);
3188 IRTemp result = newTemp(Ity_I64);
3189
3190 assign(op2, get_gpr_dw0(r2));
3191 assign(op3, get_gpr_dw0(r3));
3192 assign(result, binop(Iop_And64, mkexpr(op2), mkexpr(op3)));
3193 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3194 put_gpr_dw0(r1, mkexpr(result));
3195
3196 return "ngrk";
3197}
3198
florian55085f82012-11-21 00:36:55 +00003199static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003200s390_irgen_N(UChar r1, IRTemp op2addr)
3201{
3202 IRTemp op1 = newTemp(Ity_I32);
3203 IRTemp op2 = newTemp(Ity_I32);
3204 IRTemp result = newTemp(Ity_I32);
3205
3206 assign(op1, get_gpr_w1(r1));
3207 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3208 assign(result, binop(Iop_And32, mkexpr(op1), mkexpr(op2)));
3209 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3210 put_gpr_w1(r1, mkexpr(result));
3211
3212 return "n";
3213}
3214
florian55085f82012-11-21 00:36:55 +00003215static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003216s390_irgen_NY(UChar r1, IRTemp op2addr)
3217{
3218 IRTemp op1 = newTemp(Ity_I32);
3219 IRTemp op2 = newTemp(Ity_I32);
3220 IRTemp result = newTemp(Ity_I32);
3221
3222 assign(op1, get_gpr_w1(r1));
3223 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3224 assign(result, binop(Iop_And32, mkexpr(op1), mkexpr(op2)));
3225 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3226 put_gpr_w1(r1, mkexpr(result));
3227
3228 return "ny";
3229}
3230
florian55085f82012-11-21 00:36:55 +00003231static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003232s390_irgen_NG(UChar r1, IRTemp op2addr)
3233{
3234 IRTemp op1 = newTemp(Ity_I64);
3235 IRTemp op2 = newTemp(Ity_I64);
3236 IRTemp result = newTemp(Ity_I64);
3237
3238 assign(op1, get_gpr_dw0(r1));
3239 assign(op2, load(Ity_I64, mkexpr(op2addr)));
3240 assign(result, binop(Iop_And64, mkexpr(op1), mkexpr(op2)));
3241 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3242 put_gpr_dw0(r1, mkexpr(result));
3243
3244 return "ng";
3245}
3246
florian55085f82012-11-21 00:36:55 +00003247static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003248s390_irgen_NI(UChar i2, IRTemp op1addr)
3249{
3250 IRTemp op1 = newTemp(Ity_I8);
3251 UChar op2;
3252 IRTemp result = newTemp(Ity_I8);
3253
3254 assign(op1, load(Ity_I8, mkexpr(op1addr)));
3255 op2 = i2;
3256 assign(result, binop(Iop_And8, mkexpr(op1), mkU8(op2)));
3257 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3258 store(mkexpr(op1addr), mkexpr(result));
3259
3260 return "ni";
3261}
3262
florian55085f82012-11-21 00:36:55 +00003263static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003264s390_irgen_NIY(UChar i2, IRTemp op1addr)
3265{
3266 IRTemp op1 = newTemp(Ity_I8);
3267 UChar op2;
3268 IRTemp result = newTemp(Ity_I8);
3269
3270 assign(op1, load(Ity_I8, mkexpr(op1addr)));
3271 op2 = i2;
3272 assign(result, binop(Iop_And8, mkexpr(op1), mkU8(op2)));
3273 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3274 store(mkexpr(op1addr), mkexpr(result));
3275
3276 return "niy";
3277}
3278
florian55085f82012-11-21 00:36:55 +00003279static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003280s390_irgen_NIHF(UChar r1, UInt i2)
3281{
3282 IRTemp op1 = newTemp(Ity_I32);
3283 UInt op2;
3284 IRTemp result = newTemp(Ity_I32);
3285
3286 assign(op1, get_gpr_w0(r1));
3287 op2 = i2;
3288 assign(result, binop(Iop_And32, mkexpr(op1), mkU32(op2)));
3289 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3290 put_gpr_w0(r1, mkexpr(result));
3291
3292 return "nihf";
3293}
3294
florian55085f82012-11-21 00:36:55 +00003295static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003296s390_irgen_NIHH(UChar r1, UShort i2)
3297{
3298 IRTemp op1 = newTemp(Ity_I16);
3299 UShort op2;
3300 IRTemp result = newTemp(Ity_I16);
3301
3302 assign(op1, get_gpr_hw0(r1));
3303 op2 = i2;
3304 assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
3305 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3306 put_gpr_hw0(r1, mkexpr(result));
3307
3308 return "nihh";
3309}
3310
florian55085f82012-11-21 00:36:55 +00003311static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003312s390_irgen_NIHL(UChar r1, UShort i2)
3313{
3314 IRTemp op1 = newTemp(Ity_I16);
3315 UShort op2;
3316 IRTemp result = newTemp(Ity_I16);
3317
3318 assign(op1, get_gpr_hw1(r1));
3319 op2 = i2;
3320 assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
3321 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3322 put_gpr_hw1(r1, mkexpr(result));
3323
3324 return "nihl";
3325}
3326
florian55085f82012-11-21 00:36:55 +00003327static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003328s390_irgen_NILF(UChar r1, UInt i2)
3329{
3330 IRTemp op1 = newTemp(Ity_I32);
3331 UInt op2;
3332 IRTemp result = newTemp(Ity_I32);
3333
3334 assign(op1, get_gpr_w1(r1));
3335 op2 = i2;
3336 assign(result, binop(Iop_And32, mkexpr(op1), mkU32(op2)));
3337 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3338 put_gpr_w1(r1, mkexpr(result));
3339
3340 return "nilf";
3341}
3342
florian55085f82012-11-21 00:36:55 +00003343static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003344s390_irgen_NILH(UChar r1, UShort i2)
3345{
3346 IRTemp op1 = newTemp(Ity_I16);
3347 UShort op2;
3348 IRTemp result = newTemp(Ity_I16);
3349
3350 assign(op1, get_gpr_hw2(r1));
3351 op2 = i2;
3352 assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
3353 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3354 put_gpr_hw2(r1, mkexpr(result));
3355
3356 return "nilh";
3357}
3358
florian55085f82012-11-21 00:36:55 +00003359static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003360s390_irgen_NILL(UChar r1, UShort i2)
3361{
3362 IRTemp op1 = newTemp(Ity_I16);
3363 UShort op2;
3364 IRTemp result = newTemp(Ity_I16);
3365
3366 assign(op1, get_gpr_hw3(r1));
3367 op2 = i2;
3368 assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
3369 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3370 put_gpr_hw3(r1, mkexpr(result));
3371
3372 return "nill";
3373}
3374
florian55085f82012-11-21 00:36:55 +00003375static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003376s390_irgen_BASR(UChar r1, UChar r2)
3377{
3378 IRTemp target = newTemp(Ity_I64);
3379
3380 if (r2 == 0) {
3381 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 2ULL));
3382 } else {
3383 if (r1 != r2) {
3384 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 2ULL));
3385 call_function(get_gpr_dw0(r2));
3386 } else {
3387 assign(target, get_gpr_dw0(r2));
3388 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 2ULL));
3389 call_function(mkexpr(target));
3390 }
3391 }
3392
3393 return "basr";
3394}
3395
florian55085f82012-11-21 00:36:55 +00003396static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003397s390_irgen_BAS(UChar r1, IRTemp op2addr)
3398{
3399 IRTemp target = newTemp(Ity_I64);
3400
3401 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 4ULL));
3402 assign(target, mkexpr(op2addr));
3403 call_function(mkexpr(target));
3404
3405 return "bas";
3406}
3407
florian55085f82012-11-21 00:36:55 +00003408static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003409s390_irgen_BCR(UChar r1, UChar r2)
3410{
3411 IRTemp cond = newTemp(Ity_I32);
3412
sewardja52e37e2011-04-28 18:48:06 +00003413 if (r2 == 0 && (r1 >= 14)) { /* serialization */
3414 stmt(IRStmt_MBE(Imbe_Fence));
3415 }
3416
sewardj2019a972011-03-07 16:04:07 +00003417 if ((r2 == 0) || (r1 == 0)) {
3418 } else {
3419 if (r1 == 15) {
3420 return_from_function(get_gpr_dw0(r2));
3421 } else {
3422 assign(cond, s390_call_calculate_cond(r1));
florianf321da72012-07-21 20:32:57 +00003423 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3424 get_gpr_dw0(r2));
sewardj2019a972011-03-07 16:04:07 +00003425 }
3426 }
sewardj7ee97522011-05-09 21:45:04 +00003427 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00003428 s390_disasm(ENC2(XMNM, GPR), S390_XMNM_BCR, r1, r2);
3429
3430 return "bcr";
3431}
3432
florian55085f82012-11-21 00:36:55 +00003433static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003434s390_irgen_BC(UChar r1, UChar x2, UChar b2, UShort d2, IRTemp op2addr)
3435{
3436 IRTemp cond = newTemp(Ity_I32);
3437
3438 if (r1 == 0) {
3439 } else {
3440 if (r1 == 15) {
3441 always_goto(mkexpr(op2addr));
3442 } else {
3443 assign(cond, s390_call_calculate_cond(r1));
florianf321da72012-07-21 20:32:57 +00003444 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3445 mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003446 }
3447 }
sewardj7ee97522011-05-09 21:45:04 +00003448 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00003449 s390_disasm(ENC2(XMNM, UDXB), S390_XMNM_BC, r1, d2, x2, b2);
3450
3451 return "bc";
3452}
3453
florian55085f82012-11-21 00:36:55 +00003454static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003455s390_irgen_BCTR(UChar r1, UChar r2)
3456{
3457 put_gpr_w1(r1, binop(Iop_Sub32, get_gpr_w1(r1), mkU32(1)));
3458 if (r2 != 0) {
florianf321da72012-07-21 20:32:57 +00003459 if_condition_goto_computed(binop(Iop_CmpNE32, get_gpr_w1(r1), mkU32(0)),
3460 get_gpr_dw0(r2));
sewardj2019a972011-03-07 16:04:07 +00003461 }
3462
3463 return "bctr";
3464}
3465
florian55085f82012-11-21 00:36:55 +00003466static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003467s390_irgen_BCTGR(UChar r1, UChar r2)
3468{
3469 put_gpr_dw0(r1, binop(Iop_Sub64, get_gpr_dw0(r1), mkU64(1)));
3470 if (r2 != 0) {
florianf321da72012-07-21 20:32:57 +00003471 if_condition_goto_computed(binop(Iop_CmpNE64, get_gpr_dw0(r1), mkU64(0)),
3472 get_gpr_dw0(r2));
sewardj2019a972011-03-07 16:04:07 +00003473 }
3474
3475 return "bctgr";
3476}
3477
florian55085f82012-11-21 00:36:55 +00003478static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003479s390_irgen_BCT(UChar r1, IRTemp op2addr)
3480{
3481 put_gpr_w1(r1, binop(Iop_Sub32, get_gpr_w1(r1), mkU32(1)));
florianf321da72012-07-21 20:32:57 +00003482 if_condition_goto_computed(binop(Iop_CmpNE32, get_gpr_w1(r1), mkU32(0)),
3483 mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003484
3485 return "bct";
3486}
3487
florian55085f82012-11-21 00:36:55 +00003488static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003489s390_irgen_BCTG(UChar r1, IRTemp op2addr)
3490{
3491 put_gpr_dw0(r1, binop(Iop_Sub64, get_gpr_dw0(r1), mkU64(1)));
florianf321da72012-07-21 20:32:57 +00003492 if_condition_goto_computed(binop(Iop_CmpNE64, get_gpr_dw0(r1), mkU64(0)),
3493 mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003494
3495 return "bctg";
3496}
3497
florian55085f82012-11-21 00:36:55 +00003498static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003499s390_irgen_BXH(UChar r1, UChar r3, IRTemp op2addr)
3500{
3501 IRTemp value = newTemp(Ity_I32);
3502
3503 assign(value, get_gpr_w1(r3 | 1));
3504 put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
florianf321da72012-07-21 20:32:57 +00003505 if_condition_goto_computed(binop(Iop_CmpLT32S, mkexpr(value),
3506 get_gpr_w1(r1)), mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003507
3508 return "bxh";
3509}
3510
florian55085f82012-11-21 00:36:55 +00003511static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003512s390_irgen_BXHG(UChar r1, UChar r3, IRTemp op2addr)
3513{
3514 IRTemp value = newTemp(Ity_I64);
3515
3516 assign(value, get_gpr_dw0(r3 | 1));
3517 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
florianf321da72012-07-21 20:32:57 +00003518 if_condition_goto_computed(binop(Iop_CmpLT64S, mkexpr(value),
3519 get_gpr_dw0(r1)), mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003520
3521 return "bxhg";
3522}
3523
florian55085f82012-11-21 00:36:55 +00003524static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003525s390_irgen_BXLE(UChar r1, UChar r3, IRTemp op2addr)
3526{
3527 IRTemp value = newTemp(Ity_I32);
3528
3529 assign(value, get_gpr_w1(r3 | 1));
3530 put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
florianf321da72012-07-21 20:32:57 +00003531 if_condition_goto_computed(binop(Iop_CmpLE32S, get_gpr_w1(r1),
3532 mkexpr(value)), mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003533
3534 return "bxle";
3535}
3536
florian55085f82012-11-21 00:36:55 +00003537static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003538s390_irgen_BXLEG(UChar r1, UChar r3, IRTemp op2addr)
3539{
3540 IRTemp value = newTemp(Ity_I64);
3541
3542 assign(value, get_gpr_dw0(r3 | 1));
3543 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
florianf321da72012-07-21 20:32:57 +00003544 if_condition_goto_computed(binop(Iop_CmpLE64S, get_gpr_dw0(r1),
3545 mkexpr(value)), mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003546
3547 return "bxleg";
3548}
3549
florian55085f82012-11-21 00:36:55 +00003550static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003551s390_irgen_BRAS(UChar r1, UShort i2)
3552{
3553 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 4ULL));
floriana64c2432011-07-16 02:11:50 +00003554 call_function_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
sewardj2019a972011-03-07 16:04:07 +00003555
3556 return "bras";
3557}
3558
florian55085f82012-11-21 00:36:55 +00003559static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003560s390_irgen_BRASL(UChar r1, UInt i2)
3561{
3562 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 6ULL));
floriana64c2432011-07-16 02:11:50 +00003563 call_function_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1));
sewardj2019a972011-03-07 16:04:07 +00003564
3565 return "brasl";
3566}
3567
florian55085f82012-11-21 00:36:55 +00003568static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003569s390_irgen_BRC(UChar r1, UShort i2)
3570{
3571 IRTemp cond = newTemp(Ity_I32);
3572
3573 if (r1 == 0) {
3574 } else {
3575 if (r1 == 15) {
floriana64c2432011-07-16 02:11:50 +00003576 always_goto_and_chase(
3577 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
sewardj2019a972011-03-07 16:04:07 +00003578 } else {
3579 assign(cond, s390_call_calculate_cond(r1));
3580 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3581 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3582
3583 }
3584 }
sewardj7ee97522011-05-09 21:45:04 +00003585 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00003586 s390_disasm(ENC2(XMNM, PCREL), S390_XMNM_BRC, r1, (Int)(Short)i2);
3587
3588 return "brc";
3589}
3590
florian55085f82012-11-21 00:36:55 +00003591static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003592s390_irgen_BRCL(UChar r1, UInt i2)
3593{
3594 IRTemp cond = newTemp(Ity_I32);
3595
3596 if (r1 == 0) {
3597 } else {
3598 if (r1 == 15) {
floriana64c2432011-07-16 02:11:50 +00003599 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1));
sewardj2019a972011-03-07 16:04:07 +00003600 } else {
3601 assign(cond, s390_call_calculate_cond(r1));
3602 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3603 guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1));
3604 }
3605 }
sewardj7ee97522011-05-09 21:45:04 +00003606 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00003607 s390_disasm(ENC2(XMNM, PCREL), S390_XMNM_BRCL, r1, i2);
3608
3609 return "brcl";
3610}
3611
florian55085f82012-11-21 00:36:55 +00003612static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003613s390_irgen_BRCT(UChar r1, UShort i2)
3614{
3615 put_gpr_w1(r1, binop(Iop_Sub32, get_gpr_w1(r1), mkU32(1)));
3616 if_condition_goto(binop(Iop_CmpNE32, get_gpr_w1(r1), mkU32(0)),
3617 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3618
3619 return "brct";
3620}
3621
florian55085f82012-11-21 00:36:55 +00003622static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003623s390_irgen_BRCTG(UChar r1, UShort i2)
3624{
3625 put_gpr_dw0(r1, binop(Iop_Sub64, get_gpr_dw0(r1), mkU64(1)));
3626 if_condition_goto(binop(Iop_CmpNE64, get_gpr_dw0(r1), mkU64(0)),
3627 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3628
3629 return "brctg";
3630}
3631
florian55085f82012-11-21 00:36:55 +00003632static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003633s390_irgen_BRXH(UChar r1, UChar r3, UShort i2)
3634{
3635 IRTemp value = newTemp(Ity_I32);
3636
3637 assign(value, get_gpr_w1(r3 | 1));
3638 put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
3639 if_condition_goto(binop(Iop_CmpLT32S, mkexpr(value), get_gpr_w1(r1)),
3640 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3641
3642 return "brxh";
3643}
3644
florian55085f82012-11-21 00:36:55 +00003645static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003646s390_irgen_BRXHG(UChar r1, UChar r3, UShort i2)
3647{
3648 IRTemp value = newTemp(Ity_I64);
3649
3650 assign(value, get_gpr_dw0(r3 | 1));
3651 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
3652 if_condition_goto(binop(Iop_CmpLT64S, mkexpr(value), get_gpr_dw0(r1)),
3653 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3654
3655 return "brxhg";
3656}
3657
florian55085f82012-11-21 00:36:55 +00003658static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003659s390_irgen_BRXLE(UChar r1, UChar r3, UShort i2)
3660{
3661 IRTemp value = newTemp(Ity_I32);
3662
3663 assign(value, get_gpr_w1(r3 | 1));
3664 put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
3665 if_condition_goto(binop(Iop_CmpLE32S, get_gpr_w1(r1), mkexpr(value)),
3666 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3667
3668 return "brxle";
3669}
3670
florian55085f82012-11-21 00:36:55 +00003671static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003672s390_irgen_BRXLG(UChar r1, UChar r3, UShort i2)
3673{
3674 IRTemp value = newTemp(Ity_I64);
3675
3676 assign(value, get_gpr_dw0(r3 | 1));
3677 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
3678 if_condition_goto(binop(Iop_CmpLE64S, get_gpr_dw0(r1), mkexpr(value)),
3679 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3680
3681 return "brxlg";
3682}
3683
florian55085f82012-11-21 00:36:55 +00003684static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003685s390_irgen_CR(UChar r1, UChar r2)
3686{
3687 IRTemp op1 = newTemp(Ity_I32);
3688 IRTemp op2 = newTemp(Ity_I32);
3689
3690 assign(op1, get_gpr_w1(r1));
3691 assign(op2, get_gpr_w1(r2));
3692 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3693
3694 return "cr";
3695}
3696
florian55085f82012-11-21 00:36:55 +00003697static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003698s390_irgen_CGR(UChar r1, UChar r2)
3699{
3700 IRTemp op1 = newTemp(Ity_I64);
3701 IRTemp op2 = newTemp(Ity_I64);
3702
3703 assign(op1, get_gpr_dw0(r1));
3704 assign(op2, get_gpr_dw0(r2));
3705 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3706
3707 return "cgr";
3708}
3709
florian55085f82012-11-21 00:36:55 +00003710static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003711s390_irgen_CGFR(UChar r1, UChar r2)
3712{
3713 IRTemp op1 = newTemp(Ity_I64);
3714 IRTemp op2 = newTemp(Ity_I64);
3715
3716 assign(op1, get_gpr_dw0(r1));
3717 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
3718 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3719
3720 return "cgfr";
3721}
3722
florian55085f82012-11-21 00:36:55 +00003723static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003724s390_irgen_C(UChar r1, IRTemp op2addr)
3725{
3726 IRTemp op1 = newTemp(Ity_I32);
3727 IRTemp op2 = newTemp(Ity_I32);
3728
3729 assign(op1, get_gpr_w1(r1));
3730 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3731 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3732
3733 return "c";
3734}
3735
florian55085f82012-11-21 00:36:55 +00003736static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003737s390_irgen_CY(UChar r1, IRTemp op2addr)
3738{
3739 IRTemp op1 = newTemp(Ity_I32);
3740 IRTemp op2 = newTemp(Ity_I32);
3741
3742 assign(op1, get_gpr_w1(r1));
3743 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3744 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3745
3746 return "cy";
3747}
3748
florian55085f82012-11-21 00:36:55 +00003749static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003750s390_irgen_CG(UChar r1, IRTemp op2addr)
3751{
3752 IRTemp op1 = newTemp(Ity_I64);
3753 IRTemp op2 = newTemp(Ity_I64);
3754
3755 assign(op1, get_gpr_dw0(r1));
3756 assign(op2, load(Ity_I64, mkexpr(op2addr)));
3757 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3758
3759 return "cg";
3760}
3761
florian55085f82012-11-21 00:36:55 +00003762static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003763s390_irgen_CGF(UChar r1, IRTemp op2addr)
3764{
3765 IRTemp op1 = newTemp(Ity_I64);
3766 IRTemp op2 = newTemp(Ity_I64);
3767
3768 assign(op1, get_gpr_dw0(r1));
3769 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
3770 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3771
3772 return "cgf";
3773}
3774
florian55085f82012-11-21 00:36:55 +00003775static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003776s390_irgen_CFI(UChar r1, UInt i2)
3777{
3778 IRTemp op1 = newTemp(Ity_I32);
3779 Int op2;
3780
3781 assign(op1, get_gpr_w1(r1));
3782 op2 = (Int)i2;
3783 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
3784 mkU32((UInt)op2)));
3785
3786 return "cfi";
3787}
3788
florian55085f82012-11-21 00:36:55 +00003789static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003790s390_irgen_CGFI(UChar r1, UInt i2)
3791{
3792 IRTemp op1 = newTemp(Ity_I64);
3793 Long op2;
3794
3795 assign(op1, get_gpr_dw0(r1));
3796 op2 = (Long)(Int)i2;
3797 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I64,
3798 mkU64((ULong)op2)));
3799
3800 return "cgfi";
3801}
3802
florian55085f82012-11-21 00:36:55 +00003803static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003804s390_irgen_CRL(UChar r1, UInt i2)
3805{
3806 IRTemp op1 = newTemp(Ity_I32);
3807 IRTemp op2 = newTemp(Ity_I32);
3808
3809 assign(op1, get_gpr_w1(r1));
3810 assign(op2, load(Ity_I32, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
3811 i2 << 1))));
3812 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3813
3814 return "crl";
3815}
3816
florian55085f82012-11-21 00:36:55 +00003817static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003818s390_irgen_CGRL(UChar r1, UInt i2)
3819{
3820 IRTemp op1 = newTemp(Ity_I64);
3821 IRTemp op2 = newTemp(Ity_I64);
3822
3823 assign(op1, get_gpr_dw0(r1));
3824 assign(op2, load(Ity_I64, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
3825 i2 << 1))));
3826 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3827
3828 return "cgrl";
3829}
3830
florian55085f82012-11-21 00:36:55 +00003831static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003832s390_irgen_CGFRL(UChar r1, UInt i2)
3833{
3834 IRTemp op1 = newTemp(Ity_I64);
3835 IRTemp op2 = newTemp(Ity_I64);
3836
3837 assign(op1, get_gpr_dw0(r1));
3838 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
3839 ((ULong)(Long)(Int)i2 << 1)))));
3840 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3841
3842 return "cgfrl";
3843}
3844
florian55085f82012-11-21 00:36:55 +00003845static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003846s390_irgen_CRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
3847{
3848 IRTemp op1 = newTemp(Ity_I32);
3849 IRTemp op2 = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00003850 IRTemp cond = newTemp(Ity_I32);
3851
3852 if (m3 == 0) {
3853 } else {
3854 if (m3 == 14) {
3855 always_goto(mkexpr(op4addr));
3856 } else {
3857 assign(op1, get_gpr_w1(r1));
3858 assign(op2, get_gpr_w1(r2));
florianff9613f2012-05-12 15:26:44 +00003859 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
3860 op1, op2));
florianf321da72012-07-21 20:32:57 +00003861 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond),
3862 mkU32(0)), mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00003863 }
3864 }
3865
3866 return "crb";
3867}
3868
florian55085f82012-11-21 00:36:55 +00003869static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003870s390_irgen_CGRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
3871{
3872 IRTemp op1 = newTemp(Ity_I64);
3873 IRTemp op2 = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00003874 IRTemp cond = newTemp(Ity_I32);
3875
3876 if (m3 == 0) {
3877 } else {
3878 if (m3 == 14) {
3879 always_goto(mkexpr(op4addr));
3880 } else {
3881 assign(op1, get_gpr_dw0(r1));
3882 assign(op2, get_gpr_dw0(r2));
florianff9613f2012-05-12 15:26:44 +00003883 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
3884 op1, op2));
florianf321da72012-07-21 20:32:57 +00003885 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond),
3886 mkU32(0)), mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00003887 }
3888 }
3889
3890 return "cgrb";
3891}
3892
florian55085f82012-11-21 00:36:55 +00003893static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003894s390_irgen_CRJ(UChar r1, UChar r2, UShort i4, UChar m3)
3895{
3896 IRTemp op1 = newTemp(Ity_I32);
3897 IRTemp op2 = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00003898 IRTemp cond = newTemp(Ity_I32);
3899
3900 if (m3 == 0) {
3901 } else {
3902 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00003903 always_goto_and_chase(
3904 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00003905 } else {
3906 assign(op1, get_gpr_w1(r1));
3907 assign(op2, get_gpr_w1(r2));
florianff9613f2012-05-12 15:26:44 +00003908 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
3909 op1, op2));
sewardj2019a972011-03-07 16:04:07 +00003910 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3911 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
3912
3913 }
3914 }
3915
3916 return "crj";
3917}
3918
florian55085f82012-11-21 00:36:55 +00003919static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003920s390_irgen_CGRJ(UChar r1, UChar r2, UShort i4, UChar m3)
3921{
3922 IRTemp op1 = newTemp(Ity_I64);
3923 IRTemp op2 = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00003924 IRTemp cond = newTemp(Ity_I32);
3925
3926 if (m3 == 0) {
3927 } else {
3928 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00003929 always_goto_and_chase(
3930 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00003931 } else {
3932 assign(op1, get_gpr_dw0(r1));
3933 assign(op2, get_gpr_dw0(r2));
florianff9613f2012-05-12 15:26:44 +00003934 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
3935 op1, op2));
sewardj2019a972011-03-07 16:04:07 +00003936 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3937 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
3938
3939 }
3940 }
3941
3942 return "cgrj";
3943}
3944
florian55085f82012-11-21 00:36:55 +00003945static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003946s390_irgen_CIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
3947{
3948 IRTemp op1 = newTemp(Ity_I32);
3949 Int op2;
sewardj2019a972011-03-07 16:04:07 +00003950 IRTemp cond = newTemp(Ity_I32);
3951
3952 if (m3 == 0) {
3953 } else {
3954 if (m3 == 14) {
3955 always_goto(mkexpr(op4addr));
3956 } else {
3957 assign(op1, get_gpr_w1(r1));
3958 op2 = (Int)(Char)i2;
florianff9613f2012-05-12 15:26:44 +00003959 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
3960 mktemp(Ity_I32, mkU32((UInt)op2))));
florianf321da72012-07-21 20:32:57 +00003961 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3962 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00003963 }
3964 }
3965
3966 return "cib";
3967}
3968
florian55085f82012-11-21 00:36:55 +00003969static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003970s390_irgen_CGIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
3971{
3972 IRTemp op1 = newTemp(Ity_I64);
3973 Long op2;
sewardj2019a972011-03-07 16:04:07 +00003974 IRTemp cond = newTemp(Ity_I32);
3975
3976 if (m3 == 0) {
3977 } else {
3978 if (m3 == 14) {
3979 always_goto(mkexpr(op4addr));
3980 } else {
3981 assign(op1, get_gpr_dw0(r1));
3982 op2 = (Long)(Char)i2;
florianff9613f2012-05-12 15:26:44 +00003983 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
3984 mktemp(Ity_I64, mkU64((ULong)op2))));
florianf321da72012-07-21 20:32:57 +00003985 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3986 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00003987 }
3988 }
3989
3990 return "cgib";
3991}
3992
florian55085f82012-11-21 00:36:55 +00003993static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003994s390_irgen_CIJ(UChar r1, UChar m3, UShort i4, UChar i2)
3995{
3996 IRTemp op1 = newTemp(Ity_I32);
3997 Int op2;
sewardj2019a972011-03-07 16:04:07 +00003998 IRTemp cond = newTemp(Ity_I32);
3999
4000 if (m3 == 0) {
4001 } else {
4002 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004003 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004004 } else {
4005 assign(op1, get_gpr_w1(r1));
4006 op2 = (Int)(Char)i2;
florianff9613f2012-05-12 15:26:44 +00004007 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
4008 mktemp(Ity_I32, mkU32((UInt)op2))));
sewardj2019a972011-03-07 16:04:07 +00004009 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4010 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4011
4012 }
4013 }
4014
4015 return "cij";
4016}
4017
florian55085f82012-11-21 00:36:55 +00004018static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004019s390_irgen_CGIJ(UChar r1, UChar m3, UShort i4, UChar i2)
4020{
4021 IRTemp op1 = newTemp(Ity_I64);
4022 Long op2;
sewardj2019a972011-03-07 16:04:07 +00004023 IRTemp cond = newTemp(Ity_I32);
4024
4025 if (m3 == 0) {
4026 } else {
4027 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004028 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004029 } else {
4030 assign(op1, get_gpr_dw0(r1));
4031 op2 = (Long)(Char)i2;
florianff9613f2012-05-12 15:26:44 +00004032 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
4033 mktemp(Ity_I64, mkU64((ULong)op2))));
sewardj2019a972011-03-07 16:04:07 +00004034 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4035 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4036
4037 }
4038 }
4039
4040 return "cgij";
4041}
4042
florian55085f82012-11-21 00:36:55 +00004043static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004044s390_irgen_CH(UChar r1, IRTemp op2addr)
4045{
4046 IRTemp op1 = newTemp(Ity_I32);
4047 IRTemp op2 = newTemp(Ity_I32);
4048
4049 assign(op1, get_gpr_w1(r1));
4050 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
4051 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4052
4053 return "ch";
4054}
4055
florian55085f82012-11-21 00:36:55 +00004056static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004057s390_irgen_CHY(UChar r1, IRTemp op2addr)
4058{
4059 IRTemp op1 = newTemp(Ity_I32);
4060 IRTemp op2 = newTemp(Ity_I32);
4061
4062 assign(op1, get_gpr_w1(r1));
4063 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
4064 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4065
4066 return "chy";
4067}
4068
florian55085f82012-11-21 00:36:55 +00004069static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004070s390_irgen_CGH(UChar r1, IRTemp op2addr)
4071{
4072 IRTemp op1 = newTemp(Ity_I64);
4073 IRTemp op2 = newTemp(Ity_I64);
4074
4075 assign(op1, get_gpr_dw0(r1));
4076 assign(op2, unop(Iop_16Sto64, load(Ity_I16, mkexpr(op2addr))));
4077 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4078
4079 return "cgh";
4080}
4081
florian55085f82012-11-21 00:36:55 +00004082static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004083s390_irgen_CHI(UChar r1, UShort i2)
4084{
4085 IRTemp op1 = newTemp(Ity_I32);
4086 Int op2;
4087
4088 assign(op1, get_gpr_w1(r1));
4089 op2 = (Int)(Short)i2;
4090 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
4091 mkU32((UInt)op2)));
4092
4093 return "chi";
4094}
4095
florian55085f82012-11-21 00:36:55 +00004096static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004097s390_irgen_CGHI(UChar r1, UShort i2)
4098{
4099 IRTemp op1 = newTemp(Ity_I64);
4100 Long op2;
4101
4102 assign(op1, get_gpr_dw0(r1));
4103 op2 = (Long)(Short)i2;
4104 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I64,
4105 mkU64((ULong)op2)));
4106
4107 return "cghi";
4108}
4109
florian55085f82012-11-21 00:36:55 +00004110static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004111s390_irgen_CHHSI(UShort i2, IRTemp op1addr)
4112{
4113 IRTemp op1 = newTemp(Ity_I16);
4114 Short op2;
4115
4116 assign(op1, load(Ity_I16, mkexpr(op1addr)));
4117 op2 = (Short)i2;
4118 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I16,
4119 mkU16((UShort)op2)));
4120
4121 return "chhsi";
4122}
4123
florian55085f82012-11-21 00:36:55 +00004124static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004125s390_irgen_CHSI(UShort i2, IRTemp op1addr)
4126{
4127 IRTemp op1 = newTemp(Ity_I32);
4128 Int op2;
4129
4130 assign(op1, load(Ity_I32, mkexpr(op1addr)));
4131 op2 = (Int)(Short)i2;
4132 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
4133 mkU32((UInt)op2)));
4134
4135 return "chsi";
4136}
4137
florian55085f82012-11-21 00:36:55 +00004138static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004139s390_irgen_CGHSI(UShort i2, IRTemp op1addr)
4140{
4141 IRTemp op1 = newTemp(Ity_I64);
4142 Long op2;
4143
4144 assign(op1, load(Ity_I64, mkexpr(op1addr)));
4145 op2 = (Long)(Short)i2;
4146 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I64,
4147 mkU64((ULong)op2)));
4148
4149 return "cghsi";
4150}
4151
florian55085f82012-11-21 00:36:55 +00004152static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004153s390_irgen_CHRL(UChar r1, UInt i2)
4154{
4155 IRTemp op1 = newTemp(Ity_I32);
4156 IRTemp op2 = newTemp(Ity_I32);
4157
4158 assign(op1, get_gpr_w1(r1));
4159 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
4160 ((ULong)(Long)(Int)i2 << 1)))));
4161 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4162
4163 return "chrl";
4164}
4165
florian55085f82012-11-21 00:36:55 +00004166static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004167s390_irgen_CGHRL(UChar r1, UInt i2)
4168{
4169 IRTemp op1 = newTemp(Ity_I64);
4170 IRTemp op2 = newTemp(Ity_I64);
4171
4172 assign(op1, get_gpr_dw0(r1));
4173 assign(op2, unop(Iop_16Sto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
4174 ((ULong)(Long)(Int)i2 << 1)))));
4175 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4176
4177 return "cghrl";
4178}
4179
florian55085f82012-11-21 00:36:55 +00004180static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004181s390_irgen_CHHR(UChar r1, UChar r2)
4182{
4183 IRTemp op1 = newTemp(Ity_I32);
4184 IRTemp op2 = newTemp(Ity_I32);
4185
4186 assign(op1, get_gpr_w0(r1));
4187 assign(op2, get_gpr_w0(r2));
4188 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4189
4190 return "chhr";
4191}
4192
florian55085f82012-11-21 00:36:55 +00004193static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004194s390_irgen_CHLR(UChar r1, UChar r2)
4195{
4196 IRTemp op1 = newTemp(Ity_I32);
4197 IRTemp op2 = newTemp(Ity_I32);
4198
4199 assign(op1, get_gpr_w0(r1));
4200 assign(op2, get_gpr_w1(r2));
4201 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4202
4203 return "chlr";
4204}
4205
florian55085f82012-11-21 00:36:55 +00004206static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004207s390_irgen_CHF(UChar r1, IRTemp op2addr)
4208{
4209 IRTemp op1 = newTemp(Ity_I32);
4210 IRTemp op2 = newTemp(Ity_I32);
4211
4212 assign(op1, get_gpr_w0(r1));
4213 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4214 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4215
4216 return "chf";
4217}
4218
florian55085f82012-11-21 00:36:55 +00004219static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004220s390_irgen_CIH(UChar r1, UInt i2)
4221{
4222 IRTemp op1 = newTemp(Ity_I32);
4223 Int op2;
4224
4225 assign(op1, get_gpr_w0(r1));
4226 op2 = (Int)i2;
4227 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
4228 mkU32((UInt)op2)));
4229
4230 return "cih";
4231}
4232
florian55085f82012-11-21 00:36:55 +00004233static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004234s390_irgen_CLR(UChar r1, UChar r2)
4235{
4236 IRTemp op1 = newTemp(Ity_I32);
4237 IRTemp op2 = newTemp(Ity_I32);
4238
4239 assign(op1, get_gpr_w1(r1));
4240 assign(op2, get_gpr_w1(r2));
4241 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4242
4243 return "clr";
4244}
4245
florian55085f82012-11-21 00:36:55 +00004246static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004247s390_irgen_CLGR(UChar r1, UChar r2)
4248{
4249 IRTemp op1 = newTemp(Ity_I64);
4250 IRTemp op2 = newTemp(Ity_I64);
4251
4252 assign(op1, get_gpr_dw0(r1));
4253 assign(op2, get_gpr_dw0(r2));
4254 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4255
4256 return "clgr";
4257}
4258
florian55085f82012-11-21 00:36:55 +00004259static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004260s390_irgen_CLGFR(UChar r1, UChar r2)
4261{
4262 IRTemp op1 = newTemp(Ity_I64);
4263 IRTemp op2 = newTemp(Ity_I64);
4264
4265 assign(op1, get_gpr_dw0(r1));
4266 assign(op2, unop(Iop_32Uto64, get_gpr_w1(r2)));
4267 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4268
4269 return "clgfr";
4270}
4271
florian55085f82012-11-21 00:36:55 +00004272static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004273s390_irgen_CL(UChar r1, IRTemp op2addr)
4274{
4275 IRTemp op1 = newTemp(Ity_I32);
4276 IRTemp op2 = newTemp(Ity_I32);
4277
4278 assign(op1, get_gpr_w1(r1));
4279 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4280 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4281
4282 return "cl";
4283}
4284
florian55085f82012-11-21 00:36:55 +00004285static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004286s390_irgen_CLY(UChar r1, IRTemp op2addr)
4287{
4288 IRTemp op1 = newTemp(Ity_I32);
4289 IRTemp op2 = newTemp(Ity_I32);
4290
4291 assign(op1, get_gpr_w1(r1));
4292 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4293 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4294
4295 return "cly";
4296}
4297
florian55085f82012-11-21 00:36:55 +00004298static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004299s390_irgen_CLG(UChar r1, IRTemp op2addr)
4300{
4301 IRTemp op1 = newTemp(Ity_I64);
4302 IRTemp op2 = newTemp(Ity_I64);
4303
4304 assign(op1, get_gpr_dw0(r1));
4305 assign(op2, load(Ity_I64, mkexpr(op2addr)));
4306 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4307
4308 return "clg";
4309}
4310
florian55085f82012-11-21 00:36:55 +00004311static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004312s390_irgen_CLGF(UChar r1, IRTemp op2addr)
4313{
4314 IRTemp op1 = newTemp(Ity_I64);
4315 IRTemp op2 = newTemp(Ity_I64);
4316
4317 assign(op1, get_gpr_dw0(r1));
4318 assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
4319 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4320
4321 return "clgf";
4322}
4323
florian55085f82012-11-21 00:36:55 +00004324static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004325s390_irgen_CLFI(UChar r1, UInt i2)
4326{
4327 IRTemp op1 = newTemp(Ity_I32);
4328 UInt op2;
4329
4330 assign(op1, get_gpr_w1(r1));
4331 op2 = i2;
4332 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I32,
4333 mkU32(op2)));
4334
4335 return "clfi";
4336}
4337
florian55085f82012-11-21 00:36:55 +00004338static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004339s390_irgen_CLGFI(UChar r1, UInt i2)
4340{
4341 IRTemp op1 = newTemp(Ity_I64);
4342 ULong op2;
4343
4344 assign(op1, get_gpr_dw0(r1));
4345 op2 = (ULong)i2;
4346 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I64,
4347 mkU64(op2)));
4348
4349 return "clgfi";
4350}
4351
florian55085f82012-11-21 00:36:55 +00004352static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004353s390_irgen_CLI(UChar i2, IRTemp op1addr)
4354{
4355 IRTemp op1 = newTemp(Ity_I8);
4356 UChar op2;
4357
4358 assign(op1, load(Ity_I8, mkexpr(op1addr)));
4359 op2 = i2;
4360 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I8,
4361 mkU8(op2)));
4362
4363 return "cli";
4364}
4365
florian55085f82012-11-21 00:36:55 +00004366static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004367s390_irgen_CLIY(UChar i2, IRTemp op1addr)
4368{
4369 IRTemp op1 = newTemp(Ity_I8);
4370 UChar op2;
4371
4372 assign(op1, load(Ity_I8, mkexpr(op1addr)));
4373 op2 = i2;
4374 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I8,
4375 mkU8(op2)));
4376
4377 return "cliy";
4378}
4379
florian55085f82012-11-21 00:36:55 +00004380static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004381s390_irgen_CLFHSI(UShort i2, IRTemp op1addr)
4382{
4383 IRTemp op1 = newTemp(Ity_I32);
4384 UInt op2;
4385
4386 assign(op1, load(Ity_I32, mkexpr(op1addr)));
4387 op2 = (UInt)i2;
4388 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I32,
4389 mkU32(op2)));
4390
4391 return "clfhsi";
4392}
4393
florian55085f82012-11-21 00:36:55 +00004394static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004395s390_irgen_CLGHSI(UShort i2, IRTemp op1addr)
4396{
4397 IRTemp op1 = newTemp(Ity_I64);
4398 ULong op2;
4399
4400 assign(op1, load(Ity_I64, mkexpr(op1addr)));
4401 op2 = (ULong)i2;
4402 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I64,
4403 mkU64(op2)));
4404
4405 return "clghsi";
4406}
4407
florian55085f82012-11-21 00:36:55 +00004408static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004409s390_irgen_CLHHSI(UShort i2, IRTemp op1addr)
4410{
4411 IRTemp op1 = newTemp(Ity_I16);
4412 UShort op2;
4413
4414 assign(op1, load(Ity_I16, mkexpr(op1addr)));
4415 op2 = i2;
4416 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I16,
4417 mkU16(op2)));
4418
4419 return "clhhsi";
4420}
4421
florian55085f82012-11-21 00:36:55 +00004422static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004423s390_irgen_CLRL(UChar r1, UInt i2)
4424{
4425 IRTemp op1 = newTemp(Ity_I32);
4426 IRTemp op2 = newTemp(Ity_I32);
4427
4428 assign(op1, get_gpr_w1(r1));
4429 assign(op2, load(Ity_I32, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
4430 i2 << 1))));
4431 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4432
4433 return "clrl";
4434}
4435
florian55085f82012-11-21 00:36:55 +00004436static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004437s390_irgen_CLGRL(UChar r1, UInt i2)
4438{
4439 IRTemp op1 = newTemp(Ity_I64);
4440 IRTemp op2 = newTemp(Ity_I64);
4441
4442 assign(op1, get_gpr_dw0(r1));
4443 assign(op2, load(Ity_I64, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
4444 i2 << 1))));
4445 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4446
4447 return "clgrl";
4448}
4449
florian55085f82012-11-21 00:36:55 +00004450static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004451s390_irgen_CLGFRL(UChar r1, UInt i2)
4452{
4453 IRTemp op1 = newTemp(Ity_I64);
4454 IRTemp op2 = newTemp(Ity_I64);
4455
4456 assign(op1, get_gpr_dw0(r1));
4457 assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
4458 ((ULong)(Long)(Int)i2 << 1)))));
4459 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4460
4461 return "clgfrl";
4462}
4463
florian55085f82012-11-21 00:36:55 +00004464static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004465s390_irgen_CLHRL(UChar r1, UInt i2)
4466{
4467 IRTemp op1 = newTemp(Ity_I32);
4468 IRTemp op2 = newTemp(Ity_I32);
4469
4470 assign(op1, get_gpr_w1(r1));
4471 assign(op2, unop(Iop_16Uto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
4472 ((ULong)(Long)(Int)i2 << 1)))));
4473 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4474
4475 return "clhrl";
4476}
4477
florian55085f82012-11-21 00:36:55 +00004478static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004479s390_irgen_CLGHRL(UChar r1, UInt i2)
4480{
4481 IRTemp op1 = newTemp(Ity_I64);
4482 IRTemp op2 = newTemp(Ity_I64);
4483
4484 assign(op1, get_gpr_dw0(r1));
4485 assign(op2, unop(Iop_16Uto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
4486 ((ULong)(Long)(Int)i2 << 1)))));
4487 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4488
4489 return "clghrl";
4490}
4491
florian55085f82012-11-21 00:36:55 +00004492static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004493s390_irgen_CLRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
4494{
4495 IRTemp op1 = newTemp(Ity_I32);
4496 IRTemp op2 = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00004497 IRTemp cond = newTemp(Ity_I32);
4498
4499 if (m3 == 0) {
4500 } else {
4501 if (m3 == 14) {
4502 always_goto(mkexpr(op4addr));
4503 } else {
4504 assign(op1, get_gpr_w1(r1));
4505 assign(op2, get_gpr_w1(r2));
florianff9613f2012-05-12 15:26:44 +00004506 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4507 op1, op2));
florianf321da72012-07-21 20:32:57 +00004508 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4509 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004510 }
4511 }
4512
4513 return "clrb";
4514}
4515
florian55085f82012-11-21 00:36:55 +00004516static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004517s390_irgen_CLGRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
4518{
4519 IRTemp op1 = newTemp(Ity_I64);
4520 IRTemp op2 = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00004521 IRTemp cond = newTemp(Ity_I32);
4522
4523 if (m3 == 0) {
4524 } else {
4525 if (m3 == 14) {
4526 always_goto(mkexpr(op4addr));
4527 } else {
4528 assign(op1, get_gpr_dw0(r1));
4529 assign(op2, get_gpr_dw0(r2));
florianff9613f2012-05-12 15:26:44 +00004530 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4531 op1, op2));
florianf321da72012-07-21 20:32:57 +00004532 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4533 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004534 }
4535 }
4536
4537 return "clgrb";
4538}
4539
florian55085f82012-11-21 00:36:55 +00004540static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004541s390_irgen_CLRJ(UChar r1, UChar r2, UShort i4, UChar m3)
4542{
4543 IRTemp op1 = newTemp(Ity_I32);
4544 IRTemp op2 = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00004545 IRTemp cond = newTemp(Ity_I32);
4546
4547 if (m3 == 0) {
4548 } else {
4549 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004550 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004551 } else {
4552 assign(op1, get_gpr_w1(r1));
4553 assign(op2, get_gpr_w1(r2));
florianff9613f2012-05-12 15:26:44 +00004554 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4555 op1, op2));
sewardj2019a972011-03-07 16:04:07 +00004556 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4557 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4558
4559 }
4560 }
4561
4562 return "clrj";
4563}
4564
florian55085f82012-11-21 00:36:55 +00004565static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004566s390_irgen_CLGRJ(UChar r1, UChar r2, UShort i4, UChar m3)
4567{
4568 IRTemp op1 = newTemp(Ity_I64);
4569 IRTemp op2 = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00004570 IRTemp cond = newTemp(Ity_I32);
4571
4572 if (m3 == 0) {
4573 } else {
4574 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004575 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004576 } else {
4577 assign(op1, get_gpr_dw0(r1));
4578 assign(op2, get_gpr_dw0(r2));
florianff9613f2012-05-12 15:26:44 +00004579 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4580 op1, op2));
sewardj2019a972011-03-07 16:04:07 +00004581 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4582 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4583
4584 }
4585 }
4586
4587 return "clgrj";
4588}
4589
florian55085f82012-11-21 00:36:55 +00004590static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004591s390_irgen_CLIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
4592{
4593 IRTemp op1 = newTemp(Ity_I32);
4594 UInt op2;
sewardj2019a972011-03-07 16:04:07 +00004595 IRTemp cond = newTemp(Ity_I32);
4596
4597 if (m3 == 0) {
4598 } else {
4599 if (m3 == 14) {
4600 always_goto(mkexpr(op4addr));
4601 } else {
4602 assign(op1, get_gpr_w1(r1));
4603 op2 = (UInt)i2;
florianff9613f2012-05-12 15:26:44 +00004604 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4605 mktemp(Ity_I32, mkU32(op2))));
florianf321da72012-07-21 20:32:57 +00004606 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4607 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004608 }
4609 }
4610
4611 return "clib";
4612}
4613
florian55085f82012-11-21 00:36:55 +00004614static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004615s390_irgen_CLGIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
4616{
4617 IRTemp op1 = newTemp(Ity_I64);
4618 ULong op2;
sewardj2019a972011-03-07 16:04:07 +00004619 IRTemp cond = newTemp(Ity_I32);
4620
4621 if (m3 == 0) {
4622 } else {
4623 if (m3 == 14) {
4624 always_goto(mkexpr(op4addr));
4625 } else {
4626 assign(op1, get_gpr_dw0(r1));
4627 op2 = (ULong)i2;
florianff9613f2012-05-12 15:26:44 +00004628 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4629 mktemp(Ity_I64, mkU64(op2))));
florianf321da72012-07-21 20:32:57 +00004630 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4631 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004632 }
4633 }
4634
4635 return "clgib";
4636}
4637
florian55085f82012-11-21 00:36:55 +00004638static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004639s390_irgen_CLIJ(UChar r1, UChar m3, UShort i4, UChar i2)
4640{
4641 IRTemp op1 = newTemp(Ity_I32);
4642 UInt op2;
sewardj2019a972011-03-07 16:04:07 +00004643 IRTemp cond = newTemp(Ity_I32);
4644
4645 if (m3 == 0) {
4646 } else {
4647 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004648 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004649 } else {
4650 assign(op1, get_gpr_w1(r1));
4651 op2 = (UInt)i2;
florianff9613f2012-05-12 15:26:44 +00004652 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4653 mktemp(Ity_I32, mkU32(op2))));
sewardj2019a972011-03-07 16:04:07 +00004654 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4655 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4656
4657 }
4658 }
4659
4660 return "clij";
4661}
4662
florian55085f82012-11-21 00:36:55 +00004663static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004664s390_irgen_CLGIJ(UChar r1, UChar m3, UShort i4, UChar i2)
4665{
4666 IRTemp op1 = newTemp(Ity_I64);
4667 ULong op2;
sewardj2019a972011-03-07 16:04:07 +00004668 IRTemp cond = newTemp(Ity_I32);
4669
4670 if (m3 == 0) {
4671 } else {
4672 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004673 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004674 } else {
4675 assign(op1, get_gpr_dw0(r1));
4676 op2 = (ULong)i2;
florianff9613f2012-05-12 15:26:44 +00004677 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4678 mktemp(Ity_I64, mkU64(op2))));
sewardj2019a972011-03-07 16:04:07 +00004679 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4680 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4681
4682 }
4683 }
4684
4685 return "clgij";
4686}
4687
florian55085f82012-11-21 00:36:55 +00004688static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004689s390_irgen_CLM(UChar r1, UChar r3, IRTemp op2addr)
4690{
4691 IRTemp op1 = newTemp(Ity_I32);
4692 IRTemp op2 = newTemp(Ity_I32);
4693 IRTemp b0 = newTemp(Ity_I32);
4694 IRTemp b1 = newTemp(Ity_I32);
4695 IRTemp b2 = newTemp(Ity_I32);
4696 IRTemp b3 = newTemp(Ity_I32);
4697 IRTemp c0 = newTemp(Ity_I32);
4698 IRTemp c1 = newTemp(Ity_I32);
4699 IRTemp c2 = newTemp(Ity_I32);
4700 IRTemp c3 = newTemp(Ity_I32);
4701 UChar n;
4702
4703 n = 0;
4704 if ((r3 & 8) != 0) {
4705 assign(b0, unop(Iop_8Uto32, get_gpr_b4(r1)));
4706 assign(c0, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
4707 n = n + 1;
4708 } else {
4709 assign(b0, mkU32(0));
4710 assign(c0, mkU32(0));
4711 }
4712 if ((r3 & 4) != 0) {
4713 assign(b1, unop(Iop_8Uto32, get_gpr_b5(r1)));
4714 assign(c1, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4715 mkU64(n)))));
4716 n = n + 1;
4717 } else {
4718 assign(b1, mkU32(0));
4719 assign(c1, mkU32(0));
4720 }
4721 if ((r3 & 2) != 0) {
4722 assign(b2, unop(Iop_8Uto32, get_gpr_b6(r1)));
4723 assign(c2, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4724 mkU64(n)))));
4725 n = n + 1;
4726 } else {
4727 assign(b2, mkU32(0));
4728 assign(c2, mkU32(0));
4729 }
4730 if ((r3 & 1) != 0) {
4731 assign(b3, unop(Iop_8Uto32, get_gpr_b7(r1)));
4732 assign(c3, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4733 mkU64(n)))));
4734 n = n + 1;
4735 } else {
4736 assign(b3, mkU32(0));
4737 assign(c3, mkU32(0));
4738 }
4739 assign(op1, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4740 mkexpr(b0), mkU8(24)), binop(Iop_Shl32, mkexpr(b1), mkU8(16))),
4741 binop(Iop_Shl32, mkexpr(b2), mkU8(8))), mkexpr(b3)));
4742 assign(op2, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4743 mkexpr(c0), mkU8(24)), binop(Iop_Shl32, mkexpr(c1), mkU8(16))),
4744 binop(Iop_Shl32, mkexpr(c2), mkU8(8))), mkexpr(c3)));
4745 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4746
4747 return "clm";
4748}
4749
florian55085f82012-11-21 00:36:55 +00004750static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004751s390_irgen_CLMY(UChar r1, UChar r3, IRTemp op2addr)
4752{
4753 IRTemp op1 = newTemp(Ity_I32);
4754 IRTemp op2 = newTemp(Ity_I32);
4755 IRTemp b0 = newTemp(Ity_I32);
4756 IRTemp b1 = newTemp(Ity_I32);
4757 IRTemp b2 = newTemp(Ity_I32);
4758 IRTemp b3 = newTemp(Ity_I32);
4759 IRTemp c0 = newTemp(Ity_I32);
4760 IRTemp c1 = newTemp(Ity_I32);
4761 IRTemp c2 = newTemp(Ity_I32);
4762 IRTemp c3 = newTemp(Ity_I32);
4763 UChar n;
4764
4765 n = 0;
4766 if ((r3 & 8) != 0) {
4767 assign(b0, unop(Iop_8Uto32, get_gpr_b4(r1)));
4768 assign(c0, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
4769 n = n + 1;
4770 } else {
4771 assign(b0, mkU32(0));
4772 assign(c0, mkU32(0));
4773 }
4774 if ((r3 & 4) != 0) {
4775 assign(b1, unop(Iop_8Uto32, get_gpr_b5(r1)));
4776 assign(c1, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4777 mkU64(n)))));
4778 n = n + 1;
4779 } else {
4780 assign(b1, mkU32(0));
4781 assign(c1, mkU32(0));
4782 }
4783 if ((r3 & 2) != 0) {
4784 assign(b2, unop(Iop_8Uto32, get_gpr_b6(r1)));
4785 assign(c2, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4786 mkU64(n)))));
4787 n = n + 1;
4788 } else {
4789 assign(b2, mkU32(0));
4790 assign(c2, mkU32(0));
4791 }
4792 if ((r3 & 1) != 0) {
4793 assign(b3, unop(Iop_8Uto32, get_gpr_b7(r1)));
4794 assign(c3, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4795 mkU64(n)))));
4796 n = n + 1;
4797 } else {
4798 assign(b3, mkU32(0));
4799 assign(c3, mkU32(0));
4800 }
4801 assign(op1, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4802 mkexpr(b0), mkU8(24)), binop(Iop_Shl32, mkexpr(b1), mkU8(16))),
4803 binop(Iop_Shl32, mkexpr(b2), mkU8(8))), mkexpr(b3)));
4804 assign(op2, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4805 mkexpr(c0), mkU8(24)), binop(Iop_Shl32, mkexpr(c1), mkU8(16))),
4806 binop(Iop_Shl32, mkexpr(c2), mkU8(8))), mkexpr(c3)));
4807 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4808
4809 return "clmy";
4810}
4811
florian55085f82012-11-21 00:36:55 +00004812static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004813s390_irgen_CLMH(UChar r1, UChar r3, IRTemp op2addr)
4814{
4815 IRTemp op1 = newTemp(Ity_I32);
4816 IRTemp op2 = newTemp(Ity_I32);
4817 IRTemp b0 = newTemp(Ity_I32);
4818 IRTemp b1 = newTemp(Ity_I32);
4819 IRTemp b2 = newTemp(Ity_I32);
4820 IRTemp b3 = newTemp(Ity_I32);
4821 IRTemp c0 = newTemp(Ity_I32);
4822 IRTemp c1 = newTemp(Ity_I32);
4823 IRTemp c2 = newTemp(Ity_I32);
4824 IRTemp c3 = newTemp(Ity_I32);
4825 UChar n;
4826
4827 n = 0;
4828 if ((r3 & 8) != 0) {
4829 assign(b0, unop(Iop_8Uto32, get_gpr_b0(r1)));
4830 assign(c0, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
4831 n = n + 1;
4832 } else {
4833 assign(b0, mkU32(0));
4834 assign(c0, mkU32(0));
4835 }
4836 if ((r3 & 4) != 0) {
4837 assign(b1, unop(Iop_8Uto32, get_gpr_b1(r1)));
4838 assign(c1, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4839 mkU64(n)))));
4840 n = n + 1;
4841 } else {
4842 assign(b1, mkU32(0));
4843 assign(c1, mkU32(0));
4844 }
4845 if ((r3 & 2) != 0) {
4846 assign(b2, unop(Iop_8Uto32, get_gpr_b2(r1)));
4847 assign(c2, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4848 mkU64(n)))));
4849 n = n + 1;
4850 } else {
4851 assign(b2, mkU32(0));
4852 assign(c2, mkU32(0));
4853 }
4854 if ((r3 & 1) != 0) {
4855 assign(b3, unop(Iop_8Uto32, get_gpr_b3(r1)));
4856 assign(c3, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4857 mkU64(n)))));
4858 n = n + 1;
4859 } else {
4860 assign(b3, mkU32(0));
4861 assign(c3, mkU32(0));
4862 }
4863 assign(op1, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4864 mkexpr(b0), mkU8(24)), binop(Iop_Shl32, mkexpr(b1), mkU8(16))),
4865 binop(Iop_Shl32, mkexpr(b2), mkU8(8))), mkexpr(b3)));
4866 assign(op2, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4867 mkexpr(c0), mkU8(24)), binop(Iop_Shl32, mkexpr(c1), mkU8(16))),
4868 binop(Iop_Shl32, mkexpr(c2), mkU8(8))), mkexpr(c3)));
4869 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4870
4871 return "clmh";
4872}
4873
florian55085f82012-11-21 00:36:55 +00004874static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004875s390_irgen_CLHHR(UChar r1, UChar r2)
4876{
4877 IRTemp op1 = newTemp(Ity_I32);
4878 IRTemp op2 = newTemp(Ity_I32);
4879
4880 assign(op1, get_gpr_w0(r1));
4881 assign(op2, get_gpr_w0(r2));
4882 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4883
4884 return "clhhr";
4885}
4886
florian55085f82012-11-21 00:36:55 +00004887static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004888s390_irgen_CLHLR(UChar r1, UChar r2)
4889{
4890 IRTemp op1 = newTemp(Ity_I32);
4891 IRTemp op2 = newTemp(Ity_I32);
4892
4893 assign(op1, get_gpr_w0(r1));
4894 assign(op2, get_gpr_w1(r2));
4895 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4896
4897 return "clhlr";
4898}
4899
florian55085f82012-11-21 00:36:55 +00004900static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004901s390_irgen_CLHF(UChar r1, IRTemp op2addr)
4902{
4903 IRTemp op1 = newTemp(Ity_I32);
4904 IRTemp op2 = newTemp(Ity_I32);
4905
4906 assign(op1, get_gpr_w0(r1));
4907 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4908 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4909
4910 return "clhf";
4911}
4912
florian55085f82012-11-21 00:36:55 +00004913static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004914s390_irgen_CLIH(UChar r1, UInt i2)
4915{
4916 IRTemp op1 = newTemp(Ity_I32);
4917 UInt op2;
4918
4919 assign(op1, get_gpr_w0(r1));
4920 op2 = i2;
4921 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I32,
4922 mkU32(op2)));
4923
4924 return "clih";
4925}
4926
florian55085f82012-11-21 00:36:55 +00004927static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004928s390_irgen_CPYA(UChar r1, UChar r2)
4929{
4930 put_ar_w0(r1, get_ar_w0(r2));
sewardj7ee97522011-05-09 21:45:04 +00004931 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00004932 s390_disasm(ENC3(MNM, AR, AR), "cpya", r1, r2);
4933
4934 return "cpya";
4935}
4936
florian55085f82012-11-21 00:36:55 +00004937static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004938s390_irgen_XR(UChar r1, UChar r2)
4939{
4940 IRTemp op1 = newTemp(Ity_I32);
4941 IRTemp op2 = newTemp(Ity_I32);
4942 IRTemp result = newTemp(Ity_I32);
4943
4944 if (r1 == r2) {
4945 assign(result, mkU32(0));
4946 } else {
4947 assign(op1, get_gpr_w1(r1));
4948 assign(op2, get_gpr_w1(r2));
4949 assign(result, binop(Iop_Xor32, mkexpr(op1), mkexpr(op2)));
4950 }
4951 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4952 put_gpr_w1(r1, mkexpr(result));
4953
4954 return "xr";
4955}
4956
florian55085f82012-11-21 00:36:55 +00004957static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004958s390_irgen_XGR(UChar r1, UChar r2)
4959{
4960 IRTemp op1 = newTemp(Ity_I64);
4961 IRTemp op2 = newTemp(Ity_I64);
4962 IRTemp result = newTemp(Ity_I64);
4963
4964 if (r1 == r2) {
4965 assign(result, mkU64(0));
4966 } else {
4967 assign(op1, get_gpr_dw0(r1));
4968 assign(op2, get_gpr_dw0(r2));
4969 assign(result, binop(Iop_Xor64, mkexpr(op1), mkexpr(op2)));
4970 }
4971 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4972 put_gpr_dw0(r1, mkexpr(result));
4973
4974 return "xgr";
4975}
4976
florian55085f82012-11-21 00:36:55 +00004977static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004978s390_irgen_XRK(UChar r3, UChar r1, UChar r2)
4979{
4980 IRTemp op2 = newTemp(Ity_I32);
4981 IRTemp op3 = newTemp(Ity_I32);
4982 IRTemp result = newTemp(Ity_I32);
4983
4984 assign(op2, get_gpr_w1(r2));
4985 assign(op3, get_gpr_w1(r3));
4986 assign(result, binop(Iop_Xor32, mkexpr(op2), mkexpr(op3)));
4987 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
4988 put_gpr_w1(r1, mkexpr(result));
4989
4990 return "xrk";
4991}
4992
florian55085f82012-11-21 00:36:55 +00004993static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004994s390_irgen_XGRK(UChar r3, UChar r1, UChar r2)
4995{
4996 IRTemp op2 = newTemp(Ity_I64);
4997 IRTemp op3 = newTemp(Ity_I64);
4998 IRTemp result = newTemp(Ity_I64);
4999
5000 assign(op2, get_gpr_dw0(r2));
5001 assign(op3, get_gpr_dw0(r3));
5002 assign(result, binop(Iop_Xor64, mkexpr(op2), mkexpr(op3)));
5003 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5004 put_gpr_dw0(r1, mkexpr(result));
5005
5006 return "xgrk";
5007}
5008
florian55085f82012-11-21 00:36:55 +00005009static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005010s390_irgen_X(UChar r1, IRTemp op2addr)
5011{
5012 IRTemp op1 = newTemp(Ity_I32);
5013 IRTemp op2 = newTemp(Ity_I32);
5014 IRTemp result = newTemp(Ity_I32);
5015
5016 assign(op1, get_gpr_w1(r1));
5017 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5018 assign(result, binop(Iop_Xor32, mkexpr(op1), mkexpr(op2)));
5019 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5020 put_gpr_w1(r1, mkexpr(result));
5021
5022 return "x";
5023}
5024
florian55085f82012-11-21 00:36:55 +00005025static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005026s390_irgen_XY(UChar r1, IRTemp op2addr)
5027{
5028 IRTemp op1 = newTemp(Ity_I32);
5029 IRTemp op2 = newTemp(Ity_I32);
5030 IRTemp result = newTemp(Ity_I32);
5031
5032 assign(op1, get_gpr_w1(r1));
5033 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5034 assign(result, binop(Iop_Xor32, mkexpr(op1), mkexpr(op2)));
5035 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5036 put_gpr_w1(r1, mkexpr(result));
5037
5038 return "xy";
5039}
5040
florian55085f82012-11-21 00:36:55 +00005041static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005042s390_irgen_XG(UChar r1, IRTemp op2addr)
5043{
5044 IRTemp op1 = newTemp(Ity_I64);
5045 IRTemp op2 = newTemp(Ity_I64);
5046 IRTemp result = newTemp(Ity_I64);
5047
5048 assign(op1, get_gpr_dw0(r1));
5049 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5050 assign(result, binop(Iop_Xor64, mkexpr(op1), mkexpr(op2)));
5051 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5052 put_gpr_dw0(r1, mkexpr(result));
5053
5054 return "xg";
5055}
5056
florian55085f82012-11-21 00:36:55 +00005057static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005058s390_irgen_XI(UChar i2, IRTemp op1addr)
5059{
5060 IRTemp op1 = newTemp(Ity_I8);
5061 UChar op2;
5062 IRTemp result = newTemp(Ity_I8);
5063
5064 assign(op1, load(Ity_I8, mkexpr(op1addr)));
5065 op2 = i2;
5066 assign(result, binop(Iop_Xor8, mkexpr(op1), mkU8(op2)));
5067 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5068 store(mkexpr(op1addr), mkexpr(result));
5069
5070 return "xi";
5071}
5072
florian55085f82012-11-21 00:36:55 +00005073static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005074s390_irgen_XIY(UChar i2, IRTemp op1addr)
5075{
5076 IRTemp op1 = newTemp(Ity_I8);
5077 UChar op2;
5078 IRTemp result = newTemp(Ity_I8);
5079
5080 assign(op1, load(Ity_I8, mkexpr(op1addr)));
5081 op2 = i2;
5082 assign(result, binop(Iop_Xor8, mkexpr(op1), mkU8(op2)));
5083 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5084 store(mkexpr(op1addr), mkexpr(result));
5085
5086 return "xiy";
5087}
5088
florian55085f82012-11-21 00:36:55 +00005089static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005090s390_irgen_XIHF(UChar r1, UInt i2)
5091{
5092 IRTemp op1 = newTemp(Ity_I32);
5093 UInt op2;
5094 IRTemp result = newTemp(Ity_I32);
5095
5096 assign(op1, get_gpr_w0(r1));
5097 op2 = i2;
5098 assign(result, binop(Iop_Xor32, mkexpr(op1), mkU32(op2)));
5099 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5100 put_gpr_w0(r1, mkexpr(result));
5101
5102 return "xihf";
5103}
5104
florian55085f82012-11-21 00:36:55 +00005105static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005106s390_irgen_XILF(UChar r1, UInt i2)
5107{
5108 IRTemp op1 = newTemp(Ity_I32);
5109 UInt op2;
5110 IRTemp result = newTemp(Ity_I32);
5111
5112 assign(op1, get_gpr_w1(r1));
5113 op2 = i2;
5114 assign(result, binop(Iop_Xor32, mkexpr(op1), mkU32(op2)));
5115 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5116 put_gpr_w1(r1, mkexpr(result));
5117
5118 return "xilf";
5119}
5120
florian55085f82012-11-21 00:36:55 +00005121static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005122s390_irgen_EAR(UChar r1, UChar r2)
5123{
5124 put_gpr_w1(r1, get_ar_w0(r2));
sewardj7ee97522011-05-09 21:45:04 +00005125 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00005126 s390_disasm(ENC3(MNM, GPR, AR), "ear", r1, r2);
5127
5128 return "ear";
5129}
5130
florian55085f82012-11-21 00:36:55 +00005131static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005132s390_irgen_IC(UChar r1, IRTemp op2addr)
5133{
5134 put_gpr_b7(r1, load(Ity_I8, mkexpr(op2addr)));
5135
5136 return "ic";
5137}
5138
florian55085f82012-11-21 00:36:55 +00005139static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005140s390_irgen_ICY(UChar r1, IRTemp op2addr)
5141{
5142 put_gpr_b7(r1, load(Ity_I8, mkexpr(op2addr)));
5143
5144 return "icy";
5145}
5146
florian55085f82012-11-21 00:36:55 +00005147static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005148s390_irgen_ICM(UChar r1, UChar r3, IRTemp op2addr)
5149{
5150 UChar n;
5151 IRTemp result = newTemp(Ity_I32);
5152 UInt mask;
5153
5154 n = 0;
5155 mask = (UInt)r3;
5156 if ((mask & 8) != 0) {
5157 put_gpr_b4(r1, load(Ity_I8, mkexpr(op2addr)));
5158 n = n + 1;
5159 }
5160 if ((mask & 4) != 0) {
5161 put_gpr_b5(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5162
5163 n = n + 1;
5164 }
5165 if ((mask & 2) != 0) {
5166 put_gpr_b6(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5167
5168 n = n + 1;
5169 }
5170 if ((mask & 1) != 0) {
5171 put_gpr_b7(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5172
5173 n = n + 1;
5174 }
5175 assign(result, get_gpr_w1(r1));
5176 s390_cc_thunk_putZZ(S390_CC_OP_INSERT_CHAR_MASK_32, result, mktemp(Ity_I32,
5177 mkU32(mask)));
5178
5179 return "icm";
5180}
5181
florian55085f82012-11-21 00:36:55 +00005182static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005183s390_irgen_ICMY(UChar r1, UChar r3, IRTemp op2addr)
5184{
5185 UChar n;
5186 IRTemp result = newTemp(Ity_I32);
5187 UInt mask;
5188
5189 n = 0;
5190 mask = (UInt)r3;
5191 if ((mask & 8) != 0) {
5192 put_gpr_b4(r1, load(Ity_I8, mkexpr(op2addr)));
5193 n = n + 1;
5194 }
5195 if ((mask & 4) != 0) {
5196 put_gpr_b5(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5197
5198 n = n + 1;
5199 }
5200 if ((mask & 2) != 0) {
5201 put_gpr_b6(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5202
5203 n = n + 1;
5204 }
5205 if ((mask & 1) != 0) {
5206 put_gpr_b7(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5207
5208 n = n + 1;
5209 }
5210 assign(result, get_gpr_w1(r1));
5211 s390_cc_thunk_putZZ(S390_CC_OP_INSERT_CHAR_MASK_32, result, mktemp(Ity_I32,
5212 mkU32(mask)));
5213
5214 return "icmy";
5215}
5216
florian55085f82012-11-21 00:36:55 +00005217static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005218s390_irgen_ICMH(UChar r1, UChar r3, IRTemp op2addr)
5219{
5220 UChar n;
5221 IRTemp result = newTemp(Ity_I32);
5222 UInt mask;
5223
5224 n = 0;
5225 mask = (UInt)r3;
5226 if ((mask & 8) != 0) {
5227 put_gpr_b0(r1, load(Ity_I8, mkexpr(op2addr)));
5228 n = n + 1;
5229 }
5230 if ((mask & 4) != 0) {
5231 put_gpr_b1(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5232
5233 n = n + 1;
5234 }
5235 if ((mask & 2) != 0) {
5236 put_gpr_b2(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5237
5238 n = n + 1;
5239 }
5240 if ((mask & 1) != 0) {
5241 put_gpr_b3(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5242
5243 n = n + 1;
5244 }
5245 assign(result, get_gpr_w0(r1));
5246 s390_cc_thunk_putZZ(S390_CC_OP_INSERT_CHAR_MASK_32, result, mktemp(Ity_I32,
5247 mkU32(mask)));
5248
5249 return "icmh";
5250}
5251
florian55085f82012-11-21 00:36:55 +00005252static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005253s390_irgen_IIHF(UChar r1, UInt i2)
5254{
5255 put_gpr_w0(r1, mkU32(i2));
5256
5257 return "iihf";
5258}
5259
florian55085f82012-11-21 00:36:55 +00005260static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005261s390_irgen_IIHH(UChar r1, UShort i2)
5262{
5263 put_gpr_hw0(r1, mkU16(i2));
5264
5265 return "iihh";
5266}
5267
florian55085f82012-11-21 00:36:55 +00005268static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005269s390_irgen_IIHL(UChar r1, UShort i2)
5270{
5271 put_gpr_hw1(r1, mkU16(i2));
5272
5273 return "iihl";
5274}
5275
florian55085f82012-11-21 00:36:55 +00005276static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005277s390_irgen_IILF(UChar r1, UInt i2)
5278{
5279 put_gpr_w1(r1, mkU32(i2));
5280
5281 return "iilf";
5282}
5283
florian55085f82012-11-21 00:36:55 +00005284static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005285s390_irgen_IILH(UChar r1, UShort i2)
5286{
5287 put_gpr_hw2(r1, mkU16(i2));
5288
5289 return "iilh";
5290}
5291
florian55085f82012-11-21 00:36:55 +00005292static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005293s390_irgen_IILL(UChar r1, UShort i2)
5294{
5295 put_gpr_hw3(r1, mkU16(i2));
5296
5297 return "iill";
5298}
5299
florian55085f82012-11-21 00:36:55 +00005300static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005301s390_irgen_LR(UChar r1, UChar r2)
5302{
5303 put_gpr_w1(r1, get_gpr_w1(r2));
5304
5305 return "lr";
5306}
5307
florian55085f82012-11-21 00:36:55 +00005308static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005309s390_irgen_LGR(UChar r1, UChar r2)
5310{
5311 put_gpr_dw0(r1, get_gpr_dw0(r2));
5312
5313 return "lgr";
5314}
5315
florian55085f82012-11-21 00:36:55 +00005316static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005317s390_irgen_LGFR(UChar r1, UChar r2)
5318{
5319 put_gpr_dw0(r1, unop(Iop_32Sto64, get_gpr_w1(r2)));
5320
5321 return "lgfr";
5322}
5323
florian55085f82012-11-21 00:36:55 +00005324static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005325s390_irgen_L(UChar r1, IRTemp op2addr)
5326{
5327 put_gpr_w1(r1, load(Ity_I32, mkexpr(op2addr)));
5328
5329 return "l";
5330}
5331
florian55085f82012-11-21 00:36:55 +00005332static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005333s390_irgen_LY(UChar r1, IRTemp op2addr)
5334{
5335 put_gpr_w1(r1, load(Ity_I32, mkexpr(op2addr)));
5336
5337 return "ly";
5338}
5339
florian55085f82012-11-21 00:36:55 +00005340static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005341s390_irgen_LG(UChar r1, IRTemp op2addr)
5342{
5343 put_gpr_dw0(r1, load(Ity_I64, mkexpr(op2addr)));
5344
5345 return "lg";
5346}
5347
florian55085f82012-11-21 00:36:55 +00005348static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005349s390_irgen_LGF(UChar r1, IRTemp op2addr)
5350{
5351 put_gpr_dw0(r1, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
5352
5353 return "lgf";
5354}
5355
florian55085f82012-11-21 00:36:55 +00005356static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005357s390_irgen_LGFI(UChar r1, UInt i2)
5358{
5359 put_gpr_dw0(r1, mkU64((ULong)(Long)(Int)i2));
5360
5361 return "lgfi";
5362}
5363
florian55085f82012-11-21 00:36:55 +00005364static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005365s390_irgen_LRL(UChar r1, UInt i2)
5366{
5367 put_gpr_w1(r1, load(Ity_I32, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
5368 i2 << 1))));
5369
5370 return "lrl";
5371}
5372
florian55085f82012-11-21 00:36:55 +00005373static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005374s390_irgen_LGRL(UChar r1, UInt i2)
5375{
5376 put_gpr_dw0(r1, load(Ity_I64, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
5377 i2 << 1))));
5378
5379 return "lgrl";
5380}
5381
florian55085f82012-11-21 00:36:55 +00005382static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005383s390_irgen_LGFRL(UChar r1, UInt i2)
5384{
5385 put_gpr_dw0(r1, unop(Iop_32Sto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
5386 ((ULong)(Long)(Int)i2 << 1)))));
5387
5388 return "lgfrl";
5389}
5390
florian55085f82012-11-21 00:36:55 +00005391static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005392s390_irgen_LA(UChar r1, IRTemp op2addr)
5393{
5394 put_gpr_dw0(r1, mkexpr(op2addr));
5395
5396 return "la";
5397}
5398
florian55085f82012-11-21 00:36:55 +00005399static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005400s390_irgen_LAY(UChar r1, IRTemp op2addr)
5401{
5402 put_gpr_dw0(r1, mkexpr(op2addr));
5403
5404 return "lay";
5405}
5406
florian55085f82012-11-21 00:36:55 +00005407static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005408s390_irgen_LAE(UChar r1, IRTemp op2addr)
5409{
5410 put_gpr_dw0(r1, mkexpr(op2addr));
5411
5412 return "lae";
5413}
5414
florian55085f82012-11-21 00:36:55 +00005415static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005416s390_irgen_LAEY(UChar r1, IRTemp op2addr)
5417{
5418 put_gpr_dw0(r1, mkexpr(op2addr));
5419
5420 return "laey";
5421}
5422
florian55085f82012-11-21 00:36:55 +00005423static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005424s390_irgen_LARL(UChar r1, UInt i2)
5425{
5426 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)));
5427
5428 return "larl";
5429}
5430
floriana265ee72012-12-02 20:58:17 +00005431/* The IR representation of LAA and friends is an approximation of what
5432 happens natively. Essentially a loop containing a compare-and-swap is
5433 constructed which will iterate until the CAS succeeds. As a consequence,
5434 instrumenters may see more memory accesses than happen natively. See also
5435 discussion here: https://bugs.kde.org/show_bug.cgi?id=306035 */
florianffc94012012-12-02 21:31:15 +00005436static void
5437s390_irgen_load_and_add32(UChar r1, UChar r3, IRTemp op2addr, Bool is_signed)
sewardj2019a972011-03-07 16:04:07 +00005438{
floriana265ee72012-12-02 20:58:17 +00005439 IRCAS *cas;
5440 IRTemp old_mem = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00005441 IRTemp op2 = newTemp(Ity_I32);
5442 IRTemp op3 = newTemp(Ity_I32);
5443 IRTemp result = newTemp(Ity_I32);
5444
5445 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5446 assign(op3, get_gpr_w1(r3));
5447 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
floriana265ee72012-12-02 20:58:17 +00005448
5449 /* Place the addition of second operand and third operand at the
5450 second-operand location everytime */
5451 cas = mkIRCAS(IRTemp_INVALID, old_mem,
5452 Iend_BE, mkexpr(op2addr),
5453 NULL, mkexpr(op2), /* expected value */
5454 NULL, mkexpr(result) /* new value */);
5455 stmt(IRStmt_CAS(cas));
5456
florianffc94012012-12-02 21:31:15 +00005457 /* Set CC according to 32-bit addition */
5458 if (is_signed) {
5459 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
5460 } else {
5461 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
5462 }
floriana265ee72012-12-02 20:58:17 +00005463
5464 /* If old_mem contains the expected value, then the CAS succeeded.
5465 Otherwise, it did not */
5466 yield_if(binop(Iop_CmpNE32, mkexpr(old_mem), mkexpr(op2)));
5467 put_gpr_w1(r1, mkexpr(old_mem));
florianffc94012012-12-02 21:31:15 +00005468}
5469
5470static void
5471s390_irgen_load_and_add64(UChar r1, UChar r3, IRTemp op2addr, Bool is_signed)
5472{
5473 IRCAS *cas;
5474 IRTemp old_mem = newTemp(Ity_I64);
5475 IRTemp op2 = newTemp(Ity_I64);
5476 IRTemp op3 = newTemp(Ity_I64);
5477 IRTemp result = newTemp(Ity_I64);
5478
5479 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5480 assign(op3, get_gpr_dw0(r3));
5481 assign(result, binop(Iop_Add64, mkexpr(op2), mkexpr(op3)));
5482
5483 /* Place the addition of second operand and third operand at the
5484 second-operand location everytime */
5485 cas = mkIRCAS(IRTemp_INVALID, old_mem,
5486 Iend_BE, mkexpr(op2addr),
5487 NULL, mkexpr(op2), /* expected value */
5488 NULL, mkexpr(result) /* new value */);
5489 stmt(IRStmt_CAS(cas));
5490
5491 /* Set CC according to 64-bit addition */
5492 if (is_signed) {
5493 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op2, op3);
5494 } else {
5495 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op2, op3);
5496 }
5497
5498 /* If old_mem contains the expected value, then the CAS succeeded.
5499 Otherwise, it did not */
5500 yield_if(binop(Iop_CmpNE64, mkexpr(old_mem), mkexpr(op2)));
5501 put_gpr_dw0(r1, mkexpr(old_mem));
5502}
5503
5504static void
5505s390_irgen_load_and_bitwise32(UChar r1, UChar r3, IRTemp op2addr, IROp op)
5506{
5507 IRCAS *cas;
5508 IRTemp old_mem = newTemp(Ity_I32);
5509 IRTemp op2 = newTemp(Ity_I32);
5510 IRTemp op3 = newTemp(Ity_I32);
5511 IRTemp result = newTemp(Ity_I32);
5512
5513 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5514 assign(op3, get_gpr_w1(r3));
5515 assign(result, binop(op, mkexpr(op2), mkexpr(op3)));
5516
5517 /* Place the addition of second operand and third operand at the
5518 second-operand location everytime */
5519 cas = mkIRCAS(IRTemp_INVALID, old_mem,
5520 Iend_BE, mkexpr(op2addr),
5521 NULL, mkexpr(op2), /* expected value */
5522 NULL, mkexpr(result) /* new value */);
5523 stmt(IRStmt_CAS(cas));
5524
5525 /* Set CC according to bitwise operation */
5526 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5527
5528 /* If old_mem contains the expected value, then the CAS succeeded.
5529 Otherwise, it did not */
5530 yield_if(binop(Iop_CmpNE32, mkexpr(old_mem), mkexpr(op2)));
5531 put_gpr_w1(r1, mkexpr(old_mem));
5532}
5533
5534static void
5535s390_irgen_load_and_bitwise64(UChar r1, UChar r3, IRTemp op2addr, IROp op)
5536{
5537 IRCAS *cas;
5538 IRTemp old_mem = newTemp(Ity_I64);
5539 IRTemp op2 = newTemp(Ity_I64);
5540 IRTemp op3 = newTemp(Ity_I64);
5541 IRTemp result = newTemp(Ity_I64);
5542
5543 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5544 assign(op3, get_gpr_dw0(r3));
5545 assign(result, binop(op, mkexpr(op2), mkexpr(op3)));
5546
5547 /* Place the addition of second operand and third operand at the
5548 second-operand location everytime */
5549 cas = mkIRCAS(IRTemp_INVALID, old_mem,
5550 Iend_BE, mkexpr(op2addr),
5551 NULL, mkexpr(op2), /* expected value */
5552 NULL, mkexpr(result) /* new value */);
5553 stmt(IRStmt_CAS(cas));
5554
5555 /* Set CC according to bitwise operation */
5556 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5557
5558 /* If old_mem contains the expected value, then the CAS succeeded.
5559 Otherwise, it did not */
5560 yield_if(binop(Iop_CmpNE64, mkexpr(old_mem), mkexpr(op2)));
5561 put_gpr_dw0(r1, mkexpr(old_mem));
5562}
5563
5564static const HChar *
5565s390_irgen_LAA(UChar r1, UChar r3, IRTemp op2addr)
5566{
5567 s390_irgen_load_and_add32(r1, r3, op2addr, True /* is_signed */);
sewardj2019a972011-03-07 16:04:07 +00005568
5569 return "laa";
5570}
5571
florian55085f82012-11-21 00:36:55 +00005572static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005573s390_irgen_LAAG(UChar r1, UChar r3, IRTemp op2addr)
5574{
florianffc94012012-12-02 21:31:15 +00005575 s390_irgen_load_and_add64(r1, r3, op2addr, True /* is_signed */);
sewardj2019a972011-03-07 16:04:07 +00005576
5577 return "laag";
5578}
5579
florian55085f82012-11-21 00:36:55 +00005580static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005581s390_irgen_LAAL(UChar r1, UChar r3, IRTemp op2addr)
5582{
florianffc94012012-12-02 21:31:15 +00005583 s390_irgen_load_and_add32(r1, r3, op2addr, False /* is_signed */);
sewardj2019a972011-03-07 16:04:07 +00005584
5585 return "laal";
5586}
5587
florian55085f82012-11-21 00:36:55 +00005588static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005589s390_irgen_LAALG(UChar r1, UChar r3, IRTemp op2addr)
5590{
florianffc94012012-12-02 21:31:15 +00005591 s390_irgen_load_and_add64(r1, r3, op2addr, False /* is_signed */);
sewardj2019a972011-03-07 16:04:07 +00005592
5593 return "laalg";
5594}
5595
florian55085f82012-11-21 00:36:55 +00005596static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005597s390_irgen_LAN(UChar r1, UChar r3, IRTemp op2addr)
5598{
florianffc94012012-12-02 21:31:15 +00005599 s390_irgen_load_and_bitwise32(r1, r3, op2addr, Iop_And32);
sewardj2019a972011-03-07 16:04:07 +00005600
5601 return "lan";
5602}
5603
florian55085f82012-11-21 00:36:55 +00005604static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005605s390_irgen_LANG(UChar r1, UChar r3, IRTemp op2addr)
5606{
florianffc94012012-12-02 21:31:15 +00005607 s390_irgen_load_and_bitwise64(r1, r3, op2addr, Iop_And64);
sewardj2019a972011-03-07 16:04:07 +00005608
5609 return "lang";
5610}
5611
florian55085f82012-11-21 00:36:55 +00005612static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005613s390_irgen_LAX(UChar r1, UChar r3, IRTemp op2addr)
5614{
florianffc94012012-12-02 21:31:15 +00005615 s390_irgen_load_and_bitwise32(r1, r3, op2addr, Iop_Xor32);
sewardj2019a972011-03-07 16:04:07 +00005616
5617 return "lax";
5618}
5619
florian55085f82012-11-21 00:36:55 +00005620static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005621s390_irgen_LAXG(UChar r1, UChar r3, IRTemp op2addr)
5622{
florianffc94012012-12-02 21:31:15 +00005623 s390_irgen_load_and_bitwise64(r1, r3, op2addr, Iop_Xor64);
sewardj2019a972011-03-07 16:04:07 +00005624
5625 return "laxg";
5626}
5627
florian55085f82012-11-21 00:36:55 +00005628static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005629s390_irgen_LAO(UChar r1, UChar r3, IRTemp op2addr)
5630{
florianffc94012012-12-02 21:31:15 +00005631 s390_irgen_load_and_bitwise32(r1, r3, op2addr, Iop_Or32);
sewardj2019a972011-03-07 16:04:07 +00005632
5633 return "lao";
5634}
5635
florian55085f82012-11-21 00:36:55 +00005636static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005637s390_irgen_LAOG(UChar r1, UChar r3, IRTemp op2addr)
5638{
florianffc94012012-12-02 21:31:15 +00005639 s390_irgen_load_and_bitwise64(r1, r3, op2addr, Iop_Or64);
sewardj2019a972011-03-07 16:04:07 +00005640
5641 return "laog";
5642}
5643
florian55085f82012-11-21 00:36:55 +00005644static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005645s390_irgen_LTR(UChar r1, UChar r2)
5646{
5647 IRTemp op2 = newTemp(Ity_I32);
5648
5649 assign(op2, get_gpr_w1(r2));
5650 put_gpr_w1(r1, mkexpr(op2));
5651 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5652
5653 return "ltr";
5654}
5655
florian55085f82012-11-21 00:36:55 +00005656static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005657s390_irgen_LTGR(UChar r1, UChar r2)
5658{
5659 IRTemp op2 = newTemp(Ity_I64);
5660
5661 assign(op2, get_gpr_dw0(r2));
5662 put_gpr_dw0(r1, mkexpr(op2));
5663 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5664
5665 return "ltgr";
5666}
5667
florian55085f82012-11-21 00:36:55 +00005668static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005669s390_irgen_LTGFR(UChar r1, UChar r2)
5670{
5671 IRTemp op2 = newTemp(Ity_I64);
5672
5673 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
5674 put_gpr_dw0(r1, mkexpr(op2));
5675 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5676
5677 return "ltgfr";
5678}
5679
florian55085f82012-11-21 00:36:55 +00005680static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005681s390_irgen_LT(UChar r1, IRTemp op2addr)
5682{
5683 IRTemp op2 = newTemp(Ity_I32);
5684
5685 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5686 put_gpr_w1(r1, mkexpr(op2));
5687 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5688
5689 return "lt";
5690}
5691
florian55085f82012-11-21 00:36:55 +00005692static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005693s390_irgen_LTG(UChar r1, IRTemp op2addr)
5694{
5695 IRTemp op2 = newTemp(Ity_I64);
5696
5697 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5698 put_gpr_dw0(r1, mkexpr(op2));
5699 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5700
5701 return "ltg";
5702}
5703
florian55085f82012-11-21 00:36:55 +00005704static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005705s390_irgen_LTGF(UChar r1, IRTemp op2addr)
5706{
5707 IRTemp op2 = newTemp(Ity_I64);
5708
5709 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
5710 put_gpr_dw0(r1, mkexpr(op2));
5711 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5712
5713 return "ltgf";
5714}
5715
florian55085f82012-11-21 00:36:55 +00005716static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005717s390_irgen_LBR(UChar r1, UChar r2)
5718{
5719 put_gpr_w1(r1, unop(Iop_8Sto32, get_gpr_b7(r2)));
5720
5721 return "lbr";
5722}
5723
florian55085f82012-11-21 00:36:55 +00005724static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005725s390_irgen_LGBR(UChar r1, UChar r2)
5726{
5727 put_gpr_dw0(r1, unop(Iop_8Sto64, get_gpr_b7(r2)));
5728
5729 return "lgbr";
5730}
5731
florian55085f82012-11-21 00:36:55 +00005732static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005733s390_irgen_LB(UChar r1, IRTemp op2addr)
5734{
5735 put_gpr_w1(r1, unop(Iop_8Sto32, load(Ity_I8, mkexpr(op2addr))));
5736
5737 return "lb";
5738}
5739
florian55085f82012-11-21 00:36:55 +00005740static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005741s390_irgen_LGB(UChar r1, IRTemp op2addr)
5742{
5743 put_gpr_dw0(r1, unop(Iop_8Sto64, load(Ity_I8, mkexpr(op2addr))));
5744
5745 return "lgb";
5746}
5747
florian55085f82012-11-21 00:36:55 +00005748static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005749s390_irgen_LBH(UChar r1, IRTemp op2addr)
5750{
5751 put_gpr_w0(r1, unop(Iop_8Sto32, load(Ity_I8, mkexpr(op2addr))));
5752
5753 return "lbh";
5754}
5755
florian55085f82012-11-21 00:36:55 +00005756static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005757s390_irgen_LCR(UChar r1, UChar r2)
5758{
5759 Int op1;
5760 IRTemp op2 = newTemp(Ity_I32);
5761 IRTemp result = newTemp(Ity_I32);
5762
5763 op1 = 0;
5764 assign(op2, get_gpr_w1(r2));
5765 assign(result, binop(Iop_Sub32, mkU32((UInt)op1), mkexpr(op2)));
5766 put_gpr_w1(r1, mkexpr(result));
5767 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, mktemp(Ity_I32, mkU32((UInt)
5768 op1)), op2);
5769
5770 return "lcr";
5771}
5772
florian55085f82012-11-21 00:36:55 +00005773static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005774s390_irgen_LCGR(UChar r1, UChar r2)
5775{
5776 Long op1;
5777 IRTemp op2 = newTemp(Ity_I64);
5778 IRTemp result = newTemp(Ity_I64);
5779
5780 op1 = 0ULL;
5781 assign(op2, get_gpr_dw0(r2));
5782 assign(result, binop(Iop_Sub64, mkU64((ULong)op1), mkexpr(op2)));
5783 put_gpr_dw0(r1, mkexpr(result));
5784 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, mktemp(Ity_I64, mkU64((ULong)
5785 op1)), op2);
5786
5787 return "lcgr";
5788}
5789
florian55085f82012-11-21 00:36:55 +00005790static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005791s390_irgen_LCGFR(UChar r1, UChar r2)
5792{
5793 Long op1;
5794 IRTemp op2 = newTemp(Ity_I64);
5795 IRTemp result = newTemp(Ity_I64);
5796
5797 op1 = 0ULL;
5798 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
5799 assign(result, binop(Iop_Sub64, mkU64((ULong)op1), mkexpr(op2)));
5800 put_gpr_dw0(r1, mkexpr(result));
5801 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, mktemp(Ity_I64, mkU64((ULong)
5802 op1)), op2);
5803
5804 return "lcgfr";
5805}
5806
florian55085f82012-11-21 00:36:55 +00005807static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005808s390_irgen_LHR(UChar r1, UChar r2)
5809{
5810 put_gpr_w1(r1, unop(Iop_16Sto32, get_gpr_hw3(r2)));
5811
5812 return "lhr";
5813}
5814
florian55085f82012-11-21 00:36:55 +00005815static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005816s390_irgen_LGHR(UChar r1, UChar r2)
5817{
5818 put_gpr_dw0(r1, unop(Iop_16Sto64, get_gpr_hw3(r2)));
5819
5820 return "lghr";
5821}
5822
florian55085f82012-11-21 00:36:55 +00005823static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005824s390_irgen_LH(UChar r1, IRTemp op2addr)
5825{
5826 put_gpr_w1(r1, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
5827
5828 return "lh";
5829}
5830
florian55085f82012-11-21 00:36:55 +00005831static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005832s390_irgen_LHY(UChar r1, IRTemp op2addr)
5833{
5834 put_gpr_w1(r1, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
5835
5836 return "lhy";
5837}
5838
florian55085f82012-11-21 00:36:55 +00005839static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005840s390_irgen_LGH(UChar r1, IRTemp op2addr)
5841{
5842 put_gpr_dw0(r1, unop(Iop_16Sto64, load(Ity_I16, mkexpr(op2addr))));
5843
5844 return "lgh";
5845}
5846
florian55085f82012-11-21 00:36:55 +00005847static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005848s390_irgen_LHI(UChar r1, UShort i2)
5849{
5850 put_gpr_w1(r1, mkU32((UInt)(Int)(Short)i2));
5851
5852 return "lhi";
5853}
5854
florian55085f82012-11-21 00:36:55 +00005855static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005856s390_irgen_LGHI(UChar r1, UShort i2)
5857{
5858 put_gpr_dw0(r1, mkU64((ULong)(Long)(Short)i2));
5859
5860 return "lghi";
5861}
5862
florian55085f82012-11-21 00:36:55 +00005863static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005864s390_irgen_LHRL(UChar r1, UInt i2)
5865{
5866 put_gpr_w1(r1, unop(Iop_16Sto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
5867 ((ULong)(Long)(Int)i2 << 1)))));
5868
5869 return "lhrl";
5870}
5871
florian55085f82012-11-21 00:36:55 +00005872static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005873s390_irgen_LGHRL(UChar r1, UInt i2)
5874{
5875 put_gpr_dw0(r1, unop(Iop_16Sto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
5876 ((ULong)(Long)(Int)i2 << 1)))));
5877
5878 return "lghrl";
5879}
5880
florian55085f82012-11-21 00:36:55 +00005881static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005882s390_irgen_LHH(UChar r1, IRTemp op2addr)
5883{
5884 put_gpr_w0(r1, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
5885
5886 return "lhh";
5887}
5888
florian55085f82012-11-21 00:36:55 +00005889static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005890s390_irgen_LFH(UChar r1, IRTemp op2addr)
5891{
5892 put_gpr_w0(r1, load(Ity_I32, mkexpr(op2addr)));
5893
5894 return "lfh";
5895}
5896
florian55085f82012-11-21 00:36:55 +00005897static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005898s390_irgen_LLGFR(UChar r1, UChar r2)
5899{
5900 put_gpr_dw0(r1, unop(Iop_32Uto64, get_gpr_w1(r2)));
5901
5902 return "llgfr";
5903}
5904
florian55085f82012-11-21 00:36:55 +00005905static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005906s390_irgen_LLGF(UChar r1, IRTemp op2addr)
5907{
5908 put_gpr_dw0(r1, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
5909
5910 return "llgf";
5911}
5912
florian55085f82012-11-21 00:36:55 +00005913static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005914s390_irgen_LLGFRL(UChar r1, UInt i2)
5915{
5916 put_gpr_dw0(r1, unop(Iop_32Uto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
5917 ((ULong)(Long)(Int)i2 << 1)))));
5918
5919 return "llgfrl";
5920}
5921
florian55085f82012-11-21 00:36:55 +00005922static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005923s390_irgen_LLCR(UChar r1, UChar r2)
5924{
5925 put_gpr_w1(r1, unop(Iop_8Uto32, get_gpr_b7(r2)));
5926
5927 return "llcr";
5928}
5929
florian55085f82012-11-21 00:36:55 +00005930static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005931s390_irgen_LLGCR(UChar r1, UChar r2)
5932{
5933 put_gpr_dw0(r1, unop(Iop_8Uto64, get_gpr_b7(r2)));
5934
5935 return "llgcr";
5936}
5937
florian55085f82012-11-21 00:36:55 +00005938static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005939s390_irgen_LLC(UChar r1, IRTemp op2addr)
5940{
5941 put_gpr_w1(r1, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
5942
5943 return "llc";
5944}
5945
florian55085f82012-11-21 00:36:55 +00005946static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005947s390_irgen_LLGC(UChar r1, IRTemp op2addr)
5948{
5949 put_gpr_dw0(r1, unop(Iop_8Uto64, load(Ity_I8, mkexpr(op2addr))));
5950
5951 return "llgc";
5952}
5953
florian55085f82012-11-21 00:36:55 +00005954static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005955s390_irgen_LLCH(UChar r1, IRTemp op2addr)
5956{
5957 put_gpr_w0(r1, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
5958
5959 return "llch";
5960}
5961
florian55085f82012-11-21 00:36:55 +00005962static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005963s390_irgen_LLHR(UChar r1, UChar r2)
5964{
5965 put_gpr_w1(r1, unop(Iop_16Uto32, get_gpr_hw3(r2)));
5966
5967 return "llhr";
5968}
5969
florian55085f82012-11-21 00:36:55 +00005970static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005971s390_irgen_LLGHR(UChar r1, UChar r2)
5972{
5973 put_gpr_dw0(r1, unop(Iop_16Uto64, get_gpr_hw3(r2)));
5974
5975 return "llghr";
5976}
5977
florian55085f82012-11-21 00:36:55 +00005978static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005979s390_irgen_LLH(UChar r1, IRTemp op2addr)
5980{
5981 put_gpr_w1(r1, unop(Iop_16Uto32, load(Ity_I16, mkexpr(op2addr))));
5982
5983 return "llh";
5984}
5985
florian55085f82012-11-21 00:36:55 +00005986static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005987s390_irgen_LLGH(UChar r1, IRTemp op2addr)
5988{
5989 put_gpr_dw0(r1, unop(Iop_16Uto64, load(Ity_I16, mkexpr(op2addr))));
5990
5991 return "llgh";
5992}
5993
florian55085f82012-11-21 00:36:55 +00005994static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005995s390_irgen_LLHRL(UChar r1, UInt i2)
5996{
5997 put_gpr_w1(r1, unop(Iop_16Uto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
5998 ((ULong)(Long)(Int)i2 << 1)))));
5999
6000 return "llhrl";
6001}
6002
florian55085f82012-11-21 00:36:55 +00006003static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006004s390_irgen_LLGHRL(UChar r1, UInt i2)
6005{
6006 put_gpr_dw0(r1, unop(Iop_16Uto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
6007 ((ULong)(Long)(Int)i2 << 1)))));
6008
6009 return "llghrl";
6010}
6011
florian55085f82012-11-21 00:36:55 +00006012static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006013s390_irgen_LLHH(UChar r1, IRTemp op2addr)
6014{
6015 put_gpr_w0(r1, unop(Iop_16Uto32, load(Ity_I16, mkexpr(op2addr))));
6016
6017 return "llhh";
6018}
6019
florian55085f82012-11-21 00:36:55 +00006020static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006021s390_irgen_LLIHF(UChar r1, UInt i2)
6022{
6023 put_gpr_dw0(r1, mkU64(((ULong)i2) << 32));
6024
6025 return "llihf";
6026}
6027
florian55085f82012-11-21 00:36:55 +00006028static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006029s390_irgen_LLIHH(UChar r1, UShort i2)
6030{
6031 put_gpr_dw0(r1, mkU64(((ULong)i2) << 48));
6032
6033 return "llihh";
6034}
6035
florian55085f82012-11-21 00:36:55 +00006036static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006037s390_irgen_LLIHL(UChar r1, UShort i2)
6038{
6039 put_gpr_dw0(r1, mkU64(((ULong)i2) << 32));
6040
6041 return "llihl";
6042}
6043
florian55085f82012-11-21 00:36:55 +00006044static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006045s390_irgen_LLILF(UChar r1, UInt i2)
6046{
6047 put_gpr_dw0(r1, mkU64(i2));
6048
6049 return "llilf";
6050}
6051
florian55085f82012-11-21 00:36:55 +00006052static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006053s390_irgen_LLILH(UChar r1, UShort i2)
6054{
6055 put_gpr_dw0(r1, mkU64(((ULong)i2) << 16));
6056
6057 return "llilh";
6058}
6059
florian55085f82012-11-21 00:36:55 +00006060static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006061s390_irgen_LLILL(UChar r1, UShort i2)
6062{
6063 put_gpr_dw0(r1, mkU64(i2));
6064
6065 return "llill";
6066}
6067
florian55085f82012-11-21 00:36:55 +00006068static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006069s390_irgen_LLGTR(UChar r1, UChar r2)
6070{
6071 put_gpr_dw0(r1, unop(Iop_32Uto64, binop(Iop_And32, get_gpr_w1(r2),
6072 mkU32(2147483647))));
6073
6074 return "llgtr";
6075}
6076
florian55085f82012-11-21 00:36:55 +00006077static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006078s390_irgen_LLGT(UChar r1, IRTemp op2addr)
6079{
6080 put_gpr_dw0(r1, unop(Iop_32Uto64, binop(Iop_And32, load(Ity_I32,
6081 mkexpr(op2addr)), mkU32(2147483647))));
6082
6083 return "llgt";
6084}
6085
florian55085f82012-11-21 00:36:55 +00006086static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006087s390_irgen_LNR(UChar r1, UChar r2)
6088{
6089 IRTemp op2 = newTemp(Ity_I32);
6090 IRTemp result = newTemp(Ity_I32);
6091
6092 assign(op2, get_gpr_w1(r2));
6093 assign(result, mkite(binop(Iop_CmpLE32S, mkexpr(op2), mkU32(0)), mkexpr(op2),
6094 binop(Iop_Sub32, mkU32(0), mkexpr(op2))));
6095 put_gpr_w1(r1, mkexpr(result));
6096 s390_cc_thunk_putS(S390_CC_OP_BITWISE, result);
6097
6098 return "lnr";
6099}
6100
florian55085f82012-11-21 00:36:55 +00006101static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006102s390_irgen_LNGR(UChar r1, UChar r2)
6103{
6104 IRTemp op2 = newTemp(Ity_I64);
6105 IRTemp result = newTemp(Ity_I64);
6106
6107 assign(op2, get_gpr_dw0(r2));
6108 assign(result, mkite(binop(Iop_CmpLE64S, mkexpr(op2), mkU64(0)), mkexpr(op2),
6109 binop(Iop_Sub64, mkU64(0), mkexpr(op2))));
6110 put_gpr_dw0(r1, mkexpr(result));
6111 s390_cc_thunk_putS(S390_CC_OP_BITWISE, result);
6112
6113 return "lngr";
6114}
6115
florian55085f82012-11-21 00:36:55 +00006116static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006117s390_irgen_LNGFR(UChar r1, UChar r2 __attribute__((unused)))
6118{
6119 IRTemp op2 = newTemp(Ity_I64);
6120 IRTemp result = newTemp(Ity_I64);
6121
6122 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r1)));
6123 assign(result, mkite(binop(Iop_CmpLE64S, mkexpr(op2), mkU64(0)), mkexpr(op2),
6124 binop(Iop_Sub64, mkU64(0), mkexpr(op2))));
6125 put_gpr_dw0(r1, mkexpr(result));
6126 s390_cc_thunk_putS(S390_CC_OP_BITWISE, result);
6127
6128 return "lngfr";
6129}
6130
florian55085f82012-11-21 00:36:55 +00006131static const HChar *
sewardjd7bde722011-04-05 13:19:33 +00006132s390_irgen_LOCR(UChar m3, UChar r1, UChar r2)
6133{
florian6820ba52012-07-26 02:01:50 +00006134 next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0)));
sewardjd7bde722011-04-05 13:19:33 +00006135 put_gpr_w1(r1, get_gpr_w1(r2));
6136
6137 return "locr";
6138}
6139
florian55085f82012-11-21 00:36:55 +00006140static const HChar *
sewardjd7bde722011-04-05 13:19:33 +00006141s390_irgen_LOCGR(UChar m3, UChar r1, UChar r2)
6142{
florian6820ba52012-07-26 02:01:50 +00006143 next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0)));
sewardjd7bde722011-04-05 13:19:33 +00006144 put_gpr_dw0(r1, get_gpr_dw0(r2));
6145
6146 return "locgr";
6147}
6148
florian55085f82012-11-21 00:36:55 +00006149static const HChar *
sewardjd7bde722011-04-05 13:19:33 +00006150s390_irgen_LOC(UChar r1, IRTemp op2addr)
6151{
6152 /* condition is checked in format handler */
6153 put_gpr_w1(r1, load(Ity_I32, mkexpr(op2addr)));
6154
6155 return "loc";
6156}
6157
florian55085f82012-11-21 00:36:55 +00006158static const HChar *
sewardjd7bde722011-04-05 13:19:33 +00006159s390_irgen_LOCG(UChar r1, IRTemp op2addr)
6160{
6161 /* condition is checked in format handler */
6162 put_gpr_dw0(r1, load(Ity_I64, mkexpr(op2addr)));
6163
6164 return "locg";
6165}
6166
florian55085f82012-11-21 00:36:55 +00006167static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006168s390_irgen_LPQ(UChar r1, IRTemp op2addr)
6169{
6170 put_gpr_dw0(r1, load(Ity_I64, mkexpr(op2addr)));
6171 put_gpr_dw0(r1 + 1, load(Ity_I64, binop(Iop_Add64, mkexpr(op2addr), mkU64(8))
6172 ));
6173
6174 return "lpq";
6175}
6176
florian55085f82012-11-21 00:36:55 +00006177static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006178s390_irgen_LPR(UChar r1, UChar r2)
6179{
6180 IRTemp op2 = newTemp(Ity_I32);
6181 IRTemp result = newTemp(Ity_I32);
6182
6183 assign(op2, get_gpr_w1(r2));
6184 assign(result, mkite(binop(Iop_CmpLT32S, mkexpr(op2), mkU32(0)),
6185 binop(Iop_Sub32, mkU32(0), mkexpr(op2)), mkexpr(op2)));
6186 put_gpr_w1(r1, mkexpr(result));
6187 s390_cc_thunk_putS(S390_CC_OP_LOAD_POSITIVE_32, op2);
6188
6189 return "lpr";
6190}
6191
florian55085f82012-11-21 00:36:55 +00006192static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006193s390_irgen_LPGR(UChar r1, UChar r2)
6194{
6195 IRTemp op2 = newTemp(Ity_I64);
6196 IRTemp result = newTemp(Ity_I64);
6197
6198 assign(op2, get_gpr_dw0(r2));
6199 assign(result, mkite(binop(Iop_CmpLT64S, mkexpr(op2), mkU64(0)),
6200 binop(Iop_Sub64, mkU64(0), mkexpr(op2)), mkexpr(op2)));
6201 put_gpr_dw0(r1, mkexpr(result));
6202 s390_cc_thunk_putS(S390_CC_OP_LOAD_POSITIVE_64, op2);
6203
6204 return "lpgr";
6205}
6206
florian55085f82012-11-21 00:36:55 +00006207static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006208s390_irgen_LPGFR(UChar r1, UChar r2)
6209{
6210 IRTemp op2 = newTemp(Ity_I64);
6211 IRTemp result = newTemp(Ity_I64);
6212
6213 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
6214 assign(result, mkite(binop(Iop_CmpLT64S, mkexpr(op2), mkU64(0)),
6215 binop(Iop_Sub64, mkU64(0), mkexpr(op2)), mkexpr(op2)));
6216 put_gpr_dw0(r1, mkexpr(result));
6217 s390_cc_thunk_putS(S390_CC_OP_LOAD_POSITIVE_64, op2);
6218
6219 return "lpgfr";
6220}
6221
florian55085f82012-11-21 00:36:55 +00006222static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006223s390_irgen_LRVR(UChar r1, UChar r2)
6224{
6225 IRTemp b0 = newTemp(Ity_I8);
6226 IRTemp b1 = newTemp(Ity_I8);
6227 IRTemp b2 = newTemp(Ity_I8);
6228 IRTemp b3 = newTemp(Ity_I8);
6229
6230 assign(b3, get_gpr_b7(r2));
6231 assign(b2, get_gpr_b6(r2));
6232 assign(b1, get_gpr_b5(r2));
6233 assign(b0, get_gpr_b4(r2));
6234 put_gpr_b4(r1, mkexpr(b3));
6235 put_gpr_b5(r1, mkexpr(b2));
6236 put_gpr_b6(r1, mkexpr(b1));
6237 put_gpr_b7(r1, mkexpr(b0));
6238
6239 return "lrvr";
6240}
6241
florian55085f82012-11-21 00:36:55 +00006242static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006243s390_irgen_LRVGR(UChar r1, UChar r2)
6244{
6245 IRTemp b0 = newTemp(Ity_I8);
6246 IRTemp b1 = newTemp(Ity_I8);
6247 IRTemp b2 = newTemp(Ity_I8);
6248 IRTemp b3 = newTemp(Ity_I8);
6249 IRTemp b4 = newTemp(Ity_I8);
6250 IRTemp b5 = newTemp(Ity_I8);
6251 IRTemp b6 = newTemp(Ity_I8);
6252 IRTemp b7 = newTemp(Ity_I8);
6253
6254 assign(b7, get_gpr_b7(r2));
6255 assign(b6, get_gpr_b6(r2));
6256 assign(b5, get_gpr_b5(r2));
6257 assign(b4, get_gpr_b4(r2));
6258 assign(b3, get_gpr_b3(r2));
6259 assign(b2, get_gpr_b2(r2));
6260 assign(b1, get_gpr_b1(r2));
6261 assign(b0, get_gpr_b0(r2));
6262 put_gpr_b0(r1, mkexpr(b7));
6263 put_gpr_b1(r1, mkexpr(b6));
6264 put_gpr_b2(r1, mkexpr(b5));
6265 put_gpr_b3(r1, mkexpr(b4));
6266 put_gpr_b4(r1, mkexpr(b3));
6267 put_gpr_b5(r1, mkexpr(b2));
6268 put_gpr_b6(r1, mkexpr(b1));
6269 put_gpr_b7(r1, mkexpr(b0));
6270
6271 return "lrvgr";
6272}
6273
florian55085f82012-11-21 00:36:55 +00006274static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006275s390_irgen_LRVH(UChar r1, IRTemp op2addr)
6276{
6277 IRTemp op2 = newTemp(Ity_I16);
6278
6279 assign(op2, load(Ity_I16, mkexpr(op2addr)));
6280 put_gpr_b6(r1, unop(Iop_16to8, mkexpr(op2)));
6281 put_gpr_b7(r1, unop(Iop_16HIto8, mkexpr(op2)));
6282
6283 return "lrvh";
6284}
6285
florian55085f82012-11-21 00:36:55 +00006286static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006287s390_irgen_LRV(UChar r1, IRTemp op2addr)
6288{
6289 IRTemp op2 = newTemp(Ity_I32);
6290
6291 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6292 put_gpr_b4(r1, unop(Iop_32to8, binop(Iop_And32, mkexpr(op2), mkU32(255))));
6293 put_gpr_b5(r1, unop(Iop_32to8, binop(Iop_And32, binop(Iop_Shr32, mkexpr(op2),
6294 mkU8(8)), mkU32(255))));
6295 put_gpr_b6(r1, unop(Iop_32to8, binop(Iop_And32, binop(Iop_Shr32, mkexpr(op2),
6296 mkU8(16)), mkU32(255))));
6297 put_gpr_b7(r1, unop(Iop_32to8, binop(Iop_And32, binop(Iop_Shr32, mkexpr(op2),
6298 mkU8(24)), mkU32(255))));
6299
6300 return "lrv";
6301}
6302
florian55085f82012-11-21 00:36:55 +00006303static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006304s390_irgen_LRVG(UChar r1, IRTemp op2addr)
6305{
6306 IRTemp op2 = newTemp(Ity_I64);
6307
6308 assign(op2, load(Ity_I64, mkexpr(op2addr)));
6309 put_gpr_b0(r1, unop(Iop_64to8, binop(Iop_And64, mkexpr(op2), mkU64(255))));
6310 put_gpr_b1(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6311 mkU8(8)), mkU64(255))));
6312 put_gpr_b2(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6313 mkU8(16)), mkU64(255))));
6314 put_gpr_b3(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6315 mkU8(24)), mkU64(255))));
6316 put_gpr_b4(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6317 mkU8(32)), mkU64(255))));
6318 put_gpr_b5(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6319 mkU8(40)), mkU64(255))));
6320 put_gpr_b6(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6321 mkU8(48)), mkU64(255))));
6322 put_gpr_b7(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6323 mkU8(56)), mkU64(255))));
6324
6325 return "lrvg";
6326}
6327
florian55085f82012-11-21 00:36:55 +00006328static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006329s390_irgen_MVHHI(UShort i2, IRTemp op1addr)
6330{
6331 store(mkexpr(op1addr), mkU16(i2));
6332
6333 return "mvhhi";
6334}
6335
florian55085f82012-11-21 00:36:55 +00006336static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006337s390_irgen_MVHI(UShort i2, IRTemp op1addr)
6338{
6339 store(mkexpr(op1addr), mkU32((UInt)(Int)(Short)i2));
6340
6341 return "mvhi";
6342}
6343
florian55085f82012-11-21 00:36:55 +00006344static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006345s390_irgen_MVGHI(UShort i2, IRTemp op1addr)
6346{
6347 store(mkexpr(op1addr), mkU64((ULong)(Long)(Short)i2));
6348
6349 return "mvghi";
6350}
6351
florian55085f82012-11-21 00:36:55 +00006352static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006353s390_irgen_MVI(UChar i2, IRTemp op1addr)
6354{
6355 store(mkexpr(op1addr), mkU8(i2));
6356
6357 return "mvi";
6358}
6359
florian55085f82012-11-21 00:36:55 +00006360static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006361s390_irgen_MVIY(UChar i2, IRTemp op1addr)
6362{
6363 store(mkexpr(op1addr), mkU8(i2));
6364
6365 return "mviy";
6366}
6367
florian55085f82012-11-21 00:36:55 +00006368static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006369s390_irgen_MR(UChar r1, UChar r2)
6370{
6371 IRTemp op1 = newTemp(Ity_I32);
6372 IRTemp op2 = newTemp(Ity_I32);
6373 IRTemp result = newTemp(Ity_I64);
6374
6375 assign(op1, get_gpr_w1(r1 + 1));
6376 assign(op2, get_gpr_w1(r2));
6377 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6378 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6379 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6380
6381 return "mr";
6382}
6383
florian55085f82012-11-21 00:36:55 +00006384static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006385s390_irgen_M(UChar r1, IRTemp op2addr)
6386{
6387 IRTemp op1 = newTemp(Ity_I32);
6388 IRTemp op2 = newTemp(Ity_I32);
6389 IRTemp result = newTemp(Ity_I64);
6390
6391 assign(op1, get_gpr_w1(r1 + 1));
6392 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6393 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6394 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6395 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6396
6397 return "m";
6398}
6399
florian55085f82012-11-21 00:36:55 +00006400static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006401s390_irgen_MFY(UChar r1, IRTemp op2addr)
6402{
6403 IRTemp op1 = newTemp(Ity_I32);
6404 IRTemp op2 = newTemp(Ity_I32);
6405 IRTemp result = newTemp(Ity_I64);
6406
6407 assign(op1, get_gpr_w1(r1 + 1));
6408 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6409 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6410 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6411 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6412
6413 return "mfy";
6414}
6415
florian55085f82012-11-21 00:36:55 +00006416static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006417s390_irgen_MH(UChar r1, IRTemp op2addr)
6418{
6419 IRTemp op1 = newTemp(Ity_I32);
6420 IRTemp op2 = newTemp(Ity_I16);
6421 IRTemp result = newTemp(Ity_I64);
6422
6423 assign(op1, get_gpr_w1(r1));
6424 assign(op2, load(Ity_I16, mkexpr(op2addr)));
6425 assign(result, binop(Iop_MullS32, mkexpr(op1), unop(Iop_16Sto32, mkexpr(op2))
6426 ));
6427 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6428
6429 return "mh";
6430}
6431
florian55085f82012-11-21 00:36:55 +00006432static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006433s390_irgen_MHY(UChar r1, IRTemp op2addr)
6434{
6435 IRTemp op1 = newTemp(Ity_I32);
6436 IRTemp op2 = newTemp(Ity_I16);
6437 IRTemp result = newTemp(Ity_I64);
6438
6439 assign(op1, get_gpr_w1(r1));
6440 assign(op2, load(Ity_I16, mkexpr(op2addr)));
6441 assign(result, binop(Iop_MullS32, mkexpr(op1), unop(Iop_16Sto32, mkexpr(op2))
6442 ));
6443 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6444
6445 return "mhy";
6446}
6447
florian55085f82012-11-21 00:36:55 +00006448static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006449s390_irgen_MHI(UChar r1, UShort i2)
6450{
6451 IRTemp op1 = newTemp(Ity_I32);
6452 Short op2;
6453 IRTemp result = newTemp(Ity_I64);
6454
6455 assign(op1, get_gpr_w1(r1));
6456 op2 = (Short)i2;
6457 assign(result, binop(Iop_MullS32, mkexpr(op1), unop(Iop_16Sto32,
6458 mkU16((UShort)op2))));
6459 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6460
6461 return "mhi";
6462}
6463
florian55085f82012-11-21 00:36:55 +00006464static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006465s390_irgen_MGHI(UChar r1, UShort i2)
6466{
6467 IRTemp op1 = newTemp(Ity_I64);
6468 Short op2;
6469 IRTemp result = newTemp(Ity_I128);
6470
6471 assign(op1, get_gpr_dw0(r1));
6472 op2 = (Short)i2;
6473 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_16Sto64,
6474 mkU16((UShort)op2))));
6475 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6476
6477 return "mghi";
6478}
6479
florian55085f82012-11-21 00:36:55 +00006480static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006481s390_irgen_MLR(UChar r1, UChar r2)
6482{
6483 IRTemp op1 = newTemp(Ity_I32);
6484 IRTemp op2 = newTemp(Ity_I32);
6485 IRTemp result = newTemp(Ity_I64);
6486
6487 assign(op1, get_gpr_w1(r1 + 1));
6488 assign(op2, get_gpr_w1(r2));
6489 assign(result, binop(Iop_MullU32, mkexpr(op1), mkexpr(op2)));
6490 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6491 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6492
6493 return "mlr";
6494}
6495
florian55085f82012-11-21 00:36:55 +00006496static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006497s390_irgen_MLGR(UChar r1, UChar r2)
6498{
6499 IRTemp op1 = newTemp(Ity_I64);
6500 IRTemp op2 = newTemp(Ity_I64);
6501 IRTemp result = newTemp(Ity_I128);
6502
6503 assign(op1, get_gpr_dw0(r1 + 1));
6504 assign(op2, get_gpr_dw0(r2));
6505 assign(result, binop(Iop_MullU64, mkexpr(op1), mkexpr(op2)));
6506 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result)));
6507 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result)));
6508
6509 return "mlgr";
6510}
6511
florian55085f82012-11-21 00:36:55 +00006512static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006513s390_irgen_ML(UChar r1, IRTemp op2addr)
6514{
6515 IRTemp op1 = newTemp(Ity_I32);
6516 IRTemp op2 = newTemp(Ity_I32);
6517 IRTemp result = newTemp(Ity_I64);
6518
6519 assign(op1, get_gpr_w1(r1 + 1));
6520 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6521 assign(result, binop(Iop_MullU32, mkexpr(op1), mkexpr(op2)));
6522 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6523 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6524
6525 return "ml";
6526}
6527
florian55085f82012-11-21 00:36:55 +00006528static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006529s390_irgen_MLG(UChar r1, IRTemp op2addr)
6530{
6531 IRTemp op1 = newTemp(Ity_I64);
6532 IRTemp op2 = newTemp(Ity_I64);
6533 IRTemp result = newTemp(Ity_I128);
6534
6535 assign(op1, get_gpr_dw0(r1 + 1));
6536 assign(op2, load(Ity_I64, mkexpr(op2addr)));
6537 assign(result, binop(Iop_MullU64, mkexpr(op1), mkexpr(op2)));
6538 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result)));
6539 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result)));
6540
6541 return "mlg";
6542}
6543
florian55085f82012-11-21 00:36:55 +00006544static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006545s390_irgen_MSR(UChar r1, UChar r2)
6546{
6547 IRTemp op1 = newTemp(Ity_I32);
6548 IRTemp op2 = newTemp(Ity_I32);
6549 IRTemp result = newTemp(Ity_I64);
6550
6551 assign(op1, get_gpr_w1(r1));
6552 assign(op2, get_gpr_w1(r2));
6553 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6554 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6555
6556 return "msr";
6557}
6558
florian55085f82012-11-21 00:36:55 +00006559static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006560s390_irgen_MSGR(UChar r1, UChar r2)
6561{
6562 IRTemp op1 = newTemp(Ity_I64);
6563 IRTemp op2 = newTemp(Ity_I64);
6564 IRTemp result = newTemp(Ity_I128);
6565
6566 assign(op1, get_gpr_dw0(r1));
6567 assign(op2, get_gpr_dw0(r2));
6568 assign(result, binop(Iop_MullS64, mkexpr(op1), mkexpr(op2)));
6569 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6570
6571 return "msgr";
6572}
6573
florian55085f82012-11-21 00:36:55 +00006574static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006575s390_irgen_MSGFR(UChar r1, UChar r2)
6576{
6577 IRTemp op1 = newTemp(Ity_I64);
6578 IRTemp op2 = newTemp(Ity_I32);
6579 IRTemp result = newTemp(Ity_I128);
6580
6581 assign(op1, get_gpr_dw0(r1));
6582 assign(op2, get_gpr_w1(r2));
6583 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_32Sto64, mkexpr(op2))
6584 ));
6585 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6586
6587 return "msgfr";
6588}
6589
florian55085f82012-11-21 00:36:55 +00006590static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006591s390_irgen_MS(UChar r1, IRTemp op2addr)
6592{
6593 IRTemp op1 = newTemp(Ity_I32);
6594 IRTemp op2 = newTemp(Ity_I32);
6595 IRTemp result = newTemp(Ity_I64);
6596
6597 assign(op1, get_gpr_w1(r1));
6598 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6599 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6600 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6601
6602 return "ms";
6603}
6604
florian55085f82012-11-21 00:36:55 +00006605static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006606s390_irgen_MSY(UChar r1, IRTemp op2addr)
6607{
6608 IRTemp op1 = newTemp(Ity_I32);
6609 IRTemp op2 = newTemp(Ity_I32);
6610 IRTemp result = newTemp(Ity_I64);
6611
6612 assign(op1, get_gpr_w1(r1));
6613 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6614 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6615 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6616
6617 return "msy";
6618}
6619
florian55085f82012-11-21 00:36:55 +00006620static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006621s390_irgen_MSG(UChar r1, IRTemp op2addr)
6622{
6623 IRTemp op1 = newTemp(Ity_I64);
6624 IRTemp op2 = newTemp(Ity_I64);
6625 IRTemp result = newTemp(Ity_I128);
6626
6627 assign(op1, get_gpr_dw0(r1));
6628 assign(op2, load(Ity_I64, mkexpr(op2addr)));
6629 assign(result, binop(Iop_MullS64, mkexpr(op1), mkexpr(op2)));
6630 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6631
6632 return "msg";
6633}
6634
florian55085f82012-11-21 00:36:55 +00006635static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006636s390_irgen_MSGF(UChar r1, IRTemp op2addr)
6637{
6638 IRTemp op1 = newTemp(Ity_I64);
6639 IRTemp op2 = newTemp(Ity_I32);
6640 IRTemp result = newTemp(Ity_I128);
6641
6642 assign(op1, get_gpr_dw0(r1));
6643 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6644 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_32Sto64, mkexpr(op2))
6645 ));
6646 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6647
6648 return "msgf";
6649}
6650
florian55085f82012-11-21 00:36:55 +00006651static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006652s390_irgen_MSFI(UChar r1, UInt i2)
6653{
6654 IRTemp op1 = newTemp(Ity_I32);
6655 Int op2;
6656 IRTemp result = newTemp(Ity_I64);
6657
6658 assign(op1, get_gpr_w1(r1));
6659 op2 = (Int)i2;
6660 assign(result, binop(Iop_MullS32, mkexpr(op1), mkU32((UInt)op2)));
6661 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6662
6663 return "msfi";
6664}
6665
florian55085f82012-11-21 00:36:55 +00006666static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006667s390_irgen_MSGFI(UChar r1, UInt i2)
6668{
6669 IRTemp op1 = newTemp(Ity_I64);
6670 Int op2;
6671 IRTemp result = newTemp(Ity_I128);
6672
6673 assign(op1, get_gpr_dw0(r1));
6674 op2 = (Int)i2;
6675 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_32Sto64, mkU32((UInt)
6676 op2))));
6677 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6678
6679 return "msgfi";
6680}
6681
florian55085f82012-11-21 00:36:55 +00006682static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006683s390_irgen_OR(UChar r1, UChar r2)
6684{
6685 IRTemp op1 = newTemp(Ity_I32);
6686 IRTemp op2 = newTemp(Ity_I32);
6687 IRTemp result = newTemp(Ity_I32);
6688
6689 assign(op1, get_gpr_w1(r1));
6690 assign(op2, get_gpr_w1(r2));
6691 assign(result, binop(Iop_Or32, mkexpr(op1), mkexpr(op2)));
6692 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6693 put_gpr_w1(r1, mkexpr(result));
6694
6695 return "or";
6696}
6697
florian55085f82012-11-21 00:36:55 +00006698static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006699s390_irgen_OGR(UChar r1, UChar r2)
6700{
6701 IRTemp op1 = newTemp(Ity_I64);
6702 IRTemp op2 = newTemp(Ity_I64);
6703 IRTemp result = newTemp(Ity_I64);
6704
6705 assign(op1, get_gpr_dw0(r1));
6706 assign(op2, get_gpr_dw0(r2));
6707 assign(result, binop(Iop_Or64, mkexpr(op1), mkexpr(op2)));
6708 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6709 put_gpr_dw0(r1, mkexpr(result));
6710
6711 return "ogr";
6712}
6713
florian55085f82012-11-21 00:36:55 +00006714static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006715s390_irgen_ORK(UChar r3, UChar r1, UChar r2)
6716{
6717 IRTemp op2 = newTemp(Ity_I32);
6718 IRTemp op3 = newTemp(Ity_I32);
6719 IRTemp result = newTemp(Ity_I32);
6720
6721 assign(op2, get_gpr_w1(r2));
6722 assign(op3, get_gpr_w1(r3));
6723 assign(result, binop(Iop_Or32, mkexpr(op2), mkexpr(op3)));
6724 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6725 put_gpr_w1(r1, mkexpr(result));
6726
6727 return "ork";
6728}
6729
florian55085f82012-11-21 00:36:55 +00006730static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006731s390_irgen_OGRK(UChar r3, UChar r1, UChar r2)
6732{
6733 IRTemp op2 = newTemp(Ity_I64);
6734 IRTemp op3 = newTemp(Ity_I64);
6735 IRTemp result = newTemp(Ity_I64);
6736
6737 assign(op2, get_gpr_dw0(r2));
6738 assign(op3, get_gpr_dw0(r3));
6739 assign(result, binop(Iop_Or64, mkexpr(op2), mkexpr(op3)));
6740 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6741 put_gpr_dw0(r1, mkexpr(result));
6742
6743 return "ogrk";
6744}
6745
florian55085f82012-11-21 00:36:55 +00006746static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006747s390_irgen_O(UChar r1, IRTemp op2addr)
6748{
6749 IRTemp op1 = newTemp(Ity_I32);
6750 IRTemp op2 = newTemp(Ity_I32);
6751 IRTemp result = newTemp(Ity_I32);
6752
6753 assign(op1, get_gpr_w1(r1));
6754 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6755 assign(result, binop(Iop_Or32, mkexpr(op1), mkexpr(op2)));
6756 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6757 put_gpr_w1(r1, mkexpr(result));
6758
6759 return "o";
6760}
6761
florian55085f82012-11-21 00:36:55 +00006762static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006763s390_irgen_OY(UChar r1, IRTemp op2addr)
6764{
6765 IRTemp op1 = newTemp(Ity_I32);
6766 IRTemp op2 = newTemp(Ity_I32);
6767 IRTemp result = newTemp(Ity_I32);
6768
6769 assign(op1, get_gpr_w1(r1));
6770 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6771 assign(result, binop(Iop_Or32, mkexpr(op1), mkexpr(op2)));
6772 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6773 put_gpr_w1(r1, mkexpr(result));
6774
6775 return "oy";
6776}
6777
florian55085f82012-11-21 00:36:55 +00006778static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006779s390_irgen_OG(UChar r1, IRTemp op2addr)
6780{
6781 IRTemp op1 = newTemp(Ity_I64);
6782 IRTemp op2 = newTemp(Ity_I64);
6783 IRTemp result = newTemp(Ity_I64);
6784
6785 assign(op1, get_gpr_dw0(r1));
6786 assign(op2, load(Ity_I64, mkexpr(op2addr)));
6787 assign(result, binop(Iop_Or64, mkexpr(op1), mkexpr(op2)));
6788 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6789 put_gpr_dw0(r1, mkexpr(result));
6790
6791 return "og";
6792}
6793
florian55085f82012-11-21 00:36:55 +00006794static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006795s390_irgen_OI(UChar i2, IRTemp op1addr)
6796{
6797 IRTemp op1 = newTemp(Ity_I8);
6798 UChar op2;
6799 IRTemp result = newTemp(Ity_I8);
6800
6801 assign(op1, load(Ity_I8, mkexpr(op1addr)));
6802 op2 = i2;
6803 assign(result, binop(Iop_Or8, mkexpr(op1), mkU8(op2)));
6804 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6805 store(mkexpr(op1addr), mkexpr(result));
6806
6807 return "oi";
6808}
6809
florian55085f82012-11-21 00:36:55 +00006810static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006811s390_irgen_OIY(UChar i2, IRTemp op1addr)
6812{
6813 IRTemp op1 = newTemp(Ity_I8);
6814 UChar op2;
6815 IRTemp result = newTemp(Ity_I8);
6816
6817 assign(op1, load(Ity_I8, mkexpr(op1addr)));
6818 op2 = i2;
6819 assign(result, binop(Iop_Or8, mkexpr(op1), mkU8(op2)));
6820 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6821 store(mkexpr(op1addr), mkexpr(result));
6822
6823 return "oiy";
6824}
6825
florian55085f82012-11-21 00:36:55 +00006826static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006827s390_irgen_OIHF(UChar r1, UInt i2)
6828{
6829 IRTemp op1 = newTemp(Ity_I32);
6830 UInt op2;
6831 IRTemp result = newTemp(Ity_I32);
6832
6833 assign(op1, get_gpr_w0(r1));
6834 op2 = i2;
6835 assign(result, binop(Iop_Or32, mkexpr(op1), mkU32(op2)));
6836 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6837 put_gpr_w0(r1, mkexpr(result));
6838
6839 return "oihf";
6840}
6841
florian55085f82012-11-21 00:36:55 +00006842static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006843s390_irgen_OIHH(UChar r1, UShort i2)
6844{
6845 IRTemp op1 = newTemp(Ity_I16);
6846 UShort op2;
6847 IRTemp result = newTemp(Ity_I16);
6848
6849 assign(op1, get_gpr_hw0(r1));
6850 op2 = i2;
6851 assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
6852 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6853 put_gpr_hw0(r1, mkexpr(result));
6854
6855 return "oihh";
6856}
6857
florian55085f82012-11-21 00:36:55 +00006858static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006859s390_irgen_OIHL(UChar r1, UShort i2)
6860{
6861 IRTemp op1 = newTemp(Ity_I16);
6862 UShort op2;
6863 IRTemp result = newTemp(Ity_I16);
6864
6865 assign(op1, get_gpr_hw1(r1));
6866 op2 = i2;
6867 assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
6868 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6869 put_gpr_hw1(r1, mkexpr(result));
6870
6871 return "oihl";
6872}
6873
florian55085f82012-11-21 00:36:55 +00006874static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006875s390_irgen_OILF(UChar r1, UInt i2)
6876{
6877 IRTemp op1 = newTemp(Ity_I32);
6878 UInt op2;
6879 IRTemp result = newTemp(Ity_I32);
6880
6881 assign(op1, get_gpr_w1(r1));
6882 op2 = i2;
6883 assign(result, binop(Iop_Or32, mkexpr(op1), mkU32(op2)));
6884 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6885 put_gpr_w1(r1, mkexpr(result));
6886
6887 return "oilf";
6888}
6889
florian55085f82012-11-21 00:36:55 +00006890static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006891s390_irgen_OILH(UChar r1, UShort i2)
6892{
6893 IRTemp op1 = newTemp(Ity_I16);
6894 UShort op2;
6895 IRTemp result = newTemp(Ity_I16);
6896
6897 assign(op1, get_gpr_hw2(r1));
6898 op2 = i2;
6899 assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
6900 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6901 put_gpr_hw2(r1, mkexpr(result));
6902
6903 return "oilh";
6904}
6905
florian55085f82012-11-21 00:36:55 +00006906static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006907s390_irgen_OILL(UChar r1, UShort i2)
6908{
6909 IRTemp op1 = newTemp(Ity_I16);
6910 UShort op2;
6911 IRTemp result = newTemp(Ity_I16);
6912
6913 assign(op1, get_gpr_hw3(r1));
6914 op2 = i2;
6915 assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
6916 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6917 put_gpr_hw3(r1, mkexpr(result));
6918
6919 return "oill";
6920}
6921
florian55085f82012-11-21 00:36:55 +00006922static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006923s390_irgen_PFD(void)
6924{
6925
6926 return "pfd";
6927}
6928
florian55085f82012-11-21 00:36:55 +00006929static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006930s390_irgen_PFDRL(void)
6931{
6932
6933 return "pfdrl";
6934}
6935
florian55085f82012-11-21 00:36:55 +00006936static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006937s390_irgen_RLL(UChar r1, UChar r3, IRTemp op2addr)
6938{
6939 IRTemp amount = newTemp(Ity_I64);
6940 IRTemp op = newTemp(Ity_I32);
6941
6942 assign(amount, binop(Iop_And64, mkexpr(op2addr), mkU64(31)));
6943 assign(op, get_gpr_w1(r3));
6944 put_gpr_w1(r1, binop(Iop_Or32, binop(Iop_Shl32, mkexpr(op), unop(Iop_64to8,
6945 mkexpr(amount))), binop(Iop_Shr32, mkexpr(op), unop(Iop_64to8,
6946 binop(Iop_Sub64, mkU64(32), mkexpr(amount))))));
6947
6948 return "rll";
6949}
6950
florian55085f82012-11-21 00:36:55 +00006951static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006952s390_irgen_RLLG(UChar r1, UChar r3, IRTemp op2addr)
6953{
6954 IRTemp amount = newTemp(Ity_I64);
6955 IRTemp op = newTemp(Ity_I64);
6956
6957 assign(amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
6958 assign(op, get_gpr_dw0(r3));
6959 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(op), unop(Iop_64to8,
6960 mkexpr(amount))), binop(Iop_Shr64, mkexpr(op), unop(Iop_64to8,
6961 binop(Iop_Sub64, mkU64(64), mkexpr(amount))))));
6962
6963 return "rllg";
6964}
6965
florian55085f82012-11-21 00:36:55 +00006966static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006967s390_irgen_RNSBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
6968{
6969 UChar from;
6970 UChar to;
6971 UChar rot;
6972 UChar t_bit;
6973 ULong mask;
6974 ULong maskc;
6975 IRTemp result = newTemp(Ity_I64);
6976 IRTemp op2 = newTemp(Ity_I64);
6977
6978 from = i3 & 63;
6979 to = i4 & 63;
6980 rot = i5 & 63;
6981 t_bit = i3 & 128;
6982 assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
6983 get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
6984 mkU8(64 - rot))));
6985 if (from <= to) {
6986 mask = ~0ULL;
6987 mask = (mask >> from) & (mask << (63 - to));
6988 maskc = ~mask;
6989 } else {
6990 maskc = ~0ULL;
6991 maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
6992 mask = ~maskc;
6993 }
6994 assign(result, binop(Iop_And64, binop(Iop_And64, get_gpr_dw0(r1), mkexpr(op2)
6995 ), mkU64(mask)));
6996 if (t_bit == 0) {
6997 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
6998 mkU64(maskc)), mkexpr(result)));
6999 }
7000 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7001
7002 return "rnsbg";
7003}
7004
florian55085f82012-11-21 00:36:55 +00007005static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007006s390_irgen_RXSBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
7007{
7008 UChar from;
7009 UChar to;
7010 UChar rot;
7011 UChar t_bit;
7012 ULong mask;
7013 ULong maskc;
7014 IRTemp result = newTemp(Ity_I64);
7015 IRTemp op2 = newTemp(Ity_I64);
7016
7017 from = i3 & 63;
7018 to = i4 & 63;
7019 rot = i5 & 63;
7020 t_bit = i3 & 128;
7021 assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
7022 get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
7023 mkU8(64 - rot))));
7024 if (from <= to) {
7025 mask = ~0ULL;
7026 mask = (mask >> from) & (mask << (63 - to));
7027 maskc = ~mask;
7028 } else {
7029 maskc = ~0ULL;
7030 maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
7031 mask = ~maskc;
7032 }
7033 assign(result, binop(Iop_And64, binop(Iop_Xor64, get_gpr_dw0(r1), mkexpr(op2)
7034 ), mkU64(mask)));
7035 if (t_bit == 0) {
7036 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
7037 mkU64(maskc)), mkexpr(result)));
7038 }
7039 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7040
7041 return "rxsbg";
7042}
7043
florian55085f82012-11-21 00:36:55 +00007044static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007045s390_irgen_ROSBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
7046{
7047 UChar from;
7048 UChar to;
7049 UChar rot;
7050 UChar t_bit;
7051 ULong mask;
7052 ULong maskc;
7053 IRTemp result = newTemp(Ity_I64);
7054 IRTemp op2 = newTemp(Ity_I64);
7055
7056 from = i3 & 63;
7057 to = i4 & 63;
7058 rot = i5 & 63;
7059 t_bit = i3 & 128;
7060 assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
7061 get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
7062 mkU8(64 - rot))));
7063 if (from <= to) {
7064 mask = ~0ULL;
7065 mask = (mask >> from) & (mask << (63 - to));
7066 maskc = ~mask;
7067 } else {
7068 maskc = ~0ULL;
7069 maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
7070 mask = ~maskc;
7071 }
7072 assign(result, binop(Iop_And64, binop(Iop_Or64, get_gpr_dw0(r1), mkexpr(op2)
7073 ), mkU64(mask)));
7074 if (t_bit == 0) {
7075 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
7076 mkU64(maskc)), mkexpr(result)));
7077 }
7078 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7079
7080 return "rosbg";
7081}
7082
florian55085f82012-11-21 00:36:55 +00007083static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007084s390_irgen_RISBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
7085{
7086 UChar from;
7087 UChar to;
7088 UChar rot;
7089 UChar z_bit;
7090 ULong mask;
7091 ULong maskc;
7092 IRTemp op2 = newTemp(Ity_I64);
7093 IRTemp result = newTemp(Ity_I64);
7094
7095 from = i3 & 63;
7096 to = i4 & 63;
7097 rot = i5 & 63;
7098 z_bit = i4 & 128;
7099 assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
7100 get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
7101 mkU8(64 - rot))));
7102 if (from <= to) {
7103 mask = ~0ULL;
7104 mask = (mask >> from) & (mask << (63 - to));
7105 maskc = ~mask;
7106 } else {
7107 maskc = ~0ULL;
7108 maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
7109 mask = ~maskc;
7110 }
7111 if (z_bit == 0) {
7112 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
7113 mkU64(maskc)), binop(Iop_And64, mkexpr(op2), mkU64(mask))));
7114 } else {
7115 put_gpr_dw0(r1, binop(Iop_And64, mkexpr(op2), mkU64(mask)));
7116 }
7117 assign(result, get_gpr_dw0(r1));
7118 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
7119
7120 return "risbg";
7121}
7122
florian55085f82012-11-21 00:36:55 +00007123static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007124s390_irgen_SAR(UChar r1, UChar r2)
7125{
7126 put_ar_w0(r1, get_gpr_w1(r2));
sewardj7ee97522011-05-09 21:45:04 +00007127 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00007128 s390_disasm(ENC3(MNM, AR, GPR), "sar", r1, r2);
7129
7130 return "sar";
7131}
7132
florian55085f82012-11-21 00:36:55 +00007133static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007134s390_irgen_SLDA(UChar r1, IRTemp op2addr)
7135{
7136 IRTemp p1 = newTemp(Ity_I64);
7137 IRTemp p2 = newTemp(Ity_I64);
7138 IRTemp op = newTemp(Ity_I64);
7139 IRTemp result = newTemp(Ity_I64);
florian417b22d2012-07-13 13:41:41 +00007140 ULong sign_mask;
sewardj2019a972011-03-07 16:04:07 +00007141 IRTemp shift_amount = newTemp(Ity_I64);
7142
7143 assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
7144 assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
7145 assign(op, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1), mkU8(32)), mkexpr(p2)
7146 ));
7147 sign_mask = 1ULL << 63;
7148 assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7149 assign(result, binop(Iop_Or64, binop(Iop_And64, binop(Iop_Shl64, mkexpr(op),
florian417b22d2012-07-13 13:41:41 +00007150 unop(Iop_64to8, mkexpr(shift_amount))), mkU64(~sign_mask)),
7151 binop(Iop_And64, mkexpr(op), mkU64(sign_mask))));
sewardj2019a972011-03-07 16:04:07 +00007152 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
7153 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
7154 s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_64, op, shift_amount);
7155
7156 return "slda";
7157}
7158
florian55085f82012-11-21 00:36:55 +00007159static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007160s390_irgen_SLDL(UChar r1, IRTemp op2addr)
7161{
7162 IRTemp p1 = newTemp(Ity_I64);
7163 IRTemp p2 = newTemp(Ity_I64);
7164 IRTemp result = newTemp(Ity_I64);
7165
7166 assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
7167 assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
7168 assign(result, binop(Iop_Shl64, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1),
7169 mkU8(32)), mkexpr(p2)), unop(Iop_64to8, binop(Iop_And64,
7170 mkexpr(op2addr), mkU64(63)))));
7171 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
7172 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
7173
7174 return "sldl";
7175}
7176
florian55085f82012-11-21 00:36:55 +00007177static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007178s390_irgen_SLA(UChar r1, IRTemp op2addr)
7179{
7180 IRTemp uop = newTemp(Ity_I32);
7181 IRTemp result = newTemp(Ity_I32);
7182 UInt sign_mask;
7183 IRTemp shift_amount = newTemp(Ity_I64);
7184 IRTemp op = newTemp(Ity_I32);
7185
7186 assign(op, get_gpr_w1(r1));
7187 assign(uop, get_gpr_w1(r1));
7188 sign_mask = 2147483648U;
7189 assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7190 assign(result, binop(Iop_Or32, binop(Iop_And32, binop(Iop_Shl32, mkexpr(uop),
7191 unop(Iop_64to8, mkexpr(shift_amount))), mkU32(~sign_mask)),
7192 binop(Iop_And32, mkexpr(uop), mkU32(sign_mask))));
7193 put_gpr_w1(r1, mkexpr(result));
7194 s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_32, op, shift_amount);
7195
7196 return "sla";
7197}
7198
florian55085f82012-11-21 00:36:55 +00007199static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007200s390_irgen_SLAK(UChar r1, UChar r3, IRTemp op2addr)
7201{
7202 IRTemp uop = newTemp(Ity_I32);
7203 IRTemp result = newTemp(Ity_I32);
7204 UInt sign_mask;
7205 IRTemp shift_amount = newTemp(Ity_I64);
7206 IRTemp op = newTemp(Ity_I32);
7207
7208 assign(op, get_gpr_w1(r3));
7209 assign(uop, get_gpr_w1(r3));
7210 sign_mask = 2147483648U;
7211 assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7212 assign(result, binop(Iop_Or32, binop(Iop_And32, binop(Iop_Shl32, mkexpr(uop),
7213 unop(Iop_64to8, mkexpr(shift_amount))), mkU32(~sign_mask)),
7214 binop(Iop_And32, mkexpr(uop), mkU32(sign_mask))));
7215 put_gpr_w1(r1, mkexpr(result));
7216 s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_32, op, shift_amount);
7217
7218 return "slak";
7219}
7220
florian55085f82012-11-21 00:36:55 +00007221static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007222s390_irgen_SLAG(UChar r1, UChar r3, IRTemp op2addr)
7223{
7224 IRTemp uop = newTemp(Ity_I64);
7225 IRTemp result = newTemp(Ity_I64);
7226 ULong sign_mask;
7227 IRTemp shift_amount = newTemp(Ity_I64);
7228 IRTemp op = newTemp(Ity_I64);
7229
7230 assign(op, get_gpr_dw0(r3));
7231 assign(uop, get_gpr_dw0(r3));
7232 sign_mask = 9223372036854775808ULL;
7233 assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7234 assign(result, binop(Iop_Or64, binop(Iop_And64, binop(Iop_Shl64, mkexpr(uop),
7235 unop(Iop_64to8, mkexpr(shift_amount))), mkU64(~sign_mask)),
7236 binop(Iop_And64, mkexpr(uop), mkU64(sign_mask))));
7237 put_gpr_dw0(r1, mkexpr(result));
7238 s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_64, op, shift_amount);
7239
7240 return "slag";
7241}
7242
florian55085f82012-11-21 00:36:55 +00007243static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007244s390_irgen_SLL(UChar r1, IRTemp op2addr)
7245{
7246 put_gpr_w1(r1, binop(Iop_Shl32, get_gpr_w1(r1), unop(Iop_64to8,
7247 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
7248
7249 return "sll";
7250}
7251
florian55085f82012-11-21 00:36:55 +00007252static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007253s390_irgen_SLLK(UChar r1, UChar r3, IRTemp op2addr)
7254{
7255 put_gpr_w1(r1, binop(Iop_Shl32, get_gpr_w1(r3), unop(Iop_64to8,
7256 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
7257
7258 return "sllk";
7259}
7260
florian55085f82012-11-21 00:36:55 +00007261static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007262s390_irgen_SLLG(UChar r1, UChar r3, IRTemp op2addr)
7263{
7264 put_gpr_dw0(r1, binop(Iop_Shl64, get_gpr_dw0(r3), unop(Iop_64to8,
7265 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
7266
7267 return "sllg";
7268}
7269
florian55085f82012-11-21 00:36:55 +00007270static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007271s390_irgen_SRDA(UChar r1, IRTemp op2addr)
7272{
7273 IRTemp p1 = newTemp(Ity_I64);
7274 IRTemp p2 = newTemp(Ity_I64);
7275 IRTemp result = newTemp(Ity_I64);
7276
7277 assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
7278 assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
7279 assign(result, binop(Iop_Sar64, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1),
7280 mkU8(32)), mkexpr(p2)), unop(Iop_64to8, binop(Iop_And64,
7281 mkexpr(op2addr), mkU64(63)))));
7282 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
7283 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
7284 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7285
7286 return "srda";
7287}
7288
florian55085f82012-11-21 00:36:55 +00007289static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007290s390_irgen_SRDL(UChar r1, IRTemp op2addr)
7291{
7292 IRTemp p1 = newTemp(Ity_I64);
7293 IRTemp p2 = newTemp(Ity_I64);
7294 IRTemp result = newTemp(Ity_I64);
7295
7296 assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
7297 assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
7298 assign(result, binop(Iop_Shr64, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1),
7299 mkU8(32)), mkexpr(p2)), unop(Iop_64to8, binop(Iop_And64,
7300 mkexpr(op2addr), mkU64(63)))));
7301 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
7302 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
7303
7304 return "srdl";
7305}
7306
florian55085f82012-11-21 00:36:55 +00007307static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007308s390_irgen_SRA(UChar r1, IRTemp op2addr)
7309{
7310 IRTemp result = newTemp(Ity_I32);
7311 IRTemp op = newTemp(Ity_I32);
7312
7313 assign(op, get_gpr_w1(r1));
7314 assign(result, binop(Iop_Sar32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7315 mkexpr(op2addr), mkU64(63)))));
7316 put_gpr_w1(r1, mkexpr(result));
7317 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7318
7319 return "sra";
7320}
7321
florian55085f82012-11-21 00:36:55 +00007322static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007323s390_irgen_SRAK(UChar r1, UChar r3, IRTemp op2addr)
7324{
7325 IRTemp result = newTemp(Ity_I32);
7326 IRTemp op = newTemp(Ity_I32);
7327
7328 assign(op, get_gpr_w1(r3));
7329 assign(result, binop(Iop_Sar32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7330 mkexpr(op2addr), mkU64(63)))));
7331 put_gpr_w1(r1, mkexpr(result));
7332 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7333
7334 return "srak";
7335}
7336
florian55085f82012-11-21 00:36:55 +00007337static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007338s390_irgen_SRAG(UChar r1, UChar r3, IRTemp op2addr)
7339{
7340 IRTemp result = newTemp(Ity_I64);
7341 IRTemp op = newTemp(Ity_I64);
7342
7343 assign(op, get_gpr_dw0(r3));
7344 assign(result, binop(Iop_Sar64, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7345 mkexpr(op2addr), mkU64(63)))));
7346 put_gpr_dw0(r1, mkexpr(result));
7347 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7348
7349 return "srag";
7350}
7351
florian55085f82012-11-21 00:36:55 +00007352static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007353s390_irgen_SRL(UChar r1, IRTemp op2addr)
7354{
7355 IRTemp op = newTemp(Ity_I32);
7356
7357 assign(op, get_gpr_w1(r1));
7358 put_gpr_w1(r1, binop(Iop_Shr32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7359 mkexpr(op2addr), mkU64(63)))));
7360
7361 return "srl";
7362}
7363
florian55085f82012-11-21 00:36:55 +00007364static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007365s390_irgen_SRLK(UChar r1, UChar r3, IRTemp op2addr)
7366{
7367 IRTemp op = newTemp(Ity_I32);
7368
7369 assign(op, get_gpr_w1(r3));
7370 put_gpr_w1(r1, binop(Iop_Shr32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7371 mkexpr(op2addr), mkU64(63)))));
7372
7373 return "srlk";
7374}
7375
florian55085f82012-11-21 00:36:55 +00007376static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007377s390_irgen_SRLG(UChar r1, UChar r3, IRTemp op2addr)
7378{
7379 IRTemp op = newTemp(Ity_I64);
7380
7381 assign(op, get_gpr_dw0(r3));
7382 put_gpr_dw0(r1, binop(Iop_Shr64, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7383 mkexpr(op2addr), mkU64(63)))));
7384
7385 return "srlg";
7386}
7387
florian55085f82012-11-21 00:36:55 +00007388static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007389s390_irgen_ST(UChar r1, IRTemp op2addr)
7390{
7391 store(mkexpr(op2addr), get_gpr_w1(r1));
7392
7393 return "st";
7394}
7395
florian55085f82012-11-21 00:36:55 +00007396static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007397s390_irgen_STY(UChar r1, IRTemp op2addr)
7398{
7399 store(mkexpr(op2addr), get_gpr_w1(r1));
7400
7401 return "sty";
7402}
7403
florian55085f82012-11-21 00:36:55 +00007404static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007405s390_irgen_STG(UChar r1, IRTemp op2addr)
7406{
7407 store(mkexpr(op2addr), get_gpr_dw0(r1));
7408
7409 return "stg";
7410}
7411
florian55085f82012-11-21 00:36:55 +00007412static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007413s390_irgen_STRL(UChar r1, UInt i2)
7414{
7415 store(mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)),
7416 get_gpr_w1(r1));
7417
7418 return "strl";
7419}
7420
florian55085f82012-11-21 00:36:55 +00007421static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007422s390_irgen_STGRL(UChar r1, UInt i2)
7423{
7424 store(mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)),
7425 get_gpr_dw0(r1));
7426
7427 return "stgrl";
7428}
7429
florian55085f82012-11-21 00:36:55 +00007430static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007431s390_irgen_STC(UChar r1, IRTemp op2addr)
7432{
7433 store(mkexpr(op2addr), get_gpr_b7(r1));
7434
7435 return "stc";
7436}
7437
florian55085f82012-11-21 00:36:55 +00007438static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007439s390_irgen_STCY(UChar r1, IRTemp op2addr)
7440{
7441 store(mkexpr(op2addr), get_gpr_b7(r1));
7442
7443 return "stcy";
7444}
7445
florian55085f82012-11-21 00:36:55 +00007446static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007447s390_irgen_STCH(UChar r1, IRTemp op2addr)
7448{
7449 store(mkexpr(op2addr), get_gpr_b3(r1));
7450
7451 return "stch";
7452}
7453
florian55085f82012-11-21 00:36:55 +00007454static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007455s390_irgen_STCM(UChar r1, UChar r3, IRTemp op2addr)
7456{
7457 UChar mask;
7458 UChar n;
7459
7460 mask = (UChar)r3;
7461 n = 0;
7462 if ((mask & 8) != 0) {
7463 store(mkexpr(op2addr), get_gpr_b4(r1));
7464 n = n + 1;
7465 }
7466 if ((mask & 4) != 0) {
7467 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b5(r1));
7468 n = n + 1;
7469 }
7470 if ((mask & 2) != 0) {
7471 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b6(r1));
7472 n = n + 1;
7473 }
7474 if ((mask & 1) != 0) {
7475 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b7(r1));
7476 }
7477
7478 return "stcm";
7479}
7480
florian55085f82012-11-21 00:36:55 +00007481static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007482s390_irgen_STCMY(UChar r1, UChar r3, IRTemp op2addr)
7483{
7484 UChar mask;
7485 UChar n;
7486
7487 mask = (UChar)r3;
7488 n = 0;
7489 if ((mask & 8) != 0) {
7490 store(mkexpr(op2addr), get_gpr_b4(r1));
7491 n = n + 1;
7492 }
7493 if ((mask & 4) != 0) {
7494 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b5(r1));
7495 n = n + 1;
7496 }
7497 if ((mask & 2) != 0) {
7498 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b6(r1));
7499 n = n + 1;
7500 }
7501 if ((mask & 1) != 0) {
7502 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b7(r1));
7503 }
7504
7505 return "stcmy";
7506}
7507
florian55085f82012-11-21 00:36:55 +00007508static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007509s390_irgen_STCMH(UChar r1, UChar r3, IRTemp op2addr)
7510{
7511 UChar mask;
7512 UChar n;
7513
7514 mask = (UChar)r3;
7515 n = 0;
7516 if ((mask & 8) != 0) {
7517 store(mkexpr(op2addr), get_gpr_b0(r1));
7518 n = n + 1;
7519 }
7520 if ((mask & 4) != 0) {
7521 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b1(r1));
7522 n = n + 1;
7523 }
7524 if ((mask & 2) != 0) {
7525 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b2(r1));
7526 n = n + 1;
7527 }
7528 if ((mask & 1) != 0) {
7529 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b3(r1));
7530 }
7531
7532 return "stcmh";
7533}
7534
florian55085f82012-11-21 00:36:55 +00007535static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007536s390_irgen_STH(UChar r1, IRTemp op2addr)
7537{
7538 store(mkexpr(op2addr), get_gpr_hw3(r1));
7539
7540 return "sth";
7541}
7542
florian55085f82012-11-21 00:36:55 +00007543static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007544s390_irgen_STHY(UChar r1, IRTemp op2addr)
7545{
7546 store(mkexpr(op2addr), get_gpr_hw3(r1));
7547
7548 return "sthy";
7549}
7550
florian55085f82012-11-21 00:36:55 +00007551static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007552s390_irgen_STHRL(UChar r1, UInt i2)
7553{
7554 store(mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)),
7555 get_gpr_hw3(r1));
7556
7557 return "sthrl";
7558}
7559
florian55085f82012-11-21 00:36:55 +00007560static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007561s390_irgen_STHH(UChar r1, IRTemp op2addr)
7562{
7563 store(mkexpr(op2addr), get_gpr_hw1(r1));
7564
7565 return "sthh";
7566}
7567
florian55085f82012-11-21 00:36:55 +00007568static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007569s390_irgen_STFH(UChar r1, IRTemp op2addr)
7570{
7571 store(mkexpr(op2addr), get_gpr_w0(r1));
7572
7573 return "stfh";
7574}
7575
florian55085f82012-11-21 00:36:55 +00007576static const HChar *
sewardjd7bde722011-04-05 13:19:33 +00007577s390_irgen_STOC(UChar r1, IRTemp op2addr)
7578{
7579 /* condition is checked in format handler */
7580 store(mkexpr(op2addr), get_gpr_w1(r1));
7581
7582 return "stoc";
7583}
7584
florian55085f82012-11-21 00:36:55 +00007585static const HChar *
sewardjd7bde722011-04-05 13:19:33 +00007586s390_irgen_STOCG(UChar r1, IRTemp op2addr)
7587{
7588 /* condition is checked in format handler */
7589 store(mkexpr(op2addr), get_gpr_dw0(r1));
7590
7591 return "stocg";
7592}
7593
florian55085f82012-11-21 00:36:55 +00007594static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007595s390_irgen_STPQ(UChar r1, IRTemp op2addr)
7596{
7597 store(mkexpr(op2addr), get_gpr_dw0(r1));
7598 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(8)), get_gpr_dw0(r1 + 1));
7599
7600 return "stpq";
7601}
7602
florian55085f82012-11-21 00:36:55 +00007603static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007604s390_irgen_STRVH(UChar r1, IRTemp op2addr)
7605{
7606 store(mkexpr(op2addr), get_gpr_b7(r1));
7607 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(1)), get_gpr_b6(r1));
7608
7609 return "strvh";
7610}
7611
florian55085f82012-11-21 00:36:55 +00007612static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007613s390_irgen_STRV(UChar r1, IRTemp op2addr)
7614{
7615 store(mkexpr(op2addr), get_gpr_b7(r1));
7616 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(1)), get_gpr_b6(r1));
7617 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(2)), get_gpr_b5(r1));
7618 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(3)), get_gpr_b4(r1));
7619
7620 return "strv";
7621}
7622
florian55085f82012-11-21 00:36:55 +00007623static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007624s390_irgen_STRVG(UChar r1, IRTemp op2addr)
7625{
7626 store(mkexpr(op2addr), get_gpr_b7(r1));
7627 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(1)), get_gpr_b6(r1));
7628 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(2)), get_gpr_b5(r1));
7629 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(3)), get_gpr_b4(r1));
7630 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(4)), get_gpr_b3(r1));
7631 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(5)), get_gpr_b2(r1));
7632 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(6)), get_gpr_b1(r1));
7633 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(7)), get_gpr_b0(r1));
7634
7635 return "strvg";
7636}
7637
florian55085f82012-11-21 00:36:55 +00007638static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007639s390_irgen_SR(UChar r1, UChar r2)
7640{
7641 IRTemp op1 = newTemp(Ity_I32);
7642 IRTemp op2 = newTemp(Ity_I32);
7643 IRTemp result = newTemp(Ity_I32);
7644
7645 assign(op1, get_gpr_w1(r1));
7646 assign(op2, get_gpr_w1(r2));
7647 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7648 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
7649 put_gpr_w1(r1, mkexpr(result));
7650
7651 return "sr";
7652}
7653
florian55085f82012-11-21 00:36:55 +00007654static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007655s390_irgen_SGR(UChar r1, UChar r2)
7656{
7657 IRTemp op1 = newTemp(Ity_I64);
7658 IRTemp op2 = newTemp(Ity_I64);
7659 IRTemp result = newTemp(Ity_I64);
7660
7661 assign(op1, get_gpr_dw0(r1));
7662 assign(op2, get_gpr_dw0(r2));
7663 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7664 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
7665 put_gpr_dw0(r1, mkexpr(result));
7666
7667 return "sgr";
7668}
7669
florian55085f82012-11-21 00:36:55 +00007670static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007671s390_irgen_SGFR(UChar r1, UChar r2)
7672{
7673 IRTemp op1 = newTemp(Ity_I64);
7674 IRTemp op2 = newTemp(Ity_I64);
7675 IRTemp result = newTemp(Ity_I64);
7676
7677 assign(op1, get_gpr_dw0(r1));
7678 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
7679 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7680 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
7681 put_gpr_dw0(r1, mkexpr(result));
7682
7683 return "sgfr";
7684}
7685
florian55085f82012-11-21 00:36:55 +00007686static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007687s390_irgen_SRK(UChar r3, UChar r1, UChar r2)
7688{
7689 IRTemp op2 = newTemp(Ity_I32);
7690 IRTemp op3 = newTemp(Ity_I32);
7691 IRTemp result = newTemp(Ity_I32);
7692
7693 assign(op2, get_gpr_w1(r2));
7694 assign(op3, get_gpr_w1(r3));
7695 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
7696 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op2, op3);
7697 put_gpr_w1(r1, mkexpr(result));
7698
7699 return "srk";
7700}
7701
florian55085f82012-11-21 00:36:55 +00007702static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007703s390_irgen_SGRK(UChar r3, UChar r1, UChar r2)
7704{
7705 IRTemp op2 = newTemp(Ity_I64);
7706 IRTemp op3 = newTemp(Ity_I64);
7707 IRTemp result = newTemp(Ity_I64);
7708
7709 assign(op2, get_gpr_dw0(r2));
7710 assign(op3, get_gpr_dw0(r3));
7711 assign(result, binop(Iop_Sub64, mkexpr(op2), mkexpr(op3)));
7712 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op2, op3);
7713 put_gpr_dw0(r1, mkexpr(result));
7714
7715 return "sgrk";
7716}
7717
florian55085f82012-11-21 00:36:55 +00007718static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007719s390_irgen_S(UChar r1, IRTemp op2addr)
7720{
7721 IRTemp op1 = newTemp(Ity_I32);
7722 IRTemp op2 = newTemp(Ity_I32);
7723 IRTemp result = newTemp(Ity_I32);
7724
7725 assign(op1, get_gpr_w1(r1));
7726 assign(op2, load(Ity_I32, mkexpr(op2addr)));
7727 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7728 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
7729 put_gpr_w1(r1, mkexpr(result));
7730
7731 return "s";
7732}
7733
florian55085f82012-11-21 00:36:55 +00007734static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007735s390_irgen_SY(UChar r1, IRTemp op2addr)
7736{
7737 IRTemp op1 = newTemp(Ity_I32);
7738 IRTemp op2 = newTemp(Ity_I32);
7739 IRTemp result = newTemp(Ity_I32);
7740
7741 assign(op1, get_gpr_w1(r1));
7742 assign(op2, load(Ity_I32, mkexpr(op2addr)));
7743 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7744 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
7745 put_gpr_w1(r1, mkexpr(result));
7746
7747 return "sy";
7748}
7749
florian55085f82012-11-21 00:36:55 +00007750static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007751s390_irgen_SG(UChar r1, IRTemp op2addr)
7752{
7753 IRTemp op1 = newTemp(Ity_I64);
7754 IRTemp op2 = newTemp(Ity_I64);
7755 IRTemp result = newTemp(Ity_I64);
7756
7757 assign(op1, get_gpr_dw0(r1));
7758 assign(op2, load(Ity_I64, mkexpr(op2addr)));
7759 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7760 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
7761 put_gpr_dw0(r1, mkexpr(result));
7762
7763 return "sg";
7764}
7765
florian55085f82012-11-21 00:36:55 +00007766static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007767s390_irgen_SGF(UChar r1, IRTemp op2addr)
7768{
7769 IRTemp op1 = newTemp(Ity_I64);
7770 IRTemp op2 = newTemp(Ity_I64);
7771 IRTemp result = newTemp(Ity_I64);
7772
7773 assign(op1, get_gpr_dw0(r1));
7774 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
7775 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7776 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
7777 put_gpr_dw0(r1, mkexpr(result));
7778
7779 return "sgf";
7780}
7781
florian55085f82012-11-21 00:36:55 +00007782static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007783s390_irgen_SH(UChar r1, IRTemp op2addr)
7784{
7785 IRTemp op1 = newTemp(Ity_I32);
7786 IRTemp op2 = newTemp(Ity_I32);
7787 IRTemp result = newTemp(Ity_I32);
7788
7789 assign(op1, get_gpr_w1(r1));
7790 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
7791 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7792 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
7793 put_gpr_w1(r1, mkexpr(result));
7794
7795 return "sh";
7796}
7797
florian55085f82012-11-21 00:36:55 +00007798static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007799s390_irgen_SHY(UChar r1, IRTemp op2addr)
7800{
7801 IRTemp op1 = newTemp(Ity_I32);
7802 IRTemp op2 = newTemp(Ity_I32);
7803 IRTemp result = newTemp(Ity_I32);
7804
7805 assign(op1, get_gpr_w1(r1));
7806 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
7807 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7808 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
7809 put_gpr_w1(r1, mkexpr(result));
7810
7811 return "shy";
7812}
7813
florian55085f82012-11-21 00:36:55 +00007814static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007815s390_irgen_SHHHR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
7816{
7817 IRTemp op2 = newTemp(Ity_I32);
7818 IRTemp op3 = newTemp(Ity_I32);
7819 IRTemp result = newTemp(Ity_I32);
7820
7821 assign(op2, get_gpr_w0(r1));
7822 assign(op3, get_gpr_w0(r2));
7823 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
7824 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op2, op3);
7825 put_gpr_w0(r1, mkexpr(result));
7826
7827 return "shhhr";
7828}
7829
florian55085f82012-11-21 00:36:55 +00007830static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007831s390_irgen_SHHLR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
7832{
7833 IRTemp op2 = newTemp(Ity_I32);
7834 IRTemp op3 = newTemp(Ity_I32);
7835 IRTemp result = newTemp(Ity_I32);
7836
7837 assign(op2, get_gpr_w0(r1));
7838 assign(op3, get_gpr_w1(r2));
7839 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
7840 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op2, op3);
7841 put_gpr_w0(r1, mkexpr(result));
7842
7843 return "shhlr";
7844}
7845
florian55085f82012-11-21 00:36:55 +00007846static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007847s390_irgen_SLR(UChar r1, UChar r2)
7848{
7849 IRTemp op1 = newTemp(Ity_I32);
7850 IRTemp op2 = newTemp(Ity_I32);
7851 IRTemp result = newTemp(Ity_I32);
7852
7853 assign(op1, get_gpr_w1(r1));
7854 assign(op2, get_gpr_w1(r2));
7855 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7856 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, op2);
7857 put_gpr_w1(r1, mkexpr(result));
7858
7859 return "slr";
7860}
7861
florian55085f82012-11-21 00:36:55 +00007862static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007863s390_irgen_SLGR(UChar r1, UChar r2)
7864{
7865 IRTemp op1 = newTemp(Ity_I64);
7866 IRTemp op2 = newTemp(Ity_I64);
7867 IRTemp result = newTemp(Ity_I64);
7868
7869 assign(op1, get_gpr_dw0(r1));
7870 assign(op2, get_gpr_dw0(r2));
7871 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7872 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
7873 put_gpr_dw0(r1, mkexpr(result));
7874
7875 return "slgr";
7876}
7877
florian55085f82012-11-21 00:36:55 +00007878static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007879s390_irgen_SLGFR(UChar r1, UChar r2)
7880{
7881 IRTemp op1 = newTemp(Ity_I64);
7882 IRTemp op2 = newTemp(Ity_I64);
7883 IRTemp result = newTemp(Ity_I64);
7884
7885 assign(op1, get_gpr_dw0(r1));
7886 assign(op2, unop(Iop_32Uto64, get_gpr_w1(r2)));
7887 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7888 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
7889 put_gpr_dw0(r1, mkexpr(result));
7890
7891 return "slgfr";
7892}
7893
florian55085f82012-11-21 00:36:55 +00007894static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007895s390_irgen_SLRK(UChar r3, UChar r1, UChar r2)
7896{
7897 IRTemp op2 = newTemp(Ity_I32);
7898 IRTemp op3 = newTemp(Ity_I32);
7899 IRTemp result = newTemp(Ity_I32);
7900
7901 assign(op2, get_gpr_w1(r2));
7902 assign(op3, get_gpr_w1(r3));
7903 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
7904 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op2, op3);
7905 put_gpr_w1(r1, mkexpr(result));
7906
7907 return "slrk";
7908}
7909
florian55085f82012-11-21 00:36:55 +00007910static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007911s390_irgen_SLGRK(UChar r3, UChar r1, UChar r2)
7912{
7913 IRTemp op2 = newTemp(Ity_I64);
7914 IRTemp op3 = newTemp(Ity_I64);
7915 IRTemp result = newTemp(Ity_I64);
7916
7917 assign(op2, get_gpr_dw0(r2));
7918 assign(op3, get_gpr_dw0(r3));
7919 assign(result, binop(Iop_Sub64, mkexpr(op2), mkexpr(op3)));
7920 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op2, op3);
7921 put_gpr_dw0(r1, mkexpr(result));
7922
7923 return "slgrk";
7924}
7925
florian55085f82012-11-21 00:36:55 +00007926static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007927s390_irgen_SL(UChar r1, IRTemp op2addr)
7928{
7929 IRTemp op1 = newTemp(Ity_I32);
7930 IRTemp op2 = newTemp(Ity_I32);
7931 IRTemp result = newTemp(Ity_I32);
7932
7933 assign(op1, get_gpr_w1(r1));
7934 assign(op2, load(Ity_I32, mkexpr(op2addr)));
7935 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7936 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, op2);
7937 put_gpr_w1(r1, mkexpr(result));
7938
7939 return "sl";
7940}
7941
florian55085f82012-11-21 00:36:55 +00007942static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007943s390_irgen_SLY(UChar r1, IRTemp op2addr)
7944{
7945 IRTemp op1 = newTemp(Ity_I32);
7946 IRTemp op2 = newTemp(Ity_I32);
7947 IRTemp result = newTemp(Ity_I32);
7948
7949 assign(op1, get_gpr_w1(r1));
7950 assign(op2, load(Ity_I32, mkexpr(op2addr)));
7951 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7952 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, op2);
7953 put_gpr_w1(r1, mkexpr(result));
7954
7955 return "sly";
7956}
7957
florian55085f82012-11-21 00:36:55 +00007958static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007959s390_irgen_SLG(UChar r1, IRTemp op2addr)
7960{
7961 IRTemp op1 = newTemp(Ity_I64);
7962 IRTemp op2 = newTemp(Ity_I64);
7963 IRTemp result = newTemp(Ity_I64);
7964
7965 assign(op1, get_gpr_dw0(r1));
7966 assign(op2, load(Ity_I64, mkexpr(op2addr)));
7967 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7968 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
7969 put_gpr_dw0(r1, mkexpr(result));
7970
7971 return "slg";
7972}
7973
florian55085f82012-11-21 00:36:55 +00007974static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007975s390_irgen_SLGF(UChar r1, IRTemp op2addr)
7976{
7977 IRTemp op1 = newTemp(Ity_I64);
7978 IRTemp op2 = newTemp(Ity_I64);
7979 IRTemp result = newTemp(Ity_I64);
7980
7981 assign(op1, get_gpr_dw0(r1));
7982 assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
7983 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7984 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
7985 put_gpr_dw0(r1, mkexpr(result));
7986
7987 return "slgf";
7988}
7989
florian55085f82012-11-21 00:36:55 +00007990static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007991s390_irgen_SLFI(UChar r1, UInt i2)
7992{
7993 IRTemp op1 = newTemp(Ity_I32);
7994 UInt op2;
7995 IRTemp result = newTemp(Ity_I32);
7996
7997 assign(op1, get_gpr_w1(r1));
7998 op2 = i2;
7999 assign(result, binop(Iop_Sub32, mkexpr(op1), mkU32(op2)));
8000 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, mktemp(Ity_I32,
8001 mkU32(op2)));
8002 put_gpr_w1(r1, mkexpr(result));
8003
8004 return "slfi";
8005}
8006
florian55085f82012-11-21 00:36:55 +00008007static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008008s390_irgen_SLGFI(UChar r1, UInt i2)
8009{
8010 IRTemp op1 = newTemp(Ity_I64);
8011 ULong op2;
8012 IRTemp result = newTemp(Ity_I64);
8013
8014 assign(op1, get_gpr_dw0(r1));
8015 op2 = (ULong)i2;
8016 assign(result, binop(Iop_Sub64, mkexpr(op1), mkU64(op2)));
8017 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, mktemp(Ity_I64,
8018 mkU64(op2)));
8019 put_gpr_dw0(r1, mkexpr(result));
8020
8021 return "slgfi";
8022}
8023
florian55085f82012-11-21 00:36:55 +00008024static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008025s390_irgen_SLHHHR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
8026{
8027 IRTemp op2 = newTemp(Ity_I32);
8028 IRTemp op3 = newTemp(Ity_I32);
8029 IRTemp result = newTemp(Ity_I32);
8030
8031 assign(op2, get_gpr_w0(r1));
8032 assign(op3, get_gpr_w0(r2));
8033 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
8034 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op2, op3);
8035 put_gpr_w0(r1, mkexpr(result));
8036
8037 return "slhhhr";
8038}
8039
florian55085f82012-11-21 00:36:55 +00008040static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008041s390_irgen_SLHHLR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
8042{
8043 IRTemp op2 = newTemp(Ity_I32);
8044 IRTemp op3 = newTemp(Ity_I32);
8045 IRTemp result = newTemp(Ity_I32);
8046
8047 assign(op2, get_gpr_w0(r1));
8048 assign(op3, get_gpr_w1(r2));
8049 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
8050 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op2, op3);
8051 put_gpr_w0(r1, mkexpr(result));
8052
8053 return "slhhlr";
8054}
8055
florian55085f82012-11-21 00:36:55 +00008056static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008057s390_irgen_SLBR(UChar r1, UChar r2)
8058{
8059 IRTemp op1 = newTemp(Ity_I32);
8060 IRTemp op2 = newTemp(Ity_I32);
8061 IRTemp result = newTemp(Ity_I32);
8062 IRTemp borrow_in = newTemp(Ity_I32);
8063
8064 assign(op1, get_gpr_w1(r1));
8065 assign(op2, get_gpr_w1(r2));
8066 assign(borrow_in, binop(Iop_Sub32, mkU32(1), binop(Iop_Shr32,
8067 s390_call_calculate_cc(), mkU8(1))));
8068 assign(result, binop(Iop_Sub32, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)),
8069 mkexpr(borrow_in)));
8070 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_32, op1, op2, borrow_in);
8071 put_gpr_w1(r1, mkexpr(result));
8072
8073 return "slbr";
8074}
8075
florian55085f82012-11-21 00:36:55 +00008076static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008077s390_irgen_SLBGR(UChar r1, UChar r2)
8078{
8079 IRTemp op1 = newTemp(Ity_I64);
8080 IRTemp op2 = newTemp(Ity_I64);
8081 IRTemp result = newTemp(Ity_I64);
8082 IRTemp borrow_in = newTemp(Ity_I64);
8083
8084 assign(op1, get_gpr_dw0(r1));
8085 assign(op2, get_gpr_dw0(r2));
8086 assign(borrow_in, unop(Iop_32Uto64, binop(Iop_Sub32, mkU32(1),
8087 binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)))));
8088 assign(result, binop(Iop_Sub64, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)),
8089 mkexpr(borrow_in)));
8090 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_64, op1, op2, borrow_in);
8091 put_gpr_dw0(r1, mkexpr(result));
8092
8093 return "slbgr";
8094}
8095
florian55085f82012-11-21 00:36:55 +00008096static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008097s390_irgen_SLB(UChar r1, IRTemp op2addr)
8098{
8099 IRTemp op1 = newTemp(Ity_I32);
8100 IRTemp op2 = newTemp(Ity_I32);
8101 IRTemp result = newTemp(Ity_I32);
8102 IRTemp borrow_in = newTemp(Ity_I32);
8103
8104 assign(op1, get_gpr_w1(r1));
8105 assign(op2, load(Ity_I32, mkexpr(op2addr)));
8106 assign(borrow_in, binop(Iop_Sub32, mkU32(1), binop(Iop_Shr32,
8107 s390_call_calculate_cc(), mkU8(1))));
8108 assign(result, binop(Iop_Sub32, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)),
8109 mkexpr(borrow_in)));
8110 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_32, op1, op2, borrow_in);
8111 put_gpr_w1(r1, mkexpr(result));
8112
8113 return "slb";
8114}
8115
florian55085f82012-11-21 00:36:55 +00008116static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008117s390_irgen_SLBG(UChar r1, IRTemp op2addr)
8118{
8119 IRTemp op1 = newTemp(Ity_I64);
8120 IRTemp op2 = newTemp(Ity_I64);
8121 IRTemp result = newTemp(Ity_I64);
8122 IRTemp borrow_in = newTemp(Ity_I64);
8123
8124 assign(op1, get_gpr_dw0(r1));
8125 assign(op2, load(Ity_I64, mkexpr(op2addr)));
8126 assign(borrow_in, unop(Iop_32Uto64, binop(Iop_Sub32, mkU32(1),
8127 binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)))));
8128 assign(result, binop(Iop_Sub64, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)),
8129 mkexpr(borrow_in)));
8130 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_64, op1, op2, borrow_in);
8131 put_gpr_dw0(r1, mkexpr(result));
8132
8133 return "slbg";
8134}
8135
florian55085f82012-11-21 00:36:55 +00008136static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008137s390_irgen_SVC(UChar i)
8138{
8139 IRTemp sysno = newTemp(Ity_I64);
8140
8141 if (i != 0) {
8142 assign(sysno, mkU64(i));
8143 } else {
8144 assign(sysno, unop(Iop_32Uto64, get_gpr_w1(1)));
8145 }
8146 system_call(mkexpr(sysno));
8147
8148 return "svc";
8149}
8150
florian55085f82012-11-21 00:36:55 +00008151static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008152s390_irgen_TM(UChar i2, IRTemp op1addr)
8153{
8154 UChar mask;
8155 IRTemp value = newTemp(Ity_I8);
8156
8157 mask = i2;
8158 assign(value, load(Ity_I8, mkexpr(op1addr)));
8159 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_8, value, mktemp(Ity_I8,
8160 mkU8(mask)));
8161
8162 return "tm";
8163}
8164
florian55085f82012-11-21 00:36:55 +00008165static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008166s390_irgen_TMY(UChar i2, IRTemp op1addr)
8167{
8168 UChar mask;
8169 IRTemp value = newTemp(Ity_I8);
8170
8171 mask = i2;
8172 assign(value, load(Ity_I8, mkexpr(op1addr)));
8173 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_8, value, mktemp(Ity_I8,
8174 mkU8(mask)));
8175
8176 return "tmy";
8177}
8178
florian55085f82012-11-21 00:36:55 +00008179static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008180s390_irgen_TMHH(UChar r1, UShort i2)
8181{
8182 UShort mask;
8183 IRTemp value = newTemp(Ity_I16);
8184
8185 mask = i2;
8186 assign(value, get_gpr_hw0(r1));
8187 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
8188 mkU16(mask)));
8189
8190 return "tmhh";
8191}
8192
florian55085f82012-11-21 00:36:55 +00008193static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008194s390_irgen_TMHL(UChar r1, UShort i2)
8195{
8196 UShort mask;
8197 IRTemp value = newTemp(Ity_I16);
8198
8199 mask = i2;
8200 assign(value, get_gpr_hw1(r1));
8201 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
8202 mkU16(mask)));
8203
8204 return "tmhl";
8205}
8206
florian55085f82012-11-21 00:36:55 +00008207static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008208s390_irgen_TMLH(UChar r1, UShort i2)
8209{
8210 UShort mask;
8211 IRTemp value = newTemp(Ity_I16);
8212
8213 mask = i2;
8214 assign(value, get_gpr_hw2(r1));
8215 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
8216 mkU16(mask)));
8217
8218 return "tmlh";
8219}
8220
florian55085f82012-11-21 00:36:55 +00008221static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008222s390_irgen_TMLL(UChar r1, UShort i2)
8223{
8224 UShort mask;
8225 IRTemp value = newTemp(Ity_I16);
8226
8227 mask = i2;
8228 assign(value, get_gpr_hw3(r1));
8229 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
8230 mkU16(mask)));
8231
8232 return "tmll";
8233}
8234
florian55085f82012-11-21 00:36:55 +00008235static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008236s390_irgen_EFPC(UChar r1)
8237{
8238 put_gpr_w1(r1, get_fpc_w0());
8239
8240 return "efpc";
8241}
8242
florian55085f82012-11-21 00:36:55 +00008243static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008244s390_irgen_LER(UChar r1, UChar r2)
8245{
8246 put_fpr_w0(r1, get_fpr_w0(r2));
8247
8248 return "ler";
8249}
8250
florian55085f82012-11-21 00:36:55 +00008251static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008252s390_irgen_LDR(UChar r1, UChar r2)
8253{
8254 put_fpr_dw0(r1, get_fpr_dw0(r2));
8255
8256 return "ldr";
8257}
8258
florian55085f82012-11-21 00:36:55 +00008259static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008260s390_irgen_LXR(UChar r1, UChar r2)
8261{
8262 put_fpr_dw0(r1, get_fpr_dw0(r2));
8263 put_fpr_dw0(r1 + 2, get_fpr_dw0(r2 + 2));
8264
8265 return "lxr";
8266}
8267
florian55085f82012-11-21 00:36:55 +00008268static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008269s390_irgen_LE(UChar r1, IRTemp op2addr)
8270{
8271 put_fpr_w0(r1, load(Ity_F32, mkexpr(op2addr)));
8272
8273 return "le";
8274}
8275
florian55085f82012-11-21 00:36:55 +00008276static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008277s390_irgen_LD(UChar r1, IRTemp op2addr)
8278{
8279 put_fpr_dw0(r1, load(Ity_F64, mkexpr(op2addr)));
8280
8281 return "ld";
8282}
8283
florian55085f82012-11-21 00:36:55 +00008284static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008285s390_irgen_LEY(UChar r1, IRTemp op2addr)
8286{
8287 put_fpr_w0(r1, load(Ity_F32, mkexpr(op2addr)));
8288
8289 return "ley";
8290}
8291
florian55085f82012-11-21 00:36:55 +00008292static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008293s390_irgen_LDY(UChar r1, IRTemp op2addr)
8294{
8295 put_fpr_dw0(r1, load(Ity_F64, mkexpr(op2addr)));
8296
8297 return "ldy";
8298}
8299
florian55085f82012-11-21 00:36:55 +00008300static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008301s390_irgen_LFPC(IRTemp op2addr)
8302{
8303 put_fpc_w0(load(Ity_I32, mkexpr(op2addr)));
8304
8305 return "lfpc";
8306}
8307
florian55085f82012-11-21 00:36:55 +00008308static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008309s390_irgen_LZER(UChar r1)
8310{
8311 put_fpr_w0(r1, mkF32i(0x0));
8312
8313 return "lzer";
8314}
8315
florian55085f82012-11-21 00:36:55 +00008316static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008317s390_irgen_LZDR(UChar r1)
8318{
8319 put_fpr_dw0(r1, mkF64i(0x0));
8320
8321 return "lzdr";
8322}
8323
florian55085f82012-11-21 00:36:55 +00008324static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008325s390_irgen_LZXR(UChar r1)
8326{
8327 put_fpr_dw0(r1, mkF64i(0x0));
8328 put_fpr_dw0(r1 + 2, mkF64i(0x0));
8329
8330 return "lzxr";
8331}
8332
florian55085f82012-11-21 00:36:55 +00008333static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008334s390_irgen_SRNM(IRTemp op2addr)
8335{
florianf0fa1be2012-09-18 20:24:38 +00008336 UInt input_mask, fpc_mask;
sewardj2019a972011-03-07 16:04:07 +00008337
florianf0fa1be2012-09-18 20:24:38 +00008338 input_mask = 3;
8339 fpc_mask = s390_host_has_fpext ? 7 : 3;
sewardj2019a972011-03-07 16:04:07 +00008340
florianf0fa1be2012-09-18 20:24:38 +00008341 put_fpc_w0(binop(Iop_Or32,
8342 binop(Iop_And32, get_fpc_w0(), mkU32(~fpc_mask)),
8343 binop(Iop_And32, unop(Iop_64to32, mkexpr(op2addr)),
8344 mkU32(input_mask))));
sewardj2019a972011-03-07 16:04:07 +00008345 return "srnm";
8346}
8347
florian55085f82012-11-21 00:36:55 +00008348static const HChar *
florianf0fa1be2012-09-18 20:24:38 +00008349s390_irgen_SRNMB(IRTemp op2addr)
8350{
8351 UInt input_mask, fpc_mask;
8352
8353 input_mask = 7;
8354 fpc_mask = 7;
8355
8356 put_fpc_w0(binop(Iop_Or32,
8357 binop(Iop_And32, get_fpc_w0(), mkU32(~fpc_mask)),
8358 binop(Iop_And32, unop(Iop_64to32, mkexpr(op2addr)),
8359 mkU32(input_mask))));
8360 return "srnmb";
8361}
8362
florian81a4bfe2012-09-20 01:25:28 +00008363static void
florianf0fa1be2012-09-18 20:24:38 +00008364s390_irgen_srnmb_wrapper(UChar b2, UShort d2)
8365{
8366 if (b2 == 0) { /* This is the typical case */
8367 if (d2 > 3) {
8368 if (s390_host_has_fpext && d2 == 7) {
8369 /* ok */
8370 } else {
8371 emulation_warning(EmWarn_S390X_invalid_rounding);
florian125e20d2012-10-07 15:42:37 +00008372 d2 = S390_FPC_BFP_ROUND_NEAREST_EVEN;
florianf0fa1be2012-09-18 20:24:38 +00008373 }
8374 }
8375 }
8376
8377 s390_format_S_RD(s390_irgen_SRNMB, b2, d2);
8378}
8379
8380
florian55085f82012-11-21 00:36:55 +00008381static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008382s390_irgen_SFPC(UChar r1)
8383{
8384 put_fpc_w0(get_gpr_w1(r1));
8385
8386 return "sfpc";
8387}
8388
florian55085f82012-11-21 00:36:55 +00008389static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008390s390_irgen_STE(UChar r1, IRTemp op2addr)
8391{
8392 store(mkexpr(op2addr), get_fpr_w0(r1));
8393
8394 return "ste";
8395}
8396
florian55085f82012-11-21 00:36:55 +00008397static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008398s390_irgen_STD(UChar r1, IRTemp op2addr)
8399{
8400 store(mkexpr(op2addr), get_fpr_dw0(r1));
8401
8402 return "std";
8403}
8404
florian55085f82012-11-21 00:36:55 +00008405static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008406s390_irgen_STEY(UChar r1, IRTemp op2addr)
8407{
8408 store(mkexpr(op2addr), get_fpr_w0(r1));
8409
8410 return "stey";
8411}
8412
florian55085f82012-11-21 00:36:55 +00008413static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008414s390_irgen_STDY(UChar r1, IRTemp op2addr)
8415{
8416 store(mkexpr(op2addr), get_fpr_dw0(r1));
8417
8418 return "stdy";
8419}
8420
florian55085f82012-11-21 00:36:55 +00008421static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008422s390_irgen_STFPC(IRTemp op2addr)
8423{
8424 store(mkexpr(op2addr), get_fpc_w0());
8425
8426 return "stfpc";
8427}
8428
florian55085f82012-11-21 00:36:55 +00008429static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008430s390_irgen_AEBR(UChar r1, UChar r2)
8431{
8432 IRTemp op1 = newTemp(Ity_F32);
8433 IRTemp op2 = newTemp(Ity_F32);
8434 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00008435 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008436
8437 assign(op1, get_fpr_w0(r1));
8438 assign(op2, get_fpr_w0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008439 assign(result, triop(Iop_AddF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008440 mkexpr(op2)));
8441 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
8442 put_fpr_w0(r1, mkexpr(result));
8443
8444 return "aebr";
8445}
8446
florian55085f82012-11-21 00:36:55 +00008447static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008448s390_irgen_ADBR(UChar r1, UChar r2)
8449{
8450 IRTemp op1 = newTemp(Ity_F64);
8451 IRTemp op2 = newTemp(Ity_F64);
8452 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00008453 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008454
8455 assign(op1, get_fpr_dw0(r1));
8456 assign(op2, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008457 assign(result, triop(Iop_AddF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008458 mkexpr(op2)));
8459 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
8460 put_fpr_dw0(r1, mkexpr(result));
8461
8462 return "adbr";
8463}
8464
florian55085f82012-11-21 00:36:55 +00008465static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008466s390_irgen_AEB(UChar r1, IRTemp op2addr)
8467{
8468 IRTemp op1 = newTemp(Ity_F32);
8469 IRTemp op2 = newTemp(Ity_F32);
8470 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00008471 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008472
8473 assign(op1, get_fpr_w0(r1));
8474 assign(op2, load(Ity_F32, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00008475 assign(result, triop(Iop_AddF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008476 mkexpr(op2)));
8477 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
8478 put_fpr_w0(r1, mkexpr(result));
8479
8480 return "aeb";
8481}
8482
florian55085f82012-11-21 00:36:55 +00008483static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008484s390_irgen_ADB(UChar r1, IRTemp op2addr)
8485{
8486 IRTemp op1 = newTemp(Ity_F64);
8487 IRTemp op2 = newTemp(Ity_F64);
8488 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00008489 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008490
8491 assign(op1, get_fpr_dw0(r1));
8492 assign(op2, load(Ity_F64, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00008493 assign(result, triop(Iop_AddF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008494 mkexpr(op2)));
8495 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
8496 put_fpr_dw0(r1, mkexpr(result));
8497
8498 return "adb";
8499}
8500
florian55085f82012-11-21 00:36:55 +00008501static const HChar *
florian4b8efad2012-09-02 18:07:08 +00008502s390_irgen_CEFBR(UChar m3, UChar m4 __attribute__((unused)),
8503 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008504{
florian125e20d2012-10-07 15:42:37 +00008505 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian4b8efad2012-09-02 18:07:08 +00008506 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +00008507 m3 = S390_BFP_ROUND_PER_FPC;
florian4b8efad2012-09-02 18:07:08 +00008508 }
sewardj2019a972011-03-07 16:04:07 +00008509 IRTemp op2 = newTemp(Ity_I32);
8510
8511 assign(op2, get_gpr_w1(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008512 put_fpr_w0(r1, binop(Iop_I32StoF32, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +00008513 mkexpr(op2)));
sewardj2019a972011-03-07 16:04:07 +00008514
8515 return "cefbr";
8516}
8517
florian55085f82012-11-21 00:36:55 +00008518static const HChar *
florian4b8efad2012-09-02 18:07:08 +00008519s390_irgen_CDFBR(UChar m3 __attribute__((unused)),
8520 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008521{
8522 IRTemp op2 = newTemp(Ity_I32);
8523
8524 assign(op2, get_gpr_w1(r2));
8525 put_fpr_dw0(r1, unop(Iop_I32StoF64, mkexpr(op2)));
8526
8527 return "cdfbr";
8528}
8529
florian55085f82012-11-21 00:36:55 +00008530static const HChar *
florian4b8efad2012-09-02 18:07:08 +00008531s390_irgen_CEGBR(UChar m3, UChar m4 __attribute__((unused)),
8532 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008533{
florian125e20d2012-10-07 15:42:37 +00008534 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian4b8efad2012-09-02 18:07:08 +00008535 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +00008536 m3 = S390_BFP_ROUND_PER_FPC;
florian4b8efad2012-09-02 18:07:08 +00008537 }
sewardj2019a972011-03-07 16:04:07 +00008538 IRTemp op2 = newTemp(Ity_I64);
8539
8540 assign(op2, get_gpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008541 put_fpr_w0(r1, binop(Iop_I64StoF32, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +00008542 mkexpr(op2)));
sewardj2019a972011-03-07 16:04:07 +00008543
8544 return "cegbr";
8545}
8546
florian55085f82012-11-21 00:36:55 +00008547static const HChar *
florian4b8efad2012-09-02 18:07:08 +00008548s390_irgen_CDGBR(UChar m3, UChar m4 __attribute__((unused)),
8549 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008550{
florian125e20d2012-10-07 15:42:37 +00008551 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian4b8efad2012-09-02 18:07:08 +00008552 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +00008553 m3 = S390_BFP_ROUND_PER_FPC;
florian4b8efad2012-09-02 18:07:08 +00008554 }
sewardj2019a972011-03-07 16:04:07 +00008555 IRTemp op2 = newTemp(Ity_I64);
8556
8557 assign(op2, get_gpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008558 put_fpr_dw0(r1, binop(Iop_I64StoF64, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +00008559 mkexpr(op2)));
sewardj2019a972011-03-07 16:04:07 +00008560
8561 return "cdgbr";
8562}
8563
florian55085f82012-11-21 00:36:55 +00008564static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00008565s390_irgen_CELFBR(UChar m3, UChar m4 __attribute__((unused)),
8566 UChar r1, UChar r2)
8567{
floriane75dafa2012-09-01 17:54:09 +00008568 if (! s390_host_has_fpext) {
8569 emulation_failure(EmFail_S390X_fpext);
8570 } else {
8571 IRTemp op2 = newTemp(Ity_I32);
florian1c8f7ff2012-09-01 00:12:11 +00008572
floriane75dafa2012-09-01 17:54:09 +00008573 assign(op2, get_gpr_w1(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008574 put_fpr_w0(r1, binop(Iop_I32UtoF32, mkexpr(encode_bfp_rounding_mode(m3)),
floriane75dafa2012-09-01 17:54:09 +00008575 mkexpr(op2)));
8576 }
florian1c8f7ff2012-09-01 00:12:11 +00008577 return "celfbr";
8578}
8579
florian55085f82012-11-21 00:36:55 +00008580static const HChar *
floriand2129202012-09-01 20:01:39 +00008581s390_irgen_CDLFBR(UChar m3 __attribute__((unused)),
8582 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
florian1c8f7ff2012-09-01 00:12:11 +00008583{
floriane75dafa2012-09-01 17:54:09 +00008584 if (! s390_host_has_fpext) {
8585 emulation_failure(EmFail_S390X_fpext);
8586 } else {
8587 IRTemp op2 = newTemp(Ity_I32);
florian1c8f7ff2012-09-01 00:12:11 +00008588
floriane75dafa2012-09-01 17:54:09 +00008589 assign(op2, get_gpr_w1(r2));
8590 put_fpr_dw0(r1, unop(Iop_I32UtoF64, mkexpr(op2)));
8591 }
florian1c8f7ff2012-09-01 00:12:11 +00008592 return "cdlfbr";
8593}
8594
florian55085f82012-11-21 00:36:55 +00008595static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00008596s390_irgen_CELGBR(UChar m3, UChar m4 __attribute__((unused)),
8597 UChar r1, UChar r2)
8598{
floriane75dafa2012-09-01 17:54:09 +00008599 if (! s390_host_has_fpext) {
8600 emulation_failure(EmFail_S390X_fpext);
8601 } else {
8602 IRTemp op2 = newTemp(Ity_I64);
florian1c8f7ff2012-09-01 00:12:11 +00008603
floriane75dafa2012-09-01 17:54:09 +00008604 assign(op2, get_gpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008605 put_fpr_w0(r1, binop(Iop_I64UtoF32, mkexpr(encode_bfp_rounding_mode(m3)),
floriane75dafa2012-09-01 17:54:09 +00008606 mkexpr(op2)));
8607 }
florian1c8f7ff2012-09-01 00:12:11 +00008608 return "celgbr";
8609}
8610
florian55085f82012-11-21 00:36:55 +00008611static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00008612s390_irgen_CDLGBR(UChar m3, UChar m4 __attribute__((unused)),
8613 UChar r1, UChar r2)
8614{
floriane75dafa2012-09-01 17:54:09 +00008615 if (! s390_host_has_fpext) {
8616 emulation_failure(EmFail_S390X_fpext);
8617 } else {
8618 IRTemp op2 = newTemp(Ity_I64);
florian1c8f7ff2012-09-01 00:12:11 +00008619
floriane75dafa2012-09-01 17:54:09 +00008620 assign(op2, get_gpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008621 put_fpr_dw0(r1, binop(Iop_I64UtoF64,
8622 mkexpr(encode_bfp_rounding_mode(m3)),
floriane75dafa2012-09-01 17:54:09 +00008623 mkexpr(op2)));
8624 }
florian1c8f7ff2012-09-01 00:12:11 +00008625 return "cdlgbr";
8626}
8627
florian55085f82012-11-21 00:36:55 +00008628static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00008629s390_irgen_CLFEBR(UChar m3, UChar m4 __attribute__((unused)),
8630 UChar r1, UChar r2)
8631{
floriane75dafa2012-09-01 17:54:09 +00008632 if (! s390_host_has_fpext) {
8633 emulation_failure(EmFail_S390X_fpext);
8634 } else {
8635 IRTemp op = newTemp(Ity_F32);
8636 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +00008637 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +00008638
floriane75dafa2012-09-01 17:54:09 +00008639 assign(op, get_fpr_w0(r2));
florian19e00772012-09-06 03:13:22 +00008640 assign(result, binop(Iop_F32toI32U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +00008641 mkexpr(op)));
8642 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008643 s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_UINT_32, op, rounding_mode);
floriane75dafa2012-09-01 17:54:09 +00008644 }
florian1c8f7ff2012-09-01 00:12:11 +00008645 return "clfebr";
8646}
8647
florian55085f82012-11-21 00:36:55 +00008648static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00008649s390_irgen_CLFDBR(UChar m3, UChar m4 __attribute__((unused)),
8650 UChar r1, UChar r2)
8651{
floriane75dafa2012-09-01 17:54:09 +00008652 if (! s390_host_has_fpext) {
8653 emulation_failure(EmFail_S390X_fpext);
8654 } else {
8655 IRTemp op = newTemp(Ity_F64);
8656 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +00008657 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +00008658
floriane75dafa2012-09-01 17:54:09 +00008659 assign(op, get_fpr_dw0(r2));
florian19e00772012-09-06 03:13:22 +00008660 assign(result, binop(Iop_F64toI32U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +00008661 mkexpr(op)));
8662 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008663 s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_UINT_32, op, rounding_mode);
floriane75dafa2012-09-01 17:54:09 +00008664 }
florian1c8f7ff2012-09-01 00:12:11 +00008665 return "clfdbr";
8666}
8667
florian55085f82012-11-21 00:36:55 +00008668static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00008669s390_irgen_CLGEBR(UChar m3, UChar m4 __attribute__((unused)),
8670 UChar r1, UChar r2)
8671{
floriane75dafa2012-09-01 17:54:09 +00008672 if (! s390_host_has_fpext) {
8673 emulation_failure(EmFail_S390X_fpext);
8674 } else {
8675 IRTemp op = newTemp(Ity_F32);
8676 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +00008677 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +00008678
floriane75dafa2012-09-01 17:54:09 +00008679 assign(op, get_fpr_w0(r2));
florian19e00772012-09-06 03:13:22 +00008680 assign(result, binop(Iop_F32toI64U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +00008681 mkexpr(op)));
8682 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008683 s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_UINT_64, op, rounding_mode);
floriane75dafa2012-09-01 17:54:09 +00008684 }
florian1c8f7ff2012-09-01 00:12:11 +00008685 return "clgebr";
8686}
8687
florian55085f82012-11-21 00:36:55 +00008688static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00008689s390_irgen_CLGDBR(UChar m3, UChar m4 __attribute__((unused)),
8690 UChar r1, UChar r2)
8691{
floriane75dafa2012-09-01 17:54:09 +00008692 if (! s390_host_has_fpext) {
8693 emulation_failure(EmFail_S390X_fpext);
8694 } else {
8695 IRTemp op = newTemp(Ity_F64);
8696 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +00008697 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +00008698
floriane75dafa2012-09-01 17:54:09 +00008699 assign(op, get_fpr_dw0(r2));
florian19e00772012-09-06 03:13:22 +00008700 assign(result, binop(Iop_F64toI64U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +00008701 mkexpr(op)));
8702 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008703 s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_UINT_64, op, rounding_mode);
floriane75dafa2012-09-01 17:54:09 +00008704 }
florian1c8f7ff2012-09-01 00:12:11 +00008705 return "clgdbr";
8706}
8707
florian55085f82012-11-21 00:36:55 +00008708static const HChar *
florian4b8efad2012-09-02 18:07:08 +00008709s390_irgen_CFEBR(UChar m3, UChar m4 __attribute__((unused)),
8710 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008711{
8712 IRTemp op = newTemp(Ity_F32);
8713 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +00008714 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +00008715
8716 assign(op, get_fpr_w0(r2));
florian19e00772012-09-06 03:13:22 +00008717 assign(result, binop(Iop_F32toI32S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +00008718 mkexpr(op)));
8719 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008720 s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_INT_32, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +00008721
8722 return "cfebr";
8723}
8724
florian55085f82012-11-21 00:36:55 +00008725static const HChar *
florian4b8efad2012-09-02 18:07:08 +00008726s390_irgen_CFDBR(UChar m3, UChar m4 __attribute__((unused)),
8727 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008728{
8729 IRTemp op = newTemp(Ity_F64);
8730 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +00008731 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +00008732
8733 assign(op, get_fpr_dw0(r2));
florian19e00772012-09-06 03:13:22 +00008734 assign(result, binop(Iop_F64toI32S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +00008735 mkexpr(op)));
8736 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008737 s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_INT_32, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +00008738
8739 return "cfdbr";
8740}
8741
florian55085f82012-11-21 00:36:55 +00008742static const HChar *
florian4b8efad2012-09-02 18:07:08 +00008743s390_irgen_CGEBR(UChar m3, UChar m4 __attribute__((unused)),
8744 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008745{
8746 IRTemp op = newTemp(Ity_F32);
8747 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +00008748 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +00008749
8750 assign(op, get_fpr_w0(r2));
florian19e00772012-09-06 03:13:22 +00008751 assign(result, binop(Iop_F32toI64S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +00008752 mkexpr(op)));
8753 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008754 s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_INT_64, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +00008755
8756 return "cgebr";
8757}
8758
florian55085f82012-11-21 00:36:55 +00008759static const HChar *
florian4b8efad2012-09-02 18:07:08 +00008760s390_irgen_CGDBR(UChar m3, UChar m4 __attribute__((unused)),
8761 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008762{
8763 IRTemp op = newTemp(Ity_F64);
8764 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +00008765 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +00008766
8767 assign(op, get_fpr_dw0(r2));
florian19e00772012-09-06 03:13:22 +00008768 assign(result, binop(Iop_F64toI64S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +00008769 mkexpr(op)));
8770 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008771 s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_INT_64, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +00008772
8773 return "cgdbr";
8774}
8775
florian55085f82012-11-21 00:36:55 +00008776static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008777s390_irgen_DEBR(UChar r1, UChar r2)
8778{
8779 IRTemp op1 = newTemp(Ity_F32);
8780 IRTemp op2 = newTemp(Ity_F32);
8781 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00008782 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008783
8784 assign(op1, get_fpr_w0(r1));
8785 assign(op2, get_fpr_w0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008786 assign(result, triop(Iop_DivF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008787 mkexpr(op2)));
8788 put_fpr_w0(r1, mkexpr(result));
8789
8790 return "debr";
8791}
8792
florian55085f82012-11-21 00:36:55 +00008793static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008794s390_irgen_DDBR(UChar r1, UChar r2)
8795{
8796 IRTemp op1 = newTemp(Ity_F64);
8797 IRTemp op2 = newTemp(Ity_F64);
8798 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00008799 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008800
8801 assign(op1, get_fpr_dw0(r1));
8802 assign(op2, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008803 assign(result, triop(Iop_DivF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008804 mkexpr(op2)));
8805 put_fpr_dw0(r1, mkexpr(result));
8806
8807 return "ddbr";
8808}
8809
florian55085f82012-11-21 00:36:55 +00008810static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008811s390_irgen_DEB(UChar r1, IRTemp op2addr)
8812{
8813 IRTemp op1 = newTemp(Ity_F32);
8814 IRTemp op2 = newTemp(Ity_F32);
8815 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00008816 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008817
8818 assign(op1, get_fpr_w0(r1));
8819 assign(op2, load(Ity_F32, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00008820 assign(result, triop(Iop_DivF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008821 mkexpr(op2)));
8822 put_fpr_w0(r1, mkexpr(result));
8823
8824 return "deb";
8825}
8826
florian55085f82012-11-21 00:36:55 +00008827static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008828s390_irgen_DDB(UChar r1, IRTemp op2addr)
8829{
8830 IRTemp op1 = newTemp(Ity_F64);
8831 IRTemp op2 = newTemp(Ity_F64);
8832 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00008833 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008834
8835 assign(op1, get_fpr_dw0(r1));
8836 assign(op2, load(Ity_F64, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00008837 assign(result, triop(Iop_DivF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008838 mkexpr(op2)));
8839 put_fpr_dw0(r1, mkexpr(result));
8840
8841 return "ddb";
8842}
8843
florian55085f82012-11-21 00:36:55 +00008844static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008845s390_irgen_LTEBR(UChar r1, UChar r2)
8846{
8847 IRTemp result = newTemp(Ity_F32);
8848
8849 assign(result, get_fpr_w0(r2));
8850 put_fpr_w0(r1, mkexpr(result));
8851 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
8852
8853 return "ltebr";
8854}
8855
florian55085f82012-11-21 00:36:55 +00008856static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008857s390_irgen_LTDBR(UChar r1, UChar r2)
8858{
8859 IRTemp result = newTemp(Ity_F64);
8860
8861 assign(result, get_fpr_dw0(r2));
8862 put_fpr_dw0(r1, mkexpr(result));
8863 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
8864
8865 return "ltdbr";
8866}
8867
florian55085f82012-11-21 00:36:55 +00008868static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008869s390_irgen_LCEBR(UChar r1, UChar r2)
8870{
8871 IRTemp result = newTemp(Ity_F32);
8872
8873 assign(result, unop(Iop_NegF32, get_fpr_w0(r2)));
8874 put_fpr_w0(r1, mkexpr(result));
8875 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
8876
8877 return "lcebr";
8878}
8879
florian55085f82012-11-21 00:36:55 +00008880static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008881s390_irgen_LCDBR(UChar r1, UChar r2)
8882{
8883 IRTemp result = newTemp(Ity_F64);
8884
8885 assign(result, unop(Iop_NegF64, get_fpr_dw0(r2)));
8886 put_fpr_dw0(r1, mkexpr(result));
8887 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
8888
8889 return "lcdbr";
8890}
8891
florian55085f82012-11-21 00:36:55 +00008892static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008893s390_irgen_LDEBR(UChar r1, UChar r2)
8894{
8895 IRTemp op = newTemp(Ity_F32);
8896
8897 assign(op, get_fpr_w0(r2));
8898 put_fpr_dw0(r1, unop(Iop_F32toF64, mkexpr(op)));
8899
8900 return "ldebr";
8901}
8902
florian55085f82012-11-21 00:36:55 +00008903static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008904s390_irgen_LDEB(UChar r1, IRTemp op2addr)
8905{
8906 IRTemp op = newTemp(Ity_F32);
8907
8908 assign(op, load(Ity_F32, mkexpr(op2addr)));
8909 put_fpr_dw0(r1, unop(Iop_F32toF64, mkexpr(op)));
8910
8911 return "ldeb";
8912}
8913
florian55085f82012-11-21 00:36:55 +00008914static const HChar *
florian4b8efad2012-09-02 18:07:08 +00008915s390_irgen_LEDBR(UChar m3, UChar m4 __attribute__((unused)),
8916 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008917{
florian125e20d2012-10-07 15:42:37 +00008918 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian12b0bca2012-09-05 20:05:20 +00008919 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +00008920 m3 = S390_BFP_ROUND_PER_FPC;
florian12b0bca2012-09-05 20:05:20 +00008921 }
sewardj2019a972011-03-07 16:04:07 +00008922 IRTemp op = newTemp(Ity_F64);
8923
8924 assign(op, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008925 put_fpr_w0(r1, binop(Iop_F64toF32, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +00008926 mkexpr(op)));
sewardj2019a972011-03-07 16:04:07 +00008927
8928 return "ledbr";
8929}
8930
florian55085f82012-11-21 00:36:55 +00008931static const HChar *
florian12390202012-11-10 22:34:14 +00008932s390_irgen_LTDTR(UChar r1, UChar r2)
8933{
8934 IRTemp result = newTemp(Ity_D64);
8935
8936 assign(result, get_dpr_dw0(r2));
8937 put_dpr_dw0(r1, mkexpr(result));
8938 s390_cc_thunk_putF(S390_CC_OP_DFP_RESULT_64, result);
8939
8940 return "ltdtr";
8941}
8942
florian55085f82012-11-21 00:36:55 +00008943static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008944s390_irgen_MEEBR(UChar r1, UChar r2)
8945{
8946 IRTemp op1 = newTemp(Ity_F32);
8947 IRTemp op2 = newTemp(Ity_F32);
8948 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00008949 IRRoundingMode rounding_mode =
8950 encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008951
8952 assign(op1, get_fpr_w0(r1));
8953 assign(op2, get_fpr_w0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008954 assign(result, triop(Iop_MulF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008955 mkexpr(op2)));
8956 put_fpr_w0(r1, mkexpr(result));
8957
8958 return "meebr";
8959}
8960
florian55085f82012-11-21 00:36:55 +00008961static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008962s390_irgen_MDBR(UChar r1, UChar r2)
8963{
8964 IRTemp op1 = newTemp(Ity_F64);
8965 IRTemp op2 = newTemp(Ity_F64);
8966 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00008967 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008968
8969 assign(op1, get_fpr_dw0(r1));
8970 assign(op2, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008971 assign(result, triop(Iop_MulF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008972 mkexpr(op2)));
8973 put_fpr_dw0(r1, mkexpr(result));
8974
8975 return "mdbr";
8976}
8977
florian55085f82012-11-21 00:36:55 +00008978static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008979s390_irgen_MEEB(UChar r1, IRTemp op2addr)
8980{
8981 IRTemp op1 = newTemp(Ity_F32);
8982 IRTemp op2 = newTemp(Ity_F32);
8983 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00008984 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008985
8986 assign(op1, get_fpr_w0(r1));
8987 assign(op2, load(Ity_F32, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00008988 assign(result, triop(Iop_MulF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008989 mkexpr(op2)));
8990 put_fpr_w0(r1, mkexpr(result));
8991
8992 return "meeb";
8993}
8994
florian55085f82012-11-21 00:36:55 +00008995static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008996s390_irgen_MDB(UChar r1, IRTemp op2addr)
8997{
8998 IRTemp op1 = newTemp(Ity_F64);
8999 IRTemp op2 = newTemp(Ity_F64);
9000 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00009001 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009002
9003 assign(op1, get_fpr_dw0(r1));
9004 assign(op2, load(Ity_F64, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00009005 assign(result, triop(Iop_MulF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009006 mkexpr(op2)));
9007 put_fpr_dw0(r1, mkexpr(result));
9008
9009 return "mdb";
9010}
9011
florian55085f82012-11-21 00:36:55 +00009012static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009013s390_irgen_SEBR(UChar r1, UChar r2)
9014{
9015 IRTemp op1 = newTemp(Ity_F32);
9016 IRTemp op2 = newTemp(Ity_F32);
9017 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00009018 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009019
9020 assign(op1, get_fpr_w0(r1));
9021 assign(op2, get_fpr_w0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009022 assign(result, triop(Iop_SubF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009023 mkexpr(op2)));
9024 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
9025 put_fpr_w0(r1, mkexpr(result));
9026
9027 return "sebr";
9028}
9029
florian55085f82012-11-21 00:36:55 +00009030static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009031s390_irgen_SDBR(UChar r1, UChar r2)
9032{
9033 IRTemp op1 = newTemp(Ity_F64);
9034 IRTemp op2 = newTemp(Ity_F64);
9035 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00009036 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009037
9038 assign(op1, get_fpr_dw0(r1));
9039 assign(op2, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009040 assign(result, triop(Iop_SubF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009041 mkexpr(op2)));
9042 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
9043 put_fpr_dw0(r1, mkexpr(result));
9044
9045 return "sdbr";
9046}
9047
florian55085f82012-11-21 00:36:55 +00009048static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009049s390_irgen_SEB(UChar r1, IRTemp op2addr)
9050{
9051 IRTemp op1 = newTemp(Ity_F32);
9052 IRTemp op2 = newTemp(Ity_F32);
9053 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00009054 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009055
9056 assign(op1, get_fpr_w0(r1));
9057 assign(op2, load(Ity_F32, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00009058 assign(result, triop(Iop_SubF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009059 mkexpr(op2)));
9060 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
9061 put_fpr_w0(r1, mkexpr(result));
9062
9063 return "seb";
9064}
9065
florian55085f82012-11-21 00:36:55 +00009066static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009067s390_irgen_SDB(UChar r1, IRTemp op2addr)
9068{
9069 IRTemp op1 = newTemp(Ity_F64);
9070 IRTemp op2 = newTemp(Ity_F64);
9071 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00009072 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009073
9074 assign(op1, get_fpr_dw0(r1));
9075 assign(op2, load(Ity_F64, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00009076 assign(result, triop(Iop_SubF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009077 mkexpr(op2)));
9078 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
9079 put_fpr_dw0(r1, mkexpr(result));
9080
9081 return "sdb";
9082}
9083
florian55085f82012-11-21 00:36:55 +00009084static const HChar *
florian12390202012-11-10 22:34:14 +00009085s390_irgen_ADTRA(UChar r3, UChar m4, UChar r1, UChar r2)
9086{
9087 IRTemp op1 = newTemp(Ity_D64);
9088 IRTemp op2 = newTemp(Ity_D64);
9089 IRTemp result = newTemp(Ity_D64);
9090 IRTemp rounding_mode;
9091
9092 vassert(s390_host_has_dfp);
9093 vassert(m4 == 0 || s390_host_has_fpext);
9094 /* when m4 = 0, S390_DFP_ROUND_PER_FPC_0 should be set.
9095 since S390_DFP_ROUND_PER_FPC_0 is also 0, passing m4 is sufficient */
9096 rounding_mode = encode_dfp_rounding_mode(m4);
9097 assign(op1, get_dpr_dw0(r2));
9098 assign(op2, get_dpr_dw0(r3));
9099 assign(result, triop(Iop_AddD64, mkexpr(rounding_mode), mkexpr(op1),
9100 mkexpr(op2)));
9101 s390_cc_thunk_putF(S390_CC_OP_DFP_RESULT_64, result);
9102 put_dpr_dw0(r1, mkexpr(result));
9103
9104 return (m4 == 0) ? "adtr" : "adtra";
9105}
9106
florian55085f82012-11-21 00:36:55 +00009107static const HChar *
florian12390202012-11-10 22:34:14 +00009108s390_irgen_DDTRA(UChar r3, UChar m4, UChar r1, UChar r2)
9109{
9110 IRTemp op1 = newTemp(Ity_D64);
9111 IRTemp op2 = newTemp(Ity_D64);
9112 IRTemp result = newTemp(Ity_D64);
9113 IRTemp rounding_mode;
9114
9115 vassert(s390_host_has_dfp);
9116 vassert(m4 == 0 || s390_host_has_fpext);
9117 /* when m4 = 0, S390_DFP_ROUND_PER_FPC_0 should be set.
9118 since S390_DFP_ROUND_PER_FPC_0 is also 0, passing m4 is sufficient */
9119 rounding_mode = encode_dfp_rounding_mode(m4);
9120 assign(op1, get_dpr_dw0(r2));
9121 assign(op2, get_dpr_dw0(r3));
9122 assign(result, triop(Iop_DivD64, mkexpr(rounding_mode), mkexpr(op1),
9123 mkexpr(op2)));
9124 s390_cc_thunk_putF(S390_CC_OP_DFP_RESULT_64, result);
9125 put_dpr_dw0(r1, mkexpr(result));
9126
9127 return (m4 == 0) ? "ddtr" : "ddtra";
9128}
9129
florian55085f82012-11-21 00:36:55 +00009130static const HChar *
florian12390202012-11-10 22:34:14 +00009131s390_irgen_MDTRA(UChar r3, UChar m4, UChar r1, UChar r2)
9132{
9133 IRTemp op1 = newTemp(Ity_D64);
9134 IRTemp op2 = newTemp(Ity_D64);
9135 IRTemp result = newTemp(Ity_D64);
9136 IRTemp rounding_mode;
9137
9138 vassert(s390_host_has_dfp);
9139 vassert(m4 == 0 || s390_host_has_fpext);
9140 /* when m4 = 0, S390_DFP_ROUND_PER_FPC_0 should be set.
9141 since S390_DFP_ROUND_PER_FPC_0 is also 0, passing m4 is sufficient */
9142 rounding_mode = encode_dfp_rounding_mode(m4);
9143 assign(op1, get_dpr_dw0(r2));
9144 assign(op2, get_dpr_dw0(r3));
9145 assign(result, triop(Iop_MulD64, mkexpr(rounding_mode), mkexpr(op1),
9146 mkexpr(op2)));
9147 s390_cc_thunk_putF(S390_CC_OP_DFP_RESULT_64, result);
9148 put_dpr_dw0(r1, mkexpr(result));
9149
9150 return (m4 == 0) ? "mdtr" : "mdtra";
9151}
9152
florian55085f82012-11-21 00:36:55 +00009153static const HChar *
florian12390202012-11-10 22:34:14 +00009154s390_irgen_SDTRA(UChar r3, UChar m4, UChar r1, UChar r2)
9155{
9156 IRTemp op1 = newTemp(Ity_D64);
9157 IRTemp op2 = newTemp(Ity_D64);
9158 IRTemp result = newTemp(Ity_D64);
9159 IRTemp rounding_mode;
9160
9161 vassert(s390_host_has_dfp);
9162 vassert(m4 == 0 || s390_host_has_fpext);
9163 /* when m4 = 0, S390_DFP_ROUND_PER_FPC_0 should be set.
9164 since S390_DFP_ROUND_PER_FPC_0 is also 0, passing m4 is sufficient */
9165 rounding_mode = encode_dfp_rounding_mode(m4);
9166 assign(op1, get_dpr_dw0(r2));
9167 assign(op2, get_dpr_dw0(r3));
9168 assign(result, triop(Iop_SubD64, mkexpr(rounding_mode), mkexpr(op1),
9169 mkexpr(op2)));
9170 s390_cc_thunk_putF(S390_CC_OP_DFP_RESULT_64, result);
9171 put_dpr_dw0(r1, mkexpr(result));
9172
9173 return (m4 == 0) ? "sdtr" : "sdtra";
9174}
9175
sewardj2019a972011-03-07 16:04:07 +00009176
florian55085f82012-11-21 00:36:55 +00009177static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009178s390_irgen_CLC(UChar length, IRTemp start1, IRTemp start2)
9179{
florian79e839e2012-05-05 02:20:30 +00009180 IRTemp len = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00009181
florian79e839e2012-05-05 02:20:30 +00009182 assign(len, mkU64(length));
9183 s390_irgen_CLC_EX(len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +00009184
9185 return "clc";
9186}
9187
florian55085f82012-11-21 00:36:55 +00009188static const HChar *
florianb0c9a132011-09-08 15:37:39 +00009189s390_irgen_CLCL(UChar r1, UChar r2)
9190{
9191 IRTemp addr1 = newTemp(Ity_I64);
9192 IRTemp addr2 = newTemp(Ity_I64);
9193 IRTemp addr1_load = newTemp(Ity_I64);
9194 IRTemp addr2_load = newTemp(Ity_I64);
9195 IRTemp len1 = newTemp(Ity_I32);
9196 IRTemp len2 = newTemp(Ity_I32);
9197 IRTemp r1p1 = newTemp(Ity_I32); /* contents of r1 + 1 */
9198 IRTemp r2p1 = newTemp(Ity_I32); /* contents of r2 + 1 */
9199 IRTemp single1 = newTemp(Ity_I8);
9200 IRTemp single2 = newTemp(Ity_I8);
9201 IRTemp pad = newTemp(Ity_I8);
9202
9203 assign(addr1, get_gpr_dw0(r1));
9204 assign(r1p1, get_gpr_w1(r1 + 1));
9205 assign(len1, binop(Iop_And32, mkexpr(r1p1), mkU32(0x00ffffff)));
9206 assign(addr2, get_gpr_dw0(r2));
9207 assign(r2p1, get_gpr_w1(r2 + 1));
9208 assign(len2, binop(Iop_And32, mkexpr(r2p1), mkU32(0x00ffffff)));
9209 assign(pad, get_gpr_b4(r2 + 1));
9210
9211 /* len1 == 0 and len2 == 0? Exit */
9212 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +00009213 next_insn_if(binop(Iop_CmpEQ32, binop(Iop_Or32, mkexpr(len1),
9214 mkexpr(len2)), mkU32(0)));
florianb0c9a132011-09-08 15:37:39 +00009215
9216 /* Because mkite evaluates both the then-clause and the else-clause
9217 we cannot load directly from addr1 here. If len1 is 0, then adddr1
9218 may be NULL and loading from there would segfault. So we provide a
9219 valid dummy address in that case. Loading from there does no harm and
9220 the value will be discarded at runtime. */
9221 assign(addr1_load,
9222 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
9223 mkU64(guest_IA_curr_instr), mkexpr(addr1)));
9224 assign(single1,
9225 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
9226 mkexpr(pad), load(Ity_I8, mkexpr(addr1_load))));
9227
9228 assign(addr2_load,
9229 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
9230 mkU64(guest_IA_curr_instr), mkexpr(addr2)));
9231 assign(single2,
9232 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
9233 mkexpr(pad), load(Ity_I8, mkexpr(addr2_load))));
9234
9235 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, single1, single2, False);
9236 /* Fields differ ? */
florian6820ba52012-07-26 02:01:50 +00009237 next_insn_if(binop(Iop_CmpNE8, mkexpr(single1), mkexpr(single2)));
florianb0c9a132011-09-08 15:37:39 +00009238
9239 /* Update len1 and addr1, unless len1 == 0. */
9240 put_gpr_dw0(r1,
9241 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
9242 mkexpr(addr1),
9243 binop(Iop_Add64, mkexpr(addr1), mkU64(1))));
9244
9245 /* When updating len1 we must not modify bits (r1+1)[0:39] */
9246 put_gpr_w1(r1 + 1,
9247 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
9248 binop(Iop_And32, mkexpr(r1p1), mkU32(0xFF000000u)),
9249 binop(Iop_Sub32, mkexpr(r1p1), mkU32(1))));
9250
9251 /* Update len2 and addr2, unless len2 == 0. */
9252 put_gpr_dw0(r2,
9253 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
9254 mkexpr(addr2),
9255 binop(Iop_Add64, mkexpr(addr2), mkU64(1))));
9256
9257 /* When updating len2 we must not modify bits (r2+1)[0:39] */
9258 put_gpr_w1(r2 + 1,
9259 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
9260 binop(Iop_And32, mkexpr(r2p1), mkU32(0xFF000000u)),
9261 binop(Iop_Sub32, mkexpr(r2p1), mkU32(1))));
9262
florian6820ba52012-07-26 02:01:50 +00009263 iterate();
florianb0c9a132011-09-08 15:37:39 +00009264
9265 return "clcl";
9266}
9267
florian55085f82012-11-21 00:36:55 +00009268static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009269s390_irgen_CLCLE(UChar r1, UChar r3, IRTemp pad2)
9270{
9271 IRTemp addr1, addr3, addr1_load, addr3_load, len1, len3, single1, single3;
9272
9273 addr1 = newTemp(Ity_I64);
9274 addr3 = newTemp(Ity_I64);
9275 addr1_load = newTemp(Ity_I64);
9276 addr3_load = newTemp(Ity_I64);
9277 len1 = newTemp(Ity_I64);
9278 len3 = newTemp(Ity_I64);
9279 single1 = newTemp(Ity_I8);
9280 single3 = newTemp(Ity_I8);
9281
9282 assign(addr1, get_gpr_dw0(r1));
9283 assign(len1, get_gpr_dw0(r1 + 1));
9284 assign(addr3, get_gpr_dw0(r3));
9285 assign(len3, get_gpr_dw0(r3 + 1));
9286
9287 /* len1 == 0 and len3 == 0? Exit */
9288 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +00009289 next_insn_if(binop(Iop_CmpEQ64,binop(Iop_Or64, mkexpr(len1),
9290 mkexpr(len3)), mkU64(0)));
sewardj2019a972011-03-07 16:04:07 +00009291
9292 /* A mux requires both ways to be possible. This is a way to prevent clcle
9293 from reading from addr1 if it should read from the pad. Since the pad
9294 has no address, just read from the instruction, we discard that anyway */
9295 assign(addr1_load,
florian6ad49522011-09-09 02:38:55 +00009296 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
9297 mkU64(guest_IA_curr_instr), mkexpr(addr1)));
sewardj2019a972011-03-07 16:04:07 +00009298
9299 /* same for addr3 */
9300 assign(addr3_load,
florian6ad49522011-09-09 02:38:55 +00009301 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
9302 mkU64(guest_IA_curr_instr), mkexpr(addr3)));
sewardj2019a972011-03-07 16:04:07 +00009303
9304 assign(single1,
florian6ad49522011-09-09 02:38:55 +00009305 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
9306 unop(Iop_64to8, mkexpr(pad2)),
9307 load(Ity_I8, mkexpr(addr1_load))));
sewardj2019a972011-03-07 16:04:07 +00009308
9309 assign(single3,
florian6ad49522011-09-09 02:38:55 +00009310 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
9311 unop(Iop_64to8, mkexpr(pad2)),
9312 load(Ity_I8, mkexpr(addr3_load))));
sewardj2019a972011-03-07 16:04:07 +00009313
9314 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, single1, single3, False);
9315 /* Both fields differ ? */
florian6820ba52012-07-26 02:01:50 +00009316 next_insn_if(binop(Iop_CmpNE8, mkexpr(single1), mkexpr(single3)));
sewardj2019a972011-03-07 16:04:07 +00009317
9318 /* If a length in 0 we must not change this length and the address */
9319 put_gpr_dw0(r1,
florian6ad49522011-09-09 02:38:55 +00009320 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
9321 mkexpr(addr1),
9322 binop(Iop_Add64, mkexpr(addr1), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +00009323
9324 put_gpr_dw0(r1 + 1,
florian6ad49522011-09-09 02:38:55 +00009325 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
9326 mkU64(0), binop(Iop_Sub64, mkexpr(len1), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +00009327
9328 put_gpr_dw0(r3,
florian6ad49522011-09-09 02:38:55 +00009329 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
9330 mkexpr(addr3),
9331 binop(Iop_Add64, mkexpr(addr3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +00009332
9333 put_gpr_dw0(r3 + 1,
florian6ad49522011-09-09 02:38:55 +00009334 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
9335 mkU64(0), binop(Iop_Sub64, mkexpr(len3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +00009336
florian6820ba52012-07-26 02:01:50 +00009337 iterate();
sewardj2019a972011-03-07 16:04:07 +00009338
9339 return "clcle";
9340}
floriana64c2432011-07-16 02:11:50 +00009341
florianb0bf6602012-05-05 00:01:16 +00009342
sewardj2019a972011-03-07 16:04:07 +00009343static void
9344s390_irgen_XC_EX(IRTemp length, IRTemp start1, IRTemp start2)
9345{
florianb0bf6602012-05-05 00:01:16 +00009346 s390_irgen_xonc(Iop_Xor8, length, start1, start2);
9347}
sewardj2019a972011-03-07 16:04:07 +00009348
sewardj2019a972011-03-07 16:04:07 +00009349
florianb0bf6602012-05-05 00:01:16 +00009350static void
9351s390_irgen_NC_EX(IRTemp length, IRTemp start1, IRTemp start2)
9352{
9353 s390_irgen_xonc(Iop_And8, length, start1, start2);
9354}
sewardj2019a972011-03-07 16:04:07 +00009355
sewardj2019a972011-03-07 16:04:07 +00009356
florianb0bf6602012-05-05 00:01:16 +00009357static void
9358s390_irgen_OC_EX(IRTemp length, IRTemp start1, IRTemp start2)
9359{
9360 s390_irgen_xonc(Iop_Or8, length, start1, start2);
sewardj2019a972011-03-07 16:04:07 +00009361}
9362
9363
9364static void
9365s390_irgen_CLC_EX(IRTemp length, IRTemp start1, IRTemp start2)
9366{
9367 IRTemp current1 = newTemp(Ity_I8);
9368 IRTemp current2 = newTemp(Ity_I8);
9369 IRTemp counter = newTemp(Ity_I64);
9370
9371 assign(counter, get_counter_dw0());
9372 put_counter_dw0(mkU64(0));
9373
9374 assign(current1, load(Ity_I8, binop(Iop_Add64, mkexpr(start1),
9375 mkexpr(counter))));
9376 assign(current2, load(Ity_I8, binop(Iop_Add64, mkexpr(start2),
9377 mkexpr(counter))));
9378 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, current1, current2,
9379 False);
9380
9381 /* Both fields differ ? */
florian6820ba52012-07-26 02:01:50 +00009382 next_insn_if(binop(Iop_CmpNE8, mkexpr(current1), mkexpr(current2)));
sewardj2019a972011-03-07 16:04:07 +00009383
9384 /* Check for end of field */
9385 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
florian6820ba52012-07-26 02:01:50 +00009386 iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)));
sewardj2019a972011-03-07 16:04:07 +00009387 put_counter_dw0(mkU64(0));
9388}
9389
9390static void
9391s390_irgen_MVC_EX(IRTemp length, IRTemp start1, IRTemp start2)
9392{
9393 IRTemp counter = newTemp(Ity_I64);
9394
9395 assign(counter, get_counter_dw0());
9396
9397 store(binop(Iop_Add64, mkexpr(start1), mkexpr(counter)),
9398 load(Ity_I8, binop(Iop_Add64, mkexpr(start2), mkexpr(counter))));
9399
9400 /* Check for end of field */
9401 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
florian6820ba52012-07-26 02:01:50 +00009402 iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)));
sewardj2019a972011-03-07 16:04:07 +00009403 put_counter_dw0(mkU64(0));
9404}
9405
florianf87d4fb2012-05-05 02:55:24 +00009406static void
9407s390_irgen_TR_EX(IRTemp length, IRTemp start1, IRTemp start2)
9408{
9409 IRTemp op = newTemp(Ity_I8);
9410 IRTemp op1 = newTemp(Ity_I8);
9411 IRTemp result = newTemp(Ity_I64);
9412 IRTemp counter = newTemp(Ity_I64);
9413
9414 assign(counter, get_counter_dw0());
9415
9416 assign(op, load(Ity_I8, binop(Iop_Add64, mkexpr(start1), mkexpr(counter))));
9417
9418 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)), mkexpr(start2)));
9419
9420 assign(op1, load(Ity_I8, mkexpr(result)));
9421 store(binop(Iop_Add64, mkexpr(start1), mkexpr(counter)), mkexpr(op1));
9422
9423 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
florian6820ba52012-07-26 02:01:50 +00009424 iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)));
florianf87d4fb2012-05-05 02:55:24 +00009425 put_counter_dw0(mkU64(0));
9426}
sewardj2019a972011-03-07 16:04:07 +00009427
9428
9429static void
9430s390_irgen_EX_SS(UChar r, IRTemp addr2,
florian6820ba52012-07-26 02:01:50 +00009431 void (*irgen)(IRTemp length, IRTemp start1, IRTemp start2),
9432 int lensize)
sewardj2019a972011-03-07 16:04:07 +00009433{
9434 struct SS {
9435 unsigned int op : 8;
9436 unsigned int l : 8;
9437 unsigned int b1 : 4;
9438 unsigned int d1 : 12;
9439 unsigned int b2 : 4;
9440 unsigned int d2 : 12;
9441 };
9442 union {
9443 struct SS dec;
9444 unsigned long bytes;
9445 } ss;
9446 IRTemp cond;
9447 IRDirty *d;
9448 IRTemp torun;
9449
9450 IRTemp start1 = newTemp(Ity_I64);
9451 IRTemp start2 = newTemp(Ity_I64);
9452 IRTemp len = newTemp(lensize == 64 ? Ity_I64 : Ity_I32);
9453 cond = newTemp(Ity_I1);
9454 torun = newTemp(Ity_I64);
9455
9456 assign(torun, load(Ity_I64, mkexpr(addr2)));
9457 /* Start with a check that the saved code is still correct */
9458 assign(cond, binop(Iop_CmpNE64, mkexpr(torun), mkU64(last_execute_target)));
9459 /* If not, save the new value */
9460 d = unsafeIRDirty_0_N (0, "s390x_dirtyhelper_EX", &s390x_dirtyhelper_EX,
9461 mkIRExprVec_1(mkexpr(torun)));
9462 d->guard = mkexpr(cond);
9463 stmt(IRStmt_Dirty(d));
9464
9465 /* and restart */
florian428dfdd2012-03-27 03:09:49 +00009466 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TISTART),
9467 mkU64(guest_IA_curr_instr)));
9468 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TILEN), mkU64(4)));
florian6820ba52012-07-26 02:01:50 +00009469 restart_if(mkexpr(cond));
sewardj2019a972011-03-07 16:04:07 +00009470
9471 ss.bytes = last_execute_target;
9472 assign(start1, binop(Iop_Add64, mkU64(ss.dec.d1),
9473 ss.dec.b1 != 0 ? get_gpr_dw0(ss.dec.b1) : mkU64(0)));
9474 assign(start2, binop(Iop_Add64, mkU64(ss.dec.d2),
9475 ss.dec.b2 != 0 ? get_gpr_dw0(ss.dec.b2) : mkU64(0)));
9476 assign(len, unop(lensize == 64 ? Iop_8Uto64 : Iop_8Uto32, binop(Iop_Or8,
9477 r != 0 ? get_gpr_b7(r): mkU8(0), mkU8(ss.dec.l))));
9478 irgen(len, start1, start2);
florian8844a632012-04-13 04:04:06 +00009479
sewardj2019a972011-03-07 16:04:07 +00009480 last_execute_target = 0;
9481}
9482
florian55085f82012-11-21 00:36:55 +00009483static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009484s390_irgen_EX(UChar r1, IRTemp addr2)
9485{
9486 switch(last_execute_target & 0xff00000000000000ULL) {
9487 case 0:
9488 {
9489 /* no code information yet */
9490 IRDirty *d;
9491
9492 /* so safe the code... */
9493 d = unsafeIRDirty_0_N (0, "s390x_dirtyhelper_EX", &s390x_dirtyhelper_EX,
9494 mkIRExprVec_1(load(Ity_I64, mkexpr(addr2))));
9495 stmt(IRStmt_Dirty(d));
9496 /* and restart */
florian428dfdd2012-03-27 03:09:49 +00009497 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TISTART),
9498 mkU64(guest_IA_curr_instr)));
9499 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TILEN), mkU64(4)));
florian6820ba52012-07-26 02:01:50 +00009500 restart_if(IRExpr_Const(IRConst_U1(True)));
9501
sewardj2019a972011-03-07 16:04:07 +00009502 /* we know that this will be invalidated */
florianf9e1ed72012-04-17 02:41:56 +00009503 put_IA(mkaddr_expr(guest_IA_next_instr));
sewardj2019a972011-03-07 16:04:07 +00009504 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +00009505 dis_res->jk_StopHere = Ijk_TInval;
sewardj2019a972011-03-07 16:04:07 +00009506 break;
9507 }
9508
9509 case 0xd200000000000000ULL:
9510 /* special case MVC */
9511 s390_irgen_EX_SS(r1, addr2, s390_irgen_MVC_EX, 64);
9512 return "mvc via ex";
9513
9514 case 0xd500000000000000ULL:
9515 /* special case CLC */
9516 s390_irgen_EX_SS(r1, addr2, s390_irgen_CLC_EX, 64);
9517 return "clc via ex";
9518
9519 case 0xd700000000000000ULL:
9520 /* special case XC */
9521 s390_irgen_EX_SS(r1, addr2, s390_irgen_XC_EX, 32);
9522 return "xc via ex";
9523
florianb0bf6602012-05-05 00:01:16 +00009524 case 0xd600000000000000ULL:
9525 /* special case OC */
9526 s390_irgen_EX_SS(r1, addr2, s390_irgen_OC_EX, 32);
9527 return "oc via ex";
9528
9529 case 0xd400000000000000ULL:
9530 /* special case NC */
9531 s390_irgen_EX_SS(r1, addr2, s390_irgen_NC_EX, 32);
9532 return "nc via ex";
sewardj2019a972011-03-07 16:04:07 +00009533
florianf87d4fb2012-05-05 02:55:24 +00009534 case 0xdc00000000000000ULL:
9535 /* special case TR */
9536 s390_irgen_EX_SS(r1, addr2, s390_irgen_TR_EX, 64);
9537 return "tr via ex";
9538
sewardj2019a972011-03-07 16:04:07 +00009539 default:
9540 {
9541 /* everything else will get a self checking prefix that also checks the
9542 register content */
9543 IRDirty *d;
9544 UChar *bytes;
9545 IRTemp cond;
9546 IRTemp orperand;
9547 IRTemp torun;
9548
9549 cond = newTemp(Ity_I1);
9550 orperand = newTemp(Ity_I64);
9551 torun = newTemp(Ity_I64);
9552
9553 if (r1 == 0)
9554 assign(orperand, mkU64(0));
9555 else
9556 assign(orperand, unop(Iop_8Uto64,get_gpr_b7(r1)));
9557 /* This code is going to be translated */
9558 assign(torun, binop(Iop_Or64, load(Ity_I64, mkexpr(addr2)),
9559 binop(Iop_Shl64, mkexpr(orperand), mkU8(48))));
9560
9561 /* Start with a check that saved code is still correct */
9562 assign(cond, binop(Iop_CmpNE64, mkexpr(torun),
9563 mkU64(last_execute_target)));
9564 /* If not, save the new value */
9565 d = unsafeIRDirty_0_N (0, "s390x_dirtyhelper_EX", &s390x_dirtyhelper_EX,
9566 mkIRExprVec_1(mkexpr(torun)));
9567 d->guard = mkexpr(cond);
9568 stmt(IRStmt_Dirty(d));
9569
9570 /* and restart */
florian428dfdd2012-03-27 03:09:49 +00009571 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TISTART), mkU64(guest_IA_curr_instr)));
9572 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TILEN), mkU64(4)));
florian6820ba52012-07-26 02:01:50 +00009573 restart_if(mkexpr(cond));
sewardj2019a972011-03-07 16:04:07 +00009574
9575 /* Now comes the actual translation */
9576 bytes = (UChar *) &last_execute_target;
9577 s390_decode_and_irgen(bytes, ((((bytes[0] >> 6) + 1) >> 1) + 1) << 1,
9578 dis_res);
sewardj7ee97522011-05-09 21:45:04 +00009579 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00009580 vex_printf(" which was executed by\n");
9581 /* dont make useless translations in the next execute */
9582 last_execute_target = 0;
9583 }
9584 }
9585 return "ex";
9586}
9587
florian55085f82012-11-21 00:36:55 +00009588static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009589s390_irgen_EXRL(UChar r1, UInt offset)
9590{
9591 IRTemp addr = newTemp(Ity_I64);
9592 /* we might save one round trip because we know the target */
9593 if (!last_execute_target)
9594 last_execute_target = *(ULong *)(HWord)
9595 (guest_IA_curr_instr + offset * 2UL);
9596 assign(addr, mkU64(guest_IA_curr_instr + offset * 2UL));
9597 s390_irgen_EX(r1, addr);
9598 return "exrl";
9599}
9600
florian55085f82012-11-21 00:36:55 +00009601static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009602s390_irgen_IPM(UChar r1)
9603{
9604 // As long as we dont support SPM, lets just assume 0 as program mask
9605 put_gpr_b4(r1, unop(Iop_32to8, binop(Iop_Or32, mkU32(0 /* program mask */),
9606 binop(Iop_Shl32, s390_call_calculate_cc(), mkU8(4)))));
9607
9608 return "ipm";
9609}
9610
9611
florian55085f82012-11-21 00:36:55 +00009612static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009613s390_irgen_SRST(UChar r1, UChar r2)
9614{
9615 IRTemp address = newTemp(Ity_I64);
9616 IRTemp next = newTemp(Ity_I64);
9617 IRTemp delim = newTemp(Ity_I8);
9618 IRTemp counter = newTemp(Ity_I64);
9619 IRTemp byte = newTemp(Ity_I8);
9620
9621 assign(address, get_gpr_dw0(r2));
9622 assign(next, get_gpr_dw0(r1));
9623
9624 assign(counter, get_counter_dw0());
9625 put_counter_dw0(mkU64(0));
9626
9627 // start = next? CC=2 and out r1 and r2 unchanged
9628 s390_cc_set(2);
9629 put_gpr_dw0(r2, binop(Iop_Sub64, mkexpr(address), mkexpr(counter)));
florian6820ba52012-07-26 02:01:50 +00009630 next_insn_if(binop(Iop_CmpEQ64, mkexpr(address), mkexpr(next)));
sewardj2019a972011-03-07 16:04:07 +00009631
9632 assign(byte, load(Ity_I8, mkexpr(address)));
9633 assign(delim, get_gpr_b7(0));
9634
9635 // byte = delim? CC=1, R1=address
9636 s390_cc_set(1);
9637 put_gpr_dw0(r1, mkexpr(address));
florian6820ba52012-07-26 02:01:50 +00009638 next_insn_if(binop(Iop_CmpEQ8, mkexpr(delim), mkexpr(byte)));
sewardj2019a972011-03-07 16:04:07 +00009639
9640 // else: all equal, no end yet, loop
9641 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
9642 put_gpr_dw0(r1, mkexpr(next));
9643 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(address), mkU64(1)));
floriancf87c942012-07-25 00:52:21 +00009644
florian6820ba52012-07-26 02:01:50 +00009645 iterate();
sewardj2019a972011-03-07 16:04:07 +00009646
9647 return "srst";
9648}
9649
florian55085f82012-11-21 00:36:55 +00009650static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009651s390_irgen_CLST(UChar r1, UChar r2)
9652{
9653 IRTemp address1 = newTemp(Ity_I64);
9654 IRTemp address2 = newTemp(Ity_I64);
9655 IRTemp end = newTemp(Ity_I8);
9656 IRTemp counter = newTemp(Ity_I64);
9657 IRTemp byte1 = newTemp(Ity_I8);
9658 IRTemp byte2 = newTemp(Ity_I8);
9659
9660 assign(address1, get_gpr_dw0(r1));
9661 assign(address2, get_gpr_dw0(r2));
9662 assign(end, get_gpr_b7(0));
9663 assign(counter, get_counter_dw0());
9664 put_counter_dw0(mkU64(0));
9665 assign(byte1, load(Ity_I8, mkexpr(address1)));
9666 assign(byte2, load(Ity_I8, mkexpr(address2)));
9667
9668 // end in both? all equal, reset r1 and r2 to start values
9669 s390_cc_set(0);
9670 put_gpr_dw0(r1, binop(Iop_Sub64, mkexpr(address1), mkexpr(counter)));
9671 put_gpr_dw0(r2, binop(Iop_Sub64, mkexpr(address2), mkexpr(counter)));
florian6820ba52012-07-26 02:01:50 +00009672 next_insn_if(binop(Iop_CmpEQ8, mkU8(0),
9673 binop(Iop_Or8,
9674 binop(Iop_Xor8, mkexpr(byte1), mkexpr(end)),
9675 binop(Iop_Xor8, mkexpr(byte2), mkexpr(end)))));
sewardj2019a972011-03-07 16:04:07 +00009676
9677 put_gpr_dw0(r1, mkexpr(address1));
9678 put_gpr_dw0(r2, mkexpr(address2));
9679
9680 // End found in string1
9681 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +00009682 next_insn_if(binop(Iop_CmpEQ8, mkexpr(end), mkexpr(byte1)));
sewardj2019a972011-03-07 16:04:07 +00009683
9684 // End found in string2
9685 s390_cc_set(2);
florian6820ba52012-07-26 02:01:50 +00009686 next_insn_if(binop(Iop_CmpEQ8, mkexpr(end), mkexpr(byte2)));
sewardj2019a972011-03-07 16:04:07 +00009687
9688 // string1 < string2
9689 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +00009690 next_insn_if(binop(Iop_CmpLT32U, unop(Iop_8Uto32, mkexpr(byte1)),
9691 unop(Iop_8Uto32, mkexpr(byte2))));
sewardj2019a972011-03-07 16:04:07 +00009692
9693 // string2 < string1
9694 s390_cc_set(2);
florian6820ba52012-07-26 02:01:50 +00009695 next_insn_if(binop(Iop_CmpLT32U, unop(Iop_8Uto32, mkexpr(byte2)),
9696 unop(Iop_8Uto32, mkexpr(byte1))));
sewardj2019a972011-03-07 16:04:07 +00009697
9698 // else: all equal, no end yet, loop
9699 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
9700 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), mkU64(1)));
9701 put_gpr_dw0(r2, binop(Iop_Add64, get_gpr_dw0(r2), mkU64(1)));
floriancf87c942012-07-25 00:52:21 +00009702
florian6820ba52012-07-26 02:01:50 +00009703 iterate();
sewardj2019a972011-03-07 16:04:07 +00009704
9705 return "clst";
9706}
9707
9708static void
9709s390_irgen_load_multiple_32bit(UChar r1, UChar r3, IRTemp op2addr)
9710{
9711 UChar reg;
9712 IRTemp addr = newTemp(Ity_I64);
9713
9714 assign(addr, mkexpr(op2addr));
9715 reg = r1;
9716 do {
9717 IRTemp old = addr;
9718
9719 reg %= 16;
9720 put_gpr_w1(reg, load(Ity_I32, mkexpr(addr)));
9721 addr = newTemp(Ity_I64);
9722 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
9723 reg++;
9724 } while (reg != (r3 + 1));
9725}
9726
florian55085f82012-11-21 00:36:55 +00009727static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009728s390_irgen_LM(UChar r1, UChar r3, IRTemp op2addr)
9729{
9730 s390_irgen_load_multiple_32bit(r1, r3, op2addr);
9731
9732 return "lm";
9733}
9734
florian55085f82012-11-21 00:36:55 +00009735static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009736s390_irgen_LMY(UChar r1, UChar r3, IRTemp op2addr)
9737{
9738 s390_irgen_load_multiple_32bit(r1, r3, op2addr);
9739
9740 return "lmy";
9741}
9742
florian55085f82012-11-21 00:36:55 +00009743static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009744s390_irgen_LMH(UChar r1, UChar r3, IRTemp op2addr)
9745{
9746 UChar reg;
9747 IRTemp addr = newTemp(Ity_I64);
9748
9749 assign(addr, mkexpr(op2addr));
9750 reg = r1;
9751 do {
9752 IRTemp old = addr;
9753
9754 reg %= 16;
9755 put_gpr_w0(reg, load(Ity_I32, mkexpr(addr)));
9756 addr = newTemp(Ity_I64);
9757 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
9758 reg++;
9759 } while (reg != (r3 + 1));
9760
9761 return "lmh";
9762}
9763
florian55085f82012-11-21 00:36:55 +00009764static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009765s390_irgen_LMG(UChar r1, UChar r3, IRTemp op2addr)
9766{
9767 UChar reg;
9768 IRTemp addr = newTemp(Ity_I64);
9769
9770 assign(addr, mkexpr(op2addr));
9771 reg = r1;
9772 do {
9773 IRTemp old = addr;
9774
9775 reg %= 16;
9776 put_gpr_dw0(reg, load(Ity_I64, mkexpr(addr)));
9777 addr = newTemp(Ity_I64);
9778 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(8)));
9779 reg++;
9780 } while (reg != (r3 + 1));
9781
9782 return "lmg";
9783}
9784
9785static void
9786s390_irgen_store_multiple_32bit(UChar r1, UChar r3, IRTemp op2addr)
9787{
9788 UChar reg;
9789 IRTemp addr = newTemp(Ity_I64);
9790
9791 assign(addr, mkexpr(op2addr));
9792 reg = r1;
9793 do {
9794 IRTemp old = addr;
9795
9796 reg %= 16;
9797 store(mkexpr(addr), get_gpr_w1(reg));
9798 addr = newTemp(Ity_I64);
9799 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
9800 reg++;
9801 } while( reg != (r3 + 1));
9802}
9803
florian55085f82012-11-21 00:36:55 +00009804static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009805s390_irgen_STM(UChar r1, UChar r3, IRTemp op2addr)
9806{
9807 s390_irgen_store_multiple_32bit(r1, r3, op2addr);
9808
9809 return "stm";
9810}
9811
florian55085f82012-11-21 00:36:55 +00009812static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009813s390_irgen_STMY(UChar r1, UChar r3, IRTemp op2addr)
9814{
9815 s390_irgen_store_multiple_32bit(r1, r3, op2addr);
9816
9817 return "stmy";
9818}
9819
florian55085f82012-11-21 00:36:55 +00009820static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009821s390_irgen_STMH(UChar r1, UChar r3, IRTemp op2addr)
9822{
9823 UChar reg;
9824 IRTemp addr = newTemp(Ity_I64);
9825
9826 assign(addr, mkexpr(op2addr));
9827 reg = r1;
9828 do {
9829 IRTemp old = addr;
9830
9831 reg %= 16;
9832 store(mkexpr(addr), get_gpr_w0(reg));
9833 addr = newTemp(Ity_I64);
9834 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
9835 reg++;
9836 } while( reg != (r3 + 1));
9837
9838 return "stmh";
9839}
9840
florian55085f82012-11-21 00:36:55 +00009841static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009842s390_irgen_STMG(UChar r1, UChar r3, IRTemp op2addr)
9843{
9844 UChar reg;
9845 IRTemp addr = newTemp(Ity_I64);
9846
9847 assign(addr, mkexpr(op2addr));
9848 reg = r1;
9849 do {
9850 IRTemp old = addr;
9851
9852 reg %= 16;
9853 store(mkexpr(addr), get_gpr_dw0(reg));
9854 addr = newTemp(Ity_I64);
9855 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(8)));
9856 reg++;
9857 } while( reg != (r3 + 1));
9858
9859 return "stmg";
9860}
9861
9862static void
florianb0bf6602012-05-05 00:01:16 +00009863s390_irgen_xonc(IROp op, IRTemp length, IRTemp start1, IRTemp start2)
sewardj2019a972011-03-07 16:04:07 +00009864{
9865 IRTemp old1 = newTemp(Ity_I8);
9866 IRTemp old2 = newTemp(Ity_I8);
9867 IRTemp new1 = newTemp(Ity_I8);
9868 IRTemp counter = newTemp(Ity_I32);
9869 IRTemp addr1 = newTemp(Ity_I64);
9870
9871 assign(counter, get_counter_w0());
9872
9873 assign(addr1, binop(Iop_Add64, mkexpr(start1),
9874 unop(Iop_32Uto64, mkexpr(counter))));
9875
9876 assign(old1, load(Ity_I8, mkexpr(addr1)));
9877 assign(old2, load(Ity_I8, binop(Iop_Add64, mkexpr(start2),
9878 unop(Iop_32Uto64,mkexpr(counter)))));
9879 assign(new1, binop(op, mkexpr(old1), mkexpr(old2)));
9880
9881 /* Special case: xc is used to zero memory */
sewardj2019a972011-03-07 16:04:07 +00009882 if (op == Iop_Xor8) {
9883 store(mkexpr(addr1),
florian6ad49522011-09-09 02:38:55 +00009884 mkite(binop(Iop_CmpEQ64, mkexpr(start1), mkexpr(start2)),
9885 mkU8(0), mkexpr(new1)));
sewardj2019a972011-03-07 16:04:07 +00009886 } else
9887 store(mkexpr(addr1), mkexpr(new1));
9888 put_counter_w1(binop(Iop_Or32, unop(Iop_8Uto32, mkexpr(new1)),
9889 get_counter_w1()));
9890
9891 /* Check for end of field */
9892 put_counter_w0(binop(Iop_Add32, mkexpr(counter), mkU32(1)));
florian6820ba52012-07-26 02:01:50 +00009893 iterate_if(binop(Iop_CmpNE32, mkexpr(counter), mkexpr(length)));
sewardj2019a972011-03-07 16:04:07 +00009894 s390_cc_thunk_put1(S390_CC_OP_BITWISE, mktemp(Ity_I32, get_counter_w1()),
9895 False);
9896 put_counter_dw0(mkU64(0));
9897}
9898
florian55085f82012-11-21 00:36:55 +00009899static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009900s390_irgen_XC(UChar length, IRTemp start1, IRTemp start2)
9901{
florianb0bf6602012-05-05 00:01:16 +00009902 IRTemp len = newTemp(Ity_I32);
9903
9904 assign(len, mkU32(length));
9905 s390_irgen_xonc(Iop_Xor8, len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +00009906
9907 return "xc";
9908}
9909
sewardjb63967e2011-03-24 08:50:04 +00009910static void
9911s390_irgen_XC_sameloc(UChar length, UChar b, UShort d)
9912{
9913 IRTemp counter = newTemp(Ity_I32);
9914 IRTemp start = newTemp(Ity_I64);
9915 IRTemp addr = newTemp(Ity_I64);
9916
9917 assign(start,
9918 binop(Iop_Add64, mkU64(d), b != 0 ? get_gpr_dw0(b) : mkU64(0)));
9919
9920 if (length < 8) {
9921 UInt i;
9922
9923 for (i = 0; i <= length; ++i) {
9924 store(binop(Iop_Add64, mkexpr(start), mkU64(i)), mkU8(0));
9925 }
9926 } else {
9927 assign(counter, get_counter_w0());
9928
9929 assign(addr, binop(Iop_Add64, mkexpr(start),
9930 unop(Iop_32Uto64, mkexpr(counter))));
9931
9932 store(mkexpr(addr), mkU8(0));
9933
9934 /* Check for end of field */
9935 put_counter_w0(binop(Iop_Add32, mkexpr(counter), mkU32(1)));
florian6820ba52012-07-26 02:01:50 +00009936 iterate_if(binop(Iop_CmpNE32, mkexpr(counter), mkU32(length)));
sewardjb63967e2011-03-24 08:50:04 +00009937
9938 /* Reset counter */
9939 put_counter_dw0(mkU64(0));
9940 }
9941
9942 s390_cc_thunk_put1(S390_CC_OP_BITWISE, mktemp(Ity_I32, mkU32(0)), False);
9943
sewardj7ee97522011-05-09 21:45:04 +00009944 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardjb63967e2011-03-24 08:50:04 +00009945 s390_disasm(ENC3(MNM, UDLB, UDXB), "xc", d, length, b, d, 0, b);
9946}
9947
florian55085f82012-11-21 00:36:55 +00009948static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009949s390_irgen_NC(UChar length, IRTemp start1, IRTemp start2)
9950{
florianb0bf6602012-05-05 00:01:16 +00009951 IRTemp len = newTemp(Ity_I32);
9952
9953 assign(len, mkU32(length));
9954 s390_irgen_xonc(Iop_And8, len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +00009955
9956 return "nc";
9957}
9958
florian55085f82012-11-21 00:36:55 +00009959static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009960s390_irgen_OC(UChar length, IRTemp start1, IRTemp start2)
9961{
florianb0bf6602012-05-05 00:01:16 +00009962 IRTemp len = newTemp(Ity_I32);
9963
9964 assign(len, mkU32(length));
9965 s390_irgen_xonc(Iop_Or8, len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +00009966
9967 return "oc";
9968}
9969
9970
florian55085f82012-11-21 00:36:55 +00009971static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009972s390_irgen_MVC(UChar length, IRTemp start1, IRTemp start2)
9973{
florian79e839e2012-05-05 02:20:30 +00009974 IRTemp len = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00009975
florian79e839e2012-05-05 02:20:30 +00009976 assign(len, mkU64(length));
9977 s390_irgen_MVC_EX(len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +00009978
9979 return "mvc";
9980}
9981
florian55085f82012-11-21 00:36:55 +00009982static const HChar *
florianb0c9a132011-09-08 15:37:39 +00009983s390_irgen_MVCL(UChar r1, UChar r2)
9984{
9985 IRTemp addr1 = newTemp(Ity_I64);
9986 IRTemp addr2 = newTemp(Ity_I64);
9987 IRTemp addr2_load = newTemp(Ity_I64);
9988 IRTemp r1p1 = newTemp(Ity_I32); /* contents of r1 + 1 */
9989 IRTemp r2p1 = newTemp(Ity_I32); /* contents of r2 + 1 */
9990 IRTemp len1 = newTemp(Ity_I32);
9991 IRTemp len2 = newTemp(Ity_I32);
9992 IRTemp pad = newTemp(Ity_I8);
9993 IRTemp single = newTemp(Ity_I8);
9994
9995 assign(addr1, get_gpr_dw0(r1));
9996 assign(r1p1, get_gpr_w1(r1 + 1));
9997 assign(len1, binop(Iop_And32, mkexpr(r1p1), mkU32(0x00ffffff)));
9998 assign(addr2, get_gpr_dw0(r2));
9999 assign(r2p1, get_gpr_w1(r2 + 1));
10000 assign(len2, binop(Iop_And32, mkexpr(r2p1), mkU32(0x00ffffff)));
10001 assign(pad, get_gpr_b4(r2 + 1));
10002
10003 /* len1 == 0 ? */
10004 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len2, False);
florian6820ba52012-07-26 02:01:50 +000010005 next_insn_if(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)));
florianb0c9a132011-09-08 15:37:39 +000010006
10007 /* Check for destructive overlap:
10008 addr1 > addr2 && addr2 + len1 > addr1 && (addr2 + len2) > addr1 */
10009 s390_cc_set(3);
10010 IRTemp cond1 = newTemp(Ity_I32);
10011 assign(cond1, unop(Iop_1Uto32,
10012 binop(Iop_CmpLT64U, mkexpr(addr2), mkexpr(addr1))));
10013 IRTemp cond2 = newTemp(Ity_I32);
10014 assign(cond2, unop(Iop_1Uto32,
10015 binop(Iop_CmpLT64U, mkexpr(addr1),
10016 binop(Iop_Add64, mkexpr(addr2),
10017 unop(Iop_32Uto64, mkexpr(len1))))));
10018 IRTemp cond3 = newTemp(Ity_I32);
10019 assign(cond3, unop(Iop_1Uto32,
10020 binop(Iop_CmpLT64U,
10021 mkexpr(addr1),
10022 binop(Iop_Add64, mkexpr(addr2),
10023 unop(Iop_32Uto64, mkexpr(len2))))));
10024
florian6820ba52012-07-26 02:01:50 +000010025 next_insn_if(binop(Iop_CmpEQ32,
10026 binop(Iop_And32,
10027 binop(Iop_And32, mkexpr(cond1), mkexpr(cond2)),
10028 mkexpr(cond3)),
10029 mkU32(1)));
florianb0c9a132011-09-08 15:37:39 +000010030
10031 /* See s390_irgen_CLCL for explanation why we cannot load directly
10032 and need two steps. */
10033 assign(addr2_load,
10034 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
10035 mkU64(guest_IA_curr_instr), mkexpr(addr2)));
10036 assign(single,
10037 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
10038 mkexpr(pad), load(Ity_I8, mkexpr(addr2_load))));
10039
10040 store(mkexpr(addr1), mkexpr(single));
10041
10042 /* Update addr1 and len1 */
10043 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkU64(1)));
10044 put_gpr_w1(r1 + 1, binop(Iop_Sub32, mkexpr(r1p1), mkU32(1)));
10045
10046 /* Update addr2 and len2 */
10047 put_gpr_dw0(r2,
10048 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
10049 mkexpr(addr2),
10050 binop(Iop_Add64, mkexpr(addr2), mkU64(1))));
10051
10052 /* When updating len2 we must not modify bits (r2+1)[0:39] */
10053 put_gpr_w1(r2 + 1,
10054 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
10055 binop(Iop_And32, mkexpr(r2p1), mkU32(0xFF000000u)),
10056 binop(Iop_Sub32, mkexpr(r2p1), mkU32(1))));
10057
10058 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len2, False);
florian6820ba52012-07-26 02:01:50 +000010059 iterate_if(binop(Iop_CmpNE32, mkexpr(len1), mkU32(1)));
florianb0c9a132011-09-08 15:37:39 +000010060
10061 return "mvcl";
10062}
10063
10064
florian55085f82012-11-21 00:36:55 +000010065static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010066s390_irgen_MVCLE(UChar r1, UChar r3, IRTemp pad2)
10067{
10068 IRTemp addr1, addr3, addr3_load, len1, len3, single;
10069
10070 addr1 = newTemp(Ity_I64);
10071 addr3 = newTemp(Ity_I64);
10072 addr3_load = newTemp(Ity_I64);
10073 len1 = newTemp(Ity_I64);
10074 len3 = newTemp(Ity_I64);
10075 single = newTemp(Ity_I8);
10076
10077 assign(addr1, get_gpr_dw0(r1));
10078 assign(len1, get_gpr_dw0(r1 + 1));
10079 assign(addr3, get_gpr_dw0(r3));
10080 assign(len3, get_gpr_dw0(r3 + 1));
10081
10082 // len1 == 0 ?
10083 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len3, False);
florian6820ba52012-07-26 02:01:50 +000010084 next_insn_if(binop(Iop_CmpEQ64,mkexpr(len1), mkU64(0)));
sewardj2019a972011-03-07 16:04:07 +000010085
10086 /* This is a hack to prevent mvcle from reading from addr3 if it
10087 should read from the pad. Since the pad has no address, just
10088 read from the instruction, we discard that anyway */
10089 assign(addr3_load,
florian6ad49522011-09-09 02:38:55 +000010090 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
10091 mkU64(guest_IA_curr_instr), mkexpr(addr3)));
sewardj2019a972011-03-07 16:04:07 +000010092
10093 assign(single,
florian6ad49522011-09-09 02:38:55 +000010094 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
10095 unop(Iop_64to8, mkexpr(pad2)),
10096 load(Ity_I8, mkexpr(addr3_load))));
sewardj2019a972011-03-07 16:04:07 +000010097 store(mkexpr(addr1), mkexpr(single));
10098
10099 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkU64(1)));
10100
10101 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkU64(1)));
10102
10103 put_gpr_dw0(r3,
florian6ad49522011-09-09 02:38:55 +000010104 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
10105 mkexpr(addr3),
10106 binop(Iop_Add64, mkexpr(addr3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +000010107
10108 put_gpr_dw0(r3 + 1,
florian6ad49522011-09-09 02:38:55 +000010109 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
10110 mkU64(0), binop(Iop_Sub64, mkexpr(len3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +000010111
sewardj2019a972011-03-07 16:04:07 +000010112 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len3, False);
florian6820ba52012-07-26 02:01:50 +000010113 iterate_if(binop(Iop_CmpNE64, mkexpr(len1), mkU64(1)));
sewardj2019a972011-03-07 16:04:07 +000010114
10115 return "mvcle";
10116}
10117
florian55085f82012-11-21 00:36:55 +000010118static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010119s390_irgen_MVST(UChar r1, UChar r2)
10120{
10121 IRTemp addr1 = newTemp(Ity_I64);
10122 IRTemp addr2 = newTemp(Ity_I64);
10123 IRTemp end = newTemp(Ity_I8);
10124 IRTemp byte = newTemp(Ity_I8);
10125 IRTemp counter = newTemp(Ity_I64);
10126
10127 assign(addr1, get_gpr_dw0(r1));
10128 assign(addr2, get_gpr_dw0(r2));
10129 assign(counter, get_counter_dw0());
10130 assign(end, get_gpr_b7(0));
10131 assign(byte, load(Ity_I8, binop(Iop_Add64, mkexpr(addr2),mkexpr(counter))));
10132 store(binop(Iop_Add64,mkexpr(addr1),mkexpr(counter)), mkexpr(byte));
10133
10134 // We use unlimited as cpu-determined number
10135 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
florian6820ba52012-07-26 02:01:50 +000010136 iterate_if(binop(Iop_CmpNE8, mkexpr(end), mkexpr(byte)));
sewardj2019a972011-03-07 16:04:07 +000010137
10138 // and always set cc=1 at the end + update r1
10139 s390_cc_set(1);
10140 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(counter)));
10141 put_counter_dw0(mkU64(0));
10142
10143 return "mvst";
10144}
10145
10146static void
10147s390_irgen_divide_64to32(IROp op, UChar r1, IRTemp op2)
10148{
10149 IRTemp op1 = newTemp(Ity_I64);
10150 IRTemp result = newTemp(Ity_I64);
10151
10152 assign(op1, binop(Iop_32HLto64,
10153 get_gpr_w1(r1), // high 32 bits
10154 get_gpr_w1(r1 + 1))); // low 32 bits
10155 assign(result, binop(op, mkexpr(op1), mkexpr(op2)));
10156 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result))); // remainder
10157 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result))); // quotient
10158}
10159
10160static void
10161s390_irgen_divide_128to64(IROp op, UChar r1, IRTemp op2)
10162{
10163 IRTemp op1 = newTemp(Ity_I128);
10164 IRTemp result = newTemp(Ity_I128);
10165
10166 assign(op1, binop(Iop_64HLto128,
10167 get_gpr_dw0(r1), // high 64 bits
10168 get_gpr_dw0(r1 + 1))); // low 64 bits
10169 assign(result, binop(op, mkexpr(op1), mkexpr(op2)));
10170 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result))); // remainder
10171 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result))); // quotient
10172}
10173
10174static void
10175s390_irgen_divide_64to64(IROp op, UChar r1, IRTemp op2)
10176{
10177 IRTemp op1 = newTemp(Ity_I64);
10178 IRTemp result = newTemp(Ity_I128);
10179
10180 assign(op1, get_gpr_dw0(r1 + 1));
10181 assign(result, binop(op, mkexpr(op1), mkexpr(op2)));
10182 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result))); // remainder
10183 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result))); // quotient
10184}
10185
florian55085f82012-11-21 00:36:55 +000010186static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010187s390_irgen_DR(UChar r1, UChar r2)
10188{
10189 IRTemp op2 = newTemp(Ity_I32);
10190
10191 assign(op2, get_gpr_w1(r2));
10192
10193 s390_irgen_divide_64to32(Iop_DivModS64to32, r1, op2);
10194
10195 return "dr";
10196}
10197
florian55085f82012-11-21 00:36:55 +000010198static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010199s390_irgen_D(UChar r1, IRTemp op2addr)
10200{
10201 IRTemp op2 = newTemp(Ity_I32);
10202
10203 assign(op2, load(Ity_I32, mkexpr(op2addr)));
10204
10205 s390_irgen_divide_64to32(Iop_DivModS64to32, r1, op2);
10206
10207 return "d";
10208}
10209
florian55085f82012-11-21 00:36:55 +000010210static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010211s390_irgen_DLR(UChar r1, UChar r2)
10212{
10213 IRTemp op2 = newTemp(Ity_I32);
10214
10215 assign(op2, get_gpr_w1(r2));
10216
10217 s390_irgen_divide_64to32(Iop_DivModU64to32, r1, op2);
10218
florian7cd1cde2012-08-16 23:57:43 +000010219 return "dlr";
sewardj2019a972011-03-07 16:04:07 +000010220}
10221
florian55085f82012-11-21 00:36:55 +000010222static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010223s390_irgen_DL(UChar r1, IRTemp op2addr)
10224{
10225 IRTemp op2 = newTemp(Ity_I32);
10226
10227 assign(op2, load(Ity_I32, mkexpr(op2addr)));
10228
10229 s390_irgen_divide_64to32(Iop_DivModU64to32, r1, op2);
10230
10231 return "dl";
10232}
10233
florian55085f82012-11-21 00:36:55 +000010234static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010235s390_irgen_DLG(UChar r1, IRTemp op2addr)
10236{
10237 IRTemp op2 = newTemp(Ity_I64);
10238
10239 assign(op2, load(Ity_I64, mkexpr(op2addr)));
10240
10241 s390_irgen_divide_128to64(Iop_DivModU128to64, r1, op2);
10242
10243 return "dlg";
10244}
10245
florian55085f82012-11-21 00:36:55 +000010246static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010247s390_irgen_DLGR(UChar r1, UChar r2)
10248{
10249 IRTemp op2 = newTemp(Ity_I64);
10250
10251 assign(op2, get_gpr_dw0(r2));
10252
10253 s390_irgen_divide_128to64(Iop_DivModU128to64, r1, op2);
10254
10255 return "dlgr";
10256}
10257
florian55085f82012-11-21 00:36:55 +000010258static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010259s390_irgen_DSGR(UChar r1, UChar r2)
10260{
10261 IRTemp op2 = newTemp(Ity_I64);
10262
10263 assign(op2, get_gpr_dw0(r2));
10264
10265 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
10266
10267 return "dsgr";
10268}
10269
florian55085f82012-11-21 00:36:55 +000010270static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010271s390_irgen_DSG(UChar r1, IRTemp op2addr)
10272{
10273 IRTemp op2 = newTemp(Ity_I64);
10274
10275 assign(op2, load(Ity_I64, mkexpr(op2addr)));
10276
10277 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
10278
10279 return "dsg";
10280}
10281
florian55085f82012-11-21 00:36:55 +000010282static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010283s390_irgen_DSGFR(UChar r1, UChar r2)
10284{
10285 IRTemp op2 = newTemp(Ity_I64);
10286
10287 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
10288
10289 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
10290
10291 return "dsgfr";
10292}
10293
florian55085f82012-11-21 00:36:55 +000010294static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010295s390_irgen_DSGF(UChar r1, IRTemp op2addr)
10296{
10297 IRTemp op2 = newTemp(Ity_I64);
10298
10299 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
10300
10301 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
10302
10303 return "dsgf";
10304}
10305
10306static void
10307s390_irgen_load_ar_multiple(UChar r1, UChar r3, IRTemp op2addr)
10308{
10309 UChar reg;
10310 IRTemp addr = newTemp(Ity_I64);
10311
10312 assign(addr, mkexpr(op2addr));
10313 reg = r1;
10314 do {
10315 IRTemp old = addr;
10316
10317 reg %= 16;
10318 put_ar_w0(reg, load(Ity_I32, mkexpr(addr)));
10319 addr = newTemp(Ity_I64);
10320 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
10321 reg++;
10322 } while (reg != (r3 + 1));
10323}
10324
florian55085f82012-11-21 00:36:55 +000010325static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010326s390_irgen_LAM(UChar r1, UChar r3, IRTemp op2addr)
10327{
10328 s390_irgen_load_ar_multiple(r1, r3, op2addr);
10329
10330 return "lam";
10331}
10332
florian55085f82012-11-21 00:36:55 +000010333static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010334s390_irgen_LAMY(UChar r1, UChar r3, IRTemp op2addr)
10335{
10336 s390_irgen_load_ar_multiple(r1, r3, op2addr);
10337
10338 return "lamy";
10339}
10340
10341static void
10342s390_irgen_store_ar_multiple(UChar r1, UChar r3, IRTemp op2addr)
10343{
10344 UChar reg;
10345 IRTemp addr = newTemp(Ity_I64);
10346
10347 assign(addr, mkexpr(op2addr));
10348 reg = r1;
10349 do {
10350 IRTemp old = addr;
10351
10352 reg %= 16;
10353 store(mkexpr(addr), get_ar_w0(reg));
10354 addr = newTemp(Ity_I64);
10355 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
10356 reg++;
10357 } while (reg != (r3 + 1));
10358}
10359
florian55085f82012-11-21 00:36:55 +000010360static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010361s390_irgen_STAM(UChar r1, UChar r3, IRTemp op2addr)
10362{
10363 s390_irgen_store_ar_multiple(r1, r3, op2addr);
10364
10365 return "stam";
10366}
10367
florian55085f82012-11-21 00:36:55 +000010368static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010369s390_irgen_STAMY(UChar r1, UChar r3, IRTemp op2addr)
10370{
10371 s390_irgen_store_ar_multiple(r1, r3, op2addr);
10372
10373 return "stamy";
10374}
10375
10376
10377/* Implementation for 32-bit compare-and-swap */
10378static void
10379s390_irgen_cas_32(UChar r1, UChar r3, IRTemp op2addr)
10380{
10381 IRCAS *cas;
10382 IRTemp op1 = newTemp(Ity_I32);
10383 IRTemp old_mem = newTemp(Ity_I32);
10384 IRTemp op3 = newTemp(Ity_I32);
10385 IRTemp result = newTemp(Ity_I32);
10386 IRTemp nequal = newTemp(Ity_I1);
10387
10388 assign(op1, get_gpr_w1(r1));
10389 assign(op3, get_gpr_w1(r3));
10390
10391 /* The first and second operands are compared. If they are equal,
10392 the third operand is stored at the second- operand location. */
10393 cas = mkIRCAS(IRTemp_INVALID, old_mem,
10394 Iend_BE, mkexpr(op2addr),
10395 NULL, mkexpr(op1), /* expected value */
10396 NULL, mkexpr(op3) /* new value */);
10397 stmt(IRStmt_CAS(cas));
10398
10399 /* Set CC. Operands compared equal -> 0, else 1. */
10400 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(old_mem)));
10401 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
10402
10403 /* If operands were equal (cc == 0) just store the old value op1 in r1.
10404 Otherwise, store the old_value from memory in r1 and yield. */
10405 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
10406 put_gpr_w1(r1, mkite(mkexpr(nequal), mkexpr(old_mem), mkexpr(op1)));
florian6820ba52012-07-26 02:01:50 +000010407 yield_if(mkexpr(nequal));
sewardj2019a972011-03-07 16:04:07 +000010408}
10409
florian55085f82012-11-21 00:36:55 +000010410static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010411s390_irgen_CS(UChar r1, UChar r3, IRTemp op2addr)
10412{
10413 s390_irgen_cas_32(r1, r3, op2addr);
10414
10415 return "cs";
10416}
10417
florian55085f82012-11-21 00:36:55 +000010418static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010419s390_irgen_CSY(UChar r1, UChar r3, IRTemp op2addr)
10420{
10421 s390_irgen_cas_32(r1, r3, op2addr);
10422
10423 return "csy";
10424}
10425
florian55085f82012-11-21 00:36:55 +000010426static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010427s390_irgen_CSG(UChar r1, UChar r3, IRTemp op2addr)
10428{
10429 IRCAS *cas;
10430 IRTemp op1 = newTemp(Ity_I64);
10431 IRTemp old_mem = newTemp(Ity_I64);
10432 IRTemp op3 = newTemp(Ity_I64);
10433 IRTemp result = newTemp(Ity_I64);
10434 IRTemp nequal = newTemp(Ity_I1);
10435
10436 assign(op1, get_gpr_dw0(r1));
10437 assign(op3, get_gpr_dw0(r3));
10438
10439 /* The first and second operands are compared. If they are equal,
10440 the third operand is stored at the second- operand location. */
10441 cas = mkIRCAS(IRTemp_INVALID, old_mem,
10442 Iend_BE, mkexpr(op2addr),
10443 NULL, mkexpr(op1), /* expected value */
10444 NULL, mkexpr(op3) /* new value */);
10445 stmt(IRStmt_CAS(cas));
10446
10447 /* Set CC. Operands compared equal -> 0, else 1. */
10448 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(old_mem)));
10449 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
10450
10451 /* If operands were equal (cc == 0) just store the old value op1 in r1.
10452 Otherwise, store the old_value from memory in r1 and yield. */
10453 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
10454 put_gpr_dw0(r1, mkite(mkexpr(nequal), mkexpr(old_mem), mkexpr(op1)));
florian6820ba52012-07-26 02:01:50 +000010455 yield_if(mkexpr(nequal));
sewardj2019a972011-03-07 16:04:07 +000010456
10457 return "csg";
10458}
10459
florian448cbba2012-06-06 02:26:01 +000010460/* Implementation for 32-bit compare-double-and-swap */
10461static void
10462s390_irgen_cdas_32(UChar r1, UChar r3, IRTemp op2addr)
10463{
10464 IRCAS *cas;
10465 IRTemp op1_high = newTemp(Ity_I32);
10466 IRTemp op1_low = newTemp(Ity_I32);
10467 IRTemp old_mem_high = newTemp(Ity_I32);
10468 IRTemp old_mem_low = newTemp(Ity_I32);
10469 IRTemp op3_high = newTemp(Ity_I32);
10470 IRTemp op3_low = newTemp(Ity_I32);
10471 IRTemp result = newTemp(Ity_I32);
10472 IRTemp nequal = newTemp(Ity_I1);
10473
10474 assign(op1_high, get_gpr_w1(r1));
10475 assign(op1_low, get_gpr_w1(r1+1));
10476 assign(op3_high, get_gpr_w1(r3));
10477 assign(op3_low, get_gpr_w1(r3+1));
10478
10479 /* The first and second operands are compared. If they are equal,
10480 the third operand is stored at the second-operand location. */
10481 cas = mkIRCAS(old_mem_high, old_mem_low,
10482 Iend_BE, mkexpr(op2addr),
10483 mkexpr(op1_high), mkexpr(op1_low), /* expected value */
10484 mkexpr(op3_high), mkexpr(op3_low) /* new value */);
10485 stmt(IRStmt_CAS(cas));
10486
10487 /* Set CC. Operands compared equal -> 0, else 1. */
10488 assign(result, unop(Iop_1Uto32,
10489 binop(Iop_CmpNE32,
10490 binop(Iop_Or32,
10491 binop(Iop_Xor32, mkexpr(op1_high), mkexpr(old_mem_high)),
10492 binop(Iop_Xor32, mkexpr(op1_low), mkexpr(old_mem_low))),
10493 mkU32(0))));
10494
10495 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
10496
10497 /* If operands were equal (cc == 0) just store the old value op1 in r1.
10498 Otherwise, store the old_value from memory in r1 and yield. */
10499 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
10500 put_gpr_w1(r1, mkite(mkexpr(nequal), mkexpr(old_mem_high), mkexpr(op1_high)));
10501 put_gpr_w1(r1+1, mkite(mkexpr(nequal), mkexpr(old_mem_low), mkexpr(op1_low)));
florian6820ba52012-07-26 02:01:50 +000010502 yield_if(mkexpr(nequal));
florian448cbba2012-06-06 02:26:01 +000010503}
10504
florian55085f82012-11-21 00:36:55 +000010505static const HChar *
florian448cbba2012-06-06 02:26:01 +000010506s390_irgen_CDS(UChar r1, UChar r3, IRTemp op2addr)
10507{
10508 s390_irgen_cdas_32(r1, r3, op2addr);
10509
10510 return "cds";
10511}
10512
florian55085f82012-11-21 00:36:55 +000010513static const HChar *
florian448cbba2012-06-06 02:26:01 +000010514s390_irgen_CDSY(UChar r1, UChar r3, IRTemp op2addr)
10515{
10516 s390_irgen_cdas_32(r1, r3, op2addr);
10517
10518 return "cdsy";
10519}
10520
florian55085f82012-11-21 00:36:55 +000010521static const HChar *
florian448cbba2012-06-06 02:26:01 +000010522s390_irgen_CDSG(UChar r1, UChar r3, IRTemp op2addr)
10523{
10524 IRCAS *cas;
10525 IRTemp op1_high = newTemp(Ity_I64);
10526 IRTemp op1_low = newTemp(Ity_I64);
10527 IRTemp old_mem_high = newTemp(Ity_I64);
10528 IRTemp old_mem_low = newTemp(Ity_I64);
10529 IRTemp op3_high = newTemp(Ity_I64);
10530 IRTemp op3_low = newTemp(Ity_I64);
10531 IRTemp result = newTemp(Ity_I64);
10532 IRTemp nequal = newTemp(Ity_I1);
10533
10534 assign(op1_high, get_gpr_dw0(r1));
10535 assign(op1_low, get_gpr_dw0(r1+1));
10536 assign(op3_high, get_gpr_dw0(r3));
10537 assign(op3_low, get_gpr_dw0(r3+1));
10538
10539 /* The first and second operands are compared. If they are equal,
10540 the third operand is stored at the second-operand location. */
10541 cas = mkIRCAS(old_mem_high, old_mem_low,
10542 Iend_BE, mkexpr(op2addr),
10543 mkexpr(op1_high), mkexpr(op1_low), /* expected value */
10544 mkexpr(op3_high), mkexpr(op3_low) /* new value */);
10545 stmt(IRStmt_CAS(cas));
10546
10547 /* Set CC. Operands compared equal -> 0, else 1. */
10548 assign(result, unop(Iop_1Uto64,
10549 binop(Iop_CmpNE64,
10550 binop(Iop_Or64,
10551 binop(Iop_Xor64, mkexpr(op1_high), mkexpr(old_mem_high)),
10552 binop(Iop_Xor64, mkexpr(op1_low), mkexpr(old_mem_low))),
10553 mkU64(0))));
10554
10555 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
10556
10557 /* If operands were equal (cc == 0) just store the old value op1 in r1.
10558 Otherwise, store the old_value from memory in r1 and yield. */
10559 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
10560 put_gpr_dw0(r1, mkite(mkexpr(nequal), mkexpr(old_mem_high), mkexpr(op1_high)));
10561 put_gpr_dw0(r1+1, mkite(mkexpr(nequal), mkexpr(old_mem_low), mkexpr(op1_low)));
florian6820ba52012-07-26 02:01:50 +000010562 yield_if(mkexpr(nequal));
10563
florian448cbba2012-06-06 02:26:01 +000010564 return "cdsg";
10565}
10566
sewardj2019a972011-03-07 16:04:07 +000010567
10568/* Binary floating point */
10569
florian55085f82012-11-21 00:36:55 +000010570static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010571s390_irgen_AXBR(UChar r1, UChar r2)
10572{
10573 IRTemp op1 = newTemp(Ity_F128);
10574 IRTemp op2 = newTemp(Ity_F128);
10575 IRTemp result = newTemp(Ity_F128);
florian125e20d2012-10-07 15:42:37 +000010576 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000010577
10578 assign(op1, get_fpr_pair(r1));
10579 assign(op2, get_fpr_pair(r2));
floriandb4fcaa2012-09-05 19:54:08 +000010580 assign(result, triop(Iop_AddF128, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +000010581 mkexpr(op2)));
10582 put_fpr_pair(r1, mkexpr(result));
10583
10584 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
10585
10586 return "axbr";
10587}
10588
10589/* The result of a Iop_CmdFxx operation is a condition code. It is
10590 encoded using the values defined in type IRCmpFxxResult.
10591 Before we can store the condition code into the guest state (or do
10592 anything else with it for that matter) we need to convert it to
10593 the encoding that s390 uses. This is what this function does.
10594
10595 s390 VEX b6 b2 b0 cc.1 cc.0
10596 0 0x40 EQ 1 0 0 0 0
10597 1 0x01 LT 0 0 1 0 1
10598 2 0x00 GT 0 0 0 1 0
10599 3 0x45 Unordered 1 1 1 1 1
10600
10601 The following bits from the VEX encoding are interesting:
10602 b0, b2, b6 with b0 being the LSB. We observe:
10603
10604 cc.0 = b0;
10605 cc.1 = b2 | (~b0 & ~b6)
10606
10607 with cc being the s390 condition code.
10608*/
10609static IRExpr *
10610convert_vex_fpcc_to_s390(IRTemp vex_cc)
10611{
10612 IRTemp cc0 = newTemp(Ity_I32);
10613 IRTemp cc1 = newTemp(Ity_I32);
10614 IRTemp b0 = newTemp(Ity_I32);
10615 IRTemp b2 = newTemp(Ity_I32);
10616 IRTemp b6 = newTemp(Ity_I32);
10617
10618 assign(b0, binop(Iop_And32, mkexpr(vex_cc), mkU32(1)));
10619 assign(b2, binop(Iop_And32, binop(Iop_Shr32, mkexpr(vex_cc), mkU8(2)),
10620 mkU32(1)));
10621 assign(b6, binop(Iop_And32, binop(Iop_Shr32, mkexpr(vex_cc), mkU8(6)),
10622 mkU32(1)));
10623
10624 assign(cc0, mkexpr(b0));
10625 assign(cc1, binop(Iop_Or32, mkexpr(b2),
10626 binop(Iop_And32,
10627 binop(Iop_Sub32, mkU32(1), mkexpr(b0)), /* ~b0 */
10628 binop(Iop_Sub32, mkU32(1), mkexpr(b6)) /* ~b6 */
10629 )));
10630
10631 return binop(Iop_Or32, mkexpr(cc0), binop(Iop_Shl32, mkexpr(cc1), mkU8(1)));
10632}
10633
florian55085f82012-11-21 00:36:55 +000010634static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010635s390_irgen_CEBR(UChar r1, UChar r2)
10636{
10637 IRTemp op1 = newTemp(Ity_F32);
10638 IRTemp op2 = newTemp(Ity_F32);
10639 IRTemp cc_vex = newTemp(Ity_I32);
10640 IRTemp cc_s390 = newTemp(Ity_I32);
10641
10642 assign(op1, get_fpr_w0(r1));
10643 assign(op2, get_fpr_w0(r2));
10644 assign(cc_vex, binop(Iop_CmpF32, mkexpr(op1), mkexpr(op2)));
10645
10646 assign(cc_s390, convert_vex_fpcc_to_s390(cc_vex));
10647 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
10648
10649 return "cebr";
10650}
10651
florian55085f82012-11-21 00:36:55 +000010652static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010653s390_irgen_CDBR(UChar r1, UChar r2)
10654{
10655 IRTemp op1 = newTemp(Ity_F64);
10656 IRTemp op2 = newTemp(Ity_F64);
10657 IRTemp cc_vex = newTemp(Ity_I32);
10658 IRTemp cc_s390 = newTemp(Ity_I32);
10659
10660 assign(op1, get_fpr_dw0(r1));
10661 assign(op2, get_fpr_dw0(r2));
10662 assign(cc_vex, binop(Iop_CmpF64, mkexpr(op1), mkexpr(op2)));
10663
10664 assign(cc_s390, convert_vex_fpcc_to_s390(cc_vex));
10665 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
10666
10667 return "cdbr";
10668}
10669
florian55085f82012-11-21 00:36:55 +000010670static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010671s390_irgen_CXBR(UChar r1, UChar r2)
10672{
10673 IRTemp op1 = newTemp(Ity_F128);
10674 IRTemp op2 = newTemp(Ity_F128);
10675 IRTemp cc_vex = newTemp(Ity_I32);
10676 IRTemp cc_s390 = newTemp(Ity_I32);
10677
10678 assign(op1, get_fpr_pair(r1));
10679 assign(op2, get_fpr_pair(r2));
10680 assign(cc_vex, binop(Iop_CmpF128, mkexpr(op1), mkexpr(op2)));
10681
10682 assign(cc_s390, convert_vex_fpcc_to_s390(cc_vex));
10683 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
10684
10685 return "cxbr";
10686}
10687
florian55085f82012-11-21 00:36:55 +000010688static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010689s390_irgen_CEB(UChar r1, IRTemp op2addr)
10690{
10691 IRTemp op1 = newTemp(Ity_F32);
10692 IRTemp op2 = newTemp(Ity_F32);
10693 IRTemp cc_vex = newTemp(Ity_I32);
10694 IRTemp cc_s390 = newTemp(Ity_I32);
10695
10696 assign(op1, get_fpr_w0(r1));
10697 assign(op2, load(Ity_F32, mkexpr(op2addr)));
10698 assign(cc_vex, binop(Iop_CmpF32, mkexpr(op1), mkexpr(op2)));
10699
10700 assign(cc_s390, convert_vex_fpcc_to_s390(cc_vex));
10701 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
10702
10703 return "ceb";
10704}
10705
florian55085f82012-11-21 00:36:55 +000010706static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010707s390_irgen_CDB(UChar r1, IRTemp op2addr)
10708{
10709 IRTemp op1 = newTemp(Ity_F64);
10710 IRTemp op2 = newTemp(Ity_F64);
10711 IRTemp cc_vex = newTemp(Ity_I32);
10712 IRTemp cc_s390 = newTemp(Ity_I32);
10713
10714 assign(op1, get_fpr_dw0(r1));
10715 assign(op2, load(Ity_F64, mkexpr(op2addr)));
10716 assign(cc_vex, binop(Iop_CmpF64, mkexpr(op1), mkexpr(op2)));
10717
10718 assign(cc_s390, convert_vex_fpcc_to_s390(cc_vex));
10719 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
10720
10721 return "cdb";
10722}
10723
florian55085f82012-11-21 00:36:55 +000010724static const HChar *
florian4b8efad2012-09-02 18:07:08 +000010725s390_irgen_CXFBR(UChar m3 __attribute__((unused)),
10726 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000010727{
10728 IRTemp op2 = newTemp(Ity_I32);
10729
10730 assign(op2, get_gpr_w1(r2));
10731 put_fpr_pair(r1, unop(Iop_I32StoF128, mkexpr(op2)));
10732
10733 return "cxfbr";
10734}
10735
florian55085f82012-11-21 00:36:55 +000010736static const HChar *
floriand2129202012-09-01 20:01:39 +000010737s390_irgen_CXLFBR(UChar m3 __attribute__((unused)),
10738 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
florian1c8f7ff2012-09-01 00:12:11 +000010739{
floriane75dafa2012-09-01 17:54:09 +000010740 if (! s390_host_has_fpext) {
10741 emulation_failure(EmFail_S390X_fpext);
10742 } else {
10743 IRTemp op2 = newTemp(Ity_I32);
florian1c8f7ff2012-09-01 00:12:11 +000010744
floriane75dafa2012-09-01 17:54:09 +000010745 assign(op2, get_gpr_w1(r2));
10746 put_fpr_pair(r1, unop(Iop_I32UtoF128, mkexpr(op2)));
10747 }
florian1c8f7ff2012-09-01 00:12:11 +000010748 return "cxlfbr";
10749}
10750
10751
florian55085f82012-11-21 00:36:55 +000010752static const HChar *
florian4b8efad2012-09-02 18:07:08 +000010753s390_irgen_CXGBR(UChar m3 __attribute__((unused)),
10754 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000010755{
10756 IRTemp op2 = newTemp(Ity_I64);
10757
10758 assign(op2, get_gpr_dw0(r2));
10759 put_fpr_pair(r1, unop(Iop_I64StoF128, mkexpr(op2)));
10760
10761 return "cxgbr";
10762}
10763
florian55085f82012-11-21 00:36:55 +000010764static const HChar *
floriand2129202012-09-01 20:01:39 +000010765s390_irgen_CXLGBR(UChar m3 __attribute__((unused)),
10766 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
florian1c8f7ff2012-09-01 00:12:11 +000010767{
floriane75dafa2012-09-01 17:54:09 +000010768 if (! s390_host_has_fpext) {
10769 emulation_failure(EmFail_S390X_fpext);
10770 } else {
10771 IRTemp op2 = newTemp(Ity_I64);
florian1c8f7ff2012-09-01 00:12:11 +000010772
floriane75dafa2012-09-01 17:54:09 +000010773 assign(op2, get_gpr_dw0(r2));
10774 put_fpr_pair(r1, unop(Iop_I64UtoF128, mkexpr(op2)));
10775 }
florian1c8f7ff2012-09-01 00:12:11 +000010776 return "cxlgbr";
10777}
10778
florian55085f82012-11-21 00:36:55 +000010779static const HChar *
florian4b8efad2012-09-02 18:07:08 +000010780s390_irgen_CFXBR(UChar m3, UChar m4 __attribute__((unused)),
10781 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000010782{
10783 IRTemp op = newTemp(Ity_F128);
10784 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +000010785 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +000010786
10787 assign(op, get_fpr_pair(r2));
florian19e00772012-09-06 03:13:22 +000010788 assign(result, binop(Iop_F128toI32S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +000010789 mkexpr(op)));
10790 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +000010791 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_INT_32, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +000010792
10793 return "cfxbr";
10794}
10795
florian55085f82012-11-21 00:36:55 +000010796static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +000010797s390_irgen_CLFXBR(UChar m3, UChar m4 __attribute__((unused)),
10798 UChar r1, UChar r2)
10799{
floriane75dafa2012-09-01 17:54:09 +000010800 if (! s390_host_has_fpext) {
10801 emulation_failure(EmFail_S390X_fpext);
10802 } else {
10803 IRTemp op = newTemp(Ity_F128);
10804 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +000010805 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +000010806
floriane75dafa2012-09-01 17:54:09 +000010807 assign(op, get_fpr_pair(r2));
florian19e00772012-09-06 03:13:22 +000010808 assign(result, binop(Iop_F128toI32U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +000010809 mkexpr(op)));
10810 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +000010811 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_UINT_32, op, rounding_mode);
floriane75dafa2012-09-01 17:54:09 +000010812 }
florian1c8f7ff2012-09-01 00:12:11 +000010813 return "clfxbr";
10814}
10815
10816
florian55085f82012-11-21 00:36:55 +000010817static const HChar *
florian4b8efad2012-09-02 18:07:08 +000010818s390_irgen_CGXBR(UChar m3, UChar m4 __attribute__((unused)),
10819 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000010820{
10821 IRTemp op = newTemp(Ity_F128);
10822 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +000010823 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +000010824
10825 assign(op, get_fpr_pair(r2));
florian19e00772012-09-06 03:13:22 +000010826 assign(result, binop(Iop_F128toI64S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +000010827 mkexpr(op)));
10828 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +000010829 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_INT_64, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +000010830
10831 return "cgxbr";
10832}
10833
florian55085f82012-11-21 00:36:55 +000010834static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +000010835s390_irgen_CLGXBR(UChar m3, UChar m4 __attribute__((unused)),
10836 UChar r1, UChar r2)
10837{
floriane75dafa2012-09-01 17:54:09 +000010838 if (! s390_host_has_fpext) {
10839 emulation_failure(EmFail_S390X_fpext);
10840 } else {
10841 IRTemp op = newTemp(Ity_F128);
10842 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +000010843 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +000010844
floriane75dafa2012-09-01 17:54:09 +000010845 assign(op, get_fpr_pair(r2));
florian19e00772012-09-06 03:13:22 +000010846 assign(result, binop(Iop_F128toI64U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +000010847 mkexpr(op)));
10848 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +000010849 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_UINT_64, op,
10850 rounding_mode);
floriane75dafa2012-09-01 17:54:09 +000010851 }
florian1c8f7ff2012-09-01 00:12:11 +000010852 return "clgxbr";
10853}
10854
florian55085f82012-11-21 00:36:55 +000010855static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010856s390_irgen_DXBR(UChar r1, UChar r2)
10857{
10858 IRTemp op1 = newTemp(Ity_F128);
10859 IRTemp op2 = newTemp(Ity_F128);
10860 IRTemp result = newTemp(Ity_F128);
florian125e20d2012-10-07 15:42:37 +000010861 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000010862
10863 assign(op1, get_fpr_pair(r1));
10864 assign(op2, get_fpr_pair(r2));
floriandb4fcaa2012-09-05 19:54:08 +000010865 assign(result, triop(Iop_DivF128, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +000010866 mkexpr(op2)));
10867 put_fpr_pair(r1, mkexpr(result));
10868
10869 return "dxbr";
10870}
10871
florian55085f82012-11-21 00:36:55 +000010872static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010873s390_irgen_LTXBR(UChar r1, UChar r2)
10874{
10875 IRTemp result = newTemp(Ity_F128);
10876
10877 assign(result, get_fpr_pair(r2));
10878 put_fpr_pair(r1, mkexpr(result));
10879 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
10880
10881 return "ltxbr";
10882}
10883
florian55085f82012-11-21 00:36:55 +000010884static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010885s390_irgen_LCXBR(UChar r1, UChar r2)
10886{
10887 IRTemp result = newTemp(Ity_F128);
10888
10889 assign(result, unop(Iop_NegF128, get_fpr_pair(r2)));
10890 put_fpr_pair(r1, mkexpr(result));
10891 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
10892
10893 return "lcxbr";
10894}
10895
florian55085f82012-11-21 00:36:55 +000010896static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010897s390_irgen_LXDBR(UChar r1, UChar r2)
10898{
10899 IRTemp op = newTemp(Ity_F64);
10900
10901 assign(op, get_fpr_dw0(r2));
10902 put_fpr_pair(r1, unop(Iop_F64toF128, mkexpr(op)));
10903
10904 return "lxdbr";
10905}
10906
florian55085f82012-11-21 00:36:55 +000010907static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010908s390_irgen_LXEBR(UChar r1, UChar r2)
10909{
10910 IRTemp op = newTemp(Ity_F32);
10911
10912 assign(op, get_fpr_w0(r2));
10913 put_fpr_pair(r1, unop(Iop_F32toF128, mkexpr(op)));
10914
10915 return "lxebr";
10916}
10917
florian55085f82012-11-21 00:36:55 +000010918static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010919s390_irgen_LXDB(UChar r1, IRTemp op2addr)
10920{
10921 IRTemp op = newTemp(Ity_F64);
10922
10923 assign(op, load(Ity_F64, mkexpr(op2addr)));
10924 put_fpr_pair(r1, unop(Iop_F64toF128, mkexpr(op)));
10925
10926 return "lxdb";
10927}
10928
florian55085f82012-11-21 00:36:55 +000010929static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010930s390_irgen_LXEB(UChar r1, IRTemp op2addr)
10931{
10932 IRTemp op = newTemp(Ity_F32);
10933
10934 assign(op, load(Ity_F32, mkexpr(op2addr)));
10935 put_fpr_pair(r1, unop(Iop_F32toF128, mkexpr(op)));
10936
10937 return "lxeb";
10938}
10939
florian55085f82012-11-21 00:36:55 +000010940static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010941s390_irgen_LNEBR(UChar r1, UChar r2)
10942{
10943 IRTemp result = newTemp(Ity_F32);
10944
10945 assign(result, unop(Iop_NegF32, unop(Iop_AbsF32, get_fpr_w0(r2))));
10946 put_fpr_w0(r1, mkexpr(result));
10947 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_32, result);
10948
10949 return "lnebr";
10950}
10951
florian55085f82012-11-21 00:36:55 +000010952static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010953s390_irgen_LNDBR(UChar r1, UChar r2)
10954{
10955 IRTemp result = newTemp(Ity_F64);
10956
10957 assign(result, unop(Iop_NegF64, unop(Iop_AbsF64, get_fpr_dw0(r2))));
10958 put_fpr_dw0(r1, mkexpr(result));
10959 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_64, result);
10960
10961 return "lndbr";
10962}
10963
florian55085f82012-11-21 00:36:55 +000010964static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010965s390_irgen_LNXBR(UChar r1, UChar r2)
10966{
10967 IRTemp result = newTemp(Ity_F128);
10968
10969 assign(result, unop(Iop_NegF128, unop(Iop_AbsF128, get_fpr_pair(r2))));
10970 put_fpr_pair(r1, mkexpr(result));
10971 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
10972
10973 return "lnxbr";
10974}
10975
florian55085f82012-11-21 00:36:55 +000010976static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010977s390_irgen_LPEBR(UChar r1, UChar r2)
10978{
10979 IRTemp result = newTemp(Ity_F32);
10980
10981 assign(result, unop(Iop_AbsF32, get_fpr_w0(r2)));
10982 put_fpr_w0(r1, mkexpr(result));
10983 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_32, result);
10984
10985 return "lpebr";
10986}
10987
florian55085f82012-11-21 00:36:55 +000010988static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010989s390_irgen_LPDBR(UChar r1, UChar r2)
10990{
10991 IRTemp result = newTemp(Ity_F64);
10992
10993 assign(result, unop(Iop_AbsF64, get_fpr_dw0(r2)));
10994 put_fpr_dw0(r1, mkexpr(result));
10995 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_64, result);
10996
10997 return "lpdbr";
10998}
10999
florian55085f82012-11-21 00:36:55 +000011000static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011001s390_irgen_LPXBR(UChar r1, UChar r2)
11002{
11003 IRTemp result = newTemp(Ity_F128);
11004
11005 assign(result, unop(Iop_AbsF128, get_fpr_pair(r2)));
11006 put_fpr_pair(r1, mkexpr(result));
11007 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
11008
11009 return "lpxbr";
11010}
11011
florian55085f82012-11-21 00:36:55 +000011012static const HChar *
florian4b8efad2012-09-02 18:07:08 +000011013s390_irgen_LDXBR(UChar m3, UChar m4 __attribute__((unused)),
11014 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000011015{
florian125e20d2012-10-07 15:42:37 +000011016 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian12b0bca2012-09-05 20:05:20 +000011017 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +000011018 m3 = S390_BFP_ROUND_PER_FPC;
florian12b0bca2012-09-05 20:05:20 +000011019 }
sewardj2019a972011-03-07 16:04:07 +000011020 IRTemp result = newTemp(Ity_F64);
11021
floriandb4fcaa2012-09-05 19:54:08 +000011022 assign(result, binop(Iop_F128toF64, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +000011023 get_fpr_pair(r2)));
sewardj2019a972011-03-07 16:04:07 +000011024 put_fpr_dw0(r1, mkexpr(result));
11025
11026 return "ldxbr";
11027}
11028
florian55085f82012-11-21 00:36:55 +000011029static const HChar *
florian4b8efad2012-09-02 18:07:08 +000011030s390_irgen_LEXBR(UChar m3, UChar m4 __attribute__((unused)),
11031 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000011032{
florian125e20d2012-10-07 15:42:37 +000011033 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian12b0bca2012-09-05 20:05:20 +000011034 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +000011035 m3 = S390_BFP_ROUND_PER_FPC;
florian12b0bca2012-09-05 20:05:20 +000011036 }
sewardj2019a972011-03-07 16:04:07 +000011037 IRTemp result = newTemp(Ity_F32);
11038
floriandb4fcaa2012-09-05 19:54:08 +000011039 assign(result, binop(Iop_F128toF32, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +000011040 get_fpr_pair(r2)));
sewardj2019a972011-03-07 16:04:07 +000011041 put_fpr_w0(r1, mkexpr(result));
11042
11043 return "lexbr";
11044}
11045
florian55085f82012-11-21 00:36:55 +000011046static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011047s390_irgen_MXBR(UChar r1, UChar r2)
11048{
11049 IRTemp op1 = newTemp(Ity_F128);
11050 IRTemp op2 = newTemp(Ity_F128);
11051 IRTemp result = newTemp(Ity_F128);
florian125e20d2012-10-07 15:42:37 +000011052 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011053
11054 assign(op1, get_fpr_pair(r1));
11055 assign(op2, get_fpr_pair(r2));
floriandb4fcaa2012-09-05 19:54:08 +000011056 assign(result, triop(Iop_MulF128, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +000011057 mkexpr(op2)));
11058 put_fpr_pair(r1, mkexpr(result));
11059
11060 return "mxbr";
11061}
11062
florian55085f82012-11-21 00:36:55 +000011063static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011064s390_irgen_MAEBR(UChar r1, UChar r3, UChar r2)
11065{
florian125e20d2012-10-07 15:42:37 +000011066 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
florian847684d2012-09-05 04:19:09 +000011067
floriandb4fcaa2012-09-05 19:54:08 +000011068 put_fpr_w0(r1, qop(Iop_MAddF32, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000011069 get_fpr_w0(r3), get_fpr_w0(r2), get_fpr_w0(r1)));
sewardj2019a972011-03-07 16:04:07 +000011070
11071 return "maebr";
11072}
11073
florian55085f82012-11-21 00:36:55 +000011074static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011075s390_irgen_MADBR(UChar r1, UChar r3, UChar r2)
11076{
florian125e20d2012-10-07 15:42:37 +000011077 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
florian847684d2012-09-05 04:19:09 +000011078
floriandb4fcaa2012-09-05 19:54:08 +000011079 put_fpr_dw0(r1, qop(Iop_MAddF64, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000011080 get_fpr_dw0(r3), get_fpr_dw0(r2), get_fpr_dw0(r1)));
sewardj2019a972011-03-07 16:04:07 +000011081
11082 return "madbr";
11083}
11084
florian55085f82012-11-21 00:36:55 +000011085static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011086s390_irgen_MAEB(UChar r3, IRTemp op2addr, UChar r1)
11087{
11088 IRExpr *op2 = load(Ity_F32, mkexpr(op2addr));
florian125e20d2012-10-07 15:42:37 +000011089 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011090
floriandb4fcaa2012-09-05 19:54:08 +000011091 put_fpr_w0(r1, qop(Iop_MAddF32, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000011092 get_fpr_w0(r3), op2, get_fpr_w0(r1)));
sewardj2019a972011-03-07 16:04:07 +000011093
11094 return "maeb";
11095}
11096
florian55085f82012-11-21 00:36:55 +000011097static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011098s390_irgen_MADB(UChar r3, IRTemp op2addr, UChar r1)
11099{
11100 IRExpr *op2 = load(Ity_F64, mkexpr(op2addr));
florian125e20d2012-10-07 15:42:37 +000011101 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011102
floriandb4fcaa2012-09-05 19:54:08 +000011103 put_fpr_dw0(r1, qop(Iop_MAddF64, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000011104 get_fpr_dw0(r3), op2, get_fpr_dw0(r1)));
sewardj2019a972011-03-07 16:04:07 +000011105
11106 return "madb";
11107}
11108
florian55085f82012-11-21 00:36:55 +000011109static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011110s390_irgen_MSEBR(UChar r1, UChar r3, UChar r2)
11111{
florian125e20d2012-10-07 15:42:37 +000011112 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
florian847684d2012-09-05 04:19:09 +000011113
floriandb4fcaa2012-09-05 19:54:08 +000011114 put_fpr_w0(r1, qop(Iop_MSubF32, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000011115 get_fpr_w0(r3), get_fpr_w0(r2), get_fpr_w0(r1)));
sewardj2019a972011-03-07 16:04:07 +000011116
11117 return "msebr";
11118}
11119
florian55085f82012-11-21 00:36:55 +000011120static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011121s390_irgen_MSDBR(UChar r1, UChar r3, UChar r2)
11122{
florian125e20d2012-10-07 15:42:37 +000011123 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
florian847684d2012-09-05 04:19:09 +000011124
floriandb4fcaa2012-09-05 19:54:08 +000011125 put_fpr_dw0(r1, qop(Iop_MSubF64, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000011126 get_fpr_dw0(r3), get_fpr_dw0(r2), get_fpr_dw0(r1)));
sewardj2019a972011-03-07 16:04:07 +000011127
11128 return "msdbr";
11129}
11130
florian55085f82012-11-21 00:36:55 +000011131static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011132s390_irgen_MSEB(UChar r3, IRTemp op2addr, UChar r1)
11133{
11134 IRExpr *op2 = load(Ity_F32, mkexpr(op2addr));
florian125e20d2012-10-07 15:42:37 +000011135 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011136
floriandb4fcaa2012-09-05 19:54:08 +000011137 put_fpr_w0(r1, qop(Iop_MSubF32, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000011138 get_fpr_w0(r3), op2, get_fpr_w0(r1)));
sewardj2019a972011-03-07 16:04:07 +000011139
11140 return "mseb";
11141}
11142
florian55085f82012-11-21 00:36:55 +000011143static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011144s390_irgen_MSDB(UChar r3, IRTemp op2addr, UChar r1)
11145{
11146 IRExpr *op2 = load(Ity_F64, mkexpr(op2addr));
florian125e20d2012-10-07 15:42:37 +000011147 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011148
floriandb4fcaa2012-09-05 19:54:08 +000011149 put_fpr_dw0(r1, qop(Iop_MSubF64, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000011150 get_fpr_dw0(r3), op2, get_fpr_dw0(r1)));
sewardj2019a972011-03-07 16:04:07 +000011151
11152 return "msdb";
11153}
11154
florian55085f82012-11-21 00:36:55 +000011155static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011156s390_irgen_SQEBR(UChar r1, UChar r2)
11157{
11158 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +000011159 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011160
floriandb4fcaa2012-09-05 19:54:08 +000011161 assign(result, binop(Iop_SqrtF32, mkexpr(rounding_mode), get_fpr_w0(r2)));
sewardj2019a972011-03-07 16:04:07 +000011162 put_fpr_w0(r1, mkexpr(result));
11163
11164 return "sqebr";
11165}
11166
florian55085f82012-11-21 00:36:55 +000011167static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011168s390_irgen_SQDBR(UChar r1, UChar r2)
11169{
11170 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +000011171 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011172
floriandb4fcaa2012-09-05 19:54:08 +000011173 assign(result, binop(Iop_SqrtF64, mkexpr(rounding_mode), get_fpr_dw0(r2)));
sewardj2019a972011-03-07 16:04:07 +000011174 put_fpr_dw0(r1, mkexpr(result));
11175
11176 return "sqdbr";
11177}
11178
florian55085f82012-11-21 00:36:55 +000011179static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011180s390_irgen_SQXBR(UChar r1, UChar r2)
11181{
11182 IRTemp result = newTemp(Ity_F128);
florian125e20d2012-10-07 15:42:37 +000011183 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011184
floriandb4fcaa2012-09-05 19:54:08 +000011185 assign(result, binop(Iop_SqrtF128, mkexpr(rounding_mode),
11186 get_fpr_pair(r2)));
sewardj2019a972011-03-07 16:04:07 +000011187 put_fpr_pair(r1, mkexpr(result));
11188
11189 return "sqxbr";
11190}
11191
florian55085f82012-11-21 00:36:55 +000011192static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011193s390_irgen_SQEB(UChar r1, IRTemp op2addr)
11194{
11195 IRTemp op = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +000011196 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011197
11198 assign(op, load(Ity_F32, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +000011199 put_fpr_w0(r1, binop(Iop_SqrtF32, mkexpr(rounding_mode), mkexpr(op)));
sewardj2019a972011-03-07 16:04:07 +000011200
11201 return "sqeb";
11202}
11203
florian55085f82012-11-21 00:36:55 +000011204static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011205s390_irgen_SQDB(UChar r1, IRTemp op2addr)
11206{
11207 IRTemp op = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +000011208 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011209
11210 assign(op, load(Ity_F64, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +000011211 put_fpr_dw0(r1, binop(Iop_SqrtF64, mkexpr(rounding_mode), mkexpr(op)));
sewardj2019a972011-03-07 16:04:07 +000011212
11213 return "sqdb";
11214}
11215
florian55085f82012-11-21 00:36:55 +000011216static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011217s390_irgen_SXBR(UChar r1, UChar r2)
11218{
11219 IRTemp op1 = newTemp(Ity_F128);
11220 IRTemp op2 = newTemp(Ity_F128);
11221 IRTemp result = newTemp(Ity_F128);
florian125e20d2012-10-07 15:42:37 +000011222 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011223
11224 assign(op1, get_fpr_pair(r1));
11225 assign(op2, get_fpr_pair(r2));
floriandb4fcaa2012-09-05 19:54:08 +000011226 assign(result, triop(Iop_SubF128, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +000011227 mkexpr(op2)));
11228 put_fpr_pair(r1, mkexpr(result));
11229 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
11230
11231 return "sxbr";
11232}
11233
florian55085f82012-11-21 00:36:55 +000011234static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011235s390_irgen_TCEB(UChar r1, IRTemp op2addr)
11236{
11237 IRTemp value = newTemp(Ity_F32);
11238
11239 assign(value, get_fpr_w0(r1));
11240
11241 s390_cc_thunk_putFZ(S390_CC_OP_BFP_TDC_32, value, op2addr);
11242
11243 return "tceb";
11244}
11245
florian55085f82012-11-21 00:36:55 +000011246static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011247s390_irgen_TCDB(UChar r1, IRTemp op2addr)
11248{
11249 IRTemp value = newTemp(Ity_F64);
11250
11251 assign(value, get_fpr_dw0(r1));
11252
11253 s390_cc_thunk_putFZ(S390_CC_OP_BFP_TDC_64, value, op2addr);
11254
11255 return "tcdb";
11256}
11257
florian55085f82012-11-21 00:36:55 +000011258static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011259s390_irgen_TCXB(UChar r1, IRTemp op2addr)
11260{
11261 IRTemp value = newTemp(Ity_F128);
11262
11263 assign(value, get_fpr_pair(r1));
11264
11265 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_TDC_128, value, op2addr);
11266
11267 return "tcxb";
11268}
11269
florian55085f82012-11-21 00:36:55 +000011270static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011271s390_irgen_LCDFR(UChar r1, UChar r2)
11272{
11273 IRTemp result = newTemp(Ity_F64);
11274
11275 assign(result, unop(Iop_NegF64, get_fpr_dw0(r2)));
11276 put_fpr_dw0(r1, mkexpr(result));
11277
11278 return "lcdfr";
11279}
11280
florian55085f82012-11-21 00:36:55 +000011281static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011282s390_irgen_LNDFR(UChar r1, UChar r2)
11283{
11284 IRTemp result = newTemp(Ity_F64);
11285
11286 assign(result, unop(Iop_NegF64, unop(Iop_AbsF64, get_fpr_dw0(r2))));
11287 put_fpr_dw0(r1, mkexpr(result));
11288
11289 return "lndfr";
11290}
11291
florian55085f82012-11-21 00:36:55 +000011292static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011293s390_irgen_LPDFR(UChar r1, UChar r2)
11294{
11295 IRTemp result = newTemp(Ity_F64);
11296
11297 assign(result, unop(Iop_AbsF64, get_fpr_dw0(r2)));
11298 put_fpr_dw0(r1, mkexpr(result));
11299
11300 return "lpdfr";
11301}
11302
florian55085f82012-11-21 00:36:55 +000011303static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011304s390_irgen_LDGR(UChar r1, UChar r2)
11305{
11306 put_fpr_dw0(r1, unop(Iop_ReinterpI64asF64, get_gpr_dw0(r2)));
11307
11308 return "ldgr";
11309}
11310
florian55085f82012-11-21 00:36:55 +000011311static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011312s390_irgen_LGDR(UChar r1, UChar r2)
11313{
11314 put_gpr_dw0(r1, unop(Iop_ReinterpF64asI64, get_fpr_dw0(r2)));
11315
11316 return "lgdr";
11317}
11318
11319
florian55085f82012-11-21 00:36:55 +000011320static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011321s390_irgen_CPSDR(UChar r3, UChar r1, UChar r2)
11322{
11323 IRTemp sign = newTemp(Ity_I64);
11324 IRTemp value = newTemp(Ity_I64);
11325
11326 assign(sign, binop(Iop_And64, unop(Iop_ReinterpF64asI64, get_fpr_dw0(r3)),
11327 mkU64(1ULL << 63)));
11328 assign(value, binop(Iop_And64, unop(Iop_ReinterpF64asI64, get_fpr_dw0(r2)),
11329 mkU64((1ULL << 63) - 1)));
11330 put_fpr_dw0(r1, unop(Iop_ReinterpI64asF64, binop(Iop_Or64, mkexpr(value),
11331 mkexpr(sign))));
11332
11333 return "cpsdr";
11334}
11335
11336
sewardj2019a972011-03-07 16:04:07 +000011337static IRExpr *
11338s390_call_cvb(IRExpr *in)
11339{
11340 IRExpr **args, *call;
11341
11342 args = mkIRExprVec_1(in);
11343 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
11344 "s390_do_cvb", &s390_do_cvb, args);
11345
11346 /* Nothing is excluded from definedness checking. */
11347 call->Iex.CCall.cee->mcx_mask = 0;
11348
11349 return call;
11350}
11351
florian55085f82012-11-21 00:36:55 +000011352static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011353s390_irgen_CVB(UChar r1, IRTemp op2addr)
11354{
11355 put_gpr_w1(r1, s390_call_cvb(load(Ity_I64, mkexpr(op2addr))));
11356
11357 return "cvb";
11358}
11359
florian55085f82012-11-21 00:36:55 +000011360static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011361s390_irgen_CVBY(UChar r1, IRTemp op2addr)
11362{
11363 put_gpr_w1(r1, s390_call_cvb(load(Ity_I64, mkexpr(op2addr))));
11364
11365 return "cvby";
11366}
11367
11368
sewardj2019a972011-03-07 16:04:07 +000011369static IRExpr *
11370s390_call_cvd(IRExpr *in)
11371{
11372 IRExpr **args, *call;
11373
11374 args = mkIRExprVec_1(in);
11375 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
11376 "s390_do_cvd", &s390_do_cvd, args);
11377
11378 /* Nothing is excluded from definedness checking. */
11379 call->Iex.CCall.cee->mcx_mask = 0;
11380
11381 return call;
11382}
11383
florian55085f82012-11-21 00:36:55 +000011384static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011385s390_irgen_CVD(UChar r1, IRTemp op2addr)
11386{
florian11b8ee82012-08-06 13:35:33 +000011387 store(mkexpr(op2addr), s390_call_cvd(unop(Iop_32Uto64, get_gpr_w1(r1))));
sewardj2019a972011-03-07 16:04:07 +000011388
11389 return "cvd";
11390}
11391
florian55085f82012-11-21 00:36:55 +000011392static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011393s390_irgen_CVDY(UChar r1, IRTemp op2addr)
11394{
11395 store(mkexpr(op2addr), s390_call_cvd(get_gpr_w1(r1)));
11396
11397 return "cvdy";
11398}
11399
florian55085f82012-11-21 00:36:55 +000011400static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011401s390_irgen_FLOGR(UChar r1, UChar r2)
11402{
11403 IRTemp input = newTemp(Ity_I64);
11404 IRTemp not_zero = newTemp(Ity_I64);
11405 IRTemp tmpnum = newTemp(Ity_I64);
11406 IRTemp num = newTemp(Ity_I64);
11407 IRTemp shift_amount = newTemp(Ity_I8);
11408
11409 /* We use the "count leading zeroes" operator because the number of
11410 leading zeroes is identical with the bit position of the first '1' bit.
11411 However, that operator does not work when the input value is zero.
11412 Therefore, we set the LSB of the input value to 1 and use Clz64 on
11413 the modified value. If input == 0, then the result is 64. Otherwise,
11414 the result of Clz64 is what we want. */
11415
11416 assign(input, get_gpr_dw0(r2));
11417 assign(not_zero, binop(Iop_Or64, mkexpr(input), mkU64(1)));
11418 assign(tmpnum, unop(Iop_Clz64, mkexpr(not_zero)));
11419
11420 /* num = (input == 0) ? 64 : tmpnum */
11421 assign(num, mkite(binop(Iop_CmpEQ64, mkexpr(input), mkU64(0)),
11422 /* == 0 */ mkU64(64),
11423 /* != 0 */ mkexpr(tmpnum)));
11424
11425 put_gpr_dw0(r1, mkexpr(num));
11426
11427 /* Set the leftmost '1' bit of the input value to zero. The general scheme
11428 is to first shift the input value by NUM + 1 bits to the left which
11429 causes the leftmost '1' bit to disappear. Then we shift logically to
11430 the right by NUM + 1 bits. Because the semantics of Iop_Shl64 and
11431 Iop_Shr64 are undefined if the shift-amount is greater than or equal to
11432 the width of the value-to-be-shifted, we need to special case
11433 NUM + 1 >= 64. This is equivalent to INPUT != 0 && INPUT != 1.
11434 For both such INPUT values the result will be 0. */
11435
11436 assign(shift_amount, unop(Iop_64to8, binop(Iop_Add64, mkexpr(num),
11437 mkU64(1))));
11438
11439 put_gpr_dw0(r1 + 1,
florian6ad49522011-09-09 02:38:55 +000011440 mkite(binop(Iop_CmpLE64U, mkexpr(input), mkU64(1)),
11441 /* == 0 || == 1*/ mkU64(0),
11442 /* otherwise */
11443 binop(Iop_Shr64,
11444 binop(Iop_Shl64, mkexpr(input),
11445 mkexpr(shift_amount)),
11446 mkexpr(shift_amount))));
sewardj2019a972011-03-07 16:04:07 +000011447
11448 /* Compare the original value as an unsigned integer with 0. */
11449 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, input,
11450 mktemp(Ity_I64, mkU64(0)), False);
11451
11452 return "flogr";
11453}
11454
florian55085f82012-11-21 00:36:55 +000011455static const HChar *
sewardj1e5fea62011-05-17 16:18:36 +000011456s390_irgen_STCK(IRTemp op2addr)
11457{
11458 IRDirty *d;
11459 IRTemp cc = newTemp(Ity_I64);
11460
11461 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STCK",
11462 &s390x_dirtyhelper_STCK,
11463 mkIRExprVec_1(mkexpr(op2addr)));
11464 d->mFx = Ifx_Write;
11465 d->mAddr = mkexpr(op2addr);
11466 d->mSize = 8;
11467 stmt(IRStmt_Dirty(d));
11468 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
11469 mkexpr(cc), mkU64(0), mkU64(0));
11470 return "stck";
11471}
11472
florian55085f82012-11-21 00:36:55 +000011473static const HChar *
sewardj1e5fea62011-05-17 16:18:36 +000011474s390_irgen_STCKF(IRTemp op2addr)
11475{
florianc5c669b2012-08-26 14:32:28 +000011476 if (! s390_host_has_stckf) {
floriane75dafa2012-09-01 17:54:09 +000011477 emulation_failure(EmFail_S390X_stckf);
florianc5c669b2012-08-26 14:32:28 +000011478 } else {
11479 IRTemp cc = newTemp(Ity_I64);
sewardj1e5fea62011-05-17 16:18:36 +000011480
florianc5c669b2012-08-26 14:32:28 +000011481 IRDirty *d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STCKF",
11482 &s390x_dirtyhelper_STCKF,
11483 mkIRExprVec_1(mkexpr(op2addr)));
11484 d->mFx = Ifx_Write;
11485 d->mAddr = mkexpr(op2addr);
11486 d->mSize = 8;
11487 stmt(IRStmt_Dirty(d));
11488 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
11489 mkexpr(cc), mkU64(0), mkU64(0));
11490 }
sewardj1e5fea62011-05-17 16:18:36 +000011491 return "stckf";
11492}
11493
florian55085f82012-11-21 00:36:55 +000011494static const HChar *
sewardj1e5fea62011-05-17 16:18:36 +000011495s390_irgen_STCKE(IRTemp op2addr)
11496{
11497 IRDirty *d;
11498 IRTemp cc = newTemp(Ity_I64);
11499
11500 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STCKE",
11501 &s390x_dirtyhelper_STCKE,
11502 mkIRExprVec_1(mkexpr(op2addr)));
11503 d->mFx = Ifx_Write;
11504 d->mAddr = mkexpr(op2addr);
11505 d->mSize = 16;
11506 stmt(IRStmt_Dirty(d));
11507 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
11508 mkexpr(cc), mkU64(0), mkU64(0));
11509 return "stcke";
11510}
11511
florian55085f82012-11-21 00:36:55 +000011512static const HChar *
florian933065d2011-07-11 01:48:02 +000011513s390_irgen_STFLE(IRTemp op2addr)
11514{
florian4e0083e2012-08-26 03:41:56 +000011515 if (! s390_host_has_stfle) {
floriane75dafa2012-09-01 17:54:09 +000011516 emulation_failure(EmFail_S390X_stfle);
florian4e0083e2012-08-26 03:41:56 +000011517 return "stfle";
11518 }
11519
florian933065d2011-07-11 01:48:02 +000011520 IRDirty *d;
11521 IRTemp cc = newTemp(Ity_I64);
11522
11523 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STFLE",
11524 &s390x_dirtyhelper_STFLE,
11525 mkIRExprVec_1(mkexpr(op2addr)));
11526
11527 d->needsBBP = 1; /* Need to pass pointer to guest state to helper */
11528
sewardjc9069f22012-06-01 16:09:50 +000011529 d->nFxState = 1;
11530 vex_bzero(&d->fxState, sizeof(d->fxState));
11531
florian933065d2011-07-11 01:48:02 +000011532 d->fxState[0].fx = Ifx_Modify; /* read then write */
11533 d->fxState[0].offset = S390X_GUEST_OFFSET(guest_r0);
11534 d->fxState[0].size = sizeof(ULong);
florian933065d2011-07-11 01:48:02 +000011535
11536 d->mAddr = mkexpr(op2addr);
11537 /* Pretend all double words are written */
11538 d->mSize = S390_NUM_FACILITY_DW * sizeof(ULong);
11539 d->mFx = Ifx_Write;
11540
11541 stmt(IRStmt_Dirty(d));
11542
11543 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET), mkexpr(cc), mkU64(0), mkU64(0));
11544
11545 return "stfle";
11546}
11547
florian55085f82012-11-21 00:36:55 +000011548static const HChar *
floriana4384a32011-08-11 16:58:45 +000011549s390_irgen_CKSM(UChar r1,UChar r2)
11550{
11551 IRTemp addr = newTemp(Ity_I64);
11552 IRTemp op = newTemp(Ity_I32);
11553 IRTemp len = newTemp(Ity_I64);
11554 IRTemp oldval = newTemp(Ity_I32);
11555 IRTemp mask = newTemp(Ity_I32);
11556 IRTemp newop = newTemp(Ity_I32);
11557 IRTemp result = newTemp(Ity_I32);
11558 IRTemp result1 = newTemp(Ity_I32);
11559 IRTemp inc = newTemp(Ity_I64);
11560
11561 assign(oldval, get_gpr_w1(r1));
11562 assign(addr, get_gpr_dw0(r2));
11563 assign(len, get_gpr_dw0(r2+1));
11564
11565 /* Condition code is always zero. */
11566 s390_cc_set(0);
11567
11568 /* If length is zero, there is no need to calculate the checksum */
florian6820ba52012-07-26 02:01:50 +000011569 next_insn_if(binop(Iop_CmpEQ64, mkexpr(len), mkU64(0)));
floriana4384a32011-08-11 16:58:45 +000011570
11571 /* Assiging the increment variable to adjust address and length
11572 later on. */
11573 assign(inc, mkite(binop(Iop_CmpLT64U, mkexpr(len), mkU64(4)),
11574 mkexpr(len), mkU64(4)));
11575
11576 /* If length < 4 the final 4-byte 2nd operand value is computed by
11577 appending the remaining bytes to the right with 0. This is done
11578 by AND'ing the 4 bytes loaded from memory with an appropriate
11579 mask. If length >= 4, that mask is simply 0xffffffff. */
11580
11581 assign(mask, mkite(binop(Iop_CmpLT64U, mkexpr(len), mkU64(4)),
11582 /* Mask computation when len < 4:
11583 0xffffffff << (32 - (len % 4)*8) */
11584 binop(Iop_Shl32, mkU32(0xffffffff),
11585 unop(Iop_32to8,
11586 binop(Iop_Sub32, mkU32(32),
11587 binop(Iop_Shl32,
11588 unop(Iop_64to32,
11589 binop(Iop_And64,
11590 mkexpr(len), mkU64(3))),
11591 mkU8(3))))),
11592 mkU32(0xffffffff)));
11593
11594 assign(op, load(Ity_I32, mkexpr(addr)));
11595 assign(newop, binop(Iop_And32, mkexpr(op), mkexpr(mask)));
11596 assign(result, binop(Iop_Add32, mkexpr(newop), mkexpr(oldval)));
11597
11598 /* Checking for carry */
11599 assign(result1, mkite(binop(Iop_CmpLT32U, mkexpr(result), mkexpr(newop)),
11600 binop(Iop_Add32, mkexpr(result), mkU32(1)),
11601 mkexpr(result)));
11602
11603 put_gpr_w1(r1, mkexpr(result1));
11604 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr), mkexpr(inc)));
11605 put_gpr_dw0(r2+1, binop(Iop_Sub64, mkexpr(len), mkexpr(inc)));
11606
florian6820ba52012-07-26 02:01:50 +000011607 iterate_if(binop(Iop_CmpNE64, mkexpr(len), mkU64(0)));
floriana4384a32011-08-11 16:58:45 +000011608
11609 return "cksm";
11610}
11611
florian55085f82012-11-21 00:36:55 +000011612static const HChar *
florian9af37692012-01-15 21:01:16 +000011613s390_irgen_TROO(UChar m3, UChar r1, UChar r2)
11614{
11615 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
11616 src_addr = newTemp(Ity_I64);
11617 des_addr = newTemp(Ity_I64);
11618 tab_addr = newTemp(Ity_I64);
11619 test_byte = newTemp(Ity_I8);
11620 src_len = newTemp(Ity_I64);
11621
11622 assign(src_addr, get_gpr_dw0(r2));
11623 assign(des_addr, get_gpr_dw0(r1));
11624 assign(tab_addr, get_gpr_dw0(1));
florian53518532012-01-18 14:00:31 +000011625 assign(src_len, get_gpr_dw0(r1+1));
florian9af37692012-01-15 21:01:16 +000011626 assign(test_byte, get_gpr_b7(0));
11627
11628 IRTemp op = newTemp(Ity_I8);
11629 IRTemp op1 = newTemp(Ity_I8);
11630 IRTemp result = newTemp(Ity_I64);
11631
11632 /* End of source string? We're done; proceed to next insn */
11633 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000011634 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian9af37692012-01-15 21:01:16 +000011635
11636 /* Load character from source string, index translation table and
11637 store translated character in op1. */
11638 assign(op, load(Ity_I8, mkexpr(src_addr)));
11639
11640 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)),
11641 mkexpr(tab_addr)));
11642 assign(op1, load(Ity_I8, mkexpr(result)));
11643
11644 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
11645 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000011646 next_insn_if(binop(Iop_CmpEQ8, mkexpr(op1), mkexpr(test_byte)));
florian9af37692012-01-15 21:01:16 +000011647 }
11648 store(get_gpr_dw0(r1), mkexpr(op1));
11649
11650 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(1)));
11651 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(1)));
11652 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(1)));
11653
florian6820ba52012-07-26 02:01:50 +000011654 iterate();
florian9af37692012-01-15 21:01:16 +000011655
11656 return "troo";
11657}
11658
florian55085f82012-11-21 00:36:55 +000011659static const HChar *
florian730448f2012-02-04 17:07:07 +000011660s390_irgen_TRTO(UChar m3, UChar r1, UChar r2)
11661{
11662 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
11663 src_addr = newTemp(Ity_I64);
11664 des_addr = newTemp(Ity_I64);
11665 tab_addr = newTemp(Ity_I64);
11666 test_byte = newTemp(Ity_I8);
11667 src_len = newTemp(Ity_I64);
11668
11669 assign(src_addr, get_gpr_dw0(r2));
11670 assign(des_addr, get_gpr_dw0(r1));
11671 assign(tab_addr, get_gpr_dw0(1));
11672 assign(src_len, get_gpr_dw0(r1+1));
11673 assign(test_byte, get_gpr_b7(0));
11674
11675 IRTemp op = newTemp(Ity_I16);
11676 IRTemp op1 = newTemp(Ity_I8);
11677 IRTemp result = newTemp(Ity_I64);
11678
11679 /* End of source string? We're done; proceed to next insn */
11680 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000011681 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian730448f2012-02-04 17:07:07 +000011682
11683 /* Load character from source string, index translation table and
11684 store translated character in op1. */
11685 assign(op, load(Ity_I16, mkexpr(src_addr)));
11686
11687 assign(result, binop(Iop_Add64, unop(Iop_16Uto64, mkexpr(op)),
11688 mkexpr(tab_addr)));
11689
11690 assign(op1, load(Ity_I8, mkexpr(result)));
11691
11692 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
11693 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000011694 next_insn_if(binop(Iop_CmpEQ8, mkexpr(op1), mkexpr(test_byte)));
florian730448f2012-02-04 17:07:07 +000011695 }
11696 store(get_gpr_dw0(r1), mkexpr(op1));
11697
11698 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(2)));
11699 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(1)));
11700 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(2)));
11701
florian6820ba52012-07-26 02:01:50 +000011702 iterate();
florian730448f2012-02-04 17:07:07 +000011703
11704 return "trto";
11705}
11706
florian55085f82012-11-21 00:36:55 +000011707static const HChar *
florian730448f2012-02-04 17:07:07 +000011708s390_irgen_TROT(UChar m3, UChar r1, UChar r2)
11709{
11710 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
11711 src_addr = newTemp(Ity_I64);
11712 des_addr = newTemp(Ity_I64);
11713 tab_addr = newTemp(Ity_I64);
11714 test_byte = newTemp(Ity_I16);
11715 src_len = newTemp(Ity_I64);
11716
11717 assign(src_addr, get_gpr_dw0(r2));
11718 assign(des_addr, get_gpr_dw0(r1));
11719 assign(tab_addr, get_gpr_dw0(1));
11720 assign(src_len, get_gpr_dw0(r1+1));
11721 assign(test_byte, get_gpr_hw3(0));
11722
11723 IRTemp op = newTemp(Ity_I8);
11724 IRTemp op1 = newTemp(Ity_I16);
11725 IRTemp result = newTemp(Ity_I64);
11726
11727 /* End of source string? We're done; proceed to next insn */
11728 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000011729 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian730448f2012-02-04 17:07:07 +000011730
11731 /* Load character from source string, index translation table and
11732 store translated character in op1. */
11733 assign(op, binop(Iop_Shl8, load(Ity_I8, mkexpr(src_addr)), mkU8(1)));
11734
11735 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)),
11736 mkexpr(tab_addr)));
11737 assign(op1, load(Ity_I16, mkexpr(result)));
11738
11739 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
11740 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000011741 next_insn_if(binop(Iop_CmpEQ16, mkexpr(op1), mkexpr(test_byte)));
florian730448f2012-02-04 17:07:07 +000011742 }
11743 store(get_gpr_dw0(r1), mkexpr(op1));
11744
11745 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(1)));
11746 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(2)));
11747 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(1)));
11748
florian6820ba52012-07-26 02:01:50 +000011749 iterate();
florian730448f2012-02-04 17:07:07 +000011750
11751 return "trot";
11752}
11753
florian55085f82012-11-21 00:36:55 +000011754static const HChar *
florian730448f2012-02-04 17:07:07 +000011755s390_irgen_TRTT(UChar m3, UChar r1, UChar r2)
11756{
11757 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
11758 src_addr = newTemp(Ity_I64);
11759 des_addr = newTemp(Ity_I64);
11760 tab_addr = newTemp(Ity_I64);
11761 test_byte = newTemp(Ity_I16);
11762 src_len = newTemp(Ity_I64);
11763
11764 assign(src_addr, get_gpr_dw0(r2));
11765 assign(des_addr, get_gpr_dw0(r1));
11766 assign(tab_addr, get_gpr_dw0(1));
11767 assign(src_len, get_gpr_dw0(r1+1));
11768 assign(test_byte, get_gpr_hw3(0));
11769
11770 IRTemp op = newTemp(Ity_I16);
11771 IRTemp op1 = newTemp(Ity_I16);
11772 IRTemp result = newTemp(Ity_I64);
11773
11774 /* End of source string? We're done; proceed to next insn */
11775 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000011776 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian730448f2012-02-04 17:07:07 +000011777
11778 /* Load character from source string, index translation table and
11779 store translated character in op1. */
11780 assign(op, binop(Iop_Shl16, load(Ity_I16, mkexpr(src_addr)), mkU8(1)));
11781
11782 assign(result, binop(Iop_Add64, unop(Iop_16Uto64, mkexpr(op)),
11783 mkexpr(tab_addr)));
11784 assign(op1, load(Ity_I16, mkexpr(result)));
11785
11786 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
11787 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000011788 next_insn_if(binop(Iop_CmpEQ16, mkexpr(op1), mkexpr(test_byte)));
florian730448f2012-02-04 17:07:07 +000011789 }
11790
11791 store(get_gpr_dw0(r1), mkexpr(op1));
11792
11793 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(2)));
11794 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(2)));
11795 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(2)));
11796
florian6820ba52012-07-26 02:01:50 +000011797 iterate();
florian730448f2012-02-04 17:07:07 +000011798
11799 return "trtt";
11800}
11801
florian55085f82012-11-21 00:36:55 +000011802static const HChar *
florian730448f2012-02-04 17:07:07 +000011803s390_irgen_TR(UChar length, IRTemp start1, IRTemp start2)
11804{
florianf87d4fb2012-05-05 02:55:24 +000011805 IRTemp len = newTemp(Ity_I64);
florian730448f2012-02-04 17:07:07 +000011806
florianf87d4fb2012-05-05 02:55:24 +000011807 assign(len, mkU64(length));
11808 s390_irgen_TR_EX(len, start1, start2);
florian730448f2012-02-04 17:07:07 +000011809
11810 return "tr";
11811}
11812
florian55085f82012-11-21 00:36:55 +000011813static const HChar *
florian730448f2012-02-04 17:07:07 +000011814s390_irgen_TRE(UChar r1,UChar r2)
11815{
11816 IRTemp src_addr, tab_addr, src_len, test_byte;
11817 src_addr = newTemp(Ity_I64);
11818 tab_addr = newTemp(Ity_I64);
11819 src_len = newTemp(Ity_I64);
11820 test_byte = newTemp(Ity_I8);
11821
11822 assign(src_addr, get_gpr_dw0(r1));
11823 assign(src_len, get_gpr_dw0(r1+1));
11824 assign(tab_addr, get_gpr_dw0(r2));
11825 assign(test_byte, get_gpr_b7(0));
11826
11827 IRTemp op = newTemp(Ity_I8);
11828 IRTemp op1 = newTemp(Ity_I8);
11829 IRTemp result = newTemp(Ity_I64);
11830
11831 /* End of source string? We're done; proceed to next insn */
11832 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000011833 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian730448f2012-02-04 17:07:07 +000011834
11835 /* Load character from source string and compare with test byte */
11836 assign(op, load(Ity_I8, mkexpr(src_addr)));
11837
11838 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000011839 next_insn_if(binop(Iop_CmpEQ8, mkexpr(op), mkexpr(test_byte)));
florian730448f2012-02-04 17:07:07 +000011840
11841 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)),
11842 mkexpr(tab_addr)));
11843
11844 assign(op1, load(Ity_I8, mkexpr(result)));
11845
11846 store(get_gpr_dw0(r1), mkexpr(op1));
11847 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(src_addr), mkU64(1)));
11848 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(1)));
11849
florian6820ba52012-07-26 02:01:50 +000011850 iterate();
florian730448f2012-02-04 17:07:07 +000011851
11852 return "tre";
11853}
11854
floriana0100c92012-07-20 00:06:35 +000011855static IRExpr *
11856s390_call_cu21(IRExpr *srcval, IRExpr *low_surrogate)
11857{
11858 IRExpr **args, *call;
11859 args = mkIRExprVec_2(srcval, low_surrogate);
11860 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
11861 "s390_do_cu21", &s390_do_cu21, args);
11862
11863 /* Nothing is excluded from definedness checking. */
11864 call->Iex.CCall.cee->mcx_mask = 0;
11865
11866 return call;
11867}
11868
florian55085f82012-11-21 00:36:55 +000011869static const HChar *
floriana0100c92012-07-20 00:06:35 +000011870s390_irgen_CU21(UChar m3, UChar r1, UChar r2)
11871{
11872 IRTemp addr1 = newTemp(Ity_I64);
11873 IRTemp addr2 = newTemp(Ity_I64);
11874 IRTemp len1 = newTemp(Ity_I64);
11875 IRTemp len2 = newTemp(Ity_I64);
11876
11877 assign(addr1, get_gpr_dw0(r1));
11878 assign(addr2, get_gpr_dw0(r2));
11879 assign(len1, get_gpr_dw0(r1 + 1));
11880 assign(len2, get_gpr_dw0(r2 + 1));
11881
11882 /* We're processing the 2nd operand 2 bytes at a time. Therefore, if
11883 there are less than 2 bytes left, then the 2nd operand is exhausted
11884 and we're done here. cc = 0 */
11885 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000011886 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(2)));
floriana0100c92012-07-20 00:06:35 +000011887
11888 /* There are at least two bytes there. Read them. */
11889 IRTemp srcval = newTemp(Ity_I32);
11890 assign(srcval, unop(Iop_16Uto32, load(Ity_I16, mkexpr(addr2))));
11891
11892 /* Find out whether this is a high surrogate. I.e. SRCVAL lies
11893 inside the interval [0xd800 - 0xdbff] */
11894 IRTemp is_high_surrogate = newTemp(Ity_I32);
11895 IRExpr *flag1 = mkite(binop(Iop_CmpLE32U, mkU32(0xd800), mkexpr(srcval)),
11896 mkU32(1), mkU32(0));
11897 IRExpr *flag2 = mkite(binop(Iop_CmpLE32U, mkexpr(srcval), mkU32(0xdbff)),
11898 mkU32(1), mkU32(0));
11899 assign(is_high_surrogate, binop(Iop_And32, flag1, flag2));
11900
11901 /* If SRCVAL is a high surrogate and there are less than 4 bytes left,
11902 then the 2nd operand is exhausted and we're done here. cc = 0 */
11903 IRExpr *not_enough_bytes =
11904 mkite(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)), mkU32(1), mkU32(0));
11905
florian6820ba52012-07-26 02:01:50 +000011906 next_insn_if(binop(Iop_CmpEQ32,
11907 binop(Iop_And32, mkexpr(is_high_surrogate),
11908 not_enough_bytes), mkU32(1)));
floriana0100c92012-07-20 00:06:35 +000011909
11910 /* The 2nd operand is not exhausted. If the first 2 bytes are a high
11911 surrogate, read the next two bytes (low surrogate). */
11912 IRTemp low_surrogate = newTemp(Ity_I32);
11913 IRExpr *low_surrogate_addr = binop(Iop_Add64, mkexpr(addr2), mkU64(2));
11914
11915 assign(low_surrogate,
11916 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
11917 unop(Iop_16Uto32, load(Ity_I16, low_surrogate_addr)),
11918 mkU32(0))); // any value is fine; it will not be used
11919
11920 /* Call the helper */
11921 IRTemp retval = newTemp(Ity_I64);
florian11b8ee82012-08-06 13:35:33 +000011922 assign(retval, s390_call_cu21(unop(Iop_32Uto64, mkexpr(srcval)),
11923 unop(Iop_32Uto64, mkexpr(low_surrogate))));
floriana0100c92012-07-20 00:06:35 +000011924
11925 /* Before we can test whether the 1st operand is exhausted we need to
11926 test for an invalid low surrogate. Because cc=2 outranks cc=1. */
11927 if (s390_host_has_etf3 && (m3 & 0x1) == 1) {
11928 IRExpr *invalid_low_surrogate =
11929 binop(Iop_And64, mkexpr(retval), mkU64(0xff));
11930
11931 s390_cc_set(2);
florian6820ba52012-07-26 02:01:50 +000011932 next_insn_if(binop(Iop_CmpEQ64, invalid_low_surrogate, mkU64(1)));
floriana0100c92012-07-20 00:06:35 +000011933 }
11934
11935 /* Now test whether the 1st operand is exhausted */
11936 IRTemp num_bytes = newTemp(Ity_I64);
11937 assign(num_bytes, binop(Iop_And64,
11938 binop(Iop_Shr64, mkexpr(retval), mkU8(8)),
11939 mkU64(0xff)));
11940 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000011941 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
floriana0100c92012-07-20 00:06:35 +000011942
11943 /* Extract the bytes to be stored at addr1 */
11944 IRTemp data = newTemp(Ity_I64);
11945 assign(data, binop(Iop_Shr64, mkexpr(retval), mkU8(16)));
11946
11947 /* To store the bytes construct 4 dirty helper calls. The helper calls
11948 are guarded (num_bytes == 1, num_bytes == 2, etc) such that only
11949 one of them will be called at runtime. */
11950 int i;
11951 for (i = 1; i <= 4; ++i) {
11952 IRDirty *d;
11953
11954 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
11955 &s390x_dirtyhelper_CUxy,
11956 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
11957 mkexpr(num_bytes)));
11958 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
11959 d->mFx = Ifx_Write;
11960 d->mAddr = mkexpr(addr1);
11961 d->mSize = i;
11962 stmt(IRStmt_Dirty(d));
11963 }
11964
11965 /* Update source address and length */
11966 IRTemp num_src_bytes = newTemp(Ity_I64);
11967 assign(num_src_bytes,
11968 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
11969 mkU64(4), mkU64(2)));
11970 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkexpr(num_src_bytes)));
11971 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkexpr(num_src_bytes)));
11972
11973 /* Update destination address and length */
11974 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
11975 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
11976
florian6820ba52012-07-26 02:01:50 +000011977 iterate();
floriana0100c92012-07-20 00:06:35 +000011978
11979 return "cu21";
11980}
11981
florian2a415a12012-07-21 17:41:36 +000011982static IRExpr *
11983s390_call_cu24(IRExpr *srcval, IRExpr *low_surrogate)
11984{
11985 IRExpr **args, *call;
11986 args = mkIRExprVec_2(srcval, low_surrogate);
11987 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
11988 "s390_do_cu24", &s390_do_cu24, args);
11989
11990 /* Nothing is excluded from definedness checking. */
11991 call->Iex.CCall.cee->mcx_mask = 0;
11992
11993 return call;
11994}
11995
florian55085f82012-11-21 00:36:55 +000011996static const HChar *
florian2a415a12012-07-21 17:41:36 +000011997s390_irgen_CU24(UChar m3, UChar r1, UChar r2)
11998{
11999 IRTemp addr1 = newTemp(Ity_I64);
12000 IRTemp addr2 = newTemp(Ity_I64);
12001 IRTemp len1 = newTemp(Ity_I64);
12002 IRTemp len2 = newTemp(Ity_I64);
12003
12004 assign(addr1, get_gpr_dw0(r1));
12005 assign(addr2, get_gpr_dw0(r2));
12006 assign(len1, get_gpr_dw0(r1 + 1));
12007 assign(len2, get_gpr_dw0(r2 + 1));
12008
12009 /* We're processing the 2nd operand 2 bytes at a time. Therefore, if
12010 there are less than 2 bytes left, then the 2nd operand is exhausted
12011 and we're done here. cc = 0 */
12012 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000012013 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(2)));
florian2a415a12012-07-21 17:41:36 +000012014
12015 /* There are at least two bytes there. Read them. */
12016 IRTemp srcval = newTemp(Ity_I32);
12017 assign(srcval, unop(Iop_16Uto32, load(Ity_I16, mkexpr(addr2))));
12018
12019 /* Find out whether this is a high surrogate. I.e. SRCVAL lies
12020 inside the interval [0xd800 - 0xdbff] */
12021 IRTemp is_high_surrogate = newTemp(Ity_I32);
12022 IRExpr *flag1 = mkite(binop(Iop_CmpLE32U, mkU32(0xd800), mkexpr(srcval)),
12023 mkU32(1), mkU32(0));
12024 IRExpr *flag2 = mkite(binop(Iop_CmpLE32U, mkexpr(srcval), mkU32(0xdbff)),
12025 mkU32(1), mkU32(0));
12026 assign(is_high_surrogate, binop(Iop_And32, flag1, flag2));
12027
12028 /* If SRCVAL is a high surrogate and there are less than 4 bytes left,
12029 then the 2nd operand is exhausted and we're done here. cc = 0 */
12030 IRExpr *not_enough_bytes =
12031 mkite(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)), mkU32(1), mkU32(0));
12032
florian6820ba52012-07-26 02:01:50 +000012033 next_insn_if(binop(Iop_CmpEQ32,
12034 binop(Iop_And32, mkexpr(is_high_surrogate),
12035 not_enough_bytes),
12036 mkU32(1)));
florian2a415a12012-07-21 17:41:36 +000012037
12038 /* The 2nd operand is not exhausted. If the first 2 bytes are a high
12039 surrogate, read the next two bytes (low surrogate). */
12040 IRTemp low_surrogate = newTemp(Ity_I32);
12041 IRExpr *low_surrogate_addr = binop(Iop_Add64, mkexpr(addr2), mkU64(2));
12042
12043 assign(low_surrogate,
12044 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
12045 unop(Iop_16Uto32, load(Ity_I16, low_surrogate_addr)),
12046 mkU32(0))); // any value is fine; it will not be used
12047
12048 /* Call the helper */
12049 IRTemp retval = newTemp(Ity_I64);
florian11b8ee82012-08-06 13:35:33 +000012050 assign(retval, s390_call_cu24(unop(Iop_32Uto64, mkexpr(srcval)),
12051 unop(Iop_32Uto64, mkexpr(low_surrogate))));
florian2a415a12012-07-21 17:41:36 +000012052
12053 /* Before we can test whether the 1st operand is exhausted we need to
12054 test for an invalid low surrogate. Because cc=2 outranks cc=1. */
12055 if (s390_host_has_etf3 && (m3 & 0x1) == 1) {
12056 IRExpr *invalid_low_surrogate =
12057 binop(Iop_And64, mkexpr(retval), mkU64(0xff));
12058
12059 s390_cc_set(2);
florian6820ba52012-07-26 02:01:50 +000012060 next_insn_if(binop(Iop_CmpEQ64, invalid_low_surrogate, mkU64(1)));
florian2a415a12012-07-21 17:41:36 +000012061 }
12062
12063 /* Now test whether the 1st operand is exhausted */
12064 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000012065 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkU64(4)));
florian2a415a12012-07-21 17:41:36 +000012066
12067 /* Extract the bytes to be stored at addr1 */
12068 IRExpr *data = unop(Iop_64to32, binop(Iop_Shr64, mkexpr(retval), mkU8(8)));
12069
12070 store(mkexpr(addr1), data);
12071
12072 /* Update source address and length */
12073 IRTemp num_src_bytes = newTemp(Ity_I64);
12074 assign(num_src_bytes,
12075 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
12076 mkU64(4), mkU64(2)));
12077 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkexpr(num_src_bytes)));
12078 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkexpr(num_src_bytes)));
12079
12080 /* Update destination address and length */
12081 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkU64(4)));
12082 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkU64(4)));
12083
florian6820ba52012-07-26 02:01:50 +000012084 iterate();
florian2a415a12012-07-21 17:41:36 +000012085
12086 return "cu24";
12087}
floriana4384a32011-08-11 16:58:45 +000012088
florian956194b2012-07-28 22:18:32 +000012089static IRExpr *
12090s390_call_cu42(IRExpr *srcval)
12091{
12092 IRExpr **args, *call;
12093 args = mkIRExprVec_1(srcval);
12094 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
12095 "s390_do_cu42", &s390_do_cu42, args);
12096
12097 /* Nothing is excluded from definedness checking. */
12098 call->Iex.CCall.cee->mcx_mask = 0;
12099
12100 return call;
12101}
12102
florian55085f82012-11-21 00:36:55 +000012103static const HChar *
florian956194b2012-07-28 22:18:32 +000012104s390_irgen_CU42(UChar r1, UChar r2)
12105{
12106 IRTemp addr1 = newTemp(Ity_I64);
12107 IRTemp addr2 = newTemp(Ity_I64);
12108 IRTemp len1 = newTemp(Ity_I64);
12109 IRTemp len2 = newTemp(Ity_I64);
12110
12111 assign(addr1, get_gpr_dw0(r1));
12112 assign(addr2, get_gpr_dw0(r2));
12113 assign(len1, get_gpr_dw0(r1 + 1));
12114 assign(len2, get_gpr_dw0(r2 + 1));
12115
12116 /* We're processing the 2nd operand 4 bytes at a time. Therefore, if
12117 there are less than 4 bytes left, then the 2nd operand is exhausted
12118 and we're done here. cc = 0 */
12119 s390_cc_set(0);
12120 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)));
12121
12122 /* Read the 2nd operand. */
12123 IRTemp srcval = newTemp(Ity_I32);
12124 assign(srcval, load(Ity_I32, mkexpr(addr2)));
12125
12126 /* Call the helper */
12127 IRTemp retval = newTemp(Ity_I64);
florian11b8ee82012-08-06 13:35:33 +000012128 assign(retval, s390_call_cu42(unop(Iop_32Uto64, mkexpr(srcval))));
florian956194b2012-07-28 22:18:32 +000012129
12130 /* If the UTF-32 character was invalid, set cc=2 and we're done.
12131 cc=2 outranks cc=1 (1st operand exhausted) */
12132 IRExpr *invalid_character = binop(Iop_And64, mkexpr(retval), mkU64(0xff));
12133
12134 s390_cc_set(2);
12135 next_insn_if(binop(Iop_CmpEQ64, invalid_character, mkU64(1)));
12136
12137 /* Now test whether the 1st operand is exhausted */
12138 IRTemp num_bytes = newTemp(Ity_I64);
12139 assign(num_bytes, binop(Iop_And64,
12140 binop(Iop_Shr64, mkexpr(retval), mkU8(8)),
12141 mkU64(0xff)));
12142 s390_cc_set(1);
12143 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
12144
12145 /* Extract the bytes to be stored at addr1 */
12146 IRTemp data = newTemp(Ity_I64);
12147 assign(data, binop(Iop_Shr64, mkexpr(retval), mkU8(16)));
12148
12149 /* To store the bytes construct 2 dirty helper calls. The helper calls
12150 are guarded (num_bytes == 2 and num_bytes == 4, respectively) such
12151 that only one of them will be called at runtime. */
12152
12153 Int i;
12154 for (i = 2; i <= 4; ++i) {
12155 IRDirty *d;
12156
12157 if (i == 3) continue; // skip this one
12158
12159 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
12160 &s390x_dirtyhelper_CUxy,
12161 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
12162 mkexpr(num_bytes)));
12163 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
12164 d->mFx = Ifx_Write;
12165 d->mAddr = mkexpr(addr1);
12166 d->mSize = i;
12167 stmt(IRStmt_Dirty(d));
12168 }
12169
12170 /* Update source address and length */
12171 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkU64(4)));
12172 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkU64(4)));
12173
12174 /* Update destination address and length */
12175 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
12176 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
12177
12178 iterate();
12179
12180 return "cu42";
12181}
12182
florian6d9b9b22012-08-03 18:35:39 +000012183static IRExpr *
florianaf2194f2012-08-06 00:07:54 +000012184s390_call_cu41(IRExpr *srcval)
12185{
12186 IRExpr **args, *call;
12187 args = mkIRExprVec_1(srcval);
12188 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
12189 "s390_do_cu41", &s390_do_cu41, args);
12190
12191 /* Nothing is excluded from definedness checking. */
12192 call->Iex.CCall.cee->mcx_mask = 0;
12193
12194 return call;
12195}
12196
florian55085f82012-11-21 00:36:55 +000012197static const HChar *
florianaf2194f2012-08-06 00:07:54 +000012198s390_irgen_CU41(UChar r1, UChar r2)
12199{
12200 IRTemp addr1 = newTemp(Ity_I64);
12201 IRTemp addr2 = newTemp(Ity_I64);
12202 IRTemp len1 = newTemp(Ity_I64);
12203 IRTemp len2 = newTemp(Ity_I64);
12204
12205 assign(addr1, get_gpr_dw0(r1));
12206 assign(addr2, get_gpr_dw0(r2));
12207 assign(len1, get_gpr_dw0(r1 + 1));
12208 assign(len2, get_gpr_dw0(r2 + 1));
12209
12210 /* We're processing the 2nd operand 4 bytes at a time. Therefore, if
12211 there are less than 4 bytes left, then the 2nd operand is exhausted
12212 and we're done here. cc = 0 */
12213 s390_cc_set(0);
12214 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)));
12215
12216 /* Read the 2nd operand. */
12217 IRTemp srcval = newTemp(Ity_I32);
12218 assign(srcval, load(Ity_I32, mkexpr(addr2)));
12219
12220 /* Call the helper */
12221 IRTemp retval = newTemp(Ity_I64);
florian11b8ee82012-08-06 13:35:33 +000012222 assign(retval, s390_call_cu41(unop(Iop_32Uto64, mkexpr(srcval))));
florianaf2194f2012-08-06 00:07:54 +000012223
12224 /* If the UTF-32 character was invalid, set cc=2 and we're done.
12225 cc=2 outranks cc=1 (1st operand exhausted) */
12226 IRExpr *invalid_character = binop(Iop_And64, mkexpr(retval), mkU64(0xff));
12227
12228 s390_cc_set(2);
12229 next_insn_if(binop(Iop_CmpEQ64, invalid_character, mkU64(1)));
12230
12231 /* Now test whether the 1st operand is exhausted */
12232 IRTemp num_bytes = newTemp(Ity_I64);
12233 assign(num_bytes, binop(Iop_And64,
12234 binop(Iop_Shr64, mkexpr(retval), mkU8(8)),
12235 mkU64(0xff)));
12236 s390_cc_set(1);
12237 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
12238
12239 /* Extract the bytes to be stored at addr1 */
12240 IRTemp data = newTemp(Ity_I64);
12241 assign(data, binop(Iop_Shr64, mkexpr(retval), mkU8(16)));
12242
12243 /* To store the bytes construct 4 dirty helper calls. The helper calls
12244 are guarded (num_bytes == 1, num_bytes == 2, etc) such that only
12245 one of them will be called at runtime. */
12246 int i;
12247 for (i = 1; i <= 4; ++i) {
12248 IRDirty *d;
12249
12250 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
12251 &s390x_dirtyhelper_CUxy,
12252 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
12253 mkexpr(num_bytes)));
12254 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
12255 d->mFx = Ifx_Write;
12256 d->mAddr = mkexpr(addr1);
12257 d->mSize = i;
12258 stmt(IRStmt_Dirty(d));
12259 }
12260
12261 /* Update source address and length */
12262 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkU64(4)));
12263 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkU64(4)));
12264
12265 /* Update destination address and length */
12266 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
12267 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
12268
12269 iterate();
12270
12271 return "cu41";
12272}
12273
12274static IRExpr *
florian3f8a96a2012-08-05 02:59:55 +000012275s390_call_cu12_cu14_helper1(IRExpr *byte1, IRExpr *etf3_and_m3_is_1)
florian6d9b9b22012-08-03 18:35:39 +000012276{
12277 IRExpr **args, *call;
12278 args = mkIRExprVec_2(byte1, etf3_and_m3_is_1);
florian3f8a96a2012-08-05 02:59:55 +000012279 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/, "s390_do_cu12_cu14_helper1",
12280 &s390_do_cu12_cu14_helper1, args);
florian6d9b9b22012-08-03 18:35:39 +000012281
12282 /* Nothing is excluded from definedness checking. */
12283 call->Iex.CCall.cee->mcx_mask = 0;
12284
12285 return call;
12286}
12287
12288static IRExpr *
12289s390_call_cu12_helper2(IRExpr *byte1, IRExpr *byte2, IRExpr *byte3,
12290 IRExpr *byte4, IRExpr *stuff)
12291{
12292 IRExpr **args, *call;
12293 args = mkIRExprVec_5(byte1, byte2, byte3, byte4, stuff);
12294 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
12295 "s390_do_cu12_helper2", &s390_do_cu12_helper2, args);
12296
12297 /* Nothing is excluded from definedness checking. */
12298 call->Iex.CCall.cee->mcx_mask = 0;
12299
12300 return call;
12301}
12302
florian3f8a96a2012-08-05 02:59:55 +000012303static IRExpr *
12304s390_call_cu14_helper2(IRExpr *byte1, IRExpr *byte2, IRExpr *byte3,
12305 IRExpr *byte4, IRExpr *stuff)
12306{
12307 IRExpr **args, *call;
12308 args = mkIRExprVec_5(byte1, byte2, byte3, byte4, stuff);
12309 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
12310 "s390_do_cu14_helper2", &s390_do_cu14_helper2, args);
12311
12312 /* Nothing is excluded from definedness checking. */
12313 call->Iex.CCall.cee->mcx_mask = 0;
12314
12315 return call;
12316}
12317
12318static void
12319s390_irgen_cu12_cu14(UChar m3, UChar r1, UChar r2, Bool is_cu12)
florian6d9b9b22012-08-03 18:35:39 +000012320{
12321 IRTemp addr1 = newTemp(Ity_I64);
12322 IRTemp addr2 = newTemp(Ity_I64);
12323 IRTemp len1 = newTemp(Ity_I64);
12324 IRTemp len2 = newTemp(Ity_I64);
12325
12326 assign(addr1, get_gpr_dw0(r1));
12327 assign(addr2, get_gpr_dw0(r2));
12328 assign(len1, get_gpr_dw0(r1 + 1));
12329 assign(len2, get_gpr_dw0(r2 + 1));
12330
12331 UInt extended_checking = s390_host_has_etf3 && (m3 & 0x1) == 1;
12332
12333 /* We're processing the 2nd operand 1 byte at a time. Therefore, if
12334 there is less than 1 byte left, then the 2nd operand is exhausted
12335 and we're done here. cc = 0 */
12336 s390_cc_set(0);
12337 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(1)));
12338
12339 /* There is at least one byte there. Read it. */
florian11b8ee82012-08-06 13:35:33 +000012340 IRTemp byte1 = newTemp(Ity_I64);
12341 assign(byte1, unop(Iop_8Uto64, load(Ity_I8, mkexpr(addr2))));
florian6d9b9b22012-08-03 18:35:39 +000012342
12343 /* Call the helper to get number of bytes and invalid byte indicator */
12344 IRTemp retval1 = newTemp(Ity_I64);
florian3f8a96a2012-08-05 02:59:55 +000012345 assign(retval1, s390_call_cu12_cu14_helper1(mkexpr(byte1),
florian11b8ee82012-08-06 13:35:33 +000012346 mkU64(extended_checking)));
florian6d9b9b22012-08-03 18:35:39 +000012347
12348 /* Check for invalid 1st byte */
12349 IRExpr *is_invalid = unop(Iop_64to1, mkexpr(retval1));
12350 s390_cc_set(2);
12351 next_insn_if(is_invalid);
12352
12353 /* How many bytes do we have to read? */
12354 IRTemp num_src_bytes = newTemp(Ity_I64);
12355 assign(num_src_bytes, binop(Iop_Shr64, mkexpr(retval1), mkU8(8)));
12356
12357 /* Now test whether the 2nd operand is exhausted */
12358 s390_cc_set(0);
12359 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkexpr(num_src_bytes)));
12360
12361 /* Read the remaining bytes */
12362 IRExpr *cond, *addr, *byte2, *byte3, *byte4;
12363
12364 cond = binop(Iop_CmpLE64U, mkU64(2), mkexpr(num_src_bytes));
12365 addr = binop(Iop_Add64, mkexpr(addr2), mkU64(1));
florian11b8ee82012-08-06 13:35:33 +000012366 byte2 = mkite(cond, unop(Iop_8Uto64, load(Ity_I8, addr)), mkU64(0));
florian6d9b9b22012-08-03 18:35:39 +000012367 cond = binop(Iop_CmpLE64U, mkU64(3), mkexpr(num_src_bytes));
12368 addr = binop(Iop_Add64, mkexpr(addr2), mkU64(2));
florian11b8ee82012-08-06 13:35:33 +000012369 byte3 = mkite(cond, unop(Iop_8Uto64, load(Ity_I8, addr)), mkU64(0));
florian6d9b9b22012-08-03 18:35:39 +000012370 cond = binop(Iop_CmpLE64U, mkU64(4), mkexpr(num_src_bytes));
12371 addr = binop(Iop_Add64, mkexpr(addr2), mkU64(3));
florian11b8ee82012-08-06 13:35:33 +000012372 byte4 = mkite(cond, unop(Iop_8Uto64, load(Ity_I8, addr)), mkU64(0));
florian6d9b9b22012-08-03 18:35:39 +000012373
12374 /* Call the helper to get the converted value and invalid byte indicator.
12375 We can pass at most 5 arguments; therefore some encoding is needed
12376 here */
12377 IRExpr *stuff = binop(Iop_Or64,
12378 binop(Iop_Shl64, mkexpr(num_src_bytes), mkU8(1)),
12379 mkU64(extended_checking));
12380 IRTemp retval2 = newTemp(Ity_I64);
florian3f8a96a2012-08-05 02:59:55 +000012381
12382 if (is_cu12) {
12383 assign(retval2, s390_call_cu12_helper2(mkexpr(byte1), byte2, byte3,
12384 byte4, stuff));
12385 } else {
12386 assign(retval2, s390_call_cu14_helper2(mkexpr(byte1), byte2, byte3,
12387 byte4, stuff));
12388 }
florian6d9b9b22012-08-03 18:35:39 +000012389
12390 /* Check for invalid character */
12391 s390_cc_set(2);
12392 is_invalid = unop(Iop_64to1, mkexpr(retval2));
12393 next_insn_if(is_invalid);
12394
12395 /* Now test whether the 1st operand is exhausted */
12396 IRTemp num_bytes = newTemp(Ity_I64);
12397 assign(num_bytes, binop(Iop_And64,
12398 binop(Iop_Shr64, mkexpr(retval2), mkU8(8)),
12399 mkU64(0xff)));
12400 s390_cc_set(1);
12401 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
12402
12403 /* Extract the bytes to be stored at addr1 */
12404 IRTemp data = newTemp(Ity_I64);
12405 assign(data, binop(Iop_Shr64, mkexpr(retval2), mkU8(16)));
12406
florian3f8a96a2012-08-05 02:59:55 +000012407 if (is_cu12) {
12408 /* To store the bytes construct 2 dirty helper calls. The helper calls
12409 are guarded (num_bytes == 2 and num_bytes == 4, respectively) such
12410 that only one of them will be called at runtime. */
florian6d9b9b22012-08-03 18:35:39 +000012411
florian3f8a96a2012-08-05 02:59:55 +000012412 Int i;
12413 for (i = 2; i <= 4; ++i) {
12414 IRDirty *d;
florian6d9b9b22012-08-03 18:35:39 +000012415
florian3f8a96a2012-08-05 02:59:55 +000012416 if (i == 3) continue; // skip this one
florian6d9b9b22012-08-03 18:35:39 +000012417
florian3f8a96a2012-08-05 02:59:55 +000012418 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
12419 &s390x_dirtyhelper_CUxy,
12420 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
12421 mkexpr(num_bytes)));
12422 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
12423 d->mFx = Ifx_Write;
12424 d->mAddr = mkexpr(addr1);
12425 d->mSize = i;
12426 stmt(IRStmt_Dirty(d));
12427 }
12428 } else {
12429 // cu14
12430 store(mkexpr(addr1), unop(Iop_64to32, mkexpr(data)));
florian6d9b9b22012-08-03 18:35:39 +000012431 }
12432
12433 /* Update source address and length */
12434 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkexpr(num_src_bytes)));
12435 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkexpr(num_src_bytes)));
12436
12437 /* Update destination address and length */
12438 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
12439 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
12440
12441 iterate();
florian3f8a96a2012-08-05 02:59:55 +000012442}
12443
florian55085f82012-11-21 00:36:55 +000012444static const HChar *
florian3f8a96a2012-08-05 02:59:55 +000012445s390_irgen_CU12(UChar m3, UChar r1, UChar r2)
12446{
12447 s390_irgen_cu12_cu14(m3, r1, r2, /* is_cu12 = */ 1);
florian6d9b9b22012-08-03 18:35:39 +000012448
12449 return "cu12";
12450}
12451
florian55085f82012-11-21 00:36:55 +000012452static const HChar *
florian3f8a96a2012-08-05 02:59:55 +000012453s390_irgen_CU14(UChar m3, UChar r1, UChar r2)
12454{
12455 s390_irgen_cu12_cu14(m3, r1, r2, /* is_cu12 = */ 0);
12456
12457 return "cu14";
12458}
12459
florian8c88cb62012-08-26 18:58:13 +000012460static IRExpr *
12461s390_call_ecag(IRExpr *op2addr)
12462{
12463 IRExpr **args, *call;
12464
12465 args = mkIRExprVec_1(op2addr);
12466 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
12467 "s390_do_ecag", &s390_do_ecag, args);
12468
12469 /* Nothing is excluded from definedness checking. */
12470 call->Iex.CCall.cee->mcx_mask = 0;
12471
12472 return call;
12473}
12474
florian55085f82012-11-21 00:36:55 +000012475static const HChar *
floriand2129202012-09-01 20:01:39 +000012476s390_irgen_ECAG(UChar r1, UChar r3 __attribute__((unused)), IRTemp op2addr)
florian8c88cb62012-08-26 18:58:13 +000012477{
12478 if (! s390_host_has_gie) {
floriane75dafa2012-09-01 17:54:09 +000012479 emulation_failure(EmFail_S390X_ecag);
florian8c88cb62012-08-26 18:58:13 +000012480 } else {
12481 put_gpr_dw0(r1, s390_call_ecag(mkexpr(op2addr)));
12482 }
12483
12484 return "ecag";
12485}
12486
12487
florianb7def222012-12-04 04:45:32 +000012488/* New insns are added here.
12489 If an insn is contingent on a facility being installed also
12490 check whether the list of supported facilities in function
12491 s390x_dirtyhelper_STFLE needs updating */
12492
sewardj2019a972011-03-07 16:04:07 +000012493/*------------------------------------------------------------*/
12494/*--- Build IR for special instructions ---*/
12495/*------------------------------------------------------------*/
12496
florianb4df7682011-07-05 02:09:01 +000012497static void
sewardj2019a972011-03-07 16:04:07 +000012498s390_irgen_client_request(void)
12499{
12500 if (0)
12501 vex_printf("%%R3 = client_request ( %%R2 )\n");
12502
florianf9e1ed72012-04-17 02:41:56 +000012503 Addr64 next = guest_IA_curr_instr + S390_SPECIAL_OP_PREAMBLE_SIZE
12504 + S390_SPECIAL_OP_SIZE;
sewardj2019a972011-03-07 16:04:07 +000012505
florianf9e1ed72012-04-17 02:41:56 +000012506 dis_res->jk_StopHere = Ijk_ClientReq;
sewardj2019a972011-03-07 16:04:07 +000012507 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +000012508
12509 put_IA(mkaddr_expr(next));
sewardj2019a972011-03-07 16:04:07 +000012510}
12511
florianb4df7682011-07-05 02:09:01 +000012512static void
sewardj2019a972011-03-07 16:04:07 +000012513s390_irgen_guest_NRADDR(void)
12514{
12515 if (0)
12516 vex_printf("%%R3 = guest_NRADDR\n");
12517
floriane88b3c92011-07-05 02:48:39 +000012518 put_gpr_dw0(3, IRExpr_Get(S390X_GUEST_OFFSET(guest_NRADDR), Ity_I64));
sewardj2019a972011-03-07 16:04:07 +000012519}
12520
florianb4df7682011-07-05 02:09:01 +000012521static void
sewardj2019a972011-03-07 16:04:07 +000012522s390_irgen_call_noredir(void)
12523{
florianf9e1ed72012-04-17 02:41:56 +000012524 Addr64 next = guest_IA_curr_instr + S390_SPECIAL_OP_PREAMBLE_SIZE
12525 + S390_SPECIAL_OP_SIZE;
12526
sewardj2019a972011-03-07 16:04:07 +000012527 /* Continue after special op */
florianf9e1ed72012-04-17 02:41:56 +000012528 put_gpr_dw0(14, mkaddr_expr(next));
sewardj2019a972011-03-07 16:04:07 +000012529
12530 /* The address is in REG1, all parameters are in the right (guest) places */
florianf9e1ed72012-04-17 02:41:56 +000012531 put_IA(get_gpr_dw0(1));
sewardj2019a972011-03-07 16:04:07 +000012532
12533 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +000012534 dis_res->jk_StopHere = Ijk_NoRedir;
sewardj2019a972011-03-07 16:04:07 +000012535}
12536
12537/* Force proper alignment for the structures below. */
12538#pragma pack(1)
12539
12540
12541static s390_decode_t
12542s390_decode_2byte_and_irgen(UChar *bytes)
12543{
12544 typedef union {
12545 struct {
12546 unsigned int op : 16;
12547 } E;
12548 struct {
12549 unsigned int op : 8;
12550 unsigned int i : 8;
12551 } I;
12552 struct {
12553 unsigned int op : 8;
12554 unsigned int r1 : 4;
12555 unsigned int r2 : 4;
12556 } RR;
12557 } formats;
12558 union {
12559 formats fmt;
12560 UShort value;
12561 } ovl;
12562
12563 vassert(sizeof(formats) == 2);
12564
12565 ((char *)(&ovl.value))[0] = bytes[0];
12566 ((char *)(&ovl.value))[1] = bytes[1];
12567
12568 switch (ovl.value & 0xffff) {
12569 case 0x0101: /* PR */ goto unimplemented;
12570 case 0x0102: /* UPT */ goto unimplemented;
12571 case 0x0104: /* PTFF */ goto unimplemented;
12572 case 0x0107: /* SCKPF */ goto unimplemented;
12573 case 0x010a: /* PFPO */ goto unimplemented;
12574 case 0x010b: /* TAM */ goto unimplemented;
12575 case 0x010c: /* SAM24 */ goto unimplemented;
12576 case 0x010d: /* SAM31 */ goto unimplemented;
12577 case 0x010e: /* SAM64 */ goto unimplemented;
12578 case 0x01ff: /* TRAP2 */ goto unimplemented;
12579 }
12580
12581 switch ((ovl.value & 0xff00) >> 8) {
12582 case 0x04: /* SPM */ goto unimplemented;
12583 case 0x05: /* BALR */ goto unimplemented;
12584 case 0x06: s390_format_RR_RR(s390_irgen_BCTR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12585 goto ok;
12586 case 0x07: s390_format_RR(s390_irgen_BCR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12587 goto ok;
12588 case 0x0a: s390_format_I(s390_irgen_SVC, ovl.fmt.I.i); goto ok;
12589 case 0x0b: /* BSM */ goto unimplemented;
12590 case 0x0c: /* BASSM */ goto unimplemented;
12591 case 0x0d: s390_format_RR_RR(s390_irgen_BASR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12592 goto ok;
florianb0c9a132011-09-08 15:37:39 +000012593 case 0x0e: s390_format_RR(s390_irgen_MVCL, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12594 goto ok;
12595 case 0x0f: s390_format_RR(s390_irgen_CLCL, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12596 goto ok;
sewardj2019a972011-03-07 16:04:07 +000012597 case 0x10: s390_format_RR_RR(s390_irgen_LPR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12598 goto ok;
12599 case 0x11: s390_format_RR_RR(s390_irgen_LNR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12600 goto ok;
12601 case 0x12: s390_format_RR_RR(s390_irgen_LTR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12602 goto ok;
12603 case 0x13: s390_format_RR_RR(s390_irgen_LCR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12604 goto ok;
12605 case 0x14: s390_format_RR_RR(s390_irgen_NR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12606 goto ok;
12607 case 0x15: s390_format_RR_RR(s390_irgen_CLR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12608 goto ok;
12609 case 0x16: s390_format_RR_RR(s390_irgen_OR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12610 goto ok;
12611 case 0x17: s390_format_RR_RR(s390_irgen_XR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12612 goto ok;
12613 case 0x18: s390_format_RR_RR(s390_irgen_LR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12614 goto ok;
12615 case 0x19: s390_format_RR_RR(s390_irgen_CR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12616 goto ok;
12617 case 0x1a: s390_format_RR_RR(s390_irgen_AR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12618 goto ok;
12619 case 0x1b: s390_format_RR_RR(s390_irgen_SR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12620 goto ok;
12621 case 0x1c: s390_format_RR_RR(s390_irgen_MR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12622 goto ok;
12623 case 0x1d: s390_format_RR_RR(s390_irgen_DR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12624 goto ok;
12625 case 0x1e: s390_format_RR_RR(s390_irgen_ALR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12626 goto ok;
12627 case 0x1f: s390_format_RR_RR(s390_irgen_SLR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12628 goto ok;
12629 case 0x20: /* LPDR */ goto unimplemented;
12630 case 0x21: /* LNDR */ goto unimplemented;
12631 case 0x22: /* LTDR */ goto unimplemented;
12632 case 0x23: /* LCDR */ goto unimplemented;
12633 case 0x24: /* HDR */ goto unimplemented;
12634 case 0x25: /* LDXR */ goto unimplemented;
12635 case 0x26: /* MXR */ goto unimplemented;
12636 case 0x27: /* MXDR */ goto unimplemented;
12637 case 0x28: s390_format_RR_FF(s390_irgen_LDR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12638 goto ok;
12639 case 0x29: /* CDR */ goto unimplemented;
12640 case 0x2a: /* ADR */ goto unimplemented;
12641 case 0x2b: /* SDR */ goto unimplemented;
12642 case 0x2c: /* MDR */ goto unimplemented;
12643 case 0x2d: /* DDR */ goto unimplemented;
12644 case 0x2e: /* AWR */ goto unimplemented;
12645 case 0x2f: /* SWR */ goto unimplemented;
12646 case 0x30: /* LPER */ goto unimplemented;
12647 case 0x31: /* LNER */ goto unimplemented;
12648 case 0x32: /* LTER */ goto unimplemented;
12649 case 0x33: /* LCER */ goto unimplemented;
12650 case 0x34: /* HER */ goto unimplemented;
12651 case 0x35: /* LEDR */ goto unimplemented;
12652 case 0x36: /* AXR */ goto unimplemented;
12653 case 0x37: /* SXR */ goto unimplemented;
12654 case 0x38: s390_format_RR_FF(s390_irgen_LER, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12655 goto ok;
12656 case 0x39: /* CER */ goto unimplemented;
12657 case 0x3a: /* AER */ goto unimplemented;
12658 case 0x3b: /* SER */ goto unimplemented;
12659 case 0x3c: /* MDER */ goto unimplemented;
12660 case 0x3d: /* DER */ goto unimplemented;
12661 case 0x3e: /* AUR */ goto unimplemented;
12662 case 0x3f: /* SUR */ goto unimplemented;
12663 }
12664
12665 return S390_DECODE_UNKNOWN_INSN;
12666
12667ok:
12668 return S390_DECODE_OK;
12669
12670unimplemented:
12671 return S390_DECODE_UNIMPLEMENTED_INSN;
12672}
12673
12674static s390_decode_t
12675s390_decode_4byte_and_irgen(UChar *bytes)
12676{
12677 typedef union {
12678 struct {
12679 unsigned int op1 : 8;
12680 unsigned int r1 : 4;
12681 unsigned int op2 : 4;
12682 unsigned int i2 : 16;
12683 } RI;
12684 struct {
12685 unsigned int op : 16;
12686 unsigned int : 8;
12687 unsigned int r1 : 4;
12688 unsigned int r2 : 4;
12689 } RRE;
12690 struct {
12691 unsigned int op : 16;
12692 unsigned int r1 : 4;
12693 unsigned int : 4;
12694 unsigned int r3 : 4;
12695 unsigned int r2 : 4;
12696 } RRF;
12697 struct {
12698 unsigned int op : 16;
florian1c8f7ff2012-09-01 00:12:11 +000012699 unsigned int m3 : 4;
sewardj2019a972011-03-07 16:04:07 +000012700 unsigned int m4 : 4;
12701 unsigned int r1 : 4;
12702 unsigned int r2 : 4;
12703 } RRF2;
12704 struct {
12705 unsigned int op : 16;
12706 unsigned int r3 : 4;
12707 unsigned int : 4;
12708 unsigned int r1 : 4;
12709 unsigned int r2 : 4;
12710 } RRF3;
12711 struct {
12712 unsigned int op : 16;
12713 unsigned int r3 : 4;
12714 unsigned int : 4;
12715 unsigned int r1 : 4;
12716 unsigned int r2 : 4;
12717 } RRR;
12718 struct {
12719 unsigned int op : 16;
12720 unsigned int r3 : 4;
florian12390202012-11-10 22:34:14 +000012721 unsigned int m4 : 4;
sewardj2019a972011-03-07 16:04:07 +000012722 unsigned int r1 : 4;
12723 unsigned int r2 : 4;
12724 } RRF4;
12725 struct {
12726 unsigned int op : 8;
12727 unsigned int r1 : 4;
12728 unsigned int r3 : 4;
12729 unsigned int b2 : 4;
12730 unsigned int d2 : 12;
12731 } RS;
12732 struct {
12733 unsigned int op : 8;
12734 unsigned int r1 : 4;
12735 unsigned int r3 : 4;
12736 unsigned int i2 : 16;
12737 } RSI;
12738 struct {
12739 unsigned int op : 8;
12740 unsigned int r1 : 4;
12741 unsigned int x2 : 4;
12742 unsigned int b2 : 4;
12743 unsigned int d2 : 12;
12744 } RX;
12745 struct {
12746 unsigned int op : 16;
12747 unsigned int b2 : 4;
12748 unsigned int d2 : 12;
12749 } S;
12750 struct {
12751 unsigned int op : 8;
12752 unsigned int i2 : 8;
12753 unsigned int b1 : 4;
12754 unsigned int d1 : 12;
12755 } SI;
12756 } formats;
12757 union {
12758 formats fmt;
12759 UInt value;
12760 } ovl;
12761
12762 vassert(sizeof(formats) == 4);
12763
12764 ((char *)(&ovl.value))[0] = bytes[0];
12765 ((char *)(&ovl.value))[1] = bytes[1];
12766 ((char *)(&ovl.value))[2] = bytes[2];
12767 ((char *)(&ovl.value))[3] = bytes[3];
12768
12769 switch ((ovl.value & 0xff0f0000) >> 16) {
12770 case 0xa500: s390_format_RI_RU(s390_irgen_IIHH, ovl.fmt.RI.r1,
12771 ovl.fmt.RI.i2); goto ok;
12772 case 0xa501: s390_format_RI_RU(s390_irgen_IIHL, ovl.fmt.RI.r1,
12773 ovl.fmt.RI.i2); goto ok;
12774 case 0xa502: s390_format_RI_RU(s390_irgen_IILH, ovl.fmt.RI.r1,
12775 ovl.fmt.RI.i2); goto ok;
12776 case 0xa503: s390_format_RI_RU(s390_irgen_IILL, ovl.fmt.RI.r1,
12777 ovl.fmt.RI.i2); goto ok;
12778 case 0xa504: s390_format_RI_RU(s390_irgen_NIHH, ovl.fmt.RI.r1,
12779 ovl.fmt.RI.i2); goto ok;
12780 case 0xa505: s390_format_RI_RU(s390_irgen_NIHL, ovl.fmt.RI.r1,
12781 ovl.fmt.RI.i2); goto ok;
12782 case 0xa506: s390_format_RI_RU(s390_irgen_NILH, ovl.fmt.RI.r1,
12783 ovl.fmt.RI.i2); goto ok;
12784 case 0xa507: s390_format_RI_RU(s390_irgen_NILL, ovl.fmt.RI.r1,
12785 ovl.fmt.RI.i2); goto ok;
12786 case 0xa508: s390_format_RI_RU(s390_irgen_OIHH, ovl.fmt.RI.r1,
12787 ovl.fmt.RI.i2); goto ok;
12788 case 0xa509: s390_format_RI_RU(s390_irgen_OIHL, ovl.fmt.RI.r1,
12789 ovl.fmt.RI.i2); goto ok;
12790 case 0xa50a: s390_format_RI_RU(s390_irgen_OILH, ovl.fmt.RI.r1,
12791 ovl.fmt.RI.i2); goto ok;
12792 case 0xa50b: s390_format_RI_RU(s390_irgen_OILL, ovl.fmt.RI.r1,
12793 ovl.fmt.RI.i2); goto ok;
12794 case 0xa50c: s390_format_RI_RU(s390_irgen_LLIHH, ovl.fmt.RI.r1,
12795 ovl.fmt.RI.i2); goto ok;
12796 case 0xa50d: s390_format_RI_RU(s390_irgen_LLIHL, ovl.fmt.RI.r1,
12797 ovl.fmt.RI.i2); goto ok;
12798 case 0xa50e: s390_format_RI_RU(s390_irgen_LLILH, ovl.fmt.RI.r1,
12799 ovl.fmt.RI.i2); goto ok;
12800 case 0xa50f: s390_format_RI_RU(s390_irgen_LLILL, ovl.fmt.RI.r1,
12801 ovl.fmt.RI.i2); goto ok;
12802 case 0xa700: s390_format_RI_RU(s390_irgen_TMLH, ovl.fmt.RI.r1,
12803 ovl.fmt.RI.i2); goto ok;
12804 case 0xa701: s390_format_RI_RU(s390_irgen_TMLL, ovl.fmt.RI.r1,
12805 ovl.fmt.RI.i2); goto ok;
12806 case 0xa702: s390_format_RI_RU(s390_irgen_TMHH, ovl.fmt.RI.r1,
12807 ovl.fmt.RI.i2); goto ok;
12808 case 0xa703: s390_format_RI_RU(s390_irgen_TMHL, ovl.fmt.RI.r1,
12809 ovl.fmt.RI.i2); goto ok;
12810 case 0xa704: s390_format_RI(s390_irgen_BRC, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
12811 goto ok;
12812 case 0xa705: s390_format_RI_RP(s390_irgen_BRAS, ovl.fmt.RI.r1,
12813 ovl.fmt.RI.i2); goto ok;
12814 case 0xa706: s390_format_RI_RP(s390_irgen_BRCT, ovl.fmt.RI.r1,
12815 ovl.fmt.RI.i2); goto ok;
12816 case 0xa707: s390_format_RI_RP(s390_irgen_BRCTG, ovl.fmt.RI.r1,
12817 ovl.fmt.RI.i2); goto ok;
12818 case 0xa708: s390_format_RI_RI(s390_irgen_LHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
12819 goto ok;
12820 case 0xa709: s390_format_RI_RI(s390_irgen_LGHI, ovl.fmt.RI.r1,
12821 ovl.fmt.RI.i2); goto ok;
12822 case 0xa70a: s390_format_RI_RI(s390_irgen_AHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
12823 goto ok;
12824 case 0xa70b: s390_format_RI_RI(s390_irgen_AGHI, ovl.fmt.RI.r1,
12825 ovl.fmt.RI.i2); goto ok;
12826 case 0xa70c: s390_format_RI_RI(s390_irgen_MHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
12827 goto ok;
12828 case 0xa70d: s390_format_RI_RI(s390_irgen_MGHI, ovl.fmt.RI.r1,
12829 ovl.fmt.RI.i2); goto ok;
12830 case 0xa70e: s390_format_RI_RI(s390_irgen_CHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
12831 goto ok;
12832 case 0xa70f: s390_format_RI_RI(s390_irgen_CGHI, ovl.fmt.RI.r1,
12833 ovl.fmt.RI.i2); goto ok;
12834 }
12835
12836 switch ((ovl.value & 0xffff0000) >> 16) {
12837 case 0x8000: /* SSM */ goto unimplemented;
12838 case 0x8200: /* LPSW */ goto unimplemented;
florian7700fc92012-01-16 17:25:55 +000012839 case 0x9300: /* TS */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000012840 case 0xb202: /* STIDP */ goto unimplemented;
12841 case 0xb204: /* SCK */ goto unimplemented;
florian7700fc92012-01-16 17:25:55 +000012842 case 0xb205: s390_format_S_RD(s390_irgen_STCK, ovl.fmt.S.b2, ovl.fmt.S.d2);
12843 goto ok;
sewardj2019a972011-03-07 16:04:07 +000012844 case 0xb206: /* SCKC */ goto unimplemented;
12845 case 0xb207: /* STCKC */ goto unimplemented;
12846 case 0xb208: /* SPT */ goto unimplemented;
12847 case 0xb209: /* STPT */ goto unimplemented;
12848 case 0xb20a: /* SPKA */ goto unimplemented;
12849 case 0xb20b: /* IPK */ goto unimplemented;
12850 case 0xb20d: /* PTLB */ goto unimplemented;
12851 case 0xb210: /* SPX */ goto unimplemented;
12852 case 0xb211: /* STPX */ goto unimplemented;
12853 case 0xb212: /* STAP */ goto unimplemented;
12854 case 0xb214: /* SIE */ goto unimplemented;
12855 case 0xb218: /* PC */ goto unimplemented;
12856 case 0xb219: /* SAC */ goto unimplemented;
12857 case 0xb21a: /* CFC */ goto unimplemented;
12858 case 0xb221: /* IPTE */ goto unimplemented;
12859 case 0xb222: s390_format_RRE_R0(s390_irgen_IPM, ovl.fmt.RRE.r1); goto ok;
12860 case 0xb223: /* IVSK */ goto unimplemented;
12861 case 0xb224: /* IAC */ goto unimplemented;
12862 case 0xb225: /* SSAR */ goto unimplemented;
12863 case 0xb226: /* EPAR */ goto unimplemented;
12864 case 0xb227: /* ESAR */ goto unimplemented;
12865 case 0xb228: /* PT */ goto unimplemented;
12866 case 0xb229: /* ISKE */ goto unimplemented;
12867 case 0xb22a: /* RRBE */ goto unimplemented;
12868 case 0xb22b: /* SSKE */ goto unimplemented;
12869 case 0xb22c: /* TB */ goto unimplemented;
12870 case 0xb22d: /* DXR */ goto unimplemented;
12871 case 0xb22e: /* PGIN */ goto unimplemented;
12872 case 0xb22f: /* PGOUT */ goto unimplemented;
12873 case 0xb230: /* CSCH */ goto unimplemented;
12874 case 0xb231: /* HSCH */ goto unimplemented;
12875 case 0xb232: /* MSCH */ goto unimplemented;
12876 case 0xb233: /* SSCH */ goto unimplemented;
12877 case 0xb234: /* STSCH */ goto unimplemented;
12878 case 0xb235: /* TSCH */ goto unimplemented;
12879 case 0xb236: /* TPI */ goto unimplemented;
12880 case 0xb237: /* SAL */ goto unimplemented;
12881 case 0xb238: /* RSCH */ goto unimplemented;
12882 case 0xb239: /* STCRW */ goto unimplemented;
12883 case 0xb23a: /* STCPS */ goto unimplemented;
12884 case 0xb23b: /* RCHP */ goto unimplemented;
12885 case 0xb23c: /* SCHM */ goto unimplemented;
12886 case 0xb240: /* BAKR */ goto unimplemented;
floriana4384a32011-08-11 16:58:45 +000012887 case 0xb241: s390_format_RRE(s390_irgen_CKSM, ovl.fmt.RRE.r1,
12888 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000012889 case 0xb244: /* SQDR */ goto unimplemented;
12890 case 0xb245: /* SQER */ goto unimplemented;
12891 case 0xb246: /* STURA */ goto unimplemented;
12892 case 0xb247: /* MSTA */ goto unimplemented;
12893 case 0xb248: /* PALB */ goto unimplemented;
12894 case 0xb249: /* EREG */ goto unimplemented;
12895 case 0xb24a: /* ESTA */ goto unimplemented;
12896 case 0xb24b: /* LURA */ goto unimplemented;
12897 case 0xb24c: /* TAR */ goto unimplemented;
12898 case 0xb24d: s390_format_RRE(s390_irgen_CPYA, ovl.fmt.RRE.r1,
12899 ovl.fmt.RRE.r2); goto ok;
12900 case 0xb24e: s390_format_RRE(s390_irgen_SAR, ovl.fmt.RRE.r1, ovl.fmt.RRE.r2);
12901 goto ok;
12902 case 0xb24f: s390_format_RRE(s390_irgen_EAR, ovl.fmt.RRE.r1, ovl.fmt.RRE.r2);
12903 goto ok;
12904 case 0xb250: /* CSP */ goto unimplemented;
12905 case 0xb252: s390_format_RRE_RR(s390_irgen_MSR, ovl.fmt.RRE.r1,
12906 ovl.fmt.RRE.r2); goto ok;
12907 case 0xb254: /* MVPG */ goto unimplemented;
12908 case 0xb255: s390_format_RRE_RR(s390_irgen_MVST, ovl.fmt.RRE.r1,
12909 ovl.fmt.RRE.r2); goto ok;
12910 case 0xb257: /* CUSE */ goto unimplemented;
12911 case 0xb258: /* BSG */ goto unimplemented;
12912 case 0xb25a: /* BSA */ goto unimplemented;
12913 case 0xb25d: s390_format_RRE_RR(s390_irgen_CLST, ovl.fmt.RRE.r1,
12914 ovl.fmt.RRE.r2); goto ok;
12915 case 0xb25e: s390_format_RRE_RR(s390_irgen_SRST, ovl.fmt.RRE.r1,
12916 ovl.fmt.RRE.r2); goto ok;
12917 case 0xb263: /* CMPSC */ goto unimplemented;
12918 case 0xb274: /* SIGA */ goto unimplemented;
12919 case 0xb276: /* XSCH */ goto unimplemented;
12920 case 0xb277: /* RP */ goto unimplemented;
sewardj1e5fea62011-05-17 16:18:36 +000012921 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 +000012922 case 0xb279: /* SACF */ goto unimplemented;
sewardj1e5fea62011-05-17 16:18:36 +000012923 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 +000012924 case 0xb27d: /* STSI */ goto unimplemented;
12925 case 0xb299: s390_format_S_RD(s390_irgen_SRNM, ovl.fmt.S.b2, ovl.fmt.S.d2);
12926 goto ok;
12927 case 0xb29c: s390_format_S_RD(s390_irgen_STFPC, ovl.fmt.S.b2, ovl.fmt.S.d2);
12928 goto ok;
12929 case 0xb29d: s390_format_S_RD(s390_irgen_LFPC, ovl.fmt.S.b2, ovl.fmt.S.d2);
12930 goto ok;
florian730448f2012-02-04 17:07:07 +000012931 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 +000012932 case 0xb2a6: s390_format_RRF_M0RERE(s390_irgen_CU21, ovl.fmt.RRF3.r3,
12933 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
12934 goto ok;
florian6d9b9b22012-08-03 18:35:39 +000012935 case 0xb2a7: s390_format_RRF_M0RERE(s390_irgen_CU12, ovl.fmt.RRF3.r3,
12936 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
12937 goto ok;
florian933065d2011-07-11 01:48:02 +000012938 case 0xb2b0: s390_format_S_RD(s390_irgen_STFLE, ovl.fmt.S.b2, ovl.fmt.S.d2);
12939 goto ok;
sewardj2019a972011-03-07 16:04:07 +000012940 case 0xb2b1: /* STFL */ goto unimplemented;
12941 case 0xb2b2: /* LPSWE */ goto unimplemented;
florianf0fa1be2012-09-18 20:24:38 +000012942 case 0xb2b8: s390_irgen_srnmb_wrapper(ovl.fmt.S.b2, ovl.fmt.S.d2);
12943 goto ok;
sewardj2019a972011-03-07 16:04:07 +000012944 case 0xb2b9: /* SRNMT */ goto unimplemented;
12945 case 0xb2bd: /* LFAS */ goto unimplemented;
florian2289cd42012-12-05 04:23:42 +000012946 case 0xb2e8: /* PPA */ goto unimplemented;
12947 case 0xb2ec: /* ETND */ goto unimplemented;
12948 case 0xb2f8: /* TEND */ goto unimplemented;
12949 case 0xb2fa: /* NIAI */ goto unimplemented;
12950 case 0xb2fc: /* TABORT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000012951 case 0xb2ff: /* TRAP4 */ goto unimplemented;
12952 case 0xb300: s390_format_RRE_FF(s390_irgen_LPEBR, ovl.fmt.RRE.r1,
12953 ovl.fmt.RRE.r2); goto ok;
12954 case 0xb301: s390_format_RRE_FF(s390_irgen_LNEBR, ovl.fmt.RRE.r1,
12955 ovl.fmt.RRE.r2); goto ok;
12956 case 0xb302: s390_format_RRE_FF(s390_irgen_LTEBR, ovl.fmt.RRE.r1,
12957 ovl.fmt.RRE.r2); goto ok;
12958 case 0xb303: s390_format_RRE_FF(s390_irgen_LCEBR, ovl.fmt.RRE.r1,
12959 ovl.fmt.RRE.r2); goto ok;
12960 case 0xb304: s390_format_RRE_FF(s390_irgen_LDEBR, ovl.fmt.RRE.r1,
12961 ovl.fmt.RRE.r2); goto ok;
12962 case 0xb305: s390_format_RRE_FF(s390_irgen_LXDBR, ovl.fmt.RRE.r1,
12963 ovl.fmt.RRE.r2); goto ok;
12964 case 0xb306: s390_format_RRE_FF(s390_irgen_LXEBR, ovl.fmt.RRE.r1,
12965 ovl.fmt.RRE.r2); goto ok;
12966 case 0xb307: /* MXDBR */ goto unimplemented;
12967 case 0xb308: /* KEBR */ goto unimplemented;
12968 case 0xb309: s390_format_RRE_FF(s390_irgen_CEBR, ovl.fmt.RRE.r1,
12969 ovl.fmt.RRE.r2); goto ok;
12970 case 0xb30a: s390_format_RRE_FF(s390_irgen_AEBR, ovl.fmt.RRE.r1,
12971 ovl.fmt.RRE.r2); goto ok;
12972 case 0xb30b: s390_format_RRE_FF(s390_irgen_SEBR, ovl.fmt.RRE.r1,
12973 ovl.fmt.RRE.r2); goto ok;
12974 case 0xb30c: /* MDEBR */ goto unimplemented;
12975 case 0xb30d: s390_format_RRE_FF(s390_irgen_DEBR, ovl.fmt.RRE.r1,
12976 ovl.fmt.RRE.r2); goto ok;
12977 case 0xb30e: s390_format_RRF_F0FF(s390_irgen_MAEBR, ovl.fmt.RRF.r1,
12978 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
12979 case 0xb30f: s390_format_RRF_F0FF(s390_irgen_MSEBR, ovl.fmt.RRF.r1,
12980 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
12981 case 0xb310: s390_format_RRE_FF(s390_irgen_LPDBR, ovl.fmt.RRE.r1,
12982 ovl.fmt.RRE.r2); goto ok;
12983 case 0xb311: s390_format_RRE_FF(s390_irgen_LNDBR, ovl.fmt.RRE.r1,
12984 ovl.fmt.RRE.r2); goto ok;
12985 case 0xb312: s390_format_RRE_FF(s390_irgen_LTDBR, ovl.fmt.RRE.r1,
12986 ovl.fmt.RRE.r2); goto ok;
12987 case 0xb313: s390_format_RRE_FF(s390_irgen_LCDBR, ovl.fmt.RRE.r1,
12988 ovl.fmt.RRE.r2); goto ok;
12989 case 0xb314: s390_format_RRE_FF(s390_irgen_SQEBR, ovl.fmt.RRE.r1,
12990 ovl.fmt.RRE.r2); goto ok;
12991 case 0xb315: s390_format_RRE_FF(s390_irgen_SQDBR, ovl.fmt.RRE.r1,
12992 ovl.fmt.RRE.r2); goto ok;
12993 case 0xb316: s390_format_RRE_FF(s390_irgen_SQXBR, ovl.fmt.RRE.r1,
12994 ovl.fmt.RRE.r2); goto ok;
12995 case 0xb317: s390_format_RRE_FF(s390_irgen_MEEBR, ovl.fmt.RRE.r1,
12996 ovl.fmt.RRE.r2); goto ok;
12997 case 0xb318: /* KDBR */ goto unimplemented;
12998 case 0xb319: s390_format_RRE_FF(s390_irgen_CDBR, ovl.fmt.RRE.r1,
12999 ovl.fmt.RRE.r2); goto ok;
13000 case 0xb31a: s390_format_RRE_FF(s390_irgen_ADBR, ovl.fmt.RRE.r1,
13001 ovl.fmt.RRE.r2); goto ok;
13002 case 0xb31b: s390_format_RRE_FF(s390_irgen_SDBR, ovl.fmt.RRE.r1,
13003 ovl.fmt.RRE.r2); goto ok;
13004 case 0xb31c: s390_format_RRE_FF(s390_irgen_MDBR, ovl.fmt.RRE.r1,
13005 ovl.fmt.RRE.r2); goto ok;
13006 case 0xb31d: s390_format_RRE_FF(s390_irgen_DDBR, ovl.fmt.RRE.r1,
13007 ovl.fmt.RRE.r2); goto ok;
13008 case 0xb31e: s390_format_RRF_F0FF(s390_irgen_MADBR, ovl.fmt.RRF.r1,
13009 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
13010 case 0xb31f: s390_format_RRF_F0FF(s390_irgen_MSDBR, ovl.fmt.RRF.r1,
13011 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
13012 case 0xb324: /* LDER */ goto unimplemented;
13013 case 0xb325: /* LXDR */ goto unimplemented;
13014 case 0xb326: /* LXER */ goto unimplemented;
13015 case 0xb32e: /* MAER */ goto unimplemented;
13016 case 0xb32f: /* MSER */ goto unimplemented;
13017 case 0xb336: /* SQXR */ goto unimplemented;
13018 case 0xb337: /* MEER */ goto unimplemented;
13019 case 0xb338: /* MAYLR */ goto unimplemented;
13020 case 0xb339: /* MYLR */ goto unimplemented;
13021 case 0xb33a: /* MAYR */ goto unimplemented;
13022 case 0xb33b: /* MYR */ goto unimplemented;
13023 case 0xb33c: /* MAYHR */ goto unimplemented;
13024 case 0xb33d: /* MYHR */ goto unimplemented;
13025 case 0xb33e: /* MADR */ goto unimplemented;
13026 case 0xb33f: /* MSDR */ goto unimplemented;
13027 case 0xb340: s390_format_RRE_FF(s390_irgen_LPXBR, ovl.fmt.RRE.r1,
13028 ovl.fmt.RRE.r2); goto ok;
13029 case 0xb341: s390_format_RRE_FF(s390_irgen_LNXBR, ovl.fmt.RRE.r1,
13030 ovl.fmt.RRE.r2); goto ok;
13031 case 0xb342: s390_format_RRE_FF(s390_irgen_LTXBR, ovl.fmt.RRE.r1,
13032 ovl.fmt.RRE.r2); goto ok;
13033 case 0xb343: s390_format_RRE_FF(s390_irgen_LCXBR, ovl.fmt.RRE.r1,
13034 ovl.fmt.RRE.r2); goto ok;
florian4b8efad2012-09-02 18:07:08 +000013035 case 0xb344: s390_format_RRF_UUFF(s390_irgen_LEDBR, ovl.fmt.RRF2.m3,
13036 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13037 ovl.fmt.RRF2.r2); goto ok;
13038 case 0xb345: s390_format_RRF_UUFF(s390_irgen_LDXBR, ovl.fmt.RRF2.m3,
13039 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13040 ovl.fmt.RRF2.r2); goto ok;
13041 case 0xb346: s390_format_RRF_UUFF(s390_irgen_LEXBR, ovl.fmt.RRF2.m3,
13042 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13043 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013044 case 0xb347: /* FIXBR */ goto unimplemented;
13045 case 0xb348: /* KXBR */ goto unimplemented;
13046 case 0xb349: s390_format_RRE_FF(s390_irgen_CXBR, ovl.fmt.RRE.r1,
13047 ovl.fmt.RRE.r2); goto ok;
13048 case 0xb34a: s390_format_RRE_FF(s390_irgen_AXBR, ovl.fmt.RRE.r1,
13049 ovl.fmt.RRE.r2); goto ok;
13050 case 0xb34b: s390_format_RRE_FF(s390_irgen_SXBR, ovl.fmt.RRE.r1,
13051 ovl.fmt.RRE.r2); goto ok;
13052 case 0xb34c: s390_format_RRE_FF(s390_irgen_MXBR, ovl.fmt.RRE.r1,
13053 ovl.fmt.RRE.r2); goto ok;
13054 case 0xb34d: s390_format_RRE_FF(s390_irgen_DXBR, ovl.fmt.RRE.r1,
13055 ovl.fmt.RRE.r2); goto ok;
13056 case 0xb350: /* TBEDR */ goto unimplemented;
13057 case 0xb351: /* TBDR */ goto unimplemented;
13058 case 0xb353: /* DIEBR */ goto unimplemented;
13059 case 0xb357: /* FIEBR */ goto unimplemented;
13060 case 0xb358: /* THDER */ goto unimplemented;
13061 case 0xb359: /* THDR */ goto unimplemented;
13062 case 0xb35b: /* DIDBR */ goto unimplemented;
13063 case 0xb35f: /* FIDBR */ goto unimplemented;
13064 case 0xb360: /* LPXR */ goto unimplemented;
13065 case 0xb361: /* LNXR */ goto unimplemented;
13066 case 0xb362: /* LTXR */ goto unimplemented;
13067 case 0xb363: /* LCXR */ goto unimplemented;
13068 case 0xb365: s390_format_RRE_FF(s390_irgen_LXR, ovl.fmt.RRE.r1,
13069 ovl.fmt.RRE.r2); goto ok;
13070 case 0xb366: /* LEXR */ goto unimplemented;
13071 case 0xb367: /* FIXR */ goto unimplemented;
13072 case 0xb369: /* CXR */ goto unimplemented;
13073 case 0xb370: s390_format_RRE_FF(s390_irgen_LPDFR, ovl.fmt.RRE.r1,
13074 ovl.fmt.RRE.r2); goto ok;
13075 case 0xb371: s390_format_RRE_FF(s390_irgen_LNDFR, ovl.fmt.RRE.r1,
13076 ovl.fmt.RRE.r2); goto ok;
13077 case 0xb372: s390_format_RRF_F0FF2(s390_irgen_CPSDR, ovl.fmt.RRF3.r3,
13078 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
13079 goto ok;
13080 case 0xb373: s390_format_RRE_FF(s390_irgen_LCDFR, ovl.fmt.RRE.r1,
13081 ovl.fmt.RRE.r2); goto ok;
13082 case 0xb374: s390_format_RRE_F0(s390_irgen_LZER, ovl.fmt.RRE.r1); goto ok;
13083 case 0xb375: s390_format_RRE_F0(s390_irgen_LZDR, ovl.fmt.RRE.r1); goto ok;
13084 case 0xb376: s390_format_RRE_F0(s390_irgen_LZXR, ovl.fmt.RRE.r1); goto ok;
13085 case 0xb377: /* FIER */ goto unimplemented;
13086 case 0xb37f: /* FIDR */ goto unimplemented;
13087 case 0xb384: s390_format_RRE_R0(s390_irgen_SFPC, ovl.fmt.RRE.r1); goto ok;
13088 case 0xb385: /* SFASR */ goto unimplemented;
13089 case 0xb38c: s390_format_RRE_R0(s390_irgen_EFPC, ovl.fmt.RRE.r1); goto ok;
florian1c8f7ff2012-09-01 00:12:11 +000013090 case 0xb390: s390_format_RRF_UUFR(s390_irgen_CELFBR, ovl.fmt.RRF2.m3,
13091 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13092 ovl.fmt.RRF2.r2); goto ok;
13093 case 0xb391: s390_format_RRF_UUFR(s390_irgen_CDLFBR, ovl.fmt.RRF2.m3,
13094 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13095 ovl.fmt.RRF2.r2); goto ok;
13096 case 0xb392: s390_format_RRF_UUFR(s390_irgen_CXLFBR, ovl.fmt.RRF2.m3,
13097 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13098 ovl.fmt.RRF2.r2); goto ok;
florian4b8efad2012-09-02 18:07:08 +000013099 case 0xb394: s390_format_RRF_UUFR(s390_irgen_CEFBR, ovl.fmt.RRF2.m3,
13100 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13101 ovl.fmt.RRF2.r2); goto ok;
13102 case 0xb395: s390_format_RRF_UUFR(s390_irgen_CDFBR, ovl.fmt.RRF2.m3,
13103 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13104 ovl.fmt.RRF2.r2); goto ok;
13105 case 0xb396: s390_format_RRF_UUFR(s390_irgen_CXFBR, ovl.fmt.RRF2.m3,
13106 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13107 ovl.fmt.RRF2.r2); goto ok;
13108 case 0xb398: s390_format_RRF_UURF(s390_irgen_CFEBR, ovl.fmt.RRF2.m3,
13109 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13110 ovl.fmt.RRF2.r2); goto ok;
13111 case 0xb399: s390_format_RRF_UURF(s390_irgen_CFDBR, ovl.fmt.RRF2.m3,
13112 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13113 ovl.fmt.RRF2.r2); goto ok;
13114 case 0xb39a: s390_format_RRF_UURF(s390_irgen_CFXBR, ovl.fmt.RRF2.m3,
13115 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13116 ovl.fmt.RRF2.r2); goto ok;
florian1c8f7ff2012-09-01 00:12:11 +000013117 case 0xb39c: s390_format_RRF_UURF(s390_irgen_CLFEBR, ovl.fmt.RRF2.m3,
13118 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13119 ovl.fmt.RRF2.r2); goto ok;
13120 case 0xb39d: s390_format_RRF_UURF(s390_irgen_CLFDBR, ovl.fmt.RRF2.m3,
13121 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13122 ovl.fmt.RRF2.r2); goto ok;
13123 case 0xb39e: s390_format_RRF_UURF(s390_irgen_CLFXBR, ovl.fmt.RRF2.m3,
13124 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13125 ovl.fmt.RRF2.r2); goto ok;
13126 case 0xb3a0: s390_format_RRF_UUFR(s390_irgen_CELGBR, ovl.fmt.RRF2.m3,
13127 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13128 ovl.fmt.RRF2.r2); goto ok;
13129 case 0xb3a1: s390_format_RRF_UUFR(s390_irgen_CDLGBR, ovl.fmt.RRF2.m3,
13130 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13131 ovl.fmt.RRF2.r2); goto ok;
13132 case 0xb3a2: s390_format_RRF_UUFR(s390_irgen_CXLGBR, ovl.fmt.RRF2.m3,
13133 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13134 ovl.fmt.RRF2.r2); goto ok;
florian4b8efad2012-09-02 18:07:08 +000013135 case 0xb3a4: s390_format_RRF_UUFR(s390_irgen_CEGBR, ovl.fmt.RRF2.m3,
13136 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13137 ovl.fmt.RRF2.r2); goto ok;
13138 case 0xb3a5: s390_format_RRF_UUFR(s390_irgen_CDGBR, ovl.fmt.RRF2.m3,
13139 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13140 ovl.fmt.RRF2.r2); goto ok;
13141 case 0xb3a6: s390_format_RRF_UUFR(s390_irgen_CXGBR, ovl.fmt.RRF2.m3,
13142 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13143 ovl.fmt.RRF2.r2); goto ok;
13144 case 0xb3a8: s390_format_RRF_UURF(s390_irgen_CGEBR, ovl.fmt.RRF2.m3,
13145 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13146 ovl.fmt.RRF2.r2); goto ok;
13147 case 0xb3a9: s390_format_RRF_UURF(s390_irgen_CGDBR, ovl.fmt.RRF2.m3,
13148 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13149 ovl.fmt.RRF2.r2); goto ok;
13150 case 0xb3aa: s390_format_RRF_UURF(s390_irgen_CGXBR, ovl.fmt.RRF2.m3,
13151 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13152 ovl.fmt.RRF2.r2); goto ok;
florian1c8f7ff2012-09-01 00:12:11 +000013153 case 0xb3ac: s390_format_RRF_UURF(s390_irgen_CLGEBR, ovl.fmt.RRF2.m3,
13154 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13155 ovl.fmt.RRF2.r2); goto ok;
13156 case 0xb3ad: s390_format_RRF_UURF(s390_irgen_CLGDBR, ovl.fmt.RRF2.m3,
13157 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13158 ovl.fmt.RRF2.r2); goto ok;
13159 case 0xb3ae: s390_format_RRF_UURF(s390_irgen_CLGXBR, ovl.fmt.RRF2.m3,
13160 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13161 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013162 case 0xb3b4: /* CEFR */ goto unimplemented;
13163 case 0xb3b5: /* CDFR */ goto unimplemented;
13164 case 0xb3b6: /* CXFR */ goto unimplemented;
13165 case 0xb3b8: /* CFER */ goto unimplemented;
13166 case 0xb3b9: /* CFDR */ goto unimplemented;
13167 case 0xb3ba: /* CFXR */ goto unimplemented;
13168 case 0xb3c1: s390_format_RRE_FR(s390_irgen_LDGR, ovl.fmt.RRE.r1,
13169 ovl.fmt.RRE.r2); goto ok;
13170 case 0xb3c4: /* CEGR */ goto unimplemented;
13171 case 0xb3c5: /* CDGR */ goto unimplemented;
13172 case 0xb3c6: /* CXGR */ goto unimplemented;
13173 case 0xb3c8: /* CGER */ goto unimplemented;
13174 case 0xb3c9: /* CGDR */ goto unimplemented;
13175 case 0xb3ca: /* CGXR */ goto unimplemented;
13176 case 0xb3cd: s390_format_RRE_RF(s390_irgen_LGDR, ovl.fmt.RRE.r1,
13177 ovl.fmt.RRE.r2); goto ok;
florian12390202012-11-10 22:34:14 +000013178 case 0xb3d0: s390_format_RRF_FUFF2(s390_irgen_MDTRA, ovl.fmt.RRF4.r3,
13179 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
13180 ovl.fmt.RRF4.r2); goto ok;
13181 case 0xb3d1: s390_format_RRF_FUFF2(s390_irgen_DDTRA, ovl.fmt.RRF4.r3,
13182 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
13183 ovl.fmt.RRF4.r2); goto ok;
13184 case 0xb3d2: s390_format_RRF_FUFF2(s390_irgen_ADTRA, ovl.fmt.RRF4.r3,
13185 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
13186 ovl.fmt.RRF4.r2); goto ok;
13187 case 0xb3d3: s390_format_RRF_FUFF2(s390_irgen_SDTRA, ovl.fmt.RRF4.r3,
13188 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
13189 ovl.fmt.RRF4.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013190 case 0xb3d4: /* LDETR */ goto unimplemented;
13191 case 0xb3d5: /* LEDTR */ goto unimplemented;
florian12390202012-11-10 22:34:14 +000013192 case 0xb3d6: s390_format_RRE_FF(s390_irgen_LTDTR, ovl.fmt.RRE.r1,
13193 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013194 case 0xb3d7: /* FIDTR */ goto unimplemented;
13195 case 0xb3d8: /* MXTR */ goto unimplemented;
13196 case 0xb3d9: /* DXTR */ goto unimplemented;
13197 case 0xb3da: /* AXTR */ goto unimplemented;
13198 case 0xb3db: /* SXTR */ goto unimplemented;
13199 case 0xb3dc: /* LXDTR */ goto unimplemented;
13200 case 0xb3dd: /* LDXTR */ goto unimplemented;
13201 case 0xb3de: /* LTXTR */ goto unimplemented;
13202 case 0xb3df: /* FIXTR */ goto unimplemented;
13203 case 0xb3e0: /* KDTR */ goto unimplemented;
13204 case 0xb3e1: /* CGDTR */ goto unimplemented;
13205 case 0xb3e2: /* CUDTR */ goto unimplemented;
13206 case 0xb3e3: /* CSDTR */ goto unimplemented;
13207 case 0xb3e4: /* CDTR */ goto unimplemented;
13208 case 0xb3e5: /* EEDTR */ goto unimplemented;
13209 case 0xb3e7: /* ESDTR */ goto unimplemented;
13210 case 0xb3e8: /* KXTR */ goto unimplemented;
13211 case 0xb3e9: /* CGXTR */ goto unimplemented;
13212 case 0xb3ea: /* CUXTR */ goto unimplemented;
13213 case 0xb3eb: /* CSXTR */ goto unimplemented;
13214 case 0xb3ec: /* CXTR */ goto unimplemented;
13215 case 0xb3ed: /* EEXTR */ goto unimplemented;
13216 case 0xb3ef: /* ESXTR */ goto unimplemented;
13217 case 0xb3f1: /* CDGTR */ goto unimplemented;
13218 case 0xb3f2: /* CDUTR */ goto unimplemented;
13219 case 0xb3f3: /* CDSTR */ goto unimplemented;
13220 case 0xb3f4: /* CEDTR */ goto unimplemented;
13221 case 0xb3f5: /* QADTR */ goto unimplemented;
13222 case 0xb3f6: /* IEDTR */ goto unimplemented;
13223 case 0xb3f7: /* RRDTR */ goto unimplemented;
13224 case 0xb3f9: /* CXGTR */ goto unimplemented;
13225 case 0xb3fa: /* CXUTR */ goto unimplemented;
13226 case 0xb3fb: /* CXSTR */ goto unimplemented;
13227 case 0xb3fc: /* CEXTR */ goto unimplemented;
13228 case 0xb3fd: /* QAXTR */ goto unimplemented;
13229 case 0xb3fe: /* IEXTR */ goto unimplemented;
13230 case 0xb3ff: /* RRXTR */ goto unimplemented;
13231 case 0xb900: s390_format_RRE_RR(s390_irgen_LPGR, ovl.fmt.RRE.r1,
13232 ovl.fmt.RRE.r2); goto ok;
13233 case 0xb901: s390_format_RRE_RR(s390_irgen_LNGR, ovl.fmt.RRE.r1,
13234 ovl.fmt.RRE.r2); goto ok;
13235 case 0xb902: s390_format_RRE_RR(s390_irgen_LTGR, ovl.fmt.RRE.r1,
13236 ovl.fmt.RRE.r2); goto ok;
13237 case 0xb903: s390_format_RRE_RR(s390_irgen_LCGR, ovl.fmt.RRE.r1,
13238 ovl.fmt.RRE.r2); goto ok;
13239 case 0xb904: s390_format_RRE_RR(s390_irgen_LGR, ovl.fmt.RRE.r1,
13240 ovl.fmt.RRE.r2); goto ok;
13241 case 0xb905: /* LURAG */ goto unimplemented;
13242 case 0xb906: s390_format_RRE_RR(s390_irgen_LGBR, ovl.fmt.RRE.r1,
13243 ovl.fmt.RRE.r2); goto ok;
13244 case 0xb907: s390_format_RRE_RR(s390_irgen_LGHR, ovl.fmt.RRE.r1,
13245 ovl.fmt.RRE.r2); goto ok;
13246 case 0xb908: s390_format_RRE_RR(s390_irgen_AGR, ovl.fmt.RRE.r1,
13247 ovl.fmt.RRE.r2); goto ok;
13248 case 0xb909: s390_format_RRE_RR(s390_irgen_SGR, ovl.fmt.RRE.r1,
13249 ovl.fmt.RRE.r2); goto ok;
13250 case 0xb90a: s390_format_RRE_RR(s390_irgen_ALGR, ovl.fmt.RRE.r1,
13251 ovl.fmt.RRE.r2); goto ok;
13252 case 0xb90b: s390_format_RRE_RR(s390_irgen_SLGR, ovl.fmt.RRE.r1,
13253 ovl.fmt.RRE.r2); goto ok;
13254 case 0xb90c: s390_format_RRE_RR(s390_irgen_MSGR, ovl.fmt.RRE.r1,
13255 ovl.fmt.RRE.r2); goto ok;
13256 case 0xb90d: s390_format_RRE_RR(s390_irgen_DSGR, ovl.fmt.RRE.r1,
13257 ovl.fmt.RRE.r2); goto ok;
13258 case 0xb90e: /* EREGG */ goto unimplemented;
13259 case 0xb90f: s390_format_RRE_RR(s390_irgen_LRVGR, ovl.fmt.RRE.r1,
13260 ovl.fmt.RRE.r2); goto ok;
13261 case 0xb910: s390_format_RRE_RR(s390_irgen_LPGFR, ovl.fmt.RRE.r1,
13262 ovl.fmt.RRE.r2); goto ok;
13263 case 0xb911: s390_format_RRE_RR(s390_irgen_LNGFR, ovl.fmt.RRE.r1,
13264 ovl.fmt.RRE.r2); goto ok;
13265 case 0xb912: s390_format_RRE_RR(s390_irgen_LTGFR, ovl.fmt.RRE.r1,
13266 ovl.fmt.RRE.r2); goto ok;
13267 case 0xb913: s390_format_RRE_RR(s390_irgen_LCGFR, ovl.fmt.RRE.r1,
13268 ovl.fmt.RRE.r2); goto ok;
13269 case 0xb914: s390_format_RRE_RR(s390_irgen_LGFR, ovl.fmt.RRE.r1,
13270 ovl.fmt.RRE.r2); goto ok;
13271 case 0xb916: s390_format_RRE_RR(s390_irgen_LLGFR, ovl.fmt.RRE.r1,
13272 ovl.fmt.RRE.r2); goto ok;
13273 case 0xb917: s390_format_RRE_RR(s390_irgen_LLGTR, ovl.fmt.RRE.r1,
13274 ovl.fmt.RRE.r2); goto ok;
13275 case 0xb918: s390_format_RRE_RR(s390_irgen_AGFR, ovl.fmt.RRE.r1,
13276 ovl.fmt.RRE.r2); goto ok;
13277 case 0xb919: s390_format_RRE_RR(s390_irgen_SGFR, ovl.fmt.RRE.r1,
13278 ovl.fmt.RRE.r2); goto ok;
13279 case 0xb91a: s390_format_RRE_RR(s390_irgen_ALGFR, ovl.fmt.RRE.r1,
13280 ovl.fmt.RRE.r2); goto ok;
13281 case 0xb91b: s390_format_RRE_RR(s390_irgen_SLGFR, ovl.fmt.RRE.r1,
13282 ovl.fmt.RRE.r2); goto ok;
13283 case 0xb91c: s390_format_RRE_RR(s390_irgen_MSGFR, ovl.fmt.RRE.r1,
13284 ovl.fmt.RRE.r2); goto ok;
13285 case 0xb91d: s390_format_RRE_RR(s390_irgen_DSGFR, ovl.fmt.RRE.r1,
13286 ovl.fmt.RRE.r2); goto ok;
13287 case 0xb91e: /* KMAC */ goto unimplemented;
13288 case 0xb91f: s390_format_RRE_RR(s390_irgen_LRVR, ovl.fmt.RRE.r1,
13289 ovl.fmt.RRE.r2); goto ok;
13290 case 0xb920: s390_format_RRE_RR(s390_irgen_CGR, ovl.fmt.RRE.r1,
13291 ovl.fmt.RRE.r2); goto ok;
13292 case 0xb921: s390_format_RRE_RR(s390_irgen_CLGR, ovl.fmt.RRE.r1,
13293 ovl.fmt.RRE.r2); goto ok;
13294 case 0xb925: /* STURG */ goto unimplemented;
13295 case 0xb926: s390_format_RRE_RR(s390_irgen_LBR, ovl.fmt.RRE.r1,
13296 ovl.fmt.RRE.r2); goto ok;
13297 case 0xb927: s390_format_RRE_RR(s390_irgen_LHR, ovl.fmt.RRE.r1,
13298 ovl.fmt.RRE.r2); goto ok;
13299 case 0xb928: /* PCKMO */ goto unimplemented;
13300 case 0xb92b: /* KMO */ goto unimplemented;
13301 case 0xb92c: /* PCC */ goto unimplemented;
13302 case 0xb92d: /* KMCTR */ goto unimplemented;
13303 case 0xb92e: /* KM */ goto unimplemented;
13304 case 0xb92f: /* KMC */ goto unimplemented;
13305 case 0xb930: s390_format_RRE_RR(s390_irgen_CGFR, ovl.fmt.RRE.r1,
13306 ovl.fmt.RRE.r2); goto ok;
13307 case 0xb931: s390_format_RRE_RR(s390_irgen_CLGFR, ovl.fmt.RRE.r1,
13308 ovl.fmt.RRE.r2); goto ok;
13309 case 0xb93e: /* KIMD */ goto unimplemented;
13310 case 0xb93f: /* KLMD */ goto unimplemented;
13311 case 0xb941: /* CFDTR */ goto unimplemented;
13312 case 0xb942: /* CLGDTR */ goto unimplemented;
13313 case 0xb943: /* CLFDTR */ goto unimplemented;
13314 case 0xb946: s390_format_RRE_RR(s390_irgen_BCTGR, ovl.fmt.RRE.r1,
13315 ovl.fmt.RRE.r2); goto ok;
13316 case 0xb949: /* CFXTR */ goto unimplemented;
13317 case 0xb94a: /* CLGXTR */ goto unimplemented;
13318 case 0xb94b: /* CLFXTR */ goto unimplemented;
13319 case 0xb951: /* CDFTR */ goto unimplemented;
13320 case 0xb952: /* CDLGTR */ goto unimplemented;
13321 case 0xb953: /* CDLFTR */ goto unimplemented;
13322 case 0xb959: /* CXFTR */ goto unimplemented;
13323 case 0xb95a: /* CXLGTR */ goto unimplemented;
13324 case 0xb95b: /* CXLFTR */ goto unimplemented;
13325 case 0xb960: /* CGRT */ goto unimplemented;
13326 case 0xb961: /* CLGRT */ goto unimplemented;
13327 case 0xb972: /* CRT */ goto unimplemented;
13328 case 0xb973: /* CLRT */ goto unimplemented;
13329 case 0xb980: s390_format_RRE_RR(s390_irgen_NGR, ovl.fmt.RRE.r1,
13330 ovl.fmt.RRE.r2); goto ok;
13331 case 0xb981: s390_format_RRE_RR(s390_irgen_OGR, ovl.fmt.RRE.r1,
13332 ovl.fmt.RRE.r2); goto ok;
13333 case 0xb982: s390_format_RRE_RR(s390_irgen_XGR, ovl.fmt.RRE.r1,
13334 ovl.fmt.RRE.r2); goto ok;
13335 case 0xb983: s390_format_RRE_RR(s390_irgen_FLOGR, ovl.fmt.RRE.r1,
13336 ovl.fmt.RRE.r2); goto ok;
13337 case 0xb984: s390_format_RRE_RR(s390_irgen_LLGCR, ovl.fmt.RRE.r1,
13338 ovl.fmt.RRE.r2); goto ok;
13339 case 0xb985: s390_format_RRE_RR(s390_irgen_LLGHR, ovl.fmt.RRE.r1,
13340 ovl.fmt.RRE.r2); goto ok;
13341 case 0xb986: s390_format_RRE_RR(s390_irgen_MLGR, ovl.fmt.RRE.r1,
13342 ovl.fmt.RRE.r2); goto ok;
13343 case 0xb987: s390_format_RRE_RR(s390_irgen_DLGR, ovl.fmt.RRE.r1,
13344 ovl.fmt.RRE.r2); goto ok;
13345 case 0xb988: s390_format_RRE_RR(s390_irgen_ALCGR, ovl.fmt.RRE.r1,
13346 ovl.fmt.RRE.r2); goto ok;
13347 case 0xb989: s390_format_RRE_RR(s390_irgen_SLBGR, ovl.fmt.RRE.r1,
13348 ovl.fmt.RRE.r2); goto ok;
13349 case 0xb98a: /* CSPG */ goto unimplemented;
13350 case 0xb98d: /* EPSW */ goto unimplemented;
13351 case 0xb98e: /* IDTE */ goto unimplemented;
florian2289cd42012-12-05 04:23:42 +000013352 case 0xb98f: /* CRDTE */ goto unimplemented;
florian730448f2012-02-04 17:07:07 +000013353 case 0xb990: s390_format_RRF_M0RERE(s390_irgen_TRTT, ovl.fmt.RRF3.r3,
13354 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
13355 case 0xb991: s390_format_RRF_M0RERE(s390_irgen_TRTO, ovl.fmt.RRF3.r3,
13356 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
13357 case 0xb992: s390_format_RRF_M0RERE(s390_irgen_TROT, ovl.fmt.RRF3.r3,
13358 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
florian9af37692012-01-15 21:01:16 +000013359 case 0xb993: s390_format_RRF_M0RERE(s390_irgen_TROO, ovl.fmt.RRF3.r3,
13360 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013361 case 0xb994: s390_format_RRE_RR(s390_irgen_LLCR, ovl.fmt.RRE.r1,
13362 ovl.fmt.RRE.r2); goto ok;
13363 case 0xb995: s390_format_RRE_RR(s390_irgen_LLHR, ovl.fmt.RRE.r1,
13364 ovl.fmt.RRE.r2); goto ok;
13365 case 0xb996: s390_format_RRE_RR(s390_irgen_MLR, ovl.fmt.RRE.r1,
13366 ovl.fmt.RRE.r2); goto ok;
13367 case 0xb997: s390_format_RRE_RR(s390_irgen_DLR, ovl.fmt.RRE.r1,
13368 ovl.fmt.RRE.r2); goto ok;
13369 case 0xb998: s390_format_RRE_RR(s390_irgen_ALCR, ovl.fmt.RRE.r1,
13370 ovl.fmt.RRE.r2); goto ok;
13371 case 0xb999: s390_format_RRE_RR(s390_irgen_SLBR, ovl.fmt.RRE.r1,
13372 ovl.fmt.RRE.r2); goto ok;
13373 case 0xb99a: /* EPAIR */ goto unimplemented;
13374 case 0xb99b: /* ESAIR */ goto unimplemented;
13375 case 0xb99d: /* ESEA */ goto unimplemented;
13376 case 0xb99e: /* PTI */ goto unimplemented;
13377 case 0xb99f: /* SSAIR */ goto unimplemented;
13378 case 0xb9a2: /* PTF */ goto unimplemented;
13379 case 0xb9aa: /* LPTEA */ goto unimplemented;
13380 case 0xb9ae: /* RRBM */ goto unimplemented;
13381 case 0xb9af: /* PFMF */ goto unimplemented;
florian3f8a96a2012-08-05 02:59:55 +000013382 case 0xb9b0: s390_format_RRF_M0RERE(s390_irgen_CU14, ovl.fmt.RRF3.r3,
13383 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
13384 goto ok;
florian2a415a12012-07-21 17:41:36 +000013385 case 0xb9b1: s390_format_RRF_M0RERE(s390_irgen_CU24, ovl.fmt.RRF3.r3,
13386 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
13387 goto ok;
florianaf2194f2012-08-06 00:07:54 +000013388 case 0xb9b2: s390_format_RRE_RR(s390_irgen_CU41, ovl.fmt.RRE.r1,
13389 ovl.fmt.RRE.r2); goto ok;
florian956194b2012-07-28 22:18:32 +000013390 case 0xb9b3: s390_format_RRE_RR(s390_irgen_CU42, ovl.fmt.RRE.r1,
13391 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013392 case 0xb9bd: /* TRTRE */ goto unimplemented;
13393 case 0xb9be: /* SRSTU */ goto unimplemented;
13394 case 0xb9bf: /* TRTE */ goto unimplemented;
13395 case 0xb9c8: s390_format_RRF_R0RR2(s390_irgen_AHHHR, ovl.fmt.RRF4.r3,
13396 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13397 goto ok;
13398 case 0xb9c9: s390_format_RRF_R0RR2(s390_irgen_SHHHR, ovl.fmt.RRF4.r3,
13399 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13400 goto ok;
13401 case 0xb9ca: s390_format_RRF_R0RR2(s390_irgen_ALHHHR, ovl.fmt.RRF4.r3,
13402 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13403 goto ok;
13404 case 0xb9cb: s390_format_RRF_R0RR2(s390_irgen_SLHHHR, ovl.fmt.RRF4.r3,
13405 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13406 goto ok;
13407 case 0xb9cd: s390_format_RRE_RR(s390_irgen_CHHR, ovl.fmt.RRE.r1,
13408 ovl.fmt.RRE.r2); goto ok;
13409 case 0xb9cf: s390_format_RRE_RR(s390_irgen_CLHHR, ovl.fmt.RRE.r1,
13410 ovl.fmt.RRE.r2); goto ok;
13411 case 0xb9d8: s390_format_RRF_R0RR2(s390_irgen_AHHLR, ovl.fmt.RRF4.r3,
13412 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13413 goto ok;
13414 case 0xb9d9: s390_format_RRF_R0RR2(s390_irgen_SHHLR, ovl.fmt.RRF4.r3,
13415 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13416 goto ok;
13417 case 0xb9da: s390_format_RRF_R0RR2(s390_irgen_ALHHLR, ovl.fmt.RRF4.r3,
13418 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13419 goto ok;
13420 case 0xb9db: s390_format_RRF_R0RR2(s390_irgen_SLHHLR, ovl.fmt.RRF4.r3,
13421 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13422 goto ok;
13423 case 0xb9dd: s390_format_RRE_RR(s390_irgen_CHLR, ovl.fmt.RRE.r1,
13424 ovl.fmt.RRE.r2); goto ok;
13425 case 0xb9df: s390_format_RRE_RR(s390_irgen_CLHLR, ovl.fmt.RRE.r1,
13426 ovl.fmt.RRE.r2); goto ok;
13427 case 0xb9e1: /* POPCNT */ goto unimplemented;
sewardjd7bde722011-04-05 13:19:33 +000013428 case 0xb9e2: s390_format_RRF_U0RR(s390_irgen_LOCGR, ovl.fmt.RRF3.r3,
13429 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2,
13430 S390_XMNM_LOCGR); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013431 case 0xb9e4: s390_format_RRF_R0RR2(s390_irgen_NGRK, ovl.fmt.RRF4.r3,
13432 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13433 goto ok;
13434 case 0xb9e6: s390_format_RRF_R0RR2(s390_irgen_OGRK, ovl.fmt.RRF4.r3,
13435 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13436 goto ok;
13437 case 0xb9e7: s390_format_RRF_R0RR2(s390_irgen_XGRK, ovl.fmt.RRF4.r3,
13438 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13439 goto ok;
13440 case 0xb9e8: s390_format_RRF_R0RR2(s390_irgen_AGRK, ovl.fmt.RRF4.r3,
13441 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13442 goto ok;
13443 case 0xb9e9: s390_format_RRF_R0RR2(s390_irgen_SGRK, ovl.fmt.RRF4.r3,
13444 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13445 goto ok;
13446 case 0xb9ea: s390_format_RRF_R0RR2(s390_irgen_ALGRK, ovl.fmt.RRF4.r3,
13447 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13448 goto ok;
13449 case 0xb9eb: s390_format_RRF_R0RR2(s390_irgen_SLGRK, ovl.fmt.RRF4.r3,
13450 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13451 goto ok;
sewardjd7bde722011-04-05 13:19:33 +000013452 case 0xb9f2: s390_format_RRF_U0RR(s390_irgen_LOCR, ovl.fmt.RRF3.r3,
13453 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2,
13454 S390_XMNM_LOCR); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013455 case 0xb9f4: s390_format_RRF_R0RR2(s390_irgen_NRK, ovl.fmt.RRF4.r3,
13456 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13457 goto ok;
13458 case 0xb9f6: s390_format_RRF_R0RR2(s390_irgen_ORK, ovl.fmt.RRF4.r3,
13459 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13460 goto ok;
13461 case 0xb9f7: s390_format_RRF_R0RR2(s390_irgen_XRK, ovl.fmt.RRF4.r3,
13462 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13463 goto ok;
13464 case 0xb9f8: s390_format_RRF_R0RR2(s390_irgen_ARK, ovl.fmt.RRF4.r3,
13465 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13466 goto ok;
13467 case 0xb9f9: s390_format_RRF_R0RR2(s390_irgen_SRK, ovl.fmt.RRF4.r3,
13468 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13469 goto ok;
13470 case 0xb9fa: s390_format_RRF_R0RR2(s390_irgen_ALRK, ovl.fmt.RRF4.r3,
13471 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13472 goto ok;
13473 case 0xb9fb: s390_format_RRF_R0RR2(s390_irgen_SLRK, ovl.fmt.RRF4.r3,
13474 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13475 goto ok;
13476 }
13477
13478 switch ((ovl.value & 0xff000000) >> 24) {
13479 case 0x40: s390_format_RX_RRRD(s390_irgen_STH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13480 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13481 case 0x41: s390_format_RX_RRRD(s390_irgen_LA, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13482 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13483 case 0x42: s390_format_RX_RRRD(s390_irgen_STC, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13484 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13485 case 0x43: s390_format_RX_RRRD(s390_irgen_IC, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13486 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13487 case 0x44: s390_format_RX_RRRD(s390_irgen_EX, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13488 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13489 case 0x45: /* BAL */ goto unimplemented;
13490 case 0x46: s390_format_RX_RRRD(s390_irgen_BCT, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13491 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13492 case 0x47: s390_format_RX(s390_irgen_BC, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13493 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13494 case 0x48: s390_format_RX_RRRD(s390_irgen_LH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13495 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13496 case 0x49: s390_format_RX_RRRD(s390_irgen_CH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13497 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13498 case 0x4a: s390_format_RX_RRRD(s390_irgen_AH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13499 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13500 case 0x4b: s390_format_RX_RRRD(s390_irgen_SH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13501 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13502 case 0x4c: s390_format_RX_RRRD(s390_irgen_MH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13503 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13504 case 0x4d: s390_format_RX_RRRD(s390_irgen_BAS, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13505 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13506 case 0x4e: s390_format_RX_RRRD(s390_irgen_CVD, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13507 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13508 case 0x4f: s390_format_RX_RRRD(s390_irgen_CVB, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13509 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13510 case 0x50: s390_format_RX_RRRD(s390_irgen_ST, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13511 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13512 case 0x51: s390_format_RX_RRRD(s390_irgen_LAE, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13513 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13514 case 0x54: s390_format_RX_RRRD(s390_irgen_N, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13515 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13516 case 0x55: s390_format_RX_RRRD(s390_irgen_CL, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13517 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13518 case 0x56: s390_format_RX_RRRD(s390_irgen_O, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13519 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13520 case 0x57: s390_format_RX_RRRD(s390_irgen_X, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13521 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13522 case 0x58: s390_format_RX_RRRD(s390_irgen_L, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13523 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13524 case 0x59: s390_format_RX_RRRD(s390_irgen_C, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13525 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13526 case 0x5a: s390_format_RX_RRRD(s390_irgen_A, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13527 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13528 case 0x5b: s390_format_RX_RRRD(s390_irgen_S, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13529 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13530 case 0x5c: s390_format_RX_RRRD(s390_irgen_M, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13531 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13532 case 0x5d: s390_format_RX_RRRD(s390_irgen_D, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13533 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13534 case 0x5e: s390_format_RX_RRRD(s390_irgen_AL, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13535 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13536 case 0x5f: s390_format_RX_RRRD(s390_irgen_SL, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13537 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13538 case 0x60: s390_format_RX_FRRD(s390_irgen_STD, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13539 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13540 case 0x67: /* MXD */ goto unimplemented;
13541 case 0x68: s390_format_RX_FRRD(s390_irgen_LD, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13542 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13543 case 0x69: /* CD */ goto unimplemented;
13544 case 0x6a: /* AD */ goto unimplemented;
13545 case 0x6b: /* SD */ goto unimplemented;
13546 case 0x6c: /* MD */ goto unimplemented;
13547 case 0x6d: /* DD */ goto unimplemented;
13548 case 0x6e: /* AW */ goto unimplemented;
13549 case 0x6f: /* SW */ goto unimplemented;
13550 case 0x70: s390_format_RX_FRRD(s390_irgen_STE, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13551 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13552 case 0x71: s390_format_RX_RRRD(s390_irgen_MS, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13553 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13554 case 0x78: s390_format_RX_FRRD(s390_irgen_LE, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13555 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13556 case 0x79: /* CE */ goto unimplemented;
13557 case 0x7a: /* AE */ goto unimplemented;
13558 case 0x7b: /* SE */ goto unimplemented;
13559 case 0x7c: /* MDE */ goto unimplemented;
13560 case 0x7d: /* DE */ goto unimplemented;
13561 case 0x7e: /* AU */ goto unimplemented;
13562 case 0x7f: /* SU */ goto unimplemented;
13563 case 0x83: /* DIAG */ goto unimplemented;
13564 case 0x84: s390_format_RSI_RRP(s390_irgen_BRXH, ovl.fmt.RSI.r1,
13565 ovl.fmt.RSI.r3, ovl.fmt.RSI.i2); goto ok;
13566 case 0x85: s390_format_RSI_RRP(s390_irgen_BRXLE, ovl.fmt.RSI.r1,
13567 ovl.fmt.RSI.r3, ovl.fmt.RSI.i2); goto ok;
13568 case 0x86: s390_format_RS_RRRD(s390_irgen_BXH, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13569 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13570 case 0x87: s390_format_RS_RRRD(s390_irgen_BXLE, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13571 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13572 case 0x88: s390_format_RS_R0RD(s390_irgen_SRL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
13573 ovl.fmt.RS.d2); goto ok;
13574 case 0x89: s390_format_RS_R0RD(s390_irgen_SLL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
13575 ovl.fmt.RS.d2); goto ok;
13576 case 0x8a: s390_format_RS_R0RD(s390_irgen_SRA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
13577 ovl.fmt.RS.d2); goto ok;
13578 case 0x8b: s390_format_RS_R0RD(s390_irgen_SLA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
13579 ovl.fmt.RS.d2); goto ok;
13580 case 0x8c: s390_format_RS_R0RD(s390_irgen_SRDL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
13581 ovl.fmt.RS.d2); goto ok;
13582 case 0x8d: s390_format_RS_R0RD(s390_irgen_SLDL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
13583 ovl.fmt.RS.d2); goto ok;
13584 case 0x8e: s390_format_RS_R0RD(s390_irgen_SRDA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
13585 ovl.fmt.RS.d2); goto ok;
13586 case 0x8f: s390_format_RS_R0RD(s390_irgen_SLDA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
13587 ovl.fmt.RS.d2); goto ok;
13588 case 0x90: s390_format_RS_RRRD(s390_irgen_STM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13589 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13590 case 0x91: s390_format_SI_URD(s390_irgen_TM, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
13591 ovl.fmt.SI.d1); goto ok;
13592 case 0x92: s390_format_SI_URD(s390_irgen_MVI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
13593 ovl.fmt.SI.d1); goto ok;
13594 case 0x94: s390_format_SI_URD(s390_irgen_NI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
13595 ovl.fmt.SI.d1); goto ok;
13596 case 0x95: s390_format_SI_URD(s390_irgen_CLI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
13597 ovl.fmt.SI.d1); goto ok;
13598 case 0x96: s390_format_SI_URD(s390_irgen_OI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
13599 ovl.fmt.SI.d1); goto ok;
13600 case 0x97: s390_format_SI_URD(s390_irgen_XI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
13601 ovl.fmt.SI.d1); goto ok;
13602 case 0x98: s390_format_RS_RRRD(s390_irgen_LM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13603 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13604 case 0x99: /* TRACE */ goto unimplemented;
13605 case 0x9a: s390_format_RS_AARD(s390_irgen_LAM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13606 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13607 case 0x9b: s390_format_RS_AARD(s390_irgen_STAM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13608 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13609 case 0xa8: s390_format_RS_RRRD(s390_irgen_MVCLE, ovl.fmt.RS.r1,
13610 ovl.fmt.RS.r3, ovl.fmt.RS.b2, ovl.fmt.RS.d2);
13611 goto ok;
13612 case 0xa9: s390_format_RS_RRRD(s390_irgen_CLCLE, ovl.fmt.RS.r1,
13613 ovl.fmt.RS.r3, ovl.fmt.RS.b2, ovl.fmt.RS.d2);
13614 goto ok;
13615 case 0xac: /* STNSM */ goto unimplemented;
13616 case 0xad: /* STOSM */ goto unimplemented;
13617 case 0xae: /* SIGP */ goto unimplemented;
13618 case 0xaf: /* MC */ goto unimplemented;
13619 case 0xb1: /* LRA */ goto unimplemented;
13620 case 0xb6: /* STCTL */ goto unimplemented;
13621 case 0xb7: /* LCTL */ goto unimplemented;
13622 case 0xba: s390_format_RS_RRRD(s390_irgen_CS, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13623 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
florian448cbba2012-06-06 02:26:01 +000013624 case 0xbb: s390_format_RS_RRRD(s390_irgen_CDS, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13625 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013626 case 0xbd: s390_format_RS_RURD(s390_irgen_CLM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13627 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13628 case 0xbe: s390_format_RS_RURD(s390_irgen_STCM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13629 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13630 case 0xbf: s390_format_RS_RURD(s390_irgen_ICM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13631 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13632 }
13633
13634 return S390_DECODE_UNKNOWN_INSN;
13635
13636ok:
13637 return S390_DECODE_OK;
13638
13639unimplemented:
13640 return S390_DECODE_UNIMPLEMENTED_INSN;
13641}
13642
13643static s390_decode_t
13644s390_decode_6byte_and_irgen(UChar *bytes)
13645{
13646 typedef union {
13647 struct {
13648 unsigned int op1 : 8;
13649 unsigned int r1 : 4;
13650 unsigned int r3 : 4;
13651 unsigned int i2 : 16;
13652 unsigned int : 8;
13653 unsigned int op2 : 8;
13654 } RIE;
13655 struct {
13656 unsigned int op1 : 8;
13657 unsigned int r1 : 4;
13658 unsigned int r2 : 4;
13659 unsigned int i3 : 8;
13660 unsigned int i4 : 8;
13661 unsigned int i5 : 8;
13662 unsigned int op2 : 8;
13663 } RIE_RRUUU;
13664 struct {
13665 unsigned int op1 : 8;
13666 unsigned int r1 : 4;
13667 unsigned int : 4;
13668 unsigned int i2 : 16;
13669 unsigned int m3 : 4;
13670 unsigned int : 4;
13671 unsigned int op2 : 8;
13672 } RIEv1;
13673 struct {
13674 unsigned int op1 : 8;
13675 unsigned int r1 : 4;
13676 unsigned int r2 : 4;
13677 unsigned int i4 : 16;
13678 unsigned int m3 : 4;
13679 unsigned int : 4;
13680 unsigned int op2 : 8;
13681 } RIE_RRPU;
13682 struct {
13683 unsigned int op1 : 8;
13684 unsigned int r1 : 4;
13685 unsigned int m3 : 4;
13686 unsigned int i4 : 16;
13687 unsigned int i2 : 8;
13688 unsigned int op2 : 8;
13689 } RIEv3;
13690 struct {
13691 unsigned int op1 : 8;
13692 unsigned int r1 : 4;
13693 unsigned int op2 : 4;
13694 unsigned int i2 : 32;
13695 } RIL;
13696 struct {
13697 unsigned int op1 : 8;
13698 unsigned int r1 : 4;
13699 unsigned int m3 : 4;
13700 unsigned int b4 : 4;
13701 unsigned int d4 : 12;
13702 unsigned int i2 : 8;
13703 unsigned int op2 : 8;
13704 } RIS;
13705 struct {
13706 unsigned int op1 : 8;
13707 unsigned int r1 : 4;
13708 unsigned int r2 : 4;
13709 unsigned int b4 : 4;
13710 unsigned int d4 : 12;
13711 unsigned int m3 : 4;
13712 unsigned int : 4;
13713 unsigned int op2 : 8;
13714 } RRS;
13715 struct {
13716 unsigned int op1 : 8;
13717 unsigned int l1 : 4;
13718 unsigned int : 4;
13719 unsigned int b1 : 4;
13720 unsigned int d1 : 12;
13721 unsigned int : 8;
13722 unsigned int op2 : 8;
13723 } RSL;
13724 struct {
13725 unsigned int op1 : 8;
13726 unsigned int r1 : 4;
13727 unsigned int r3 : 4;
13728 unsigned int b2 : 4;
13729 unsigned int dl2 : 12;
13730 unsigned int dh2 : 8;
13731 unsigned int op2 : 8;
13732 } RSY;
13733 struct {
13734 unsigned int op1 : 8;
13735 unsigned int r1 : 4;
13736 unsigned int x2 : 4;
13737 unsigned int b2 : 4;
13738 unsigned int d2 : 12;
13739 unsigned int : 8;
13740 unsigned int op2 : 8;
13741 } RXE;
13742 struct {
13743 unsigned int op1 : 8;
13744 unsigned int r3 : 4;
13745 unsigned int x2 : 4;
13746 unsigned int b2 : 4;
13747 unsigned int d2 : 12;
13748 unsigned int r1 : 4;
13749 unsigned int : 4;
13750 unsigned int op2 : 8;
13751 } RXF;
13752 struct {
13753 unsigned int op1 : 8;
13754 unsigned int r1 : 4;
13755 unsigned int x2 : 4;
13756 unsigned int b2 : 4;
13757 unsigned int dl2 : 12;
13758 unsigned int dh2 : 8;
13759 unsigned int op2 : 8;
13760 } RXY;
13761 struct {
13762 unsigned int op1 : 8;
13763 unsigned int i2 : 8;
13764 unsigned int b1 : 4;
13765 unsigned int dl1 : 12;
13766 unsigned int dh1 : 8;
13767 unsigned int op2 : 8;
13768 } SIY;
13769 struct {
13770 unsigned int op : 8;
13771 unsigned int l : 8;
13772 unsigned int b1 : 4;
13773 unsigned int d1 : 12;
13774 unsigned int b2 : 4;
13775 unsigned int d2 : 12;
13776 } SS;
13777 struct {
13778 unsigned int op : 8;
13779 unsigned int l1 : 4;
13780 unsigned int l2 : 4;
13781 unsigned int b1 : 4;
13782 unsigned int d1 : 12;
13783 unsigned int b2 : 4;
13784 unsigned int d2 : 12;
13785 } SS_LLRDRD;
13786 struct {
13787 unsigned int op : 8;
13788 unsigned int r1 : 4;
13789 unsigned int r3 : 4;
13790 unsigned int b2 : 4;
13791 unsigned int d2 : 12;
13792 unsigned int b4 : 4;
13793 unsigned int d4 : 12;
13794 } SS_RRRDRD2;
13795 struct {
13796 unsigned int op : 16;
13797 unsigned int b1 : 4;
13798 unsigned int d1 : 12;
13799 unsigned int b2 : 4;
13800 unsigned int d2 : 12;
13801 } SSE;
13802 struct {
13803 unsigned int op1 : 8;
13804 unsigned int r3 : 4;
13805 unsigned int op2 : 4;
13806 unsigned int b1 : 4;
13807 unsigned int d1 : 12;
13808 unsigned int b2 : 4;
13809 unsigned int d2 : 12;
13810 } SSF;
13811 struct {
13812 unsigned int op : 16;
13813 unsigned int b1 : 4;
13814 unsigned int d1 : 12;
13815 unsigned int i2 : 16;
13816 } SIL;
13817 } formats;
13818 union {
13819 formats fmt;
13820 ULong value;
13821 } ovl;
13822
13823 vassert(sizeof(formats) == 6);
13824
13825 ((char *)(&ovl.value))[0] = bytes[0];
13826 ((char *)(&ovl.value))[1] = bytes[1];
13827 ((char *)(&ovl.value))[2] = bytes[2];
13828 ((char *)(&ovl.value))[3] = bytes[3];
13829 ((char *)(&ovl.value))[4] = bytes[4];
13830 ((char *)(&ovl.value))[5] = bytes[5];
13831 ((char *)(&ovl.value))[6] = 0x0;
13832 ((char *)(&ovl.value))[7] = 0x0;
13833
13834 switch ((ovl.value >> 16) & 0xff00000000ffULL) {
13835 case 0xe30000000002ULL: s390_format_RXY_RRRD(s390_irgen_LTG, ovl.fmt.RXY.r1,
13836 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13837 ovl.fmt.RXY.dl2,
13838 ovl.fmt.RXY.dh2); goto ok;
13839 case 0xe30000000003ULL: /* LRAG */ goto unimplemented;
13840 case 0xe30000000004ULL: s390_format_RXY_RRRD(s390_irgen_LG, 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 0xe30000000006ULL: s390_format_RXY_RRRD(s390_irgen_CVBY, 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 0xe30000000008ULL: s390_format_RXY_RRRD(s390_irgen_AG, 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 0xe30000000009ULL: s390_format_RXY_RRRD(s390_irgen_SG, 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 0xe3000000000aULL: s390_format_RXY_RRRD(s390_irgen_ALG, 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 0xe3000000000bULL: s390_format_RXY_RRRD(s390_irgen_SLG, 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 0xe3000000000cULL: s390_format_RXY_RRRD(s390_irgen_MSG, 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 0xe3000000000dULL: s390_format_RXY_RRRD(s390_irgen_DSG, 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 0xe3000000000eULL: /* CVBG */ goto unimplemented;
13873 case 0xe3000000000fULL: s390_format_RXY_RRRD(s390_irgen_LRVG, ovl.fmt.RXY.r1,
13874 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13875 ovl.fmt.RXY.dl2,
13876 ovl.fmt.RXY.dh2); goto ok;
13877 case 0xe30000000012ULL: s390_format_RXY_RRRD(s390_irgen_LT, ovl.fmt.RXY.r1,
13878 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13879 ovl.fmt.RXY.dl2,
13880 ovl.fmt.RXY.dh2); goto ok;
13881 case 0xe30000000013ULL: /* LRAY */ goto unimplemented;
13882 case 0xe30000000014ULL: s390_format_RXY_RRRD(s390_irgen_LGF, ovl.fmt.RXY.r1,
13883 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13884 ovl.fmt.RXY.dl2,
13885 ovl.fmt.RXY.dh2); goto ok;
13886 case 0xe30000000015ULL: s390_format_RXY_RRRD(s390_irgen_LGH, ovl.fmt.RXY.r1,
13887 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13888 ovl.fmt.RXY.dl2,
13889 ovl.fmt.RXY.dh2); goto ok;
13890 case 0xe30000000016ULL: s390_format_RXY_RRRD(s390_irgen_LLGF, ovl.fmt.RXY.r1,
13891 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13892 ovl.fmt.RXY.dl2,
13893 ovl.fmt.RXY.dh2); goto ok;
13894 case 0xe30000000017ULL: s390_format_RXY_RRRD(s390_irgen_LLGT, ovl.fmt.RXY.r1,
13895 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13896 ovl.fmt.RXY.dl2,
13897 ovl.fmt.RXY.dh2); goto ok;
13898 case 0xe30000000018ULL: s390_format_RXY_RRRD(s390_irgen_AGF, ovl.fmt.RXY.r1,
13899 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13900 ovl.fmt.RXY.dl2,
13901 ovl.fmt.RXY.dh2); goto ok;
13902 case 0xe30000000019ULL: s390_format_RXY_RRRD(s390_irgen_SGF, ovl.fmt.RXY.r1,
13903 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13904 ovl.fmt.RXY.dl2,
13905 ovl.fmt.RXY.dh2); goto ok;
13906 case 0xe3000000001aULL: s390_format_RXY_RRRD(s390_irgen_ALGF, ovl.fmt.RXY.r1,
13907 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13908 ovl.fmt.RXY.dl2,
13909 ovl.fmt.RXY.dh2); goto ok;
13910 case 0xe3000000001bULL: s390_format_RXY_RRRD(s390_irgen_SLGF, ovl.fmt.RXY.r1,
13911 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13912 ovl.fmt.RXY.dl2,
13913 ovl.fmt.RXY.dh2); goto ok;
13914 case 0xe3000000001cULL: s390_format_RXY_RRRD(s390_irgen_MSGF, ovl.fmt.RXY.r1,
13915 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13916 ovl.fmt.RXY.dl2,
13917 ovl.fmt.RXY.dh2); goto ok;
13918 case 0xe3000000001dULL: s390_format_RXY_RRRD(s390_irgen_DSGF, ovl.fmt.RXY.r1,
13919 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13920 ovl.fmt.RXY.dl2,
13921 ovl.fmt.RXY.dh2); goto ok;
13922 case 0xe3000000001eULL: s390_format_RXY_RRRD(s390_irgen_LRV, ovl.fmt.RXY.r1,
13923 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13924 ovl.fmt.RXY.dl2,
13925 ovl.fmt.RXY.dh2); goto ok;
13926 case 0xe3000000001fULL: s390_format_RXY_RRRD(s390_irgen_LRVH, ovl.fmt.RXY.r1,
13927 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13928 ovl.fmt.RXY.dl2,
13929 ovl.fmt.RXY.dh2); goto ok;
13930 case 0xe30000000020ULL: s390_format_RXY_RRRD(s390_irgen_CG, ovl.fmt.RXY.r1,
13931 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13932 ovl.fmt.RXY.dl2,
13933 ovl.fmt.RXY.dh2); goto ok;
13934 case 0xe30000000021ULL: s390_format_RXY_RRRD(s390_irgen_CLG, ovl.fmt.RXY.r1,
13935 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13936 ovl.fmt.RXY.dl2,
13937 ovl.fmt.RXY.dh2); goto ok;
13938 case 0xe30000000024ULL: s390_format_RXY_RRRD(s390_irgen_STG, ovl.fmt.RXY.r1,
13939 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13940 ovl.fmt.RXY.dl2,
13941 ovl.fmt.RXY.dh2); goto ok;
florian2289cd42012-12-05 04:23:42 +000013942 case 0xe30000000025ULL: /* NTSTG */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000013943 case 0xe30000000026ULL: s390_format_RXY_RRRD(s390_irgen_CVDY, ovl.fmt.RXY.r1,
13944 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13945 ovl.fmt.RXY.dl2,
13946 ovl.fmt.RXY.dh2); goto ok;
13947 case 0xe3000000002eULL: /* CVDG */ goto unimplemented;
13948 case 0xe3000000002fULL: s390_format_RXY_RRRD(s390_irgen_STRVG,
13949 ovl.fmt.RXY.r1, ovl.fmt.RXY.x2,
13950 ovl.fmt.RXY.b2, ovl.fmt.RXY.dl2,
13951 ovl.fmt.RXY.dh2); goto ok;
13952 case 0xe30000000030ULL: s390_format_RXY_RRRD(s390_irgen_CGF, 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 0xe30000000031ULL: s390_format_RXY_RRRD(s390_irgen_CLGF, 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 0xe30000000032ULL: s390_format_RXY_RRRD(s390_irgen_LTGF, 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 0xe30000000034ULL: s390_format_RXY_RRRD(s390_irgen_CGH, 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 0xe30000000036ULL: s390_format_RXY_URRD(s390_irgen_PFD, 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 0xe3000000003eULL: s390_format_RXY_RRRD(s390_irgen_STRV, 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 0xe3000000003fULL: s390_format_RXY_RRRD(s390_irgen_STRVH,
13977 ovl.fmt.RXY.r1, ovl.fmt.RXY.x2,
13978 ovl.fmt.RXY.b2, ovl.fmt.RXY.dl2,
13979 ovl.fmt.RXY.dh2); goto ok;
13980 case 0xe30000000046ULL: s390_format_RXY_RRRD(s390_irgen_BCTG, 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 0xe30000000050ULL: s390_format_RXY_RRRD(s390_irgen_STY, 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 0xe30000000051ULL: s390_format_RXY_RRRD(s390_irgen_MSY, ovl.fmt.RXY.r1,
13989 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13990 ovl.fmt.RXY.dl2,
13991 ovl.fmt.RXY.dh2); goto ok;
13992 case 0xe30000000054ULL: s390_format_RXY_RRRD(s390_irgen_NY, ovl.fmt.RXY.r1,
13993 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13994 ovl.fmt.RXY.dl2,
13995 ovl.fmt.RXY.dh2); goto ok;
13996 case 0xe30000000055ULL: s390_format_RXY_RRRD(s390_irgen_CLY, ovl.fmt.RXY.r1,
13997 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
13998 ovl.fmt.RXY.dl2,
13999 ovl.fmt.RXY.dh2); goto ok;
14000 case 0xe30000000056ULL: s390_format_RXY_RRRD(s390_irgen_OY, ovl.fmt.RXY.r1,
14001 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14002 ovl.fmt.RXY.dl2,
14003 ovl.fmt.RXY.dh2); goto ok;
14004 case 0xe30000000057ULL: s390_format_RXY_RRRD(s390_irgen_XY, ovl.fmt.RXY.r1,
14005 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14006 ovl.fmt.RXY.dl2,
14007 ovl.fmt.RXY.dh2); goto ok;
14008 case 0xe30000000058ULL: s390_format_RXY_RRRD(s390_irgen_LY, ovl.fmt.RXY.r1,
14009 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14010 ovl.fmt.RXY.dl2,
14011 ovl.fmt.RXY.dh2); goto ok;
14012 case 0xe30000000059ULL: s390_format_RXY_RRRD(s390_irgen_CY, ovl.fmt.RXY.r1,
14013 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14014 ovl.fmt.RXY.dl2,
14015 ovl.fmt.RXY.dh2); goto ok;
14016 case 0xe3000000005aULL: s390_format_RXY_RRRD(s390_irgen_AY, ovl.fmt.RXY.r1,
14017 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14018 ovl.fmt.RXY.dl2,
14019 ovl.fmt.RXY.dh2); goto ok;
14020 case 0xe3000000005bULL: s390_format_RXY_RRRD(s390_irgen_SY, ovl.fmt.RXY.r1,
14021 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14022 ovl.fmt.RXY.dl2,
14023 ovl.fmt.RXY.dh2); goto ok;
14024 case 0xe3000000005cULL: s390_format_RXY_RRRD(s390_irgen_MFY, ovl.fmt.RXY.r1,
14025 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14026 ovl.fmt.RXY.dl2,
14027 ovl.fmt.RXY.dh2); goto ok;
14028 case 0xe3000000005eULL: s390_format_RXY_RRRD(s390_irgen_ALY, ovl.fmt.RXY.r1,
14029 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14030 ovl.fmt.RXY.dl2,
14031 ovl.fmt.RXY.dh2); goto ok;
14032 case 0xe3000000005fULL: s390_format_RXY_RRRD(s390_irgen_SLY, ovl.fmt.RXY.r1,
14033 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14034 ovl.fmt.RXY.dl2,
14035 ovl.fmt.RXY.dh2); goto ok;
14036 case 0xe30000000070ULL: s390_format_RXY_RRRD(s390_irgen_STHY, ovl.fmt.RXY.r1,
14037 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14038 ovl.fmt.RXY.dl2,
14039 ovl.fmt.RXY.dh2); goto ok;
14040 case 0xe30000000071ULL: s390_format_RXY_RRRD(s390_irgen_LAY, ovl.fmt.RXY.r1,
14041 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14042 ovl.fmt.RXY.dl2,
14043 ovl.fmt.RXY.dh2); goto ok;
14044 case 0xe30000000072ULL: s390_format_RXY_RRRD(s390_irgen_STCY, ovl.fmt.RXY.r1,
14045 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14046 ovl.fmt.RXY.dl2,
14047 ovl.fmt.RXY.dh2); goto ok;
14048 case 0xe30000000073ULL: s390_format_RXY_RRRD(s390_irgen_ICY, ovl.fmt.RXY.r1,
14049 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14050 ovl.fmt.RXY.dl2,
14051 ovl.fmt.RXY.dh2); goto ok;
14052 case 0xe30000000075ULL: s390_format_RXY_RRRD(s390_irgen_LAEY, ovl.fmt.RXY.r1,
14053 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14054 ovl.fmt.RXY.dl2,
14055 ovl.fmt.RXY.dh2); goto ok;
14056 case 0xe30000000076ULL: s390_format_RXY_RRRD(s390_irgen_LB, ovl.fmt.RXY.r1,
14057 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14058 ovl.fmt.RXY.dl2,
14059 ovl.fmt.RXY.dh2); goto ok;
14060 case 0xe30000000077ULL: s390_format_RXY_RRRD(s390_irgen_LGB, ovl.fmt.RXY.r1,
14061 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14062 ovl.fmt.RXY.dl2,
14063 ovl.fmt.RXY.dh2); goto ok;
14064 case 0xe30000000078ULL: s390_format_RXY_RRRD(s390_irgen_LHY, ovl.fmt.RXY.r1,
14065 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14066 ovl.fmt.RXY.dl2,
14067 ovl.fmt.RXY.dh2); goto ok;
14068 case 0xe30000000079ULL: s390_format_RXY_RRRD(s390_irgen_CHY, ovl.fmt.RXY.r1,
14069 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14070 ovl.fmt.RXY.dl2,
14071 ovl.fmt.RXY.dh2); goto ok;
14072 case 0xe3000000007aULL: s390_format_RXY_RRRD(s390_irgen_AHY, ovl.fmt.RXY.r1,
14073 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14074 ovl.fmt.RXY.dl2,
14075 ovl.fmt.RXY.dh2); goto ok;
14076 case 0xe3000000007bULL: s390_format_RXY_RRRD(s390_irgen_SHY, ovl.fmt.RXY.r1,
14077 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14078 ovl.fmt.RXY.dl2,
14079 ovl.fmt.RXY.dh2); goto ok;
14080 case 0xe3000000007cULL: s390_format_RXY_RRRD(s390_irgen_MHY, ovl.fmt.RXY.r1,
14081 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14082 ovl.fmt.RXY.dl2,
14083 ovl.fmt.RXY.dh2); goto ok;
14084 case 0xe30000000080ULL: s390_format_RXY_RRRD(s390_irgen_NG, ovl.fmt.RXY.r1,
14085 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14086 ovl.fmt.RXY.dl2,
14087 ovl.fmt.RXY.dh2); goto ok;
14088 case 0xe30000000081ULL: s390_format_RXY_RRRD(s390_irgen_OG, ovl.fmt.RXY.r1,
14089 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14090 ovl.fmt.RXY.dl2,
14091 ovl.fmt.RXY.dh2); goto ok;
14092 case 0xe30000000082ULL: s390_format_RXY_RRRD(s390_irgen_XG, ovl.fmt.RXY.r1,
14093 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14094 ovl.fmt.RXY.dl2,
14095 ovl.fmt.RXY.dh2); goto ok;
florian2289cd42012-12-05 04:23:42 +000014096 case 0xe30000000085ULL: /* LGAT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000014097 case 0xe30000000086ULL: s390_format_RXY_RRRD(s390_irgen_MLG, ovl.fmt.RXY.r1,
14098 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14099 ovl.fmt.RXY.dl2,
14100 ovl.fmt.RXY.dh2); goto ok;
14101 case 0xe30000000087ULL: s390_format_RXY_RRRD(s390_irgen_DLG, ovl.fmt.RXY.r1,
14102 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14103 ovl.fmt.RXY.dl2,
14104 ovl.fmt.RXY.dh2); goto ok;
14105 case 0xe30000000088ULL: s390_format_RXY_RRRD(s390_irgen_ALCG, ovl.fmt.RXY.r1,
14106 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14107 ovl.fmt.RXY.dl2,
14108 ovl.fmt.RXY.dh2); goto ok;
14109 case 0xe30000000089ULL: s390_format_RXY_RRRD(s390_irgen_SLBG, ovl.fmt.RXY.r1,
14110 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14111 ovl.fmt.RXY.dl2,
14112 ovl.fmt.RXY.dh2); goto ok;
14113 case 0xe3000000008eULL: s390_format_RXY_RRRD(s390_irgen_STPQ, ovl.fmt.RXY.r1,
14114 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14115 ovl.fmt.RXY.dl2,
14116 ovl.fmt.RXY.dh2); goto ok;
14117 case 0xe3000000008fULL: s390_format_RXY_RRRD(s390_irgen_LPQ, ovl.fmt.RXY.r1,
14118 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14119 ovl.fmt.RXY.dl2,
14120 ovl.fmt.RXY.dh2); goto ok;
14121 case 0xe30000000090ULL: s390_format_RXY_RRRD(s390_irgen_LLGC, ovl.fmt.RXY.r1,
14122 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14123 ovl.fmt.RXY.dl2,
14124 ovl.fmt.RXY.dh2); goto ok;
14125 case 0xe30000000091ULL: s390_format_RXY_RRRD(s390_irgen_LLGH, ovl.fmt.RXY.r1,
14126 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14127 ovl.fmt.RXY.dl2,
14128 ovl.fmt.RXY.dh2); goto ok;
14129 case 0xe30000000094ULL: s390_format_RXY_RRRD(s390_irgen_LLC, ovl.fmt.RXY.r1,
14130 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14131 ovl.fmt.RXY.dl2,
14132 ovl.fmt.RXY.dh2); goto ok;
14133 case 0xe30000000095ULL: s390_format_RXY_RRRD(s390_irgen_LLH, ovl.fmt.RXY.r1,
14134 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14135 ovl.fmt.RXY.dl2,
14136 ovl.fmt.RXY.dh2); goto ok;
14137 case 0xe30000000096ULL: s390_format_RXY_RRRD(s390_irgen_ML, ovl.fmt.RXY.r1,
14138 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14139 ovl.fmt.RXY.dl2,
14140 ovl.fmt.RXY.dh2); goto ok;
14141 case 0xe30000000097ULL: s390_format_RXY_RRRD(s390_irgen_DL, ovl.fmt.RXY.r1,
14142 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14143 ovl.fmt.RXY.dl2,
14144 ovl.fmt.RXY.dh2); goto ok;
14145 case 0xe30000000098ULL: s390_format_RXY_RRRD(s390_irgen_ALC, ovl.fmt.RXY.r1,
14146 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14147 ovl.fmt.RXY.dl2,
14148 ovl.fmt.RXY.dh2); goto ok;
14149 case 0xe30000000099ULL: s390_format_RXY_RRRD(s390_irgen_SLB, ovl.fmt.RXY.r1,
14150 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14151 ovl.fmt.RXY.dl2,
14152 ovl.fmt.RXY.dh2); goto ok;
florian2289cd42012-12-05 04:23:42 +000014153 case 0xe3000000009cULL: /* LLGTAT */ goto unimplemented;
14154 case 0xe3000000009dULL: /* LLGFAT */ goto unimplemented;
14155 case 0xe3000000009fULL: /* LAT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000014156 case 0xe300000000c0ULL: s390_format_RXY_RRRD(s390_irgen_LBH, ovl.fmt.RXY.r1,
14157 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14158 ovl.fmt.RXY.dl2,
14159 ovl.fmt.RXY.dh2); goto ok;
14160 case 0xe300000000c2ULL: s390_format_RXY_RRRD(s390_irgen_LLCH, ovl.fmt.RXY.r1,
14161 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14162 ovl.fmt.RXY.dl2,
14163 ovl.fmt.RXY.dh2); goto ok;
14164 case 0xe300000000c3ULL: s390_format_RXY_RRRD(s390_irgen_STCH, ovl.fmt.RXY.r1,
14165 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14166 ovl.fmt.RXY.dl2,
14167 ovl.fmt.RXY.dh2); goto ok;
14168 case 0xe300000000c4ULL: s390_format_RXY_RRRD(s390_irgen_LHH, ovl.fmt.RXY.r1,
14169 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14170 ovl.fmt.RXY.dl2,
14171 ovl.fmt.RXY.dh2); goto ok;
14172 case 0xe300000000c6ULL: s390_format_RXY_RRRD(s390_irgen_LLHH, ovl.fmt.RXY.r1,
14173 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14174 ovl.fmt.RXY.dl2,
14175 ovl.fmt.RXY.dh2); goto ok;
14176 case 0xe300000000c7ULL: s390_format_RXY_RRRD(s390_irgen_STHH, ovl.fmt.RXY.r1,
14177 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14178 ovl.fmt.RXY.dl2,
14179 ovl.fmt.RXY.dh2); goto ok;
florian2289cd42012-12-05 04:23:42 +000014180 case 0xe300000000c8ULL: /* LFHAT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000014181 case 0xe300000000caULL: s390_format_RXY_RRRD(s390_irgen_LFH, ovl.fmt.RXY.r1,
14182 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14183 ovl.fmt.RXY.dl2,
14184 ovl.fmt.RXY.dh2); goto ok;
14185 case 0xe300000000cbULL: s390_format_RXY_RRRD(s390_irgen_STFH, ovl.fmt.RXY.r1,
14186 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14187 ovl.fmt.RXY.dl2,
14188 ovl.fmt.RXY.dh2); goto ok;
14189 case 0xe300000000cdULL: s390_format_RXY_RRRD(s390_irgen_CHF, ovl.fmt.RXY.r1,
14190 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14191 ovl.fmt.RXY.dl2,
14192 ovl.fmt.RXY.dh2); goto ok;
14193 case 0xe300000000cfULL: s390_format_RXY_RRRD(s390_irgen_CLHF, ovl.fmt.RXY.r1,
14194 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14195 ovl.fmt.RXY.dl2,
14196 ovl.fmt.RXY.dh2); goto ok;
14197 case 0xeb0000000004ULL: s390_format_RSY_RRRD(s390_irgen_LMG, ovl.fmt.RSY.r1,
14198 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14199 ovl.fmt.RSY.dl2,
14200 ovl.fmt.RSY.dh2); goto ok;
14201 case 0xeb000000000aULL: s390_format_RSY_RRRD(s390_irgen_SRAG, ovl.fmt.RSY.r1,
14202 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14203 ovl.fmt.RSY.dl2,
14204 ovl.fmt.RSY.dh2); goto ok;
14205 case 0xeb000000000bULL: s390_format_RSY_RRRD(s390_irgen_SLAG, ovl.fmt.RSY.r1,
14206 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14207 ovl.fmt.RSY.dl2,
14208 ovl.fmt.RSY.dh2); goto ok;
14209 case 0xeb000000000cULL: s390_format_RSY_RRRD(s390_irgen_SRLG, ovl.fmt.RSY.r1,
14210 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14211 ovl.fmt.RSY.dl2,
14212 ovl.fmt.RSY.dh2); goto ok;
14213 case 0xeb000000000dULL: s390_format_RSY_RRRD(s390_irgen_SLLG, ovl.fmt.RSY.r1,
14214 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14215 ovl.fmt.RSY.dl2,
14216 ovl.fmt.RSY.dh2); goto ok;
14217 case 0xeb000000000fULL: /* TRACG */ goto unimplemented;
14218 case 0xeb0000000014ULL: s390_format_RSY_RRRD(s390_irgen_CSY, ovl.fmt.RSY.r1,
14219 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14220 ovl.fmt.RSY.dl2,
14221 ovl.fmt.RSY.dh2); goto ok;
14222 case 0xeb000000001cULL: s390_format_RSY_RRRD(s390_irgen_RLLG, ovl.fmt.RSY.r1,
14223 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14224 ovl.fmt.RSY.dl2,
14225 ovl.fmt.RSY.dh2); goto ok;
14226 case 0xeb000000001dULL: s390_format_RSY_RRRD(s390_irgen_RLL, ovl.fmt.RSY.r1,
14227 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14228 ovl.fmt.RSY.dl2,
14229 ovl.fmt.RSY.dh2); goto ok;
14230 case 0xeb0000000020ULL: s390_format_RSY_RURD(s390_irgen_CLMH, ovl.fmt.RSY.r1,
14231 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14232 ovl.fmt.RSY.dl2,
14233 ovl.fmt.RSY.dh2); goto ok;
14234 case 0xeb0000000021ULL: s390_format_RSY_RURD(s390_irgen_CLMY, ovl.fmt.RSY.r1,
14235 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14236 ovl.fmt.RSY.dl2,
14237 ovl.fmt.RSY.dh2); goto ok;
florian2289cd42012-12-05 04:23:42 +000014238 case 0xeb0000000023ULL: /* CLT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000014239 case 0xeb0000000024ULL: s390_format_RSY_RRRD(s390_irgen_STMG, ovl.fmt.RSY.r1,
14240 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14241 ovl.fmt.RSY.dl2,
14242 ovl.fmt.RSY.dh2); goto ok;
14243 case 0xeb0000000025ULL: /* STCTG */ goto unimplemented;
14244 case 0xeb0000000026ULL: s390_format_RSY_RRRD(s390_irgen_STMH, ovl.fmt.RSY.r1,
14245 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14246 ovl.fmt.RSY.dl2,
14247 ovl.fmt.RSY.dh2); goto ok;
florian2289cd42012-12-05 04:23:42 +000014248 case 0xeb000000002bULL: /* CLGT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000014249 case 0xeb000000002cULL: s390_format_RSY_RURD(s390_irgen_STCMH,
14250 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
14251 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
14252 ovl.fmt.RSY.dh2); goto ok;
14253 case 0xeb000000002dULL: s390_format_RSY_RURD(s390_irgen_STCMY,
14254 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
14255 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
14256 ovl.fmt.RSY.dh2); goto ok;
14257 case 0xeb000000002fULL: /* LCTLG */ goto unimplemented;
14258 case 0xeb0000000030ULL: s390_format_RSY_RRRD(s390_irgen_CSG, ovl.fmt.RSY.r1,
14259 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14260 ovl.fmt.RSY.dl2,
14261 ovl.fmt.RSY.dh2); goto ok;
florian448cbba2012-06-06 02:26:01 +000014262 case 0xeb0000000031ULL: s390_format_RSY_RRRD(s390_irgen_CDSY, ovl.fmt.RSY.r1,
14263 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14264 ovl.fmt.RSY.dl2,
14265 ovl.fmt.RSY.dh2); goto ok;
14266 case 0xeb000000003eULL: s390_format_RSY_RRRD(s390_irgen_CDSG, ovl.fmt.RSY.r1,
14267 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14268 ovl.fmt.RSY.dl2,
14269 ovl.fmt.RSY.dh2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014270 case 0xeb0000000044ULL: s390_format_RSY_RRRD(s390_irgen_BXHG, ovl.fmt.RSY.r1,
14271 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14272 ovl.fmt.RSY.dl2,
14273 ovl.fmt.RSY.dh2); goto ok;
14274 case 0xeb0000000045ULL: s390_format_RSY_RRRD(s390_irgen_BXLEG,
14275 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
14276 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
14277 ovl.fmt.RSY.dh2); goto ok;
florian8c88cb62012-08-26 18:58:13 +000014278 case 0xeb000000004cULL: s390_format_RSY_RRRD(s390_irgen_ECAG, ovl.fmt.RSY.r1,
14279 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14280 ovl.fmt.RSY.dl2,
14281 ovl.fmt.RSY.dh2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014282 case 0xeb0000000051ULL: s390_format_SIY_URD(s390_irgen_TMY, ovl.fmt.SIY.i2,
14283 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
14284 ovl.fmt.SIY.dh1); goto ok;
14285 case 0xeb0000000052ULL: s390_format_SIY_URD(s390_irgen_MVIY, ovl.fmt.SIY.i2,
14286 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
14287 ovl.fmt.SIY.dh1); goto ok;
14288 case 0xeb0000000054ULL: s390_format_SIY_URD(s390_irgen_NIY, ovl.fmt.SIY.i2,
14289 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
14290 ovl.fmt.SIY.dh1); goto ok;
14291 case 0xeb0000000055ULL: s390_format_SIY_URD(s390_irgen_CLIY, ovl.fmt.SIY.i2,
14292 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
14293 ovl.fmt.SIY.dh1); goto ok;
14294 case 0xeb0000000056ULL: s390_format_SIY_URD(s390_irgen_OIY, ovl.fmt.SIY.i2,
14295 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
14296 ovl.fmt.SIY.dh1); goto ok;
14297 case 0xeb0000000057ULL: s390_format_SIY_URD(s390_irgen_XIY, ovl.fmt.SIY.i2,
14298 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
14299 ovl.fmt.SIY.dh1); goto ok;
14300 case 0xeb000000006aULL: s390_format_SIY_IRD(s390_irgen_ASI, ovl.fmt.SIY.i2,
14301 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
14302 ovl.fmt.SIY.dh1); goto ok;
14303 case 0xeb000000006eULL: s390_format_SIY_IRD(s390_irgen_ALSI, ovl.fmt.SIY.i2,
14304 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
14305 ovl.fmt.SIY.dh1); goto ok;
14306 case 0xeb000000007aULL: s390_format_SIY_IRD(s390_irgen_AGSI, ovl.fmt.SIY.i2,
14307 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
14308 ovl.fmt.SIY.dh1); goto ok;
14309 case 0xeb000000007eULL: s390_format_SIY_IRD(s390_irgen_ALGSI, ovl.fmt.SIY.i2,
14310 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
14311 ovl.fmt.SIY.dh1); goto ok;
14312 case 0xeb0000000080ULL: s390_format_RSY_RURD(s390_irgen_ICMH, ovl.fmt.RSY.r1,
14313 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14314 ovl.fmt.RSY.dl2,
14315 ovl.fmt.RSY.dh2); goto ok;
14316 case 0xeb0000000081ULL: s390_format_RSY_RURD(s390_irgen_ICMY, ovl.fmt.RSY.r1,
14317 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14318 ovl.fmt.RSY.dl2,
14319 ovl.fmt.RSY.dh2); goto ok;
14320 case 0xeb000000008eULL: /* MVCLU */ goto unimplemented;
14321 case 0xeb000000008fULL: /* CLCLU */ goto unimplemented;
14322 case 0xeb0000000090ULL: s390_format_RSY_RRRD(s390_irgen_STMY, ovl.fmt.RSY.r1,
14323 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14324 ovl.fmt.RSY.dl2,
14325 ovl.fmt.RSY.dh2); goto ok;
14326 case 0xeb0000000096ULL: s390_format_RSY_RRRD(s390_irgen_LMH, ovl.fmt.RSY.r1,
14327 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14328 ovl.fmt.RSY.dl2,
14329 ovl.fmt.RSY.dh2); goto ok;
14330 case 0xeb0000000098ULL: s390_format_RSY_RRRD(s390_irgen_LMY, ovl.fmt.RSY.r1,
14331 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14332 ovl.fmt.RSY.dl2,
14333 ovl.fmt.RSY.dh2); goto ok;
14334 case 0xeb000000009aULL: s390_format_RSY_AARD(s390_irgen_LAMY, ovl.fmt.RSY.r1,
14335 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14336 ovl.fmt.RSY.dl2,
14337 ovl.fmt.RSY.dh2); goto ok;
14338 case 0xeb000000009bULL: s390_format_RSY_AARD(s390_irgen_STAMY,
14339 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
14340 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
14341 ovl.fmt.RSY.dh2); goto ok;
14342 case 0xeb00000000c0ULL: /* TP */ goto unimplemented;
14343 case 0xeb00000000dcULL: s390_format_RSY_RRRD(s390_irgen_SRAK, ovl.fmt.RSY.r1,
14344 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14345 ovl.fmt.RSY.dl2,
14346 ovl.fmt.RSY.dh2); goto ok;
14347 case 0xeb00000000ddULL: s390_format_RSY_RRRD(s390_irgen_SLAK, ovl.fmt.RSY.r1,
14348 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14349 ovl.fmt.RSY.dl2,
14350 ovl.fmt.RSY.dh2); goto ok;
14351 case 0xeb00000000deULL: s390_format_RSY_RRRD(s390_irgen_SRLK, ovl.fmt.RSY.r1,
14352 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14353 ovl.fmt.RSY.dl2,
14354 ovl.fmt.RSY.dh2); goto ok;
14355 case 0xeb00000000dfULL: s390_format_RSY_RRRD(s390_irgen_SLLK, ovl.fmt.RSY.r1,
14356 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14357 ovl.fmt.RSY.dl2,
14358 ovl.fmt.RSY.dh2); goto ok;
sewardjd7bde722011-04-05 13:19:33 +000014359 case 0xeb00000000e2ULL: s390_format_RSY_RDRM(s390_irgen_LOCG, ovl.fmt.RSY.r1,
14360 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14361 ovl.fmt.RSY.dl2,
14362 ovl.fmt.RSY.dh2,
14363 S390_XMNM_LOCG); goto ok;
14364 case 0xeb00000000e3ULL: s390_format_RSY_RDRM(s390_irgen_STOCG,
14365 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
14366 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
14367 ovl.fmt.RSY.dh2,
14368 S390_XMNM_STOCG); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014369 case 0xeb00000000e4ULL: s390_format_RSY_RRRD(s390_irgen_LANG, ovl.fmt.RSY.r1,
14370 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14371 ovl.fmt.RSY.dl2,
14372 ovl.fmt.RSY.dh2); goto ok;
14373 case 0xeb00000000e6ULL: s390_format_RSY_RRRD(s390_irgen_LAOG, ovl.fmt.RSY.r1,
14374 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14375 ovl.fmt.RSY.dl2,
14376 ovl.fmt.RSY.dh2); goto ok;
14377 case 0xeb00000000e7ULL: s390_format_RSY_RRRD(s390_irgen_LAXG, ovl.fmt.RSY.r1,
14378 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14379 ovl.fmt.RSY.dl2,
14380 ovl.fmt.RSY.dh2); goto ok;
14381 case 0xeb00000000e8ULL: s390_format_RSY_RRRD(s390_irgen_LAAG, ovl.fmt.RSY.r1,
14382 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14383 ovl.fmt.RSY.dl2,
14384 ovl.fmt.RSY.dh2); goto ok;
14385 case 0xeb00000000eaULL: s390_format_RSY_RRRD(s390_irgen_LAALG,
14386 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
14387 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
14388 ovl.fmt.RSY.dh2); goto ok;
sewardjd7bde722011-04-05 13:19:33 +000014389 case 0xeb00000000f2ULL: s390_format_RSY_RDRM(s390_irgen_LOC, ovl.fmt.RSY.r1,
14390 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14391 ovl.fmt.RSY.dl2,
14392 ovl.fmt.RSY.dh2, S390_XMNM_LOC);
14393 goto ok;
14394 case 0xeb00000000f3ULL: s390_format_RSY_RDRM(s390_irgen_STOC, ovl.fmt.RSY.r1,
14395 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14396 ovl.fmt.RSY.dl2,
14397 ovl.fmt.RSY.dh2,
14398 S390_XMNM_STOC); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014399 case 0xeb00000000f4ULL: s390_format_RSY_RRRD(s390_irgen_LAN, ovl.fmt.RSY.r1,
14400 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14401 ovl.fmt.RSY.dl2,
14402 ovl.fmt.RSY.dh2); goto ok;
14403 case 0xeb00000000f6ULL: s390_format_RSY_RRRD(s390_irgen_LAO, ovl.fmt.RSY.r1,
14404 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14405 ovl.fmt.RSY.dl2,
14406 ovl.fmt.RSY.dh2); goto ok;
14407 case 0xeb00000000f7ULL: s390_format_RSY_RRRD(s390_irgen_LAX, ovl.fmt.RSY.r1,
14408 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14409 ovl.fmt.RSY.dl2,
14410 ovl.fmt.RSY.dh2); goto ok;
14411 case 0xeb00000000f8ULL: s390_format_RSY_RRRD(s390_irgen_LAA, ovl.fmt.RSY.r1,
14412 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14413 ovl.fmt.RSY.dl2,
14414 ovl.fmt.RSY.dh2); goto ok;
14415 case 0xeb00000000faULL: s390_format_RSY_RRRD(s390_irgen_LAAL, ovl.fmt.RSY.r1,
14416 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14417 ovl.fmt.RSY.dl2,
14418 ovl.fmt.RSY.dh2); goto ok;
14419 case 0xec0000000044ULL: s390_format_RIE_RRP(s390_irgen_BRXHG, ovl.fmt.RIE.r1,
14420 ovl.fmt.RIE.r3, ovl.fmt.RIE.i2);
14421 goto ok;
14422 case 0xec0000000045ULL: s390_format_RIE_RRP(s390_irgen_BRXLG, ovl.fmt.RIE.r1,
14423 ovl.fmt.RIE.r3, ovl.fmt.RIE.i2);
14424 goto ok;
14425 case 0xec0000000051ULL: /* RISBLG */ goto unimplemented;
14426 case 0xec0000000054ULL: s390_format_RIE_RRUUU(s390_irgen_RNSBG,
14427 ovl.fmt.RIE_RRUUU.r1,
14428 ovl.fmt.RIE_RRUUU.r2,
14429 ovl.fmt.RIE_RRUUU.i3,
14430 ovl.fmt.RIE_RRUUU.i4,
14431 ovl.fmt.RIE_RRUUU.i5);
14432 goto ok;
14433 case 0xec0000000055ULL: s390_format_RIE_RRUUU(s390_irgen_RISBG,
14434 ovl.fmt.RIE_RRUUU.r1,
14435 ovl.fmt.RIE_RRUUU.r2,
14436 ovl.fmt.RIE_RRUUU.i3,
14437 ovl.fmt.RIE_RRUUU.i4,
14438 ovl.fmt.RIE_RRUUU.i5);
14439 goto ok;
14440 case 0xec0000000056ULL: s390_format_RIE_RRUUU(s390_irgen_ROSBG,
14441 ovl.fmt.RIE_RRUUU.r1,
14442 ovl.fmt.RIE_RRUUU.r2,
14443 ovl.fmt.RIE_RRUUU.i3,
14444 ovl.fmt.RIE_RRUUU.i4,
14445 ovl.fmt.RIE_RRUUU.i5);
14446 goto ok;
14447 case 0xec0000000057ULL: s390_format_RIE_RRUUU(s390_irgen_RXSBG,
14448 ovl.fmt.RIE_RRUUU.r1,
14449 ovl.fmt.RIE_RRUUU.r2,
14450 ovl.fmt.RIE_RRUUU.i3,
14451 ovl.fmt.RIE_RRUUU.i4,
14452 ovl.fmt.RIE_RRUUU.i5);
14453 goto ok;
florian2289cd42012-12-05 04:23:42 +000014454 case 0xec0000000059ULL: /* RISBGN */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000014455 case 0xec000000005dULL: /* RISBHG */ goto unimplemented;
14456 case 0xec0000000064ULL: s390_format_RIE_RRPU(s390_irgen_CGRJ,
14457 ovl.fmt.RIE_RRPU.r1,
14458 ovl.fmt.RIE_RRPU.r2,
14459 ovl.fmt.RIE_RRPU.i4,
14460 ovl.fmt.RIE_RRPU.m3); goto ok;
14461 case 0xec0000000065ULL: s390_format_RIE_RRPU(s390_irgen_CLGRJ,
14462 ovl.fmt.RIE_RRPU.r1,
14463 ovl.fmt.RIE_RRPU.r2,
14464 ovl.fmt.RIE_RRPU.i4,
14465 ovl.fmt.RIE_RRPU.m3); goto ok;
14466 case 0xec0000000070ULL: /* CGIT */ goto unimplemented;
14467 case 0xec0000000071ULL: /* CLGIT */ goto unimplemented;
14468 case 0xec0000000072ULL: /* CIT */ goto unimplemented;
14469 case 0xec0000000073ULL: /* CLFIT */ goto unimplemented;
14470 case 0xec0000000076ULL: s390_format_RIE_RRPU(s390_irgen_CRJ,
14471 ovl.fmt.RIE_RRPU.r1,
14472 ovl.fmt.RIE_RRPU.r2,
14473 ovl.fmt.RIE_RRPU.i4,
14474 ovl.fmt.RIE_RRPU.m3); goto ok;
14475 case 0xec0000000077ULL: s390_format_RIE_RRPU(s390_irgen_CLRJ,
14476 ovl.fmt.RIE_RRPU.r1,
14477 ovl.fmt.RIE_RRPU.r2,
14478 ovl.fmt.RIE_RRPU.i4,
14479 ovl.fmt.RIE_RRPU.m3); goto ok;
14480 case 0xec000000007cULL: s390_format_RIE_RUPI(s390_irgen_CGIJ,
14481 ovl.fmt.RIEv3.r1,
14482 ovl.fmt.RIEv3.m3,
14483 ovl.fmt.RIEv3.i4,
14484 ovl.fmt.RIEv3.i2); goto ok;
14485 case 0xec000000007dULL: s390_format_RIE_RUPU(s390_irgen_CLGIJ,
14486 ovl.fmt.RIEv3.r1,
14487 ovl.fmt.RIEv3.m3,
14488 ovl.fmt.RIEv3.i4,
14489 ovl.fmt.RIEv3.i2); goto ok;
14490 case 0xec000000007eULL: s390_format_RIE_RUPI(s390_irgen_CIJ,
14491 ovl.fmt.RIEv3.r1,
14492 ovl.fmt.RIEv3.m3,
14493 ovl.fmt.RIEv3.i4,
14494 ovl.fmt.RIEv3.i2); goto ok;
14495 case 0xec000000007fULL: s390_format_RIE_RUPU(s390_irgen_CLIJ,
14496 ovl.fmt.RIEv3.r1,
14497 ovl.fmt.RIEv3.m3,
14498 ovl.fmt.RIEv3.i4,
14499 ovl.fmt.RIEv3.i2); goto ok;
14500 case 0xec00000000d8ULL: s390_format_RIE_RRI0(s390_irgen_AHIK, ovl.fmt.RIE.r1,
14501 ovl.fmt.RIE.r3, ovl.fmt.RIE.i2);
14502 goto ok;
14503 case 0xec00000000d9ULL: s390_format_RIE_RRI0(s390_irgen_AGHIK,
14504 ovl.fmt.RIE.r1, ovl.fmt.RIE.r3,
14505 ovl.fmt.RIE.i2); goto ok;
14506 case 0xec00000000daULL: s390_format_RIE_RRI0(s390_irgen_ALHSIK,
14507 ovl.fmt.RIE.r1, ovl.fmt.RIE.r3,
14508 ovl.fmt.RIE.i2); goto ok;
14509 case 0xec00000000dbULL: s390_format_RIE_RRI0(s390_irgen_ALGHSIK,
14510 ovl.fmt.RIE.r1, ovl.fmt.RIE.r3,
14511 ovl.fmt.RIE.i2); goto ok;
14512 case 0xec00000000e4ULL: s390_format_RRS(s390_irgen_CGRB, ovl.fmt.RRS.r1,
14513 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
14514 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
14515 goto ok;
14516 case 0xec00000000e5ULL: s390_format_RRS(s390_irgen_CLGRB, ovl.fmt.RRS.r1,
14517 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
14518 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
14519 goto ok;
14520 case 0xec00000000f6ULL: s390_format_RRS(s390_irgen_CRB, ovl.fmt.RRS.r1,
14521 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
14522 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
14523 goto ok;
14524 case 0xec00000000f7ULL: s390_format_RRS(s390_irgen_CLRB, ovl.fmt.RRS.r1,
14525 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
14526 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
14527 goto ok;
14528 case 0xec00000000fcULL: s390_format_RIS_RURDI(s390_irgen_CGIB,
14529 ovl.fmt.RIS.r1, ovl.fmt.RIS.m3,
14530 ovl.fmt.RIS.b4, ovl.fmt.RIS.d4,
14531 ovl.fmt.RIS.i2); goto ok;
14532 case 0xec00000000fdULL: s390_format_RIS_RURDU(s390_irgen_CLGIB,
14533 ovl.fmt.RIS.r1, ovl.fmt.RIS.m3,
14534 ovl.fmt.RIS.b4, ovl.fmt.RIS.d4,
14535 ovl.fmt.RIS.i2); goto ok;
14536 case 0xec00000000feULL: s390_format_RIS_RURDI(s390_irgen_CIB, ovl.fmt.RIS.r1,
14537 ovl.fmt.RIS.m3, ovl.fmt.RIS.b4,
14538 ovl.fmt.RIS.d4,
14539 ovl.fmt.RIS.i2); goto ok;
14540 case 0xec00000000ffULL: s390_format_RIS_RURDU(s390_irgen_CLIB,
14541 ovl.fmt.RIS.r1, ovl.fmt.RIS.m3,
14542 ovl.fmt.RIS.b4, ovl.fmt.RIS.d4,
14543 ovl.fmt.RIS.i2); goto ok;
14544 case 0xed0000000004ULL: s390_format_RXE_FRRD(s390_irgen_LDEB, ovl.fmt.RXE.r1,
14545 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14546 ovl.fmt.RXE.d2); goto ok;
14547 case 0xed0000000005ULL: s390_format_RXE_FRRD(s390_irgen_LXDB, ovl.fmt.RXE.r1,
14548 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14549 ovl.fmt.RXE.d2); goto ok;
14550 case 0xed0000000006ULL: s390_format_RXE_FRRD(s390_irgen_LXEB, ovl.fmt.RXE.r1,
14551 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14552 ovl.fmt.RXE.d2); goto ok;
14553 case 0xed0000000007ULL: /* MXDB */ goto unimplemented;
14554 case 0xed0000000008ULL: /* KEB */ goto unimplemented;
14555 case 0xed0000000009ULL: s390_format_RXE_FRRD(s390_irgen_CEB, ovl.fmt.RXE.r1,
14556 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14557 ovl.fmt.RXE.d2); goto ok;
14558 case 0xed000000000aULL: s390_format_RXE_FRRD(s390_irgen_AEB, ovl.fmt.RXE.r1,
14559 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14560 ovl.fmt.RXE.d2); goto ok;
14561 case 0xed000000000bULL: s390_format_RXE_FRRD(s390_irgen_SEB, ovl.fmt.RXE.r1,
14562 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14563 ovl.fmt.RXE.d2); goto ok;
14564 case 0xed000000000cULL: /* MDEB */ goto unimplemented;
14565 case 0xed000000000dULL: s390_format_RXE_FRRD(s390_irgen_DEB, ovl.fmt.RXE.r1,
14566 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14567 ovl.fmt.RXE.d2); goto ok;
14568 case 0xed000000000eULL: s390_format_RXF_FRRDF(s390_irgen_MAEB,
14569 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
14570 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
14571 ovl.fmt.RXF.r1); goto ok;
14572 case 0xed000000000fULL: s390_format_RXF_FRRDF(s390_irgen_MSEB,
14573 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
14574 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
14575 ovl.fmt.RXF.r1); goto ok;
14576 case 0xed0000000010ULL: s390_format_RXE_FRRD(s390_irgen_TCEB, ovl.fmt.RXE.r1,
14577 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14578 ovl.fmt.RXE.d2); goto ok;
14579 case 0xed0000000011ULL: s390_format_RXE_FRRD(s390_irgen_TCDB, ovl.fmt.RXE.r1,
14580 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14581 ovl.fmt.RXE.d2); goto ok;
14582 case 0xed0000000012ULL: s390_format_RXE_FRRD(s390_irgen_TCXB, ovl.fmt.RXE.r1,
14583 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14584 ovl.fmt.RXE.d2); goto ok;
14585 case 0xed0000000014ULL: s390_format_RXE_FRRD(s390_irgen_SQEB, ovl.fmt.RXE.r1,
14586 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14587 ovl.fmt.RXE.d2); goto ok;
14588 case 0xed0000000015ULL: s390_format_RXE_FRRD(s390_irgen_SQDB, ovl.fmt.RXE.r1,
14589 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14590 ovl.fmt.RXE.d2); goto ok;
14591 case 0xed0000000017ULL: s390_format_RXE_FRRD(s390_irgen_MEEB, ovl.fmt.RXE.r1,
14592 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14593 ovl.fmt.RXE.d2); goto ok;
14594 case 0xed0000000018ULL: /* KDB */ goto unimplemented;
14595 case 0xed0000000019ULL: s390_format_RXE_FRRD(s390_irgen_CDB, ovl.fmt.RXE.r1,
14596 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14597 ovl.fmt.RXE.d2); goto ok;
14598 case 0xed000000001aULL: s390_format_RXE_FRRD(s390_irgen_ADB, ovl.fmt.RXE.r1,
14599 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14600 ovl.fmt.RXE.d2); goto ok;
14601 case 0xed000000001bULL: s390_format_RXE_FRRD(s390_irgen_SDB, ovl.fmt.RXE.r1,
14602 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14603 ovl.fmt.RXE.d2); goto ok;
14604 case 0xed000000001cULL: s390_format_RXE_FRRD(s390_irgen_MDB, ovl.fmt.RXE.r1,
14605 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14606 ovl.fmt.RXE.d2); goto ok;
14607 case 0xed000000001dULL: s390_format_RXE_FRRD(s390_irgen_DDB, ovl.fmt.RXE.r1,
14608 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14609 ovl.fmt.RXE.d2); goto ok;
14610 case 0xed000000001eULL: s390_format_RXF_FRRDF(s390_irgen_MADB,
14611 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
14612 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
14613 ovl.fmt.RXF.r1); goto ok;
14614 case 0xed000000001fULL: s390_format_RXF_FRRDF(s390_irgen_MSDB,
14615 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
14616 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
14617 ovl.fmt.RXF.r1); goto ok;
14618 case 0xed0000000024ULL: /* LDE */ goto unimplemented;
14619 case 0xed0000000025ULL: /* LXD */ goto unimplemented;
14620 case 0xed0000000026ULL: /* LXE */ goto unimplemented;
14621 case 0xed000000002eULL: /* MAE */ goto unimplemented;
14622 case 0xed000000002fULL: /* MSE */ goto unimplemented;
14623 case 0xed0000000034ULL: /* SQE */ goto unimplemented;
14624 case 0xed0000000035ULL: /* SQD */ goto unimplemented;
14625 case 0xed0000000037ULL: /* MEE */ goto unimplemented;
14626 case 0xed0000000038ULL: /* MAYL */ goto unimplemented;
14627 case 0xed0000000039ULL: /* MYL */ goto unimplemented;
14628 case 0xed000000003aULL: /* MAY */ goto unimplemented;
14629 case 0xed000000003bULL: /* MY */ goto unimplemented;
14630 case 0xed000000003cULL: /* MAYH */ goto unimplemented;
14631 case 0xed000000003dULL: /* MYH */ goto unimplemented;
14632 case 0xed000000003eULL: /* MAD */ goto unimplemented;
14633 case 0xed000000003fULL: /* MSD */ goto unimplemented;
14634 case 0xed0000000040ULL: /* SLDT */ goto unimplemented;
14635 case 0xed0000000041ULL: /* SRDT */ goto unimplemented;
14636 case 0xed0000000048ULL: /* SLXT */ goto unimplemented;
14637 case 0xed0000000049ULL: /* SRXT */ goto unimplemented;
14638 case 0xed0000000050ULL: /* TDCET */ goto unimplemented;
14639 case 0xed0000000051ULL: /* TDGET */ goto unimplemented;
14640 case 0xed0000000054ULL: /* TDCDT */ goto unimplemented;
14641 case 0xed0000000055ULL: /* TDGDT */ goto unimplemented;
14642 case 0xed0000000058ULL: /* TDCXT */ goto unimplemented;
14643 case 0xed0000000059ULL: /* TDGXT */ goto unimplemented;
14644 case 0xed0000000064ULL: s390_format_RXY_FRRD(s390_irgen_LEY, ovl.fmt.RXY.r1,
14645 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14646 ovl.fmt.RXY.dl2,
14647 ovl.fmt.RXY.dh2); goto ok;
14648 case 0xed0000000065ULL: s390_format_RXY_FRRD(s390_irgen_LDY, ovl.fmt.RXY.r1,
14649 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14650 ovl.fmt.RXY.dl2,
14651 ovl.fmt.RXY.dh2); goto ok;
14652 case 0xed0000000066ULL: s390_format_RXY_FRRD(s390_irgen_STEY, ovl.fmt.RXY.r1,
14653 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14654 ovl.fmt.RXY.dl2,
14655 ovl.fmt.RXY.dh2); goto ok;
14656 case 0xed0000000067ULL: s390_format_RXY_FRRD(s390_irgen_STDY, ovl.fmt.RXY.r1,
14657 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14658 ovl.fmt.RXY.dl2,
14659 ovl.fmt.RXY.dh2); goto ok;
florian2289cd42012-12-05 04:23:42 +000014660 case 0xed00000000a8ULL: /* CZDT */ goto unimplemented;
14661 case 0xed00000000a9ULL: /* CZXT */ goto unimplemented;
14662 case 0xed00000000aaULL: /* CDZT */ goto unimplemented;
14663 case 0xed00000000abULL: /* CXZT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000014664 }
14665
14666 switch (((ovl.value >> 16) & 0xff0f00000000ULL) >> 32) {
14667 case 0xc000ULL: s390_format_RIL_RP(s390_irgen_LARL, ovl.fmt.RIL.r1,
14668 ovl.fmt.RIL.i2); goto ok;
14669 case 0xc001ULL: s390_format_RIL_RI(s390_irgen_LGFI, ovl.fmt.RIL.r1,
14670 ovl.fmt.RIL.i2); goto ok;
14671 case 0xc004ULL: s390_format_RIL(s390_irgen_BRCL, ovl.fmt.RIL.r1,
14672 ovl.fmt.RIL.i2); goto ok;
14673 case 0xc005ULL: s390_format_RIL_RP(s390_irgen_BRASL, ovl.fmt.RIL.r1,
14674 ovl.fmt.RIL.i2); goto ok;
14675 case 0xc006ULL: s390_format_RIL_RU(s390_irgen_XIHF, ovl.fmt.RIL.r1,
14676 ovl.fmt.RIL.i2); goto ok;
14677 case 0xc007ULL: s390_format_RIL_RU(s390_irgen_XILF, ovl.fmt.RIL.r1,
14678 ovl.fmt.RIL.i2); goto ok;
14679 case 0xc008ULL: s390_format_RIL_RU(s390_irgen_IIHF, ovl.fmt.RIL.r1,
14680 ovl.fmt.RIL.i2); goto ok;
14681 case 0xc009ULL: s390_format_RIL_RU(s390_irgen_IILF, ovl.fmt.RIL.r1,
14682 ovl.fmt.RIL.i2); goto ok;
14683 case 0xc00aULL: s390_format_RIL_RU(s390_irgen_NIHF, ovl.fmt.RIL.r1,
14684 ovl.fmt.RIL.i2); goto ok;
14685 case 0xc00bULL: s390_format_RIL_RU(s390_irgen_NILF, ovl.fmt.RIL.r1,
14686 ovl.fmt.RIL.i2); goto ok;
14687 case 0xc00cULL: s390_format_RIL_RU(s390_irgen_OIHF, ovl.fmt.RIL.r1,
14688 ovl.fmt.RIL.i2); goto ok;
14689 case 0xc00dULL: s390_format_RIL_RU(s390_irgen_OILF, ovl.fmt.RIL.r1,
14690 ovl.fmt.RIL.i2); goto ok;
14691 case 0xc00eULL: s390_format_RIL_RU(s390_irgen_LLIHF, ovl.fmt.RIL.r1,
14692 ovl.fmt.RIL.i2); goto ok;
14693 case 0xc00fULL: s390_format_RIL_RU(s390_irgen_LLILF, ovl.fmt.RIL.r1,
14694 ovl.fmt.RIL.i2); goto ok;
14695 case 0xc200ULL: s390_format_RIL_RI(s390_irgen_MSGFI, ovl.fmt.RIL.r1,
14696 ovl.fmt.RIL.i2); goto ok;
14697 case 0xc201ULL: s390_format_RIL_RI(s390_irgen_MSFI, ovl.fmt.RIL.r1,
14698 ovl.fmt.RIL.i2); goto ok;
14699 case 0xc204ULL: s390_format_RIL_RU(s390_irgen_SLGFI, ovl.fmt.RIL.r1,
14700 ovl.fmt.RIL.i2); goto ok;
14701 case 0xc205ULL: s390_format_RIL_RU(s390_irgen_SLFI, ovl.fmt.RIL.r1,
14702 ovl.fmt.RIL.i2); goto ok;
14703 case 0xc208ULL: s390_format_RIL_RI(s390_irgen_AGFI, ovl.fmt.RIL.r1,
14704 ovl.fmt.RIL.i2); goto ok;
14705 case 0xc209ULL: s390_format_RIL_RI(s390_irgen_AFI, ovl.fmt.RIL.r1,
14706 ovl.fmt.RIL.i2); goto ok;
14707 case 0xc20aULL: s390_format_RIL_RU(s390_irgen_ALGFI, ovl.fmt.RIL.r1,
14708 ovl.fmt.RIL.i2); goto ok;
14709 case 0xc20bULL: s390_format_RIL_RU(s390_irgen_ALFI, ovl.fmt.RIL.r1,
14710 ovl.fmt.RIL.i2); goto ok;
14711 case 0xc20cULL: s390_format_RIL_RI(s390_irgen_CGFI, ovl.fmt.RIL.r1,
14712 ovl.fmt.RIL.i2); goto ok;
14713 case 0xc20dULL: s390_format_RIL_RI(s390_irgen_CFI, ovl.fmt.RIL.r1,
14714 ovl.fmt.RIL.i2); goto ok;
14715 case 0xc20eULL: s390_format_RIL_RU(s390_irgen_CLGFI, ovl.fmt.RIL.r1,
14716 ovl.fmt.RIL.i2); goto ok;
14717 case 0xc20fULL: s390_format_RIL_RU(s390_irgen_CLFI, ovl.fmt.RIL.r1,
14718 ovl.fmt.RIL.i2); goto ok;
14719 case 0xc402ULL: s390_format_RIL_RP(s390_irgen_LLHRL, ovl.fmt.RIL.r1,
14720 ovl.fmt.RIL.i2); goto ok;
14721 case 0xc404ULL: s390_format_RIL_RP(s390_irgen_LGHRL, ovl.fmt.RIL.r1,
14722 ovl.fmt.RIL.i2); goto ok;
14723 case 0xc405ULL: s390_format_RIL_RP(s390_irgen_LHRL, ovl.fmt.RIL.r1,
14724 ovl.fmt.RIL.i2); goto ok;
14725 case 0xc406ULL: s390_format_RIL_RP(s390_irgen_LLGHRL, ovl.fmt.RIL.r1,
14726 ovl.fmt.RIL.i2); goto ok;
14727 case 0xc407ULL: s390_format_RIL_RP(s390_irgen_STHRL, ovl.fmt.RIL.r1,
14728 ovl.fmt.RIL.i2); goto ok;
14729 case 0xc408ULL: s390_format_RIL_RP(s390_irgen_LGRL, ovl.fmt.RIL.r1,
14730 ovl.fmt.RIL.i2); goto ok;
14731 case 0xc40bULL: s390_format_RIL_RP(s390_irgen_STGRL, ovl.fmt.RIL.r1,
14732 ovl.fmt.RIL.i2); goto ok;
14733 case 0xc40cULL: s390_format_RIL_RP(s390_irgen_LGFRL, ovl.fmt.RIL.r1,
14734 ovl.fmt.RIL.i2); goto ok;
14735 case 0xc40dULL: s390_format_RIL_RP(s390_irgen_LRL, ovl.fmt.RIL.r1,
14736 ovl.fmt.RIL.i2); goto ok;
14737 case 0xc40eULL: s390_format_RIL_RP(s390_irgen_LLGFRL, ovl.fmt.RIL.r1,
14738 ovl.fmt.RIL.i2); goto ok;
14739 case 0xc40fULL: s390_format_RIL_RP(s390_irgen_STRL, ovl.fmt.RIL.r1,
14740 ovl.fmt.RIL.i2); goto ok;
14741 case 0xc600ULL: s390_format_RIL_RP(s390_irgen_EXRL, ovl.fmt.RIL.r1,
14742 ovl.fmt.RIL.i2); goto ok;
14743 case 0xc602ULL: s390_format_RIL_UP(s390_irgen_PFDRL, ovl.fmt.RIL.r1,
14744 ovl.fmt.RIL.i2); goto ok;
14745 case 0xc604ULL: s390_format_RIL_RP(s390_irgen_CGHRL, ovl.fmt.RIL.r1,
14746 ovl.fmt.RIL.i2); goto ok;
14747 case 0xc605ULL: s390_format_RIL_RP(s390_irgen_CHRL, ovl.fmt.RIL.r1,
14748 ovl.fmt.RIL.i2); goto ok;
14749 case 0xc606ULL: s390_format_RIL_RP(s390_irgen_CLGHRL, ovl.fmt.RIL.r1,
14750 ovl.fmt.RIL.i2); goto ok;
14751 case 0xc607ULL: s390_format_RIL_RP(s390_irgen_CLHRL, ovl.fmt.RIL.r1,
14752 ovl.fmt.RIL.i2); goto ok;
14753 case 0xc608ULL: s390_format_RIL_RP(s390_irgen_CGRL, ovl.fmt.RIL.r1,
14754 ovl.fmt.RIL.i2); goto ok;
14755 case 0xc60aULL: s390_format_RIL_RP(s390_irgen_CLGRL, ovl.fmt.RIL.r1,
14756 ovl.fmt.RIL.i2); goto ok;
14757 case 0xc60cULL: s390_format_RIL_RP(s390_irgen_CGFRL, ovl.fmt.RIL.r1,
14758 ovl.fmt.RIL.i2); goto ok;
14759 case 0xc60dULL: s390_format_RIL_RP(s390_irgen_CRL, ovl.fmt.RIL.r1,
14760 ovl.fmt.RIL.i2); goto ok;
14761 case 0xc60eULL: s390_format_RIL_RP(s390_irgen_CLGFRL, ovl.fmt.RIL.r1,
14762 ovl.fmt.RIL.i2); goto ok;
14763 case 0xc60fULL: s390_format_RIL_RP(s390_irgen_CLRL, ovl.fmt.RIL.r1,
14764 ovl.fmt.RIL.i2); goto ok;
14765 case 0xc800ULL: /* MVCOS */ goto unimplemented;
14766 case 0xc801ULL: /* ECTG */ goto unimplemented;
14767 case 0xc802ULL: /* CSST */ goto unimplemented;
14768 case 0xc804ULL: /* LPD */ goto unimplemented;
14769 case 0xc805ULL: /* LPDG */ goto unimplemented;
14770 case 0xcc06ULL: /* BRCTH */ goto unimplemented;
14771 case 0xcc08ULL: s390_format_RIL_RI(s390_irgen_AIH, ovl.fmt.RIL.r1,
14772 ovl.fmt.RIL.i2); goto ok;
14773 case 0xcc0aULL: s390_format_RIL_RI(s390_irgen_ALSIH, ovl.fmt.RIL.r1,
14774 ovl.fmt.RIL.i2); goto ok;
14775 case 0xcc0bULL: s390_format_RIL_RI(s390_irgen_ALSIHN, ovl.fmt.RIL.r1,
14776 ovl.fmt.RIL.i2); goto ok;
14777 case 0xcc0dULL: s390_format_RIL_RI(s390_irgen_CIH, ovl.fmt.RIL.r1,
14778 ovl.fmt.RIL.i2); goto ok;
14779 case 0xcc0fULL: s390_format_RIL_RU(s390_irgen_CLIH, ovl.fmt.RIL.r1,
14780 ovl.fmt.RIL.i2); goto ok;
14781 }
14782
14783 switch (((ovl.value >> 16) & 0xff0000000000ULL) >> 40) {
florian2289cd42012-12-05 04:23:42 +000014784 case 0xc5ULL: /* BPRP */ goto unimplemented;
14785 case 0xc7ULL: /* BPP */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000014786 case 0xd0ULL: /* TRTR */ goto unimplemented;
14787 case 0xd1ULL: /* MVN */ goto unimplemented;
14788 case 0xd2ULL: s390_format_SS_L0RDRD(s390_irgen_MVC, ovl.fmt.SS.l,
14789 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
14790 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
14791 case 0xd3ULL: /* MVZ */ goto unimplemented;
14792 case 0xd4ULL: s390_format_SS_L0RDRD(s390_irgen_NC, ovl.fmt.SS.l,
14793 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
14794 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
14795 case 0xd5ULL: s390_format_SS_L0RDRD(s390_irgen_CLC, ovl.fmt.SS.l,
14796 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
14797 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
14798 case 0xd6ULL: s390_format_SS_L0RDRD(s390_irgen_OC, ovl.fmt.SS.l,
14799 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
14800 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
sewardjb63967e2011-03-24 08:50:04 +000014801 case 0xd7ULL:
14802 if (ovl.fmt.SS.b1 == ovl.fmt.SS.b2 && ovl.fmt.SS.d1 == ovl.fmt.SS.d2)
14803 s390_irgen_XC_sameloc(ovl.fmt.SS.l, ovl.fmt.SS.b1, ovl.fmt.SS.d1);
14804 else
14805 s390_format_SS_L0RDRD(s390_irgen_XC, ovl.fmt.SS.l,
14806 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
14807 ovl.fmt.SS.b2, ovl.fmt.SS.d2);
14808 goto ok;
sewardj2019a972011-03-07 16:04:07 +000014809 case 0xd9ULL: /* MVCK */ goto unimplemented;
14810 case 0xdaULL: /* MVCP */ goto unimplemented;
14811 case 0xdbULL: /* MVCS */ goto unimplemented;
florian730448f2012-02-04 17:07:07 +000014812 case 0xdcULL: s390_format_SS_L0RDRD(s390_irgen_TR, ovl.fmt.SS.l,
14813 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
14814 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014815 case 0xddULL: /* TRT */ goto unimplemented;
14816 case 0xdeULL: /* ED */ goto unimplemented;
14817 case 0xdfULL: /* EDMK */ goto unimplemented;
14818 case 0xe1ULL: /* PKU */ goto unimplemented;
14819 case 0xe2ULL: /* UNPKU */ goto unimplemented;
14820 case 0xe8ULL: /* MVCIN */ goto unimplemented;
14821 case 0xe9ULL: /* PKA */ goto unimplemented;
14822 case 0xeaULL: /* UNPKA */ goto unimplemented;
14823 case 0xeeULL: /* PLO */ goto unimplemented;
14824 case 0xefULL: /* LMD */ goto unimplemented;
14825 case 0xf0ULL: /* SRP */ goto unimplemented;
14826 case 0xf1ULL: /* MVO */ goto unimplemented;
14827 case 0xf2ULL: /* PACK */ goto unimplemented;
14828 case 0xf3ULL: /* UNPK */ goto unimplemented;
14829 case 0xf8ULL: /* ZAP */ goto unimplemented;
14830 case 0xf9ULL: /* CP */ goto unimplemented;
14831 case 0xfaULL: /* AP */ goto unimplemented;
14832 case 0xfbULL: /* SP */ goto unimplemented;
14833 case 0xfcULL: /* MP */ goto unimplemented;
14834 case 0xfdULL: /* DP */ goto unimplemented;
14835 }
14836
14837 switch (((ovl.value >> 16) & 0xffff00000000ULL) >> 32) {
14838 case 0xe500ULL: /* LASP */ goto unimplemented;
14839 case 0xe501ULL: /* TPROT */ goto unimplemented;
14840 case 0xe502ULL: /* STRAG */ goto unimplemented;
14841 case 0xe50eULL: /* MVCSK */ goto unimplemented;
14842 case 0xe50fULL: /* MVCDK */ goto unimplemented;
14843 case 0xe544ULL: s390_format_SIL_RDI(s390_irgen_MVHHI, ovl.fmt.SIL.b1,
14844 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14845 goto ok;
14846 case 0xe548ULL: s390_format_SIL_RDI(s390_irgen_MVGHI, ovl.fmt.SIL.b1,
14847 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14848 goto ok;
14849 case 0xe54cULL: s390_format_SIL_RDI(s390_irgen_MVHI, ovl.fmt.SIL.b1,
14850 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14851 goto ok;
14852 case 0xe554ULL: s390_format_SIL_RDI(s390_irgen_CHHSI, ovl.fmt.SIL.b1,
14853 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14854 goto ok;
14855 case 0xe555ULL: s390_format_SIL_RDU(s390_irgen_CLHHSI, ovl.fmt.SIL.b1,
14856 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14857 goto ok;
14858 case 0xe558ULL: s390_format_SIL_RDI(s390_irgen_CGHSI, ovl.fmt.SIL.b1,
14859 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14860 goto ok;
14861 case 0xe559ULL: s390_format_SIL_RDU(s390_irgen_CLGHSI, ovl.fmt.SIL.b1,
14862 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14863 goto ok;
14864 case 0xe55cULL: s390_format_SIL_RDI(s390_irgen_CHSI, ovl.fmt.SIL.b1,
14865 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14866 goto ok;
14867 case 0xe55dULL: s390_format_SIL_RDU(s390_irgen_CLFHSI, ovl.fmt.SIL.b1,
14868 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
14869 goto ok;
florian2289cd42012-12-05 04:23:42 +000014870 case 0xe560ULL: /* TBEGIN */ goto unimplemented;
14871 case 0xe561ULL: /* TBEGINC */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000014872 }
14873
14874 return S390_DECODE_UNKNOWN_INSN;
14875
14876ok:
14877 return S390_DECODE_OK;
14878
14879unimplemented:
14880 return S390_DECODE_UNIMPLEMENTED_INSN;
14881}
14882
14883/* Handle "special" instructions. */
14884static s390_decode_t
14885s390_decode_special_and_irgen(UChar *bytes)
14886{
14887 s390_decode_t status = S390_DECODE_OK;
14888
14889 /* Got a "Special" instruction preamble. Which one is it? */
14890 if (bytes[0] == 0x18 && bytes[1] == 0x22 /* lr %r2, %r2 */) {
14891 s390_irgen_client_request();
14892 } else if (bytes[0] == 0x18 && bytes[1] == 0x33 /* lr %r3, %r3 */) {
14893 s390_irgen_guest_NRADDR();
14894 } else if (bytes[0] == 0x18 && bytes[1] == 0x44 /* lr %r4, %r4 */) {
14895 s390_irgen_call_noredir();
florian2245ce92012-08-28 16:49:30 +000014896 } else if (bytes[0] == 0x18 && bytes[1] == 0x55 /* lr %r5, %r5 */) {
14897 vex_inject_ir(irsb, Iend_BE);
14898
14899 /* Invalidate the current insn. The reason is that the IRop we're
14900 injecting here can change. In which case the translation has to
14901 be redone. For ease of handling, we simply invalidate all the
14902 time. */
14903 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TISTART),
14904 mkU64(guest_IA_curr_instr)));
14905 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TILEN),
14906 mkU64(guest_IA_next_instr - guest_IA_curr_instr)));
14907 vassert(guest_IA_next_instr - guest_IA_curr_instr ==
14908 S390_SPECIAL_OP_PREAMBLE_SIZE + S390_SPECIAL_OP_SIZE);
14909
14910 put_IA(mkaddr_expr(guest_IA_next_instr));
14911 dis_res->whatNext = Dis_StopHere;
14912 dis_res->jk_StopHere = Ijk_TInval;
sewardj2019a972011-03-07 16:04:07 +000014913 } else {
14914 /* We don't know what it is. */
14915 return S390_DECODE_UNKNOWN_SPECIAL_INSN;
14916 }
14917
14918 dis_res->len = S390_SPECIAL_OP_PREAMBLE_SIZE + S390_SPECIAL_OP_SIZE;
14919
14920 return status;
14921}
14922
14923
14924/* Function returns # bytes that were decoded or 0 in case of failure */
florianb4df7682011-07-05 02:09:01 +000014925static UInt
sewardj2019a972011-03-07 16:04:07 +000014926s390_decode_and_irgen(UChar *bytes, UInt insn_length, DisResult *dres)
14927{
14928 s390_decode_t status;
14929
14930 dis_res = dres;
14931
14932 /* Spot the 8-byte preamble: 18ff lr r15,r15
14933 1811 lr r1,r1
14934 1822 lr r2,r2
14935 1833 lr r3,r3 */
14936 if (bytes[ 0] == 0x18 && bytes[ 1] == 0xff && bytes[ 2] == 0x18 &&
14937 bytes[ 3] == 0x11 && bytes[ 4] == 0x18 && bytes[ 5] == 0x22 &&
14938 bytes[ 6] == 0x18 && bytes[ 7] == 0x33) {
14939
14940 /* Handle special instruction that follows that preamble. */
14941 if (0) vex_printf("special function handling...\n");
florian2c8ed942011-08-01 22:07:51 +000014942
14943 insn_length = S390_SPECIAL_OP_PREAMBLE_SIZE + S390_SPECIAL_OP_SIZE;
14944 guest_IA_next_instr = guest_IA_curr_instr + insn_length;
14945
14946 status =
14947 s390_decode_special_and_irgen(bytes + S390_SPECIAL_OP_PREAMBLE_SIZE);
sewardj2019a972011-03-07 16:04:07 +000014948 } else {
14949 /* Handle normal instructions. */
14950 switch (insn_length) {
14951 case 2:
14952 status = s390_decode_2byte_and_irgen(bytes);
14953 break;
14954
14955 case 4:
14956 status = s390_decode_4byte_and_irgen(bytes);
14957 break;
14958
14959 case 6:
14960 status = s390_decode_6byte_and_irgen(bytes);
14961 break;
14962
14963 default:
14964 status = S390_DECODE_ERROR;
14965 break;
14966 }
14967 }
florian5fcbba22011-07-27 20:40:22 +000014968 /* If next instruction is execute, stop here */
florianf9e1ed72012-04-17 02:41:56 +000014969 if (dis_res->whatNext == Dis_Continue && bytes[insn_length] == 0x44) {
14970 put_IA(mkaddr_expr(guest_IA_next_instr));
sewardj2019a972011-03-07 16:04:07 +000014971 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +000014972 dis_res->jk_StopHere = Ijk_Boring;
sewardj2019a972011-03-07 16:04:07 +000014973 }
14974
14975 if (status == S390_DECODE_OK) return insn_length; /* OK */
14976
14977 /* Decoding failed somehow */
sewardj442e51a2012-12-06 18:08:04 +000014978 if (sigill_diag) {
14979 vex_printf("vex s390->IR: ");
14980 switch (status) {
14981 case S390_DECODE_UNKNOWN_INSN:
14982 vex_printf("unknown insn: ");
14983 break;
sewardj2019a972011-03-07 16:04:07 +000014984
sewardj442e51a2012-12-06 18:08:04 +000014985 case S390_DECODE_UNIMPLEMENTED_INSN:
14986 vex_printf("unimplemented insn: ");
14987 break;
sewardj2019a972011-03-07 16:04:07 +000014988
sewardj442e51a2012-12-06 18:08:04 +000014989 case S390_DECODE_UNKNOWN_SPECIAL_INSN:
14990 vex_printf("unimplemented special insn: ");
14991 break;
sewardj2019a972011-03-07 16:04:07 +000014992
sewardj442e51a2012-12-06 18:08:04 +000014993 default:
14994 case S390_DECODE_ERROR:
14995 vex_printf("decoding error: ");
14996 break;
14997 }
14998
14999 vex_printf("%02x%02x", bytes[0], bytes[1]);
15000 if (insn_length > 2) {
15001 vex_printf(" %02x%02x", bytes[2], bytes[3]);
15002 }
15003 if (insn_length > 4) {
15004 vex_printf(" %02x%02x", bytes[4], bytes[5]);
15005 }
15006 vex_printf("\n");
sewardj2019a972011-03-07 16:04:07 +000015007 }
15008
sewardj2019a972011-03-07 16:04:07 +000015009 return 0; /* Failed */
15010}
15011
15012
sewardj2019a972011-03-07 16:04:07 +000015013/* Disassemble a single instruction INSN into IR. */
15014static DisResult
florian420c5012011-07-22 02:12:28 +000015015disInstr_S390_WRK(UChar *insn)
sewardj2019a972011-03-07 16:04:07 +000015016{
15017 UChar byte;
15018 UInt insn_length;
15019 DisResult dres;
15020
15021 /* ---------------------------------------------------- */
15022 /* --- Compute instruction length -- */
15023 /* ---------------------------------------------------- */
15024
15025 /* Get the first byte of the insn. */
15026 byte = insn[0];
15027
15028 /* The leftmost two bits (0:1) encode the length of the insn in bytes.
15029 00 -> 2 bytes, 01 -> 4 bytes, 10 -> 4 bytes, 11 -> 6 bytes. */
15030 insn_length = ((((byte >> 6) + 1) >> 1) + 1) << 1;
15031
15032 guest_IA_next_instr = guest_IA_curr_instr + insn_length;
15033
15034 /* ---------------------------------------------------- */
15035 /* --- Initialise the DisResult data -- */
15036 /* ---------------------------------------------------- */
15037 dres.whatNext = Dis_Continue;
15038 dres.len = insn_length;
15039 dres.continueAt = 0;
florian8844a632012-04-13 04:04:06 +000015040 dres.jk_StopHere = Ijk_INVALID;
sewardj2019a972011-03-07 16:04:07 +000015041
floriana99f20e2011-07-17 14:16:41 +000015042 /* fixs390: consider chasing of conditional jumps */
15043
sewardj2019a972011-03-07 16:04:07 +000015044 /* Normal and special instruction handling starts here. */
15045 if (s390_decode_and_irgen(insn, insn_length, &dres) == 0) {
15046 /* All decode failures end up here. The decoder has already issued an
15047 error message.
15048 Tell the dispatcher that this insn cannot be decoded, and so has
florian342e01a2012-07-26 02:37:49 +000015049 not been executed, and (is currently) the next to be executed.
15050 The insn address in the guest state needs to be set to
15051 guest_IA_curr_instr, otherwise the complaint will report an
15052 incorrect address. */
15053 put_IA(mkaddr_expr(guest_IA_curr_instr));
sewardj2019a972011-03-07 16:04:07 +000015054
florian8844a632012-04-13 04:04:06 +000015055 dres.whatNext = Dis_StopHere;
15056 dres.jk_StopHere = Ijk_NoDecode;
15057 dres.continueAt = 0;
15058 dres.len = 0;
15059 } else {
15060 /* Decode success */
15061 switch (dres.whatNext) {
15062 case Dis_Continue:
florian8559e412012-04-19 14:23:48 +000015063 put_IA(mkaddr_expr(guest_IA_next_instr));
florian8844a632012-04-13 04:04:06 +000015064 break;
15065 case Dis_ResteerU:
15066 case Dis_ResteerC:
15067 put_IA(mkaddr_expr(dres.continueAt));
15068 break;
15069 case Dis_StopHere:
florian4b8efad2012-09-02 18:07:08 +000015070 if (dres.jk_StopHere == Ijk_EmWarn ||
15071 dres.jk_StopHere == Ijk_EmFail) {
15072 /* We assume here, that emulation warnings are not given for
15073 insns that transfer control. There is no good way to
15074 do that. */
15075 put_IA(mkaddr_expr(guest_IA_next_instr));
15076 }
florian8844a632012-04-13 04:04:06 +000015077 break;
15078 default:
15079 vassert(0);
15080 }
sewardj2019a972011-03-07 16:04:07 +000015081 }
15082
15083 return dres;
15084}
15085
15086
15087/*------------------------------------------------------------*/
15088/*--- Top-level fn ---*/
15089/*------------------------------------------------------------*/
15090
15091/* Disassemble a single instruction into IR. The instruction
15092 is located in host memory at &guest_code[delta]. */
15093
15094DisResult
15095disInstr_S390(IRSB *irsb_IN,
sewardj2019a972011-03-07 16:04:07 +000015096 Bool (*resteerOkFn)(void *, Addr64),
15097 Bool resteerCisOk,
15098 void *callback_opaque,
15099 UChar *guest_code,
15100 Long delta,
15101 Addr64 guest_IP,
15102 VexArch guest_arch,
15103 VexArchInfo *archinfo,
15104 VexAbiInfo *abiinfo,
sewardj442e51a2012-12-06 18:08:04 +000015105 Bool host_bigendian,
15106 Bool sigill_diag_IN)
sewardj2019a972011-03-07 16:04:07 +000015107{
15108 vassert(guest_arch == VexArchS390X);
15109
15110 /* The instruction decoder requires a big-endian machine. */
15111 vassert(host_bigendian == True);
15112
15113 /* Set globals (see top of this file) */
15114 guest_IA_curr_instr = guest_IP;
sewardj2019a972011-03-07 16:04:07 +000015115 irsb = irsb_IN;
florian420c5012011-07-22 02:12:28 +000015116 resteer_fn = resteerOkFn;
15117 resteer_data = callback_opaque;
sewardj442e51a2012-12-06 18:08:04 +000015118 sigill_diag = sigill_diag_IN;
sewardj2019a972011-03-07 16:04:07 +000015119
florian420c5012011-07-22 02:12:28 +000015120 return disInstr_S390_WRK(guest_code + delta);
sewardj2019a972011-03-07 16:04:07 +000015121}
15122
15123/*---------------------------------------------------------------*/
15124/*--- end guest_s390_toIR.c ---*/
15125/*---------------------------------------------------------------*/